// matrix inversion // the result is put in Y void Camera::MatrixInversion(float **A, int order, float **Y) { // get the determinant of a double det = 1.0/CalcDeterminant(A,order); // memory allocation float *temp = new float[(order-1)*(order-1)]; float **minor = new float*[order-1]; for(int i=0;i<order-1;i++) minor[i] = temp+(i*(order-1)); for(int j=0;j<order;j++) { for(int i=0;i<order;i++) { // get the co-factor (matrix) of A(j,i) GetMinor(A,minor,j,i,order); Y[i][j] = det*CalcDeterminant(minor,order-1); if( (i+j)%2 == 1) Y[i][j] = -Y[i][j]; } } // release memory //delete [] minor[0]; delete [] temp; delete [] minor; }
// Calculate the determinant recursively. double Camera::CalcDeterminant( float **mat, int order) { // order must be >= 0 // stop the recursion when matrix is a single element if( order == 1 ) return mat[0][0]; // the determinant value float det = 0; // allocate the cofactor matrix float **minor; minor = new float*[order-1]; for(int i=0;i<order-1;i++) minor[i] = new float[order-1]; for(int i = 0; i < order; i++ ) { // get minor of element (0,i) GetMinor( mat, minor, 0, i , order); // the recusion is here! det += (i%2==1?-1.0:1.0) * mat[0][i] * CalcDeterminant(minor,order-1); //det += pow( -1.0, i ) * mat[0][i] * CalcDeterminant( minor,order-1 ); } // release memory for(int i=0;i<order-1;i++) delete [] minor[i]; delete [] minor; return det; }
// Calculate the determinant recursively. double CalcDeterminant( float **mat, int s) { //Señal que detiene la recursividad if( s == 1 ) return mat[0][0]; float det = 0; // Generamos espacio temporal para almacenar la menor float **minor; minor = new float*[s-1]; for(int i=0;i<s-1;i++) minor[i] = new float[s-1]; //Siempre obtiene la determinante usando la primer fila for(int i = 0; i < s; i++ ) { GetMinor( mat, minor, 0, i , s); //Sobreescribe la matriz menor //Aqui obtenemos el cofactor, multiplicamos por el elemento en la posicion i y ahora por la determinante det += (i%2==1?-1.0:1.0) * mat[0][i] * CalcDeterminant(minor,s-1); } // Quitamos el espacio usado for(int i=0;i<s-1;i++) delete [] minor[i]; delete [] minor; return det; }
int main(int argc, const char * argv[]) { int size=3; //Definir tamaño float **matrix = new float*[size]; for(int i =0;i<size;++i) matrix[i]=new float[size]; matrix[0][0]=0; matrix[0][1]=2; matrix[0][2]=0; matrix[1][0]=2; matrix[1][1]=1; matrix[1][2]=1; matrix[2][0]=2; matrix[2][1]=1; matrix[2][2]=2; //LLENAMOS LA MATRIX COMO EL EJEMPLO DEL PDF std::cout<<CalcDeterminant(matrix, size)<<"\n"; //PRINTEAMOS DETERMINANTE float **inv=MatrixInversion(matrix, size); //El apuntador Inv se llena aqui std::cout<<"\nOriginal\n"; //PRINTEAR MATRIX for(int i =0;i<size;++i) { for(int j =0;j<size;++j) std::cout<<matrix[i][j]<<"\t"; std::cout<<"\n"; } //PRINTEAR MATRIX INV std::cout<<"\nInversa\n"; for(int i =0;i<size;++i) { for(int j =0;j<size;++j) std::cout<<inv[i][j]<<"\t"; std::cout<<"\n"; } return 0; }
void MatrixInversion(float **A, int order, float **Y) /*< matrix inversion main interface >*/ { /* calculate determinant */ double det = 1.0/CalcDeterminant(A,order); /* allocate memory for co-factor matrix */ float **minor = sf_floatalloc2(order-1,order-1); for(int j=0; j < order; j++) { for(int i=0; i < order; i++) { /* get the co-factor matrix of A(j,i) */ GetMinor(A,minor,j,i,order); Y[i][j] = det*CalcDeterminant(minor,order-1); if((i+j)%2 == 1) Y[i][j] = -Y[i][j]; } } }
//逆行列を計算する Matrix Matrix::CalcInverseMatrix() { if (this->xSize != this->ySize) //正方行列ではない場合 return Matrix(0, 0); double Determinant = CalcDeterminant(); //行列式の値を計算する if (Determinant == 0.0) //行列式が0の場合 return Matrix(0, 0); //逆行列は存在しない Matrix mtrxCofactor = CalcCofactorMatrix(); //余因子行列を計算 return mtrxCofactor * (1.0 / Determinant); //余因子行列を行列式の値で割る }
double CalcDeterminant(float **mat, int order) /*< recursive calculation of determinant >*/ { /* stop recursion when matrix is a single element */ if(order == 1) return mat[0][0]; /* the determinant value */ float det = 0.; /* allocate memory for cofactor matrix */ float **minor = sf_floatalloc2(order-1,order-1); for(int i=0; i < order; i++) { /* get minor of element (0,i) */ GetMinor(mat,minor,0,i,order); /* recursion */ det += (i%2==1?-1.0:1.0) * mat[0][i] * CalcDeterminant(minor,order-1); } return det; }