プログラミング演習I 行列計算と線形方程式の求解

Slides:



Advertisements
Similar presentations
大規模な三角 Toeplitz 線形方 程式の高速解法とその応用 ○ 安村 修一(法政大学 4 年) 李 磊(法政大学) 日本応用数理学会「行列・固有値の解法とその応用」研究部会 第6回研究会.
Advertisements

IT 入門 B2 ー 連立一次方程式( 2 ) ー. ガウスの消去法の問題点 – 浮動小数点数の特殊な値 – 数学関数 ピボット選択つきガウスの消去法 演習 授 業 内 容 授 業 内 容.
プログラミング実習 1 ・ 2 ク ラス 第 2 週目 担当教員 : 渡邊 直樹. 課題 2 ● 2 × 2型行列の固有値, 固有ベクトルを求め る EigMatrix.java というプログラムを作成せ よ。 ● 行列の各要素はコマンド・プロンプトから入力 ● 計算した結果もコマンド・プロンプトに表示.
原子動力工学特論 課題2 交通電子機械工学専攻 2003310 齋藤 泰治.
データ解析
配列の宣言 配列要素の初期値 配列の上限 メモリ領域 多次元配列 配列の応用
プログラミング演習(1組) 第7回
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
4.3 連立1次方程式   Ax = b   (23) と書くことができる。
数個、数十個のデータ点から その特徴をつかむ
第12回構造体.
解析的には解が得られない 方程式を数値的に求める。 例:3次方程式
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング論 I 行列の演算
基礎プログラミングおよび演習 第9回
第四回 線形計画法(2) 混合最大値問題 山梨大学.
連立一次方程式 a11x1+a12x2+a13x3+...+a1nxn= b1
原子動力工学特論 課題 3、4 交通電子機械工学専攻   齋藤 泰治.
プログラミング演習(2組) 第12回
基礎プログラミング (第五回) 担当者: 伊藤誠 (量子多体物理研究室) 内容: 1. 先週のおさらいと続き (実習)
プログラミング実習 1・2 クラス 第 1 週目 担当教員:  渡邊 直樹.
IT入門B2 ー 連立一次方程式 ー.
コンピュータープログラミング (C言語)(8) 1.乱数(復習) 2.配列とその利用
第二回 連立1次方程式の解法 内容 目標 連立1次方程式の掃出し法 初期基底を求める 連立1次方程式を掃出し法を用いてExcelで解析する
プログラミング論 II 電卓,逆ポーランド記法電卓
数値解析シラバス C言語環境と数値解析の概要(1回) 方程式の根(1回) 連立一次方程式(2回) 補間と近似(2回) 数値積分(1回)
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
第7回 条件による繰り返し.
第2回 Microsoft Visual Studio C++ を使ってみよう
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
数学 ---> 抽象化、一般化 より複雑な関係ー>解析学 一次関数 y=ax+b より多くの要素ー>線形代数 x y f(x) y1 x1
ニュートン法の解の計算 情報電子工学系学科 電気電子工学コース・情報通信システム工学コース
プログラミング2 関数
Cプログラミング演習 中間まとめ2.
Cプログラミング演習 第6回 ファイル処理と配列.
プログラミング論 ファイル入出力
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
Cプログラミング演習.
数値積分.
Cプログラミング演習 第7回 メモリ内でのデータの配置.
フーリエ級数展開 ~矩形波について~ 長江 栞 中島 涼 中村 勇樹
傾きがわかった関数の軌跡を求める. 変数は二つ以上
LU分解を用いた連立一次方程式.
第7回 条件による繰り返し.
プログラミング論 ファイル入出力
Cの実行モデル.
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
Cプログラミング演習 第10回 二分探索木.
ポリゴンメッシュ (2) - 変形と簡略化- 東京大学 精密工学専攻 大竹豊 資料および授業の情報は :
高度プログラミング演習 (05).
高度プログラミング演習 (05).
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
Cプログラミング演習資料.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
プログラミング序論演習.
連立一次方程式 a11x1+a12x2+a13x3+...+a1nxn= b1
2008年6月5日 非線形方程式の近似解 2分法,はさみうち法,Newton-Raphson法)
ニュートン法による 非線型方程式の解.
cp-1. クラスとメソッド (C++ オブジェクト指向プログラミング入門)
cp-3. 計算 (C プログラミング演習,Visual Studio 2019 対応)
Cプログラミング演習 ニュートン法による方程式の求解.
プログラミング演習I 数値計算における計算精度と誤差
Cp-1. Microsoft Visual Studio 2019 C++ の使い方 (C プログラミング演習,Visual Studio 2019 対応) 金子邦彦.
3 一次関数 1章 一次関数とグラフ §4 方程式とグラフ         (3時間).
Cプログラミング演習資料.
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
プログラミング入門2 第5回 配列 変数宣言、初期化について
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
プログラミング演習I 補講用課題
Presentation transcript:

