예제 #1
0
파일: matrix.c 프로젝트: kichiki/libstokes
/* solve generalized linear set of equations using LU-decomposition
 * INPUT
 *  n1, n2 : dimension
 *  A [n1 * n1] :
 *  B [n1 * n2] :
 *  C [n2 * n1] :
 *  D [n2 * n2] :
 *
 *  E [n1 * n1] :
 *  F [n1 * n2] :
 *  G [n2 * n1] :
 *  H [n2 * n2] :
 *  where the generalized linear set of equations is
 *   [A B](x) = [E F](b)
 *   [C D](y)   [G H](c)
 * OUTPUT
 *  I [n1 * n1] :
 *  J [n1 * n2] :
 *  K [n2 * n1] :
 *  L [n2 * n2] :
 *  where the generalized linear set of equations is
 *   (x) = [I J](b)
 *   (c)   [K L](y)
 *  note that A-D, E-H are destroyed!
 */
void
solve_gen_linear (int n1, int n2,
		  double * A, double * B, double * C, double * D,
		  double * E, double * F, double * G, double * H,
		  double * I, double * J, double * K, double * L)
{
  /* H := H^-1 */
  lapack_inv_ (n2, H);

  /* C := (H^-1) . C */
  mul_left_sq (C, n2, n1, H);
  /* G := (H^-1) . G */
  mul_left_sq (G, n2, n1, H);
  /* D := (H^-1) . D */
  mul_left_sq (D, n2, n2, H);


  double *a = (double *)malloc (sizeof (double) * n1 * n1);
  double *e = (double *)malloc (sizeof (double) * n1 * n1);
  double *b = (double *)malloc (sizeof (double) * n1 * n2);
  CHECK_MALLOC (a, "solve_gen_linear");
  CHECK_MALLOC (e, "solve_gen_linear");
  CHECK_MALLOC (b, "solve_gen_linear");

  /* a [n1, n1] := A - F.(H^-1).C */
  add_and_mul (A, n1, n1, F, n1, n2, C, n2, n1, 1.0, -1.0, a);
  // e [n1, n1] := E - F.(H^-1).G
  add_and_mul (E, n1, n1, F, n1, n2, G, n2, n1, 1.0, -1.0, e);
  // b [n1, n2] := - B + F.(H^-1).D
  add_and_mul (B, n1, n2, F, n1, n2, D, n2, n2, -1.0, 1.0, b);

  /* a := (A-F.(H^-1).C)^-1 */
  lapack_inv_ (n1, a);

  /* I := a.e */
  mul_matrices (a, n1, n1, e, n1, n1, I);
  /* J := a.b */
  mul_matrices (a, n1, n1, b, n1, n2, J);

  free (a);
  free (e);
  free (b);


  // K := - G + C.I
  add_and_mul (G, n2, n1, C, n2, n1, I, n1, n1, -1.0, 1.0, K);
  // L := D + C.J
  add_and_mul (D, n2, n2, C, n2, n1, J, n1, n2, 1.0, 1.0, L);
}
예제 #2
0
/* solve natural resistance problem in FT version in the fluid-rest frame
 * for both periodic and non-periodic boundary conditions
 * INPUT
 *  sys : system parameters
 *  u [np * 3] : = U - u^inf, that is, in the fluid-rest frame
 *  o [np * 3] : = O - O^inf, that is, in the fluid-rest frame
 * OUTPUT
 *  f [np * 3] :
 *  t [np * 3] :
 */
