예제 #1
0
void test_eigen2_eigensolver()
{
  for(int i = 0; i < g_repeat; i++) {
    // very important to test a 3x3 matrix since we provide a special path for it
    CALL_SUBTEST_1( selfadjointeigensolver(Matrix3f()) );
    CALL_SUBTEST_2( selfadjointeigensolver(Matrix4d()) );
    CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(7,7)) );
    CALL_SUBTEST_4( selfadjointeigensolver(MatrixXcd(5,5)) );
    CALL_SUBTEST_5( selfadjointeigensolver(MatrixXd(19,19)) );

    CALL_SUBTEST_6( eigensolver(Matrix4f()) );
    CALL_SUBTEST_5( eigensolver(MatrixXd(17,17)) );
  }
}
inline void solvePlaneParametersEigen(const Eigen::Matrix3f &covariance_matrix,
                                      float &nx, float &ny, float &nz,
                                      float &lam0, float &lam1, float &lam2)
{
    Eigen::Matrix3f eigen_vectors;
    Eigen::Vector3f eigen_values;

    Eigen::SelfAdjointEigenSolver
        <Eigen::Matrix3f> eigensolver(covariance_matrix);

    if (eigensolver.info() != Eigen::Success) {
        nx = ny = nz = lam0 = lam1 = lam2 = std::numeric_limits
            <float>::quiet_NaN();
        return;
    }

    eigen_vectors = eigensolver.eigenvectors();
    eigen_values = eigensolver.eigenvalues();

    // first column, no?
    nx = eigen_vectors(0, 0);
    ny = eigen_vectors(1, 0);
    nz = eigen_vectors(2, 0);

    lam0 = eigen_values(0);
    lam1 = eigen_values(1);
    lam2 = eigen_values(2);
}
  qreal ellipticityOfASymmetricThreeByThreeMatrix(const Matrix<qreal,3,3> &A)
  {
    SelfAdjointEigenSolver<Matrix<qreal, 3, 3> > eigensolver(A);
    Matrix<qreal, 3, 1> eigenvalues=eigensolver.eigenvalues();

    return (eigenvalues(0) / eigenvalues(1)) - 1.0 ;
  }
