我希望得到一些概念上的帮助,关于如何解决一个线性方程组与罚函数。示例代码在底部。
假设我试着拟合这个方程:
Ie=IaX+IbY+IcZ
其中Ie,Ia,Ib,Ic是常数,X,Y,Z是变量,我可以很容易地用scipy,least_squares来解这个方程组,但是我想用两个约束来约束这个系统。
1. X+Y+Z=1
2. X,Y,Z > 0 and X,Y,Z < 1
为了做到这一点,我随后修改了上述函数。
Ie-Ic=X(Ia-Ic)+Y(Ib-Ic) where X+Y+Z=1 I solved for Z
therefore
Ax=B where A=[Ia-Ic,Ib-Ic] and B=[Ie-Ic] given bounds (0,1)
这解决了X,Y,Z > 0 and X,Y,Z < 1
的第二个标准,但没有解决第一个问题。要解决第一个问题,需要做一个额外的约束,其中X+Y<1
,我不太知道如何做。
所以我假设最小二乘有一些内置的惩罚函数的界限。
chi^2=||A-Bx||^2+P
where P is the conditions, if X,Y,Z>0 then P = 10000
thus, giving high chi squared values and thus setting the constraints
我不知道如何添加进一步的条件,所以if X+Y<1 then P=10000
或者类似的东西。
简而言之,least_squares允许您设置单个值的边界,但我想设置一些进一步的约束,但我不太知道如何使用least_squares来实现这一点。我在scipy.minimize中看到了其他不等式约束选项,但我不太知道如何将其应用于格式为Ax=B的线性方程组。
作为一个示例代码,假设我已经完成了计算,得到了常数矩阵A和向量B。我使用最小二乘法,得到了X和Y的值,并且可以计算Z,因为X+Y+Z=1。这里的问题是在我的最小化中,我没有设置X+Y〈1的约束,所以在某些情况下,你可以得到X+Y〉1的值。所以我想找到一个方法,除了单个变量的边界约束之外,我还可以设置附加约束:
Ax=np.array([[1,2],[2,4],[3,4]])
B=np.array([0,1,2])
solution=lsq_linear(Ax,B,lsq_solver='lsmr',bounds=(0,1))
X=solution.x[0]
Y=solution.x[1]
Z=1-sum(solution.x)
如果最小化是这里的解决方案,你能告诉我如何设置它给上面的矩阵A和数组B?
任何建议,提示,或帮助我在正确的方向是非常感谢!
编辑:所以我在这里找到了类似的东西:Minimizing Least Squares with Algebraic Constraints and Bounds所以我想我应该把它应用到我的案例中,但我不认为我已经能够正确地应用它。
Ax=np.array([[1,2],[2,4],[3,4]])
B=np.array([0,1,2])
def fun(x,a1,a2,y):
fun_output=x[0]*a1+x[1]*a2
return np.sum((fun_output-y)**2)
cons = [{"type": "eq", "fun": lambda x: x[0] + x[1] - 1}]
bnds = [(0, 1), (0, 1)]
xinit = np.array([1, 1])
solution=minimize(fun,args=(Ax[:,0],Ax[:,1], B), x0=xinit, bounds=bnds, constraints=cons)
solution_2=lsq_linear(Ax,B,bounds=(0,1))
print(solution.x)
print(solution_2.x)
问题是,这个函数的输出与lsq_linear不同,无论输入数组是什么,我几乎总是得到一个非常接近于零的Z值。我不知道我是否正确地设置/理解了这个函数。
1条答案
按热度按时间blmhpbnm1#
你最初的猜测
xinit
是不可行的,也不满足你的约束。我认为,直接将初始问题作为约束非线性优化问题(NLP)来求解,而不是重写它是更简单的方法。假设您有所有的数据点
Ia, Ib, Ic
和Ie
(您没有提供所有的数据点),您可以使用下面的代码片段,它与我在您的问题中的链接答案是相同的。