質問するログイン新規登録

Q&A

解決済

2回答

628閲覧

ヤコビ法のプログラムの解説をお願いします

lap._

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2024/12/08 14:21

0

1

実現したいこと

プログラムがなにもわからないまま難しい授業に突入してしまいわからないところがわからないので、どなたか優しい方解説していただけますか。

発生している問題・分からないこと

連立方程式を行列Aにすることはわかります。ただ、最初のepsからコードが全く分かりません。このコードはクラスの人が送ってくれました。先生に聞こうと思ったのですが、調べての一点張りで(ごもっとも)。ただ、前述したとおり、まったくわからないので、わからないコードを調べると調べたところで分からないことが発生してまいってしまいました。

該当のソースコード

import numpy as np eps=1e-8 N=100 A=np.matrix([[4,-1,-1,0,200], [-0.25,1,0,-0.25,50], [-0.5,0,2,-0.5,50], [0,-0.01,-0.01,0.04,1]]) n,m=np.shape(A) b=A[:,m-1] for i in range(n): A[i]/=A[i,i] b/=A[i,i] x=np.matrix([[100],[100],[75],[68.75]]) B=np.eye(n)-A[:,0:n] for m in range(N): x_tmp=np.copy(x) x=b+B*x_tmp if np.linalg.norm(x-x_tmp)<eps: break for i in range(n): print('x[%d]=%f'%(i,x[i,0]))

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

x[0]=87.500000
x[1]=87.500000
x[2]=62.500000
x[3]=62.500000

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

meg_

2024/12/08 14:59

> プログラムがなにもわからないまま難しい授業に突入してしまい 状況が分からないのですがまず何の授業でしょうか? 「 プログラムがなにもわからない」というのはPythonの文法が分からないという意味でしょうか?文法についてはある程度暗記するしかないと思いますが。
nururi

2024/12/09 01:38

> プログラムがなにもわからないまま難しい授業に突入してしまいわからないところがわからないので、どなたか優しい方解説していただけますか。 さすがに授業で急に知らない事ばかり詰め込んでくるとは思えないので、今までの授業をきちんと受けていなかっただけではないですか? ジタバタしてもどうにもならないので、今からでも頑張って復習するか、諦めて留年するか好きな方を選んでください。
srsnsts

2024/12/09 02:00

meg_さん 横から失礼します。 授業についてはおそらく、数値計算で連立方程式の解を求めるプログラミングの授業だと思います。 提題のコードは、その手法の一つであるヤコビ法だと思われます。
lap._

2024/12/10 01:52

meg_さん、回答ありがとうございます。 for文やif文とかの簡単な文法はある程度覚えているのですが、np.~や[:,0:n]がなにを表しているかわからなかったです。
lap._

2024/12/10 02:00

nururiさん、回答ありがとうございます。誠に仰られる通りでございます。普通に諦めて留年したほうがいいですよね...。私何をしても覚えられないし課題の提出二週間前からわからなくてしらみつぶしに調べていって調べていった先で全く見たことのないコードが出てきてそれをまた調べてもまたわからないのが出てきて普通に精神的に参っていただけなので、こんなくそみたいなやつに回答なんかされなくても大丈夫ですよ。nururiさんの貴重なお時間を無駄にしてしまい誠に申し訳ございませんでした。
AbeTakashi

2024/12/10 02:04

numpyに関する知識が足りないのだと思います。まずはnumpyの部分の復習をしたり、本やネットなどを頼りにしてnumpyに関する基礎知識を身につけるところからです。 それでもお手上げということであれば、Udemyのような講座を受けることを検討しても良いかもしれません。残念ですがこのサイトは手取り足取り教えてもらえるようなサイトではないので。 参考 https://teratail.com/help/question-tips https://www.udemy.com/courses/search/?src=ukw&q=numpy
meg_

2024/12/10 03:46