void
solve_res_lub_3ft_matrix_0 (struct stokes * sys,
			    const double *u, const double *o,
			    double *f, double *t)
{
  if (sys->version != 1)
    {
      fprintf (stderr, "libstokes solve_res_lub_3ft_matrix_0 :"
	       " the version is wrong. reset to FT\n");
      sys->version = 1;
    }

  int np = sys->np;
  int n6 = np * 6;

  double *mob = (double *) malloc (sizeof (double) * n6 * n6);
  double *lub = (double *) malloc (sizeof (double) * n6 * n6);
  double *b = (double *) malloc (sizeof (double) * n6);
  double *x = (double *) malloc (sizeof (double) * n6);
  CHECK_MALLOC (mob, "solve_res_lub_3ft_matrix");
  CHECK_MALLOC (lub, "solve_res_lub_3ft_matrix");
  CHECK_MALLOC (b, "solve_res_lub_3ft_matrix");
  CHECK_MALLOC (x, "solve_res_lub_3ft_matrix");

  // M matrix
  make_matrix_mob_3all (sys, mob); // sys->version is 1 (FT)
  // M^-1
  lapack_inv_ (n6, mob);

  // L matrix
  make_matrix_lub_3ft (sys, lub);

  // M^-1 + L
  int i;
  for (i = 0; i < n6 * n6; i ++)
    {
      lub [i] += mob [i];
    }
  free (mob);

  /* b := (UO) */
  set_ft_by_FT (np, b, u, o);

  // x := (M^-1 + L).(UO)
  dot_prod_matrix (lub, n6, n6, b, x);

  // (FT) = x
  set_FT_by_ft (np, f, t, x);

  free (lub);
  free (b);
  free (x);
}
예제 #3
0
파일: matrix.c 프로젝트: kichiki/libstokes
/* solve linear set of equations using LU-decomposition
 * INPUT
 *  n1, n2 : dimension
 *  A [n1 * n1] :
 *  B [n1 * n2] :
 *  C [n2 * n1] :
 *  D [n2 * n2] :
 *  where the generalized linear set of equations is
 *   (b) = [A B](x)
 *   (c)   [C D](y)
 * OUTPUT
 *  I [n1 * n1] :
 *  J [n1 * n2] :
 *  K [n2 * n1] :
 *  L [n2 * n2] :
 *  where the generalized linear set of equations is
 *   (x) = [I J](b)
 *   (c)   [K L](y)
 *  note that A-D are destroyed!
 */
void
solve_linear (int n1, int n2,
	      double * A, double * B, double * C, double * D,
	      double * I, double * J, double * K, double * L)
{
  int i;
  /* type 1 */

  /* A := A^-1 */
  lapack_inv_ (n1, A);

  /* B := (A^-1).B */
  double *tmp = (double *) malloc (sizeof (double) * n1 * n2);
  CHECK_MALLOC (tmp, "solve_linear");

  mul_matrices (A, n1, n1,
		B, n1, n2,
		tmp);

  for (i = 0; i < n1 * n2; i ++)
    {
      B[i] = tmp[i];
    }
  free (tmp);

  // L [n2, n2] := D - C.(A^-1).B
  add_and_mul (D, n2, n2, C, n2, n1, B, n1, n2, 1.0, -1.0, L);
  // K := C.A
  mul_matrices (C, n2, n1, A, n1, n1, K);

  for (i = 0; i < n1 * n1; ++i)
    {
      I [i] = A [i];
    }
  for (i = 0; i < n1 * n2; ++i)
    {
      J [i] = - B [i];
    }
}
예제 #4
0
/*
 * INPUT
 *  verbose : if non-zero, print results
 * OUTPUT
 *  (returned value) : 0 => passed
 *                     otherwise => failed
 */