예제 #4
0
void print_dir(FILE *fp,real *Uaver)
{
    real eigvec[DIM*DIM];
    real tmp[DIM*DIM];  
    rvec eigval;
    int d,m;

    fprintf(fp,"MSF     X         Y         Z\n");
    for(d=0; d<DIM; d++)
    {
        fprintf(fp," %c ",'X'+d-XX);
        for(m=0; m<DIM; m++)
            fprintf(fp," %9.2e",Uaver[3*m+d]);
        fprintf(fp,"%s\n",m==DIM ? " (nm^2)" : "");
    }
  
    for(m=0; m<DIM*DIM; m++)
        tmp[m] = Uaver[m];

  
    eigensolver(tmp,DIM,0,DIM,eigval,eigvec);
    
    fprintf(fp,"\n             Eigenvectors\n\n");
    fprintf(fp,"Eigv  %-8.2e %-8.2e %-8.2e (nm^2)\n\n",
            eigval[2],eigval[1],eigval[0]);
    for(d=0; d<DIM; d++)
    {
        fprintf(fp,"  %c   ",'X'+d-XX);
        for(m=DIM-1; m>=0; m--)
            fprintf(fp,"%7.4f  ",eigvec[3*m+d]);
        fprintf(fp,"\n");
    }
}
예제 #5
0
void CCovarianceFunctionCacheOld::updateSVD()
{
	Eigen::SelfAdjointEigenSolver<MatrixXd> eigensolver(rgetK());
	UCache = eigensolver.eigenvectors();
	SCache = eigensolver.eigenvalues();
	SVDCacheNull=false;
}
예제 #6
0
int main(int argc, char *argv[])
{
 	PetscErrorCode ierr;
	params params;

	Mat H; 

	SlepcInitialize(&argc,&argv,(char*)0,help);

	ierr = PetscPrintf(PETSC_COMM_WORLD,"--------------------------------------------------------------------------------------\n");CHKERRQ(ierr);
	ierr = PetscPrintf(PETSC_COMM_WORLD,"               _______ __  __  _______          _______ ______ _______                \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"              |__   __|  \\/  |/ ____\\ \\        / /_   _|  ____|__   __|               \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"                 | |  | \\  / | (___  \\ \\  /\\  / /  | | | |__     | |                  \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"                 | |  | |\\/| |\\___ \\  \\ \\/  \\/ /   | | |  __|    | |                  \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"                 | |  | |  | |____) |  \\  /\\  /   _| |_| |       | |                  \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"                 |_|  |_|  |_|_____/    \\/  \\/   |_____|_|       |_|                  \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"               True Muonium Solver with Iterative Front-Form Techniques               \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"                                                                                      \n");CHKERRQ(ierr);
        ierr = PetscPrintf(PETSC_COMM_WORLD,"--------------------------------------------------------------------------------------\n");CHKERRQ(ierr);


	read_input(ierr,argv,&params);
	print_input(ierr,&params);
	
	if(check_file(params.hfile))
	{
		PetscViewer    viewer_H;
		PetscViewerBinaryOpen(PETSC_COMM_WORLD,params.hfile.c_str(),FILE_MODE_READ,&viewer_H);
		MatCreate(PETSC_COMM_WORLD,&H);
		MatSetFromOptions(H);
		MatLoad(H,viewer_H);
		PetscViewerDestroy(&viewer_H);		

	}else
	{
        	discretize(ierr,&params);
//  	    	ierr = VecView(params.mu,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//        	ierr = VecView(params.theta,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);

		write_output(ierr,&params);	

        	coulomb_trick(ierr,&params);	
//		ierr = VecView(params.CT,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);

		ct_discrete(ierr,&params);
//		ierr = VecView(params.CT,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);

		hamiltonian(ierr,&params,H);
// 		ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_DENSE);//DENSE<-->COMMON
//	      	MatView(H,PETSC_VIEWER_STDOUT_WORLD);
	}

	cleanup(ierr,&params);	
	eigensolver(ierr,&params,H,argc,argv);

	ierr = MatDestroy(&H);CHKERRQ(ierr);

	ierr = SlepcFinalize();
	return 0;
}
예제 #7
0
static void
nma_full_hessian(real     *           hess,
                 int                  ndim,
                 gmx_bool             bM,
                 t_topology     *     top,
                 int                  begin,
                 int                  end,
                 real     *           eigenvalues,
                 real     *           eigenvectors)
{
    int  i, j, k, l;
    real mass_fac, rdum;
    int  natoms;

    natoms = top->atoms.nr;

    /* divide elements hess[i][j] by sqrt(mas[i])*sqrt(mas[j]) when required */

    if (bM)
    {
        for (i = 0; (i < natoms); i++)
        {
            for (j = 0; (j < DIM); j++)
            {
                for (k = 0; (k < natoms); k++)
                {
                    mass_fac = gmx_invsqrt(top->atoms.atom[i].m*top->atoms.atom[k].m);
                    for (l = 0; (l < DIM); l++)
                    {
                        hess[(i*DIM+j)*ndim+k*DIM+l] *= mass_fac;
                    }
                }
            }
        }
    }

    /* call diagonalization routine. */

    fprintf(stderr, "\nDiagonalizing to find vectors %d through %d...\n", begin, end);
    fflush(stderr);

    eigensolver(hess, ndim, begin-1, end-1, eigenvalues, eigenvectors);

    /* And scale the output eigenvectors */
    if (bM && eigenvectors != NULL)
    {
        for (i = 0; i < (end-begin+1); i++)
        {
            for (j = 0; j < natoms; j++)
            {
                mass_fac = gmx_invsqrt(top->atoms.atom[j].m);
                for (k = 0; (k < DIM); k++)
                {
                    eigenvectors[i*ndim+j*DIM+k] *= mass_fac;
                }
            }
        }
    }
}
예제 #8
0
void mesh_core::Plane::leastSquaresGeneral(
      const EigenSTL::vector_Vector3d& points,
      Eigen::Vector3d* average)
{
  if (points.empty())
  {
    normal_ = Eigen::Vector3d(0,0,1);
    d_ = 0;
    if (average)
      *average = Eigen::Vector3d::Zero();
    return;
  }

  // find c, the average of the points
  Eigen::Vector3d c;
  c.setZero();

  EigenSTL::vector_Vector3d::const_iterator p = points.begin();
  EigenSTL::vector_Vector3d::const_iterator end = points.end();
  for ( ; p != end ; ++p)
    c += *p;

  c *= 1.0/double(points.size());

  // Find the matrix
  Eigen::Matrix3d m;
  m.setZero();

  p = points.begin();
  for ( ; p != end ; ++p)
  {
    Eigen::Vector3d cp = *p - c;
    m(0,0) += cp.x() * cp.x();
    m(1,0) += cp.x() * cp.y();
    m(2,0) += cp.x() * cp.z();
    m(1,1) += cp.y() * cp.y();
    m(2,1) += cp.y() * cp.z();
    m(2,2) += cp.z() * cp.z();
  }
  m(0,1) = m(1,0);
  m(0,2) = m(2,0);
  m(1,2) = m(2,1);

  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(m);
  if (eigensolver.info() == Eigen::Success)
  {
    normal_ = eigensolver.eigenvectors().col(0);
    normal_.normalize();
  }
  else
  {
    normal_ = Eigen::Vector3d(0,0,1);
  }

  d_ = -c.dot(normal_);

  if (average)
    *average = c;
}
예제 #9
0
static void
nma_full_hessian(real                      *hess,
                 int                        ndim,
                 gmx_bool                   bM,
                 const t_topology          *top,
                 const std::vector<size_t> &atom_index,
                 int                        begin,
                 int                        end,
                 real                      *eigenvalues,
                 real                      *eigenvectors)
{
    real mass_fac;

    /* divide elements hess[i][j] by sqrt(mas[i])*sqrt(mas[j]) when required */

    if (bM)
    {
        for (size_t i = 0; (i < atom_index.size()); i++)
        {
            size_t ai = atom_index[i];
            for (size_t j = 0; (j < DIM); j++)
            {
                for (size_t k = 0; (k < atom_index.size()); k++)
                {
                    size_t ak = atom_index[k];
                    mass_fac = gmx::invsqrt(top->atoms.atom[ai].m*top->atoms.atom[ak].m);
                    for (size_t l = 0; (l < DIM); l++)
                    {
                        hess[(i*DIM+j)*ndim+k*DIM+l] *= mass_fac;
                    }
                }
            }
        }
    }

    /* call diagonalization routine. */

    fprintf(stderr, "\nDiagonalizing to find vectors %d through %d...\n", begin, end);
    fflush(stderr);

    eigensolver(hess, ndim, begin-1, end-1, eigenvalues, eigenvectors);

    /* And scale the output eigenvectors */
    if (bM && eigenvectors != NULL)
    {
        for (int i = 0; i < (end-begin+1); i++)
        {
            for (size_t j = 0; j < atom_index.size(); j++)
            {
                size_t aj = atom_index[j];
                mass_fac = gmx::invsqrt(top->atoms.atom[aj].m);
                for (size_t k = 0; (k < DIM); k++)
                {
                    eigenvectors[i*ndim+j*DIM+k] *= mass_fac;
                }
            }
        }
    }
}
VectorXd MultivariateFNormalSufficient::get_Sigma_eigenvalues() const
{
    Eigen::SelfAdjointEigenSolver<MatrixXd> eigensolver(get_Sigma(),
            Eigen::EigenvaluesOnly);
    if (eigensolver.info() != Eigen::Success)
            IMP_THROW("Could not determine eigenvalues!", ModelException);
    return eigensolver.eigenvalues();
}
VectorXd MultivariateFNormalSufficient::get_Sigma_eigenvalues() const
{
    Eigen::SelfAdjointEigenSolver<MatrixXd> eigensolver(get_Sigma(),
            Eigen::EigenvaluesOnly);
    CHECK(eigensolver.info() == Eigen::Success,
            "Could not determine eigenvalues!");
    return eigensolver.eigenvalues();
}
  qint64 signatureOfASymmetricThreeByThreeMatrix(const Matrix<qreal,3,3> &A)
  {
    SelfAdjointEigenSolver<Matrix<qreal, 3, 3> > eigensolver(A);
    Matrix<qreal,3,1> eigenvalues=eigensolver.eigenvalues();

    return signOfARealNumber(eigenvalues(0)) +
        signOfARealNumber(eigenvalues(1)) +
        signOfARealNumber(eigenvalues(2));
  }
void test_boostmultiprec()
{
  typedef Matrix<Real,Dynamic,Dynamic> Mat;
  typedef Matrix<std::complex<Real>,Dynamic,Dynamic> MatC;

  std::cout << "NumTraits<Real>::epsilon()         = " << NumTraits<Real>::epsilon() << std::endl;
  std::cout << "NumTraits<Real>::dummy_precision() = " << NumTraits<Real>::dummy_precision() << std::endl;
  std::cout << "NumTraits<Real>::lowest()          = " << NumTraits<Real>::lowest() << std::endl;
  std::cout << "NumTraits<Real>::highest()         = " << NumTraits<Real>::highest() << std::endl;
  std::cout << "NumTraits<Real>::digits10()        = " << NumTraits<Real>::digits10() << std::endl;

  // chekc stream output
  {
    Mat A(10,10);
    A.setRandom();
    std::stringstream ss;
    ss << A;
  }
  {
    MatC A(10,10);
    A.setRandom();
    std::stringstream ss;
    ss << A;
  }

  for(int i = 0; i < g_repeat; i++) {
    int s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);

    CALL_SUBTEST_1( cholesky(Mat(s,s)) );

    CALL_SUBTEST_2( lu_non_invertible<Mat>() );
    CALL_SUBTEST_2( lu_invertible<Mat>() );
    CALL_SUBTEST_2( lu_non_invertible<MatC>() );
    CALL_SUBTEST_2( lu_invertible<MatC>() );

    CALL_SUBTEST_3( qr(Mat(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_3( qr_invertible<Mat>() );

    CALL_SUBTEST_4( qr<Mat>() );
    CALL_SUBTEST_4( cod<Mat>() );
    CALL_SUBTEST_4( qr_invertible<Mat>() );

    CALL_SUBTEST_5( qr<Mat>() );
    CALL_SUBTEST_5( qr_invertible<Mat>() );

    CALL_SUBTEST_6( selfadjointeigensolver(Mat(s,s)) );

    CALL_SUBTEST_7( eigensolver(Mat(s,s)) );

    CALL_SUBTEST_8( generalized_eigensolver_real(Mat(s,s)) );

    TEST_SET_BUT_UNUSED_VARIABLE(s)
  }

  CALL_SUBTEST_9(( jacobisvd(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
  CALL_SUBTEST_10(( bdcsvd(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
}
void taskwrenchEllipsoid::computeTorqueEllipsoid()
{

    //Computing pca on the pointset and scale such that it encloses!
    Eigen::Vector3d mean=sampledPointsEllipse_.rowwise().mean();
    MatSampledPts aligned = sampledPointsEllipse_.colwise() - mean;
    Eigen::Matrix3d covMat=aligned*aligned.transpose(); //maybe already enough??
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(covMat);
    Eigen::Vector3d eigenValues=eigensolver.eigenvalues();
    Eigen::Matrix3d eigenVectors=eigensolver.eigenvectors();

    //Now compute scaling of Eigenvectors such to have a circumscribed ellipsoid. transforming
    //Points into the PCA::Frame and get Max in each direction!

    pcaMat_=eigenVectors;
    pcaEv_=eigenValues;

#if DEBUGQM
    std::cout << "[Debug]:" << std::endl;
    std::cout << "mean: " << mean.transpose() << std::endl;
    std::cout << "eigenVectors: " << eigenVectors << std::endl;
    std::cout << "eigenValues: " << eigenValues.transpose() << std::endl;



    //Transform Pointset to EigenFrame
    //getting the max in the eigenvectorFrame

    //check if right handed rotation matrix!
    std::cout << "Determinant" << std::endl;
    std::cout << pcaMat_.determinant() << std::endl;
#endif

    MatSampledPts transf=pcaMat_.inverse()*aligned; //why inverse seems to work?? debug that more!!
    Eigen::Vector3d max3D=transf.rowwise().maxCoeff();
    //get Enclosed Ellipse by scaling Eigenvectors with maxCoeff
    double delta=0.00001;
    Eigen::Matrix3d scalMat=Eigen::Vector3d(pow(max3D(0)+delta,-2),pow(max3D(1)+delta,-2),pow(max3D(2)+delta,-2)).asDiagonal();
    Eigen::Vector3d maxScale=scalMat*eigenValues;//eigenvalues in new frame, why does the ordering change?!
    double scale=maxScale.maxCoeff();

#if DEBUGQM
    std::cout << "max3D" << max3D << std::endl;
    std::cout << "maxScale" << maxScale<<std::endl;
    std::cout << "scale" << scale<<std::endl;

#endif
    pcaEv_ << pow((eigenValues(0)+0)/scale,0.5), pow(eigenValues(1)/scale,0.5),pow(eigenValues(2)/scale,0.5); //Now scaled to halfaxes!

    pca_to_ellipse_.rotation=pcaMat_;
    pca_to_ellipse_.translation<<0,0,0;


}
예제 #15
0
void test_eigensolver_complex()
{
  int s = 0;
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( eigensolver(Matrix4cf()) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_2( eigensolver(MatrixXcd(s,s)) );
    CALL_SUBTEST_3( eigensolver(Matrix<std::complex<float>, 1, 1>()) );
    CALL_SUBTEST_4( eigensolver(Matrix3f()) );
  }
  CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4cf()) );
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
  CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXcd(s,s)) );
  CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<std::complex<float>, 1, 1>()) );
  CALL_SUBTEST_4( eigensolver_verify_assert(Matrix3f()) );

  // Test problem size constructors
  CALL_SUBTEST_5(ComplexEigenSolver<MatrixXf> tmp(s));
  
  TEST_SET_BUT_UNUSED_VARIABLE(s)
}
예제 #16
0
DescType DescriptorMakerCpu::GetDescriptorByEigenDecomp(float Avec[NUM_VAR])
{
    float egval[PT_DIM];
    float egvec[PT_DIM*PT_DIM];

    // convert solution to 3x3 matrix
    float Amat[PT_DIM][PT_DIM];
    Amat[0][0] = Avec[0];
    Amat[1][1] = Avec[1];
    Amat[2][2] = Avec[2];
    Amat[0][1] = Amat[1][0] = Avec[3];
    Amat[1][2] = Amat[2][1] = Avec[4];
    Amat[0][2] = Amat[2][0] = Avec[5];

    // eigen decomposition using Eigen3
    Eigen::Matrix3f Emat;
    for(int i=0; i<PT_DIM; i++)
        for(int k=0; k<PT_DIM; k++)
            Emat(i,k) = Amat[i][k];

    Eigen::EigenSolver<Eigen::Matrix3f> eigensolver(Emat);
    Eigen::Vector3f Eval = eigensolver.eigenvalues().real();
    Eigen::Matrix3f Evec = eigensolver.eigenvectors().real();

    for(int i=0; i<PT_DIM; i++)
    {
        egval[i] = Eval(i);
        for(int k=0; k<PT_DIM; k++)
            egvec[i*PT_DIM+k] = Evec(i,k);
    }

    // sort eigenvalues and eigenvectors w.r.t eigenvalues
    int first=0, second=1;
    // swap first largest eigenvalue with eigenvalue[0]
    if(fabsf(egval[0]) <= fabsf(egval[2]) && fabsf(egval[1]) <= fabsf(egval[2]))
        first = 2;
    else if(fabsf(egval[0]) <= fabsf(egval[1]) && fabsf(egval[2]) <= fabsf(egval[1]))
        first = 1;
    SwapEigen(egval, egvec, first, 0);

    // swap second largest eigenvalue with eigenvalue[1]
    if(fabsf(egval[1]) < fabsf(egval[2]))
    {
        second = 2;
        SwapEigen(egval, egvec, second, 1);
    }

    // rescale descriptor and reverse sign of descriptor
    DescType descriptor;
    for(int i=0; i<PT_DIM; i++)
        descriptor.s[i] = -egval[i]*EQUATION_SCALE;
    return descriptor;
}
예제 #17
0
void test_eigensolver_generic()
{
  int s = 0;
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( eigensolver(Matrix4f()) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_2( eigensolver(MatrixXd(s,s)) );

    // some trivial but implementation-wise tricky cases
    CALL_SUBTEST_2( eigensolver(MatrixXd(1,1)) );
    CALL_SUBTEST_2( eigensolver(MatrixXd(2,2)) );
    CALL_SUBTEST_3( eigensolver(Matrix<double,1,1>()) );
    CALL_SUBTEST_4( eigensolver(Matrix2d()) );
  }

  CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4f()) );
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
  CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXd(s,s)) );
  CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<double,1,1>()) );
  CALL_SUBTEST_4( eigensolver_verify_assert(Matrix2d()) );

  // Test problem size constructors
  CALL_SUBTEST_5(EigenSolver<MatrixXf> tmp(s));

  // regression test for bug 410
  CALL_SUBTEST_2(
  {
     MatrixXd A(1,1);
     A(0,0) = std::sqrt(-1.);
     Eigen::EigenSolver<MatrixXd> solver(A);
     MatrixXd V(1, 1);
     V(0,0) = solver.eigenvectors()(0,0).real();
  }
  );
