如何在python中设置方程式

时间:2014-11-25 21:26:53

标签: python math numpy

我有一个系数列表,它定义了我想要解决的方程组。系数列表中的第一项始终为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将有数百个长度。

5 个答案:

答案 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.])