![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
部分行列の抜き出し(C言語)
ある行列から、任意の部分行列を抜き出すような関数を作りたいのですが、わからないので手助けをお願いしたいです。
たとえば4行4列の行列Aがあった場合、その2行2列、2行3列、3行2列、3行3列目の
4つの(2行2列の)要素を抜き出すような関数です。
枠組みは出来ているので載せておきます。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct matrix{
double *data;
int size[2];
}MATRIX;
MATRIX create_matrix(int m,int l,int a);//行列の作成
void print_matrix(MATRIX A); //行列の表示
MATRIX submatrix(MATRIX matrix_A,int m,int n,int l,int k); //任意の部分行列の抜き出し
int main(int argc,char **argv)
{
//構造体の初期化
MATRIX matrix_A={NULL,NULL,NULL};
MATRIX matrix_B={NULL,NULL,NULL};
MATRIX matrix_C={NULL,NULL,NULL};
int m=0; //行列の行
int l=0; //行列の列
int a=1; //要素
double det=0; //行列計算
//行列Aの作成
m=4;//行
l=4;//列
matrix_A = create_matrix( m, l, a);
//関数
matrix_C = submatrix(matrix_A,2,2,3,3);
//行列結果出力
printf("\n\tmatrix input");
print_matrix(matrix_A);
printf("\n\tmatrix output");
print_matrix(matrix_C);
//行列の開放
free(matrix_A.data); matrix_A.data=NULL;
free(matrix_C.data); matrix_C.data=NULL;
printf("終了!\n\n");
return 0;
}
MATRIX create_matrix(int m,int l,int a)
{
MATRIX matrix_A={NULL,NULL,NULL};
int i=0;
//サイズの確保 行;size[0] 列;size[1]
matrix_A.size[0]=m;
matrix_A.size[1]=l;
//メモリの確保
matrix_A.data=(double *)malloc(sizeof(double)*matrix_A.size[0]*matrix_A.size[1]);
if(matrix_A.data == NULL){
printf("メモリ確保失敗!![matrix_A]\n");
exit(1);
}
//行列Aの作成
for(i=0; i<((matrix_A.size[0])*(matrix_A.size[1])) ;i++){
*(matrix_A.data+i)=a+i;
}
return(matrix_A);
}
/*行列の表示*/
void print_matrix(MATRIX matrix_A)
{
int i=0;
int j;//行
int k; //列
printf("\n行列の表示\n");
//行列Aのプリント
for(j=0;j<matrix_A.size[0];j++){
for(k=0;k<matrix_A.size[1];k++){
printf("%f\t",*(matrix_A.data+k*matrix_A.size[0]+j));
}
printf("\n");
}
return;
}
MATRIX submatrix(MATRIX matrix_A,int m,int n,int l,int k)
{
MATRIX matrix_C = {NULL,NULL,NULL};
int i,j;
//サイズの確保 行;size[0] 列;size[1]
matrix_C.size[0]=l-m+1;
matrix_C.size[1]=k-n+1;
//メモリの確保
matrix_C.data=(double *)malloc(sizeof(double)*matrix_C.size[0]*matrix_C.size[1]);
if(matrix_C.data == NULL){
printf("メモリ確保失敗!![matrix_C]\n");
exit(1);
}
//任意の部分行列の抜き出し
(ここがわかりません。)
}
よろしくお願いします。
![「部分行列の抜き出し(C言語)」の質問画像](http://oshiete.xgoo.jp/_/bucket/oshietegoo/images/media/2/19967523_5497d7c5b07d4/M.jpg)
No.3ベストアンサー
- 回答日時:
>抜き出すような関数
を作る前に、「初期化」「出力」関数の動作確認をしてみたら、如何でしょう?。
(その関数の中で、_A を使うのは間違いの元ですよ)
No.2 さんも指摘していますが、★の方がよいかと・・。
30年以上昔のことで記憶が定かでないですが、Fortran77 だって★の「入り方(メモリの並び)」だったような。
2つの関数の動作確認ができたら、これまた No.1 さんが言われるように
>そしてそれは print_matrix でやっていることと同じ
に、「抜き出すような関数」を作るだけ、と思います。
例)for( j = m; j <= l; j++ ){ // m ↓ l
for( k = n; k <= k; k++ ){ // n → k
左辺(ちょっと考えて) = 右辺(そのまんま)
#include <stdio.h>
#include <stdlib.h>
typedef struct{
double *data;
int iGyouSize; // [0] とかより分かり易いかと・・2つしかないんだし。
int iRetuSize;
}MATRIX;
void print_matrix( MATRIX matrix )
{
int j; // 行
int k; // 列
printf( "\n行列の表示\n" );
for( j = 0; j < matrix.iGyouSize; j++ ){ // m ↓ l
for( k = 0; k < matrix.iRetuSize; k++ ){ // n → k
printf( "%lf\t", *( matrix.data + k * matrix.iGyouSize + j ) ); // 質問者様
// printf( "%lf\t", *( matrix.data + k + matrix.iRetuSize * j ) ); // お勧め★
}
printf( "\n" );
}
}
MATRIX create_matrix( int m, int l, int a )
{
MATRIX matrix;
int i;
matrix.iGyouSize = m;
matrix.iRetuSize = l;
matrix.data = (double *)malloc( sizeof(double) * matrix.iGyouSize * matrix.iRetuSize );
if( NULL == matrix.data ){
printf( "メモリ確保失敗!![matrix]\n" );
exit( 1 );
}
for( i = 0; i < ( matrix.iGyouSize * matrix.iRetuSize ); i++ ) *( matrix.data + i ) = (double)( a + i );
return( matrix );
}
int main( void )
{
int m = 4; // 行列の行
int l = 4; // 行列の列
int a = 1; // 要素
MATRIX matrix_A;
matrix_A = create_matrix( m, l, a );
print_matrix( matrix_A );
free( matrix_A.data );
return( 0 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
No.4
- 回答日時:
いや, FORTRAN や Fortran では C と異なり前の方の添字が先にまわります>#3. つまり A(0:1, 0:1) は
A(0, 0), A(1, 0), A(0, 1), A(1, 1)
の順に配置されます.
No.2
- 回答日時:
for ループは 2重でいけます. m, n, l, k は (ここでは) 固定されていることに注意.
i と j を (適切な範囲で) 2重ループでまわしながら, c[i][j] = a[m+i][n+j]; に相当する文を書くだけです.
ちなみにもっと姑息に行けばループは 1つですみます.
あとたぶん蛇足だけど, データの配置順序が普通の C の順序と逆っぽい気がする. 今は A の (j, k) 要素を
*(matrix_A.data+k*matrix_A.size[0]+j)
で取り出してるけど, 普通の C の順序では
*(matrix_A.data+j*matrix_A.size[1]+k)
となるはず. いや, Fortran が念頭にあるならいいけど.
No.1
- 回答日時:
普通の 2次元配列だと思えば
c[i][j] = a[m+i][n+j];
ですよね. これを「1次元的にアクセスする」だけです. そしてそれは print_matrix でやっていることと同じ.
なお,
MATRIX matrix_A={NULL,NULL,NULL};
という初期化は間違いです. 2つ目, 3つ目の NULL は int data[2] に対する初期化データになりますが, NULL は「ポインタと解釈すべき」であり, それを使って int を初期化するのはおかしいです (NULL を 0 で定義する処理系もあり, その場合には結果的に問題ないとはいえ論理的にはおかしい).
この回答への補足
素早いご指摘ありがとうございます。初期化に関しては修正してみますね。
関数部分なのですが、1次元的に考えるという点は理解できるのですが、どうプログラムを組めばいいか未だにわかりません。
for文って4つ必要ですか??自分なりに考えたプログラムだと4つ
使うんですが、実行してみるとエラーこそでないですが、抜き出した
行列の要素が全部同じになっちゃて困っています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語での引数の省略方法
-
「指定されたキャストは有効で...
-
if と配列の組み合わせ
-
read関数をノンブロッキングで...
-
複数桁10進数の*桁目だけを抽出...
-
CStringの配列要素を関数で受け...
-
C言語 等差数列問題
-
実数の整数部,小数部の取得
-
エラー 添字が付けられた値が、...
-
fprintfでの文字化け
-
ポインタを使って関数の値の...
-
Listの<Label>と<PictureBox>
-
C言語での奇数の和
-
「{ } で囲むだけ」は正しい?
-
演算子オーバーロードのプログ...
-
VB.NET DLL 参照型String読込み
-
C++でvectorにテキストファイル...
-
int型の変数値をバイト列として...
-
数字列を3桁ごとにカンマで区切...
-
C#の質問
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
AtCoderABC135の問題Cについて
-
C言語 エラーの原因がわからな...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
実数の整数部,小数部の取得
-
ラップ関数とはどんなものですか?
-
if と配列の組み合わせ
-
return 1L
-
read関数をノンブロッキングで...
-
(int *)の意味
-
std::set<int> で、ある値が何...
-
Win32APIで作るコンボボックス...
-
C++でvectorにテキストファイル...
-
「{ } で囲むだけ」は正しい?
-
足して100になるような乱数のア...
-
Arduinoのプログラムにエラーが...
-
課題でつまってます・・・
おすすめ情報