- 締切済み
JScriptの添削お願いします。
連立一次方程式の解を求めるプログラムです。 下のプログラムで示した部分で2次元配列の行データの初期化をしたいのですがうまくいきません。 たぶんそこだけ間違えているだけだとは思いますが、他に間違えているところもあれば指摘お願いします。 全体的な書き直しで訂正を頂くよりも、今の状態からどこを直せばいいのか教えてもらえると勉強になります。 また、定数が3つから4つに増えた場合は、※(下記参照お願いします)にて単純に数字をコンマで区切って4つに増やせばいいのでしょうか? 例)var A=[ [1,-4,3.3], [1,-5,2.3], [1,-1,1.3], ],b=[-1,2,0.3] 他に下の方のプログラムも変えなければいけないのでしょうか? 以上質問2つありますが、片方だけでも結構ですのでよろしくお願いします。 以下がプログラムになります。 var A=[ [1,-4,3], [1,-5,2], [1,-1,1], ],b=[-1,2,0] //※ WScript.Echo("ガウスの消去法による解:"+Gauss(A,b)); function Gauss(A,b){ var s,x=new Array(A.length),M=new Array(A.length); //ガウスの消去法 for(var k=0;k<A.length-1;k++){ for(var i=k+1;i<A.length;i++){ M[i]=new Array() ; // ←ここが違うと思うのですが… M[i][k]=A[i][k]/A[k][k]; for(var j=k+1; j<A.length;j++) A[i][j]= A[i][j] - M[i][k]*A[k][j] ; b[i]=b[i]-M[i][k]*b[k]; } } //ガウスの消去法 for(var i=A.length-1;i>=0;i--){ s=0; for(var k=i+1;k<A.length;k++) s+= A[i][k]*s ; x[i]=(1/A[i][i])*(b[i]-s); } return x; }
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- fujillin
- ベストアンサー率61% (1594/2576)
なかなか、回答がないようなので… 「ガウスの消去法って何?」状態で見てますので、本物の付け焼刃ですが、 ・配列Aの内容を操作してよければ、必ずしもMの配列を作る必要はないと 思われます。しかも2次元である必要性はまったくありません。 (計算用に中間値を一時保存する変数があればよい) ・前半の行列操作でk行k列の係数を1にするのを忘れてませんか? ・解の計算はx[N]から順に求めてゆくはずですが、逆順になっていま せんか?(後退代入) ・最初のAへの代入の最終行に注意 (「,」をつけると、undefinedが追加されて、A.lengthは4になります) JScriptではありませんが、javascriptでもとの形に似せて書き直してみました。(構文はほぼ同じはず。確認はブラウザでしてください) 表示される結果が正しいのかどうかを、キチンと確認はしていません。 (多分、大丈夫だと思うといった程度です。いい加減ですみません) ・配列bもAに合わせてN行×(N+1)列の配列にしておく方が、値の操作が 全て添え字で行えるので、通常はそのような方法が取られているよう です。(この部分は、もとのままにしてあります。) ・また、誤差の縮小や0割の回避などのために、ピボット処理をするのが 通常のようですが、例では省略しています。(もとのコードに無いので) ・同様に、回答が無い場合(等価な式が含まれていたりする場合)のチェッ クがないとエラーになると思われます。(これも省略) --ご参考まで-- <html> <head> <script type="text/javascript"> var A=[ [1,-4,3.3], [1,-5,2.3], [1,-1,1.3] ], b=[-1,2,0.3]; matrix_check('◇開始時行列'); //←開始時の行列を表示 document.write('◆解の行列<br>' + Gauss(A,b).toString()); matrix_check('◇終了時行列'); //←終了時の行列を表示 function Gauss(A,b){ var k, i, j, p, q, N=A.length, x=[]; //ガウスの消去法 for (k=0; k<N; k++) { //pivotの処理をいれるならここ(省略) //解けない場合のチェックなども(省略) p = A[k][k]; A[k][k] = 1; b[k] /= p; for (j=k+1; j<N; j++) A[k][j] /= p; for (i=k+1; i<N; i++) { q = A[i][k]; A[i][k] = 0; b[i] -= q*b[k]; for (j=k+1; j<N; j++) A[i][j] -= q*A[k][j]; } } //解の計算 for (i=N-1; i>=0; i--) { x[i] = b[i]; for (j=N-1; j>i ;j--) x[i] -= A[i][j]*x[j]; } return x; } //行列内容の表示(確認用) function matrix_check(s){ var i, N = A.length; document.write('<p>' + s + '(A/b)<br>'); for (i=0; i<N; i++) document.write(A[i].toString() + ' / ' + b[i] + '<br>'); document.write('<br>'); } </script> </head> <body> </body> </html> なお、参考にしたサイトは以下です。 http://next1.cc.it-hiroshima.ac.jp/MULTIMEDIA/numeanal1/node28.html http://pc-physics.com/gauss1.html >単純に数字をコンマで区切って4つに増やせばいいのでしょうか? その通りです。