プログラミング演習I 行列計算と線形方程式の求解 Cプログラミング演習 行列計算と線形方程式の求解

LU分解 連立一次方程式を解く手段。 通常、連立方程式を解く場合は、変数を減らしていくという方針で解いていくが、LU分解もその1つ。 プログラミング演習I LU分解 連立一次方程式を解く手段。 通常、連立方程式を解く場合は、変数を減らしていくという方針で解いていくが、LU分解もその1つ。 Gaussの消去法とLU分解の比較。 計算機で実装した場合、Gaussの消去法はLU分解に比べて計算速度がかなり「遅い」。 逆行列を求める方法も「遅い」。

連立一次方程式の行列表現 一般に連立一次方程式は、 A0,0x0+A0,1x1・・・A0,n-1xn-1 = b0 プログラミング演習I 連立一次方程式の行列表現 一般に連立一次方程式は、 これを行列表現すると、 A0,0x0+A0,1x1・・・A0,n-1xn-1 = b0 A1,0x0+A1,1x1・・・A1,n-1xn-1 = b1 An-1,0x0+An-1,1x1・・・An-1,n-1xn-1 = bn-1   (1) A0,0 A0,1 ・・ A0,n-1 A1,0 A1,1 A1,n-1 : An-1,0 An-1,1 An-1,n-1 x0 x1 : xn-1 b0 b1 : bn-1 = Ax=b (2)

上三角行列,下三角行列 A= 三角行列であれば解を求めることが容易。 LU分解では,行列Aを下三角行列Lと上三角行列Uの二つに分解する。 = プログラミング演習I 上三角行列,下三角行列 三角行列であれば解を求めることが容易。 LU分解では,行列Aを下三角行列Lと上三角行列Uの二つに分解する。 A0,0 A0,1 ・・ A0,n-1 A1,0 A1,1 A1,n-1 : An-1,0 An-1,1 An-1,n-1 A= 1 ・・・ l1,0 : ln-2,0 ln-2,1 ln-1,0 ln-1,1 ln-1,n-2 u0,0 u0,1 ・・・ u0,n-2 u0,n-1 u1,1 u1,n-2 u1,n-1 : un-2,n-2 un-2,n-1 un-1,n-1 = =LU   (3)

LU分解で連立一次方程式を解く(1) 一次方程式 Ax = b を解く。 行列Aを下三角行列Lと上三角行列Uの二つにLU分解する。 プログラミング演習I LU分解で連立一次方程式を解く(1) 一次方程式 Ax = b を解く。 行列Aを下三角行列Lと上三角行列Uの二つにLU分解する。 A = LU (4) 行列AがLU分解されると求める方程式は以下のようになる。 Ax = LUx = b (5)

LU分解で連立一次方程式を解く(2) Ux=c とおいて、まず、 Lc = b (6) を解く c を求めたら、 Ux = c (7) プログラミング演習I LU分解で連立一次方程式を解く(2) Ux=c とおいて、まず、 Lc = b (6) を解く c を求めたら、 Ux = c (7) を解くことで、xが求まる