> np.~や[:,0:n]がなにを表しているかわからなかったです。 numpyモジュールの使い方や配列操作についてですね。よく使う関数はそれほど多くはないかと思うので反復練習が効果的かと思います。私はドキュメントを読みつつそれでも分からない箇所はネット検索しています。
guest

回答2

0

eps っていうのは、ギリシャ文字のイプシロンで、誤差のことです。
x と x_tmpの差を取ってその誤差がeps未満なら、計算を打ち切り、

if np.linalg.norm(x-x_tmp)<eps: break

解が求められたと判断するわけです。

投稿2024/12/09 01:54

srsnsts

総合スコア515

lap._

2024/12/10 01:47

ありがとうございます!
srsnsts

2024/12/10 03:03

誤差のところだけじゃなくて、 もう少し全般的な解説が必要な感じですか? ・numpyのこと ・コードの意味 とか。
guest

0

ベストアンサー

ヤコビ法(Wikipedia)の「具体例」の前に記載されている漸化式を実装するという内容で説明します。なお,連立方程式「Ax = b」の係数行列「A」と右辺ベクトル「b」を横方向に結合した行列(拡大係数行列)を「該当のソースコード」では A と記述していますが,以下の説明等では「A」は係数行列を表し,「Ab」で拡大係数行列を表すことにします。

まず,漸化式を使う前に事前に以下の処理をこの順番で行います。

  • 漸化式で「1/aii = 1」(すなわち「aii = 1」)となるように「A」と「b」の i 行目を「aii」で除算する(等式両辺の除算なので数学的には解「x」に影響はない)

  • 漸化式の「Σ」の条件式「j ≠ i」を実現するため「aii = 0」とする(前項により他で「aii」は使わなくなったので影響はない)

なお,「該当のソースコード」ではこれらの処理を「拡大係数行列」に対して行い,その後に係数行列と右辺ベクトルに分けて漸化式で使っています。

一方,これらの事前処理と漸化式を numpy モジュールを使って Python で記述するにあたり,「該当のソースコード」には以下のような修正した方が良い点があります。

  • データ型として numpy.matrix (行列型)は既に非推奨となっているので,numpy.ndarray(多次元配列型)を使った方が良いでしょう(行列とは2次元配列のことなので移行可です)

  • 事前処理の2番目の「対角成分をゼロにする」ために B = np.eye(n) - A[:, 0:n] と記述していますが,(数値解析の課題でもあり?)誤差の混入を減らすためにも直接ゼロを代入した方が良いでしょう

以上を踏まえた記述例を下記に示します。

なお,記述例の中の Ab[:, :-1] は2次元配列 Ab の最終列を除いた2次元配列を,Ab[:, -1]Ab の最終列のみの1次元配列を表します([]の使い方は Indexing on ndarrays 等を参照ください)。また,漸化式の中の @ 演算子は配列の積を表します(詳細は numpy.matmul 等を参照ください)。

Python

1import numpy as np 2 3eps = 1e-8 4N = 100 5 6Ab = np.array([[4, -1, -1, 0, 200], 7 [-0.25, 1, 0, -0.25, 50], 8 [-0.5, 0, 2, -0.5, 50], 9 [0, -0.01, -0.01, 0.04, 1]]) 10n, m = np.shape(Ab) # m = n + 1 11 12for i in range(n): 13 Ab[i] /= Ab[i, i] 14 Ab[i, i] = 0 15 16A, b = Ab[:, :-1], Ab[:, -1] 17x = np.array([100, 100, 75, 68.75]) 18 19for i in range(N): 20 x_tmp = x.copy() 21 x = b - A @ x_tmp 22 if np.linalg.norm(x - x_tmp) < eps: 23 break 24 25print(i + 1, x) 26# 32 [87.5 87.5 62.5 62.5]

投稿2024/12/13 10:10

little_street

総合スコア563

lap._

2024/12/15 08:22

丁寧にありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.25%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問