Минимизировать функцию с помощью переменных Sympy в SciPy? - PullRequest
0 голосов
/ 05 августа 2020

В настоящее время у меня есть следующий код, который определяет функцию fun c

from scipy.optimize import minimize
import sympy as sp
x2=sp.Symbol('x2')
u2=sp.Symbol('u2')
fm=25*u2-20.0*(sp.sin(x2)) + 38.7296387*(sp.cos(x2)) - 38.7296387
def func(x2,u2):
    return -fm
def constraint1(u2,x2):
    return -u2+40*sp.sin(x2)+0.2
def constraint2(u2,x2):
    return -u2-40*sp.sin(x2)+0.2
b=[-1,1]
bnds=[b,b]
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'ineq', 'fun': constraint2}
cons = ([con1,con2])
x0=[0,0]
solution = minimize(func,x0,method='SLSQP',bounds=bnds,constraints=cons)

Я минимизирую f по отношению к x2 и u2. Набор инструментов оптимизации SciPy не позволяет минимизировать функции с переменными Sympy в аргументах. Есть ли способ сделать это?

1 Ответ

1 голос
/ 05 августа 2020

SymPy - это символьная c математическая библиотека, а SciPy - математическая c библиотека числовых значений. SciPy не понимает ничего общего с символами SymPy и будет работать только с числовыми c значениями, такими как числа с плавающей запятой.

Вы должны попытаться сделать так, чтобы каждая переменная имела собственное имя, чтобы избежать путаницы. Это означает четкое разделение ваших числовых c значений x с его символическими c значениями. Например, в func вы ничего не делаете со своими входными значениями x2 и u2, возможно, из-за этой путаницы. fm - это символьное c выражение, которое SciPy не понимает. Чтобы получить число с плавающей запятой из fm, вам необходимо оценить его в точке, используя subs().

Вторая ошибка заключается в том, что SciPy использует функции, которые принимают один ввод кортежа вместо функции с несколькими входами с плавающей запятой. . Вам необходимо самостоятельно разделить входы внутри функции.

Третья ошибка - замена x2 и u2 между func, constraint1 и constraint2. Это приведет к тому, что входные данные условий будут заменены местами, что создаст совершенно другое ограничение, чем вы ожидали.

Вот ваш код с этими 3 исправлениями:

from scipy.optimize import minimize
import sympy as sp

x2_symbol = sp.Symbol('x2')
u2_symbol = sp.Symbol('u2')
fm = 25 * u2_symbol - 20.0 * (sp.sin(x2_symbol)) + 38.7296387 * (sp.cos(x2_symbol)) - 38.7296387

def func(x):
    x2_float, u2_float = x
    return -fm.subs([(x2_symbol, x2_float), (u2_symbol, u2_float)])

def constraint1(x):
    x2_float, u2_float = x
    return -u2_float + 40 * sp.sin(x2_float) + 0.2

def constraint2(x):
    x2_float, u2_float = x
    return -u2_float - 40 * sp.sin(x2_float) + 0.2

b = [-1, 1]
bounds = [b, b]
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'ineq', 'fun': constraint2}
constraints = (con1, con2)
x0 = [0, 0]
solution = minimize(func, x0, method='SLSQP', bounds=bounds, constraints=constraints)
print(solution)

Я полагаю fm было получено из предыдущего решения другой проблемы и поэтому должно содержать символы. В противном случае эту проблему можно было бы решить чисто численно с очень небольшими изменениями в приведенном выше коде.

Вы также можете решить эту проблему чисто символически, используя условия Каруша – Куна – Такера . Я могу опубликовать решение этой проблемы, если сочту нужным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...