查找该二次方程组的解析解

时间:2019-07-03 16:19:36

标签: math equation-solving

我已将问题简化为由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)

我花了很多时间没有找到分析解决方案。有人可以给我解决方案吗?

P.S。常数之间存在某些关系,可以简化问题。如果需要的话,我可以寄给他们。

彼得(Thx Peter)

1 个答案:

答案 0 :(得分:1)

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

(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更改为复杂数据类型...