예제 #18
0
void test_eigensolver_generic()
{
  int s = 0;
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( eigensolver(Matrix4f()) );
    s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
    CALL_SUBTEST_2( eigensolver(MatrixXd(s,s)) );
    TEST_SET_BUT_UNUSED_VARIABLE(s)

    // some trivial but implementation-wise tricky cases
    CALL_SUBTEST_2( eigensolver(MatrixXd(1,1)) );
    CALL_SUBTEST_2( eigensolver(MatrixXd(2,2)) );
    CALL_SUBTEST_3( eigensolver(Matrix<double,1,1>()) );
    CALL_SUBTEST_4( eigensolver(Matrix2d()) );
  }

  CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4f()) );
  s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
  CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXd(s,s)) );
  CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<double,1,1>()) );
  CALL_SUBTEST_4( eigensolver_verify_assert(Matrix2d()) );

  // Test problem size constructors
  CALL_SUBTEST_5(EigenSolver<MatrixXf> tmp(s));

  // regression test for bug 410
  CALL_SUBTEST_2(
  {
     MatrixXd A(1,1);
     A(0,0) = std::sqrt(-1.); // is Not-a-Number
     Eigen::EigenSolver<MatrixXd> solver(A);
     VERIFY_IS_EQUAL(solver.info(), NumericalIssue);
  }
  );
