예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
/*******************************************
 * 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;
}
예제 #4
0
/* 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;
}