我有价格向量和数量向量。我想象征性地将这两个载体划分为同情。我甚至找不到矢量设施。因此,我完全迷失于如何创建矢量符号以及如何操纵它们。
最终我想用lagrangian方法最大化的是prod((x / p)** b)受到约束sum(x)= 1.我可以用标量来做,但不能用向量:< / p>
import sympy as sp
import sympy
from sympy.abc import,p1, p2, l, x1, x2, b1, b2
sp.init_printing()
U = ((x1/p1)**b1)*((x2/p2)**b2)
L = U - l*(x1 + x2 - 1)
dL_dy = sp.diff(L, x1)
dL_dx = sp.diff(L, x2)
dL_dl = sp.diff(L, l)
sp.solve([dL_dy, dL_dx, dL_dl], (x1, x2, l))
答案 0 :(得分:2)
这是一种方法。
import sympy as sp
定义(向量)变量和参数:
# vector size (integer, user input):
n = 2
# vector variables:
x = sp.var('x0:'+str(n), positive = True)
y = sp.var('y0:'+str(n), positive = True)
# vector parameters:
p = sp.var('p0:'+str(n), positive = True)
q = sp.var('q0:'+str(n), positive = True)
# scalar parameters
b = sp.var('b', real = True)
c = sp.var('c', real = True)
# Lagrange multiplier for sum constraint:
l = sp.var('lambda')
目标函数:
U = reduce(lambda xi, xj: xi * xj, [(xi/pi)**b * (yi/qi)**c for xi,pi,yi,qi in zip(x,p,y,q)],1)
U
(X0 / P0)** B *(X1 / P1)** B *(Y0 / Q0)** C *(Y1 / Q1)**ç
拉格朗日:
L = U + l * (sum(x+y)-1)
KKT条件(每个列表元素必须等于零):
KKT = sp.simplify([sp.numer(sp.together(sp.diff(L, xi))) for xi in x]+\
[sp.numer(sp.together(sp.diff(L, xi))) for yi in y] + [sp.diff(L, l)])
为了帮助求解器,我只考虑了导数的分子。这意味着由于相应的零分母(必须手动检查),基于此方法的某些解决方案可能无效。
现在可以获得解决方案
sp.solve(KKT,sp.flatten([x,y,l]))
对于参数b
和c
的一般值,似乎Sympy无法提供解决方案。但是,可以获得这些参数的某些选择的解决方案。例如,对于b=2
和c=2
,给出的解决方案是
[{lambda: y0**2*y1**2*(y0 + y1 - 1)**3/(4*p0**2*p1**2*q0**2*q1**2), x0: -y0/2 - y1/2 + 1/2, x1: -y0/2 - y1/2 + 1/2}]
答案 1 :(得分:0)
IndexedBase
是一个很好的对象,当您需要类似向量的数量时可以使用:
>>> from sympy import *
>>> quant=IndexedBase('q')
>>> price=IndexedBase('p')
>>> i = var('i',integer=True)
>>> product(price[i]/quant[i],(i,1,2))
p[1]*p[2]/(q[1]*q[2])
你也可以区分 p[1]、q[1] 等等。这会帮助你更自然地提出问题吗?