int
check_lapack_inv_ (int n, int verbose, double tiny)
{
    if (verbose != 0)
    {
        fprintf (stdout,
                 "==================================================\n"
                 "check_lapack_inv_(n=%d) : start\n", n);
    }

    int check = 0;
    double max = 0.0;


    double *a  = (double *)malloc (sizeof (double) * n * n);
    double *a_ = (double *)malloc (sizeof (double) * n * n);
    double *b  = (double *)malloc (sizeof (double) * n * n);
    CHECK_MALLOC (a,  "check_lapack_inv_");
    CHECK_MALLOC (a_, "check_lapack_inv_");
    CHECK_MALLOC (b, "check_lapack_inv_");

    int i;
    srand48 (0);
    for (i = 0; i < n * n; i ++)
    {
        a [i] = drand48();
        a_[i] = a [i];
    }

    // a = a^-1
    lapack_inv_ (n, a);

    // b = a^-1 . a
    mul_matrices (a, n, n, a_, n, n, b);
    /*
    int j, k;
    for (i = 0; i < n; i ++)
      {
        for (j = 0; j < n; j ++)
    {
      b[i*n+j] = 0.0;
      for (k = 0; k < n; k ++)
        {
          b[i*n+j] += a[i*n+k] * a_[k*n+j];
        }
    }
      }
    */

    char label[80];
    double d;
    for (i = 0; i < n; i ++)
    {
        int j;
        for (j = 0; j < n; j ++)
        {
            if (i == j) d = fabs (b [i*n+j] - 1.0);
            else        d = fabs (b [i*n+j]);

            sprintf (label, "check_lapack_inv_ : [%d]", i);
            check += compare_max (d+1.0, 1.0, label, verbose, tiny, &max);
        }
    }

    free (a);
    free (a_);
    free (b);

    if (verbose != 0)
    {
        fprintf (stdout, " max error = %e vs tiny = %e\n", max, tiny);
        if (check == 0) fprintf (stdout, " => PASSED\n\n");
        else            fprintf (stdout, " => FAILED\n\n");
    }

    return (check);
}
예제 #5
0
파일: minv-poly.cpp 프로젝트: ryseto/demsd
/* calc scalar functions of (M^inf)^-1 in FTS for unequal spheres
 * INPUT
 *  r      := x_b - x_a
 *  aa, ab : radius of particle a and b
 * OUTPUT
 *  scalar_fts [44] : scalar functions in dimensional form!
 *       0, 1, 2, 3 : (XA11, XA12, XA21, XA22)
 *       4, 5, 6, 7 : (YA11, YA12, YA21, YA22)
 *       8, 9,10,11 : (YB11, YB12, YB21, YB22)
 *      12,13,14,15 : (XC11, XC12, XC21, XC22)
 *      16,17,18,19 : (YC11, YC12, YC21, YC22)
 *      20,21,22,23 : (XG11, XG12, XG21, XG22)
 *      24,25,26,27 : (YG11, YG12, YG21, YG22)
 *      28,29,30,31 : (YH11, YH12, YH21, YH22)
 *      32,33,34,35 : (XM11, XM12, XM21, XM22)
 *      36,37,38,39 : (YM11, YM12, YM21, YM22)
 *      40,41,42,43 : (ZM11, ZM12, ZM21, ZM22)
 */
