当矩阵的条件数较大时,Python中是否有精确求解线性方程组的方法?

2024-04-27 05:03:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python求解一个方程组,但结果并不像预期的那样。我用的是水蟒分布。Spyder 4.1.5和Python 3.8

应用是机器人末端执行器运动的轨迹生成。我试图建立一个计时定律,它规定在给定的时间‘t’:位置是q(t),速度是q_点(t),加速度是q_点(t)

构造定时律的方法是将3个五阶多项式函数的段拼接在一起。在多项式函数的交点处,一阶导数和二阶导数具有相同的值。我已经成功地创建了前两个部分,使用了与下图类似的理论和代码,但第三个部分很难实现

其思想是找到满足用户定义的初始和最终条件的五阶多项式的6个系数值。方程式如下所示:

qi = x_0 + x_1*t_i + x_2*t_i^2 + x_3*t_i^3 + x_4*t_i^4 + x_5*t_i^5
qi_dot = 0 + x_1+2*x_2*t_i + 3*x_3*t_i^2 + 4*x_4*t_i^3 + 5*x_5*t_i^4
qi_dot_dot = 0 + 0 + 2*x_2 + 6*x_3*t_i + 12*x_4*t_i^2 + 20*x_5*t_i^3
qf = x_0 + x_1*t_f + x_2*t_f^2 + x_3*t_f^3 + x_4*t_f^4 + x_5*t_f^5
qf_dot = 0 + x_1 + 2*x_2*t_f + 3*x_3*t_f^2 + 4*x_4*t_f^3 + 5*x_5*t_f^4
qf_dot_dot = 0 + 0 + 2*x_2 + 6*x_3*t_f + 12*x_4*t_f^2 + 20*x_5*t_f^3

目标是在给定以下初始和最终条件的情况下求解所有六个x:

t_i = 0.31            #initial time in seconds
t_f = 0.38            #final time in seconds
q_i =  0.921          #initial position in meters
q_i_dot = 2           #initial velocity in m/s
q_i_dot_dot = -40     #initial acceleration in m/s**2
q_f = 0.971           #final position in meters
q_f_dot = 0           #final velocity in m/s
q_f_dot_dot = 0       #final acceleration in m/s**2 

问题的形式为Ax=b,其中“A”是矩阵,“x”是要求解的系数向量,“b”是给定条件的向量

以下是Python代码:

#X3 are constants of segment 3
import numpy as np

t3_i = 0.31            #initial time in seconds
t3_f = 0.38            #final time in seconds
q3_i =  0.921          #initial position in meters
q3_i_dot = 2           #inital velocity in m/s
q3_i_dot_dot = -40     #inital acceleration in m/s**2
q3_f = 0.971           #final position in meters
q3_f_dot = 0           #final velocity in m/s
q3_f_dot_dot = 0       #final acceleration in m/s**2

m3_list = [[1.0, t3_i, t3_i**2, t3_i**3  , t3_i**4    ,t3_i**5],   \
           [0.0, 1.0 , 2*t3_i , 3*t3_i**2, 4*t3_i**3  ,5*t3_i**4], \
           [0.0, 0.0 , 2.0    , 6*t3_i   , 12*t3_i**2 ,20*t3_i**3],\
           [1.0, t3_f, t3_f**2, t3_f**3  , t3_f**4    ,t3_f**5],   \
           [0.0, 1.0 , 2*t3_f , 3*t3_f**2, 4*t3_f**3  ,5*t3_f**4], \
           [0.0, 0.0 , 2.0    , 6*t3_f   , 12*t3_f**2 ,20*t3_f**3]]
A3 = np.array(m3_list)
B3 = np.array([q3_i,q3_i_dot,q3_i_dot_dot,q3_f,q3_f_dot,q3_f_dot_dot])
X3 = np.linalg.inv(A3).dot(B3)
print(X3)

以下是从控制台复制和粘贴的结果矩阵“A”:

array([[1.        , 0.31      , 0.0961    , 0.029791  , 0.00923521,0.00286292],
       [0.        , 1.        , 0.62      , 0.2883    , 0.119164  ,0.04617605],
       [0.        , 0.        , 2.        , 1.86      , 1.1532    ,0.59582   ],
       [1.        , 0.38      , 0.1444    , 0.054872  , 0.02085136,0.00792352],
       [0.        , 1.        , 0.76      , 0.4332    , 0.219488  ,0.1042568 ],
       [0.        , 0.        , 2.        , 2.28      , 1.7328    ,1.09744   ]])

以下是从控制台复制和粘贴的结果向量“b”:

B3 = array([  0.921,   2.   , -40.   ,   0.971,   0.   ,   0.   ])

以下是从控制台复制和粘贴的“x”的当前结果值。但是,它们不会生成所需的多项式。关于我认为正确(或至少非常可接受)的结果,请参阅下文:

X3 = array([    69.08188618,  -1005.89416312,   5829.44011406, -16638.42446549,23454.5129998 , -13089.78401814])

注:np.linalg.cond(A3)产生的矩阵条件数为57845218.0…这是一个大值

到目前为止,无论使用Python编码时使用何种方法,结果都是相同的(或至少非常相似)。到目前为止,我已经尝试:

X3 = np.linalg.inv(A3).dot(B3)

X3 = np.linalg.solve(A3,B3)

X3 = np.linalg.lstsq(A3,B3)

from scipy.linalg import lu_factor, lu_solve
lu, piv = lu_factor(A3)
X3 = lu_solve((lu, piv), B3)

import mpmath
A3 = mpmath.matrix(m3_list)
B3 = mpmath.matrix([q3_i,q3_i_dot,q3_i_dot_dot,q3_f,q3_f_dot,q3_f_dot_dot])
Ainv = A**-1
X3 = Ainv*B3

编写的代码中可能存在错误。也可能存在逻辑错误,即我对数学的基本理解错误。我已经研究了其他几个关于堆栈溢出的类似问题和回答,并做了大量的一般互联网研究以找到解决方案,但我似乎找不到哪里出了问题

我还手动将A和b的值输入到该站点上的解算器:matrixcalc.org

它产生了x的以下值:

x0 = 20903843842657/3000260067000 = 6.967343955472177
x1 = -470666045663/5000433445 = -94.12504952618163
x2 = 493930536760/1000086689 = 493.8877221272565
x3 = -9731957378000/9000780201 = -1081.2348663862233
x4 = 2559057700000/3000260067 = 852.945292358884
x5 = -1486000000/3000260067 = -0.4952903971040988

有趣的是,这些系数值实际上产生了一个多项式,它符合预期的给定条件。更有趣的是,使用同一个站点,我在不同的日期再次手动输入值,得到不同的结果,我永远无法重现原始结果。还要注意,输出对输入的任何舍入都非常敏感

非常感谢Python中用于解决这些方程的任何建议方法/修复!谢谢你抽出时间


Tags: intimenp条件arraydota3initial