プログラミング演習I LU分解する。 A0,0 A0,1 A0,2 A1,0 A1,1 A1,2 A2,0 A2,1 A2,2 1 l1,0 l2,0 l2,1 u0,0 u0,1 u0,2 u1,1 u1,2 u2,2 = A00=u00 A01=u01 A02=u02 A10=l10*u00 A11=l10*u01+u11 A12=l10*u02+u12 A20=l20*u00 A21=l20*u01+l21*u11 A22=l20*u02+l21*u12+u22 u00=A00 u01=A01 u02=A02 l10=A10/u00 u11=A11-l10*u01 u12=A12-l10*u02 l20=A20/u00 l21=(A21-l20*u01)/u11 u22=A22-l20*u02-l21*u12 u00=A00 u01=A01 u02=A02 l10=A10/u00 l20=A20/u00 u11=A11-l10*u01 u12=A12-l10*u02 l21=(A21-l20*u01)/u11 u22=A22-l20*u02-l21*u12

u1,k = A1,k-u0,k・l1,0 where(1≦k≦n-1) (8) プログラミング演習I 一般化すると、 A0,0 A0,1 ・・ A0,n-1 A1,0 A1,1 A1,n-1 : An-1,0 An-1,1 An-1,n-1 1 2 3 1 ・・・ l1,0 : ln-2,0 ln-2,1 ln-1,0 ln-1,1 ln-1,n-2 u0,0 u0,1 ・・・ u0,n-2 u0,n-1 u1,1 u1,n-2 u1,n-1 : un-2,n-2 un-2,n-1 un-1,n-1 1 2 3 u0,k = A0,k where(0≦k≦n-1) li,0 = Ai,0/u0,0 where(1≦i≦n-1) u1,k = A1,k-u0,k・l1,0 where(1≦k≦n-1) (8)

(6) の Lc = b これを c について解くと、 = (9) c0 = b0 c1 = b1-l1,0・c0 プログラミング演習I (6) の Lc = b 1 ・・・ l1,0 ln-2,0 ln-2,1 ln-1,0 ln-1,1 ln-1,n-2 c0 c1 cn-2 cn-1 b0 b1 bn-2 bn-1 = (9) これを c について解くと、 c0 = b0 c1 = b1-l1,0・c0 c2 = b2-l2,0・c0-l2,1・c1 ck = bk-∑lk,i・ci where(0≦k≦n-1)    (10) k-1 i=0

最後に (7) の Ux = c これを x について解くと、 = (11) xn-1 = cn-1/un-1,n-1 プログラミング演習I 最後に (7) の Ux = c u0,0 u0,1 ・・・ u0,n-2 u0,n-1 u1,1 u1,n-2 u1,n-1 un-2,n-2 un-2,n-1 un-1,n-1 x0 x1 xn-2 xn-1 c0 c1 cn-2 cn-1 = (11) これを x について解くと、 xn-1 = cn-1/un-1,n-1 xn-2 = (cn-2-un-2,n-1・xn-1)/un-2,n-2 xn-3 = (cn-3-un-3,n-2・xn-2-un-3,n-1・xn-1)/un-3,n-3 xn-k = (cn-k-∑un-k,n-i・xn-i)/un-k,n-k where(1≦k≦n) (12) k-1 i=1

プログラム例 入力行列は既にファイル(c:\lu_test.txt)にあるものとする c:\lu_data.txtの中身 プログラミング演習I プログラム例 入力行列は既にファイル(c:\lu_test.txt)にあるものとする c:\lu_data.txtの中身 3 2 6 1 17 2 4 1 6 23 5 4 1 3 23 3 2 5 6 26 これは、以下の方程式を表しているものとする。 3x0 + 2x1 + 6x2 + x3 = 17 2x0 + 4x1 + x2 + 6x3 = 23 5x0 + 4x1 + x2 +3x2 = 23 3x0 + 2x1 + 5x2 + 6x3 = 26

