C 언어로 행렬의 직교성 확인하기

CBeginner
지금 연습하기

소개

이 실습에서는 C 프로그래밍으로 정방 행렬이 직교 행렬인지 확인하는 방법을 배웁니다. 이 실습은 정방 행렬을 읽고, 행렬의 전치 행렬을 계산하고, AᵀA = I 조건을 검증하여 행렬이 직교 행렬인지 확인하는 단계를 다룹니다. 이 실습을 마치면 C 를 사용한 행렬 연산 및 선형 대수 응용에 대한 포괄적인 이해를 얻게 될 것입니다.

이 실습은 정방 행렬을 읽는 것부터 시작하여 행렬의 전치 행렬을 계산하고 마지막으로 AᵀA = I 조건을 검증하여 행렬이 직교 행렬인지 확인하는 단계별 가이드를 제공합니다. 이 실습은 데이터 분석, 과학적 계산 및 엔지니어링을 포함한 다양한 분야에서 C 프로그래밍을 사용한 행렬 및 선형 대수 기술을 개발하는 데 도움이 되도록 설계되었습니다.

정방 행렬 읽기

이 단계에서는 C 프로그래밍에서 정방 행렬을 읽는 방법을 배웁니다. 정방 행렬은 행과 열의 개수가 같은 행렬입니다. 이번에는 사용자가 동적으로 정방 행렬을 입력할 수 있도록 프로그램을 작성할 것입니다.

먼저 행렬 연산을 위한 C 소스 파일을 만들어 봅시다.

cd ~/project
nano matrix_orthogonal.c

이제 정방 행렬을 읽는 다음 코드를 추가합니다.

#include <stdio.h>
#define MAX_SIZE 100

void readMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
    printf("행렬 요소를 행 단위로 입력하세요:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            scanf("%d", &matrix[i][j]);
        }
    }
}

int main() {
    int size, matrix[MAX_SIZE][MAX_SIZE];

    printf("정방 행렬의 크기를 입력하세요: ");
    scanf("%d", &size);

    readMatrix(matrix, size);

    // 입력 확인을 위해 행렬 출력
    printf("\n입력 행렬:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    return 0;
}

프로그램을 컴파일하고 실행합니다.

gcc matrix_orthogonal.c -o matrix_orthogonal
./matrix_orthogonal

예시 출력:

정방 행렬의 크기를 입력하세요: 3
행렬 요소를 행 단위로 입력하세요:
1 0 0
0 1 0
0 0 1

입력 행렬:
1 0 0
0 1 0
0 0 1
설명
  • MAX_SIZE는 행렬의 최대 크기를 정의합니다.
  • readMatrix() 함수는 2 차원 배열과 크기를 매개변수로 받습니다.
  • 사용자가 행 단위로 행렬 크기와 요소를 입력합니다.
  • 프로그램은 입력된 행렬을 출력하여 입력이 올바른지 확인합니다.

Aᵀ 계산 및 AᵀA = I 확인

이 단계에서는 이전 프로그램을 확장하여 행렬의 전치 행렬을 계산하고 AᵀA = I 조건을 검증하여 행렬이 직교 행렬인지 확인합니다.

다음 코드로 matrix_orthogonal.c 파일을 업데이트합니다.

nano ~/project/matrix_orthogonal.c

다음 구현을 추가합니다.

#include <stdio.h>
#include <stdbool.h>
#define MAX_SIZE 100

void readMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
    printf("행렬 요소를 행 단위로 입력하세요:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            scanf("%d", &matrix[i][j]);
        }
    }
}

void transposeMatrix(int original[MAX_SIZE][MAX_SIZE],
                     int transpose[MAX_SIZE][MAX_SIZE],
                     int size) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            transpose[j][i] = original[i][j];
        }
    }
}

bool checkOrthogonality(int matrix[MAX_SIZE][MAX_SIZE],
                        int transpose[MAX_SIZE][MAX_SIZE],
                        int size) {
    int result[MAX_SIZE][MAX_SIZE] = {0};

    // 전치 행렬과 원본 행렬을 곱합니다.
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            for (int k = 0; k < size; k++) {
                result[i][j] += transpose[i][k] * matrix[k][j];
            }
        }
    }

    // 결과가 단위 행렬인지 확인합니다.
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            if (i == j && result[i][j] != 1) return false;
            if (i != j && result[i][j] != 0) return false;
        }
    }

    return true;
}

