我有一个系数列表,它定义了我想要解决的方程组。系数列表中的第一项始终为1,解决方案中的第一个变量也假定为1.
如果
coeffs = [1,2,3,4]
然后我想解决的方程组是coeffs
与变量[1, x[3], x[2], x[1]]
的循环卷积。通过这种方式,我们得到了
1*1 + 2*x[3] + 3*x[2] + 4*x[1] = 0
1*x[3] + 2*x[2] + 3*x[1] + 4*1 = 0
1*x[2] + 2*x[1] + 3*1 + 4*x[3] = 0
1*x[1] + 2*1 + 3*x[3] + 4*x[2] = 0
鉴于coeffs
,如何在numpy中设置这个方程组,以便我可以求解x
?在实际情况中,coeffs
将有数百个长度。
答案 0 :(得分:4)
>>> import numpy as np
>>> coeffs = [1, 2, 3, 4]
>>> N = len(coeffs)
>>> a = np.tile(coeffs, (N, 1))
>>> a
array([[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]])
>>> for i in xrange(1, N):
... a[i] = np.roll(a[i], i)
...
>>> a
array([[1, 2, 3, 4],
[4, 1, 2, 3],
[3, 4, 1, 2],
[2, 3, 4, 1]])
>>>
答案 1 :(得分:1)
扩展simleo的答案,你可以使用numpy的速度(对于更大的数据)而不是使用python循环来生成它:
>>> coeffs = [1, 2, 3, 4]
>>> N = len(coeffs)
# Create coeffs matrix
>>> coeffs = np.tile(coeffs, (N, 1))
# Create grid of indexes
>>> rows, column_indices = np.ogrid[:N, :N]
# Create shift vector (shift each row by its index)
>>> shift = np.arange(N)
# Create shifted column indexes for each row
>>> column_indices = column_indices - shift[:, np.newaxis]
# Reorder
>>> coeffs = coeffs[rows, column_indices]
>>> coeffs
array([[1, 2, 3, 4],
[4, 1, 2, 3],
[3, 4, 1, 2],
[2, 3, 4, 1]])
考虑到coeffs = [1 2 3 4] = [a b c d]
并考虑您的变量x = [1 x3 x2 x1]
,您可以使用x3 * b + x2 * c + x1 *d = -a
形式转换问题(对于您的第一种情况):
>>> a = coeffs[:, 1:]
>>> b = -coeffs[:, 0]
>>> np.linalg.lstsq(a,b)[0]
array([-0.47058824, 0.01960784, -0.47058824])
答案 2 :(得分:1)
>>> import numpy as np
>>> a = [1,20,300,4000]
>>> b = np.arr[a[n:]+a[:n] for n in range(4)]
>>> sol = np.linalg.solve(b[1:,1:],-b[1:,0])
>>> print "Using last N equations the solution is:", [1.0]+list(sol)
Using last N equations the solution is: [1.0, -0.11111111111111105, -0.11111111111111113, -1.2222222222222223]
>>> print "Substituting in first equation gives:", a[0]+sol.dot(a[1:]), "= 0"
Substituting in first equation gives: -4.44444444444 = 0
>>>
此时你的程序可以决定残差是否过多或解决方案是否足够好。
如果解决方案足够好,可能您希望使用
最小化错误>>> sol = numpy.linalg.lstsq(b[:,1:],-b[:,0])
请注意,解决方案元组的其他元素可以深入了解最小二乘解的性质,
>>> print np.linspace.lstsq.__doc__
了解整个故事。
关于效率,当你要解决一个大系统(NxN,差不多......)的方程时,你不介意用一个纯粹的numpy解决方案来构建系数矩阵的0.2s。
答案 3 :(得分:1)
您可以使用A的pseudoinverse矩阵表示为A + 。当且仅当AA + b = b且所有解都由下式给出时,存在一种解决方案 x = A + b +(I - A + A)* u
import numpy as np
def solvep(coeffs, tol=1e-10):
a = np.array([np.roll(coeffs, i) for i, _ in enumerate(coeffs)])
A, b = a[:, 1:], -a[:, 0]
x = np.linalg.pinv(A).dot(b)
z = np.abs(A.dot(x) - b)
if np.all(z < tol):
return x
else:
print "There is no solution, max error = {}".format(z.max())
return None
示例:
>>> solvep([1,2,3,4])
There is no solution, max error = 2.1568627451
>>> solvep([1,1,1])
array([-0.33333333, -0.33333333, -0.33333333])
答案 4 :(得分:0)
使用numpy linalg.solve
来自http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.solve.html
的示例Solve the system of equations 3 * x0 + x1 = 9 and x0 + 2 * x1 = 8:
>>>
>>> a = np.array([[3,1], [1,2]])
>>> b = np.array([9,8])
>>> x = np.linalg.solve(a, b)
>>> x
array([ 2., 3.])