2

I'm trying to minimize a function of three N-sized arrays that contain the minimization parameters that I want to find. For example, suppose the parameters I want to find in order to minimize the function are given by the arrays x = x[0],x[1],...,x[N-1], a = a[0],a[1],...,a[N-1], and b = b[0],b[1],...,b[N-1] . Also, in the problem, the minimization boundaries are constrained, with the constraints being given as:

0 <= x[i]  and  sum(x[i])-1=0  for all  i=0,...,N-1
0 <= a[i] <= Pi/2  for all  i=0,...,N-1
0 <= b[i] <= Pi/2  for all  i=0,...,N-1

After this question, I was able to define these constraints as follows:

import numpy as np

#defining the constraints for minimization
#constraints on x:
Dx_lhs = np.diag(np.ones(N))
def xlhs(x): #left hand side
    return Dx_lhs @ x
def xrhs(x): #right hand side
    return np.sum(x) -1
con1x = {'type': 'ineq', 'fun': lambda x: xlhs(x)}
con2x = {'type': 'eq', 'fun': lambda x: xrhs(x)}

#constraints on a:
Da_lhs = np.diag(np.ones(N))
Da_rhs = -np.diag(np.ones(N))
def alhs(a):
    return Da_lhs @ a
def arhs(a): 
    return Da_rhs @ a + (np.ones(N))*np.pi/2
con1a = {'type': 'ineq', 'fun': lambda a: alhs(H)}
con2a = {'type': 'ineq', 'fun': lambda a: -1.0*Hrhs(H)}

# Restrições em b:
Db_lhs = np.diag(np.ones(N))
Db_rhs = -np.diag(np.ones(N))
def blhs(b):
    return Db_lhs @ b
def brhs(b): 
    return Db_rhs @ b + (np.ones(N))*np.pi/2
con1b = {'type': 'ineq', 'fun': lambda b: alhs(H)}
con2b = {'type': 'ineq', 'fun': lambda b: -1.0*Hrhs(H)}

Now suppose I have a function like:

def fun(mins): #just an example
    x, a, b = mins
    for i in range(N):
        sbi=0; sai=0
        for j in range(i+1):
            sbi += 2*x[j]*np.tan(b[j])
            sli += 2*x[j]*np.tan(a[j])
        B[i]=sbi
        A[i]=sai
    return (B @ C)

Which is not working since probably the first line of the function isn't the right way to define it (I couldn't figure out how should I declare the arrays containing the variables that I want to minimize). Can anyone help me on how can I fix this and apply the scipy.optimize.minimize to find the values for x[], a[] and b[] that minimizes my function?

P.S.: The function presented is just for illustrative purposes, the minimization solution may be obvious.

Muhammad Mohsin Khan
  • 1,444
  • 7
  • 16
  • 23

1 Answers1

1

The to-be-minimized function should accept a 1D-array of all parameters. If you want to split this array into 3 distinct arrays, you can use a reshape operation:

x, a, b = mins.reshape(3, N)
a_guest
  • 34,165
  • 12
  • 64
  • 118
  • Thank you @a_guest, but even tough I put this command inside my function, when I tried to apply the optimization with `res = scipy.optimize.minimize(fun(mins),x0=np.zeros(3*N),constraints=(con1x,con2x,con1a,con2a,con1b,con2b))` I got the error that the name 'mins' is not defined. – Mateus Forcelini Jan 25 '22 at 12:28
  • You should just pass the function, i.e. `minimize(func, x0=...)`. It will be called by the optimizer (starting with `x0`). – a_guest Jan 25 '22 at 12:33
  • I'm still getting some errors apparently with the constraints. Did I called them in the right manner? – Mateus Forcelini Jan 25 '22 at 13:28
  • @MateusForcelini It's hard to say without seeing the specific error message. – a_guest Jan 25 '22 at 13:35
  • Its a little long messagem... but the last lines are: `ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 9 is different from 3)`. Maybe I can show it to you in some other place? P.S.: I adopted N=3 in the example – Mateus Forcelini Jan 25 '22 at 13:49
  • @MateusForcelini It probably means you arrays `B` and `C` have incompatible shapes for the matrix multiplication in `B @ C`. Since you don't show the code that creates those arrays, it's difficult to say where the error is exactly. – a_guest Jan 25 '22 at 14:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241392/discussion-between-mateus-forcelini-and-a-guest). – Mateus Forcelini Jan 25 '22 at 15:36