예제 #1
0
//--------------------------------------------------------------//
void
CheckPositiveDefiniteCorrMatrix(double corr01, double corr02, double corr12, std::string & errTxt)
{

  NRLib::Matrix corr_matrix(3, 3, 0);
  for(int i=0; i<3; i++)
    corr_matrix(i,i) = 1;

  corr_matrix(0,1) = corr01;
  corr_matrix(1,0) = corr01;
  corr_matrix(0,2) = corr02;
  corr_matrix(2,0) = corr02;
  corr_matrix(1,2) = corr12;
  corr_matrix(2,1) = corr12;

  NRLib::Vector eigen_values(3, 0);
  NRLib::Matrix eigen_vectors(3, 3, 0);
  NRLib::ComputeEigenVectors(corr_matrix, eigen_values, eigen_vectors);

  bool pos_def = true;
  for( int i=0; i<3; i++) {
    if(eigen_values(i) < 0)
      pos_def = false;
  }

  if(pos_def == false)
    errTxt += "The correlations given in the tabulated rock physics model need to generate a positive definite matrix\n";
}
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);
}
void
RockPhysicsInversion4D::SolveGEVProblem(NRLib::Matrix sigma_prior,
                                        NRLib::Matrix sigma_posterior,
                                        NRLib::Matrix & vOut){
  //Compute transforms v1, v2, v3 and v4  ----------------------------------------

  // computing filter
  NRLib::SymmetricMatrix  sigma_priorInv(6);
  for(int i=0;i<6;i++)
    for(int j=0;j<=i;j++)
      sigma_priorInv(j,i)=sigma_prior(i,j);

  NRLib::CholeskyInvert(sigma_priorInv);
  NRLib::Matrix eye = NRLib::IdentityMatrix(6);
  NRLib::Matrix filter = eye- sigma_priorInv*sigma_posterior;
  // computing components
  NRLib::Vector eigen_values(6);
  NRLib::Matrix eigen_vectors(6,6);
  NRLib::ComputeEigenVectors( filter ,eigen_values,eigen_vectors);

  // extracting four best components
  std::vector<int> current_index(6);
  current_index[0] = 0;current_index[1] = 1;
  current_index[2] = 2;current_index[3] = 3;
  current_index[4] = 4;current_index[5] = 5;

  std::vector<int> best_index(4);
  std::vector<int> keep_index(6);
  keep_index = current_index;

  NRLib::Vector current_value(6);
  NRLib::Vector keep_value(6);
  keep_value  = eigen_values;

  for(int i=0;i<4;i++){
    current_index=keep_index;
    current_value =keep_value;
    double maxVal=-999; // (the theoretical max value is less than 1 and larger than zero)
    for(int j=0;j<6-i;j++){
      if(current_value(j) > maxVal){
        maxVal=current_value(j);
        best_index[i]=current_index[j];
      }
    }
    int counter=0;
    for(int j=0;j<6-i;j++){
      if(current_value(j) != maxVal){
        keep_value(counter)=current_value(j);
        keep_index[counter]=current_index[j];
        counter++;
      }
    }
  }
  vOut.resize(6,4);
  for(int i=0;i<4;i++)
    for(int j=0;j<6;j++)
      vOut(j,i)=eigen_vectors(j,best_index[i]);
}
예제 #4
0
파일: tabulated.cpp 프로젝트: CRAVA/crava
void
Tabulated::CalculateSigmaSqrt(const NRLib::Grid2D<double> & Sigma)
{
  // Calculate square root of positive definite correlation matrix

  NRLib::Matrix corr_matrix(n_variables_,n_variables_);
  for(int i=0; i<n_variables_; i++) {
    for(int j=0; j<n_variables_; j++)
      corr_matrix(i,j) = Sigma(i,j);
  }

  NRLib::Vector eigen_values(n_variables_);
  NRLib::Matrix eigen_vectors(n_variables_,n_variables_);
  NRLib::ComputeEigenVectors(corr_matrix, eigen_values, eigen_vectors);

  NRLib::Matrix eigen_vectors_transpose(n_variables_,n_variables_);
  for(int i=0; i<n_variables_; i++) {
    for(int j=0; j<n_variables_; j++)
      eigen_vectors_transpose(j,i) = eigen_vectors(i,j);
  }

  NRLib::Matrix lambda_square(n_variables_,n_variables_);
  for(int i=0; i<n_variables_; i++) {
    for(int j=0; j<n_variables_; j++) {
      if(i == j)
        lambda_square(i,j) = std::sqrt(eigen_values(i));
      else
        lambda_square(i,j) = 0;
    }
  }

  NRLib::Matrix Sigma_sqrt1(n_variables_,n_variables_);
  NRLib::Matrix Sigma_sqrt(n_variables_,n_variables_);

  Sigma_sqrt1 = eigen_vectors * lambda_square;
  Sigma_sqrt  = Sigma_sqrt1   * eigen_vectors_transpose;

  for(int i=0; i<n_variables_; i++) {
    for(int j=0; j<n_variables_; j++)
      Sigma_sqrt_(i,j) = Sigma_sqrt(i,j);
  }
}
void getSpectralProfile(const pcl::PointCloud<PointT> &cloud, SpectralProfile &spectralProfile)
{
   Eigen::Matrix3d eigen_vectors;
   Eigen::Vector3d eigen_values;
   sensor_msgs::PointCloud2 cloudMsg2;
   pcl::toROSMsg (cloud,cloudMsg2);
   sensor_msgs::PointCloud cloudMsg;
   sensor_msgs::convertPointCloud2ToPointCloud(cloudMsg2,cloudMsg);
  cloud_geometry::nearest::computePatchEigenNormalized (cloudMsg,eigen_vectors,eigen_values,spectralProfile.centroid);
  
  spectralProfile.setEigValues (eigen_values);
  float minEigV=FLT_MAX;
 
  for(int i=0;i<3;i++)
    {
      
          cout<<"eig value:"<<eigen_values(i)<<endl;
      if(minEigV>eigen_values(i))
        {
          minEigV=eigen_values(i);
          cout<<"min eig value:"<<minEigV<<endl;
          spectralProfile.normal=eigen_vectors.col(i);
          // check the angle with line joining the centroid to origin
          VectorG centroid(spectralProfile.centroid.x,spectralProfile.centroid.y,spectralProfile.centroid.z);
          VectorG camera=originalFrames[cloud.points[1].cameraIndex]->getCameraTrans().getOrigin();
          VectorG cent2cam=camera.subtract(centroid);
          VectorG normal(spectralProfile.normal[0],spectralProfile.normal[1],spectralProfile.normal[2]);
          if (normal.dotProduct(cent2cam) < 0)
          {
              // flip the sign of the normal
              spectralProfile.normal[0] = -spectralProfile.normal[0];
              spectralProfile.normal[1] = -spectralProfile.normal[1];
              spectralProfile.normal[2] = -spectralProfile.normal[2];
          }
        }
    }
  assert(minEigV==spectralProfile.getDescendingLambda (2));
}
예제 #6
0
geometry_msgs::Quaternion calc_quaternion_average( std::vector<geometry_msgs::Pose> pose_vector ){
	
	Eigen::Matrix4f averaging_matrix;
	Eigen::Vector4f quaternion;
	
	averaging_matrix.setZero();
	for( unsigned int sample_ii=0; sample_ii<pose_vector.size(); sample_ii++){
		quaternion(0) = pose_vector[sample_ii].orientation.x;
		quaternion(1) = pose_vector[sample_ii].orientation.y;
		quaternion(2) = pose_vector[sample_ii].orientation.z;
		quaternion(3) = pose_vector[sample_ii].orientation.w;
		averaging_matrix =  averaging_matrix + quaternion*quaternion.transpose();
	  }// for all samples
	 
	 Eigen::EigenSolver<Eigen::Matrix4f> ev_solver;
	 ev_solver.compute( averaging_matrix);
	 Eigen::Vector4cf eigen_values = ev_solver.eigenvalues();
	 float max_ev=eigen_values(0).real();
	 unsigned int max_ii = 0;
	 for( unsigned int ev_ii=1; ev_ii<4; ev_ii++){
		 if( eigen_values(ev_ii).real()>max_ev ){
			 max_ev = eigen_values(ev_ii).real();
			 max_ii=ev_ii;
		 }
	 }
	 
	 Eigen::Vector4f eigen_vector = ev_solver.eigenvectors().col(max_ii).real();
	 eigen_vector.normalize();
	  
	 geometry_msgs::Quaternion quaternion_msg;
	 quaternion_msg.x = eigen_vector(0);
	 quaternion_msg.y = eigen_vector(1);
	 quaternion_msg.z = eigen_vector(2);
	 quaternion_msg.w = eigen_vector(3);
	 return quaternion_msg;
	 
}
예제 #7
0
파일: pod.hpp 프로젝트: TrojanXu/feelpp
int POD<TruthModelType>::pod( mode_set_type& ModeSet, bool is_primal, const wn_type& elements_set, bool use_solutions )
{
    M_backend = backend_type::build( BACKEND_PETSC );

    Eigen::SelfAdjointEigenSolver< matrixN_type > eigen_solver;
    M_use_solutions = use_solutions;

    fillPodMatrix( elements_set );
    int size = M_pod_matrix.cols();

    //store the matrix
    if ( M_store_pod_matrix )
    {
        std::ofstream matrix_file;
        LOG(INFO)<<"saving Pod matrix in a file \n";
        matrix_file.open( "PodMatrix",std::ios::out );
        matrix_file<<M_pod_matrix.rows();
        matrix_file<<"\n";
        matrix_file<<M_pod_matrix.cols();
        matrix_file<<"\n";

        for ( int i=0; i<M_pod_matrix.rows(); i++ )
        {
            for ( int j=0; j<M_pod_matrix.cols(); j++ )
            {
                matrix_file<< std::setprecision( 16 ) <<M_pod_matrix( i,j )<<" ";
            }

            matrix_file<<"\n";
        }

        LOG(INFO)<<" matrix wrote in file named PodMatrix \n";
    }

    else if ( M_store_pod_matrix_format_octave )
    {
        std::ofstream matrix_file;
        LOG(INFO)<<"saving Pod matrix in a file \n";
        matrix_file.open( "PodMatrixOctave.mat",std::ios::out );
        matrix_file<<"# name: A\n";
        matrix_file<<"# type: matrix\n";
        matrix_file<<"# rows: "<<M_pod_matrix.rows()<<"\n";
        matrix_file<<"# columns: "<<M_pod_matrix.cols()<<"\n";

        for ( int i=0; i<M_pod_matrix.rows(); i++ )
        {
            for ( int j=0; j<M_pod_matrix.cols(); j++ )
            {
                matrix_file<< std::setprecision( 16 ) <<M_pod_matrix( i,j )<<" ";
            }

            matrix_file<<"\n";
        }

        LOG(INFO)<<" matrix wrote in file named PodMatrix \n";
        matrix_file.close();
    }


    eigen_solver.compute( M_pod_matrix ); // solve M_pod_matrix psi = lambda psi

    int number_of_eigenvalues =  eigen_solver.eigenvalues().size();
    LOG(INFO)<<"Number of eigenvalues  : "<<number_of_eigenvalues<<"\n";
    //we copy eigenvalues in a std::vector beacause it's easier to manipulate it
    std::vector<double> eigen_values( number_of_eigenvalues );

    int too_small_index = 0;

    for ( int i=0; i<number_of_eigenvalues; i++ )
    {
        if ( imag( eigen_solver.eigenvalues()[i] )>1e-12 )
        {
            throw std::logic_error( "[POD::pod] ERROR : complex eigenvalues were found" );
        }

        eigen_values[i]=real( eigen_solver.eigenvalues()[i] );
    }


    //tab will contains index of maximum eigenvalues
    std::vector<int> max_idx;
    std::vector<double> copy_eigen_values ( eigen_values );
    int number_of_good_eigenvectors=0;
    bool go = true;
    double min_eigenvalue = option(_name="pod.minimum-eigenvalue").template as<double>();
    //for(int maxmode=0; maxmode<M_Nm; maxmode++)
    auto max = std::max_element( copy_eigen_values.begin(), copy_eigen_values.end() );
    double idx = std::distance( copy_eigen_values.begin(), max );
    if( *max < min_eigenvalue )
        go=false;
    while( go )
    {
        number_of_good_eigenvectors++;
        max_idx.push_back( idx );
        copy_eigen_values[idx]=0;
        max = std::max_element( copy_eigen_values.begin(), copy_eigen_values.end() );
        idx = std::distance( copy_eigen_values.begin(), max );
        if( *max < min_eigenvalue )
            go = false;
        if( number_of_good_eigenvectors == M_Nm )
            go = false;
        if( number_of_good_eigenvectors == number_of_eigenvalues )
            go = false;
    }

    CHECK( number_of_good_eigenvectors > 0 )<<"The max eigenvalue "<<*max<<" is under the minimum eigenvalue set by the user "<<min_eigenvalue<<" and we have zero eigenvectors !\n";

    int position_of_largest_eigenvalue=max_idx[0];

    if( M_Nm == -1 )
    {
        //in this case the user doesn't know a priori
        //what value give to M_Nm
        //this case appears for when apply-POD-to-WN=true
        M_Nm = number_of_good_eigenvectors;
    }
    if ( M_Nm > number_of_good_eigenvectors && number_of_good_eigenvectors>0 && is_primal )
    {
        //in this case, the user set M_Nm but with respect to
        //the minimum eigenvalue set, we don't find enough eigenvectors
        M_Nm = number_of_good_eigenvectors;
    }

    for ( int i=0; i<M_Nm; i++ )
    {
        element_ptrtype mode ( new element_type( M_model->functionSpace() ) );
        mode->zero();

        int index=0;

        if( M_use_solutions )
        {
            M_bdf->setRestart( true );

            for ( M_bdf->restart(); !M_bdf->isFinished(); M_bdf->next() )
            {
                M_bdf->loadCurrent();
                double psi_k = real( eigen_solver.eigenvectors().col( position_of_largest_eigenvalue )[index] );
                M_bdf->unknown( 0 ).scale( psi_k );
                mode->add( 1 , M_bdf->unknown( 0 ) );
                index++;
            }
        }//if use solutions
        else
        {
            double eigenvalue = eigen_values[ position_of_largest_eigenvalue ];
            for(int j=0; j<size; j++)
            {
                double psi_k = real( eigen_solver.eigenvectors().col( position_of_largest_eigenvalue )[index] );
                mode->add( psi_k , elements_set[j] );
                index++;
            }
        }//if use elements set


        //check
        auto eigenvector = eigen_solver.eigenvectors().col( position_of_largest_eigenvalue );
        double eigenvalue = eigen_values[position_of_largest_eigenvalue];
        auto Aw = M_pod_matrix*eigenvector;
        auto lambdaw = eigenvalue*eigenvector;
        double Awnorm = Aw.norm();
        double lambdawnorm = lambdaw.norm();
        double eigenvectornorm = eigenvector.norm();
        double check_tol = option(_name="pod.check-tol").template as<double>();
        CHECK( math::abs(Awnorm - lambdawnorm) < check_tol )<<" A w : "<<Awnorm<<" and lambda w : "<<lambdawnorm<<" so math::abs(A w - lambda w) : "<<math::abs(Awnorm - lambdawnorm)<<" and pod.check-tol : "<<check_tol<<" -- eigenvalue : "<<eigenvalue<<"\n";

        if( (i+1) < max_idx.size() )
            position_of_largest_eigenvalue=max_idx[i+1];
        ModeSet.push_back( *mode );
    }// loop on number of modes


    //check orthogonality
    if( option(_name="pod.check-orthogonality").template as<bool>() )
    {
        position_of_largest_eigenvalue=max_idx[0];
        for(int i=1; i<M_Nm; i++)
        {
            auto modei = ModeSet[i-1];
            for(int j=i+1; j<M_Nm; j++)
            {
                auto modej = ModeSet[j-1];
                double prod = M_model->scalarProductForPod( modei , modej );
                CHECK( prod < 1e-10 )<<"scalar product between mode "<<i<<" and mode "<<j<<" is not null and is "<<prod<<"\n";
            }
            double eigenvalue = eigen_values[ position_of_largest_eigenvalue ];
            double prod = M_model->scalarProductForPod( modei , modei );
            {
                CHECK( (prod - eigenvalue) < 1e-12 )<<"scalar product between mode "<<i<<" and mode "<<i<<" is "<<prod<<" and associated eigenvalue : "<<eigenvalue<<" ( i = "<<i<<") \n";
            }
            if( i < max_idx.size() )
                position_of_largest_eigenvalue=max_idx[i];
        }
    }

    if ( M_store_pod_matrix_format_octave )
    {
        std::cout<<"M_store_pod_matrix_format_octave = "<<M_store_pod_matrix_format_octave<<std::endl;
        std::ofstream eigenvalue_file;
        eigenvalue_file.open( "eigen_values.mat",std::ios::out );
        eigenvalue_file<<"# name: E\n";
        eigenvalue_file<<"# type: matrix\n";
        eigenvalue_file<<"# rows: "<<number_of_eigenvalues<<"\n";
        eigenvalue_file<<"# columns: 1\n";

        for ( int i=0; i<number_of_eigenvalues; i++ )
        {
            eigenvalue_file<<std::setprecision( 16 )<<eigen_values[i]<<"\n";
        }

        eigenvalue_file.close();


        std::ofstream eigenvector_file( ( boost::format( "eigen_vectors" ) ).str().c_str() );

        for ( int j=0; j<M_pod_matrix.cols(); j++ )
        {
            for ( int i=0; i<number_of_eigenvalues; i++ )
            {
                eigenvector_file<<std::setprecision( 16 )<<eigen_solver.eigenvectors().col( i )[j] <<" ";
            }

            eigenvector_file<<"\n";
        }

        eigenvector_file.close();


        for ( int i=0; i<M_Nm; i++ )
        {
            std::ofstream mode_file( ( boost::format( "mode_%1%" ) %i ).str().c_str() );
            element_type e = ModeSet[i];

            for ( size_type j=0; j<e.size(); j++ ) mode_file<<std::setprecision( 16 )<<e( j )<<"\n";

            mode_file.close();
        }

    }

    return M_Nm;

}