[C언어-기초실습-12] 2x2 역행렬 구하기

in #kr-dev7 years ago (edited)

[C언어-기초실습-12] 2x2 역행렬 구하기



계속 행렬에 대해서 이야기를 하고 있네요. 오늘은 A행렬에 대해 A역행렬를 구하는 코딩을 실습하고자 합니다. 사실 2x2행렬은 공식이 간단해서 어렵지 않게 코딩을 할 수 있습니다. 문제는 nxn 행렬을 구할 때 3x3 이상은 좀 계산법이 복잡해 지는데 기초 실습에서는 수학을 배우는 것이 아니기 때문에 간단히 감각을 키우는 정도로 실습을 하는게 좋기 때문에 2x2행렬을 기준으로 역행렬 실습이 좋기에 이번 post의 주제로 결정 했네요.

1. 문제의 이해


우선 2x2 행렬의 공식을 살펴 볼까요.
a1.jpg

위와 같은 식으로 풀이 할 수 있습니다. A행렬의 A역행렬의 곱은 단위(E) 행렬이 성립됩니다. 이 원리를 이용하여 A행렬을 E행렬이 있는 곳으로 넘겨주어 식을 만들면 A역행렬을 구할 수 있게 됩니다.

a2.jpg

이 수학이 중학교 때인가 고등학교때인가 아마 다들 배우셨을 거에요. 그때 깅거으로는 단지 위 공식을 외워 뒀다가 A행렬의 값이 주어지면 A의 역행렬을 시험지에서 풀이 했던 기억이 어렴 픗이 떠오르네요.

이 공식을 그대로 코딩화 하면 됩니다.

첫번째로 이 식을 코딩화 합시다.

a3.jpg

d=A[0][0]*A[1][1]-A[0][1]*A[1][0];

두번째로 역행렬을 했을 때 A행렬의 자리 바꿈과 마이너스 부호의 위치를 공식에서 잘 보시고 그대로 코딩화 하면 됩니다.
a4.jpg

    invers_A[0][0] = A[1][1]/d;
    invers_A[0][1] = -A[0][1]/d;
    invers_A[1][0] = -A[1][0]/d;
    invers_A[1][1] = A[0][0]/d;

행렬은 For문을 연상하라


역행렬을 위와 같이 일일히 표현하면 좀 그렇죠. 계속 행렬을 실습하면서 For문을 연상하라고 했는데 갑자기 일일히 코딩해놓으면 좀 그렇죠.
위의 패턴을 잘 찾으시면 For문 구현을 할 수 있습니다.

    x=1;        
    for(i=0;i<2;i++){
        y=1;
        for(j=0;j<2;j++){
            invers_A[i][j]=A[y][x]/d;       
            y--;
        }
        x--;            
    }

이렇게 말이죠. 약간은 좀 어거지 같은 표현이지만 그래도 행렬과 For문 연상을 위해서 실습을 대충 이렇게 했네요.

위 코딩이 정상적으로 계산 되는지 실행 결과를 살펴봐야 겠죠.

2. 코딩


[전체소스]

#include <stdio.h>
#include <Windows.h>

int main(int argc, char *argv[]) {
    
    float A[2][2];
    float invers_A[2][2];
    int i,j;
    int x,y;
    float d;    
    
    //입력 
    printf("2x2 A행렬을 입력하시오? "); 
    for(i=0;i<2;i++){
        for(j=0;j<2;j++){
            scanf("%f",&A[i][j]);
            
        }
    }
    //출력 
    printf("A행렬\n");
    printf("-----------\n");
    for(i=0;i<2;i++){
        for(j=0;j<2;j++){
            printf("%f ",A[i][j]);          
        }
        printf("\n");
    }

    d=A[0][0]*A[1][1]-A[0][1]*A[1][0];
    
    if(d==0){
        printf("역행렬이 존재하지 않음!\n");
        
    }
    else{
        printf("A역행렬\n");
        printf("-----------\n");
        
        //A역행렬 구하기 
        /*
        invers_A[0][0] = A[1][1]/d;
        invers_A[0][1] = -A[0][1]/d;
        invers_A[1][0] = -A[1][0]/d;
        invers_A[1][1] = A[0][0]/d;
        */
        
        x=1;        
        for(i=0;i<2;i++){
            y=1;
            for(j=0;j<2;j++){
                invers_A[i][j]=A[y][x]/d;       
                y--;
            }
            x--;            
        }
        */
        //출력 
        for(i=0;i<2;i++){
            for(j=0;j<2;j++){
                printf("%f ",invers_A[i][j]);           
            }
            printf("\n");
        }       
    }
    
    system("pause");
    return 0;
    
}

[결과]
a5.jpg

마무리


행렬을 주제로 계속 수학 강좌가 된 것 같는 느낌이네요. 감각을 키우기에는 이런 실습이 필요하기에 계속 같은 주제가 이여 지네요. 그리고 더 큰 행렬을 가지고 역행렬을 구하고 싶다면 가우스 조던 소거법을 이용하여 실습을 해보시기 바랍니다. 구글 검색을 하시면 해당 소스를 쉽게 구할 수 있을거에요. 선형대수학인가 수치해석인가 아무튼 관련 책에 보시면 수학관련 코딩들이 많이 있는데 그곳에서 찾아서 다양한 코딩 실습을 해보세요.


Sponsored ( Powered by dclick )

dclick-imagead

Coin Marketplace

STEEM 0.04
TRX 0.33
JST 0.083
BTC 62069.28
ETH 1614.34
USDT 1.00
SBD 0.45