int main() {
    int size, matrix[MAX_SIZE][MAX_SIZE], transpose[MAX_SIZE][MAX_SIZE];

    printf("정방 행렬의 크기를 입력하세요: ");
    scanf("%d", &size);

    readMatrix(matrix, size);

    // 전치 행렬 계산
    transposeMatrix(matrix, transpose, size);

    // 직교 여부 확인
    bool isOrthogonal = checkOrthogonality(matrix, transpose, size);

    printf("\n전치 행렬:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", transpose[i][j]);
        }
        printf("\n");
    }

    printf("\n행렬이 직교인가요? %s\n", isOrthogonal ? "예" : "아니요");

    return 0;
}

프로그램을 컴파일하고 실행합니다.

gcc matrix_orthogonal.c -o matrix_orthogonal
./matrix_orthogonal

예시 출력:

정방 행렬의 크기를 입력하세요: 3
행렬 요소를 행 단위로 입력하세요:
1 0 0
0 1 0
0 0 1

전치 행렬:
1 0 0
0 1 0
0 0 1

행렬이 직교인가요? 예
설명
  • transposeMatrix() 함수는 행렬의 전치 행렬을 계산합니다.
  • checkOrthogonality() 함수는 AᵀA = I 조건을 검증합니다.
  • 프로그램은 전치 행렬과 원본 행렬을 곱하여 행렬이 직교인지 확인합니다.

직교 여부 출력

이 마지막 단계에서는 행렬의 직교성에 대한 더 자세한 출력을 제공하고 다양한 행렬 시나리오를 보여주도록 이전 프로그램을 개선합니다.

다음 개선된 구현으로 matrix_orthogonal.c 파일을 업데이트합니다.

nano ~/project/matrix_orthogonal.c

이전 구현을 다음으로 대체합니다.

#include <stdio.h>
#include <stdbool.h>
#define MAX_SIZE 100

void readMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
    printf("행렬 요소를 행 단위로 입력하세요:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            scanf("%d", &matrix[i][j]);
        }
    }
}

void transposeMatrix(int original[MAX_SIZE][MAX_SIZE],
                     int transpose[MAX_SIZE][MAX_SIZE],
                     int size) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            transpose[j][i] = original[i][j];
        }
    }
}

bool checkOrthogonality(int matrix[MAX_SIZE][MAX_SIZE],
                        int transpose[MAX_SIZE][MAX_SIZE],
                        int size) {
    int result[MAX_SIZE][MAX_SIZE] = {0};

    // 전치 행렬과 원본 행렬을 곱합니다.
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            for (int k = 0; k < size; k++) {
                result[i][j] += transpose[i][k] * matrix[k][j];
            }
        }
    }

    // 결과가 단위 행렬인지 확인합니다.
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            if (i == j && result[i][j] != 1) return false;
            if (i != j && result[i][j] != 0) return false;
        }
    }

    return true;
}

void printDetailedOrthogonalityInfo(int matrix[MAX_SIZE][MAX_SIZE],
                                    int transpose[MAX_SIZE][MAX_SIZE],
                                    int size) {
    bool isOrthogonal = checkOrthogonality(matrix, transpose, size);

    printf("\n--- 행렬 직교성 분석 ---\n");
    printf("원본 행렬:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    printf("\n전치 행렬:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", transpose[i][j]);
        }
        printf("\n");
    }

    printf("\n직교 여부: %s\n", isOrthogonal ? "✓ 직교 행렬" : "✗ 직교 행렬 아님");

    if (isOrthogonal) {
        printf("설명: A * Aᵀ = I (단위 행렬)\n");
    } else {
        printf("설명: A * Aᵀ ≠ I (단위 행렬 아님)\n");
    }
}

int main() {
    int size, matrix[MAX_SIZE][MAX_SIZE], transpose[MAX_SIZE][MAX_SIZE];

    printf("정방 행렬의 크기를 입력하세요: ");
    scanf("%d", &size);

    readMatrix(matrix, size);
    transposeMatrix(matrix, transpose, size);
    printDetailedOrthogonalityInfo(matrix, transpose, size);

    return 0;
}

... (나머지 코드는 동일)

##### 설명

- 포괄적인 출력을 위한 `printDetailedOrthogonalityInfo()` 함수 추가
- 원본 행렬, 전치 행렬 및 직교 여부 상태 표시
- 직교 조건에 대한 명확한 설명 제공

요약

이 실험에서는 먼저 C 프로그래밍에서 정방 행렬을 읽는 방법을 배웠습니다. 사용자가 동적으로 정방 행렬을 입력할 수 있도록 하고, 입력된 행렬을 출력하여 입력이 올바른지 확인하는 프로그램을 만들었습니다. 다음으로, 프로그램을 확장하여 입력 행렬의 전치 행렬을 계산하고, AᵀA = I 조건을 검증하여 행렬이 직교인지 확인했습니다. 프로그램은 전치 행렬과 원본 행렬의 곱을 계산하고, 결과가 단위 행렬인지 확인하여 입력 행렬이 직교 행렬인지 판별합니다.