2016-09-29 2 views
1

저는 아직 파이썬에서 초보자입니다. 너무 사소한 경우 미안합니다. 총 12 개의 변수가있는 함수의 최소값을 계산하고 싶습니다. 이 12 개의 변수 중 10 개가 주어진 값에 고정되어 있고 나머지 2 개는 최소값을 계산할 자유입니다. 다음은 내 코드 예제입니다. 코드 조각에 따라무료 및 고정 매개 변수가있는 sympy의 최소화 함수 ('SLSQP'메서드) 사용

import numpy as np 
from sympy import * 
from scipy.optimize import minimize 
init_printing(use_unicode=True) 

X_1,X_2,Y_1,Y_2,X_c1,X_c2,Y_c1,Y_c2,a_1,a_2,b_1,b_2,t_1,t_2,psi_1,psi_2= symbols('X_1 X_2 Y_1 Y_2 X_c1 X_c2 Y_c1 Y_c2 a_1 a_2 b_1 b_2 t_1 t_2 psi_1 psi_2') 

    X_1=X_c1 + (a_1 * cos(t_1) * cos(psi_1)) - ((b_1) * sin(t_1)* sin(psi_1)) 
    X_2=X_c2 + (a_2 * cos(t_2) * cos(psi_2)) - ((b_2) * sin(t_2)* sin(psi_2)) 
    Y_1=Y_c1 + (a_1 * cos(t_1) * sin(psi_1)) + ((b_1) * sin(t_1)* cos(psi_1)) 
    Y_2=Y_c2 + (a_2 * cos(t_2) * sin(psi_2)) + ((b_2) * sin(t_2)* sin(psi_2)) 

param=(t_1,t_2,X_c1,X_c2,Y_c1,Y_c2,a_1,a_2,b_1,b_2,psi_1,psi_2) #12 parameters, 10 are fixed and 2 are free. 
free_param=(t_1,t_2) #These are my two free parameters 
D=((X_2-X_1)**2 + (Y_2-Y_1)**2)**0.5 #Expression to be minimised 
distance=lambdify(param, D, modules='numpy') 

이 링크를 기반으로하고있다 : Want to do multi-variation minimize with sympy

#Build Jacobian: 
jac_D=[D.diff(x) for x in param] 
jac_distance=[lambdify(param, jf, modules='numpy') for jf in jac_D] 

def vector_distance(zz): 
""" Helper for receiving vector parameters """ 
return distance(zz[0], zz[1], zz[2], zz[3], zz[4], zz[5], zz[6], zz[7], zz[8], zz[9], zz[10], zz[11]) 

def jac_vector_distance(zz): 
""" Jacobian Helper for receiving vector parameters """ 
return np.array([jfn(zz[0], zz[1], zz[2], zz[3], zz[4], zz[5], zz[6], zz[7], zz[8], zz[9], zz[10], zz[11]) for jfn in jac_distance]) 

zz0 = np.array([np.pi/2, np.p1/2]) #Guess values for t_1 and t_2 

가 지금은 다른 10 개 변수의 값을 수정합니다. 나는 제약을 사용하는 것을 생각했다.

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
TypeError: can't convert expression to float 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
SystemError: <built-in function hasattr> returned a result with an error set 

During handling of the above exception, another exception occurred: 

SystemError        Traceback (most recent call last) 
<ipython-input-18-fc64da7d0cae> in <module>() 
----> 1 rslts = minimize(vector_distance, zz0, method='SLSQP', jac=jac_vector_distance, constraints=cons) 

/users/vishnu/anaconda3/lib/python3.5/site-packages/scipy/optimize/_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options) 
    453  elif meth == 'slsqp': 
    454   return _minimize_slsqp(fun, x0, args, jac, bounds, 
--> 455        constraints, callback=callback, **options) 
    456  elif meth == 'dogleg': 
    457   return _minimize_dogleg(fun, x0, args, jac, hess, 

/users/vishnu/anaconda3/lib/python3.5/site-packages/scipy/optimize/slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, **unknown_options) 
    404 
    405   # Call SLSQP 
--> 406   slsqp(m, meq, x, xl, xu, fx, c, g, a, acc, majiter, mode, w, jw) 
    407 
    408   # call callback if major iteration has incremented 

/users/vishnu/anaconda3/lib/python3.5/site-packages/sympy/core/expr.py in __float__(self) 
    219   # to fail, and if it is we still need to check that it evalf'ed to 
    220   # a number. 
