bool least_solve(double * const A,//m*n double * const B,//m*z double *X,//n*z unknown double *AA,//A'A n*n temp double *TAA,//(A'A)^1 n*n temp double *AB,//A'B n*z temp int m,int n,int z) { //A'A mata(A,AA,m,n); //A'B matb(A,B,AB,m,n,z); //(A'A)^-1 if(!gauss_elim(AA,TAA,n)) { return false; } //X mul(TAA,AB,X,n,n,z); return true; }
void example(void) { #define M 4 static const size_t n = M; num equation[M * (M + 1)] = { 12, 8, 1, 1, 69, 10, 13, 10, 2, 14, 15, 9, 2, 7, 194, 5, 10, 13, 14, 193 }; gauss_elim(n, equation); print_solutions(n, equation); }
/******************************************* * invert(matrix, size) * * -- * * Calculates the inverse of matrix using * * Partial-Pivoting Gaussian Elimination * *******************************************/ double *invert(double *m, int n) { int i,j,k; int *pivot = (int *) malloc(sizeof(int)*n); double *identity = (double *) malloc(sizeof(double) * n * n); double *inverse = (double *) malloc(sizeof(double) * n * n); double *m_prime = (double *) malloc(sizeof(double) * n * n); //setup identity matrix and pivot //copy m into m_prime for (i = 0; i < n; ++i) { identity[i*(n+1)] = 1.0; m_prime[i*(n+1)] = m[i*(n+1)]; pivot[i] = i; for (j = i+1; j < n; ++j) { identity[(j*n)+i] = identity[(i*n)+j] = 0.0; m_prime[(i*n)+j] = m[(i*n)+j]; m_prime[(j*n)+i] = m[(j*n)+i]; } } gauss_elim(m_prime, pivot, n); for (i = 0; i < n-1; ++i) { for (j = i+1; j < n; ++j) { for (k = 0; k < n; ++k) { identity[(pivot[j]*n)+k] -= m_prime[(pivot[j]*n)+i] * identity[(pivot[i]*n)+k]; } } } for (i = 0; i < n; ++i) { inverse[((n-1)*n)+i] = identity[(pivot[n-1]*n)+i] / m_prime[(pivot[n-1]*n)+n-1]; for (j = n-2; j >= 0; j = j-1) { inverse[(j*n)+i] = identity[(pivot[j]*n)+i]; for (k = j+1; k < n; ++k) { inverse[(j*n)+i] -= m_prime[(pivot[j]*n)+k] * inverse[(k*n)+i]; } inverse[(j*n)+i] /= m_prime[(pivot[j]*n)+j]; } } free_array((void *)pivot); free_array((void *)identity); free_array((void *)m_prime); return inverse; }
/* for compatibilty with Treeki's code */ int solve(const num *equation, num *solutions, int n) { const size_t eqlen = n * (n + 1); const size_t size = (eqlen + n * 2) * sizeof(*equation); size_t i; int is_unique = 1; num *buf = (num *)malloc(size); num *equation2 = buf; num *solutions2 = buf + eqlen; memcpy(equation2, equation, size); /* do the magic */ gauss_elim((size_t)n, equation2); if (get_solutions(solutions2, n, equation2) == 1) { fprintf(stderr, "warning: solution does not exist\n"); is_unique = 0; } for (i = 0; i != n; ++i) { const num numer = solutions2[i * 2]; const num denom = solutions2[i * 2 + 1]; if (denom) { solutions[i] = numer / denom; continue; } solutions[i] = 0; is_unique = 0; if (numer) { continue; } fprintf(stderr, "warning: multiple solutions " "exist for variable #%zu\n", i); } free(buf); return is_unique; }