找到这个二次方程组的解析解
Find analytic solution to this system of quadratic equations
我已将我的问题简化为这个由 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。常数之间存在一些关系可以简化问题。如果明天需要,我可以 post 他们。
谢谢彼得
纯数学但可以通过编程解决,...首先使用 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
更改为复杂的 data-type...
我已将我的问题简化为这个由 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。常数之间存在一些关系可以简化问题。如果明天需要,我可以 post 他们。
谢谢彼得
纯数学但可以通过编程解决,...首先使用 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
更改为复杂的 data-type...