чистая математика, но разрешимая программированием, ... сначала используйте комментарий Жиля-Филиппа Пайе и отдельные переменные:
(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
Так что это простая обратная матрица 3х3.Если вы расширите его до 4x4, добавив нулевое заполнение и добавив 1 к диагонали, вы можете использовать обратную матрицу 4x4 следующим образом:
Просто найдите matrix_inv
в примере кода C ++.Там вы также можете найти умножение матрицы и вектора 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
комбинаций вычисляем результат ... Сами комбинации могут быть сделаны дляВыполните цикл, используя 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
со сложным типом данных ...