人に聞けない痔の悩み、これでスッキリ >>

javaでn行n列の行列の2乗を求めたいのですが、どうすればよいでしょうか?3行3列の2乗はできたのですがn行n列への拡張の仕方がわかりません。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

行列のかけ算について調べて理論を理解しておいてください。



イメージ的には↓のようなプログラムになります

for(i=0; i<n; i++ ){
 for(j=0; j<n; j++ ){
  b[i][j] = 0 ;
  for(k=0; k<n; k++){
   b[i][j] += a[i][k]*a[k][j] ;
  }
 }
}

ちなみに実際に大規模行列の乗算を行う場合は、上記のようなijk形式のループではなく、キャッシュ等を考慮してブロック化したり演算の順序を変えたりします。
    • good
    • 0
この回答へのお礼

早い返信ありがとうございます。とりあえずやってみます。

お礼日時:2005/07/06 20:09

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QJava、2の0乗~10乗の表示

Javaのプログラムで
2の0乗~10乗までを改行表示したいのですが、for文を使って書かなければいけません。

まだ学んでいませんが累乗を計算する構文もあるようですが、それを使わずにfor文で2の0乗~10乗まで表示したいです。

1乗~10乗までは出来たのですが、0乗を含めることがどうしても出来ないので、回答お待ちしています。

Aベストアンサー

補足に書かれているところまでできているんだったら、
(案1)
int num = 1;
System.out.println(num); // 2を掛ける前にprintlnする
for(int i=0; i<10; i++){
num *= 2;
System.out.println(num);
}
でいいと思います。
別にfor文の中でprintlnしなくても、
for文に入る前にprintlnしていいんでしょ?

どうしてもfor文の中でprintlnしたいんだったら
(案2)
int num = 1;
for(int i=0; i<=10; i++){ // 10までループする
System.out.println(num); // 2を掛ける前にprintlnする
num *= 2;
}
でもいいと思います。
この場合2の10乗まで表示したあと、
さらに2を掛けてからループ終了なので、
不必要な計算が入ります。
私は案1の方がスマートでわかりやすいと思います。

QJavaを使った行列計算

Javaを使って行列の固有値などを求めるプログラムを
作りたいと考えています。そこで、自分で全て実装する前に
Javaのライブラリの中に行列を扱うクラスなどがあるのならば
それを利用したいと考えています。そこで、Javaのライブラリに
行列計算に適したクラスなどは用意されているでしょうか。
もしありましたら、教えて頂きたいと思います。お願いします。

Aベストアンサー

失礼 Apache Commons Math を使ってみましたが、どうやら対称行列の固有値計算しかサポートしていないようです。

線形代数の計算なら、JAMA がよさそうですね。
http://math.nist.gov/javanumerics/jama/

簡単な行列の固有値計算をしてみましたのでご参考までに。

[code]
public static void main(String[] args){
double[][] matrixData = {{2,1},{4,2}};
Matrix m = new Matrix(matrixData);
EigenvalueDecomposition dec = new EigenvalueDecomposition(m);

System.out.println(Arrays.toString(dec.getRealEigenvalues()));
}
[/code]

Q行列のn乗について

javaで複素行列のアルゴリズムを実装していて疑問に思ったのですが、
行列のn乗に関して、
(1) n = 0
(2) n は負の整数
(3) n は実数
(4) n は複素数
のそれぞれの場合に定義されていますでしょうか?

定義されている場合には、その概略を示していただくか
参考になるサイトをご紹介いただければ非常に幸いです。
以上、よろしくお願い申し上げます。

Aベストアンサー