VectorXf project1D( const RMatrixXf & Y, int * rep_label=NULL ) {
// 	const int MAX_SAMPLE = 20000;
	const bool fast = true, very_fast = true;
	// Remove the DC (Y : N x M)
	RMatrixXf dY = Y.rowwise() - Y.colwise().mean();
// 	RMatrixXf sY = dY;
// 	if( 0 < MAX_SAMPLE && MAX_SAMPLE < dY.rows() ) {
// 		VectorXi samples = randomChoose( dY.rows(), MAX_SAMPLE );
// 		std::sort( samples.data(), samples.data()+samples.size() );
// 		sY = RMatrixXf( samples.size(), dY.cols() );
// 		for( int i=0; i<samples.size(); i++ )
// 			sY.row(i) = dY.row( samples[i] );
// 	}
	
	// ... and use (pc > 0)
	VectorXf lbl = VectorXf::Zero( Y.rows() );
	
	// Find the largest PC of (dY.T * dY) and project onto it
	if( very_fast ) {
		// Find the largest PC using poweriterations
		VectorXf U = VectorXf::Random( dY.cols() );
		U = U.array() / U.norm()+std::numeric_limits<float>::min();
		for( int it=0; it<20; it++ ){
			// Normalize
			VectorXf s = dY.transpose()*(dY*U);
			s.array() /= s.norm()+std::numeric_limits<float>::min();
			if ( (U-s).norm() < 1e-6 )
				break;
			U = s;
		}
		// Project onto the PC
		lbl = dY*U;
	}
	else if(fast) {
		// Compute the eigen values of the covariance (and project onto the largest eigenvector)
		MatrixXf cov = dY.transpose()*dY;
		SelfAdjointEigenSolver<MatrixXf> eigensolver(0.5*(cov+cov.transpose()));
		MatrixXf ev = eigensolver.eigenvectors();
		lbl = dY * ev.col( ev.cols()-1 );
	}
	else {
		// Use the SVD
		JacobiSVD<RMatrixXf> svd = dY.jacobiSvd(ComputeThinU | ComputeThinV );
		// Project onto the largest PC
		lbl = svd.matrixU().col(0) * svd.singularValues()[0];
	}
	// Find the representative label
	if( rep_label )
		dY.array().square().rowwise().sum().minCoeff( rep_label );
	
	return (lbl.array() < 0).cast<float>();
}
예제 #20
0
void gcta::bend_A()
{
    cout<<"Bending the GRM(s) to be positive-definite (may take a long time if there are multiple GRMs)..."<<endl;
    int i=0;
    for(i=0; i<_r_indx.size(); i++){
        SelfAdjointEigenSolver<eigenMatrix> eigensolver(_A.block(0,_r_indx[i]*_n,_n,_n));
        eigenVector eval=eigensolver.eigenvalues();
        if(bending_eigenval(eval)){
            _A.block(0,_r_indx[i]*_n,_n,_n)=eigensolver.eigenvectors()*eigenDiagMat(eval)*eigensolver.eigenvectors().transpose();
            cout<<"Bending the "<<i+1<<"th GRM completed."<<endl;
        }
    }
}
예제 #21
0
void Deform_With_Seg::ReNormal(vector<Sample> &sample_list)
{
	vector<NamedPoint> points;
	for (size_t i = 0; i < sample_list.size(); i++)
	{
		points.push_back(NamedPoint(sample_list[i].position[0], sample_list[i].position[1], sample_list[i].position[2], i));
	}
	PKDTree stree(points.begin(), points.end());
	for (size_t i = 0; i < sample_list.size(); i++)
	{
		NamedPoint query(sample_list[i].position[0], sample_list[i].position[1], sample_list[i].position[2]);
		BoundedSortedArray<PKDTree::Neighbor> k_closest_elems(30);
		Eigen::Matrix3d local_covariance_matrix = Eigen::Matrix3d::Constant(3, 3, 0);
		Eigen::Vector3d centroid(0, 0, 0);
		stree.kClosestElements<MetricL2>(query, k_closest_elems, -1);  //-1 means there's no limit on the maximum allowed
		for (int kn = 0; kn < k_closest_elems.size(); kn++)
		{
			if (stree.getElements()[k_closest_elems[kn].getIndex()].id != i)
			{
				NamedPoint kpoint = stree.getElements()[k_closest_elems[kn].getIndex()];
				Eigen::Vector3d v(kpoint.position.x, kpoint.position.y, kpoint.position.z);
				centroid += v;
			}
		}
		centroid /= (float)k_closest_elems.size();

		for (int kn = 0; kn < k_closest_elems.size(); kn++)
		{
			if (stree.getElements()[k_closest_elems[kn].getIndex()].id != i)
			{
				NamedPoint kpoint = stree.getElements()[k_closest_elems[kn].getIndex()];
				Eigen::Vector3d v(kpoint.position.x, kpoint.position.y, kpoint.position.z);
				v = v - centroid;
				local_covariance_matrix += v * v.transpose();
			}
		}

		local_covariance_matrix /= (float)k_closest_elems.size();
		Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d>eigensolver(local_covariance_matrix);
		Eigen::Vector3d n = eigensolver.eigenvectors().col(0);
		vec3 normal(n(0), n(1), n(2));
		if ((sample_list[i].normal DOT normal) > 0)
		{
			sample_list[i].normal = normal;
		}
		else
		{
			sample_list[i].normal = -normal;
		}
	}
}
예제 #22
0
double DistributionGaussian::maxEigenValue(void) const
{
  if (max_eigen_value_<0.0)
  {
    SelfAdjointEigenSolver<MatrixXd> eigensolver(covar_);
    if (eigensolver.info() == Success)
    {
      // Get the eigenvalues
      VectorXd eigen_values = eigensolver.eigenvalues();
      max_eigen_value_ = eigen_values.maxCoeff();
    }
  }
  return max_eigen_value_;
}
예제 #23
0
파일: sascalc.cpp 프로젝트: dww100/sasmol
///
/// @par Detailed description 
/// ... 
/// @param [in, out] (param1) ...
/// @return ...
/// @note ...
void
sascalc::Prop::
calc_pmi(int &frame)
{
    std::vector<float> com = calc_com(frame) ;

    _x().col(frame) -= com[0] ;
    _y().col(frame) -= com[1] ;
    _z().col(frame) -= com[2] ;

    float Ixx = (_atom_mass()*(_y().col(frame)*_y().col(frame) + _z().col(frame)*_z().col(frame))).sum() ;
    float Iyy = (_atom_mass()*(_x().col(frame)*_x().col(frame) + _z().col(frame)*_z().col(frame))).sum() ;
    float Izz = (_atom_mass()*(_x().col(frame)*_x().col(frame) + _y().col(frame)*_y().col(frame))).sum() ;

    float Ixy = (-_atom_mass()*(_x().col(frame)*_y().col(frame))).sum() ;
    float Ixz = (-_atom_mass()*(_x().col(frame)*_z().col(frame))).sum() ;
    float Iyz = (-_atom_mass()*(_y().col(frame)*_z().col(frame))).sum() ;
    float Iyx = (-_atom_mass()*(_y().col(frame)*_x().col(frame))).sum() ;
    float Izx = (-_atom_mass()*(_z().col(frame)*_x().col(frame))).sum() ;
    float Izy = (-_atom_mass()*(_z().col(frame)*_y().col(frame))).sum() ;
    
    Eigen::Matrix3f I ;

    I << Ixx, Ixy, Ixz,
         Iyx, Iyy, Iyz,
         Izx, Izy, Izz;

    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigensolver(I);

    if (eigensolver.info() != Eigen::Success) 
    {
        std::cout << "PMI calculation failed" << std::endl ;
        return ;
    }

    _uk() = eigensolver.eigenvalues() ; // .col(0) ;
    _ak() = eigensolver.eigenvectors() ;

//    std::cout << "The eigenvalues of I are:\n" << eigensolver.eigenvalues() << std::endl;
//    std::cout << "Here's a matrix whose columns are eigenvectors of I \n"
//    << "corresponding to these eigenvalues:\n"
//    << eigensolver.eigenvectors() << std::endl;

    _x().col(frame) += com[0] ;
    _y().col(frame) += com[1] ;
    _z().col(frame) += com[2] ;

    return ;
}
예제 #24
0
bool qbd_compute_pi0(const MatrixXd & R,
		     const MatrixXd & B0,
		     const MatrixXd & A0,
		     RowVectorXd & pi0,
		     const qbd_parms & parms) throw (Exc) {
  if(R.rows()!=R.cols())
    EXC_PRINT("R had to be square");

  if (!check_sizes(A0,R) || !check_sizes(A0,B0)) 
    EXC_PRINT("A0, A1, A2 matrixes have to be square and equal size");

  if ((R.minCoeff()<0)&&parms.verbose)
    cerr<<"QBD_COMPUTE_PI0: Warning: R has negative coeeficients"<<endl;
  SelfAdjointEigenSolver<MatrixXd> eigensolver(R);
  if (eigensolver.info() != Success) {
    if (parms.verbose)
      cerr<<"QBD_COMPUTE_PI0: cannot compute eigenvalues of R"<<endl;
    return false;
  }
  if ((ArrayXd(eigensolver.eigenvalues()).abs().maxCoeff()>1)&&parms.verbose)
    cerr<<"QBD_COMPUTE_PI0: Warning: R has spectral radius greater than 1"<<endl;
  int n = R.rows();
  MatrixXd Id = MatrixXd::Identity(n,n);
  VectorXd u(n);
  u.setOnes();
  MatrixXd M(n,n+1);
  M.block(0,0,n,n)= B0+R*A0-Id;
  M.block(0,n,n,1)= (Id-R).inverse()*u;

  FullPivLU<MatrixXd> lu_decomp(M);
  if(lu_decomp.rank()<n) {
    if (parms.verbose)
      cerr<<"QBD_COMPUTE_PI0: No unique solution"<<endl;
    return false;
  }

  RowVectorXd work(n+1);
  work.setZero();
  work(n)=1;
  MatrixXd W1;
  pseudoInverse<MatrixXd>(M,W1);
  pi0 = work*W1;
  if ((pi0.minCoeff()<0)&&parms.verbose)
    cerr<<"QBD_COMPUTE_PI0: Warning: x0 has negative elements"<<endl;
  return true;
}
예제 #25
0
bool KinematicsMetrics::getManipulabilityEllipsoid(const robot_state::RobotState &state,
                                                   const robot_model::JointModelGroup *joint_model_group,
                                                   Eigen::MatrixXcd &eigen_values,
                                                   Eigen::MatrixXcd &eigen_vectors) const
{
  // state.getJacobian() only works for chain groups.
  if(!joint_model_group->isChain())
  {
    return false;
  }

  Eigen::MatrixXd jacobian = state.getJacobian(joint_model_group);
  Eigen::MatrixXd matrix = jacobian*jacobian.transpose();
  Eigen::EigenSolver<Eigen::MatrixXd> eigensolver(matrix.block(0, 0, 3, 3));
  eigen_values = eigensolver.eigenvalues();
  eigen_vectors = eigensolver.eigenvectors();
  return true;
}
예제 #26
0
		bool eigen_values(const UpscaledTensor& t, vector<double>& evals, vector<vector<double>>& evecs)
		{
			typedef Eigen::Matrix<double, 3, 3> Matrix3d;
			Matrix3d eigenKeff;
			eigenKeff << t(0, 0), t(0, 1), t(0, 2), t(1, 0), t(1, 1), t(1, 2), t(2, 0), t(2, 1), t(2, 2);
			Eigen::SelfAdjointEigenSolver<Matrix3d> eigensolver(eigenKeff);
			if (eigensolver.info() != Eigen::Success)
				return false;
			//cout << "The eigenvalues of eigenKeff are:\n" << eigensolver.eigenvalues() << endl;
			auto evals_em = eigensolver.eigenvalues();
			auto evecs_em = eigensolver.eigenvectors();
			evals = vector<double>(3, 0.);
			for (size_t i(0); i < 3; ++i)
				evals[i] = evals_em(i,0);
			evecs = vector<vector<double>>(3, vector<double>(3, 0.));
			for (size_t i(0); i < 3; ++i)
				for (size_t j(0); j < 3; ++j)
					evecs[i][j] = evecs_em(j, i);
			return true;
		}
