많은 분들이 검색어를 누질르고 계시는 역행렬입니다.
이방법 2x2 는 안되는거 같기도 합니다 -.ㅡ; 나중에 다시 봐야지;;;
가우스 방법은 추후에 소개 하도록 하고 이번엔 일반적인 방법으로 코딩을 해보죠...
( 오늘 퀴즈를 보기때문에 정리할겸 블로깅 해봅니다. )
Determinant...
우선적으로 NbyN행렬의 경우 역행렬이 존재하려면 |A| =/= 0 즉...
Determinant가 '0'이 아니어야 합니다.
그뒤 Det 값이 있다면 A의 cofactor를 구하게 됩니다.
Cofactor는 각 자리에 맞게 +- 한것과 그 위치의 Minor의 Det값입니다.
이해가 안되죠 ;;; 저도 잘 이해가 되지 않았습니다.
이런건 그림으로 설명하는게 좋죠;;;
우선 이런 행렬이 있습니다.
3x3 행렬입니다. 뭐 이건 쉽죠...
그냥 이런식으로 설명합니다.
자 우선 Cofactor를 구합니다.
각 자리수에 맞게 자리 마다 +- 를 해줍니다. ( -1^(i+j) 입니다. )
그리고 각 자리 즉 a11이었던 곳에서 + 자로 상하좌우를 제거 하고 남은 2x2 행렬 ( Minor )의 Det 값을 a11에 넣습니다.
대충 위와 같이 하시면 됩니다. 그뒤에 Transpose를 해줍니다.
논리는 b(ji) = a(ij) 입니다.
즉 Adjoint는 Cofactor를 구한뒤 그것을Transpose를 한것입니다.
역시 수학을 설명하는건 세상 가장 킹왕짱 어렵군요.
위처럼 Cofactor를 구한뒤 Transpose를 한것과 같습니다.
최종결과는
위와 같습니다.
즉 3x3 행렬으로 역행렬을 구해보면...
우선 Determinant를 구한다.
' 0 ' 이 아니면 역행렬 존재.
원래 3x3행렬의 Cofactor를 구하고 Minor의 Determinant를 각자리에 대입
그뒤 Transpose를 수행한뒤
처음에 구한 Det(A)값으로 나눠준다.
역행렬 완성!!!
이와 같은 알고리즘을 가지고 코딩을 해봤습니다.
닫기
Code Type : c
/**
Project Name : Find NxN inverse Matrix(A) ( P01.c )
use : Report.
Version : 1.0
Copyright (c) 2007 : Ohyung ( ohyung@ohyung.com )
Last modified at : 2007.10.30
Base : linux (ubuntu 7.10 - Gutsy Gilbbon, kernel 2.6.22-12-generic)
compiler : gcc (GCC) 4.1.3
Tool : Code::Blocks svn4551
사용방법 : $ gcc -o P01 P01.c
실행 : $ ./P01
*/
#include < stdio.h>
#include < stdlib.h> // malloc
static double
Determinant(double** matrixA, int uesrN);
static int
InverseMatrix(double** matrixA, double** inversedMatrixA, int userN,
double determinantResult);
static int
MultiplicationMatrix(double** matrixA, double** matrixB, double** resultMatrix,
int userN);
int
main(void)
{
int userN = 0;
int userM = 0;
int row = 0;
int column = 0;
double** matrixA;
double** inversedMatrixA;
double** multiplicationalMatrixA;
double determinantResult = 0;
printf("n by n = ");
scanf("%d", &userN);
userM = userN - 1;
matrixA = (double**)malloc(sizeof(double*) * userN);
for (row = 0; row < userN; row++)
{
matrixA[row] = (double*)malloc(sizeof(double) * userN);
} /* for (row = 0; row < userN; row++) */
for (row = 0; row < userN; row++)
{
for (column = 0; column < userN; column++)
{
printf("%d , %d =", row, column);
scanf("%lf", &matrixA[row][column]);
} /* for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN; row++) */
printf("\nA =\n");
for (row = 0; row < userN; row++)
{
for (column = 0; column < userN; column++)
{
printf("%10.5lf ", matrixA[row][column]);
if(column % userN == userM)
{
printf("\n");
} /* if(column % userN == userM) */
} /* for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN; row++) */
determinantResult = Determinant(matrixA, userN);
printf("\n|A| = %.5g\n", determinantResult);
if (!determinantResult)
{
printf("\nNo determinant(A)\n");
} /* if (!determinantResult) */
else
{
inversedMatrixA = (double**)malloc(sizeof(double*) * userN);
multiplicationalMatrixA = (double**)malloc(sizeof(double*) * userN);
for (row = 0; row < userN; row++)
{
inversedMatrixA[row] = (double*)malloc(sizeof(double) * userN);
multiplicationalMatrixA[row] =
(double*)malloc(sizeof(double) * userN);
} /* for (row = 0; row < userN; row++) */
InverseMatrix(matrixA, inversedMatrixA, userN, determinantResult);
printf("\nA' = \n");
for (row = 0; row < userN; row++)
{
for (column = 0; column < userN; column++)
{
printf("%15.5lf ", inversedMatrixA[row][column]);
if (column % userN == userM)
{
printf("\n");
} /* if (column % userN == userM) */
} /* for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN; row++) */
MultiplicationMatrix(matrixA, inversedMatrixA,
multiplicationalMatrixA, userN);
printf("\nA'A = \n");
for (row = 0; row < userN; row++)
{
for (column = 0; column < userN; column++)
{
printf("%15.5lf ", multiplicationalMatrixA[row][column]);
if (column % userN == userM)
{
printf("\n");
} /* if (column % userN == userM) */
} /* for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN; row++) */
for(row = 0; row < userN; row++)
{
free(multiplicationalMatrixA[row]);
free(inversedMatrixA[row]);
} /* for(row = 0; row < userN; row++) */
free(multiplicationalMatrixA);
free(inversedMatrixA);
}
for(row = 0; row < userN; row++)
{
free(matrixA[row]);
} /* for(row = 0; row < userN; row++) */
free(matrixA);
return 0;
}
/**
* Function Name: Determinant
*
* Function Description:
* This function solve the determinant from a matrix A
*
* Input: matrixA , userN
* Output: determinantResult
* Version: 1.0
*/
static double
Determinant (double** matrixA, int userN)
{
int userM = 0;
int counter = 0;
int determinantACheck = 0;
int determinantARow = 0;
int determinantAColumn = 0;
int sign = 1;
double determinantResult = 0;
double** matrixDeterminantA;
userM = userN-1;
matrixDeterminantA = (double**)malloc(sizeof(double*) * userM);
for (counter = 0; counter < userM; counter++)
{
matrixDeterminantA[counter] = (double*)malloc(sizeof(double) * userM);
} /* for (counter = 0; counter < userM; counter++) */
if (userN == 2)
{
determinantResult = (matrixA[0][0] * matrixA[1][1]) -
(matrixA[0][1] * matrixA[1][0]);
} /* if (userN == 2) */
else
{
for (counter = 0; counter < userN; counter++)
{
for (determinantARow = 0; determinantARow < userM;
determinantARow++)
{
determinantACheck = 0;
for (determinantAColumn = 0; determinantAColumn < userM;
determinantAColumn++)
{
if (determinantAColumn == counter)
{
determinantACheck++;
} /* if (determinantAColumn == counter) */
matrixDeterminantA[determinantARow][determinantAColumn] =
matrixA[determinantARow + 1][determinantACheck];
determinantACheck++;
} /* for (determinantAColumn = 0; determinantAColumn < userM;
determinantAColumn++) */
} /* for (determinantARow = 0; determinantARow < userM;
determinantARow++) */
if(counter % 2 == 1)
{
sign = -1;
} /* if(counter % 2 == 1) */
else
{
sign = 1;
} /* else */
determinantResult += sign * matrixA[0][counter] *
Determinant(matrixDeterminantA,userM);
} /* for (counter = 0; counter < userN; counter++) */
} /* else */
for(counter = 0; counter < userM; counter++)
{
free(matrixDeterminantA[counter]);
} /* for(counter = 0; counter < userM; counter++) */
free(matrixDeterminantA);
return determinantResult;
}
/**
* Function Name: Determinant
*
* Function Description:
* This function find a inverse matrix from a matrix A
*
* Input: matrixA, userN, determinantResult
* Output: inversedMatirixA
* Version: 1.0
*/
static int
InverseMatrix(double** matrixA, double** inversedMatrixA, int userN,
double determinantResult)
{
int userM = 0;
int row = 0;
int column = 0;
int cofactorRowCheck=0;
int cofactorColumnCheck=0;
int cofactorRow=0;
int cofactorColumn=0;
int sign = 1;
double temporaryValue = 0;
double** determinantCofactorMatrixA;
double** cofactorMatrixA;
userM = userN - 1;
cofactorMatrixA = (double**)malloc(sizeof(double*) * userN);
for(row = 0; row < userN; row++)
{
cofactorMatrixA[row] = (double*)malloc(sizeof(double) * userN);
} /* for(row = 0; row < userN; row++) */
determinantCofactorMatrixA = (double**)malloc(sizeof(double*) * userM);
for(row = 0; row < userM; row++)
{
determinantCofactorMatrixA[row] =
(double*)malloc(sizeof(double) * userM);
} /* for(row = 0; row < userM; row++) */
/* Find the Cofactor */
if (userN == 2)
{
cofactorMatrixA[0][0] = (matrixA[0][0] * matrixA[1][1]) -
(matrixA[0][1] * matrixA[1][0]);
} /* if (userN == 2) */
else
{
for (row = 0; row < userN; row++)
{
for (column = 0; column < userN; column++)
{
cofactorColumnCheck=0;
for (cofactorRow = 0; cofactorRow < userM; cofactorRow++)
{
if(cofactorColumnCheck == column)
{
cofactorColumnCheck++;
} /* if(cofactorColumnCheck == column) */
cofactorRowCheck=0;
for (cofactorColumn = 0; cofactorColumn < userM;
cofactorColumn++)
{
if (cofactorColumn == row)
{
cofactorRowCheck++;
} /* if (cofactorColumn == row) */
determinantCofactorMatrixA[cofactorRow]
[cofactorColumn] =
matrixA[cofactorColumnCheck][cofactorRowCheck];
cofactorRowCheck++;
} /* for (cofactorColumn = 0; cofactorColumn < userM;
cofactorColumn++) */
cofactorColumnCheck++;
} /* for (cofactorRow = 0; cofactorRow < userM;
cofactorRow++) */
if( (row+column) % 2 == 1)
{
sign = -1;
} /* if( (row+column) % 2 == 1) */
else
{
sign = 1;
} /* else */
cofactorMatrixA[row][column] = sign *
Determinant(determinantCofactorMatrixA, userM);
} /* for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN; row++) */
} /* else */
for(row = 0; row < userM; row++)
{
free(determinantCofactorMatrixA[row]);
} /* for(row = 0; row < userM; row++) */
free(determinantCofactorMatrixA);
// adjoint
for (row = 0; row < userN; row++)
{
for (column = 0; column < userN; column++)
{
temporaryValue = cofactorMatrixA[row][column];
inversedMatrixA[row][column] = cofactorMatrixA[column][row];
inversedMatrixA[column][row] = temporaryValue;
} /* for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN; row++) */
// adjoint / determinant = inverse
for (row = 0; row < userN;row++)
{
for (column = 0; column < userN; column++)
{
inversedMatrixA[row][column] =
cofactorMatrixA[row][column] / determinantResult;
} /*for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN;row++) */
for(row = 0; row < userN; row++)
{
free(cofactorMatrixA[row]);
} /* for(row = 0; row < userN; row++) */
free(cofactorMatrixA);
return 0;
}
/**
* Function Name: MultiplicationMatrix
*
* Function Description:
* This function multiplicate the two matrix
*
* Input: matrixA, matrixB, userN
* Output: resultMatrix
* Version: 1.0
*/
static int
MultiplicationMatrix(double** matrixA, double** matrixB, double** resultMatrix,
int userN)
{
int row = 0;
int column = 0;
int check = 0;
for (row = 0; row < userN; row++)
{
for (column = 0; column < userN; column++)
{
for (check = 0; check < userN; check++)
{
resultMatrix[row][column] += matrixA[row][check] *
matrixB[check][column];
} /* for (check = 0; check < userN; check++) */
} /* for (column = 0; column < userN; column++) */
} /* for (row = 0; row < userN; row++) */
return 0;
}
닫기
위의 코드는 아래의 CC라이센스에 의해 이용가능함.
최적화는 알아서 할것. i,j 안쓰는 변태는 아님;;; -.-; ( 믿어주삼! )