行列の積を求めるプログラム

このQ&Aのポイント
  • 行列の積を求めるプログラムを作成したい
  • 現在、2次元配列を渡すためには行数または列数が必要である
  • 一般の行列の積の演算を可能にする方法を知りたい
回答を見る
  • ベストアンサー

(汎用的に)行列の積を求めるプログラム

L*M実行列A , M*N実行列B , M*N実行列C を引数として、A*BをCに代入するプログラムを作りたいと思っています。 具体的には、エラーがでるのはわかっていますがイメージとして void multiply(int L,int M,int N,double A[L][M],double B[M][N],double C[L][N]) {       for(int l=0;l<L;l++)    for(int n=0;n<N;n++)    C[l][n]=0;       for(int l=0;l<L;l++){            for(int m=0;m<M;m++){                   for(int n=0;n<N;n++)       C[l][n]+=A[l][m]*B[m][n];            }      } } という感じです。Cを自分なりに学習したところ、「2次元配列を渡すには行or列数が少なくとも既知でないといけない」のは知識として得ているのですが、ではこの問題を回避して所望のプログラムを書け、と言われると行き詰ってしまいました。 卒論をするにあたり、種々のサイズの行列演算が必要なので、できるだけ効率的な関数を書いておきたいのですが、どうすれば一般の行列の積の演算が可能になるのでしょうか?

  • expiz
  • お礼率39% (18/46)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.11

No.2 です。 とりあえず、(インクルードフォルダだけではなく)多分同じ所にある、「ライブラリのサーチフォルダ」(のような名前の所)に、該当の lib が存在するフォルダを追加すればいいのかなと思います。 maxtrix くらいなら、ヘッダファイルだけをインクルードすれば使えると思っていたのですが、なぜに、ライブラリをリンクしようとするのか? という気はしますが。 もしも、明示的に、libboost_serialization-vc100-mt-gd-1_44.lib をプロジェクトに加えていたのなら、このファイルをプロジェクトから外してみるのもいいかなとは思います。

expiz
質問者

お礼

ありがとうございます! プロパティマネージャのmicrosoft.cpp.win32のプロパティ内から、リンカー→全般→追加のライブラリディレクトリに該当のlibフォルダを追加したところ解決しました。 >>ヘッダファイルだけをインクルードすれば使えると思っていたのですが、なぜに、ライブラリをリンクしようとするのか? という気はしますが。 すいません、、、gogle先生で探した導入マニュアルページに従っていく以外の知識が無いものでして・・・

その他の回答 (11)

noname#137556
noname#137556
回答No.12

ANo.10 のお礼について multiply 関数などの定義に合わせると,全要素分をまとめて確保しないといけません。   double *pa = new double[L*M]; > MATLABは知人の研究室で採用しているらしいですが、 > このソフトは1コマンド1応答?形式と聞いています。 おっしゃる通り対話式に計算させることも出来ますし, プログラム(M ファイル)を作っておいて実行させることも出来ます。 もちろん,for や if などの制御構造も使えますし,独自の関数を定義することも可能です。 http://www.mathworks.co.jp/help/ja_JP/techdoc/ref/for.html

noname#137556
noname#137556
回答No.10

#4 です。 行列を作る部分も関数化してこんなのをイメージしてました。  MATRIX a, b, c;    // MATRIX 構造体  Eye(&a, L, M);     // a を単位行列で初期化  Eye(&b, M, N);     // b を単位行列で初期化  Product(&c, &a, &b); // 積の計算 c = a b 計算が目的なら,MATLAB を使えば #4 の補足の計算は,  a = eye(L, M)  b = eye(M, N)  c = a * b これだけで済みます。 分野によっては当たり前のように使われるので,覚えておいて損はないと思いますよ。 よく似た Scilab は無料で入手できるので,遊んでみてください。 http://www.scilab.org/

expiz
質問者

お礼