回答が無いようですのでとりあえず..
正則行列であれば,とりあえず,実数までは定義可能です.Aが対象の行列で,これには逆行列が存在してA'が逆行列とします.
(1) A^0=A*A'=E:単位行列
(2)A^(-m)=(A')^m
(3) これを有理数に展開する.そのためには行列の乗式に対して結合法則や分配法則が必要となります.
(*1)A^(n(m))=A^nm
(*2)A^(n(m+k))=A^(nm+nk)
こうすると,A^(1/n)は(B)^n=Aとなる行列Bとなります.これから,A^(m/n)は結合法則(*1)からもとまります.これで,有理数に対してA^αを定義できました.これを実数にするには,有理数から実数を構成する方法(デテキントの切断やカントールの区間収縮法など)を用いることで,A^αのαを実数にまで拡張できます.
(4)については私の知識では分かりません.

Q行列をべき乗させるプログラム

2行2列を5乗させるプログラムを作って、一応できたつもりだったんですが結果が合いません・・・
何かヒントでもいいのでわかる方いらっしゃいましたらよろしくお願いします。

<プログラム>
#include <stdio.h>

#define N 2

int A[N][N];
int A_NEW[N][N];
int A_5[N][N]; /* 行列Aを5乗したもの */

int main()
{
int i,j,k,l;

/* 2行2列の係数行列Aの成分を入力 */
printf("係数行列Aを%d行%d列で入力してください\n", N, N);

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("A[%d][%d]=", i+1, j+1);
scanf("%d", &A[i][j]);
}
}

for(i=0; i<N; i++)/* A_NEW=A*Aの計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_NEW[i][j] += A[i][k] * A[k][j];
}
}
}

for(l=0; l<3; l++)
{
for(i=0; i<N; i++)/* A_5の計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_5[i][j] += A_NEW[i][k] * A[k][j];
}
}
}

for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
A_NEW[i][j] = A_5[i][j];
}
}
}

printf("A_5=\n"); /* 出力 */

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("%d ", A_5[i][j]);
}
printf("\n");
}
}


<入力例>
A=
1 3
2 1

<期待する結果>
A=
241 303
202 241

<このプログラムの結果>
406 498
332 406

2行2列を5乗させるプログラムを作って、一応できたつもりだったんですが結果が合いません・・・
何かヒントでもいいのでわかる方いらっしゃいましたらよろしくお願いします。

<プログラム>
#include <stdio.h>

#define N 2

int A[N][N];
int A_NEW[N][N];
int A_5[N][N]; /* 行列Aを5乗したもの */

int main()
{
int i,j,k,l;

/* 2行2列の係数行列Aの成分を入力 */
printf("係数行列Aを%d行%d列で入力してください\n", N, N);

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
...続きを読む

Aベストアンサー

#include <stdio.h>

#define N 2

int A[N][N];
int A_NEW[N][N];
int A_5[N][N]; /* 行列Aを5乗したもの */

int main()
{
int i,j,k,l;

/* 2行2列の係数行列Aの成分を入力 */
printf("係数行列Aを%d行%d列で入力してください\n", N, N);

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("A[%d][%d]=", i+1, j+1);
scanf("%d", &A[i][j]);
}
}

for(i=0; i<N; i++) /* A_NEW=A*Aの計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_NEW[i][j] += A[i][k] * A[k][j];
}
}
}

for(l=0; l<3; l++)
{
for(i=0; i<N; i++) /* A_5の計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_5[i][j] += A_NEW[i][k] * A[k][j]; /* …P */
}
}
}

for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
A_NEW[i][j] = A_5[i][j];
}
}

/* 一端0に戻さないと残存している結果にPを足されることになる …Q*/

for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
A_5[i][j] = 0;
}
}


}

printf("A_5=\n"); /* 出力 */

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("%d ", A_NEW[i][j]); /* Qで0に戻しちゃったので出力結果の変数が変わっています。*/
}
printf("\n");
}
}

/*
ただ,個人的には,二つの行列を計算するだけの関数を分けて
mainから5回呼び出した方が綺麗だと思う
面倒なので書かないけど,ここまで自力でコード書く人なら
これだけできちんと書けるだけの人なはず。頑張ってね!
*/

#include <stdio.h>

#define N 2

int A[N][N];
int A_NEW[N][N];
int A_5[N][N]; /* 行列Aを5乗したもの */

int main()
{
int i,j,k,l;

/* 2行2列の係数行列Aの成分を入力 */
printf("係数行列Aを%d行%d列で入力してください\n", N, N);

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("A[%d][%d]=", i+1, j+1);
scanf("%d", &A[i][j]);
}
}

for(i=0; i<N; i++) /* A_NEW=A*Aの計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_NEW[i][j] += A[i][k] * A[k][j]...続きを読む


人気Q&Aランキング