アプリ版:「スタンプのみでお礼する」機能のリリースについて

「可変な正方行列を引数に取り、それの逆行列を出力する」プログラムが作れません。

逆行列の求め方はわかっていますし、あらかじめ次数がわかっている場合は求めることができるのですが、
これを一般化してどんな次数の正方行列でも逆行列を求められるようにしたいのです。

double Gyaku(int rank, double mat[][]){

・・・

}

このようにコードを書いたのですが、上手くいきません。
調べてみると、2次元配列を引数として渡す場合は
double Gyaku(int rank, double mat[][4]){

・・・

}

のように、次数を指定しなければいけない部分があることがわかりました。
それ自体は理解できるのですが、これでは「どのような次数でも」
という条件を満足できないので、何とか回避する方法はないでしょうか?
よろしくお願いします。

A 回答 (5件)

構造体を使うとスッキリ渡せると思いますよ?



以前書いた行列計算のプログラムの抜粋を以下に乗せますので、
よろしければ実行してみてください。
なお、行頭の全角スペースを半角スペースなどに置換してください。

一応gccは以下のコードで通りました。

#include <stdlib.h>
#include <stdio.h>

typedef struct Matrix{
 int row;
 int col;
 double** mat;
} Matrix;

Matrix* newMatrix(int row, int col){
 Matrix* tmp = (Matrix*)malloc(sizeof(Matrix));
 tmp->row = row;
 tmp->col = col;
 tmp->mat = (double**)malloc(sizeof(double*) * row);
 int i;
 for(i = 0; i < row; i++)
  tmp->mat[i] = (double*)malloc(sizeof(double) * col);
 return tmp;
}

void deleteMatrix(Matrix* matrix){
 int i;
 for(i = 0; i < matrix->row; i++){
  free(matrix->mat[i]);
 }
 free(matrix->mat);
 free(matrix);
}

Matrix* initMatrix(Matrix* matrix){
 int i;
 int j;
 for(i = 0; i < matrix->row; i++)
  for(j = 0; j < matrix->col; j++)
   matrix->mat[i][j] = 0;
 return matrix;
}

void printMatrix(Matrix* matrix){
 int i;
 int j;
 for(i = 0; i < matrix->row; i++){
  for(j = 0; j < matrix->col; j++)
   printf("%lf\t", matrix->mat[i][j]);
  printf("\n");
 }
 return matrix;
}

int main(){
 int row = 3;
 int col = 3;
 
 Matrix* matrix = newMatrix(row, col);
 initMatrix(matrix);
 printMatrix(matrix);
 deleteMatrix(matrix);
}
    • good
    • 0
この回答へのお礼

ありがとうございます。

それがいちばん簡単そうですね。
他の部分も書き換えになっちゃうのが痛いですが(汗
(といっても100行くらいのちゃちなものですが)

何とかなりそうです。

お礼日時:2007/12/17 19:59

No.2です。

こんなんどうでしょう。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/////ちなみにこのプログラムは穴だらけ(エラー処理がアマい)です。核になる箇所しか考えてないのでその点よろしこ。

void set_matrix( double *matrix, int jisuu );
void put_matrix( double *matrix, int jisuu );

int main( int argc, char *argv[] )
{
 int jisuu;//次数
 double *matrix;//正方行列へのポインタ

 jisuu = atoi( argv[1] );//次数決定
 int dsize = sizeof(double);

 if((matrix = (double *)malloc(dsize * jisuu * jisuu)) == NULL) {//(1)
  //エラー処理
 }

 set_matrix( matrix, jisuu ); //正方行列へ値をセット
 put_matrix( matrix, jisuu ); //逆行列作成

 free( matrix );
 return( 0 );
}

void set_matrix( double *matrix, int jisuu )
{
 for( int i=0; i<jisuu; i++ ) {
  for( int j=0; j<jisuu; i++ ) {
   //値をセット。主題から外れるのでここは省略。
  }
 }
}

void put_matrix( double *matrix, int jisuu )
{
 switch( jisuu ) {
 case 1:
  break;
 case 2:
  //2×2行列の逆行列を求める。主題から外れるので略。
  break;
 case 3:
  //3×3行列の逆行列を求める。主題から外れるので略。
  break;
 case 4:
  //4×4行列の逆行列を求める。主題から外れるので略。
  break;
 //以降略...
 default:
  //何かエラー処理?お任せします。
  break;
 }
}

キモになるのは上記(1)の部分です。
malloc()を使って、正方行列もどきを作っています。これを、あたかも正方行列のように扱います。

逆行列の求め方はわかっているとのことですし、*matrix は単なる double へのポインタなので、おそらく質問者さんなら自在に引数なりで引き回せるでしょうし、なんとかなるんじゃないかなと。

.....ハズしてたらすまん。
    • good
    • 0
この回答へのお礼

ありがとうございます。

doubleへのポインタを用いて後はアドレスを後ろにずらして・・・
ということでしょうか。

mallocは思いつきませんでした。ありがとうございます

お礼日時:2007/12/17 19:58

処理系によるけど, ISO C なら


double Gyaku(int rank, double mat[][])

double Gyaku(int rank, double mat[rank][rank])
にすれば OK.
    • good
    • 0
この回答へのお礼

ありがとうございます。

コンパイラの違いなのか、私の方では
それでは通りませんでした。

ISO Cなら通るということですので、今度試してみたいと思います。

お礼日時:2007/12/17 19:54

オレはこれは、単純にdoubleの2次元配列で処理できない気がする。



No.1さんも言われている通り、そもそも「逆行列を求めたいもとの行列は、どこでどのように定義しますか?」ということになる。

やり方は幾つかあると思うけど、「可変」が条件なんだから、どうしたって動的な定義になる(よね?)。
例えば仮にこの実行ファイルが test.exe だった場合、第一引数で次数を指定するとしたら、test.exe 5 みたいな実行形式になる。

それをソース中で、doubleの2次元配列で表現しようとすると、
double test_matrix[ atoi(argv[1]) ][ atoi(argv[1]) ]; みたいになる。
でも配列の要素数は定数式じゃないとダメだから、コンパイルエラーになると思う(っていうかなります)。

だから質問者さんは、関数に2次元配列を引数として渡す前に、どうやって、可変の2次元配列を作るか。
或いはそれに相当するものを作るか、を先に考えるべきじゃないかな。

とりあえずここまで回答しとく。
    • good
    • 0
この回答へのお礼

ありがとうございます。

コンパイルした後に渡すのではなく、普通に
変数を宣言して渡すと思っているのですが・・・

説明不足でした。すいません

お礼日時:2007/12/17 19:53

逆行列を求めたいもとの行列は、


どこでどのように定義しますか?
    • good
    • 0
この回答へのお礼

ありがとうございます

元の行列はdouble型の2次元配列

double matA[4][4]

のように定義すると考えてましたが、確かに説明不足ですね。
申し訳ありません。

お礼日時:2007/12/17 19:49

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