プログラミング演習I #include "stdafx.h" #pragma warning(disable:4996) int _tmain() { const int M = 4; double a[M][M]; double b[M]; double c[M]; double l[M][M]; double u[M][M]; double x[M]; int i,j,k; FILE *fp; char line[1000]; int ch; fp = fopen("c:\\lu_data.txt", "r"); /* データの読み込み */ for(i = 0; i < M; i++){ for(j = 0; j < M; j++){ fscanf_s(fp,"%lf",&a[i][j]); } fscanf_s(fp,"%lf",&b[i]); fclose(fp); for(i = 0; i < M; i++){ /* L行列、U行列を1と0で初期化 */ u[i][j] = 0; if(i == j) l[i][j] = 1; else l[i][j] = 0; for(j = i; j < M; j++){ /* U行列の生成 */ u[i][j] = a[i][j]; for(k = 0; k < i; k++){ u[i][j] -= u[k][j] * l[i][k]; for(j = i+1; j < M; j++){ /* L行列の生成 */ l[j][i] = a[j][i]; l[j][i] -= u[k][i] * l[j][k]; l[j][i] /= u[i][i]; for(i = 0; i < M; i++){ /* c行列の生成 */ c[i] = b[i]; for(j = 0; j < i; j++){ c[i] -= l[i][j] * c[j]; for(i = M-1; i >= 0; i--){ /* x行列の生成 */ x[i] = c[i]; for(j = M-1; j > i; j--){ x[i] -= u[i][j] * x[j]; x[i] /= u[i][i]; printf("入力行列\n"); /* 入力行列の出力 */ printf("%10.5lf ",a[i][j]); printf("%10.5lf\n",b[i]); printf("\nL行列\n"); /* L行列の出力 */ printf("%10.5lf ",l[i][j]); printf("\n"); printf("\nU行列\n"); /* U行列の出力 */ printf("%10.5lf ",u[i][j]); for(i = 0; i < M; i++){ /* 解の出力 */ printf("x%d = %10.5lf\n",i,x[i]); printf( "Enter キーを1,2回押してください. プログラムを終了します\n"); ch = getchar(); return 0; プログラミング演習I

プログラミング演習I 実行結果

LU分解できない場合 Ai,iやuk,k等の対角上の要素が0であれば、0徐算が発生しLU分解できない。 例 0 3 4 1 20 0 3 4 1 20 3 2 2 2 19 5 6 2 3 27 4 8 5 2 14

ピボッティング(1) これを避けるために、0である要素を含む行と0でない要素を含む行を入れ替える(ピボッティング)。 例 プログラミング演習I ピボッティング(1) これを避けるために、0である要素を含む行と0でない要素を含む行を入れ替える(ピボッティング)。 例 0 3 4 1 20 3 2 2 2 19 5 6 2 3 27 4 8 5 2 14 3 2 2 2 19 5 6 2 3 27 4 8 5 2 14 0 3 4 1 20

ピボッティング(2) 0でなくても、0に近い小さな値で割ったときは丸め誤差が大きくなる。 プログラミング演習I ピボッティング(2) 0でなくても、0に近い小さな値で割ったときは丸め誤差が大きくなる。 この誤差を小さくするために、0でなくても、最も絶対値の大きな値を含む行と最も絶対値の小さな値を含む行 を入れ替える方がよい。

解が求まらない場合 以下の例のような場合は、連立一次方程式は解くことができない。 x0 + 2x1 + 2x2 + 2x3 = 19 プログラミング演習I 解が求まらない場合 以下の例のような場合は、連立一次方程式は解くことができない。 x0 + 2x1 + 2x2 + 2x3 = 19 x0 + 2x1 + 2x2 + 2x3 = 17 x0 + x1 + x2 +2x2 = 14 x1 + x2 + x3 = 10 x0 + 2x1 + 2x2 + 2x3 = 17 x0 + x1 + x2 +2x2 = 14 x1 + x2 + x3 = 10