ショッピングモール  Automotive ( Pictorial )  Automotive ( Racing )  Automotive ( Repair )


掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.5380

3*3行列の逆行列算出について
投稿者---MoriMori(2006/02/04 16:21:01)


すみません。3*3の逆行列の公式って何でしょうか?


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:3*3行列の逆行列算出について 5381 Blue 2006/02/04 17:23:35


No.5381

Re:3*3行列の逆行列算出について
投稿者---Blue(2006/02/04 17:23:35)


>すみません。3*3の逆行列の公式って何でしょうか?
これはC言語に関係する質問でしょうか?

数学的な質問であればほかで質問してください。
ここは何でも質問所ではありませんので。

ちなみに、Googleという検索エンジンがあるのは知っていますでしょうか?
私が「逆行列 公式」で検索したら、1発で見つかりましたが、どうなんでしょうか?

Google:http://www.google.com/webhp?hl=ja
Googleの検索方法とヘルプ


この投稿にコメントする

削除パスワード

No.5382

Re:3*3行列の逆行列算出について
投稿者---MoriMori(2006/02/04 23:03:31)


え〜と、すみません。
c言語で、どういう風にプログラムしたらよいのかわからないということでした。


この投稿にコメントする

削除パスワード

No.5383

Re:3*3行列の逆行列算出について
投稿者---ぽこ(2006/02/04 23:35:44)


ご学友(?)で、同じような質問をされている方がいます。
http://www2.realint.com/cgi-bin/tarticles.cgi?pointc+25831
少なくとも、自分が書いたソースコードくらい載せましょう。
#まるで分からないのであれば、まず講師に聞くべきでは?


この投稿にコメントする

削除パスワード

No.5384

Re:3*3行列の逆行列算出について
投稿者---MoriMori(2006/02/04 23:47:43)


こんな感じのプログラムなんですけど、
1次配列で表したいのです。


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

main()
{
int i, j, k, n;
double **a, *b;
double **l, **u;

printf( "元の数=" );
scanf( "%d", &n);

/* メモリ確保 */
a = (double**)malloc(n*sizeof(double*));
l = (double**)malloc(n*sizeof(double*));
u= (double**)malloc(n*sizeof(double*));
b = (double*)malloc(n*sizeof(double));
for( i = 0; i < n; i++ ){
a[i] = (double*)malloc(n*sizeof(double));
l[i] = (double*)malloc(n*sizeof(double));
u[i] = (double*)malloc(n*sizeof(double));
}

/* 連立方程式の入力 */
for( i = 0; i < n; i++ ){
for( j = 0; j < n; j++ ){
scanf( "%lf", &a[i][j] );
}
}
for( i = 0; i < n; i++ ){
scanf( "%lf", &b[i] );
}

/* 初期化 */
for( i = 0; i < n; i++ ){
for( j = 0; j < n; j++ ){
if( i == j ){ l[i][j] = 1; }
else{ l[i][j] = 0; }
u[i][j] = a[i][j];
}
}

/* LU分解 */
for( i = 0; i < n; i++ ){
for( j = i+1; j < n; j++ ){
l[j][i] = u[j][i] / u[i][i];
for( k = i; k < n; k++ ){
u[j][k] = u[j][k] - u[i][k] * l[j][i];
}
}
}

/* 解を求める */
for( i = 0; i < n; i++ ){
for( j = i+1; j < n; j++ ){
b[j] -= b[i] * l[j][i];
}
}
for( i = n-1; i >= 0; i-- ){
for( j = i+1; j<n; j++ ){
b[i] -= u[i][j] * b[j];
}
b[i] /= u[i][i];
}

/* 出力 */
printf( "L:\n" );
for( i = 0; i < n; i++ ){
for( j = 0; j < n; j++ ){
printf( "%10lf ", l[i][j] );
}
putchar( '\n' );
}
printf( "U:\n" );
for( i = 0; i < n; i++ ){
for( j = 0; j < n; j++ ){
printf( "%10lf ", u[i][j] );
}
putchar( '\n' );
}
for( i = 0; i < n; i++ ){
printf( "解X%2d=%10f\n", i+1, b[i] );
}
}




