【问题标题】:Find analytic solution to this system of quadratic equations找到这个二次方程组的解析解
【发布时间】:2019-07-03 16:19:36
【问题描述】:

我已将我的问题简化为这个由 3 个二次方程组成的系统:

  (k1*x + k2*y + k4)^2 = k7      
  (k2*y + k3*z + k5)^2 = k8      
  (k3*z + k1*x + k6)^2 = k9

  (Solve for x, y, z, k1..k9 are constants)

我花了很长时间没有找到分析解决方案。谁能给我解决方案?

附:常数之间有一些关系可以简化问题。如果明天需要,我可以发布它们。

谢谢彼得

【问题讨论】:

  • 欢迎来到 StackOverflow。这是一个编程问题吗?如果您添加更多上下文,包括您迄今为止在该问题上所做的工作的证据以及您卡在哪里的声明,那么这个问题将更适合Mathematics Stack Exchange 站点。
  • 我投票结束这个问题,因为它不是关于实际的计算机编程,而是属于Mathematics Stack Exchange,一旦提问者添加了更多他自己的工作并解释了他在哪里卡住了。
  • 我同意它应该在 Math Exchange 上。但是,解决方案如下:取 k7、k8 和 k9 的平方根,以获得线性方程组。由于平方根可以是正数或负数,因此您需要求解所有 8 种符号组合(±sqrt(k7)、±sqrt(k8)、±sqrt(k9))的系统。如果您接受复系数,您将获得最多 8 个实值答案或恰好 8 个答案。

标签: math equation-solving


【解决方案1】:

纯数学但可通过编程解决,...首先使用 Gilles-Philippe Paillé 注释和单独的变量:

(k1*x + k2*y + k4)^2 = k7
(k2*y + k3*z + k5)^2 = k8
(k3*z + k1*x + k6)^2 = k9
-------------------------
k1*x + k2*y + k4 = sqrt(k7)
k2*y + k3*z + k5 = sqrt(k8)
k3*z + k1*x + k6 = sqrt(k9)
-------------------------
k1*x + k2*y = sqrt(k7) - k4
k2*y + k3*z = sqrt(k8) - k5
k3*z + k1*x = sqrt(k9) - k6
-------------------------
k1*x + k2*y +  0*z = sqrt(k7) - k4
 0*x + k2*y + k3*z = sqrt(k8) - k5
k1*x +  0*y + k3*z = sqrt(k9) - k6
-------------------------

现在可以改写成矩阵形式了

    | k1 k2  0 |
A = |  0 k2 k3 |
    | k1  0 k3 |

    | x |
B = | y |
    | z |

    | sqrt(k7) - k4 |
C = | sqrt(k8) - k5 |
    | sqrt(k9) - k6 |


             A * B =              C
Inverse(A) * A * B = Inverse(A) * C
                 B = Inverse(A) * C

所以它是 3x3 矩阵的简单逆矩阵。如果通过 zeor 填充将其扩展为 4x4 并将对角线加 1 您可以像这样使用 4x4 逆矩阵:

只需在 C++ 代码示例中查找 matrix_inv。你也可以在那里找到矩阵和向量的乘法matrix_mul_vector...

C++ 中的代码如下所示:

double A[16]=
 {
 k1, 0,k1, 0,
 k2,k2, 0, 0,
  0,k3,k3, 0,
  0, 0, 0, 1
 };
double B[4],C[4]=
 {
 sqrt(k7) - k4,
 sqrt(k8) - k5,
 sqrt(k9) - k6
 };

matrix_inv(A,A);
matrix_mul(B,A,C);

如果你的方程有解,现在B 应该保存你得到的x,y,z 值。剩下的只是添加符号组合作为系统丢失的sqrt...如果所有常量和变量都是非负数,您可以忘记这一点并直接使用结果而不尝试 8 种组合...

如果我没看错,组合就是这样完成的

double C[4]=
 {
 (+/-)sqrt(k7) - k4,
 (+/-)sqrt(k8) - k5,
 (+/-)sqrt(k9) - k6
 };

所以对于 8 个C 组合中的每一个组合计算结果......组合本身可以通过 for 循环使用迭代器变量的 3 个最低位来决定符号,例如:

matrix_inv(A,A);
for (int i=0;i<8;i++)
 {
 if ((i&1)==0) C[0]=+sqrt(k7)-k4; else C[0]=-sqrt(k7)-k4;
 if ((i&2)==0) C[1]=+sqrt(k8)-k5; else C[1]=-sqrt(k8)-k5;
 if ((i&4)==0) C[2]=+sqrt(k9)-k6; else C[2]=-sqrt(k9)-k6;
 matrix_mul(B,A,C);
 // here B holds the i-th solution
 }

如果是复杂的域,只需将double 更改为复杂的数据类型...

【讨论】:

  • 非常感谢,我没有取平方根,在求解 x 的一个方程时遇到了许多 ±sqrt 项。我没有看到您可以将 ± 排列作为最后一步。也感谢 Gilles-Philippe Paillé。
  • @PeterPohl 这不是最后一步,因为您在组合 +/- 之后从左侧乘以 A 的逆矩阵,但我明白了你的意思:)
  • @Spektre 感谢您的详细回答!我注意到Inverse(A) * B = Inverse(A) * C 行中有一个小错误。应该是Inverse(A) * A * B = Inverse(A) * C。另外,我认为使用 4x4 倒数对于这项任务来说有点过分了。我理解是重用现有代码,但是性能会受到很大影响。
  • @Gilles-PhilippePaillé 不错,我修好了。是的,4x4 速度较慢,但​​没那么快。我在某个地方也有 3x3,但懒得搜索它,而且 4x4 已经发布了。顺便说一句,我将这个full pseudo inverse matrix 用于正交矩阵,这要快得多,但在这种情况下不可用……因为不授予正交正态性。这是一般情况下的GEM and Determinant based inverses,我也有N维矩阵/向量模板...
  • @Gilles-PhilippePaillé 顺便说一句,最后一个模板是作为与此 QA 相关的我的 4D 引擎的核心数学编写的:how should i handle (morphing) 4D objects in opengl?
猜你喜欢
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多