예제 #27
0
파일: PCA.cpp 프로젝트: caomw/3D-Feat-Desc
// Public Methods
void // computes the normal to a set of points thanks to PCA method
PCA::compute()
{
	computeCentre();
	
	Eigen::Matrix3d covar;
	computeCovar( covar );
	
	// Compute Eigenvectors & Eigenvalues
	Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(covar);

	// Order the vectors by eigenvalues
	int order [3] = {0,1,2};
	int temp = 0;
	for(size_t i = 0; i < 3; i++)
	{
		for (size_t j = i; j < 3; j++)
		{
			if( (eigensolver.eigenvalues())(i) > (eigensolver.eigenvalues())(j) )
			{
				temp = order [j];
				order [j] = order [i];
				order [i] = temp;
			}
		}
	}
	normal = ( eigensolver.eigenvectors() ).col( order[0] );
	
	vec_base1 = ( eigensolver.eigenvectors() ).col( order[1] ) ;
	
	signCheck();
		
	vec_base2 = normal.cross( vec_base1 );
	
	if (normal.norm()!=normal.norm()){
		std::cerr << "Error PCA::compute NaN Normal: " << std::endl; 
		std::cerr << normal << std::endl; 
	}
	if (normal.norm() == 0)
		std::cerr << "Error PCA::compute Null Normal" << std::endl; 
}
예제 #28
0
void
getHeadMeasurementData( const PointSet &aPoints, HeadMeasurementData &aHeadMeasurementData )
{
	ASSERT( aPoints.size() >= 3 );

	Vector3f center;
	Eigen::Matrix3f covarianceMatrix;

	computeCovarianceMatrixFromPointSet( aPoints, center, covarianceMatrix );

	typedef Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> Solver;
	Solver eigensolver(covarianceMatrix);

	Solver::RealVectorType eigenVals = eigensolver.eigenvalues();
	Eigen::Matrix3f eigenVectors = eigensolver.eigenvectors();
	D_PRINT( "Eigen values :\n" << eigenVals );
	D_PRINT( "Eigen vectors :\n" << eigenVectors );


	Vector3f v1( eigenVectors(0,2), eigenVectors(1,2), eigenVectors(2,2) );
	Vector3f v2( eigenVectors(0,1), eigenVectors(1,1), eigenVectors(2,1) );
	
/*	Vector3f v1 = mHumeralHeadPoints[0] - center;
	Vector3f v2 = mHumeralHeadPoints[1] - center;
	VectorNormalization( v1 );
	VectorNormalization( v2 );*/
	Vector3f normal = VectorProduct( v1, v2 );
	VectorNormalization( normal );
	/*v2 = VectorProduct( v1, normal );
	VectorNormalization( v2 );*/

	aHeadMeasurementData.point = center;
	aHeadMeasurementData.normal = normal;
	aHeadMeasurementData.vDirection = v1;
	aHeadMeasurementData.wDirection = v2;
	aHeadMeasurementData.available = true;
}
예제 #29
0
파일: sasmath.cpp 프로젝트: dww100/sasmol
///
/// @par Detailed description 
/// ... 
/// @param [in, out] (param1) ...
/// @return ...
/// @note ...
Eigen::Matrix3f
sasmath::Math::
find_u(sasmol::SasMol &mol, int &frame)
{

    Eigen::Matrix3f r ;

    float rxx = (mol._x().col(frame)*_x().col(frame)).sum() ; 
    float rxy = (mol._x().col(frame)*_y().col(frame)).sum() ;
    float rxz = (mol._x().col(frame)*_z().col(frame)).sum() ;
    
    float ryx = (mol._y().col(frame)*_x().col(frame)).sum() ;
    float ryy = (mol._y().col(frame)*_y().col(frame)).sum() ;
    float ryz = (mol._y().col(frame)*_z().col(frame)).sum() ;

    float rzx = (mol._z().col(frame)*_x().col(frame)).sum() ;
    float rzy = (mol._z().col(frame)*_y().col(frame)).sum() ;
    float rzz = (mol._z().col(frame)*_z().col(frame)).sum() ;

    r << rxx,rxy,rxz,
         ryx,ryy,ryz,
         rzx,rzy,rzz;

    Eigen::Matrix3f rtr = r.transpose() * r ;
    
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigensolver(rtr);

    if (eigensolver.info() != Eigen::Success)
    {
          std::cout << "find_u calculation failed" << std::endl ;
    }

    Eigen::Matrix<float,3,1> uk ;  // eigenvalues
    Eigen::Matrix3f ak ;          // eigenvectors

    uk = eigensolver.eigenvalues() ; 
    ak = eigensolver.eigenvectors() ;

    Eigen::Matrix3f akt = ak.transpose() ;
    Eigen::Matrix3f new_ak  ;

    new_ak.row(0) = akt.row(2) ; //sort eigenvectors
    new_ak.row(1) = akt.row(1) ;
    new_ak.row(2) = akt.row(0) ;

    // python ak0 --> ak[2] ; ak1 --> ak[1] ; ak2 --> ak[0]

    //Eigen::Matrix<float,3,1> ak2 = akt.row(2).cross(akt.row(1)) ;

    Eigen::MatrixXf rak0 = (r * (akt.row(2).transpose())) ;
    Eigen::MatrixXf rak1 = (r * (akt.row(1).transpose())) ;

    Eigen::Matrix<float,3,1> urak0 ; 
    if(uk[2] == 0.0)
    { 
        urak0 = 1E15 * rak0 ;
    } 
    else
    {    
        urak0 = (1.0/sqrt(fabs(uk[2])))*rak0 ;
    }
    
    Eigen::Matrix<float,3,1> urak1 ; 
    if(uk[1] == 0.0)
    { 
        urak1 = 1E15 * rak1 ;
    } 
    else
    {    
        urak1 = (1.0/sqrt(fabs(uk[1])))*rak1 ;
    }

    Eigen::Matrix<float,3,1> urak2 = urak0.col(0).cross(urak1.col(0)) ;
    Eigen::Matrix3f bk ;

    bk << urak0,urak1,urak2;

    Eigen::Matrix3f u ;

    u =  (bk * new_ak).transpose() ;

    return u ;
/*
u = array([[-0.94513198,  0.31068658,  0.100992  ],
       [-0.3006246 , -0.70612572, -0.64110165],
       [-0.12786863, -0.63628635,  0.76078203]])
check:

u = 
-0.945133  0.310686  0.100992
-0.300624 -0.706126 -0.641102
-0.127869 -0.636287  0.760782 
*/
}
예제 #30
0
int gmx_covar(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_covar[tt] calculates and diagonalizes the (mass-weighted)",
    "covariance matrix.",
    "All structures are fitted to the structure in the structure file.",
    "When this is not a run input file periodicity will not be taken into",
    "account. When the fit and analysis groups are identical and the analysis",
    "is non mass-weighted, the fit will also be non mass-weighted.",
    "[PAR]",
    "The eigenvectors are written to a trajectory file ([TT]-v[tt]).",
    "When the same atoms are used for the fit and the covariance analysis,",
    "the reference structure for the fit is written first with t=-1.",
    "The average (or reference when [TT]-ref[tt] is used) structure is",
    "written with t=0, the eigenvectors",
    "are written as frames with the eigenvector number as timestamp.",
    "[PAR]",
    "The eigenvectors can be analyzed with [TT]g_anaeig[tt].",
    "[PAR]",
    "Option [TT]-ascii[tt] writes the whole covariance matrix to",
    "an ASCII file. The order of the elements is: x1x1, x1y1, x1z1, x1x2, ...",
    "[PAR]",
    "Option [TT]-xpm[tt] writes the whole covariance matrix to an [TT].xpm[tt] file.",
    "[PAR]",
    "Option [TT]-xpma[tt] writes the atomic covariance matrix to an [TT].xpm[tt] file,",
    "i.e. for each atom pair the sum of the xx, yy and zz covariances is",
    "written.",
    "[PAR]",
    "Note that the diagonalization of a matrix requires memory and time",
    "that will increase at least as fast as than the square of the number",
    "of atoms involved. It is easy to run out of memory, in which",
    "case this tool will probably exit with a 'Segmentation fault'. You",
    "should consider carefully whether a reduced set of atoms will meet",
    "your needs for lower costs."
  };
  static gmx_bool bFit=TRUE,bRef=FALSE,bM=FALSE,bPBC=TRUE;
  static int  end=-1;
  t_pargs pa[] = {
    { "-fit",  FALSE, etBOOL, {&bFit},
      "Fit to a reference structure"},
    { "-ref",  FALSE, etBOOL, {&bRef},
      "Use the deviation from the conformation in the structure file instead of from the average" },
    { "-mwa",  FALSE, etBOOL, {&bM},
      "Mass-weighted covariance analysis"},
    { "-last",  FALSE, etINT, {&end}, 
      "Last eigenvector to write away (-1 is till the last)" },
    { "-pbc",  FALSE,  etBOOL, {&bPBC},
      "Apply corrections for periodic boundary conditions" }
  };
  FILE       *out;
  t_trxstatus *status;
  t_trxstatus *trjout;
  t_topology top;
  int        ePBC;
  t_atoms    *atoms;  
  rvec       *x,*xread,*xref,*xav,*xproj;
  matrix     box,zerobox;
  real       *sqrtm,*mat,*eigval,sum,trace,inv_nframes;
  real       t,tstart,tend,**mat2;
  real       xj,*w_rls=NULL;
  real       min,max,*axis;
  int        ntopatoms,step;
  int        natoms,nat,count,nframes0,nframes,nlevels;
  gmx_large_int_t ndim,i,j,k,l;
  int        WriteXref;
  const char *fitfile,*trxfile,*ndxfile;
  const char *eigvalfile,*eigvecfile,*averfile,*logfile;
  const char *asciifile,*xpmfile,*xpmafile;
  char       str[STRLEN],*fitname,*ananame,*pcwd;
  int        d,dj,nfit;
  atom_id    *index,*ifit;
  gmx_bool       bDiffMass1,bDiffMass2;
  time_t     now;
  char       timebuf[STRLEN];
  t_rgb      rlo,rmi,rhi;
  real       *tmp;
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;

  t_filenm fnm[] = { 
    { efTRX, "-f",  NULL, ffREAD }, 
    { efTPS, NULL,  NULL, ffREAD },
    { efNDX, NULL,  NULL, ffOPTRD },
    { efXVG, NULL,  "eigenval", ffWRITE },
    { efTRN, "-v",  "eigenvec", ffWRITE },
    { efSTO, "-av", "average.pdb", ffWRITE },
    { efLOG, NULL,  "covar", ffWRITE },
    { efDAT, "-ascii","covar", ffOPTWR },
    { efXPM, "-xpm","covar", ffOPTWR },
    { efXPM, "-xpma","covara", ffOPTWR }
  }; 