再度の回答ありがとうございます。 MATLABは知人の研究室で採用しているらしいですが、このソフトは1コマンド1応答?形式と聞いています。 例えばfor文のように、パラメータを更新しつつ繰り返し繰り返し演算させることはできるのでしょうか? 先の1次配列として計算させるというお言葉をヒントにして再度プログラムを書いたのですが、ビルドエラーは出ませんが異常終了してしまいました。。。申し訳ないですがご指導頂けないでしょうか? 今までポインタを使わず、なるべく配列のみで処理してきたのでこのあたりの理解が劣っているのは、恥ずかしながら自覚しておりますが。 #include<iostream> #include<cmath> using namespace std; void initialize(int L,int M,double* pa); void multiply(int L,int M,int N,double* pa,double* pb,double* pc); void print(int L,int M,double* pa,char* ch); int main() { const int L=2; const int M=3; const int N=4; double** A = new double* [L]; for(int l=0;l<L;l++) A[l] = new double [M];//A[L][M] double* pa=&A[0][0]; double** B = new double* [M]; for(int m=0;m<M;m++) B[m] = new double [N];//B[M][N] double* pb=&B[0][0]; double** C = new double* [L]; for(int l=0;l<L;l++) C[l] = new double [N];//C[L][N] double* pc=&C[0][0]; initialize(L,M,pa); initialize(M,N,pb); initialize(L,N,pc); multiply(L,M,N,pa,pb,pc); print(L,M,pa,"A"); print(M,N,pb,"B"); print(L,N,pc,"C"); for( int l=0; l<L; l++) delete [] A[l]; delete [] A; for( int m=0; m<M; m++) delete [] B[m]; delete [] B; for( int l=0; l<L; l++) delete [] C[l]; delete [] C; return 0; } void initialize(int L,int M,double* pa) { for(int l=0;l<L;l++){ for(int m=0;m<M;m++){ //if(l!=m) pa[l*M+m]=0; //else pa[l*M+m]=1; pa[l*M+m]=1; } } } void multiply(int L,int M,int N,double* pa,double* pb,double* pc) { for(int l=0;l<L;l++) for(int m=0;m<M;m++) for(int n=0;n<N;n++) pc[l*N+n]=pa[l*M+m]*pb[m*N+n]; } void print(int L,int M,double* pa,char *ch) { for(int l=0;l<L;l++){ for(int m=0;m<M;m++){ cout<<ch<<"["<<l<<"]["<<m<<"]is "<<"="<<pa[l*M+m]<<endl; } } }

  • Interest
  • ベストアンサー率31% (207/659)
回答No.9

私も、ANo.7 の boostライブラリに1票。 目的は卒研用のプログラムを動かすことであって、行列演算のライブラリを作ることではありませんよね。 世の中で広く使われているライブラリがあるのですから、そちらを使ったほうが時間も労力も大幅に(数週間分以上)節約できると思います。なにしろ、自分で作るとバグも大量に作りこむことになるので。:-p) C++やboostに抵抗があるなら、matlibという手もあります。 http://robot.cs.kobe-u.ac.jp/contents/staff/hanahara/programs/matlib.html いずれにしても、先人が苦労して作ってくれたものがあるのに、似たようなものをまた作るというのは無駄な努力です。

回答No.8

