情報学部 | 菅沼ホーム | 目次 | 索引 |
2 1 1 1
/****************************/ /* 逆行列の計算 */ /* 例: 2 1 */ /* 1 1 */ /* coded by Y.Suganuma */ /****************************/ #include <stdio.h> int gauss(double **, int, int, double); int main () { double **w, eps; int i1, ind, n = 2, m = 2; /* データの設定 */ w = new double * [n]; for (i1 = 0; i1 < n; i1++) w[i1] = new double [n+m]; eps = 1.0e-10; w[0][0] = 2.0; w[0][1] = 1.0; w[0][2] = 1.0; w[0][3] = 0.0; w[1][0] = 1.0; w[1][1] = 1.0; w[1][2] = 0.0; w[1][3] = 1.0; /* 実行と出力 */ ind = gauss(w, n, m, eps); printf("ind = %d\n", ind); printf(" %f %f\n", w[0][2], w[0][3]); printf(" %f %f\n", w[1][2], w[1][3]); return 0; } /*******************************************************/ /* 線形連立方程式を解く(逆行列を求める) */ /* w : 方程式の左辺及び右辺 */ /* n : 方程式の数 */ /* m : 方程式の右辺の列の数 */ /* eps : 逆行列の存在を判定する規準 */ /* return : =0 : 正常 */ /* =1 : 逆行列が存在しない */ /*******************************************************/ #include <math.h> int gauss(double **w, int n, int m, double eps) { double y1, y2; int ind = 0, nm, m1, m2, i1, i2, i3; nm = n + m; for (i1 = 0; i1 < n && ind == 0; i1++) { y1 = .0; m1 = i1 + 1; m2 = 0; // ピボット要素の選択 for (i2 = i1; i2 < n; i2++) { y2 = fabs(w[i2][i1]); if (y1 < y2) { y1 = y2; m2 = i2; } } // 逆行列が存在しない if (y1 < eps) ind = 1; // 逆行列が存在する else { // 行の入れ替え for (i2 = i1; i2 < nm; i2++) { y1 = w[i1][i2]; w[i1][i2] = w[m2][i2]; w[m2][i2] = y1; } // 掃き出し操作 y1 = 1.0 / w[i1][i1]; for (i2 = m1; i2 < nm; i2++) w[i1][i2] *= y1; for (i2 = 0; i2 < n; i2++) { if (i2 != i1) { for (i3 = m1; i3 < nm; i3++) w[i2][i3] -= w[i2][i1] * w[i1][i3]; } } } } return(ind); }
/****************************/ /* 逆行列の計算 */ /* 例: 2 1 */ /* 1 1 */ /* coded by Y.Suganuma */ /****************************/ import java.io.*; public class Test { public static void main(String args[]) throws IOException { double w[][], eps; int ind, n = 2, m = 2; /* データの設定 */ w = new double [n][n+m]; eps = 1.0e-10; w[0][0] = 2.0; w[0][1] = 1.0; w[0][2] = 1.0; w[0][3] = 0.0; w[1][0] = 1.0; w[1][1] = 1.0; w[1][2] = 0.0; w[1][3] = 1.0; /* 実行と結果 */ ind = gauss(w, n, m, eps); System.out.println("ind = " + ind); System.out.println(" " + w[0][2] + " " + w[0][3]); System.out.println(" " + w[1][2] + " " + w[1][3]); } /*******************************************************/ /* 線形連立方程式を解く(逆行列を求める) */ /* w : 方程式の左辺及び右辺 */ /* n : 方程式の数 */ /* m : 方程式の右辺の列の数 */ /* eps : 逆行列の存在を判定する規準 */ /* return : =0 : 正常 */ /* =1 : 逆行列が存在しない */ /*******************************************************/ static int gauss(double w[][], int n, int m, double eps) { double y1, y2; int ind = 0, nm, m1, m2, i1, i2, i3; nm = n + m; for (i1 = 0; i1 < n && ind == 0; i1++) { y1 = .0; m1 = i1 + 1; m2 = 0; // ピボット要素の選択 for (i2 = i1; i2 < n; i2++) { y2 = Math.abs(w[i2][i1]); if (y1 < y2) { y1 = y2; m2 = i2; } } // 逆行列が存在しない if (y1 < eps) ind = 1; // 逆行列が存在する else { // 行の入れ替え for (i2 = i1; i2 < nm; i2++) { y1 = w[i1][i2]; w[i1][i2] = w[m2][i2]; w[m2][i2] = y1; } // 掃き出し操作 y1 = 1.0 / w[i1][i1]; for (i2 = m1; i2 < nm; i2++) w[i1][i2] *= y1; for (i2 = 0; i2 < n; i2++) { if (i2 != i1) { for (i3 = m1; i3 < nm; i3++) w[i2][i3] -= w[i2][i1] * w[i1][i3]; } } } } return(ind); } }
<!DOCTYPE HTML> <HTML> <HEAD> <TITLE>連立線形方程式と逆行列</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <SCRIPT TYPE="text/javascript"> method = 0; /**********************************************/ /* 連立方程式の解,逆行列,行列の乗算,行列式 */ /* coded by Y.Suganuma */ /**********************************************/ function main() { // 連立方程式の解,逆行列 if (method == 0 || method == 1) { let eps = 1.0e-10; let m = parseInt(document.getElementById("row").value); let A = new Array(); for (let i1 = 0; i1 < m; i1++) A[i1] = new Array(); let s = (document.getElementById("A").value).split(/ {1,}|\n{1,}/); let k = 0; for (let i1 = 0; i1 < m; i1++) { for (let i2 = 0; i2 < m; i2++) { A[i1][i2] = parseFloat(s[k]); k++; } } s = (document.getElementById("B").value).split(/ {1,}|\n{1,}/); k = 0; let n = m + 1; if (method == 1) n = 2 * m; for (let i1 = 0; i1 < m; i1++) { for (let i2 = m; i2 < n; i2++) { A[i1][i2] = parseFloat(s[k]); k++; } } let ind = gauss(A, m, n-m, eps); if (ind > 0) document.getElementById("C").value = "逆行列が存在しません!"; else { let str = ""; for (let i1 = 0; i1 < m; i1++) { for (let i2 = m; i2 < n; i2++) { if (i2 == n-1) str = str + A[i1][i2] + "\n"; else str = str + A[i1][i2] + " "; } } document.getElementById("C").value = str; } } // 行列の乗算 else if (method == 2) { let m = parseInt(document.getElementById("row").value); let n = parseInt(document.getElementById("c1").value); let l = parseInt(document.getElementById("c2").value); let A = new Array(); for (let i1 = 0; i1 < m; i1++) A[i1] = new Array(); let B = new Array(); for (let i1 = 0; i1 < n; i1++) B[i1] = new Array(); let C = new Array(); for (let i1 = 0; i1 < m; i1++) C[i1] = new Array(); let s = (document.getElementById("A").value).split(/ {1,}|\n{1,}/); let k = 0; for (let i1 = 0; i1 < m; i1++) { for (let i2 = 0; i2 < n; i2++) { A[i1][i2] = parseFloat(s[k]); k++; } } s = (document.getElementById("B").value).split(/ {1,}|\n{1,}/); k = 0; for (let i1 = 0; i1 < n; i1++) { for (let i2 = 0; i2 < l; i2++) { B[i1][i2] = parseFloat(s[k]); k++; } } for (let i1 = 0; i1 < m; i1++) { for (let i2 = 0; i2 < l; i2++) { C[i1][i2] = 0.0; for (let i3 = 0; i3 < n; i3++) C[i1][i2] += A[i1][i3] * B[i3][i2]; } } let str = ""; for (let i1 = 0; i1 < m; i1++) { for (let i2 = 0; i2 < l; i2++) { if (i2 == l-1) str = str + C[i1][i2] + "\n"; else str = str + C[i1][i2] + " "; } } document.getElementById("C").value = str; } // 行列式 else { let m = parseInt(document.getElementById("row").value); let A = new Array(); for (let i1 = 0; i1 < m; i1++) A[i1] = new Array(); let s = (document.getElementById("A").value).split(/ {1,}|\n{1,}/); let k = 0; for (let i1 = 0; i1 < m; i1++) { for (let i2 = 0; i2 < m; i2++) { A[i1][i2] = parseFloat(s[k]); k++; } } let v = det(m, A); document.getElementById("C").value = v; } } /*******************************************************/ /* 線形連立方程式を解く(逆行列を求める) */ /* w : 方程式の左辺及び右辺 */ /* n : 方程式の数 */ /* m : 方程式の右辺の列の数 */ /* eps : 逆行列の存在を判定する規準 */ /* return : =0 : 正常 */ /* =1 : 逆行列が存在しない */ /*******************************************************/ function gauss(w, n, m, eps) { let nm = n + m; let ind = 0; for (let i1 = 0; i1 < n && ind == 0; i1++) { let y1 = 0.0; let m1 = i1 + 1; let m2 = 0; // ピボット要素の選択 for (let i2 = i1; i2 < n; i2++) { let y2 = Math.abs(w[i2][i1]); if (y1 < y2) { y1 = y2; m2 = i2; } } // 逆行列が存在しない if (y1 < eps) ind = 1; // 逆行列が存在する else { // 行の入れ替え for (let i2 = i1; i2 < nm; i2++) { y1 = w[i1][i2]; w[i1][i2] = w[m2][i2]; w[m2][i2] = y1; } // 掃き出し操作 y1 = 1.0 / w[i1][i1]; for (let i2 = m1; i2 < nm; i2++) w[i1][i2] *= y1; for (let i2 = 0; i2 < n; i2++) { if (i2 != i1) { for (i3 = m1; i3 < nm; i3++) w[i2][i3] -= w[i2][i1] * w[i1][i3]; } } } } return ind; } /************************/ /* 行列式の計算 */ /* n : 次数 */ /* A : 行列 */ /* return : 行列式 */ /************************/ function det(n, A) { let v = 0.0; if (n == 1) v = A[0][0]; else if (n == 2) v = A[0][0] * A[1][1] - A[0][1] * A[1][0]; else if (n == 3) v = A[0][0] * A[1][1] * A[2][2] + A[1][0] * A[2][1] * A[0][2] + A[0][1] * A[1][2] * A[2][0] - A[2][0] * A[1][1] * A[0][2] - A[0][0] * A[1][2] * A[2][1] - A[0][1] * A[1][0] * A[2][2]; else { let B = new Array(); for (let i1 = 0; i1 < n-1; i1++) B[i1] = new Array(); let sgn = 1.0; for (let i1 = 0; i1 < n; i1++) { for (let i2 = 1; i2 < n; i2++) { for (let i3 = 0; i3 < n; i3++) { if (i3 != i1) { if (i3 < i1) B[i2-1][i3] = A[i2][i3]; else B[i2-1][i3-1] = A[i2][i3]; } } } v += sgn * A[0][i1] * det(n-1, B); sgn *= -1.0; } } return v; } /********/ /* 目的 */ /********/ function set_m() { let sel = document.getElementById("method"); for (let i1 = 0; i1 < 4; i1++) { if (sel.options[i1].selected) { method = i1; break; } } // 連立方程式 if (method == 0) { document.getElementById("row").value = "2"; document.getElementById("col1").style.display = "none"; document.getElementById("col2").style.display = "none"; document.getElementById("op").innerHTML = " x = "; document.getElementById("B").style.display = ""; document.getElementById("A").value = "2 1\n1 1"; document.getElementById("B").value = "1\n1"; } // 逆行列 else if (method == 1) { document.getElementById("row").value = "2"; document.getElementById("col1").style.display = "none"; document.getElementById("col2").style.display = "none"; document.getElementById("op").style.display = ""; document.getElementById("op").innerHTML = " x = "; document.getElementById("B").style.display = ""; document.getElementById("A").value = "2 1\n1 1"; document.getElementById("B").value = "1 0\n0 1"; } // 行列の乗算 else if (method == 2) { document.getElementById("row").value = "2"; document.getElementById("c1").value = "2"; document.getElementById("c2").value = "2"; document.getElementById("col1").style.display = ""; document.getElementById("col2").style.display = ""; document.getElementById("op").style.display = ""; document.getElementById("op").innerHTML = "×"; document.getElementById("B").style.display = ""; document.getElementById("A").value = "1 1\n1 1"; document.getElementById("B").value = "1 1\n1 1"; } // 行列式 else if (method == 3) { document.getElementById("row").value = "2"; document.getElementById("col1").style.display = "none"; document.getElementById("col2").style.display = "none"; document.getElementById("op").style.display = "none"; document.getElementById("B").style.display = "none"; document.getElementById("A").value = "1 0\n0 1"; } } </SCRIPT> </HEAD> <BODY STYLE="font-size: 130%; background-color: #eeffee;"> <H2 STYLE="text-align:center"><B>連立線形方程式と逆行列</B></H2> <DL> <DT> テキストフィールド及びテキストエリアには,連立方程式の解,逆行列,行列の乗算,及び,行列式の値を計算する例として,以下に示すような場合に対する値が設定されています.他の問題を実行する場合は,それらを適切に修正してください. <P STYLE="text-align:center"><IMG SRC="gauss.gif"></P> </DL> <DIV STYLE="text-align:center"> 目的:<SELECT ID="method" onChange="set_m()" STYLE="font-size:100%"> <OPTION SELECTED>連立方程式 <OPTION>逆行列 <OPTION>行列の乗算 <OPTION>行列式 </SELECT> 行数:<INPUT ID="row" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="2"> <SPAN ID="col1" STYLE="display: none"> 列数1:<INPUT ID="c1" STYLE="font-size: 100%;" TYPE="text" SIZE="2" VALUE="2"> </SPAN> <SPAN ID="col2" STYLE="display: none"> 列数2:<INPUT ID="c2" STYLE="font-size: 100%;" TYPE="text" SIZE="2" VALUE="2"> </SPAN> <BUTTON STYLE="font-size: 100%; background-color: pink" onClick="main()">OK</BUTTON><BR><BR> <TEXTAREA ID="A" COLS="20" ROWS="15" STYLE="font-size: 100%">2 1 1 1</TEXTAREA><SPAN ID="op"> x = </SPAN> <TEXTAREA ID="B" COLS="20" ROWS="15" STYLE="font-size: 100%">1 1</TEXTAREA><BR><BR> <TEXTAREA ID="C" COLS="30" ROWS="15" STYLE="font-size: 100%"></TEXTAREA> </DIV> </BODY> </HTML>
<?php /****************************/ /* 逆行列の計算 */ /* 例: 2 1 */ /* 1 1 */ /* coded by Y.Suganuma */ /****************************/ /* データの設定 */ $eps = 1.0e-10; $w = array(2); $w[0] = array(2.0, 1.0, 1.0, 0.0); $w[1] = array(1.0, 1.0, 0.0, 1.0); /* 実行と出力 */ $ind = gauss($w, 2, 2, $eps); printf("\$ind = %d\n", $ind); printf(" %f %f\n", $w[0][2], $w[0][3]); printf(" %f %f\n", $w[1][2], $w[1][3]); /******************************************/ /* 線形連立方程式を解く(逆行列を求める) */ /* $w : 方程式の左辺及び右辺 */ /* $n : 方程式の数 */ /* $m : 方程式の右辺の列の数 */ /* $eps : 逆行列の存在を判定する規準 */ /* return : =0 : 正常 */ /* =1 : 逆行列が存在しない */ /*******************************************/ function gauss(&$w, $n, $m, $eps) { $ind = 0; $nm = $n + $m; for ($i1 = 0; $i1 < $n && $ind == 0; $i1++) { $y1 = 0.0; $m1 = $i1 + 1; $m2 = 0; // ピボット要素の選択 for ($i2 = $i1; $i2 < $n; $i2++) { $y2 = abs($w[$i2][$i1]); if ($y1 < $y2) { $y1 = $y2; $m2 = $i2; } } // 逆行列が存在しない if ($y1 < $eps) $ind = 1; // 逆行列が存在する else { // 行の入れ替え for ($i2 = $i1; $i2 < $nm; $i2++) { $y1 = $w[$i1][$i2]; $w[$i1][$i2] = $w[$m2][$i2]; $w[$m2][$i2] = $y1; } // 掃き出し操作 $y1 = 1.0 / $w[$i1][$i1]; for ($i2 = $m1; $i2 < $nm; $i2++) $w[$i1][$i2] *= $y1; for ($i2 = 0; $i2 < $n; $i2++) { if ($i2 != $i1) { for ($i3 = $m1; $i3 < $nm; $i3++) $w[$i2][$i3] -= $w[$i2][$i1] * $w[$i1][$i3]; } } } } return $ind; } ?>
############################################ # 線形連立方程式を解く(逆行列を求める) # w : 方程式の左辺及び右辺 # n : 方程式の数 # m : 方程式の右辺の列の数 # eps : 逆行列の存在を判定する規準 # return : =0 : 正常 # =1 : 逆行列が存在しない # coded by Y.Suganuma ############################################ def gauss(w, n, m, eps) nm = n + m; ind = 0 for i1 in 0 ... n y1 = 0.0 m1 = i1 + 1 m2 = 0 # ピボット要素の選択 for i2 in i1 ... n y2 = w[i2][i1].abs() if y1 < y2 y1 = y2 m2 = i2 end end # 逆行列が存在しない if y1 < eps ind = 1 break # 逆行列が存在する else # 行の入れ替え for i2 in i1 ... nm y1 = w[i1][i2] w[i1][i2] = w[m2][i2] w[m2][i2] = y1 end # 掃き出し操作 y1 = 1.0 / w[i1][i1] for i2 in m1 ... nm w[i1][i2] *= y1 end for i2 in 0 ... n if i2 != i1 for i3 in m1 ... nm w[i2][i3] -= (w[i2][i1] * w[i1][i3]) end end end end end return ind end ############################################ # 逆行列の計算 # 例: 2 1 # 1 1 # coded by Y.Suganuma ############################################ # データの設定 eps = 1.0e-10 n = 2 m = 2 w = Array[[2.0, 1.0, 1.0, 0.0], [1.0, 1.0, 0.0, 1.0]] # 実行と出力 ind = gauss(w, n, m, eps) printf("ind = %d\n", ind) printf(" %f %f\n", w[0][2], w[0][3]) printf(" %f %f\n", w[1][2], w[1][3])
# -*- coding: UTF-8 -*- from math import * import numpy as np ############################################ # 線形連立方程式を解く(逆行列を求める) # w : 方程式の左辺及び右辺 # n : 方程式の数 # m : 方程式の右辺の列の数 # eps : 逆行列の存在を判定する規準 # return : =0 : 正常 # =1 : 逆行列が存在しない # coded by Y.Suganuma ############################################ def gauss(w, n, m, eps) : nm = n + m ind = 0 for i1 in range(0, n) : y1 = 0.0 m1 = i1 + 1 m2 = 0 # ピボット要素の選択 for i2 in range(i1, n) : y2 = abs(w[i2][i1]) if y1 < y2 : y1 = y2 m2 = i2 # 逆行列が存在しない if y1 < eps : ind = 1 break # 逆行列が存在する else : # 行の入れ替え for i2 in range(i1, nm) : y1 = w[i1][i2] w[i1][i2] = w[m2][i2] w[m2][i2] = y1 # 掃き出し操作 y1 = 1.0 / w[i1][i1] for i2 in range(m1, nm) : w[i1][i2] *= y1 for i2 in range(0, n) : if i2 != i1 : for i3 in range(m1, nm) : w[i2][i3] -= (w[i2][i1] * w[i1][i3]) return ind ############################################ # 逆行列の計算 # 例: 2 1 # 1 1 # coded by Y.Suganuma ############################################ # データの設定 eps = 1.0e-10 n = 2 m = 2 w = np.array([[2, 1, 1, 0], [1, 1, 0, 1]], np.float) # w = np.array([[2.0, 1.0, 1.0, 0.0], [1.0, 1.0, 0.0, 1.0]]) でもOK # w = np.array([[2, 1, 1, 0], [1, 1, 0, 1]]) はだめ # w = [[2, 1, 1, 0], [1, 1, 0, 1]] でもOK # 実行と出力 ind = gauss(w, n, m, eps) print("ind = " + str(ind)) print(" " + str(w[0][2]) + " " + str(w[0][3])) print(" " + str(w[1][2]) + " " + str(w[1][3]))
/****************************/ /* 逆行列の計算 */ /* 例: 2 1 */ /* 1 1 */ /* coded by Y.Suganuma */ /****************************/ using System; class Program { static void Main() { Test1 ts = new Test1(); } } class Test1 { public Test1() { /* データの設定 */ int n = 2; int m = 2; double eps = 1.0e-10; double[][] w = new double [n][]; w[0] = new double[] {2.0, 1.0, 1.0, 0.0}; w[1] = new double[] {1.0, 1.0, 0.0, 1.0}; /* 実行と結果 */ int ind = gauss(w, n, m, eps); Console.WriteLine("ind = " + ind); Console.WriteLine(" " + w[0][2] + " " + w[0][3]); Console.WriteLine(" " + w[1][2] + " " + w[1][3]); } /*******************************************************/ /* 線形連立方程式を解く(逆行列を求める) */ /* w : 方程式の左辺及び右辺 */ /* n : 方程式の数 */ /* m : 方程式の右辺の列の数 */ /* eps : 逆行列の存在を判定する規準 */ /* return : =0 : 正常 */ /* =1 : 逆行列が存在しない */ /*******************************************************/ int gauss(double[][] w, int n, int m, double eps) { int ind = 0; int nm = n + m; for (int i1 = 0; i1 < n && ind == 0; i1++) { double y1 = .0; int m1 = i1 + 1; int m2 = 0; // ピボット要素の選択 for (int i2 = i1; i2 < n; i2++) { double y2 = Math.Abs(w[i2][i1]); if (y1 < y2) { y1 = y2; m2 = i2; } } // 逆行列が存在しない if (y1 < eps) ind = 1; // 逆行列が存在する else { // 行の入れ替え for (int i2 = i1; i2 < nm; i2++) { y1 = w[i1][i2]; w[i1][i2] = w[m2][i2]; w[m2][i2] = y1; } // 掃き出し操作 y1 = 1.0 / w[i1][i1]; for (int i2 = m1; i2 < nm; i2++) w[i1][i2] *= y1; for (int i2 = 0; i2 < n; i2++) { if (i2 != i1) { for (int i3 = m1; i3 < nm; i3++) w[i2][i3] -= w[i2][i1] * w[i1][i3]; } } } } return ind; } }
'''''''''''''''''''''''''''' ' 逆行列の計算 ' ' 例: 2 1 ' ' 1 1 ' ' coded by Y.Suganuma ' '''''''''''''''''''''''''''' Module Test Sub Main() ' ' データの設定 ' Dim n As Integer = 2 Dim m As Integer = 2 Dim eps As Double = 1.0e-10 Dim w(,) = {{2.0, 1.0, 1.0, 0.0}, {1.0, 1.0, 0.0, 1.0}} ' ' 実行と結果 ' Dim ind = gauss(w, n, m, eps) Console.WriteLine("ind = " & ind) Console.WriteLine(" " & w(0,2) & " " & w(0,3)) Console.WriteLine(" " & w(1,2) & " " & w(1,3)) End Sub '''''''''''''''''''''''''''''''''''''''''' ' 線形連立方程式を解く(逆行列を求める) ' ' w : 方程式の左辺及び右辺 ' ' n : 方程式の数 ' ' m : 方程式の右辺の列の数 ' ' eps : 逆行列の存在を判定する規準 ' ' return : =0 : 正常 ' ' =1 : 逆行列が存在しない ' '''''''''''''''''''''''''''''''''''''''''' Function gauss(w(,) As Double, n As Integer, m As Integer, eps As Double) As Integer Dim ind As Integer = 0 Dim nm As Integer = n + m Dim i1 As Integer = 0 Do While i1 < n and ind = 0 Dim y1 As Double = 0.0 Dim m1 As Integer = i1 + 1 Dim m2 As Integer = 0 ' ピボット要素の選択 For i2 As Integer = i1 To n-1 Dim y2 As Double = Math.Abs(w(i2,i1)) If y1 < y2 y1 = y2 m2 = i2 End If Next ' 逆行列が存在しない If y1 < eps ind = 1 ' 逆行列が存在する Else ' 行の入れ替え For i2 As Integer = i1 To nm-1 y1 = w(i1,i2) w(i1,i2) = w(m2,i2) w(m2,i2) = y1 Next ' 掃き出し操作 y1 = 1.0 / w(i1,i1) For i2 As Integer = m1 To nm-1 w(i1,i2) *= y1 Next For i2 As Integer = 0 To n-1 If i2 <> i1 For i3 As Integer = m1 To nm-1 w(i2,i3) -= w(i2,i1) * w(i1,i3) Next End If Next End If i1 += 1 Loop Return ind End Function End Module
情報学部 | 菅沼ホーム | 目次 | 索引 |