/*
プログラム1-4(Prog1-4.cpp)
行列の演算と関数への引き渡し
*/
#include <stdio.h>
#include <stdlib.h>
#define ROWS 3 /* 行数 */
#define COLUMS 3 /* 列数 */
void add_matrix(const double (*)[COLUMS],
const double (*)[COLUMS],double (*)[COLUMS]);
void mlt_matrix(const double (*)[COLUMS],
const double (*)[COLUMS],double (*)[COLUMS]);
void dsp_matrix(const double (*)[COLUMS]);
int main(void)
{
double A[/url][COLUMS]={{1,2,3},{4,5,6},{7,8,9}};
double B[/url][COLUMS]={{9,8,7},{6,5,4},{3,2,1}};
double add[ROWS][COLUMS],mlt[ROWS][COLUMS];
int i,j;
for(i=0;i<ROWS;++i) /* 配列初期化 */
for(j=0;j<COLUMS;++j)
add[j]=mlt[j]=0;
add_matrix(A,B,add);
mlt_matrix(A,B,mlt);
puts("和A+B =");
dsp_matrix(add);
puts("積AB =");
dsp_matrix(mlt);
mlt_matrix(B,A,mlt);
puts("積BA ="); /* 一般に AB と BA は異なる */
dsp_matrix(mlt);
return EXIT_SUCCESS;
}
/* 3×3 型行列の和 */
void add_matrix(const double (*a)[COLUMS],
const double (*b)[COLUMS],double (*c)[COLUMS])
{
int i,j;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMS;++j)
c[j]=a[j]+b[j];
}
/* 3×3 型行列の積 */
void mlt_matrix(const double (*a)[COLUMS],
const double (*b)[COLUMS],double (*c)[COLUMS])
{
int i,j,k;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMS;++j)
for(k=0;k<COLUMS;++k)
c[j]+=a[k]*b[k][j];
}
/* 3×3 型行列の表示 */
void dsp_matrix(const double (*a)[COLUMS])
{
int i,j;
char ch;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMS;++j){
ch=((j+1)%COLUMS)?'\t':'\n';
printf("%10.6f%c",a[j],ch);
}
}
/* EOF */
行列
A三カッコ1 2 3 カッコ
4 5 6
B三カッコ9 8 カッコ
6 5
3 2
を使って2ABを算出するプログラムを作りたいですが、C言語初心者で全く手がつけられません・・・・。
すごく困っています。
教えて下さいお願いします。皆さんの知恵をかしてください。
困っています知恵を貸して下さい。おねがいします
Re:困っています知恵を貸して下さい。おねがいします
書き忘れましたが、自分はC言語初心者で、全く手が出なかったんです。。。
ご迷惑をおかけしますが、知恵をかしてください。分かるから、どうかよろしくお願いいたします。
ご迷惑をおかけしますが、知恵をかしてください。分かるから、どうかよろしくお願いいたします。
Re:困っています知恵を貸して下さい。おねがいします
/*
プログラム1-4(Prog1-4.cpp)
行列の演算と関数への引き渡し
*/
#include <stdio.h>
#include <stdlib.h>
#define ROWS 2 /* 行数 */ //変更しました
#define COLUMS 3 /* 列数 */
#define COLUMS2 2 //追加しました
void mlt_matrix(const double (*a)[COLUMS], const double (*b)[COLUMS2],double (*c)[COLUMS2]) ;//変更しました
void dsp_matrix(const double (*a)[COLUMS2]) ;//変更しました
int main(void)
{
double A[/url][COLUMS]={{1,2,3},{4,5,6}}; //変更しました
double B[/url][COLUMS2]={{9,8},{6,5},{3,2}}; //変更しました
double add[ROWS][COLUMS2],mlt[ROWS][COLUMS2]; //変更しました
int i,j;
for(i=0;i<ROWS;++i) /* 配列初期化 */
for(j=0;j<COLUMS2;++j) //変更しました
add[j]=mlt[j]=0;
mlt_matrix(A, B, mlt);
puts("積2AB ="); //変更しました
dsp_matrix(mlt);
return EXIT_SUCCESS;
}
/* 3×3 型行列の積 */
void mlt_matrix(const double (*a)[COLUMS], const double (*b)[COLUMS2],double (*c)[COLUMS2]) //変更しました
{
int i,j,k;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMS2;++j) //変更しました
for(k=0;k<COLUMS;++k)
c[j]+=a[k]*b[k][j];
}
/* 3×3 型行列の表示 */
void dsp_matrix(const double (*a)[COLUMS2]) //変更しました
{
int i,j;
char ch;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMS2;++j)
{
ch=((j+1)%COLUMS2)?'\t':'\n';
printf("%10.6f%c",2*a[j], ch); //変更しました ここでAB行列に2を掛け算してます
}
}
/* EOF */
で、どうでしょうか。
プログラム1-4(Prog1-4.cpp)
行列の演算と関数への引き渡し
*/
#include <stdio.h>
#include <stdlib.h>
#define ROWS 2 /* 行数 */ //変更しました
#define COLUMS 3 /* 列数 */
#define COLUMS2 2 //追加しました
void mlt_matrix(const double (*a)[COLUMS], const double (*b)[COLUMS2],double (*c)[COLUMS2]) ;//変更しました
void dsp_matrix(const double (*a)[COLUMS2]) ;//変更しました
int main(void)
{
double A[/url][COLUMS]={{1,2,3},{4,5,6}}; //変更しました
double B[/url][COLUMS2]={{9,8},{6,5},{3,2}}; //変更しました
double add[ROWS][COLUMS2],mlt[ROWS][COLUMS2]; //変更しました
int i,j;
for(i=0;i<ROWS;++i) /* 配列初期化 */
for(j=0;j<COLUMS2;++j) //変更しました
add[j]=mlt[j]=0;
mlt_matrix(A, B, mlt);
puts("積2AB ="); //変更しました
dsp_matrix(mlt);
return EXIT_SUCCESS;
}
/* 3×3 型行列の積 */
void mlt_matrix(const double (*a)[COLUMS], const double (*b)[COLUMS2],double (*c)[COLUMS2]) //変更しました
{
int i,j,k;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMS2;++j) //変更しました
for(k=0;k<COLUMS;++k)
c[j]+=a[k]*b[k][j];
}
/* 3×3 型行列の表示 */
void dsp_matrix(const double (*a)[COLUMS2]) //変更しました
{
int i,j;
char ch;
for(i=0;i<ROWS;++i)
for(j=0;j<COLUMS2;++j)
{
ch=((j+1)%COLUMS2)?'\t':'\n';
printf("%10.6f%c",2*a[j], ch); //変更しました ここでAB行列に2を掛け算してます
}
}
/* EOF */
で、どうでしょうか。
Re:困っています知恵を貸して下さい。おねがいします
main で mlt_matrix関数を実行する前に、mltの要素を表示してみてください。期待とは違うものが表示されることでしょう。
mlt_matrix関数内で c[j] = 0.0; と行列の要素を初期化した方が安全かと思います。
mlt_matrix関数内で c[j] = 0.0; と行列の要素を初期化した方が安全かと思います。
Re:困っています知恵を貸して下さい。おねがいします
チャオさん、しっぽさん、ありがとうございます。感謝します。本当にありがとうございます!!
しっぽさんのコメント、どこをどう直したら安全なのか、もう少し丁寧に教えて頂けませんでしょうか。初心者なので、理解に苦しんでいます・・・・・
しっぽさんのコメント、どこをどう直したら安全なのか、もう少し丁寧に教えて頂けませんでしょうか。初心者なので、理解に苦しんでいます・・・・・
Re:困っています知恵を貸して下さい。おねがいします
安全と言ったのは、人(自分)が犯すかもしれない過ちを予想して防ぐ手段を取れば、過ちを防止できるからです。
mlt_matrix 関数はそのままでは mlt_matrix(B,A,mlt); を実行する前にmlt に初期値を与えことが必要条件になっていますが、人は忘れてしまいやすい。そして実際、Date: 2009/10/31(土) 22:51 No:41211 のコードでは、この条件が忘却されており、期待した結果は得られません。なにが忘れられてかというと mlt_matrix(B,A,mlt); を実行する前に mlt に初期値を与えていないということです。
mlt_matrix は行列の演算で多数出くる可能性が十分ある関数なので、mlt_matrix 内で mlt の初期値を設定すれば自動的にそのようなバグを防止できるということです。add_matrix ついても同様です。
mlt_matrix 関数はそのままでは mlt_matrix(B,A,mlt); を実行する前にmlt に初期値を与えことが必要条件になっていますが、人は忘れてしまいやすい。そして実際、Date: 2009/10/31(土) 22:51 No:41211 のコードでは、この条件が忘却されており、期待した結果は得られません。なにが忘れられてかというと mlt_matrix(B,A,mlt); を実行する前に mlt に初期値を与えていないということです。
mlt_matrix は行列の演算で多数出くる可能性が十分ある関数なので、mlt_matrix 内で mlt の初期値を設定すれば自動的にそのようなバグを防止できるということです。add_matrix ついても同様です。
Re:困っています知恵を貸して下さい。おねがいします
main関数で配列の中身を初期化せずに、関数内で配列の初期化をするようにしておけば、関数を他のプログラムでも再利用することができます。
プログラムを組むときは、他人があなたのコードを利用することも意識して、プログラミングすることに慣れておくとプログラミングが上達します。
様々なプログラムをたくさん組む練習をしていけば、追々意識できるようになるかと思います。
まずは、今回のプログラムが、どのような処理の仕方で、行列の掛け算が実現できているのか理解できるようになると良いと思います。
同じ処理をするプログラムでも、人によってプログラムの書き方は違います。
今回のプログラムを自分の考え方で組めるようにしておくと良いと思います。
プログラムを組むときは、他人があなたのコードを利用することも意識して、プログラミングすることに慣れておくとプログラミングが上達します。
様々なプログラムをたくさん組む練習をしていけば、追々意識できるようになるかと思います。
まずは、今回のプログラムが、どのような処理の仕方で、行列の掛け算が実現できているのか理解できるようになると良いと思います。
同じ処理をするプログラムでも、人によってプログラムの書き方は違います。
今回のプログラムを自分の考え方で組めるようにしておくと良いと思います。