#include <stdio.h>
#include <math.h>
const int terms[22][4] = {
{+1, 0, 0, 2}, //+a2*a2*c2 +
{-1, 0, 1, 2}, //-a2*b2*c2 +
{-1, 0, 1, 3}, //-a2*b2*d2 +
{+1, 0, 1, 4}, //+a2*b2*e2 +
{+1, 0, 2, 2}, //+a2*c2*c2 +
{-1, 0, 2, 3}, //-a2*c2*d2 +
{-1, 0, 2, 4}, //-a2*c2*e2 +
{-1, 0, 2, 5}, //-a2*c2*f2 +
{+1, 0, 3, 5}, //+a2*d2*f2 +
{-1, 0, 4, 5}, //-a2*e2*f2 +
{+1, 1, 1, 3}, //+b2*b2*d2 +
{-1, 1, 2, 3}, //-b2*c2*d2 +
{+1, 1, 2, 5}, //+b2*c2*f2 +
{+1, 1, 3, 3}, //+b2*d2*d2 +
{-1, 1, 3, 4}, //-b2*d2*e2 +
{-1, 1, 3, 5}, //-b2*d2*f2 +
{-1, 1, 4, 5}, //-b2*e2*f2 +
{+1, 2, 3, 4}, //+c2*d2*e2 +
{-1, 2, 4, 5}, //-c2*e2*f2 +
{-1, 3, 4, 5}, //-d2*e2*f2 +
{+1, 4, 4, 5}, //+e2*e2*f2
{+1, 4, 5, 5}, //+e2*f2*f2
};
void solveDet(int unknownIdx, double knownValues[5], int *nSolutions, double solutions[4]){
// all variables squared, with zero for the unknown one
double allSqrValues[6];
for(int i = 0; i < 6; i++){
allSqrValues[i] = i < unknownIdx ? knownValues[i] :
i == unknownIdx ? 1 : knownValues[i-1];
allSqrValues[i] *= allSqrValues[i];
}
double a = 0, b = 0, c = 0; // coeffs of second degree equation
for(int iTerm = 0; iTerm < 22; iTerm++){
const int* term = terms[iTerm];
double term_value = term[0] * allSqrValues[term[1]] *
allSqrValues[term[2]] * allSqrValues[term[3]];
// the number of occurrences of the unknown variable in the term
int nOccurrences = (term[1] == unknownIdx) +
(term[2] == unknownIdx) + (term[3] == unknownIdx);
if(nOccurrences == 2){ //x^2
a += term_value;
}
else if(nOccurrences == 1){ //x^1
b += term_value;
}
else{ //x^0 - no x
c += term_value;
}
}
// 2nd degree equation - this should be refined to account
// for possible no solution or two positive solutions
double sqrtDelta = sqrt(b*b - 4*a*c),
x1 = (-b - sqrtDelta)/2/a,
x2 = (-b + sqrtDelta)/2/a;
// return ± the square root of the positive solutions - 0, 2, or 4 solutions
*nSolutions = 0;
if(x1 >= 0){
solutions[(*nSolutions)++] = -sqrt(x1);
solutions[(*nSolutions)++] = sqrt(x1);
}
if(x2 >= 0){
solutions[(*nSolutions)++] = -sqrt(x2);
solutions[(*nSolutions)++] = sqrt(x2);
}
// // verify det = 0
// allSqrValues[unknownIdx] = x2;
// double det = 0;
// for(int iTerm = 0; iTerm < 22; iTerm++){
// const int *term = terms[iTerm];
// //printf("%2d %d %d %d\n", term[0], term[1], term[2], term[3]);
// det += term[0] * allSqrValues[term[1]] *
// allSqrValues[term[2]] * allSqrValues[term[3]];
// }
// printf("det=%g\n", det);
};
int main(){
//a: 2.357086
//b: 2.017018
//c: 2.681643
//d: <unknown>
//e: 2.900140
//f: 3.261168
double knownValues[5] = {2.357086, 2.017018,
2.681643, 2.900140, 3.261168};
int unknownIndex = 3;
int nSolutions;
double solutions[4];
solveDet(unknownIndex, knownValues, &nSolutions, solutions);
if(nSolutions == 0){
printf("No solutions\n");
}
else{
printf("Solutions: ");
for(int iSol = 0; iSol < nSolutions; iSol++){
printf("%g ", solutions[iSol]);
}
printf("\n");
}
return 0;
}