Exemple #1
0
int solver_gauss(void *A, void *B)
{ void *X;

  if(dim1(A) != dim1(B)) return 0;
  { static int **Y;
    if(-1 == dim2(B)){
      ary2(Y,2,1);
      if(NULL == Y) return 0;
      cp(B,Y[1]); cp(Y,X);
    }else cp(B,X);
  }
  if(siz(A) == sizeof(float) && siz(B) == sizeof(float)){
    float **a,*api,s,**x,*b,bpi;
#include "solver/fb.c"
  }else if(siz(A) == sizeof(float) && siz(B) == sizeof(double)){
    float **a,*api;double s,**x,*b,bpi;
#include "solver/fb.c"
  }else if(siz(A) == sizeof(double) && siz(B) == sizeof(float)){
    double **a,*api,s;float **x,*b,bpi;
#include "solver/fb.c"
  }else	if(siz(A) == sizeof(double) && siz(B) == sizeof(double)){
    double **a,*api,s,**x,*b,bpi;
#include "solver/fb.c"
  }else{ fprintf(stderr,"solver_gauss: not supported\n"); exit(1);}
  return 0;
}
Exemple #2
0
/* function invert */
static double invert(Matrix A,Vector x,double tol,int n,int *itr)
{
  static Matrix L;
  static Matrix U;
  static Vector y;
  static Vector s;
  double c, d, xmin,lambda;
  int m, i;

  ary2(L,n+1,n+1);
  ary2(U,n+1,n+1);
  ary1(y,n+1);
  ary1(s,n+1);

  lu(A,L,U,tol,n);           // AをLU分解する。結果はLとUに入れる
				  for (m=1; m<=itr[0]; m++){
    for (i=1; i<=n; i++)
       s[i]=x[i]; 
    subs(L,U,s,y,tol,n); // LUy = s の解yを求める処理。
    c=0; d=0;
    for (i=1; i<=n; i++){
      c+=y[i]*x[i];
      d+=y[i]*y[i];
    }
    lambda =c/d;
    itr[1]=m;
    if (fabs(xmin-lambda)<tol){
      return lambda;  /* 収束した */
    }
    xmin=lambda; 
    for (i=1; i<=n; i++)
        x[i]=y[i]/sqrt(d);  // xにyを正規化して代入
				 }
  itr[1]=m;
  return lambda;  //Itr回では収束しなかった
		      }
Exemple #3
0
int
main(int argc, char **argv)
{
  static xyc *Z; static nde *N;
  static double **A, *u;

  initop(argc, argv);
  fp2mesh(stdfp(),Z,N);

  ary2(A,dim1(Z)+1, dim1(Z)+1); ary1(u,dim1(Z)+1);

  set_A(Z,N,A); set_u(Z,u);

  esolver(A,u);

  plt(NULL,NULL,Z,N,u); sleep(1000);
  return 0;
}
Exemple #4
0
int estiva_pcgssolver(void* pA, double* x, double* b)
{

  /* (i)  引数の型と種類                                                */
  D_     D, B         ;/*    D  一次元配列 D(N), B(N)                   */
  D__    A            ;/*    D  二次元配列 A(N1, 2 * NL)                */
  I__    IA           ;/*    I  二次元配列 IA(N1, 2 * NL)               */
  D_     R            ;/*    D  一次元配列 R(N)                         */
  long   NL, N1, N, ITR, IER                                            ;
  double EPS, S                                                         ;
  D_     X, DD, P, Q  ;/*    D  一次元配列で, 要素は 0〜N               */
  I_     M            ;/*    I  一次元配列  M(2 * N)  作業用            */

  /*--    DからRまでと, EPSからSまでの引数は, サブルーチンPCGと同じ   --*/  

  D_     R0, E, H     ;/*    D  一次元配列  要素数はN                   */
  D_     W            ;/*    D  一次元配列  W(0:N)                      */
  
  long   i, j, k      ;
  
  N   = dim1(b)       ;
  NL  = count_NL(pA,N);
  
  ary1(  D, N   )         ;
  ary2(  A, 2*NL, N+2*NL );
  ary2( IA, 2*NL, N+2*NL );
  ary1(  R, N   )         ;
  ary1(  X, N+1 )         ;  ary1( DD, N+1 );  ary1( P, N+1 );  ary1( Q, N+1 ); 
  ary1(  M, 2*N )         ;

  ary1( R0, N   )         ;  ary1(  E, N   );  ary1( H, N   );
  ary1(  W, N+1 )         ;
  

  /* (ii) 主プログラム → サブルーチン                                  */
  /*      サブルーチンをCALLするときには, つぎの値を与える.             */
  /*  D   : 配列Dの第1〜第n位置に行列Aの対角要素を入れておく            */
  /*  N   : 行列Aの行数を入れておく.                                    */
  /*  N1  : 配列Aの行数を入れておく. N1≧N+2*NL でないといけない.       */
  /*  NL  : 行列Aの各行における非ゼロ要素数の最大値を入れておく.        */
  /*  B   : 連立一次方程式の右辺を入れておく.                           */
  /* EPS  : 収束判定置を入れておく. ふつうは 1.×10^(-7)                */
  /* ITR  : 打切りまでの最大繰返し回数を入れておく.                     */

  /*--    D, N, N1, NL, B, EPS, ITR については, サブルーチンPCGと同じ --*/

  /*  A   : 配列Aの各行1〜NL要素は, 行列Aの下三角部分の各行の非ゼロ     */
  /*        要素を入れる. また, 各行のNL+1〜2*NL要素は, 上三角部分      */
  /*        の各行の非ゼロ要素を入れる. ただし, 各行の対角要素は配列Dに */
  /*        入れる.                                                     */
  /* IA   : 配列Aに入れた要素の列番号を, 対応する位置に入れておく.      */
  /*  S   : LUCGS法のとき 0., MLUCG法のときσ(>0)を入れておく.          */  

  for(i=1; i<=N; i++) D[i-1] = mx(pA,i,i); 

  for(i=1; i<=N; i++)for(k=0, j=1; j<i; j++)if(mx(pA,i,j) != 0.0){
    A[k][i-1]  = mx(pA,i,j)  ;
    IA[k][i-1] = j       ;
    k++                  ;
  }

  for(i=1; i<=N; i++)for(k=NL, j=i+1; j<=N; j++)if(mx(pA,i,j) != 0.0){
    A[k][i-1]  = mx(pA,i,j) ;
    IA[k][i-1] = j       ;
    k++                  ;
  }
      

  N1  =  N+2*NL;

  B   = &b[1]  ;
  EPS = 1.0e-7 ;
  ITR = N      ;
  S   = 0.     ;
  
  /* (a) リンクの方法                                                   */
  /* CALL PCGS(D,A,IA,N,N1,NL,B,EPS,ITR,S,X,DD,P,Q,R,R0,E,H,W,M,IER)    */

  pcgs(D,A[0],IA[0],&N,&N1,&NL,B,&EPS,&ITR,
			    &S,X,DD,P,Q,R,R0,E,H,W,M,&IER);

  B   = &x[1]  ;
  for(i=0; i<N; i++) B[i] = X[i+1];
  return IER;
}