>L*M実行列A , M*N実行列B , M*N実行列C C=A*BとするとCはL*N行列になるんじゃないの? for(i=0; i<L; i++){ for(n=0;n<N;n++) for(m=0;m<M;m++){ C[i][n]+=A[i][m]*B[m][n]; } } Cにはポインターという便利なものがあるので、 配列のアドレス計算をポインターで実現すればよいのです。 したがって一次元配列のアドレスとして関数に渡すのが正解です。 Cの要素を計算するこの部分は for(m=0;m<M;m++){ C[i][n]+=A[i][m]*B[m][n]; ポインターで書くとこうなります。 duble *a,*b,*c; a=&A[i*M],b=&B[n]; for(m=0;m<M;m++){ *c+=(*a)*(*b); a++,b+=N; } c++; まとめると、こんな感じ duble *a,*b,*c; int i,n; c=C; for(i=0; i<L; i++){ □for(n=0;n<N;n++){ □□double *a, *b, *amax; □□a=&A[i*M]; //aの先頭アドレスを計算する □□amax=a+M; //aの終端アドレスを計算する □□b=&B[n]; //bの先頭アドレスを計算する □□for(;a<amax;a++){ □□□*c+=(*a)*(*b); □□□b+=N; □□} □□c++; □} }

回答No.7

C++の範疇で解決すれば良くて、行列の計算が「道具として」必要ということなら、boost::matrix http://www.boost.org/doc/libs/1_39_0/libs/numeric/ublas/doc/matrix.htm がお勧めですが。 ソースも見ることができるので、ソースを見て勉強するのもありだと思います。

expiz
質問者

お礼

回答ありがとうございます 早速boostのインストールを http://www.kmonos.net/alang/boost/install.html を参考にしつつ行ってみましたが、いざhttp://www.page.sannet.ne.jp/d_takahashi/boost/ublas/index.html の見本プログラムをビルトしてみると >LINK : fatal error LNK1104: ファイル 'libboost_serialization-vc100-mt-gd-1_44.lib' を開くことができません。 と出てしまい実行ができません。 本質問の趣旨からは外れてしまうのですが、googleで検索しても全くこのエラーの情報が無いので、よろしければアドバイス頂けないでしょうか? 私の行った具体的なインストール手順は http://www.boostpro.com/download/ からBoostPro 1.44.0 Installer を実行し、チェックボックスで選択すべき個所では visual studio 2010を、また、default variantsは下2つ(single thread)を除き全てを選択しました。 更に、visual studio2010において http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=JA-JP&k=k(VS.TOOLSOPTIONSPAGES.PROJECTS.VCDIRECTORIES)&rd=true を参考にし、VC++ ディレクトリのインクルードディレクトリにC:\Program Files(x86)\boost を追加指定した次第です。 インストールの結果、C:Program Files(x86)にboostフォルダが作成され、上記のfatal error LNK1104: で指摘されているlibファイルはC:\Program Files(x86)\boost\boost_1_44\libフォルダ内に存在していたのですが、上記fatal errorが現れました。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.6

引数の渡し方がわからないなら構造体にパックしてしまうのが楽でしょう。 構造体に行列サイズ情報を含めておけば引数ひとつで完全な行列の情報を渡すことができます。 あと、CなのかC++なのかははっきりしておいてください。 Cならnewは使えません。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

行列を double** p=new double* [L]; for(int l=0;l<L;l++)p[l]=new double [M]; のような形で確保するなら, 引数は double ** じゃないとダメだよね.

  • noyuo
  • ベストアンサー率39% (33/84)
回答No.4

関数としてもいいですけど、1次元の配列を2次元の配列と扱うための アドレス計算のマクロを定義します。 /* 長さR の Y行 X列のアドレス求める */ #define REC_POS(R,X,Y) (Y*R+X) として、C[REC_POS(L,n,l)] などとして参照します。 C,A,Bともに1つのマクロで使えるかなぁ?

noname#137556
noname#137556
回答No.3

基本は,全要素分のメモリを確保(malloc)して,要素を一列に並べておけば良いです。 どういう順番で列べるか(行優先か/列優先か)さえ決めておけば,欲しい要素がどこにあるか計算で求められますよね? ただ,計算するのに,行数や列数といった情報が必要なので,まとめて構造体にして, その構造体を引数で受け取って計算をする関数をどんどん定義していけば良いです。 C++ なら,クラスにして,演算子を再定義して,ベクトルや部分行列を継承でうまく表現して・・・ と妄想が膨らみますが, 行列の演算を実装すること自体が目的でなければ,実績のある既存のライブラリを使ったり, そもそも,MATLAB や Scilab,R 言語といった行列の取り扱いに長けた処理系を使ったほうが良いかもしれません。

expiz
質問者

お礼

回答ありがとうございます >>要素を一列に並べておけば 参考になりました。一応こうすれば所望のプログラムは、動作するという意味では形にはなりましたが・・・以下のように前処理をしないと動かないものしか作れず、不格好な仕上がりとなってしまいました。 どうにかして引数に2次元配列を組み込み、(1)直接演算するか、(2)前処理部分を1つの関数に纏めるかしたいのですが、やはり多次元配列の関数への渡し方が分かりません。 一応ですが、クラス、演算子オーバーロード、vectorの基礎は習いましたので、これらを用いて楽?ができるのでしたらそちらについてもアドバイスを頂ければありがたいです。 double A[L][M],B[M][N],C[L][N]; for(int l=0;l<L;l++) for(int m=0;m<M;m++) {if(l!=m) A[l][m]=0; else A[l][m]=1;} for(int m=0;m<M;m++) for(int n=0;n<N;n++) {if(m!=n) B[m][n]=0; else B[m][n]=1;} //行列の積を無理やり1次元配列を使って解く。まず前処理 double a[L*M],b[M*N],c[L*N]; for(int l=0;l<L;l++) for(int m=0;m<M;m++) a[M*l+m]=A[l][m]; for(int m=0;m<M;m++) for(int n=0;n<N;n++) b[N*m+n]=B[m][n]; multiply(L,M,N,a,b,c);//積計算 for(int l=0;l<L;l++) for(int n=0;n<N;n++) C[l][n]=c[N*l+n];//結果代入 なお、multiplyの定義は void multiply(int L,int M,int N,double* A,double* B,double* C)//A[L][M] B[M][N] C[L][N] { for(int ln=0;ln<L*N;ln++) C[ln]=0; for(int l=0;l<L;l++){ for(int m=0;m<M;m++){ for(int n=0;n<N;n++) C[N*l+n]+=A[M*l+m]*B[N*m+n]; } } }

  • k_kota
  • ベストアンサー率19% (434/2186)
回答No.2

普通のCってそういう感じで文字を定義していいんでしたっけ?関数の最初でやっておくのが普通だと思うのですけど。 とりあえず、配列の参照渡しとポインタの概念くらいは分からないとどうにもならないと思います。 関数の定義はダメだと思います。 関数にはもろもろのサイズと2次配列をポインタ渡ししてやればいいです。 そういう意味では考え方はOKです。 あとはサイズ既知なのですから、計算結果のすべての要素について それぞれ計算してやればいいです。 行列の積の計算方法は分かりますかね。 ループは代入先の行と列のループと計算時のループで3重になります。 まあ、探せば行列の基礎なのでそれくらいあると思いますけどね。 自分で探して調べたり、理解できないならプログラムするほどのものでは無いような気がします。 エクセルでいいんじゃないの? もっと高度なことがしたいなら、3日程度できっちりプログラミングの基礎をやらないと後々苦労すると思います。

関連するQ&A

  • 行列の積を計算するプログラムがうまくいきません

    どこが間違っているのかわかる方お願いします ・行列A,Bはファイルから読み込む ・行列A,Bの積Cの計算には関数を用いる #include<stdio.h> #define ROW 10 #define COL 10 void MatrixProduct(int a[][COL],int b[][ROW],int c[][ROW],int n,int m ) { int i,j,k; for(i=0;i<n;i++){ for(j=0;j<n;j++){ c[i][j]=0; } } for(i=0;i<n;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ c[i][j]=c[i][j]+a[i][k]*b[k][j]; } } } } int main(void) { FILE *fp1,*fp2; char fname1[64],fname2[64]; int a[ROW][COL],b[ROW][COL],c[ROW][COL],n,m; int i,j,k; printf("Input file name ?"); scanf("%s",fname1); printf("Output file name ?"); scanf("%s",fname2); fp1=fopen(fname1,"r"); fp2=fopen(fname2,"w"); fscanf(fp1,"%d %d",&n,&m); MatrixProduct(a,b,c,n,m); for(i=0;i<n;i++){ for(j=0;j<n;j++){ fprintf(fp2,"%3d",c[i][j]); } fprintf(fp2,"\n"); } fclose(fp1); fclose(fp2); return(0); } fp1 3 4 1 2 3 4 2 3 4 5 3 4 5 6 1 2 3 2 3 4 3 4 5 4 5 6

  • 行列の積について

    3行3列の行列AとB、およびその和と積を表示するものです #include <stdio.h> int main (void) { int i,j,k; double a[3][3] = {{2.4, 5.5, -8.5},{0.8, 3.7, 1.1},{3.5, -9.1, 2.6}}; double b[3][3] = {{-5.1, 9.8, 2.3},{-4.1, 0.2, -0.3},{3.3, 6.1, -1.3}}; double c[3][3] = {0}; printf(" 行列A\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) printf("%5.1f", a[i][j]); printf("\n"); } printf("\n 行列B\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) printf("%5.1f", b[i][j]); printf("\n"); } printf("\n 行列A+B\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) c[i][j] = a[i][j] + b[i][j]; } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) printf("%5.1f", c[i][j]); printf("\n"); } for (i=0; i<3 ; i++){ for (j=0; j<3; j++) for (k=0; k<3; k++) c[i][j] =c[i][j]+ a[i][k]* b[k][j]; } printf("\n 行列AB\n"); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) printf("%7.2f", c[i][j]); printf("\n"); } return 0; } これだと積だけが異なった値が出てしまいます。 試しに、積の部分だけで組んでみると正しい答えが出ました。 for文のブロックの組み方がまずいのかなと思っていますが、これ以外だと、行列のレイアウトが崩れてしまいます どのように直したらいいのか、ご教示お願いします

  • c言語のプログラムで行列の積を計算する

    指定された行・列数(それぞれ10以下とする)の行列 X, Y の積 Z = X × Y を求めるプログラムを作成せよ.行列の要素はすべて整数とする. このプログラムで行と列の成分を入力するときに、1列になってしまうのですがどうしたらちゃんと入力できますか? int main(void) { double A[10][10]; double B[10][10]; int i,j,m,n,p,k; printf("行列xの行数は?:"); scanf("%d",&m); printf("行列xの列数(行列yの行数)は?:"); scanf("%d",&n); printf("行列yの列数は?:"); scanf("%d",&p); printf("行列xを入力してください。\n"); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { scanf("%d", &A[i][j]); } } printf("行列yを入力してください。\n"); for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { scanf("%d", &B[i][j]); } }

  • c言語で行列の積の値を求める

    行列の成分を入力した後に、 入力された行列は X = 1 2 3 4 5 6 7 8 9 10 11 12 Y = 1 5 2 6 3 7 4 8 のように表示して、(上の数字は適当です。) 行列 X と行列 Y の積を求めて結果を表示するプログラムが作りたいのですが、上手く表示できなくて困っています。 #include <stdio.h> int main(void) { double A[10][10]; double B[10][10]; double C[10][10]; int i,j,m,n,p,k; printf("行列xの行数は?:"); scanf("%d",&m); printf("行列xの列数(行列yの行数)は?:"); scanf("%d",&n); printf("行列yの列数は?:"); scanf("%d",&p); printf("行列xを入力してください。\n"); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { scanf("%d", &A[i][j]); } } printf("行列yを入力してください。\n"); for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { scanf("%d", &B[i][j]); } } この後にどうすればいいのか教えてください。 よろしくお願いします。

  • 行列をベクトルに

    m行n列の行列Aがあったとき、それをm×n行1列の行列(ベクトル)Bに するというプログラムを作りたいです。 つまり MATRIX B; B.m=A.m*A.n; B.n=1; return B; ということだと思うのですが、なかなかうまいくいきません。 また、構造体も使いたいので、 typedef struct { int m; int n; double *mat; } MATRIX; と宣言しました。 みなさんよろしくお願いします。

  • 行列の積を関数を使って求める・・?

    2つの行列の行と列を入力し、積を計算するプログラムを関数を使って書きたいのですが、上手く行きません。どこをどのように直したらよいか教えてください!お願いします!! 以下が私が書いたプログラムです。 #include<stdio.h> #define NUMBER 10 int first(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; do{ printf("2つの行列の行と列を入力してください\n"); scanf("%d", &x1); scanf("%d", &x2); scanf("%d", &y1); scanf("%d", &y2); if(x1 != y2){ printf("行列の積は計算できません\n"); } }while(x1 != y2); printf("行列Aの要素を入力してください\n"); for(i=0; i<x1; i++){ for(j=0; j<x2; j++) scanf("%d", &a[i][j]); } printf("行列Bの要素を入力してください\n"); for(j=0; j<y1; j++){ for(k=0; k<y2; k++) scanf("%d", &b[j][k]); } } int second(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; for(i=0; i<x1; i++){ for(k=0; k<y2; k++){ for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } } for(i=0; i<x2; i++){ for(k=0; k<y2; k++) printf("%3d", c[i][k]); printf("\n"); } } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n %d\n", first(x1,x2,y1,y2,i,j,k)); printf("行列Aと行Bの積は\n %3d",second(x1,x2,y1,y2,i,j,k)); }

  • 行列の計算

    #include<stdio.h> #define N 2 #define M 3 void hyoji(float[][M]); int main(){ int i,j,k; float a[N][M] = {{2.0,2.0,2.0},{2.0,2.0,2.0}}; float b[M][M] = {{1.0,1.0,1.0},{2.0,2.0,2.0},{1.0,1.0,1.0}}; float c[N][N]; for(i=0; i<N; i++){ for(j=0; j<M; j++){ c[i][j] = 0; for(k=0; k<M; k++){ c[i][j] += a[i][k] * b[k][j]; } } } hyoji(c); return(0); } void hyoji(float x[][M]){ int i,j; for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("%4.1f ",x[i][j]); } printf("\n"); } } 以上のプログラムで 行列aと行列bをかけ合せた行列cを求めるのですが コンパイルすると 8 8 8 8 8 1 となり、正しい結果がでません。 なにが間違っているのでしょうか?? よろしくお願いします。

  • c言語 行列の積に関して

    <問>  4行3列の行列aと3行4列の行列bの積を、4行4列の行列cに格納する関数を作成せよ。  void mat_mul(const int a[4][3], const int b[3][4], int c[4][4]) 入門レベルのスキルしかありません。 上手く行列の積のプログラムが組めません。 行列の積の計算結果が何も出てきません。 どの様にしたら良いかご指導の程、宜しくお願いします。 <プログラム>  void mat_mul(const int a[4][3], const int b[3][4], int c[4][4]) { int i, j, k; for (i = 0; i < 4; k++) { for (j = 0; j < 4; i++) for (k = 0; k < 3; j++) c[i][j] = c[i][j] + (a[i][k] * b[k][j]); } } void mat_print(const int m[4][4]) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) printf("%4d", m[i][j]); putchar('\n'); } } int main(void) { int i, j ,k; int tensu1[4][3]; int tensu2[3][4]; int seki[4][4]; for(i = 0; i < 4; i++) { for (j = 0; j < 3; j++) { scanf("%d", &tensu1[i][j]); } putchar('\n'); } for(i = 0; i < 3; i++) { for(j = 0; j < 4; j++){ scanf("%d", &tensu2[i][j]); } putchar('\n'); } putchar('\n'); mat_mul(tensu1, tensu2, seki); puts("行列の積"); mat_print(seki); return 0; }  

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

    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

  • 行列をベクトルに(C言語)

    行列をベクトルに(C言語) m行n列の行列Aがあったとき、それをm×n行1列の行列(ベクトル)Bに するというプログラムを作りたいです。 これは、行列Aの1列目m行分の要素をそのまま行列Bの1行1列目に持っていき、 それを行列Aのn列の数だけ繰り返す、といった要領です(画像参照) つまり MATRIX B; B.m=A.m*A.n; B.n=1; return B; ということだと思うのですが、なかなかうまいくいきません。 また、構造体も使いたいので、 typedef struct { int m; int n; double *mat; } MATRIX; と宣言しました。 画像は説明のため、一応載せておきました。(例として4列の行列になっています) みなさんよろしくお願いします。

専門家に質問してみよう