• 締切済み

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; }

みんなの回答

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.1

なかなか、回答がないようなので… 「ガウスの消去法って何?」状態で見てますので、本物の付け焼刃ですが、 ・配列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つに増やせばいいのでしょうか? その通りです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • JavaScriptについての質問です。

    ガウスの消去法による解の求め方をプログラムしたいのですが、上手くいかなかったので質問しました。以下のプログラムから実行はできるのですが、解が求められていませんでした。 どこを変えればきちんとできるのでしょうか、回答お願いします。 var A=[[1,-1,1],[1,2,0],[2,0,3]],b=[5,1,9]; WScript.Echo("ガウスの消去法の解:\n"+Gauss(A,b)); function Gauss(A,b) { var s,x=new Array(A.length),M=new Array(A.length); for(var i=k+1;i<A.length-1;k++) { for(var i=k+1;i<A.length;i++) { M[i]=new Array(A.length); 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.lengh-1;i>=0;i--) { s=0; for(var k=i+1;k<A.length;k++) s+=A[i][k]*x[k]; x[i]=(1/A[i][i])*(b[i]-s); } return x; }

  • 多次元配列とfor文について

    javascriptの配列について質問です。 例えば: var arrXXX = new Array(); function samplefunc{ //3次元配列の種類の作成 for (m = 0; m < aaa.length ; m++) { //連想配列作成 arrXXX .push(aaa[m]); } for (j = 0; j < bbb.length; j++) { for (i = 0; i < ccc.length; i++) { arrXXX[aaa[j]] = new Array(ccc.length); arrXXX[aaa[j]][i] = new Array(ccc.length); for (k = 0; k < ddd.length; k++) { arrXXX[aaa[j]][i][k] = eee;     ここでは配列を適切に使える・・・ } } } ここでarrXXXを使いたいが、3次元配列でなくなっている?!  arrXXX[~][0][0]はnullまたはオブジェクトではありません・・・がでます。 } 結局、for文を完全にでてしまうと、せっかくつくった配列がダメになってしまいます。どうすればfor文外で配列を使用できるのか教えてください!

  • javascriptの2次元配列をソートの仕方

    function word_grouping(data) { var code = data; //先頭についている”code="を除去 code = code.replace("code=",""); var = code.split(","); var alpha =new Array(); alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M']; //2次元配列作成 var array = new Array(); for (i =0; i < alpha.length; i++) { array[i] = [' ','0']: } //グループ名を格納 for( i = 0; i <alpha.length; i++){ array[i][0] = alpha[i] //0番目の項目から順番にグループごとに分ける for( i = 0; i < sp.length; i++){ group = sp[i].substring(0.1); //どのグループに所属しているか調べる for( j = 0; j < alpha.length; j++){ //一致したグループの配列にカウント+1していく if(group == array[j][0]{ array[j][1]++; } } } メモ ・spにはグループのどこかに所属する20個のキーワードが入っていてそれをグループに振り分けている ・グループ分けには”A001”のAだけみて振り分けています したいこと ・arrayに入ったキーワードの数を降順で並び替えたい 分からない所 ・2次元配列をsortする仕方 こんな感じなんです わかる方回答お願いします。

  • AS3.0ですが、下記2つのコードの違いがわかりません。。

    AS3.0ですが、下記2つのコードの違いがわかりません。。 ↓こちらのコードは undefined になるのですが、 --------------------------------- var box:Array = new Array(); for(var j=0; j<1; j++){ for(var i=0; i<10; i++){ box[j] = new Array(); box[j][i] = i+j; } } trace(box[0][0]); ----------------------------------- ↓こちらのコードは値をとることが出来ます。 ----------------------------------- var box:Array = new Array(); for(var k=0; k<10; k++){ box[k] = new Array(); } for(var j=0; j<1; j++){ for(var i=0; i<10; i++){ box[j][i] = i+j; } } trace(box[0][1]); ----------------------------------- どういう理由で、値が取れるのでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • Flash
  • 二次元配列に数字をランダムに入れる

    --------------------------- | 2 | 3 | 7 | 4 | 1 || 17 |<横合計> --------------------------- | 6 | 1 | 2 | 3 | / || // | --------------------------- | 1 | / | / | / | / || // | --------------------------- | 2 | / | / | / | / || // | --------------------------- | 3 | / | / | / | / || // | --------------------------- --------------------------- | 14 | / | / | / | / || // |<全合計> --------------------------- <縦合計> このように表示される。 …という処理がしたいのですがどういう処理を書けば良いのかわかりません。 理解した(1)と(2)の乱数発生の文を書いておきます。 *二次元配列を作成* a = new Array(5) for (i = 0; i <= a.length-1; i++){ //1次元 a[i] = new Array(5) for (j = 0; j <= a[i].length-1; j++){ //2次元 a[i][j] = "["+ i +","+ j +"]" var g = ""; document.write(a[i][j]); } } *乱数を100回発生* var z = ""; for(k = 1; k <= 100; k++){ z = Math.round(Math.random()); //発生した乱数をzに代入 } 以上、 よろしくお願いいたします。

  • ガウス消去

    行列3*3で4列目に答えが入る、ガウス消去の前進消去のプログラムを考えたのですが、3行目まで正規化してしまいます。 前進消去したのを行列mに格納しています。 int main() { int i, j, k,n=3; double a[3][4]={{ 3, 2,-3,-2}, { 2,-2, 1, 7}, {-3, 6, 5,28}}; double m[3][4]; /* 前進消去 */ for( i = 0; i < n; i++ ) { for( j = i+1; j <= n; j++ ) { m[i][j] = a[i][j]/a[i][i]; m[i][i]=1; for( k = i+1; k <= n+1; k++ ) { a[k][j] = a[k][j] -a[k][i] * m[i][j]; m[j][i]=0; }}}

  • 連立方程式を解くプログラムの後退代入の所

    連立方程式を解くプログラムで前進消去の部分はできたのですが、後退代入の所がうまくいきません。教えて!gooを通して皆さまの力をお借りできればと思います。よろしくお願いいたします。 import java.io.*; import java.util.*; import java.math.*; //連立方程式を解くプログラム class krm3{ public static void main(String args[]){ System.out.println("連立方程式を求めます。"); //declaring and allocating2> double[][] A = null; try{ BufferedReader br = new BufferedReader (new FileReader("renritu.txt")); String s; String[] vals; int rows = 0,cols = 0; while((s = br.readLine()) !=null){ vals = s.split(" ");//split the line with space cols = Math.max(cols,vals.length); rows++; } System.out.println(rows+"×"+cols+" array found"); A = new double[rows][cols]; br.close(); br = new BufferedReader(new FileReader("renritu.txt")); rows = cols = 0; while((s = br.readLine()) !=null){ vals =s.split(" ");//split the line with space cols = vals.length; for(int i=0; i<cols;i++) A[rows][i]=Double.parseDouble(vals[i]); rows++; } }catch (IOException e){ System.out.println(e); } for(int i = 0;i<A.length;i++){ for(int j=0;j<A[i].length;j++){ System.out.print(A[i][j]+" "); } System.out.println(); } System.out.println(); //掃き出し法 //前進消去 //行i=0~n-2に対してi+1行目以降のi列目を消去する(ただしnは行の数) // //i行目をピポッド(i,i)で正規化(割る) // 1行目に(j,i)要素をかけてj行目から引く for(int i = 0;i<A.length-1;i++){ double P = A[i][i];//pivot for(int j=0;j<A[i].length;j++) A[i][j]/= P; for(int k=i+1;k<A.length;k++){ double v = A[k][i]; for(int j=0;j<A[i].length;j++){ A[k][j]-= A[i][j]*v; } } } for(int i = 0;i<A.length;i++){ for(int j=0;j<A[i].length;j++){ System.out.print(A[i][j]+" "); } System.out.println(); } System.out.println(); // eqs= // 1 2 3 4 // 0 1 7 8 // 0 0 1 2 //後退代入 //行i=n-1~1に対してi-1行目以前のi列目を消去する for(int i = A.length;2<i;i--){ double P2 = A[i-1][i-1] ;//pivot for(int j=A[i-1].length;j>2;j--) A[i-1][j-1]/= P2; for( int k=i-1;k>2;k--){ double v2 = A[k-1][i-1]; for(int j=A[i].length;j>2;j--){ A[k][j]-= A[i][j]*v2; } } } for(int i = 0;i<A.length;i++){ for(int j=0;j<A[i].length;j++){ System.out.print(A[i][j]+" "); } System.out.println(); } System.out.println(); } }

  • ガウスの消去法のプログラム

    ガウスの消去法(部分ピボット選択)のプログラムを組んでみたつもりなのですが上手くいきません。 間違いだらけだと思いますがどうかアドバイスをして頂けませんでしょうか? #include <stdio.h> double main(void){ int i,j,k,N,M,m; double A[N+1][N+1][N+1],B[j],S,X[N+1]; printf("次数の入力。\n"); scanf("%d",&N); for(k=1;k<=N;k++){ for(i=1;i<=N;i++){ for(j=1;j<=N+1;j++){ A[k][i][j]=0; } } } for(i=1;i<=N;i++){ for(j=1;j<=N+1;j++){ printf("係数の入力.\n A[1][%d][%d]?\n",i,j); scanf("%f",&A[1][i][j]); } } for(k=2;k<=N;k++){ if(A[k-1][k-1][k-1]=0){ for(M=k;M<=N;M++){ if(A[k-1][M][k-1]!=0){ for(j=k-1;j<=N+1;j++){ B[j]=A[k-1][k-1][j]; A[k-1][k-1][j]=A[k-1][M][j]; A[k-1][M][j]=B[j]; } goto abc; } else {printf("解は無い\n");} } } abc: for(i=k;i<=N;i++){ for(j=k;j<=N+1;j++){ A[k][i][j]=A[k-1][i][j]-(A[k-1][i][k-1]/A[k-1][k-1][k-1])*A[k-1][k-1][j]; } } X[N]=A[N][N][N+1]/A[N][N][N]; printf("解X(N)は %f 。\n",X[N]); for(k=N-1;k>=1;k--){ S=0; for(m=N;m>=k+1;m--){ S+=A[k][k][m]*X[m]; } X[k]=(A[k][k][N+1]-S)/A[k][k][k]; printf("解X(%d)は %f 。\n",k,X[k]);} } }

  • お願いします。m(><)m

    つい最近Javaのプログラミングを大学ではじめたものなんですが、 次のような課題を出されたのですが全然わからないため困っており・・・ どなたか分かる方ぜひ教えていただけないでしょうか?m(><)m 3.次のプログラムは何を行うプログラムか.簡単に説明しなさい.また, 結果を得るまでに,A[k]==aの比較が行われた回数を書きなさい. A=new Array(3, 8, 19, 20, 22, 24, 45); i=0; j=A.length-1; a=19; k=Math.floor((i+j)/2); while(i<=j){ if(A[k] == a){ break; } else if(A[k] > a){ j = k - 1; } else{ i = k + 1; } k = Math.floor((i+j)/2); } if(i>j) k=-1; document.write(a," ",k);

  • 重複しない乱数を作り配列に入れる(AS3.0)

    Flash Pro CS5 AS3.0 で記述しています。 1~10の整数をランダムかつ重複せずに配列に格納したいと考えています。 そこで,ネット上で参考になるソースを見つけ, 以下のように書き直しました。 var int_a = new Array(); var int_b = new Array(); function RandomInt():void{ //ここだけ変更すればよい var maxN:Number = 10;//乱数の最大値 //0~maxNの数字を全部配列に入れる for (var i:int=0; i< maxN; i++) { int_a[i] = i+1; } var j:Number = 0; var a_length:Number = int_a.length; //要は配列をシャッフルする while (a_length) { var int_r:Number = Math.floor(Math.random()*(maxN+1-j)); //乱発生した整数を配列int_bに順番に入れ、int_aから削除する int_b[j] = int_a.splice(int_r, 1); j++; //配列int_a内の数字が一つずつ減っていく a_length = int_a.length; } //ここで配列int_bがシャッフルされた trace(int_b); } RandomInt(); としました。 しかし出力結果がなぜか 8,2,4,9,,7,6,5,10,3,1のように抜けている部分があり, 次のフレームで for(var j:int=1; j <= 10; j++){   trace(int_b[j]); } として確認してもやはり 2 4 9 7 6 5 10 3 1 となってしまします。 どの部分がおかしいのか教えていただきたいです。 また,乱数発生の部分で Math.floor(Math.random()*(maxN+1-j)); という風に記述してあったのですが,ここは間違いではないのでしょうか? jを引いていくと発生する乱数の範囲が徐々に狭くなっていってしまうと思ったのですが; それとも元のソースコードを使って ttp://www.renowan.com/blog/?p=143 0~9までの乱数を発生させてそれぞれに1を足す方が簡単でしょうか? よろしくお願いします。

    • ベストアンサー
    • Flash