我想使用linalg
以矩阵的形式解决一些系统,但是得到的解决方案应该总和为1.例如,假设有3个未知数,x,y,z。解决系统后,它们的值应总计为1,如.3,.5,.2。谁能告诉我怎么做到这一点?
目前,我使用result = linalg.solve(A, B)
之类的内容,其中A
和B
是矩阵。但是这不会返回[0, 1]
范围内的解决方案。
答案 0 :(得分:8)
linalg.solve
用于计算"精确"解决方案,x
, 确定的,即满秩,线性矩阵方程ax = b
。
被 线性,最多可以有一个解决方案。如果您找到的解决方案没有 总计为1,然后添加额外约束将不会产生解决方案。
但是,你可以使用
scipy.optimize.minimize
找到最小化数量的约束平面上的点
||Ax-b||^2
:
def f(x):
y = np.dot(A, x) - b
return np.dot(y, y)
cons = ({'type': 'eq', 'fun': lambda x: x.sum() - 1})
res = optimize.minimize(f, [0, 0, 0], method='SLSQP', constraints=cons,
options={'disp': False})
例如,给定这个方程组
import numpy as np
import numpy.linalg as LA
import scipy.optimize as optimize
A = np.array([[1, 3, 4], [5, 6, 9], [1, 2, 3]])
b = np.array([1, 2, 1])
x = LA.solve(A, b)
解决方案不等于1:
print(x)
# [-0.5 -1.5 1.5]
但您可以尝试最小化f
:
def f(x):
y = np.dot(A, x) - b
return np.dot(y, y)
受约束cons
:
cons = ({'type': 'eq', 'fun': lambda x: x.sum() - 1})
res = optimize.minimize(f, [0, 0, 0], method='SLSQP', constraints=cons,
options={'disp': False})
xbest = res['x']
# array([ 0.30000717, 1.89998823, -1.1999954 ])
xbest
总和为1:
print(xbest.sum())
1
差异A·xbest - b
是:
print(np.dot(A, xbest) - b)
# [ 0.19999026 0.10000663 -0.50000257]
和差异的平方和(也可以计算为f(xbest)
)是:
print(res['fun'])
0.30000000014542572
在满足约束条件时,x的其他任何值都不会使此数量最小化。
答案 1 :(得分:0)
你可以在A中添加由1组成的行,然后在B中添加一行。之后使用 result = linalg.lstsq(A,B)[0]
或者您可以将A行中的一行替换为由1组成的行,也将B中的值替换为同一行中的一行。然后用 result = linalg.solve(A,B)
答案 2 :(得分:0)
作为替代方案,您可以将numpy.linalg.lstsq
与新行结合使用到A
矩阵:[1, 1, 1]
和B
矩阵[1]
。
import numpy as np
A = np.array([[1, 0, 1],
[0, 1, 1],
[1, 1, 0],
[1, 1, 1]]
B = np.array([[0.5, 0.7, 0.8, 1.0]]).T
x, _, _, _ = np.linalg.lstsq(A, B)
这将x
设为[[0.3], [0.5], [0.2]]
。