Sometimes the numerical optimizer does not work for some reason. We can parameterize the problem a little differently, and it will work. (and may work faster)
For example, for borders (0,1) we can have a conversion function so that the values ββin (-inf, +inf) after the conversion are in (0,1)
We can do a similar trick with equality constraints. For example, we can reduce the size from 3 to 2, since the last element in x must be 1-sum(x) .
If it still does not work, we can switch to an optimizer that does not require information from a derivative, such as Nelder Mead .
And there is also a Lagrange multiplier .
In [111]: def trans_x(x): x1 = x**2/(1+x**2) z = np.hstack((x1, 1-sum(x1))) return z def F(x, y, gamma = 0.2): z = trans_x(x) return -(((z/y)**gamma).sum())**(1./gamma) In [112]: opt = minimize(F, np.array([0., 1.]), args=(np.array(y),), method='Nelder-Mead') opt Out[112]: status: 0 nfev: 96 success: True fun: -265.27701747828007 x: array([ 0.6463264, 0.7094782]) message: 'Optimization terminated successfully.' nit: 52
Result:
In [113]: trans_x(opt.x) Out[113]: array([ 0.29465097, 0.33482303, 0.37052601])
And we can visualize it using:
In [114]: x1 = np.linspace(0,1) y1 = np.linspace(0,1) X,Y = np.meshgrid(x1,y1) Z = np.array([F(item, y) for item in np.vstack((X.ravel(), Y.ravel())).T]).reshape((len(x1), -1), order='F') Z = np.fliplr(Z) Z = np.flipud(Z) plt.contourf(X, Y, Z, 50) plt.colorbar()