この投稿にコメントする

削除パスワード

No.5385

Re:3*3行列の逆行列算出について
投稿者---επιστημη(2006/02/04 23:59:07)


>1次配列で表したいのです。

一次元配列? ↓こんなの?

double* a_base = (double*)malloc(n*n*sizeof(double));
double** a = (double**)malloc(n*sizeof(double*));
for ( int i = 0; i < n; ++i ) {
 a[i] = a_base + n*sizeof(double)*i;
}



この投稿にコメントする

削除パスワード

No.5386

Re:3*3行列の逆行列算出について
投稿者---MoriMori(2006/02/05 00:10:28)


はい、1次配列で。
ここのところが、さっぱりなのです。


/* LU分解 */
for( i = 0; i < n; i++ ){
for( j = i+1; j < n; j++ ){
l[j][i] = u[j][i] / u[i][i];
for( k = i; k < n; k++ ){
u[j][k] = u[j][k] - u[i][k] * l[j][i];
}
}
}

/* 解を求める */
for( i = 0; i < n; i++ ){
for( j = i+1; j < n; j++ ){
b[j] -= b[i] * l[j][i];
}
}
for( i = n-1; i >= 0; i-- ){
for( j = i+1; j<n; j++ ){
b[i] -= u[i][j] * b[j];
}
b[i] /= u[i][i];
}







この投稿にコメントする

削除パスワード

No.5387

Re:3*3行列の逆行列算出について
投稿者---TJ(2006/02/05 00:21:19)
http://home.f01.itscom.net/toge/programingreport/


もしかして、

u[j][i]

とかでしたら

u[j*n + i]

ってやるとかそういう話ですか?


この投稿にコメントする

削除パスワード

No.5393

Re:3*3行列の逆行列算出について
投稿者---επιστημη(2006/02/05 04:32:28)


>はい、1次配列で。
>ここのところが、さっぱりなのです。

さっぱり、何?

配列 [a b c d e f g h i] を

[a b c]
[d e f]
[g h i]

であるかのように読み替えるだけでしょ?






この投稿にコメントする

削除パスワード

No.5392

Re:3*3行列の逆行列算出について
投稿者---Blue(2006/02/05 04:01:20)


http://www.fuka.info.waseda.ac.jp/~kozo/suuchi/simple_equation/simple_equation_4.html
からソース丸写しですよ。

引用ならば、きちんと表示しないとなりません。


この投稿にコメントする

削除パスワード

No.5390

Re:3*3行列の逆行列算出について
投稿者---Blue(2006/02/05 02:53:02)


1次元配列で、ってことになっているので
参考までに3*3の2次元配列で考えたソースを載せておきます。
(結構手抜きしてあります)
#include <stdio.h>

#define a( x, y ) ( ( *A )[ x - 1 ][ y - 1 ] )

double det2( const double ( *A )[ 2 ][ 2 ] )
{
    // サラスの公式
    return a( 1, 1 ) * a( 2, 2 ) - a( 1, 2 ) * a( 2, 1 );
}

double det3( const double ( *A )[ 3 ][ 3 ] )
{
    // サラスの公式
    return a( 1, 1 ) * a( 2, 2 ) * a( 3, 3 )
         + a( 1, 2 ) * a( 2, 3 ) * a( 3, 1 )
         + a( 1, 3 ) * a( 2, 1 ) * a( 3, 2 )
         - a( 1, 1 ) * a( 2, 3 ) * a( 3, 2 )
         - a( 1, 3 ) * a( 2, 2 ) * a( 3, 1 )
         - a( 1, 2 ) * a( 2, 1 ) * a( 3, 3 );
}

double cofactors( const double ( *A )[ 3 ][ 3 ], const int x, const int y )
{
    double B[ 2 ][ 2 ] = { 0 };
    int i, j, k = 0, l = 0;

    for ( i = 0; i < 3; i++ )
    {
        if ( i == x - 1 ) continue;

        for ( j = 0; j < 3; j++ )
        {
            if ( j == y - 1 ) continue;

            B[ k ][ l ] = ( *A )[ i ][ j ];

            l++;
        }
        l = 0;
        k++;
    }
    return ( ( x + y ) % 2 ? -1 : 1 ) * det2( &B );
}

