0

I am very amateur when it comes to scipy. I am trying to use scipy's fmin function on a multidimensional variable system. For the sake of simplicity I am using list of list of list's. My data is 12 dimensional, when I enter np.shape(DATA) it returns (3,2,2), I am not even sure if scipy can handle that many dimensions, if not no problem I can reduce them, the point is that the optimize.fmin() function doesn't accept list based arrays as x0 initial parameters, so I need help either rewriting the x0 array into numpy compatible one or the entire DATA array into a 12 dimensional matrix or something like that.

Here is a simpler example illustrating the issue:

from scipy import optimize
import numpy as np
def f(x): return(x[0][0]*1.5-x[0][1]*2.0+x[1][0]*2.5-x[1][1]*3.0)
result = optimize.fmin(f,[[0.1,0.1],[0.1,0.1]])
print(result)

It will give an error saying invalid index to scalar variable which probably comes from not understanding the [[],[]] list of list structure, so it probably only understands numpy array formats.

So how to rewrite this to make it work, and also for my (3,2,2) shaped list of list as well!?

user421473
  • 27
  • 1
  • 4
  • minor clarification: a numpy array shape of `(3,2,2)` means 3-dimensional with 3, 2 and 2 elements in 1st, 2nd and 3rd dimension (axis). – FObersteiner Jan 25 '20 at 18:57
  • @MrFuppes it basically looks like `[[[1,1],[1,1]],[[1,1],[1,1]],[[1,1],[1,1]]]` (hopefully no typo) but with other values. – user421473 Jan 25 '20 at 19:01
  • what do you mean by "multidimensional variable system"? In your example, the function basically takes 4 input parameters, so you have to supply `fmin` with a 4-element vector as `x0` (initial guess). – FObersteiner Jan 25 '20 at 19:17
  • @MrFuppes yes it seems like x0 only allows 1D list input , but as I said my variables are organized in a (3,2,2) shape, so how to make that shape be accepted by x0 or change the shape into something that will be accepted by it. – user421473 Jan 25 '20 at 19:27

1 Answers1

1

scipy.optimize.fmin needs the initial guess for the function parameters to be a 1D array with a number of elements that suits the function to optimize. In your case, maybe you can use flatten and reshape if you just need the output to be in the same shape as your input parameters. An example based on your illustration code:

from scipy import optimize
import numpy as np

def f(x):
    return x[0]*1.5-x[1]*2.0+x[2]*2.5-x[3]*3.0

guess = np.array([[0.1, 0.1], 
                  [0.1, 0.1]]) # guess.shape is (2,2)

out = optimize.fmin(f, guess.flatten()) # flatten upon input
# out.shape is (4,)

# reshape output according to guess
out = out.reshape(guess.shape) # out.shape is (2,2) again

or out = optimize.fmin(f, guess.flatten()).reshape(guess.shape) in one line. Note that this also works for a 3-dimensional array as you propose:

guess = np.arange(12).reshape(3,2,2)
# array([[[ 0,  1],
#         [ 2,  3]],
#        [[ 4,  5],
#         [ 6,  7]],
#        [[ 8,  9],
#         [10, 11]]])

guess = guess.flatten()
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

guess = guess.reshape(3,2,2)
# array([[[ 0,  1],
#         [ 2,  3]],
#        [[ 4,  5],
#         [ 6,  7]],
#        [[ 8,  9],
#         [10, 11]]])
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • thank you, this seems to work, but now I have a different problem which I will ask in a different question :) – user421473 Jan 26 '20 at 18:51