void
scalars_minv_fts_poly (double r, double aa, double ab,
		       double *scalar_fts)
{
  double scalar [44];
  scalars_nonewald_poly_full (2, // FTS version
			      r, aa, ab, scalar);
  double xa11 = scalar [0];
  double xa12 = scalar [1];
  double xa21 = scalar [2];
  double xa22 = scalar [3];

  double ya11 = scalar [4];
  double ya12 = scalar [5];
  double ya21 = scalar [6];
  double ya22 = scalar [7];

  double yb11 = scalar [8];
  double yb12 = scalar [9];
  double yb21 = scalar[10];
  double yb22 = scalar[11];

  double xc11 = scalar[12];
  double xc12 = scalar[13];
  double xc21 = scalar[14];
  double xc22 = scalar[15];

  double yc11 = scalar[16];
  double yc12 = scalar[17];
  double yc21 = scalar[18];
  double yc22 = scalar[19];

  double xg11 = scalar[20];
  double xg12 = scalar[21];
  double xg21 = scalar[22];
  double xg22 = scalar[23];

  double yg11 = scalar[24];
  double yg12 = scalar[25];
  double yg21 = scalar[26];
  double yg22 = scalar[27];

  double yh11 = scalar[28];
  double yh12 = scalar[29];
  double yh21 = scalar[30];
  double yh22 = scalar[31];

  double xm11 = scalar[32];
  double xm12 = scalar[33];
  double xm21 = scalar[34];
  double xm22 = scalar[35];

  double ym11 = scalar[36];
  double ym12 = scalar[37];
  double ym21 = scalar[38];
  double ym22 = scalar[39];

  double zm11 = scalar[40];
  double zm12 = scalar[41];
  double zm21 = scalar[42];
  double zm22 = scalar[43];


  double mat [36];
  double det;

  // XC part
  double XC11, XC12, XC21, XC22;
  det = xc11*xc22 - xc12*xc21;
  XC11 =  xc22 / det;
  XC12 = -xc12 / det;
  XC21 = -xc21 / det;
  XC22 =  xc11 / det;

  // ZM part
  double ZM11, ZM12, ZM21, ZM22;
  det = zm11*zm22 - zm12*zm21;
  ZM11 =  zm22 / det;
  ZM12 = -zm12 / det;
  ZM21 = -zm21 / det;
  ZM22 =  zm11 / det;

  // Y part
  double YA11, YA12, YA21, YA22;
  double YB11, YB12, YB21, YB22;
  double YC11, YC12, YC21, YC22;
  double YG11, YG12, YG21, YG22;
  double YH11, YH12, YH21, YH22;
  double YM11, YM12, YM21, YM22;
  
  mat [0] = ya11;     //  ya11
  mat [1] = ya12;     //  ya12
  mat [2] = -yb11;    // -yb11
  mat [3] = yb21;     //  yb21
  mat [4] = 2.0*yg11; // 2 yg11
  mat [5] = -2.0*yg21;//-2 yg21

  mat [6] = ya21;     //  ya21
  mat [7] = ya22;     //  ya22
  mat [8] = -yb12;    //  -yb12
  mat [9] = yb22;     //   yb22
  mat[10] = 2.0*yg12; // 2 yg12
  mat[11] = -2.0*yg22;//-2 yg22

  mat[12] = -yb11;    //  -yb11
  mat[13] = -yb12;    //  -yb12
  mat[14] = yc11;     //  yc11
  mat[15] = yc12;     //  yc12
  mat[16] = 2.0*yh11; // 2 yh11
  mat[17] = 2.0*yh21; // 2 yh21

  mat[18] = yb21;     //  yb21
  mat[19] = yb22;     //  yb22
  mat[20] = yc21;     //  yc21
  mat[21] = yc22;     //  yc22
  mat[22] = 2.0*yh12; // 2 yh12
  mat[23] = 2.0*yh22; // 2 yh22

  mat[24] = yg11;    //  yg11
  mat[25] = yg12;    //  yg12
  mat[26] = yh11;    //  yh11
  mat[27] = yh12;    //  yh12
  mat[28] = ym11;    //  ym11
  mat[29] = ym12;    //  ym12

  mat[30] = -yg21;   // -yg21
  mat[31] = -yg22;   // -yg22
  mat[32] = yh21;    //  yh21
  mat[33] = yh22;    //  yh22
  mat[34] = ym21;    //  ym21
  mat[35] = ym22;    //  ym22

  lapack_inv_ (6, mat);
  YA11 =  mat [0];
  YA12 =  mat [1];
  YA21 =  mat [6];
  YA22 =  mat [7];
  YB11 = -mat[12];
  YB12 = -mat[13];
  YB21 =  mat[18];
  YB22 =  mat[19];
  YC11 =  mat[14];
  YC12 =  mat[15];
  YC21 =  mat[20];
  YC22 =  mat[21];
  YG11 =  mat[24];
  YG12 =  mat[25];
  YG21 = -mat[30];
  YG22 = -mat[31];
  YH11 =  mat[26];
  YH12 =  mat[27];
  YH21 =  mat[32];
  YH22 =  mat[33];
  YM11 =  mat[28];
  YM12 =  mat[29];
  YM21 =  mat[34];
  YM22 =  mat[35];


  // X part
  double XA11, XA12, XA21, XA22;
  double XG11, XG12, XG21, XG22;
  double XM11, XM12, XM21, XM22;

  double mp11 = 0.5*(xm11 + zm11); // = 0.9/aa3
  double mp12 = 0.5*(xm12 + zm12);
  double mm11 = 0.5*(xm11 - zm11); // = 0.0
  double mm12 = 0.5*(xm12 - zm12);

  double mp21 = 0.5*(xm21 + zm21); // = 0.9/aa3
  double mp22 = 0.5*(xm22 + zm22);
  double mm21 = 0.5*(xm21 - zm21); // = 0.0
  double mm22 = 0.5*(xm22 - zm22);
  
  mat [0] = xa11;     //  xa11
  mat [1] = xa12;     //  xa12
  mat [2] = -xg11;    // -xg11
  mat [3] = xg21;     //  xg21
  mat [4] = -xg11;    // -xg11
  mat [5] = xg21;     //  xg21

  mat [6] = xa21;     //  xa21
  mat [7] = xa22;     //  xa22
  mat [8] = -xg12;    // -xg12
  mat [9] = xg22;     //  xg22
  mat[10] = -xg12;    // -xg12
  mat[11] = xg22;     //  xg22

  mat[12] = -xg11/3.0;// -xg11/3
  mat[13] = -xg12/3.0;// -xg12/3
  mat[14] = mp11;     // m+11
  mat[15] = mp12;     // m+12
  mat[16] = mm11;     // m-11
  mat[17] = mm12;     // m-12

  mat[18] = xg21/3.0; // xg21/3
  mat[19] = xg22/3.0; // xg22/3
  mat[20] = mp21;     // m+21
  mat[21] = mp22;     // m+22
  mat[22] = mm21;     // m-21
  mat[23] = mm22;     // m-22

  mat[24] = -xg11/3.0;// -xg11/3
  mat[25] = -xg12/3.0;// -xg12/3
  mat[26] = mm11;     // m-11
  mat[27] = mm12;     // m-12
  mat[28] = mp11;     // m+11
  mat[29] = mp12;     // m+12

  mat[30] = xg21/3.0; // xg21/3
  mat[31] = xg22/3.0; // xg22/3
  mat[32] = mm21;     // m-21
  mat[33] = mm22;     // m-22
  mat[34] = mp21;     // m+21
  mat[35] = mp22;     // m+22

  lapack_inv_ (6, mat);
  XA11 = mat [0];
  XA12 = mat [1];
  XA21 = mat [6];
  XA22 = mat [7];
  XG11 = -3.0 * mat[12];
  XG12 = -3.0 * mat[13];
  XG21 = 3.0 * mat[18];
  XG22 = 3.0 * mat[19];
  XM11 = 2.0 * mat[14] - ZM11;
  XM12 = 2.0 * mat[15] - ZM12;
  XM21 = 2.0 * mat[20] - ZM21;
  XM22 = 2.0 * mat[21] - ZM22;

  scalar_fts [0] = XA11;
  scalar_fts [1] = XA12;
  scalar_fts [2] = XA21;
  scalar_fts [3] = XA22;
  scalar_fts [4] = YA11;
  scalar_fts [5] = YA12;
  scalar_fts [6] = YA21;
  scalar_fts [7] = YA22;
  scalar_fts [8] = YB11;
  scalar_fts [9] = YB12;
  scalar_fts[10] = YB21;
  scalar_fts[11] = YB22;
  scalar_fts[12] = XC11;
  scalar_fts[13] = XC12;
  scalar_fts[14] = XC21;
  scalar_fts[15] = XC22;
  scalar_fts[16] = YC11;
  scalar_fts[17] = YC12;
  scalar_fts[18] = YC21;
  scalar_fts[19] = YC22;
  scalar_fts[20] = XG11;
  scalar_fts[21] = XG12;
  scalar_fts[22] = XG21;
  scalar_fts[23] = XG22;
  scalar_fts[24] = YG11;
  scalar_fts[25] = YG12;
  scalar_fts[26] = YG21;
  scalar_fts[27] = YG22;
  scalar_fts[28] = YH11;
  scalar_fts[29] = YH12;
  scalar_fts[30] = YH21;
  scalar_fts[31] = YH22;
  scalar_fts[32] = XM11;
  scalar_fts[33] = XM12;
  scalar_fts[34] = XM21;
  scalar_fts[35] = XM22;
  scalar_fts[36] = YM11;
  scalar_fts[37] = YM12;
  scalar_fts[38] = YM21;
  scalar_fts[39] = YM22;
  scalar_fts[40] = ZM11;
  scalar_fts[41] = ZM12;
  scalar_fts[42] = ZM21;
  scalar_fts[43] = ZM22;
}
예제 #6
0
파일: minv-poly.cpp 프로젝트: ryseto/demsd
/* calc scalar functions of (M^inf)^-1 in FT for unequal spheres
 * INPUT
 *  r      := x_b - x_a
 *  aa, ab : radius of particle a and b
 * OUTPUT
 *  scalar_ft [20] : scalar functions in dimensional form!
 *      0, 1, 2, 3 : (XA11, XA12, XA21, XA22)
 *      4, 5, 6, 7 : (YA11, YA12, YA21, YA22)
 *      8, 9,10,11 : (YB11, YB12, YB21, YB22)
 *     12,13,14,15 : (XC11, XC12, XC21, XC22)
 *     16,17,18,19 : (YC11, YC12, YC21, YC22)
 */
