ページ 11

ガウスの消去法について(至急回答お願い致します。)

Posted: 2013年1月07日(月) 20:09
by タカヒロ
ピボットなしでのガウスの消去法のプログラムを作りました。
左下は0になるのですが、その他の値が変わりません。
それが原因だと思うのですが、答えも正しく出力されません。
間違いは前進消去部分にあると思うのですが・・・。

間違いを指摘してください。
よろしくお願いします。

コード:

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

void printarray1(int x,int y,double **a);
void printarray2(int x,double *a);

int main(int argc, char *argv[])
{
    
  int i,j,k,n;
  double *arr0,**arr1,*arr2,arr1kk,arr1ik,
    arr2kk,arr2ik,axsum;

    srand((unsigned)time(NULL));
    if(argc != 2){
	printf("未知数の数を入力してください\n");
	return -1;
    }

    n=atoi(argv[1]);  //未知数の数をnに格納

    //arr1が係数行列
    arr1 = (double **)malloc((sizeof(double)) * n);
    for(i=0;i<n;i++){
	arr1[i] = (double *)malloc((sizeof(double)) * n);
	for(j=0;j<n;j++){
	  arr1[i][j]=(rand()%10+1)/1.0;    //乱数で値を決めます
	}
    }
    printarray1(n,n,arr1);
    
    arr2 = (double *)malloc((sizeof(double)) * n);
    for(i=0;i<n;i++){
      arr2[i]=(rand()%10+1)/1.0;
    }
    printarray2(n,arr2);
    
    //答えを格納するための配列
    arr0 = (double *)malloc((sizeof(double)) * n);
    for(i=0;i<n;i++){
      arr0[i]=0;
    }

    //前進消去
    for(k=0;k<n;k++){
      arr1kk=arr1[k][k];
      for(i=k+1;i<n;i++){
	arr1ik=arr1[i][k];
	for(j=k;j<n+1;j++){
	  arr1[i][j]=arr1[i][j]-(arr1ik/arr1kk)*arr1[k][j];
	}
	arr2[i]=arr2[i]-(arr1ik/arr1kk)*arr2[k];
      }
    }
    printarray1(n,n,arr1);
    printarray2(n,arr2);

    //後進代入
    arr0[n-1]=arr2[n-1]/arr1[n-1][n-1];
    
    for(i=n-2;i>=0;i--){
      axsum=0.0;
      for(j=i+1;j<n;j++){
	axsum=axsum+arr1[i][j]*arr2[i];
      }
      arr0[i]=(arr2[i]-axsum)/arr1[i][i];
    }
    printarray2(n,arr0);
    return 0;

}


void printarray1(int x,int y,double **a)
{
  int i,j;
  int c;

  for(i=0;i<x;i++){
    c=0;
    for(j=0;j<y;j++){
      printf("%7.2f",a[i][j]);
      c++;
      if(c==y){
	puts("\n");
      }
    }
  }
  puts("\n");
}
 
void printarray2(int x,double *a)
{
  int i;
  for(i=0;i<x;i++){
    printf("%3f\n",a[i]);
  }
}


Re: ガウスの消去法について(至急回答お願い致します。)

Posted: 2013年1月07日(月) 20:32
by box
タカヒロ さんが書きました:

コード:

    arr1 = (double **)malloc((sizeof(double)) * n);
sizeof(double) で、本当に正しいでしょうか。

インデントがくずれている箇所が多く、コードが読みづらいです。
インデントをきちんとそろえることで、コードの間違いに気づくことがあるかもしれません。

コード:

    }
    }
のように、} の真下に } が来ることなど、私が持っているコーディングの常識からすれば、あり得ません。

コード:

      for(j=i+1;j<n;j++){
    axsum=axsum+arr1[i][j]*arr2[i];
      }
のように、for文によるループの中にある文がfor文より外に飛び出している点も、私の常識からすれば、あり得ません。
私の書き方をまねてほしいとは特に思いませんが、他の投稿者の方々がどういう書き方をしているかを
よくごらんになった方がよいと思います。

また、malloc()が絶対に成功する、という前提でコードを書かない方がいいと思います。

Re: ガウスの消去法について(至急回答お願い致します。)

Posted: 2013年1月07日(月) 20:58
by タカヒロ
boxさん
汚いコードで申し訳ありません。

sizeof(double)で間違ってるでしょうか。

間違いがあったら指摘してください。

Re: ガウスの消去法について(至急回答お願い致します。)

Posted: 2013年1月07日(月) 21:02
by box
タカヒロ さんが書きました: sizeof(double)で間違ってるでしょうか。
間違っているように思えて仕方がありません。
そのmallocでは、ポインターへのポインターが指す領域を確保したいのですから、
確保すべきはdouble型へのポインターであって、double型の実体ではないと思います。

Re: ガウスの消去法について(至急回答お願い致します。)

Posted: 2013年1月07日(月) 21:41
by タカヒロ
そうしますと、

コード:

arr1 = (double **)malloc(sizeof(double *) * n);
こういうことでしょうか?

Re: ガウスの消去法について(至急回答お願い致します。)

Posted: 2013年1月07日(月) 21:56
by box
タカヒロ さんが書きました:そうしますと、

コード:

arr1 = (double **)malloc(sizeof(double *) * n);
こういうことでしょうか?
はい。

Re: ガウスの消去法について(至急回答お願い致します。)

Posted: 2013年1月08日(火) 09:43
by タカヒロ
自己解決しました。
ありがとうございました