Problem with bounds array shape in scipy.optimize constrained methods - arrays

Followup to my previous question now I have a problem with the shape of the bounds array in the constrained bfgs method.
My code is the following:
nr = 5
lag = 1
guess =numpy.array([[[ random.uniform(-1.0,1.0) for k in range(nr)] for l in range(lag)],
[[ random.uniform( 0.0,1.0) for k in range(nr)] for l in range(lag)],
[[ random.uniform(-1.0,1.0) for k in range(nr)] for l in range(lag)]])
bounds =numpy.array([[[ [-1.0,1.0] for k in range(nr)] for l in range(lag)],
[[ [ 0.0,1.0] for k in range(nr)] for l in range(lag)],
[[ [-1.0,1.0] for k in range(nr)] for l in range(lag)]])
result = optimize.fmin_l_bfgs_b( myfunc,guess.flatten(),bounds=bounds.reshape(15,2) )
As you can see I start out with a (3,1,5) shaped list of lists, which is my preferred format with which I work inside the myfunc() because it's easy to parse with nested for loops.Then this list gets crunched into a (15,) shaped numpy array to satisfy the x0 parameter's format needs, but don't worry because the X value inside the myfunc() is then transformed back into my (3,1,5) format via X=X.reshape(origshape) where the origshape global variable will save the original format. It may seem inefficient and a useless back and forth but I couldn't find a way to do it easier.
Now this works with every fmin_ function so far except with bounds like fmin_l_bfgs_b, I couldn't figure out what shape the bounded values need to be in. The documentation says:
"(min, max) pairs for each element in x, defining the bounds on that parameter."
So I thought this means 1 pair for each element, so a (15,2) shape in my situation, but when I use the code above, it gives me the following error:
TypeError: 'float' object is not subscriptable
So I guess I got the shape wrong. Please help me to fix this.

result = optimize.fmin_l_bfgs_b( myfunc,guess.flatten(),bounds=bounds.reshape(15,2),approx_grad=True )
It seems like it doesn't work without setting the approx_grad variable to True. Otherwise I guess you need to specify the fprime function.
Either way the function seems to be depreciated and using the scipy.optimize.minimize function is better.

Related

Find indices of value in array - IDL

I am learning IDL through some inherited code. In other languages (python, MATLAB), it is easy to find the indices associated with a value of interest in an array. However, I cannot seem to find any simple function or method to do this in IDL. For example:
A = [55, 6, 762, 35, 155, 1, 867, 35]
I know that the value 155 is in A, but I am interested in its location [x,y]. How can I easily access this information?
The only thing I can think of that is similar is finding a MAX value within an array.
B = max(A,location)
where the second argument (location) gives the index of the maximum value in A. However, I want to be able to do this with any value, not just max.
I am aware of the VALUE_LOCATE function, but that requires the array to be monotonic which is not the case here.
I have tried using WHERE and ARRAY_INDICES, among other things, but I don't think I am using them correctly (or they just don't do what I am asking for).
Thank you.
Of course, I figured it out right after posting this. Using the WHERE function solved the problem. If anyone searches for this in the future:
C = where(A eq desired_value)
You can keep track of the indices in the original array then use VALUE_LOCATE in the following way.
b = LINDGEN(N_ELEMENTS(a))
s = SORT(a)
c = b[s]
d = a[s]
Now just define your search value(s), say, as the variable v then you can do the following:
v = 155
i = VALUE_LOCATE(d,v) ;; index of sorted array
j = c[i[0]] ;; index of original, unsorted array
Then you can check your results by doing:
PRINT,';; ',a[j[0]],d[i[0]]
;; 155 155
The only annoying caveat of VALUE_LOCATE is that if the array a has any NaNs in it, the search will fail or return bad values so be careful of that.
If you know the value for which you are searching is an integer, then using WHERE will also work, for example:
good = WHERE(a EQ v[0],gd)
PRINT,';; ',a[good[0]]
;; 155
The caveat with using WHERE is if you only know the approximate search value and the array contains single- or double-precision floating point values. Sometimes your search will turn up null because you don't have the exact match.

Matlab loop to assign rows to cell array

I have a big cell array A=cell(a,b,c,d) and a row vector B with dimensions 1-by-b.
I want to build a loop in MATLAB that does the following:
for i=1:n
B = Calculate_row(input1,input2) %this is a function that creates my B row
A{a,:,c,i} = B(:)
end
anyway if I try to do A{a,:,c} = B(:) I receive the following error:
Expected one output from a curly brace or dot indexing expression, but there were b results.
And if I try to do A(a,:,c) = B(:) I receive the following error:
Conversion to cell from double is not possible.
Is there a way to do this? (I know a less elegant way that probably works would be to assign each value to the cell separately, but I would prefer not to do it).
One way to do this is to make B a cell array and then take advantage of comma-separated-lists:
B_cell = num2cell(B);
[A{a,:,c}] = B_cell{:} %// or [A{a,:,c,i}] = B_cell{:} if tim's comment is correct
Have a look at Loren Shure's article Deal or No Deal and also this answer for more.
The problem with your syntax, A{a,:,c} = B(:), is that the RHS (i.e. B(:)) is just one single matrix whereas the LHS is a comma-separated-list of b results. So you are basically requesting that 1 output be assigned to b variables and MATLAB doesn't like that, also hence the error message.
The problem with A(a,:,c) = B(:) is that indexing a cell array with () returns a cell array and you can't just assign a matrix (i.e. B(:)) to a cell array hence you second error.

