# -*- coding: utf-8 -*-
"""
Локальна оптимізація з границями векторної функції квазі-ньютонівським методом L-BFGS-B, який призначений для нелінійних задач з великою кількістю невідомих
"""

import numpy as np
from scipy.optimize import minimize, fmin_l_bfgs_b

def f(x): # функція n-змінних
    #y=1.43243 + x[0]*x[3]*(-1078.61) + x[0]**(-1)*x[2]*0.225551 + x[0]**(-1)*x[3]*(-0.470969) + x[1]*x[4]**(-1)*33.8941 + x[1]**(-1)*x[4]**(-1)*0.0148706 + x[3]*x[4]*(-23.2641) + x[3]*x[4]**(-1)*(-22.3094)
    #y=3.21439 + x[0]*x[1]*185.91 + x[1]*(-125.042) + x[1]*x[3]**(-1)*0.457499 + x[1]*x[4]**(-1)*94.7473 + x[1]**(-1)*x[4]*(-0.0832421) + x[1]**(-1)*x[4]**(-1)*0.0429714 + x[4]**(-1)*(-3.62757)
    y=5.4275 + x[0]*(-41.3274) + x[0]*x[4]*18.8829 + x[0]**(-1)*x[2]*0.186815 + x[2]*x[4]*(-2.26718) + x[2]**(-1)*x[3]**(-1)*2.41347e-05 + x[3]*(-128.403) + x[3]*x[4]*51.1759
    return y

#bounds=[(0.015,0.05),(0.01,0.05),(0.01,0.05),(0.025,0.065),(0.174444,0.872222)]
bounds=[(0.02514,0.03986),(0.02159,0.03841),(0.02159,0.03841),(0.036591,0.053409),(0.37664,0.67002)]
x0=[(i+j)/2 for i,j in bounds]
res=minimize(f, x0=x0, method="L-BFGS-B", bounds=bounds)
print res.x

# візуалізація
d=dict(zip(['b','R1','R2','L','a'],bounds))
import matplotlib.pyplot as plt
X=np.linspace(*d['a'])
Y=f([ 0.03986,   0.02159,   0.02159,   0.053409,  X  ])
Xn=(X-X.min())*2/(X.max()-X.min())-1 # перевід у шкалу -1,1
plt.plot(Xn,Y,'k:', lw=1)
plt.show()

"""
# 3D-візуалізація
from mpl_toolkits.mplot3d import Axes3D
ax=Axes3D(plt.figure()) # система координат
X, Y = np.meshgrid(np.linspace(*d['b']), np.linspace(*d['R2']))
Z=f([X, 0.02094605, Y, 0.065, 0.872222])
ax.plot_wireframe(X, Y, Z) # каркасна поверхня
#ax.scatter(res.x[0], res.x[1], res.fun, c='k') # мінімум
ax.set_xlabel('X0'),ax.set_ylabel('X1'),ax.set_zlabel('Y');plt.show()
"""