プログラミング演習2(課題3,第3回)
ベクトル,行列モジュールを用いて連立方程式を解く
連立方程式の解法に関する資料(修正版)
練習問題1)以下のサンプルコードを参考にして,LU分解を行う関数(LU_decomp())と,
連立方程式を解く関数(LU_solve())を作成してください.
但し,関数のプロトタイプは変更してもかまいません.
lu.h
#ifndef LU_H
#define LU_H
#include "array1d.h"
#include "array2d.h"
/*******************************************************************************
* n×n行列AをLU分解する
* (LU分解後に行列Aは左下三角行列Lと右上三角行列Uによって上書きされる)
* @param A LU分解対象の正方行列
* @param n 正方行列Aの行、列数
* @return 行列式
******************************************************************************/
double
LU_decomp(matrix A, int n);
/*******************************************************************************
* 元のn×n行列をLU_decompを用いてLU分解した後に、
* L行列とU行列によって上書きされた行列Aを用いて、
* n×1行列xとbとするときに、Ax=bを解く
* (右辺ベクトルとして与えたbは,解ベクトルxによって上書きされる)
* @param A 元の行列をLU分解後、その左下三角成分をL、その右上三角成分をUとする行列
* @param b 方程式の右辺ベクトル(解ベクトルによって上書きされる)
* @param n 行列Aの行、列数、ベクトルbの要素数
******************************************************************************/
void
LU_solve(matrix A, vector b, int n);
#endif //LU_H
lu.c
#include "lu.h"
double
LU_decomp(matrix A, int n) {
/* LU分解関数を実装せよ */
}
void
LU_solve(matrix A, vector b, int n) {
/* LU_decompによってLU分解されたL、U行列を用いて連立方程式を解くプログラムを実装せよ */
}
テストプログラム(lu_test.c)
#include <stdio.h>
#include <stdlib.h>
#include "array1d.h"
#include "array2d.h"
#include "lu.h"
int
main(void) {
int N; /* 行列のサイズ */
double det; /* 行列式 */
matrix A; /* 元の行列 */
vector b; /* 右辺ベクトル */
N = 4; /* 行列サイズの指定 */
/* 元の行列の初期化 */
A = ARRAY2D_new(N, N);
A[0][0] = 8;
A[0][1] = 16;
A[0][2] = 24;
A[0][3] = 32;
A[1][0] = 2;
A[1][1] = 7;
A[1][2] = 12;
A[1][3] = 17;
A[2][0] = 6;
A[2][1] = 17;
A[2][2] = 32;
A[2][3] = 59;
A[3][0] = 7;
A[3][1] = 22;
A[3][2] = 46;
A[3][3] = 105;
/* 右辺ベクトルの初期化 */
b = ARRAY1D_new(N);
b[0] = 160;
b[1] = 70;
b[2] = 198;
b[3] = 291;
/* ベクトル・行列の表示*/
/* 【解答例】 元の行列A =
* [8.000000,16.000000,24.000000,32.000000,
* 2.000000,7.000000,12.000000,17.000000,
* 6.000000,17.000000,32.000000,59.000000,
* 7.000000,22.000000,46.000000,105.000000]
* 右辺ベクトルb =
* [160.000000,70.000000,198.000000,291.000000] */
printf("元の行列A = \n");
ARRAY2D_print(A, N, N, "%f");
printf("右辺ベクトルb = \n");
ARRAY1D_print(b, N, "%f");
printf("\nAx=bを解く\n");
/* LU分解実行 */
/* 【解答例】 行列式 = 768.000000 */
det = LU_decomp(A, N);
printf("行列式 = %f\n", det);
/* LU分解後の行列Lと行列Uの表示 */
/* 【解答例】 LU分解後の行列
* [8.000000,2.000000,3.000000,4.000000,
* 2.000000,3.000000,2.000000,3.000000,
* 6.000000,5.000000,4.000000,5.000000,
* 7.000000,8.000000,9.000000,8.000000] */
printf("LU分解後の行列\n");
ARRAY2D_print(A, N, N, "%f");
/* LU分解後の行列を用いて連立方程式を解く */
LU_solve(A, b, N);
/* 解ベクトル表示 */
/* 【解答例】 解ベクトル
* [4.000000,3.000000,2.000000,1.000000] */
printf("解ベクトル\n");
ARRAY1D_print(b, N, "%f");
return (EXIT_SUCCESS);
}
LU分解ルーチンの別のプロトタイプ例
lu.h
#ifndef LU_H
#define LU_H
#include "array1d.h"
#include "array2d.h"
/*******************************************************************************
* n×n行列AをLU分解する
* @param A LU分解対象の正方行列
* @param L LU分解対象の左下三角行列
* @param U LU分解対象の右上三角行列
* @param n 正方行列Aの行、列数
* @return 行列式
******************************************************************************/
double
LU_decomp(const matrix A, matrix L, matrix U, int n);
/*******************************************************************************
* 元のn×n行列をLU_decompを用いてLU分解した後に、
* L行列とU行列を用いて
* n×1行列xとbとするときに、LUx=bを解く
* @param L LU分解後の左下三角行列
* @param U LU分解後の右上三角行列
* @param b 方程式の右辺ベクトル
* @param x 方程式の解ベクトル
* @param n 行列Aの行、列数、ベクトルbの要素数
******************************************************************************/
void
LU_solve(const matrix L, const matrix U, const vector b, vector x, int n);
#endif //LU_H