I have been using the scaler variable to scale a design variable that is an array. However, I want to scale one of the elements differently from the rest. But when I input an array into the scaler variable, I get the following error:
File "/usr/local/lib/python2.7/site-packages/openmdao/core/problem.py", line 1642, in _calc_gradient_ln_solver
Traceback (most recent call last):
J[item][param][:, i] *= in_scale[param]
ValueError: non-broadcastable output operand with shape (1,) doesn't match the broadcast shape (48,)
Is it possible to add an array to the scaler? Or is there a better way to scale individual elements of an array separately rather than do it manually?
It looks like you're trying to scale an array of 48 elements, but you're providing an array of one element. I believe your scaler needs to be either a scalar (which would equally impact the entire array) or an array of 48 elements.
For instance, assuming foo is a 48-element array.
scales = np.ones(48)
scales[0] = 2.0
driver.add_desvar('foo', lower=-10, upper=10, scaler=scales)
Related
I have a directory on my computer with several .fits files that I am trying to work with in IDL. For some reason I am unable to add all of the arrays together correctly, as I'm getting negative numbers in the totaled array when all of the individual elements in all files are positive.
In IDL, I tried the following code:
flatsfiles = file_search(Vflats, filter)
addedflats = make_array(1530,1020,value=0)
FOREACH element, flatsfiles DO BEGIN
flatsarray = readfits(element)
addedflats = [addedflats + flatsarray]
ENDFOREACH
Pretty simple code, yet the values in addedflats are negative, while all the arrays have ONLY positive elements on the order of 10^4. Can anyone see where I'm going wrong, or have a different way of doing this?
I've also tried adding the arrays one by one to see where it goes wrong:
array = readfits(flatsfiles[0])
addedflats = [addedflats + array]
array2 = readfits(flatsfiles[1])
addedflats = [addedflats + array2]
Here, the first addedflats array shows the same thing as array, which is expected since it's just being added to an array of 0's. The second addedflats, however, gives negative numbers again. For reference, the first element of array is 25189, the first element of array2 is 24030, but the first element of addedflats is -16317 rather than the expected 49219. TIA!!
Be careful of integer types that might not be able to hold the sum. Your example is probably 16-bit signed integers (the default integers in IDL):
IDL> print, 25189 + 24030
-16317
To fix, declare at least one of the arrays that you are adding to be an integer type that is big enough to hold there result. Here, 32-bit longs are sufficient (just doing scalars for simplicity, but the same works for arrays):
IDL> print, 25189L + 24030L
49219
I want to append an index to an Integer array during a loop. Like add 3 to [1,2] and get an array like [1,2,3]. I don't know how to write it in the format and I cannot get the answer on the Internet.
You can use Vectors to do the something similar using the & operator. You can access the individual elements just like an array, though you use () instead of []. Or you can just use a for loop and get the element directly.
See the below example:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Vectors;
procedure jdoodle is
-- Create the package for a vector of integers
package Integer_Vectors is new Ada.Containers.Vectors(Positive,Integer);
-- Using subtype to make just the Vector type visible
subtype Vector is Integer_Vectors.Vector;
-- Make all the primitive operations of Vector visible
use all type Vector;
-- Create a variable
V : Vector;
begin
-- Add an element to the vector in each iteration
for i in 1..10 loop
V := V & i;
end loop;
-- Show the results
for Element of V loop
Put_Line(Element'Image);
end loop;
-- Print the 2nd element of the array
Put_Line(Integer'Image(V(2)));
end jdoodle;
Ada arrays are first class types, even when the array type is anonymous. Thus a 2-dimensional array is a different type than a 3-dimensional array. Furthermore, arrays are not defined by directly specifying the number of elements in a dimension as they are in languages derived from C.
For instance, if you define a 2-dimensional array such as
type array_2d is array (Integer range 0..1, Integer range 1..2);
You have defined an array with a first range of 0..1 and a second range of 1..2. This would be a square matrix containing 4 elements.
You cannot simply add another dimension to an object of the type array_2d described above. Such an array must be of a different type.
Furthermore, one cannot change the definition of an array object after it is created.
Ok, so while this is a simple question it gets into the interesting details of design very quickly. The first thing is that an array "always knows its bounds" -- this language design element impacts the usage of the language profoundly: instead of having to pass the length of the array as a parameter, and possibly going out-of-sync, like in C you simply pass the array and let the "it knows its bounds" take care of the management.
Second, the Array is always static-length, meaning it cannot be changed once created. Caveat: Creating an array can be done in a "dynamic" setting, like querying user-input.
Third, if the subtype is unconstrained than it can have "variable" length. -- This means that you can have something like Type Integer_Vector is Array(Positive Range <>) of Integer and have parameters that operate on any size value passed in (and return-values that can be any size). This, in turn, means that your handling of such subtypes tends itself toward the more general.
Fourth, all of these apply and combine so that a lot of the 'need' for dynamically sized arrays aren't needed -- yes, there are cases where it is needed, or where it is more convenient to have a single adjustable object; this is what Ada.Containers.Vectors addresses -- but in the absence of needing a truly dynamically-sizing object you can use processing for achieving your goals.
Consider the following example:
Type Integer_Vector is Array(Positive range <>) of Integer;
Function Append( Input : Integer_Vector; Element : Integer ) return Integer_Vector is
( Input & Element );
X : Constant Integer_Vector:= (1,2);
Y : Integer_Vector renames Append(X, 3);
These three design choices combine to allow some intere
I am a beginner at Octave, that is why I will share something too obvious for the most.
cell_arr = cell(2,2,2);
cell_arr(2,2,2) = cell(2,2,2);
error: =: nonconformant arguments (op1 is 2x2x2, op2 is 2x2x2)
I am assigning an array of the same dimensionality as the cell_array, and it is not accepted. What should I change?
This is a spin-off from Please Explain Octave-Error : operator /: nonconformant arguments (op1 is 1x1, op2 is 1x10) and Error: nonconformant arguments (op1 is 1x3, op2 is 1x2) which both do not deal with cell arrays.
It's not clear what you're trying to do, but your understanding of cells seems to be a bit confused.
To make matters worse, I think you are coming across a bug: https://savannah.gnu.org/bugs/?func=detailitem&item_id=59637
I don't want to get too technical and confuse you even more, but what is happening here is this. We usually introduce cell arrays by saying this little story:
"There are two kinds of arrays: normal arrays, and cell arrays. Normal arrays always need to be 'rectangular', and contain elements of the same type. Cell arrays on the other hand, can contain elements of different types."
However, this isn't exactly true. It's a simplification. In reality, a 'cell' is simply a special kind of object; a container if you like. And a cell array then, is simply a normal array, whose elements are all 'cell objects'. In fact, the cell command is simply a shortcut way for creating an array of empty cells, nothing more.
More generally, cell arrays are indexed using {}, which opens up the cell object, and gives you its contents.
However, since they can also be thought of as normal arrays of 'cell objects', you can also index it with () like a normal array, and return the 'cell object' itself (as opposed to its contents).
E.g.
a = cell(1,2) # this is equivalent to a = { [], [] }
a{1} # returns an empty numerical array, which is what the first cell contains.
a(1) # returns a cell object, which happens to contain an empty numerical array.
Regarding the bug you're coming across, octave seems to report the wrong size for the elements you're trying to access when it comes to multidimensional cell arrays. This has been reported. What you should have been getting was something like
Error: op1 is 1x1, op2 is 2x2x2
In other words: "you are trying to cram a 2x2x2 array (whose elements happen to be cell objects) into a space that only fits a single element (i.e. at position 2,2,2)."
The reason for the error is that a new cell array can only be assigned to an existing cell array if the dimensions are exactly the same.
cell_arr = cell(2,2,2);
x = cell(2,2,2);
cell_arr(2,2,2) = x;
The last line causes an error, since cell_arr(2,2,2) chooses just the second item of each dimension, and not the 2 items of each dimension. Instead, only the initialisation of cell(2,2,2) builds a cell array of 2 items for each dimension.
It is thus important on which side you are, and whether you initiate or re-use a cell array.
The following works:
cell_arr(:,:,:) = x;
cell_arr(1:2,1:2,1:2) = x;
cell_arr(1:end,1:end,1:end) = x;
cell_arr(:,:,:) = x(1:2,1:2,1:2);
cell_arr(:,:,:) = x(:,:,:);
cell_arr(:,:,:) = x(1:end,1:end,1:end);
Of course, a directly initiated cell array can also be assigned:
cell_arr(:,:,:) = cell(1:2,1:2,1:2);
and this does not work with "end", since it does not exist till then:
cell_arr(1:end,1:end,1:end) = cell(1:end,1:end,1:end);
error: invalid use of 'end': may only be used to index existing value
Thus the solution is as follows, if you want to assign something to cell_arr(2,2,2):
Right: Two cell arrays of 2x2x2 are created.
cell_arr = cell(2,2,2);
x = cell(2,2,2);
And then:
Left: Only the 2nd item of each dim is chosen = 1x1. Right: Thus, only one item can be chosen per dim, for example the first item as follows:
cell_arr(2,2,2) = x(1,1,1);
I have a pointer uvw(:,:) which is two-dimensional, and I got a 1d buffer array x(:).
Now I need to point uvw(1,:)=>x(1:ncell) and uvw(2,:)=>x(ncell+1:ncell*2) etc.
I made a very simple example. I know that array of pointers does not work, but does anybody have an idea how this can be worked around?
PS: For a pragmatic reason I do not want to wrap my uvw with a declared type. ( i am changing some bit of code, and need uvw as 2D pointer. Currently is an array, and my idea is to avoid changing the way uvw is being used as it being used thousands of times)
program test
real, allocatable,target :: x(:)
real, pointer :: ptr(:,:)
allocate(x(100) )
x = 1.
ptr(1,:) => x(1:10)
end program
The error message says:
`error #8524: The syntax of this data pointer assignment is incorrect:
either 'bound spec' or 'bound remapping' is expected in this context.
[1]
ptr(1,:) => x(1:10)
----^`
You are trying to perform pointer bounds remapping, but you have the incorrect syntax and approach.
Pointer bounds remapping is a way to have the shape of the pointer different from that of the target. In particular, the rank of the pointer and target may differ. However, in such an assignment it is necessary to explicitly specify the lower and upper bounds of the remapping; it isn't sufficient to use : by itself.
Also, you'll need to assign the whole pointer in one go. That is, you can't have "the first ten elements point to this slice, the next ten to this slice" and so on in multiple statements.
The assignment statement would be
ptr(1:10,1:10) => x
Note, that this also means that you can't actually have what you want. You are asking for the elements ptr(1,1:10) to correspond to x(1:10) and ptr(2,2:10) to correspond to x(11:20). That isn't possible: the array elements must match in order: ptr(1:10,1) being the first ten elements of ptr must instead be associated with the first ten elements x(1:10). The corrected pointer assignment above has this.
If you prefer avoiding a pointer, then the UNION/MAP is an option depending on compiler. It was added to gfortran a while ago... then you can think of the array as a rank=2 but also use the vector (Rank=1) for SIMD operations.
All this assumes that one wants to avoid pointers...
As part of a larger algorithm, I need to produce the residuals of an array relative to a specified limit. In other words, I need to produce an array which, given someArray, comprises elements which encode the amount by which the corresponding element of someArray exceeds a limit value. My initial inclination was to use a distributed comparison to determine when a value has exceeded the threshold. As follows:
# Generate some test data.
residualLimit = 1
someArray = 2.1.*(rand(10,10,3).-0.5)
# Determine the residuals.
someArrayResiduals = (residualLimit-someArray)[(residualLimit-someArray.<0)]
The problem is that the someArrayResiduals is a one-dimensional vector containing the residual values, rather than a mask of (residualLimit-someArray). If you check [(residualLimit-someArray.<0)] you'll find that it is behaving as expected; it's producing a BitArray. The question is, why doesn't Julia allow to use this BitArray to mask someArray?
Casting the Bools in the BitArray to Ints using int() and distributing using .*produces the desired result, but is a bit inelegant... See the following:
# Generate some test data.
residualLimit = 1
someArray = 2.1.*(rand(10,10,3).-0.5)
# Determine the residuals.
someArrayResiduals = (residualLimit-someArray).*int(residualLimit-someArray.<0)
# This array should be (and is) limited at residualLimit. This is correct...
someArrayLimited = someArray + someArrayResiduals
Anyone know why a BitArray can't be used to mask an array? Or, any way that this entire process can be simplified?
Thanks, all!
Indexing with a logical array simply selects the elements at indices where the logical array is true. You can think of it as transforming the logical index array with find before doing the indexing expression. Note that this can be used in both array indexing and indexed assignment. These logical arrays are often themselves called masks, but indexing is more like a "selection" operation than a clamping operation.
The suggestions in the comments are good, but you can also solve your problem using logical indexing with indexed assignment:
overLimitMask = someArray .> residualLimit
someArray[overLimitMask] = residualLimit
In this case, though, I think the most readable way to solve this problem is with min or clamp: min(someArray, residualLimit) or clamp(someArray, -residualLimit, residualLimit)