#define NFILE asize(fnm) 

  CopyRight(stderr,argv[0]); 
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); 

  clear_mat(zerobox);

  fitfile    = ftp2fn(efTPS,NFILE,fnm);
  trxfile    = ftp2fn(efTRX,NFILE,fnm);
  ndxfile    = ftp2fn_null(efNDX,NFILE,fnm);
  eigvalfile = ftp2fn(efXVG,NFILE,fnm);
  eigvecfile = ftp2fn(efTRN,NFILE,fnm);
  averfile   = ftp2fn(efSTO,NFILE,fnm);
  logfile    = ftp2fn(efLOG,NFILE,fnm);
  asciifile  = opt2fn_null("-ascii",NFILE,fnm);
  xpmfile    = opt2fn_null("-xpm",NFILE,fnm);
  xpmafile   = opt2fn_null("-xpma",NFILE,fnm);

  read_tps_conf(fitfile,str,&top,&ePBC,&xref,NULL,box,TRUE);
  atoms=&top.atoms;

  if (bFit) {
    printf("\nChoose a group for the least squares fit\n"); 
    get_index(atoms,ndxfile,1,&nfit,&ifit,&fitname);
    if (nfit < 3) 
      gmx_fatal(FARGS,"Need >= 3 points to fit!\n");
  } else
    nfit=0;
  printf("\nChoose a group for the covariance analysis\n"); 
  get_index(atoms,ndxfile,1,&natoms,&index,&ananame);

  bDiffMass1=FALSE;
  if (bFit) {
    snew(w_rls,atoms->nr);
    for(i=0; (i<nfit); i++) {
      w_rls[ifit[i]]=atoms->atom[ifit[i]].m;
      if (i)
        bDiffMass1 = bDiffMass1 || (w_rls[ifit[i]]!=w_rls[ifit[i-1]]);
    }
  }
  bDiffMass2=FALSE;
  snew(sqrtm,natoms);
  for(i=0; (i<natoms); i++)
    if (bM) {
      sqrtm[i]=sqrt(atoms->atom[index[i]].m);
      if (i)
	bDiffMass2 = bDiffMass2 || (sqrtm[i]!=sqrtm[i-1]);
    }
    else
      sqrtm[i]=1.0;
  
  if (bFit && bDiffMass1 && !bDiffMass2) {
    bDiffMass1 = natoms != nfit;
    i=0;
    for (i=0; (i<natoms) && !bDiffMass1; i++)
      bDiffMass1 = index[i] != ifit[i];
    if (!bDiffMass1) {
      fprintf(stderr,"\n"
	      "Note: the fit and analysis group are identical,\n"
	      "      while the fit is mass weighted and the analysis is not.\n"
	      "      Making the fit non mass weighted.\n\n");
      for(i=0; (i<nfit); i++)
	w_rls[ifit[i]]=1.0;
    }
  }
  
  /* Prepare reference frame */
  if (bPBC) {
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,atoms->nr,box);
    gmx_rmpbc(gpbc,atoms->nr,box,xref);
  }
  if (bFit)
    reset_x(nfit,ifit,atoms->nr,NULL,xref,w_rls);

  snew(x,natoms);
  snew(xav,natoms);
  ndim=natoms*DIM;
  if (sqrt(GMX_LARGE_INT_MAX)<ndim) {
    gmx_fatal(FARGS,"Number of degrees of freedoms to large for matrix.\n");
  }
  snew(mat,ndim*ndim);

  fprintf(stderr,"Calculating the average structure ...\n");
  nframes0 = 0;
  nat=read_first_x(oenv,&status,trxfile,&t,&xread,box);
  if (nat != atoms->nr)
    fprintf(stderr,"\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n",natoms,nat);
  do {
    nframes0++;
    /* calculate x: a fitted struture of the selected atoms */
    if (bPBC)
      gmx_rmpbc(gpbc,nat,box,xread);
    if (bFit) {
      reset_x(nfit,ifit,nat,NULL,xread,w_rls);
      do_fit(nat,w_rls,xref,xread);
    }
    for (i=0; i<natoms; i++)
      rvec_inc(xav[i],xread[index[i]]);
  } while (read_next_x(oenv,status,&t,nat,xread,box));
  close_trj(status);
  
  inv_nframes = 1.0/nframes0;
  for(i=0; i<natoms; i++)
    for(d=0; d<DIM; d++) {
      xav[i][d] *= inv_nframes;
      xread[index[i]][d] = xav[i][d];
    }
  write_sto_conf_indexed(opt2fn("-av",NFILE,fnm),"Average structure",
			 atoms,xread,NULL,epbcNONE,zerobox,natoms,index);
  sfree(xread);

  fprintf(stderr,"Constructing covariance matrix (%dx%d) ...\n",(int)ndim,(int)ndim);
  nframes=0;
  nat=read_first_x(oenv,&status,trxfile,&t,&xread,box);
  tstart = t;
  do {
    nframes++;
    tend = t;
    /* calculate x: a (fitted) structure of the selected atoms */
    if (bPBC)
      gmx_rmpbc(gpbc,nat,box,xread);
    if (bFit) {
      reset_x(nfit,ifit,nat,NULL,xread,w_rls);
      do_fit(nat,w_rls,xref,xread);
    }
    if (bRef)
      for (i=0; i<natoms; i++)
	rvec_sub(xread[index[i]],xref[index[i]],x[i]);
    else
      for (i=0; i<natoms; i++)
	rvec_sub(xread[index[i]],xav[i],x[i]);
    
    for (j=0; j<natoms; j++) {
      for (dj=0; dj<DIM; dj++) {
	k=ndim*(DIM*j+dj);
	xj=x[j][dj];
	for (i=j; i<natoms; i++) {
	  l=k+DIM*i;
	  for(d=0; d<DIM; d++)
	    mat[l+d] += x[i][d]*xj;
	}
      }
    }
  } while (read_next_x(oenv,status,&t,nat,xread,box) && 
	   (bRef || nframes < nframes0));
  close_trj(status);
  gmx_rmpbc_done(gpbc);

  fprintf(stderr,"Read %d frames\n",nframes);
  
  if (bRef) {
    /* copy the reference structure to the ouput array x */
    snew(xproj,natoms);
    for (i=0; i<natoms; i++)
      copy_rvec(xref[index[i]],xproj[i]);
  } else {
    xproj = xav;
  }

  /* correct the covariance matrix for the mass */
  inv_nframes = 1.0/nframes;
  for (j=0; j<natoms; j++) 
    for (dj=0; dj<DIM; dj++) 
      for (i=j; i<natoms; i++) { 
	k = ndim*(DIM*j+dj)+DIM*i;
	for (d=0; d<DIM; d++)
	  mat[k+d] = mat[k+d]*inv_nframes*sqrtm[i]*sqrtm[j];
      }

  /* symmetrize the matrix */
  for (j=0; j<ndim; j++) 
    for (i=j; i<ndim; i++)
      mat[ndim*i+j]=mat[ndim*j+i];
  
  trace=0;
  for(i=0; i<ndim; i++)
    trace+=mat[i*ndim+i];
  fprintf(stderr,"\nTrace of the covariance matrix: %g (%snm^2)\n",
	  trace,bM ? "u " : "");
  
  if (asciifile) {
    out = ffopen(asciifile,"w");
    for (j=0; j<ndim; j++) {
      for (i=0; i<ndim; i+=3)
	fprintf(out,"%g %g %g\n",
		mat[ndim*j+i],mat[ndim*j+i+1],mat[ndim*j+i+2]);
    }
    ffclose(out);
  }
  
  if (xpmfile) {
    min = 0;
    max = 0;
    snew(mat2,ndim);
    for (j=0; j<ndim; j++) {
      mat2[j] = &(mat[ndim*j]);
      for (i=0; i<=j; i++) {
	if (mat2[j][i] < min)
	  min = mat2[j][i];
	if (mat2[j][j] > max)
	  max = mat2[j][i];
      }
    }
    snew(axis,ndim);
    for(i=0; i<ndim; i++)
      axis[i] = i+1;
    rlo.r = 0; rlo.g = 0; rlo.b = 1;
    rmi.r = 1; rmi.g = 1; rmi.b = 1;
    rhi.r = 1; rhi.g = 0; rhi.b = 0;
    out = ffopen(xpmfile,"w");
    nlevels = 80;
    write_xpm3(out,0,"Covariance",bM ? "u nm^2" : "nm^2",
	       "dim","dim",ndim,ndim,axis,axis,
	       mat2,min,0.0,max,rlo,rmi,rhi,&nlevels);
    ffclose(out);
    sfree(axis);
    sfree(mat2);
  }

  if (xpmafile) {
    min = 0;
    max = 0;
    snew(mat2,ndim/DIM);
    for (i=0; i<ndim/DIM; i++)
      snew(mat2[i],ndim/DIM);
    for (j=0; j<ndim/DIM; j++) {
      for (i=0; i<=j; i++) {
	mat2[j][i] = 0;
	for(d=0; d<DIM; d++)
	  mat2[j][i] += mat[ndim*(DIM*j+d)+DIM*i+d];
	if (mat2[j][i] < min)
	  min = mat2[j][i];
	if (mat2[j][j] > max)
	  max = mat2[j][i];
	mat2[i][j] = mat2[j][i];
      }
    }
    snew(axis,ndim/DIM);
    for(i=0; i<ndim/DIM; i++)
      axis[i] = i+1;
    rlo.r = 0; rlo.g = 0; rlo.b = 1;
    rmi.r = 1; rmi.g = 1; rmi.b = 1;
    rhi.r = 1; rhi.g = 0; rhi.b = 0;
    out = ffopen(xpmafile,"w");
    nlevels = 80;
    write_xpm3(out,0,"Covariance",bM ? "u nm^2" : "nm^2",
	       "atom","atom",ndim/DIM,ndim/DIM,axis,axis,
	       mat2,min,0.0,max,rlo,rmi,rhi,&nlevels);
    ffclose(out);
    sfree(axis);
    for (i=0; i<ndim/DIM; i++)
      sfree(mat2[i]);
    sfree(mat2);
  }


  /* call diagonalization routine */
  
  fprintf(stderr,"\nDiagonalizing ...\n");
  fflush(stderr);

  snew(eigval,ndim);
  snew(tmp,ndim*ndim);
  memcpy(tmp,mat,ndim*ndim*sizeof(real));
  eigensolver(tmp,ndim,0,ndim,eigval,mat);
  sfree(tmp);
  
  /* now write the output */

  sum=0;
  for(i=0; i<ndim; i++)
    sum+=eigval[i];
  fprintf(stderr,"\nSum of the eigenvalues: %g (%snm^2)\n",
	  sum,bM ? "u " : "");
  if (fabs(trace-sum)>0.01*trace)
    fprintf(stderr,"\nWARNING: eigenvalue sum deviates from the trace of the covariance matrix\n");
  
  fprintf(stderr,"\nWriting eigenvalues to %s\n",eigvalfile);

  sprintf(str,"(%snm\\S2\\N)",bM ? "u " : "");
  out=xvgropen(eigvalfile, 
	       "Eigenvalues of the covariance matrix",
	       "Eigenvector index",str,oenv);  
  for (i=0; (i<ndim); i++)
    fprintf (out,"%10d %g\n",(int)i+1,eigval[ndim-1-i]);
  ffclose(out);  

  if (end==-1) {
    if (nframes-1 < ndim)
      end=nframes-1;
    else
      end=ndim;
  }
  if (bFit) {
    /* misuse lambda: 0/1 mass weighted analysis no/yes */
    if (nfit==natoms) {
      WriteXref = eWXR_YES;
      for(i=0; i<nfit; i++)
	copy_rvec(xref[ifit[i]],x[i]);
    } else
      WriteXref = eWXR_NO;
  } else {
    /* misuse lambda: -1 for no fit */
    WriteXref = eWXR_NOFIT;
  }

  write_eigenvectors(eigvecfile,natoms,mat,TRUE,1,end,
		     WriteXref,x,bDiffMass1,xproj,bM,eigval);

  out = ffopen(logfile,"w");

  time(&now);
  gmx_ctime_r(&now,timebuf,STRLEN);
  fprintf(out,"Covariance analysis log, written %s\n",timebuf);
    
  fprintf(out,"Program: %s\n",argv[0]);
