这似乎是一个令人难以置信的简单而愚蠢的问题,但是我发现的所有问题都让我难以理解。
我有两个非常基本的联立方程:
X = 2x + 2z Y = z - x
既然我既知道X又知道Y,那么我将如何查找x和z?手工完成非常容易,但是我不知道如何在代码中完成。
这似乎是一个非常简单而愚蠢的问题
一点也不。这是一个很好的问题,不幸的是它有一个复杂的答案。让我们解决
a * x + b * y = u c * x + d * y = v
我在这里坚持2x2的情况。更复杂的情况将要求您使用库。
首先要注意的是Cramer公式不好用。计算行列式时
a * d - b * c
一旦您拥有了a * d ~ b * c,那么您将遭受灾难性的取消。这种情况很典型,您 必须 警惕。
a * d ~ b * c
简单性/稳定性之间的最佳权衡是部分枢纽。假设`|a|
|c|`。那么系统相当于
a * c/a * x + bc/a * y = uc/a c * x + d * y = v
这是
cx + bc/a * y = uc/a cx + dy = v
现在,将第一个收益减去第二个收益
cx + bc/a * y = uc/a (d - bc/a) * y = v - uc/a
现在可以直接解决:y = (v - uc/a) / (d - bc/a)和x = (uc/a - bc/a * y) / c。计算d - bc/a比稳定ad - bc,因为我们除以最大数(不是很明显,但是它成立了-用非常接近的系数进行计算,您会明白为什么会这样)。
y = (v - uc/a) / (d - bc/a)
x = (uc/a - bc/a * y) / c
d - bc/a
ad - bc
现在,如果为|c| > |a|,则只需交换行并以类似方式进行。
|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)
您可以使用完全旋转(需要交换x和y,以便始终以最大的系数进行第一除法),但这写起来比较麻烦,而且对于2x2的情况几乎不需要。
对于nxn情况,所有关键数据都封装在LU分解中,为此您应该使用一个库。