void
scalars_minv_ft_poly (double r, double aa, double ab,
		      double *scalar_ft)
{
  double mat[16];
  double scalar[11];

  // (12)-interaction
  // scalar[] is in the dimensional form (not the SD scaling)
  scalars_nonewald_poly (1, // FT version
			 r, aa, ab, scalar);
  double xa12, ya12;
  double yb12;
  double xc12, yc12;

  double aa2 = aa * aa;
  double aa3 = aa2 * aa;
  xa12 = scalar [0];
  ya12 = scalar [1];
  yb12 = scalar [2];
  xc12 = scalar [3];
  yc12 = scalar [4];


  // (21)-interaction
  double xa21, ya21;
  double yb21;
  double xc21, yc21;
  double ab2 = ab * ab;
  double ab3 = ab2 * ab;
  /* note:
   * [xy]a12 = [xy]a21 in dimensional form by symmetry
   * [xy]c12 = [xy]c21 in dimensional form by symmetry
   * yb12 = yb21 in dimensional form for M^infty (lack of a dependence)
   * therefore, we do not need to calculate (21)-interaction explicitly
  */
  xa21 = xa12;
  ya21 = ya12;
  yb21 = yb12;
  xc21 = xc12;
  yc21 = yc12;

  double xa11, ya11;
  xa11 = 1.0 / aa;
  ya11 = 1.0 / aa;

  double xa22, ya22;
  xa22 = 1.0 / ab;
  ya22 = 1.0 / ab;

  double xc11, yc11;
  xc11 = 0.75 / aa3;
  yc11 = 0.75 / aa3;

  double xc22, yc22;
  xc22 = 0.75 / ab3;
  yc22 = 0.75 / ab3;

  double det;

  // XA part
  double XA11, XA12, XA21, XA22;
  det = xa11*xa22 - xa12*xa21;
  XA11 =  xa22 / det;
  XA12 = -xa12 / det;
  XA21 = -xa21 / det;
  XA22 =  xa11 / det;

  // XC part
  double XC11, XC12, XC21, XC22;
  det = xc11*xc22 - xc12*xc21;
  XC11 =  xc22 / det;
  XC12 = -xc12 / det;
  XC21 = -xc21 / det;
  XC22 =  xc11 / det;

  // Y part
  double YA11, YA12, YA21, YA22;
  double YB11, YB12, YB21, YB22;
  double YC11, YC12, YC21, YC22;
  mat [0] = ya11; //  ya11
  mat [1] = ya12; //  ya12
  mat [2] = 0.0;  // -yb11
  mat [3] = yb21; //  yb21

  mat [4] = ya21;  //  ya21
  mat [5] = ya22;  //  ya22
  mat [6] = -yb12; // -yb12
  mat [7] = 0.0;   //  yb22

  mat [8] = 0.0;   // -yb11
  mat [9] = -yb12; // -yb12
  mat[10] = yc11;  //  yc11
  mat[11] = yc12;  //  yc12

  mat[12] = yb21; // yb21
  mat[13] = 0.0;  // yb22
  mat[14] = yc21; // yc21
  mat[15] = yc22; // yc22

  lapack_inv_ (4, mat);
  YA11 =  mat [0];
  YA12 =  mat [1];
  YA21 =  mat [4];
  YA22 =  mat [5];
  YB11 = -mat [8];
  YB12 = -mat [9];
  YB21 =  mat[12];
  YB22 =  mat[13];
  YC11 =  mat[10];
  YC12 =  mat[11];
  YC21 =  mat[14];
  YC22 =  mat[15];

  scalar_ft [0] = XA11;
  scalar_ft [1] = XA12;
  scalar_ft [2] = XA21;
  scalar_ft [3] = XA22;
  scalar_ft [4] = YA11;
  scalar_ft [5] = YA12;
  scalar_ft [6] = YA21;
  scalar_ft [7] = YA22;
  scalar_ft [8] = YB11;
  scalar_ft [9] = YB12;
  scalar_ft[10] = YB21;
  scalar_ft[11] = YB22;
  scalar_ft[12] = XC11;
  scalar_ft[13] = XC12;
  scalar_ft[14] = XC21;
  scalar_ft[15] = XC22;
  scalar_ft[16] = YC11;
  scalar_ft[17] = YC12;
  scalar_ft[18] = YC21;
  scalar_ft[19] = YC22;
}
예제 #7
0
파일: toeplitz.c 프로젝트: kichiki/libiter
int
Toeplitz_check_all (int n, double gamma,
		    int it_max, int it_restart, double it_eps,
		    int verbose, double tiny)
{
  if (verbose != 0)
    {
      fprintf (stdout,
	       "==================================================\n"
	       "Toeplitz_check_all n = %d gamma = %e (eps = %e): start\n",
	       n, gamma, tiny);
    }

  int check = 0;


  double *b = (double *)malloc (sizeof (double) * n);
  double *x = (double *)malloc (sizeof (double) * n);
  double *mat = (double *)malloc (sizeof (double) * n * n);
  CHECK_MALLOC (b,   "Toeplitz_check_all");
  CHECK_MALLOC (x,   "Toeplitz_check_all");
  CHECK_MALLOC (mat, "Toeplitz_check_all");

  /* given vector */
  int i;
  for (i = 0; i < n; i ++)
    {
      b[i] = 1.0;
    }

  Toeplitz_make_matrix (n, gamma, mat);
  lapack_inv_ (n, mat);
  atimes_by_matrix (n, b, x, (void *)mat);
  // x[] is the solution
  free (mat);

  /* the following schemes failed...
   * Toeplitz problem is hard for them.
  // Steepest
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "steepest", it_max, it_restart, it_eps,
		    verbose, tiny);
  // CG
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "cg", it_max, it_restart, it_eps,
		    verbose, tiny);
  // CG, another implementation
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "cg_", it_max, it_restart, it_eps,
		    verbose, tiny);
  // CGS
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "cgs", it_max, it_restart, it_eps,
		    verbose, tiny);
  */

  /* Bi-CGSTAB may failed in high tolerance -- 
   * first converging up to a certain point,
   * then start diverging,
   * and after that, start converging again,
   * but the converged value has enormous errors
   * although the residual looks small....

  // Bi-CGSTAB (in Weiss)
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "bicgstab", it_max, it_restart, it_eps,
		    verbose, tiny);
  // Bi-CGSTAB
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "sta", it_max, it_restart, it_eps,
		    verbose, tiny);
  */
  // Bi-CGSTAB2
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "sta2", it_max, it_restart, it_eps,
		    verbose, tiny);

  // GPBi-CG
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "gpb", it_max, it_restart, it_eps,
		    verbose, tiny);

  // ORTHOMIN
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "otmk", it_max, it_restart, it_eps,
		    verbose, tiny);

  // GMRES
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, NULL, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "gmres", it_max, it_restart, it_eps,
		    verbose, tiny);

  /**
   * schemes with atimes_t()
   */
  // ATPRES
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, Toeplitz_atimes_t, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "atpres", it_max, it_restart, it_eps,
		    verbose, tiny);
  // CGNE
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, Toeplitz_atimes_t, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "cgne", it_max, it_restart, it_eps,
		    verbose, tiny);
  /* the following schemes failed...
   * maybe, Toeplitz problem is hard for them.
  // BICG
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, Toeplitz_atimes_t, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "bicg", it_max, it_restart, it_eps,
		    verbose, tiny);
  // BICO
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, Toeplitz_atimes_t, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "bico", it_max, it_restart, it_eps,
		    verbose, tiny);
  // QMR
  check +=
    check_iter_gen (n, b, b, // initial guess
		    Toeplitz_atimes, Toeplitz_atimes_t, (void *) &gamma,
		    NULL, NULL, // for preconditioner
		    x, // exact solution
		    "QMR", it_max, it_restart, it_eps,
		    verbose, tiny);
  */

  free (b);
  free (x);

  if (verbose != 0)
    {
      fprintf (stdout,
	       "--------------------------------------------------\n"
	       "Toeplitz_check_all n = %d gamma = %e (eps = %e): finished\n",
	       n, gamma, tiny);

      if (check == 0)
	fprintf (stdout, " => PASSED\n");
      else
	fprintf (stdout, " => FAILED\n");

      fprintf (stdout,
	       "==================================================\n\n");
    }

  return (check);
}
예제 #8
0
파일: system.cpp 프로젝트: ryseto/stodyn
void System::solveForceFreeRigidMotion(vec3d &Utf,
                                       vec3d &Otf){
    smallmatrix Mag_uf; Mag_uf.allocate_memory(3,3);
    smallmatrix Mag_ut; Mag_ut.allocate_memory(3,3);
    smallmatrix Mag_us; Mag_us.allocate_memory(3,5);
    //////////////////////////
    smallmatrix Mag_of; Mag_of.allocate_memory(3,3);
    smallmatrix Mag_ot; Mag_ot.allocate_memory(3,3);
    smallmatrix Mag_os; Mag_os.allocate_memory(3,5);
    //////////////////////////
    smallmatrix Mag_ef; Mag_ef.allocate_memory(5,3);
    smallmatrix Mag_et; Mag_et.allocate_memory(5,3);
    smallmatrix Mag_es; Mag_es.allocate_memory(5,5);
    
    for (int i=0; i < 121; i++){
        Mag[i] = Rag[i];
    }
    lapack_inv_ (11, Mag);
    
    for (int l=0; l< 3; l++){
        for (int k=0; k < 3 ; k++){
            Mag_uf.element[l][k] = Mag[k   + 11*l];
            Mag_ut.element[l][k] = Mag[3+k + 11*l];
            Mag_of.element[l][k] = Mag[k   + 11*(3+l)];
            Mag_ot.element[l][k] = Mag[3+k + 11*(3+l)];            
        }
        for (int k=0; k < 5 ; k++){
            Mag_us.element[l][k] = Mag[6+k + 11*l];
            Mag_os.element[l][k] = Mag[6+k + 11*(3+l)];
        } 
    }
    for (int l=0; l< 5; l++){
        for (int k=0; k < 3 ; k++){
            Mag_ef.element[l][k] = Mag[k   + 11*(6+l)];
            Mag_et.element[l][k] = Mag[3+k + 11*(6+l)];
        }
        for (int k=0; k < 5 ; k++){
            Mag_es.element[l][k] = Mag[6+k + 11*(6+l)];
        }
    }
    
    double *array_inv_Mag_es;
    array_inv_Mag_es = new double [25];
    for (int l=0; l< 5; l++){
        for (int k=0; k < 5 ; k++){
            array_inv_Mag_es[k + l*5] = Mag_es.element[l][k];
        }
    }
    
    lapack_inv_ (5, array_inv_Mag_es);
    smallmatrix inv_Mag_es;
    
    inv_Mag_es.allocate_memory(5,5);
    for (int l=0; l< 5; l++){
        for (int k=0; k < 5 ; k++){
            inv_Mag_es.element[l][k] = array_inv_Mag_es[k + l*5];
        }
    }
    
    double *Sag;
    Sag = new double [5];
    for (int l=0; l < 5; l++) {Sag[l] = 0;}
    inv_Mag_es.multiplyVector( sd->Ei, Sag );
    
    double *Uag, *Oag;
    Uag = new double[3];
    Oag = new double[3];
    
    Mag_us.multiplyVector( Sag, Uag );
    for (int l=0; l < 3 ; l++) Uag[l] = - Uag[l];
    Mag_os.multiplyVector( Sag, Oag );
    for (int l=0; l < 3 ; l++) Oag[l] = - Oag[l];
    
    Oag[0] += sd->Oi[0];
    Oag[1] += sd->Oi[1];
    Oag[2] += sd->Oi[2];
    
    Utf.set(Uag[0], Uag[1], Uag[2]);
    Otf.set(Oag[0], Oag[1], Oag[2]);
    
    DELETE(Sag);
    DELETE(Uag);
    DELETE(Oag);
    DELETE(array_inv_Mag_es);
    return;
}