Beispiel #1
0
void reduce_row_vectors(matrix<T>& M)
{
  bool reiterate = true;
  while (reiterate)
  {
    reiterate = false;
    for (int v=0; v<M.rows; ++v)
      for (int w=0; w<M.rows; ++w)
        if (v!=w)
        {
          bool covered = true;
          for (int i=0; i<M.columns; ++i)
            if (M.data[v][i] > M.data[w][i])
            {
              covered = false;
              break;
            }
          if (covered)
          {
            add_multiple_row(M, w, v, -1);
            reiterate = true;
          }
        }
  }
}
// ****************************************************************************
// Calculates the inverse of N x N matrix A and stores it in matrix Ainv. 
// It is assumed that the memory required for this has already been allocated. 
// The data in matrix A is not destroyed, unless the same address is supplied for Ainv.
// (This case should be successfully handled also.)
// The function returns -1 if the matrix is not invertible.
// ****************************************************************************
int matrix_invert(double *A, double *Ainv, long int N)
{
	double *backup = malloc_1d_array_double(N*N);
	double pivot, factor;
	long int pivot_row;

	if (A==NULL || Ainv==NULL || N<1) quit_error((char*)"Bad input data to matrix_invert");
	
	// Backup the A matrix so that manipulations can be performed here
	// without damaging the original matrix.
	for (long int row=0; row<N; row++)
		for (long int col=0; col<N; col++)
			backup[row*N+col]=A[row*N+col];
	
	// First, fill Ainv with the identity matrix
	for (long int row=0; row<N; row++) {
		for (long int col=0; col<N; col++) {
			if (row==col) Ainv[row*N+col]=1;
			else Ainv[row*N+col]=0;
		}
	}

	// Calculate the inverse using Gauss-Jordan elimination
	for (long int col=0; col<N; col++) {
		//display_augmented(backup, Ainv, N);
		pivot_row=-1;
		pivot=0.0;
		for (long int row=col; row<N; row++) {
			if (fabs(backup[row*N+col])>fabs(pivot)) {
				pivot_row=row;
				pivot=backup[row*N+col];
			}
		}
		//printf("Pivot: %lf\n\n", pivot);

		if (pivot_row<0 || pivot_row>=N || fabs(pivot)<DBL_EPSILON) {
			free_1d_array_double(backup);
			return -1;
		} else {
			swap_row(col, pivot_row, backup, Ainv, N);
			multiply_row(col, 1.0/pivot, backup, Ainv, N);
			for (long int elim_row=0; elim_row<N; elim_row++) {
				if (elim_row!=col) {
					factor=-backup[elim_row*N+col];
					add_multiple_row(factor, col, elim_row, backup, Ainv, N);
				}
			}
		}
	}
	free_1d_array_double(backup);
	
	return 0;
}