FORTRAN - Assigning an array value to variable

Is there a way to get the value of an array to the shape of a variable? Even when I select a single value of an array, say A(1:1, 1:1), it still complains when I compile and want to assign this to a variable:
Error: Incompatible ranks 0 and 1 in assignment at (1)
The goal in the end is something like this:
H = MAXVAL(matrix) - epsilon
IF ( matrix(i:i, i:i) >= H ) THEN
...
but I cannot make this comparison because H is a variable and matrix(i:i, i:i) a 1x1 array. Is the only possibility for this to work to make H and array, too?
Thank you for your help!
Do not specify a range, use a single element:
A(1,1)=1
Your statement would then read:
H = MAXVAL(matrix) - epsilon
IF ( matrix(i, i) >= H ) THEN
Background:
Fortran allows you to work on sub-arrays like:
A(1:10,2:5)
which would be a 10x4 array. So A(1:1,1:1) is in fact an array (1x1) (as you noted). A(1,1), on the other hand, is a scalar and can be treated as such.

Objects in Arrays Help Lua?

So, I have an array
//loop here
nummobs = nummobs + 1
Mobs = {}
Mobs[nummobs] = Entity.Init(x(locations to spawn mob), y(locations to spawn mob),"testMob")
Then, call the draw method...
for i = 0, table.getn(Mobs) do
Mobs[i].draw()
end
Error: map.lua:54(Mobs[i].draw() line): attempt to index field '?' (a nil value)... BUT IT HAS SOMETHING IN IT! right?
Anyone ever try something like this? Can anyone fix it?
Thanks
Nate
Lua uses 1-based indexes for arrays. Thus, the range of an array is [1, n] inclusive, where n is the number of elements.
More importantly, you can use ipairs and not have to write out the loop components:
for i, mob in ipairs(Mobs) do
mob:draw()
end
Oh, and never use getn; use the # length operator instead.

Operating elementwise on an array

I'm trying to check if my arrays are returning nonsense by accessing out of bounds elements, in fortran. And I want to check these values are less than one, and if they are, change them to one.
This is the piece of my code causing issues:
lastNeighLabel=(/clusterLabel(jj-1,kk,ll), clusterLabel(jj,kk-1,ll), clusterLabel(jj,kk,ll-1)/)
LastNeighLabel contains the cluster label (between 1 and n, where n isthe total number of unique seperate clusters found) for the last neighbour in the x,y,z direction respectively.
When jj or kk or ll are 1, they try and access the 0th element in the array, and as FORTRAN counts from 1 in arrays, it tries to destroy the universe. I'm currently in a tangled mess of about 8 if/elseif statements trying to code for every eventuality. But I was hoping there was a way of operating on each element. So basically I'd like to say where((/jj-1,kk-1,ll-1/).lt.1) do clusterLabel(jj-1,kk,ll)=0 etc depending on which element is causing the problem.
But I can't think of a way to do that because where will only manipulate the variables passed to it, not a different array at the same index. Or am I wrong?
Will gladly edit if this doesn't make sense.
It is not obligatory that Fortran accesses arrays starting from one. Any starting value is allowed. If it more convenient to you to have a zero indexed array, declare the array as:
real, dimension (0:N-1, 0:M-1) :: array
Or
real, dimension (0:N, 0:M) :: array
and have the 0 indices be extra to catch special cases.
This might be another solution to your problem, since zero index values would be legal.
Another possible way to approach this, is to create an extended cluster label array (with index bounds starting at 0), which is equal to the cluster label array with a layer of zeroes tacked on the outside. You can then let your loop run safely over all values of jj, kk, and ll. It depends on the size of the array if this is a feasible solution.
integer :: extended_cluster_label(0:size(cluster_label,1), &
0:size(cluster_label,2), &
0:size(cluster_label,3) &
)
extended_cluster_label(0,:,:) = 0
extended_cluster_label(:,0,:) = 0
extended_cluster_label(:,:,0) = 0
extended_cluster_label(1:, 1:, 1:) = cluster_label
Maybe you could use a function?
real function f(A,i,j,k)
real :: A(:,:,:)
integer :: i,j,k
if (i==0.or.j==0.or.k==0) then
f=0
else
f=A(i,j,k)
endif
end function f
and then use f(clusterLabel,jj-1,kk,ll) etc.

Resources