通过代码求解联立方程

Nic*_*las 12 algorithm math equation

这似乎是一个非常简单和愚蠢的问题,但我发现的一切都太复杂了,我无法理解.

我有这两个非常基本的联立方程式:

X = 2x + 2z
Y = z - x
Run Code Online (Sandbox Code Playgroud)

鉴于我知道X和Y,我将如何找到x和z?手动完成它很容易,但我不知道如何在代码中完成.

Ale*_* C. 14

这似乎是一个非常简单和愚蠢的问题

一点也不.这是一个非常好的问题,不幸的是它是一个复杂的答案.我们来解决吧

a * x + b * y = u
c * x + d * y = v
Run Code Online (Sandbox Code Playgroud)

我坚持这里的2x2案例.更复杂的情况需要您使用库.

首先要注意的是Cramer公式不好用.计算行列式时

a * d - b * c
Run Code Online (Sandbox Code Playgroud)

一旦你有a * d ~ b * c,那么你有灾难性的取消.这种情况很典型,你必须防范它.

简单/稳定性之间的最佳权衡是部分转向.假设|a| > |c|.然后系统相当于

a * c/a * x + bc/a * y = uc/a
      c * x +    d * y = v 
Run Code Online (Sandbox Code Playgroud)

是的

cx + bc/a * y = uc/a
cx +       dy = v  
Run Code Online (Sandbox Code Playgroud)

现在,减去第一个到第二个的收益率

cx +       bc/a * y = uc/a
     (d - bc/a) * y = v - uc/a
Run Code Online (Sandbox Code Playgroud)

现在很容易解决:y = (v - uc/a) / (d - bc/a)x = (uc/a - bc/a * y) / c.计算d - bc/a比较稳定ad - bc,因为我们除以最大数字(它不是很明显,但它保持 - 用非常接近的系数进行计算,你会明白为什么它有效).

现在,如果|c| > |a|,您只需交换行并继续进行类似操作.

在代码中(请检查Python语法):

def solve(a, b, c, d, u, v):
    if abs(a) > abs(c):
         f = u * c / a
         g = b * c / a
         y = (v - f) / (d - g)
         return ((f - g * y) / c, y)
    else
         f = v * a / c
         g = d * a / c
         x = (u - f) / (b - g)
         return (x, (f - g * x) / a)
Run Code Online (Sandbox Code Playgroud)

您可以使用完全旋转(要求您交换x和y,以便第一个除法始终是最大系数),但这样写起来比较麻烦,而且2x2情况几乎不需要.

对于nxn情况,所有的旋转内容都封装在LU分解中,你应该使用一个库.