--> 221   result = self.evalf() 
    222   if result.is_Number: 
    223    return float(result) 

/users/vishnu/anaconda3/lib/python3.5/site-packages/sympy/core/evalf.py in evalf(self, n, subs, maxn, chop, strict, quad, verbose) 
    1359 
    1360   """ 
-> 1361   from sympy import Float, Number 
    1362   n = n if n is not None else 15 
    1363 

/users/vishnu/anaconda3/lib/python3.5/importlib/_bootstrap.py in _handle_fromlist(module, fromlist, import_) 

SystemError: <built-in function hasattr> returned a result with an error set 

답변

1

당신이 두 개의 타원 사이의 거리를 최소화하는 것 같다 : 이것은 다음과 같은 오류를 반환

cons=({'type': 'eq', 
    'fun' : lambda x: np.array([X_c1-150])}, 
    {'type': 'eq', 
    'fun' : lambda x:np.array([X_c2-2.03)]}, 
    {'type': 'eq', 
    'fun': lambda x:np.array([Y_c1-152])}, 
    {'type': 'eq', 
    'fun' : lambda x: np.array([Y_c2-2.31])}, 
    {'type': 'eq', 
    'fun' : lambda x:np.array([a_1-5])}, 
    {'type': 'eq', 
    'fun': lambda x:np.array([a_2-3])}, 
    {'type': 'eq', 
    'fun' : lambda x: np.array([b_1-9])}, 
    {'type': 'eq', 
    'fun' : lambda x:np.array([b_2-4])}, 
    {'type': 'eq', 
    'fun': lambda x:np.array([psi_1-np.pi/2])}, 
    {'type': 'eq', 
    'fun' : lambda x: np.array([psi_2-np.pi/4])}, 
) 

bnds=((0,np.2pi), (0,np.2pi)) # My free parameters can take values between 0 and 2pi. 
rslts = minimize(vector_distance, zz0, method='SLSQP', jac=jac_vector_distance, constraints=cons, bounds=bnds) 

(아래 그림과 같이 나는 등 X_c1 = 150, X_c2 = 2.03 싶어). 이 작업을 수행하는 데 sympy가 필요하지 않습니다.

from math import sin, cos, hypot, pi 
from scipy import optimize 
import numpy as np 

def ellipse(xc, yc, a, b, psi): 
    a_cos_p = a * cos(psi) 
    a_sin_p = a * sin(psi) 
    b_cos_p = b * cos(psi) 
    b_sin_p = b * sin(psi) 
    def f(t): 
     cos_t = cos(t) 
     sin_t = sin(t) 
     x = xc + cos_t * a_cos_p - sin_t * b_sin_p 
     y = yc + cos_t * a_sin_p + sin_t * b_cos_p 
     return x, y 
    return f 

def min_dist_between_ellipses(el1, el2): 
    def dist(pars): 
     t1, t2 = pars.tolist() 
     x1, y1 = el1(t1) 
     x2, y2 = el2(t2) 
     return hypot(x1 - x2, y1 - y2) 

    r = optimize.minimize(dist, (0, 0)) 
    return r.x.tolist(), dist(r.x) 

xc1 = 150 
xc2 = 2.03 
yc1 = 152 
yc2 = 2.31 
a1 = 5 
a2 = 3 
b1 = 9 
b2 = 4 
psi1 = pi/2 
psi2 = pi/4 

elpars1 = xc1, yc1, a1, b1, psi1 
elpars2 = xc2, yc2, a2, b2, psi2 
el1 = ellipse(*elpars1) 
el2 = ellipse(*elpars2) 

print((min_dist_between_ellipses(el1, el2))) 

x1, y1 = np.array([el1(t) for t in np.linspace(0, 2*np.pi, 100)]).T 
x2, y2 = np.array([el2(t) for t in np.linspace(0, 2*np.pi, 100)]).T 
print(np.hypot(x1[:, None] - x2[None, :], y1[:, None] - y2[None, :]).min()) 

출력 :

([2.098535986219504, 0.03199718973020122], 200.25805791197473) 
200.259630185 
+0

예, I이 작동 개의 타원과의 사이의 최단 거리를 추정하고 싶었 다음은 그 예이다. 감사. 처음에는 최단 거리를 수치로 계산할 때 0에서 2 * pi 사이의 경계를 넣지 않은 이유는 확실하지 않지만 이제는 명확합니다. – Vishnu

관련 문제