예제 #1
0
float pseudo_inv(const Eigen::MatrixXf *mat_in,
                 Eigen::MatrixXf *mat_out) {
  int dim = 0;

  // Get matrices dimension :
  if (mat_in->cols () != mat_in->rows ()) {
    THROW_ERR("Cannot compute matrix pseudo_inverse");
  } else {
    dim = mat_in->cols ();
  }

  mat_out->resize (dim, dim);

  Eigen::MatrixXf U (dim,dim);
  Eigen::MatrixXf eig_val (dim, 1);
  Eigen::MatrixXf eig_val_inv (dim, dim);
  Eigen::MatrixXf V (dim, dim);

  float det;

  eig_val_inv = Eigen::MatrixXf::Identity(dim,dim);

  // Compute the SVD decomposition
  Eigen::JacobiSVD<Eigen::MatrixXf> svd(*mat_in, Eigen::ComputeFullU | Eigen::ComputeFullV);

  eig_val = svd.singularValues();
  U = svd.matrixU();
  V = svd.matrixV();

  // Compute pseudo-inverse
  // - quick'n'dirty inversion of eigen matrix
  for (int i = 0; i<dim; ++i) {
    if (eig_val(i,0) != 0.f)
      eig_val_inv(i,i) = 1.f / eig_val(i,0);
    else
      eig_val_inv(i,i) = 0.f;
  }

  *mat_out = V.transpose() * eig_val_inv * U.transpose();

  // Compute determinant from eigenvalues..
  det = 1.f;
  for (int i=0; i<dim; ++i) {
    det *= eig_val(i,0);
  }

  return det;
}
예제 #2
0
// Small hack to compute pseudo-inverse for a 6x6 matrix using SVD method
float pseudo_inv_6(const Eigen::Matrix <float, 6,6> *mat_in,
                   Eigen::Matrix <float, 6,6> *mat_out)
{
  Eigen::Matrix <float, 6,6> U;
  Eigen::Matrix <float, 6,1> eig_val;
  Eigen::Matrix <float, 6,6> eig_val_inv;
  Eigen::Matrix <float, 6,6> V;
  float det;

  eig_val_inv = Eigen::MatrixXf::Identity(6,6);

  // Compute the SVD decomposition
  Eigen::JacobiSVD<Eigen::MatrixXf> svd(*mat_in,
                                        Eigen::ComputeThinU | Eigen::ComputeThinV);

  eig_val = svd.singularValues();
  U = svd.matrixU();
  V = svd.matrixV();

  // Compute pseudo-inverse
  // - quick'n'dirty inversion of eigen matrix
  for (int i = 0; i<6; ++i) {
    if (eig_val(i,0) != 0.f)
      eig_val_inv(i,i) = 1.f / eig_val(i,0);
    else
      eig_val_inv(i,i) = 0.f;
  }

  *mat_out = V.transpose() * eig_val_inv * U.transpose();

  // Compute determinant from eigenvalues..
  det = 1.f;
  for (int i=0; i<6; ++i) {
    det *= eig_val(i,0);
  }

  return det;
}
예제 #3
0
void LocalGeometryRef::SVD(int num_eigen)
{
	vnl_symmetric_eigensystem<double> eigen(this->probability_matrix);
	vnl_matrix<double> eig_vec = eigen.V;
	vnl_diag_matrix<double> eig_val = eigen.D;
	
	vnl_vector<double> temp_vec(this->num_row);
	for(int row = 0; row<eig_val.rows(); row++)
	{
		temp_vec(row) = eig_val(row,row);
	}

	this->eigVals.set_size(num_eigen);
	this->eigVecs.set_size(this->num_row, num_eigen);
	for(int i=0; i<num_eigen; i++)
	{
		this->eigVals(i) = temp_vec.max_value();
		int pos = temp_vec.arg_max();
		temp_vec(pos) = temp_vec.min_value() - 1;
		this->eigVecs.set_column(i, eig_vec.get_column(pos) * this->eigVals(i) );
	}

	//output files for debugging
	FILE *fp1 = fopen("eigenvecters.txt","w");
	for(int i=0; i<this->num_row; i++)
	{
		for(int j=0; j<num_eigen; j++)
		{
			fprintf(fp1,"%f\t",this->eigVecs(i, j));
		}
		fprintf(fp1,"\n");
	}
	fclose(fp1);

	FILE *fp2 = fopen("eigenvalues.txt","w");
	for(int i=0; i<num_eigen; i++)
	{
		fprintf(fp2,"%f\t",this->eigVals(i));
		std::cout<<this->eigVals(i)<<std::endl;
		fprintf(fp2,"\n");
	}
	fclose(fp2);
}