#if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
  pcwd=_getcwd(str,STRLEN);
#else
  pcwd=getcwd(str,STRLEN);
#endif
  if(NULL==pcwd)
  {
      gmx_fatal(FARGS,"Current working directory is undefined");
  }

  fprintf(out,"Working directory: %s\n\n",str);

  fprintf(out,"Read %d frames from %s (time %g to %g %s)\n",nframes,trxfile,
	  output_env_conv_time(oenv,tstart),output_env_conv_time(oenv,tend),output_env_get_time_unit(oenv));
  if (bFit)
    fprintf(out,"Read reference structure for fit from %s\n",fitfile);
  if (ndxfile)
    fprintf(out,"Read index groups from %s\n",ndxfile);
  fprintf(out,"\n");

  fprintf(out,"Analysis group is '%s' (%d atoms)\n",ananame,natoms);
  if (bFit)
    fprintf(out,"Fit group is '%s' (%d atoms)\n",fitname,nfit);
  else
    fprintf(out,"No fit was used\n");
  fprintf(out,"Analysis is %smass weighted\n", bDiffMass2 ? "":"non-");
  if (bFit)
    fprintf(out,"Fit is %smass weighted\n", bDiffMass1 ? "":"non-");
  fprintf(out,"Diagonalized the %dx%d covariance matrix\n",(int)ndim,(int)ndim);
  fprintf(out,"Trace of the covariance matrix before diagonalizing: %g\n",
	  trace);
  fprintf(out,"Trace of the covariance matrix after diagonalizing: %g\n\n",
	  sum);

  fprintf(out,"Wrote %d eigenvalues to %s\n",(int)ndim,eigvalfile);
  if (WriteXref == eWXR_YES)
    fprintf(out,"Wrote reference structure to %s\n",eigvecfile);
  fprintf(out,"Wrote average structure to %s and %s\n",averfile,eigvecfile);
  fprintf(out,"Wrote eigenvectors %d to %d to %s\n",1,end,eigvecfile);

  ffclose(out);

  fprintf(stderr,"Wrote the log to %s\n",logfile);

  thanx(stderr);
  
  return 0;
}