はじめに
この実験では、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;
}
コンパイルして実行します。
gcc matrix_orthogonal.c -o matrix_orthogonal
./matrix_orthogonal
(省略)
説明
- 詳細な出力を提供する
printDetailedOrthogonalityInfo()関数を追加しました - 元の行列、転置行列、直交性ステータスを表示します
- 直交性の条件を明確に説明します
Summary
In this lab, you first learned how to read a square matrix in C programming. You created a program that allows users to input a square matrix dynamically, and then prints the input matrix to verify the correct input. Next, you extended the program to compute the transpose of the input matrix and check if the matrix is orthogonal by verifying the condition AᵀA = I. The program computes the product of the transpose and the original matrix, and checks if the result is the identity matrix, indicating that the input matrix is orthogonal.