// 逆行列を求める関数
//    -1     1   t~
//  A    = -----  A (行列式と余因子行列を利用)
//         | A |
void inverse(  const double ( *A )[ 3 ][ 3 ], double ( *B )[ 3 ][ 3 ] )
{
    int i, j;
    double d = det3( A );

    for ( i = 0; i < 3; i++ )
    {
        for ( j = 0; j < 3; j++ )
        {
            ( *B )[ j ][ i ] = cofactors( A, i + 1, j + 1 ) / d;
        }
    }
}

void printfmatrix( const double ( *A )[ 3 ][ 3 ] )
{
    printf( "( %lf, %lf, %f )\n", a( 1, 1 ), a( 1, 2 ), a( 1, 3 ) );
    printf( "( %lf, %lf, %f )\n", a( 2, 1 ), a( 2, 2 ), a( 2, 3 ) );
    printf( "( %lf, %lf, %f )\n", a( 3, 1 ), a( 3, 2 ), a( 3, 3 ) );
}

int main( void )
{
    double A[ 3 ][ 3 ] =
    {
        {  2.0,  2.0, -4.0 },
        {  1.0,  1.0, -3.0 },
        {  1.0,  4.0,  5.0 }
    };
    double B[ 3 ][ 3 ] = { 0 };

    inverse( &A, &B );

    puts( "行列" );
    printfmatrix( &A );
    puts( "の逆行列は" );
    printfmatrix( &B );

    return 0;
}

# C++でクラスにすると結構キレイにかけるかも。


この投稿にコメントする

削除パスワード

No.5391

Re:3*3行列の逆行列算出について
投稿者---επιστημη(2006/02/05 03:04:14)


># C++でクラスにすると結構キレイにかけるかも。

キレイかどうかはともかくも、コンパクトにはなるんじゃないかな。
std::valarray<double> 使えばサクサクでしょう。



この投稿にコメントする

削除パスワード

No.5396

Re:3*3行列の逆行列算出について
投稿者---MoriMori(2006/02/05 17:01:53)


一応実行はできるんですけど、間違った結果が出てしまいます。
どうすればよいのでしょうか?


/*逆行列を求める関数*/
double gyaku(struct kouzou *ex, struct kouzou *ex5, int m, int n){
int i, j, k;


for( i = 0; i < n; i++ ){
for( j = i+1; j < n; j++ ){
ex->yoso[j * m + i] /= ex->yoso[i * m + i];
for( k = i+1; k < n; k++ ){
ex->yoso[j * m + k] -= ex->yoso[i * m + k] * ex->yoso[j * m + i];
}
}
}



for( k = 0; k < n; k++ ){
for( i = 0; i < n; i++ ){
if( i == k ){ ex5->yoso[i * m + k] = 1; }
else{ex5->yoso[i * m + k] = 0; }
}
for( i = 0; i < n; i++ ){
for( j = i + 1; j < n; j++){
ex5->yoso[j * m + k] -= ex5->yoso[i * m + k] * ex->yoso[j * m + i];
}
}
for( i = n-1; i >= 0; i-- ){
for( j = i + 1; j < n; j++ ){
ex5->yoso[i * m + k] -= ex->yoso[i * m + j] * ex5->yoso[j * m + k];
}
ex5->yoso[i * m + k] /= ex->yoso[i * m + i];
}
}
}
/*出力関数*/
void shuturyoku(struct kouzou *ex, int m, int n){
int i,j;
printf("\n");
for(i = 0; i < m; i++){
for(j = 0; j < n; j++){
printf("%7.3f ", ex->yoso[i * n + j]);
}
printf("\n");
}
}



この投稿にコメントする

削除パスワード

No.5397

Re:3*3行列の逆行列算出について
投稿者---επιστημη(2006/02/05 18:39:03)


>一応実行はできるんですけど、間違った結果が出てしまいます。
>どうすればよいのでしょうか?

どこで間違っているかを突き止め、修正する。
要所要所にprinfをバラ撒き、途中経過をプリントすればわかるはず。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity