Exemplo n.º 1
0
void implicit_1Dx(double *phi, double *xx,
                  double nu, double gamma, double h, double beta, double dt, int L,
                  int use_delj_trick) {
    int ii;

    double *dx = malloc((L-1) * sizeof(*dx));
    double *dfactor = malloc(L * sizeof(*dfactor));
    double *xInt = malloc((L-1) * sizeof(*xInt));

    double Mfirst, Mlast;
    double *MInt = malloc((L-1) * sizeof(*MInt));
    double *V = malloc(L * sizeof(*V));
    double *VInt = malloc((L-1) * sizeof(*VInt));

    double *delj = malloc((L-1) * sizeof(*delj));

    double *a = malloc(L * sizeof(*a));
    double *b = malloc(L * sizeof(*b));
    double *c = malloc(L * sizeof(*c));
    double *r = malloc(L * sizeof(*r));

    compute_dx(xx, L, dx);
    compute_dfactor(dx, L, dfactor);
    compute_xInt(xx, L, xInt);

    Mfirst = Mfunc1D(xx[0], gamma, h);
    Mlast = Mfunc1D(xx[L-1], gamma, h);
    for(ii=0; ii < L; ii++)
        V[ii] = Vfunc_beta(xx[ii], nu, beta);
    for(ii=0; ii < L-1; ii++) {
        MInt[ii] = Mfunc1D(xInt[ii], gamma, h);
        VInt[ii] = Vfunc_beta(xInt[ii], nu, beta);
    }

    compute_delj(dx, MInt, VInt, L, delj, use_delj_trick);

    compute_abc_nobc(dx, dfactor, delj, MInt, V, dt, L, a, b, c);
    for(ii = 0; ii < L; ii++)
        r[ii] = phi[ii]/dt;

    /* Boundary conditions */
    if(Mfirst <= 0)
        b[0] += (0.5/nu - Mfirst)*2./dx[0];
    if(Mlast >= 0)
        b[L-1] += -(-0.5/nu - Mlast)*2./dx[L-2];

    tridiag(a, b, c, r, phi, L);

    free(dx);
    free(dfactor);
    free(xInt);
    free(MInt);
    free(V);
    free(VInt);
    free(delj);
    free(a);
    free(b);
    free(c);
    free(r);
}
Exemplo n.º 2
0
void poisson_r(double *q, int m, int NR, int NZ, double dr, double dz)
 {
  int j;
  double *a,*b,*c,*r,alpha,beta;
  alpha=2.0*(cos(2.0*PI*m/(NZ))-1.0)/pow(dz,2);
  beta=4.0/pow(dr,2);
  a = new double[NR]; 
  b = new double[NR]; 
  c = new double[NR]; 
  r = new double[NR]; 
  for(j=1; j<NR; j++)
    {
     a[j]=(1.0-0.5/((double)j))/pow(dr,2);
     c[j]=(1.0+0.5/((double)j))/pow(dr,2);
     b[j]=2.0*((cos(2.0*PI*m/(NZ))-1.0)/pow(dz,2)-1.0/pow(dr,2));
     r[j]=-q[j]/eps0;
    }
  b[0]=alpha-beta;
  c[0]=beta; 
  r[0]=-q[0]/eps0; 
  tridiag(q,a,b,c,r,NR);
  delete a;
  delete b;
  delete c;
  delete r;
 }
Exemplo n.º 3
0
template<typename MatrixType> void qr(const MatrixType& m)
{
  /* this test covers the following files:
     QR.h
  */
  int rows = m.rows();
  int cols = m.cols();

  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> SquareMatrixType;
  typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;

  MatrixType a = MatrixType::Random(rows,cols);
  QR<MatrixType> qrOfA(a);
  VERIFY_IS_APPROX(a, qrOfA.matrixQ() * qrOfA.matrixR());
  VERIFY_IS_NOT_APPROX(a+MatrixType::Identity(rows, cols), qrOfA.matrixQ() * qrOfA.matrixR());

  SquareMatrixType b = a.adjoint() * a;

  // check tridiagonalization
  Tridiagonalization<SquareMatrixType> tridiag(b);
  VERIFY_IS_APPROX(b, tridiag.matrixQ() * tridiag.matrixT() * tridiag.matrixQ().adjoint());

  // check hessenberg decomposition
  HessenbergDecomposition<SquareMatrixType> hess(b);
  VERIFY_IS_APPROX(b, hess.matrixQ() * hess.matrixH() * hess.matrixQ().adjoint());
  VERIFY_IS_APPROX(tridiag.matrixT(), hess.matrixH());
  b = SquareMatrixType::Random(cols,cols);
  hess.compute(b);
  VERIFY_IS_APPROX(b, hess.matrixQ() * hess.matrixH() * hess.matrixQ().adjoint());
}
Exemplo n.º 4
0
 BOOST_FORCEINLINE result_type operator()(A0 const& a0,
                                          A1 const& a1,
                                          A2 const& a2) const
 {
   return tridiag(nt2::repnum(a0, nt2::numel(a2), size_t(1)),
                  a1,
                  a2);
 }
Exemplo n.º 5
0
 typename meta::call<nt2::tag::tridiag_(const I&, nt2::meta::as_<T>) >::type
 tridiag(const I& n)
 {
   return tridiag(n, nt2::meta::as_<T>());
 }
template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  /* this test covers the following files:
     EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)
  */
  Index rows = m.rows();
  Index cols = m.cols();

  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  RealScalar largerEps = 10*test_precision<RealScalar>();

  MatrixType a = MatrixType::Random(rows,cols);
  MatrixType a1 = MatrixType::Random(rows,cols);
  MatrixType symmA =  a.adjoint() * a + a1.adjoint() * a1;
  MatrixType symmC = symmA;
  
  svd_fill_random(symmA,Symmetric);

  symmA.template triangularView<StrictlyUpper>().setZero();
  symmC.template triangularView<StrictlyUpper>().setZero();

  MatrixType b = MatrixType::Random(rows,cols);
  MatrixType b1 = MatrixType::Random(rows,cols);
  MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
  symmB.template triangularView<StrictlyUpper>().setZero();
  
  CALL_SUBTEST( selfadjointeigensolver_essential_check(symmA) );

  SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
  // generalized eigen pb
  GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmC, symmB);

  SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
  VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
  VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());
  
  // generalized eigen problem Ax = lBx
  eiSymmGen.compute(symmC, symmB,Ax_lBx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(
          symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem BAx = lx
  eiSymmGen.compute(symmC, symmB,BAx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmB.template selfadjointView<Lower>() * (symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem ABx = lx
  eiSymmGen.compute(symmC, symmB,ABx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));


  eiSymm.compute(symmC);
  MatrixType sqrtSymmA = eiSymm.operatorSqrt();
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);
  VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());

  MatrixType id = MatrixType::Identity(rows, cols);
  VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));

  SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  eiSymmUninitialized.compute(symmA, false);
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  // test Tridiagonalization's methods
  Tridiagonalization<MatrixType> tridiag(symmC);
  VERIFY_IS_APPROX(tridiag.diagonal(), tridiag.matrixT().diagonal());
  VERIFY_IS_APPROX(tridiag.subDiagonal(), tridiag.matrixT().template diagonal<-1>());
  Matrix<RealScalar,Dynamic,Dynamic> T = tridiag.matrixT();
  if(rows>1 && cols>1) {
    // FIXME check that upper and lower part are 0:
    //VERIFY(T.topRightCorner(rows-2, cols-2).template triangularView<Upper>().isZero());
  }
  VERIFY_IS_APPROX(tridiag.diagonal(), T.diagonal());
  VERIFY_IS_APPROX(tridiag.subDiagonal(), T.template diagonal<1>());
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT() * tridiag.matrixQ().adjoint());
  
  // Test computation of eigenvalues from tridiagonal matrix
  if(rows > 1)
  {
    SelfAdjointEigenSolver<MatrixType> eiSymmTridiag;
    eiSymmTridiag.computeFromTridiagonal(tridiag.matrixT().diagonal(), tridiag.matrixT().diagonal(-1), ComputeEigenvectors);
    VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmTridiag.eigenvalues());
    VERIFY_IS_APPROX(tridiag.matrixT(), eiSymmTridiag.eigenvectors().real() * eiSymmTridiag.eigenvalues().asDiagonal() * eiSymmTridiag.eigenvectors().real().transpose());
  }

  if (rows > 1)
  {
    // Test matrix with NaN
    symmC(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
    SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmC);
    VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
  }
}
template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  /* this test covers the following files:
     EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)
  */
  Index rows = m.rows();
  Index cols = m.cols();

  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
  typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
  typedef typename std::complex<typename NumTraits<typename MatrixType::Scalar>::Real> Complex;

  RealScalar largerEps = 10*test_precision<RealScalar>();

  MatrixType a = MatrixType::Random(rows,cols);
  MatrixType a1 = MatrixType::Random(rows,cols);
  MatrixType symmA =  a.adjoint() * a + a1.adjoint() * a1;
  symmA.template triangularView<StrictlyUpper>().setZero();

  MatrixType b = MatrixType::Random(rows,cols);
  MatrixType b1 = MatrixType::Random(rows,cols);
  MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
  symmB.template triangularView<StrictlyUpper>().setZero();

  SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
  // generalized eigen pb
  GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmA, symmB);

  #ifdef HAS_GSL
  if (internal::is_same<RealScalar,double>::value)
  {
    // restore symmA and symmB.
    symmA = MatrixType(symmA.template selfadjointView<Lower>());
    symmB = MatrixType(symmB.template selfadjointView<Lower>());
    typedef GslTraits<Scalar> Gsl;
    typename Gsl::Matrix gEvec=0, gSymmA=0, gSymmB=0;
    typename GslTraits<RealScalar>::Vector gEval=0;
    RealVectorType _eval;
    MatrixType _evec;
    convert<MatrixType>(symmA, gSymmA);
    convert<MatrixType>(symmB, gSymmB);
    convert<MatrixType>(symmA, gEvec);
    gEval = GslTraits<RealScalar>::createVector(rows);

    Gsl::eigen_symm(gSymmA, gEval, gEvec);
    convert(gEval, _eval);
    convert(gEvec, _evec);

    // test gsl itself !
    VERIFY((symmA * _evec).isApprox(_evec * _eval.asDiagonal(), largerEps));

    // compare with eigen
    VERIFY_IS_APPROX(_eval, eiSymm.eigenvalues());
    VERIFY_IS_APPROX(_evec.cwiseAbs(), eiSymm.eigenvectors().cwiseAbs());

    // generalized pb
    Gsl::eigen_symm_gen(gSymmA, gSymmB, gEval, gEvec);
    convert(gEval, _eval);
    convert(gEvec, _evec);
    // test GSL itself:
    VERIFY((symmA * _evec).isApprox(symmB * (_evec * _eval.asDiagonal()), largerEps));

    // compare with eigen
    MatrixType normalized_eivec = eiSymmGen.eigenvectors()*eiSymmGen.eigenvectors().colwise().norm().asDiagonal().inverse();
    VERIFY_IS_APPROX(_eval, eiSymmGen.eigenvalues());
    VERIFY_IS_APPROX(_evec.cwiseAbs(), normalized_eivec.cwiseAbs());

    Gsl::free(gSymmA);
    Gsl::free(gSymmB);
    GslTraits<RealScalar>::free(gEval);
    Gsl::free(gEvec);
  }
  #endif

  VERIFY_IS_EQUAL(eiSymm.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiSymm.eigenvectors()).isApprox(
          eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal(), largerEps));
  VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());

  SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
  VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
  VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());

  // generalized eigen problem Ax = lBx
  eiSymmGen.compute(symmA, symmB,Ax_lBx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(
          symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem BAx = lx
  eiSymmGen.compute(symmA, symmB,BAx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmB.template selfadjointView<Lower>() * (symmA.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem ABx = lx
  eiSymmGen.compute(symmA, symmB,ABx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));


  MatrixType sqrtSymmA = eiSymm.operatorSqrt();
  VERIFY_IS_APPROX(MatrixType(symmA.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);
  VERIFY_IS_APPROX(sqrtSymmA, symmA.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());

  MatrixType id = MatrixType::Identity(rows, cols);
  VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));

  SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  eiSymmUninitialized.compute(symmA, false);
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  // test Tridiagonalization's methods
  Tridiagonalization<MatrixType> tridiag(symmA);
  // FIXME tridiag.matrixQ().adjoint() does not work
  VERIFY_IS_APPROX(MatrixType(symmA.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());

  if (rows > 1)
  {
    // Test matrix with NaN
    symmA(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
    SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmA);
    VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
  }
}
Exemplo n.º 8
0
int main(void)
{
  int i, j, n, wahl;
  double vektor[NMAX];
  double matrix[NMAX][NMAX];
  
  printf("\n Bitte geben Sie die Spaltenzahl der zu erzeugenden Matrix ein : ");
  scanf("%d",&n);

  if (n > NMAX)
  {
    printf("\n\nArraygrenze überschritten - NMAX muß größer gewählt werden !");
    exit(1);
  }

  else
  {
    printf("\n Welchen Typ von Matrix wollen Sie erzeugen : \n");
    printf("\n                Einheitsmatrix          1");
    printf("\n                Nullmatrix              2");
    printf("\n                Symmetr. Zufallsmatrix  3");
    printf("\n                Trigonalmatrix          4");
    printf("\n\nBitte treffen Sie eine Wahl : ");
    scanf("%d",&wahl);

    switch(wahl)
    {
      case 1:  ident(n,matrix);
               break;

      case 2:  zeros(n,matrix);
               break;

      case 3:  randsym(n,matrix);
               break;

      case 4:  printf("\nBitte geben Sie den zu übergebenden Diagonalvektor ein :\n\n");

               for (i=0; i<n; i++)
               {
                 printf("%2d.-te Komponente des Vektors : ",i+1);
                 scanf("%lg",&vektor[i]);
               }

               tridiag(n,matrix,vektor);
               break;           

      default: exit(1);
    }

    printf("\n\n\t");   

    for (i=0; i<n; i++)
    {
      for (j=0; j<n; j++)
      	printf(" %2lg",matrix[i][j]);

      printf("\n\t");
    }
  
    printf("\n\n");

  }

  return 0;
}
Exemplo n.º 9
0
long BiCGSTAB_upper(double tol_rel, double tol_min, double tol_max, DOUBLEVECTOR *x, DOUBLEVECTOR *b, 
					LONGVECTOR *Ai, LONGVECTOR *Ap, DOUBLEVECTOR *Ax){
	
	DOUBLEVECTOR *r0, *r, *p, *v, *s, *t, *diag, *udiag, *y, *z;
	double rho, rho1, alpha, omeg, beta, norm_r0;
	long i=0, j;
	
	r0 = new_doublevector(x->nh);
	r = new_doublevector(x->nh);
	p = new_doublevector(x->nh);
	v = new_doublevector(x->nh);
	s = new_doublevector(x->nh);
	t = new_doublevector(x->nh);
	diag = new_doublevector(x->nh);
	udiag = new_doublevector(x->nh-1);
	y = new_doublevector(x->nh);
	z = new_doublevector(x->nh);
	
	get_diag_upper_matrix(diag, udiag, Ai, Ap, Ax);
	
	product_using_only_upper_diagonal_part(r, x, Ai, Ap, Ax);
	
    for (j=x->nl;j<=x->nh;j++ ) {	
    	r->co[j] = b->co[j] - r->co[j];
		r0->co[j] = r->co[j];
		p->co[j] = 0.;
		v->co[j] = 0.;
    }
	
	norm_r0 = norm_2(r0,r0->nh);
	
	rho = 1.;
	alpha = 1.;
	omeg = 1.;
	
	while ( i<=x->nh && norm_2(r,r->nh) > Fmax( tol_min , Fmin( tol_max , tol_rel*norm_r0) ) ) {
		
		rho1 = product(r0, r);
		
		beta = (rho1/rho)*(alpha/omeg);
		
		rho = rho1;
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			p->co[j] = r->co[j] + beta*(p->co[j] - omeg*v->co[j]);
		}
		
		tridiag(0, 0, 0, x->nh, udiag, diag, udiag, p, y);
		
		product_using_only_upper_diagonal_part(v, y, Ai, Ap, Ax);
		
		alpha = rho/product(r0, v);
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			s->co[j] = r->co[j] - alpha*v->co[j];
		}
		
		tridiag(0, 0, 0, x->nh, udiag, diag, udiag, s, z);	
		
		product_using_only_upper_diagonal_part(t, z, Ai, Ap, Ax);
		
		omeg = product(t, s)/product(t, t);
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			x->co[j] += (alpha*y->co[j] + omeg*z->co[j]);
			r->co[j] = s->co[j] - omeg*t->co[j];
		}
		
		i++;
		
		//printf("i:%ld normr0:%e normr:%e\n",i,norm_r0,norm_2(r,r->nh));
		
	}
	
	
	free_doublevector(r0);
	free_doublevector(r);
	free_doublevector(p);
	free_doublevector(v);
	free_doublevector(s);
	free_doublevector(t);
	free_doublevector(diag);
	free_doublevector(udiag);
	free_doublevector(y);
	free_doublevector(z);
	
	return i;
	
}
Exemplo n.º 10
0
long BiCGSTAB(double tol_rel, double tol_min, double tol_max, DOUBLEVECTOR *x, DOUBLEVECTOR *x0, 
			  double dt, DOUBLEVECTOR *b, t_Matrix_element_with_voidp function, void *data){

	/* \author Stefano Endrizzi
	   \date March 2010	
	   from BI-CGSTAB: A FAST AND SMOOTHLY CONVERGING VARIANT OF BI-CG FOR THE SOLUTION OF NONSYMMETRIC LINEAR SYSTEMS
	   by H. A. VAN DER VORST - SIAM J. ScI. STAT. COMPUT. Vol. 13, No. 2, pp. 631-644, March 1992
	*/

	DOUBLEVECTOR *r0, *r, *p, *v, *s, *t, *diag, *udiag, *y, *z;
	//DOUBLEVECTOR *tt, *ss;
	double rho, rho1, alpha, omeg, beta, norm_r0;
	long i=0, j;
	
	r0 = new_doublevector(x->nh);
	r = new_doublevector(x->nh);
	p = new_doublevector(x->nh);
	v = new_doublevector(x->nh);
	s = new_doublevector(x->nh);
	t = new_doublevector(x->nh);
	diag = new_doublevector(x->nh);
	udiag = new_doublevector(x->nh-1);
	y = new_doublevector(x->nh);
	z = new_doublevector(x->nh);
	//tt = new_doublevector(x->nh);
	//ss = new_doublevector(x->nh);
	
	get_diagonal(diag,x0,dt,function,data);
    get_upper_diagonal(udiag,x0,dt,function,data);

    for (j=x->nl;j<=x->nh;j++ ) {		
    	r0->co[j] = b->co[j] - (*function)(j,x,x0,dt,data);
		r->co[j] = r0->co[j];
		p->co[j] = 0.;
		v->co[j] = 0.;
    }
	
	norm_r0 = norm_2(r0,r0->nh);
	
	rho = 1.;
	alpha = 1.;
	omeg = 1.;
	
	while ( i<=x->nh && norm_2(r,r->nh) > Fmax( tol_min , Fmin( tol_max , tol_rel*norm_r0) ) ) {
		
		rho1 = product(r0, r);
		
		beta = (rho1/rho)*(alpha/omeg);
		
		rho = rho1;
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			p->co[j] = r->co[j] + beta*(p->co[j] - omeg*v->co[j]);
		}
		
		tridiag(0, 0, 0, x->nh, udiag, diag, udiag, p, y);
		
		for (j=x->nl;j<=x->nh;j++ ) {	
			v->co[j] = (*function)(j,y,x0,dt,data);
		}
		
		alpha = rho/product(r0, v);
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			s->co[j] = r->co[j] - alpha*v->co[j];
		}
		
		tridiag(0, 0, 0, x->nh, udiag, diag, udiag, s, z);	
		
		for (j=x->nl;j<=x->nh;j++ ) {	
			t->co[j] = (*function)(j,z,x0,dt,data);
		}
		
		/*tridiag(0, 0, 0, x->nh, udiag, diag, udiag, t, tt);
		tridiag(0, 0, 0, x->nh, udiag, diag, udiag, s, ss);
		omeg = product(tt, ss)/product(tt, tt);*/
		
		omeg = product(t, s)/product(t, t);
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			x->co[j] += (alpha*y->co[j] + omeg*z->co[j]);
			r->co[j] = s->co[j] - omeg*t->co[j];
		}
		
		i++;
		
		//printf("i:%ld normr0:%e normr:%e\n",i,norm_r0,norm_2(r,r->nh));
		
	}
	
	
	free_doublevector(r0);
	free_doublevector(r);
	free_doublevector(p);
	free_doublevector(v);
	free_doublevector(s);
	free_doublevector(t);
	free_doublevector(diag);
	free_doublevector(udiag);
	free_doublevector(y);
	free_doublevector(z);
	//free_doublevector(tt);
	//free_doublevector(ss);
	
	return i;
	
}
Exemplo n.º 11
0
long BiCGSTAB_strict_lower_matrix_plus_identity_by_vector(double tol_rel, double tol_min, double tol_max, DOUBLEVECTOR *x, 
									DOUBLEVECTOR *b, DOUBLEVECTOR *y, LONGVECTOR *Li, LONGVECTOR *Lp, DOUBLEVECTOR *Lx){
	
	//solve sistem (A+Iy)*x = B, find x
	//A M-matrix described by its lower diagonal part
	
	DOUBLEVECTOR *r0, *r, *p, *v, *s, *t, *diag, *udiag, *yy, *z;
	double rho, rho1, alpha, omeg, beta, norm_r0;
	long i=0, j;
	
	r0 = new_doublevector(x->nh);
	r = new_doublevector(x->nh);
	p = new_doublevector(x->nh);
	v = new_doublevector(x->nh);
	s = new_doublevector(x->nh);
	t = new_doublevector(x->nh);
	diag = new_doublevector(x->nh);
	udiag = new_doublevector(x->nh-1);
	yy = new_doublevector(x->nh);
	z = new_doublevector(x->nh);
	
	get_diag_strict_lower_matrix_plus_identity_by_vector(diag, udiag, y, Li, Lp, Lx);

	//product_using_only_strict_lower_diagonal_part_plus_identity_by_vector(r, x, y, Li, Lp, Lx);
	
    for (j=x->nl;j<=x->nh;j++ ) {	
    	//r->co[j] = b->co[j] - r->co[j];
		r->co[j] = b->co[j];
		r0->co[j] = r->co[j];
		p->co[j] = 0.;
		v->co[j] = 0.;
    }
	
	norm_r0 = norm_2(r0,r0->nh);
	
	rho = 1.;
	alpha = 1.;
	omeg = 1.;
	
	while ( i<=x->nh && norm_2(r,r->nh) > Fmax( tol_min , Fmin( tol_max , tol_rel*norm_r0) ) ) {
		
		rho1 = product(r0, r);
		
		beta = (rho1/rho)*(alpha/omeg);
		
		rho = rho1;
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			p->co[j] = r->co[j] + beta*(p->co[j] - omeg*v->co[j]);
		}
		
		tridiag(0, 0, 0, x->nh, udiag, diag, udiag, p, yy);
		
		product_using_only_strict_lower_diagonal_part_plus_identity_by_vector(v, yy, y, Li, Lp, Lx);
		
		alpha = rho/product(r0, v);
		
		for (j=x->nl;j<=x->nh;j++ ) {		
			s->co[j] = r->co[j] - alpha*v->co[j];
		}
		
		if(norm_2(s,s->nh)>1.E-10){
		
			tridiag(0, 0, 0, x->nh, udiag, diag, udiag, s, z);	
		
			product_using_only_strict_lower_diagonal_part_plus_identity_by_vector(t, z, y, Li, Lp, Lx);

			omeg = product(t, s)/product(t, t);
		
			for (j=x->nl;j<=x->nh;j++ ) {		
				x->co[j] += (alpha*yy->co[j] + omeg*z->co[j]);
				r->co[j] = s->co[j] - omeg*t->co[j];
			}
			
		}else{
			
			for (j=x->nl;j<=x->nh;j++ ) {		
				x->co[j] += alpha*yy->co[j];
				r->co[j] = s->co[j];
			}	
			
		}
		
		i++;
		
		//printf("i:%ld normr0:%e normr:%e\n",i,norm_r0,norm_2(r,r->nh));
		
	}
	
	
	free_doublevector(r0);
	free_doublevector(r);
	free_doublevector(p);
	free_doublevector(v);
	free_doublevector(s);
	free_doublevector(t);
	free_doublevector(diag);
	free_doublevector(udiag);
	free_doublevector(yy);
	free_doublevector(z);
	
	return i;
	
}
Exemplo n.º 12
0
long CG(double tol_rel, double tol_min, double tol_max, DOUBLEVECTOR *x, DOUBLEVECTOR *x0, double dt, 
		DOUBLEVECTOR *b, t_Matrix_element_with_voidp function, void *data){

	/*!
	 *\param icnt  - (long) number of reiterations
	 *\param epsilon - (double) required tollerance (2-order norm of the residuals)
	 *\param x     - (DOUBLEVECTOR *) vector of the unknowns x in Ax=b
	 *\param b     - (DOUBLEVECTOR *) vector of b in Ax=b
	 *\param funz  - (t_Matrix_element_with_voidp) - (int) pointer to the application A (x and y doublevector y=A(param)x ) it return 0 in case of success, -1 otherwise.
	 *\param data - (void *) data and parameters related to the  argurment  t_Matrix_element_with_voidp funz
	 *
	 *
	 *\brief algorithm proposed by Jonathan Richard Shewckuck in http://www.cs.cmu.edu/~jrs/jrspapers.html#cg and http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf
	 *
	 * \author Emanuele Cordano
	 * \date June 2009
	 *
	 *\return the number of reitarations
	 */


	double delta,alpha,beta,delta_new;
	DOUBLEVECTOR *r, *d,*q,*y,*sr,*diag,*udiag;

	int sl;
	long icnt_max;
	long icnt;
	long j;
	double p;
	double norm_r0;

	r=new_doublevector(x->nh);
	d=new_doublevector(x->nh);
	q=new_doublevector(x->nh);
	y=new_doublevector(x->nh);
	sr=new_doublevector(x->nh);
	diag=new_doublevector(x->nh);
	udiag=new_doublevector(x->nh-1);
	
	icnt=0;
	icnt_max=x->nh;
	//icnt_max=(long)(sqrt((double)x->nh));

	for (j=x->nl;j<=x->nh;j++){
		y->co[j]=(*function)(j,x,x0,dt,data);
	}

    get_diagonal(diag,x0,dt,function,data);
    get_upper_diagonal(udiag,x0,dt,function,data);
	
    delta_new=0.0;

    for (j=y->nl;j<=y->nh;j++) {

    	r->co[j]=b->co[j]-y->co[j];

    	if (diag->co[j]<0.0) {
    		diag->co[j]=1.0;
    		printf("\n Error in jacobi_preconditioned_conjugate_gradient_search function: diagonal of the matrix (%lf) is negative at %ld \n",diag->co[j],j);
    		stop_execution();
    	}
		
    }
	
    tridiag(0,0,0,x->nh,udiag,diag,udiag,r,d);

    for (j=y->nl;j<=y->nh;j++) {
    	//d->co[j]=r->co[j]/diag->co[j];
    	delta_new+=r->co[j]*d->co[j];
    }
	
	norm_r0 = norm_2(r, r->nh);
					
	while ( icnt<=icnt_max && norm_2(r, r->nh) > Fmax( tol_min , Fmin( tol_max , tol_rel*norm_r0) ) ) {

		delta=delta_new;
		p=0.0;

		for(j=q->nl;j<=q->nh;j++) {
			q->co[j]=(*function)(j,d,x0,dt,data);
			p+=q->co[j]*d->co[j];

		}
		alpha=delta_new/p;
		for(j=x->nl;j<=x->nh;j++) {
			x->co[j]=x->co[j]+alpha*d->co[j];
		}


	    delta_new=0.0;
	    sl=0;
	    for (j=y->nl;j<=y->nh;j++) {
	    	if (icnt%MAX_ITERATIONS==0) {
					y->co[j]=(*function)(j,x,x0,dt,data);
					r->co[j]=b->co[j]-y->co[j];
	    	} else {
					r->co[j]=r->co[j]-alpha*q->co[j];
	    	}
	    }

	    tridiag(0,0,0,x->nh,udiag,diag,udiag,r,sr);

	    for (j=y->nl;j<=y->nh;j++) {
	    	delta_new+=sr->co[j]*r->co[j];

	    }
	    beta=delta_new/delta;
		for (j=d->nl;j<=d->nh;j++) {
			 d->co[j]=sr->co[j]+beta*d->co[j];
		}

		icnt++;

		//printf("i:%ld normr0:%e normr:%e\n",icnt,norm_r0,norm_2(r,r->nh));


	}

	//printf("norm_r:%e\n",norm_2(r,r->nh));

	free_doublevector(udiag);
	free_doublevector(diag);
	free_doublevector(sr);
	free_doublevector(r);
	free_doublevector(d);
	free_doublevector(q);
	free_doublevector(y);


	return icnt;

}
Exemplo n.º 13
0
template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  /* this test covers the following files:
     EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)
  */
  Index rows = m.rows();
  Index cols = m.cols();

  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  RealScalar largerEps = 10*test_precision<RealScalar>();

  MatrixType a = MatrixType::Random(rows,cols);
  MatrixType a1 = MatrixType::Random(rows,cols);
  MatrixType symmA =  a.adjoint() * a + a1.adjoint() * a1;
  MatrixType symmC = symmA;

  // randomly nullify some rows/columns
  {
    Index count = 1;//internal::random<Index>(-cols,cols);
    for(Index k=0; k<count; ++k)
    {
      Index i = internal::random<Index>(0,cols-1);
      symmA.row(i).setZero();
      symmA.col(i).setZero();
    }
  }

  symmA.template triangularView<StrictlyUpper>().setZero();
  symmC.template triangularView<StrictlyUpper>().setZero();

  MatrixType b = MatrixType::Random(rows,cols);
  MatrixType b1 = MatrixType::Random(rows,cols);
  MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
  symmB.template triangularView<StrictlyUpper>().setZero();

  SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
  SelfAdjointEigenSolver<MatrixType> eiDirect;
  eiDirect.computeDirect(symmA);
  // generalized eigen pb
  GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmC, symmB);

  VERIFY_IS_EQUAL(eiSymm.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiSymm.eigenvectors()).isApprox(
          eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal(), largerEps));
  VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());

  VERIFY_IS_EQUAL(eiDirect.info(), Success);
  VERIFY((symmA.template selfadjointView<Lower>() * eiDirect.eigenvectors()).isApprox(
          eiDirect.eigenvectors() * eiDirect.eigenvalues().asDiagonal(), largerEps));
  VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiDirect.eigenvalues());

  SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
  VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
  VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());

  // generalized eigen problem Ax = lBx
  eiSymmGen.compute(symmC, symmB,Ax_lBx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(
          symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem BAx = lx
  eiSymmGen.compute(symmC, symmB,BAx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmB.template selfadjointView<Lower>() * (symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));

  // generalized eigen problem ABx = lx
  eiSymmGen.compute(symmC, symmB,ABx_lx);
  VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
  VERIFY((symmC.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(
         (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));


  eiSymm.compute(symmC);
  MatrixType sqrtSymmA = eiSymm.operatorSqrt();
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);
  VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());

  MatrixType id = MatrixType::Identity(rows, cols);
  VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));

  SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  eiSymmUninitialized.compute(symmA, false);
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
  VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());

  // test Tridiagonalization's methods
  Tridiagonalization<MatrixType> tridiag(symmC);
  // FIXME tridiag.matrixQ().adjoint() does not work
  VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());

  if (rows > 1)
  {
    // Test matrix with NaN
    symmC(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
    SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmC);
    VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
  }
}