本文整理汇总了C++中eigen::JacobiSVD::matrixU方法的典型用法代码示例。如果您正苦于以下问题:C++ JacobiSVD::matrixU方法的具体用法?C++ JacobiSVD::matrixU怎么用?C++ JacobiSVD::matrixU使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类eigen::JacobiSVD
的用法示例。
在下文中一共展示了JacobiSVD::matrixU方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: MatrixXr_pseudoInverse
bool MatrixXr_pseudoInverse(const MatrixXr &a, MatrixXr &a_pinv, double epsilon) {
// see : http://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse#The_general_case_and_the_SVD_method
if ( a.rows()<a.cols() ) return false;
// SVD
Eigen::JacobiSVD<MatrixXr> svdA;
svdA.compute(a,Eigen::ComputeThinU|Eigen::ComputeThinV);
MatrixXr vSingular = svdA.singularValues();
// Build a diagonal matrix with the Inverted Singular values
// The pseudo inverted singular matrix is easy to compute :
// is formed by replacing every nonzero entry by its reciprocal (inversing).
VectorXr vPseudoInvertedSingular(svdA.matrixV().cols(),1);
for (int iRow =0; iRow<vSingular.rows(); iRow++) {
if(fabs(vSingular(iRow))<=epsilon) vPseudoInvertedSingular(iRow,0)=0.;
else vPseudoInvertedSingular(iRow,0)=1./vSingular(iRow);
}
// A little optimization here
MatrixXr mAdjointU = svdA.matrixU().adjoint().block(0,0,vSingular.rows(),svdA.matrixU().adjoint().cols());
// Pseudo-Inversion : V * S * U'
a_pinv = (svdA.matrixV() * vPseudoInvertedSingular.asDiagonal()) * mAdjointU;
return true;
}
示例2: EstimateTfSVD
// Assume t = double[3], q = double[4]
void EstimateTfSVD(double* t, double* q)
{
// Assemble the correlation matrix H = target * reference'
Eigen::Matrix3d H = (cloud_tgt_demean * cloud_ref_demean.transpose ()).topLeftCorner<3, 3>();
// Compute the Singular Value Decomposition
Eigen::JacobiSVD<Eigen::Matrix3d> svd (H, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::Matrix3d u = svd.matrixU ();
Eigen::Matrix3d v = svd.matrixV ();
// Compute R = V * U'
if (u.determinant () * v.determinant () < 0)
{
for (int i = 0; i < 3; ++i)
v (i, 2) *= -1;
}
// std::cout<< "centroid_src: "<<centroid_src(0) <<" "<< centroid_src(1) <<" "<< centroid_src(2) << " "<< centroid_src(3)<<std::endl;
// std::cout<< "centroid_tgt: "<<centroid_tgt(0) <<" "<< centroid_tgt(1) <<" "<< centroid_tgt(2) << " "<< centroid_tgt(3)<<std::endl;
Eigen::Matrix3d R = v * u.transpose ();
const Eigen::Vector3d Rc (R * centroid_tgt.head<3> ());
Eigen::Vector3d T = centroid_ref.head<3> () - Rc;
// Make sure these memory locations are valid
assert(t != NULL && q!=NULL);
Eigen::Quaterniond Q(R);
t[0] = T(0); t[1] = T(1); t[2] = T(2);
q[0] = Q.w(); q[1] = Q.x(); q[2] = Q.y(); q[3] = Q.z();
}
示例3: svd
template <typename PointSource, typename PointTarget, typename Scalar> void
pcl::registration::TransformationEstimationSVD<PointSource, PointTarget, Scalar>::getTransformationFromCorrelation (
const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> &cloud_src_demean,
const Eigen::Matrix<Scalar, 4, 1> ¢roid_src,
const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> &cloud_tgt_demean,
const Eigen::Matrix<Scalar, 4, 1> ¢roid_tgt,
Matrix4 &transformation_matrix) const
{
transformation_matrix.setIdentity ();
// Assemble the correlation matrix H = source * target'
Eigen::Matrix<Scalar, 3, 3> H = (cloud_src_demean * cloud_tgt_demean.transpose ()).topLeftCorner (3, 3);
// Compute the Singular Value Decomposition
Eigen::JacobiSVD<Eigen::Matrix<Scalar, 3, 3> > svd (H, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::Matrix<Scalar, 3, 3> u = svd.matrixU ();
Eigen::Matrix<Scalar, 3, 3> v = svd.matrixV ();
// Compute R = V * U'
if (u.determinant () * v.determinant () < 0)
{
for (int x = 0; x < 3; ++x)
v (x, 2) *= -1;
}
Eigen::Matrix<Scalar, 3, 3> R = v * u.transpose ();
// Return the correct transformation
transformation_matrix.topLeftCorner (3, 3) = R;
const Eigen::Matrix<Scalar, 3, 1> Rc (R * centroid_src.head (3));
transformation_matrix.block (0, 3, 3, 1) = centroid_tgt.head (3) - Rc;
}
示例4: pose_estimation_3d3d
void pose_estimation_3d3d (
const vector<Point3f>& pts1,
const vector<Point3f>& pts2,
Mat& R, Mat& t
)
{
Point3f p1, p2; // center of mass
int N = pts1.size();
for ( int i=0; i<N; i++ )
{
p1 += pts1[i];
p2 += pts2[i];
}
p1 = Point3f( Vec3f(p1) / N);
p2 = Point3f( Vec3f(p2) / N);
vector<Point3f> q1 ( N ), q2 ( N ); // remove the center
for ( int i=0; i<N; i++ )
{
q1[i] = pts1[i] - p1;
q2[i] = pts2[i] - p2;
}
// compute q1*q2^T
Eigen::Matrix3d W = Eigen::Matrix3d::Zero();
for ( int i=0; i<N; i++ )
{
W += Eigen::Vector3d ( q1[i].x, q1[i].y, q1[i].z ) * Eigen::Vector3d ( q2[i].x, q2[i].y, q2[i].z ).transpose();
}
cout<<"W="<<W<<endl;
// SVD on W
Eigen::JacobiSVD<Eigen::Matrix3d> svd ( W, Eigen::ComputeFullU|Eigen::ComputeFullV );
Eigen::Matrix3d U = svd.matrixU();
Eigen::Matrix3d V = svd.matrixV();
if (U.determinant() * V.determinant() < 0)
{
for (int x = 0; x < 3; ++x)
{
U(x, 2) *= -1;
}
}
cout<<"U="<<U<<endl;
cout<<"V="<<V<<endl;
Eigen::Matrix3d R_ = U* ( V.transpose() );
Eigen::Vector3d t_ = Eigen::Vector3d ( p1.x, p1.y, p1.z ) - R_ * Eigen::Vector3d ( p2.x, p2.y, p2.z );
// convert to cv::Mat
R = ( Mat_<double> ( 3,3 ) <<
R_ ( 0,0 ), R_ ( 0,1 ), R_ ( 0,2 ),
R_ ( 1,0 ), R_ ( 1,1 ), R_ ( 1,2 ),
R_ ( 2,0 ), R_ ( 2,1 ), R_ ( 2,2 )
);
t = ( Mat_<double> ( 3,1 ) << t_ ( 0,0 ), t_ ( 1,0 ), t_ ( 2,0 ) );
}
示例5: svd
template <typename PointSource, typename PointTarget, typename Scalar> void
pcl::registration::TransformationEstimationSVDScale<PointSource, PointTarget, Scalar>::getTransformationFromCorrelation (
const Eigen::MatrixXf &cloud_src_demean,
const Eigen::Vector4f ¢roid_src,
const Eigen::MatrixXf &cloud_tgt_demean,
const Eigen::Vector4f ¢roid_tgt,
Matrix4 &transformation_matrix) const
{
transformation_matrix.setIdentity ();
// Assemble the correlation matrix H = source * target'
Eigen::Matrix<Scalar, 3, 3> H = (cloud_src_demean.cast<Scalar> () * cloud_tgt_demean.cast<Scalar> ().transpose ()).topLeftCorner (3, 3);
// Compute the Singular Value Decomposition
Eigen::JacobiSVD<Eigen::Matrix<Scalar, 3, 3> > svd (H, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::Matrix<Scalar, 3, 3> u = svd.matrixU ();
Eigen::Matrix<Scalar, 3, 3> v = svd.matrixV ();
// Compute R = V * U'
if (u.determinant () * v.determinant () < 0)
{
for (int x = 0; x < 3; ++x)
v (x, 2) *= -1;
}
Eigen::Matrix<Scalar, 3, 3> R = v * u.transpose ();
// rotated cloud
Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> src_ = R * cloud_src_demean.cast<Scalar> ();
float scale1, scale2;
double sum_ss = 0.0f, sum_tt = 0.0f, sum_tt_ = 0.0f;
for (unsigned corrIdx = 0; corrIdx < cloud_src_demean.cols (); ++corrIdx)
{
sum_ss += cloud_src_demean (0, corrIdx) * cloud_src_demean (0, corrIdx);
sum_ss += cloud_src_demean (1, corrIdx) * cloud_src_demean (1, corrIdx);
sum_ss += cloud_src_demean (2, corrIdx) * cloud_src_demean (2, corrIdx);
sum_tt += cloud_tgt_demean (0, corrIdx) * cloud_tgt_demean (0, corrIdx);
sum_tt += cloud_tgt_demean (1, corrIdx) * cloud_tgt_demean (1, corrIdx);
sum_tt += cloud_tgt_demean (2, corrIdx) * cloud_tgt_demean (2, corrIdx);
sum_tt_ += cloud_tgt_demean (0, corrIdx) * src_ (0, corrIdx);
sum_tt_ += cloud_tgt_demean (1, corrIdx) * src_ (1, corrIdx);
sum_tt_ += cloud_tgt_demean (2, corrIdx) * src_ (2, corrIdx);
}
scale1 = sqrt (sum_tt / sum_ss);
scale2 = sum_tt_ / sum_ss;
float scale = scale2;
transformation_matrix.topLeftCorner (3, 3) = scale * R;
const Eigen::Matrix<Scalar, 3, 1> Rc (R * centroid_src.cast<Scalar> ().head (3));
transformation_matrix.block (0, 3, 3, 1) = centroid_tgt.cast<Scalar> (). head (3) - Rc;
}
示例6: estimateRigidTransformationSVD
/**
* estimateRigidTransformationSVD
*/
void RigidTransformationRANSAC::estimateRigidTransformationSVD(
const std::vector<Eigen::Vector3f > &srcPts,
const std::vector<int> &srcIndices,
const std::vector<Eigen::Vector3f > &tgtPts,
const std::vector<int> &tgtIndices,
Eigen::Matrix4f &transform)
{
Eigen::Vector3f srcCentroid, tgtCentroid;
// compute the centroids of source, target
ComputeCentroid (srcPts, srcIndices, srcCentroid);
ComputeCentroid (tgtPts, tgtIndices, tgtCentroid);
// Subtract the centroids from source, target
Eigen::MatrixXf srcPtsDemean;
DemeanPoints(srcPts, srcIndices, srcCentroid, srcPtsDemean);
Eigen::MatrixXf tgtPtsDemean;
DemeanPoints(tgtPts, tgtIndices, tgtCentroid, tgtPtsDemean);
// Assemble the correlation matrix H = source * target'
Eigen::Matrix3f H = (srcPtsDemean * tgtPtsDemean.transpose ()).topLeftCorner<3, 3>();
// Singular Value Decomposition
Eigen::JacobiSVD<Eigen::Matrix3f> svd (H, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::Matrix3f u = svd.matrixU ();
Eigen::Matrix3f v = svd.matrixV ();
// Compute R = V * U'
if (u.determinant () * v.determinant () < 0)
{
for (int x = 0; x < 3; ++x)
v (x, 2) *= -1;
}
// Return the transformation
Eigen::Matrix3f R = v * u.transpose ();
Eigen::Vector3f t = tgtCentroid - R * srcCentroid;
// set rotation
transform.block(0,0,3,3) = R;
// set translation
transform.block(0,3,3,1) = t;
transform.block(3, 0, 1, 3).setZero();
transform(3,3) = 1.;
}
示例7: demeanPointCloud
template <typename PointT> void
pcl::SampleConsensusModelRegistration<PointT>::estimateRigidTransformationSVD (
const pcl::PointCloud<PointT> &cloud_src,
const std::vector<int> &indices_src,
const pcl::PointCloud<PointT> &cloud_tgt,
const std::vector<int> &indices_tgt,
Eigen::VectorXf &transform)
{
transform.resize (16);
Eigen::Vector4f centroid_src, centroid_tgt;
// Estimate the centroids of source, target
compute3DCentroid (cloud_src, indices_src, centroid_src);
compute3DCentroid (cloud_tgt, indices_tgt, centroid_tgt);
// Subtract the centroids from source, target
Eigen::MatrixXf cloud_src_demean;
demeanPointCloud (cloud_src, indices_src, centroid_src, cloud_src_demean);
Eigen::MatrixXf cloud_tgt_demean;
demeanPointCloud (cloud_tgt, indices_tgt, centroid_tgt, cloud_tgt_demean);
// Assemble the correlation matrix H = source * target'
Eigen::Matrix3f H = (cloud_src_demean * cloud_tgt_demean.transpose ()).topLeftCorner<3, 3>();
// Compute the Singular Value Decomposition
Eigen::JacobiSVD<Eigen::Matrix3f> svd (H, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::Matrix3f u = svd.matrixU ();
Eigen::Matrix3f v = svd.matrixV ();
// Compute R = V * U'
if (u.determinant () * v.determinant () < 0)
{
for (int x = 0; x < 3; ++x)
v (x, 2) *= -1;
}
Eigen::Matrix3f R = v * u.transpose ();
// Return the correct transformation
transform.segment<3> (0) = R.row (0); transform[12] = 0;
transform.segment<3> (4) = R.row (1); transform[13] = 0;
transform.segment<3> (8) = R.row (2); transform[14] = 0;
Eigen::Vector3f t = centroid_tgt.head<3> () - R * centroid_src.head<3> ();
transform[3] = t[0]; transform[7] = t[1]; transform[11] = t[2]; transform[15] = 1.0;
}
示例8: main
int main() {
std::ifstream file;
file.open("SVD_benchmark");
if (!file)
{
CGAL_TRACE_STREAM << "Error loading file!\n";
return 0;
}
int ite = 200000;
Eigen::JacobiSVD<Eigen::Matrix3d> svd;
Eigen::Matrix3d u, v, cov, r;
Eigen::Vector3d w;
int matrix_idx = rand()%200;
for (int i = 0; i < matrix_idx; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
file >> cov(j, k);
}
}
}
CGAL::Timer task_timer;
CGAL_TRACE_STREAM << "Start SVD decomposition...";
task_timer.start();
for (int i = 0; i < ite; i++)
{
svd.compute( cov, Eigen::ComputeFullU | Eigen::ComputeFullV );
u = svd.matrixU(); v = svd.matrixV(); w = svd.singularValues();
r = v*u.transpose();
}
task_timer.stop();
file.close();
CGAL_TRACE_STREAM << "done: " << task_timer.time() << "s\n";
return 0;
}
示例9: pinv
// Derived from code by Yohann Solaro ( http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/01/msg00187.html )
// see : http://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse#The_general_case_and_the_SVD_method
Eigen::MatrixXd pinv( const Eigen::MatrixXd &b, double rcond )
{
// TODO: Figure out why it wants fewer rows than columns
// if ( a.rows()<a.cols() )
// return false;
bool flip = false;
Eigen::MatrixXd a;
if( a.rows() < a.cols() )
{
a = b.transpose();
flip = true;
}
else
a = b;
// SVD
Eigen::JacobiSVD<Eigen::MatrixXd> svdA;
svdA.compute( a, Eigen::ComputeFullU | Eigen::ComputeThinV );
Eigen::JacobiSVD<Eigen::MatrixXd>::SingularValuesType vSingular = svdA.singularValues();
// Build a diagonal matrix with the Inverted Singular values
// The pseudo inverted singular matrix is easy to compute :
// is formed by replacing every nonzero entry by its reciprocal (inversing).
Eigen::VectorXd vPseudoInvertedSingular( svdA.matrixV().cols() );
for (int iRow=0; iRow<vSingular.rows(); iRow++)
{
if ( fabs(vSingular(iRow)) <= rcond )
{
vPseudoInvertedSingular(iRow)=0.;
}
else
vPseudoInvertedSingular(iRow)=1./vSingular(iRow);
}
// A little optimization here
Eigen::MatrixXd mAdjointU = svdA.matrixU().adjoint().block( 0, 0, vSingular.rows(), svdA.matrixU().adjoint().cols() );
// Pseudo-Inversion : V * S * U'
Eigen::MatrixXd a_pinv = (svdA.matrixV() * vPseudoInvertedSingular.asDiagonal()) * mAdjointU;
if( flip )
{
a = a.transpose();
a_pinv = a_pinv.transpose();
}
return a_pinv;
}
示例10: pseudoInverse
bool pseudoInverse(
const _Matrix_Type_ &a, _Matrix_Type_ &result,
double epsilon =
std::numeric_limits<typename _Matrix_Type_::Scalar>::epsilon()) {
if (a.rows() < a.cols())
return false;
Eigen::JacobiSVD<_Matrix_Type_> svd = a.jacobiSvd();
typename _Matrix_Type_::Scalar tolerance =
epsilon * std::max(a.cols(), a.rows()) *
svd.singularValues().array().abs().maxCoeff();
result = svd.matrixV() *
_Matrix_Type_(
_Matrix_Type_((svd.singularValues().array().abs() > tolerance)
.select(svd.singularValues().array().inverse(),
0)).diagonal()) *
svd.matrixU().adjoint();
}
示例11: svd
inline Eigen::Affine3f
pcl::TransformationFromCorrespondences::getTransformation ()
{
//Eigen::JacobiSVD<Eigen::Matrix<float, 3, 3> > svd (covariance_, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::JacobiSVD<Eigen::Matrix<float, 3, 3> > svd (covariance_, Eigen::ComputeFullU | Eigen::ComputeFullV);
const Eigen::Matrix<float, 3, 3>& u = svd.matrixU(),
& v = svd.matrixV();
Eigen::Matrix<float, 3, 3> s;
s.setIdentity();
if (u.determinant()*v.determinant() < 0.0f)
s(2,2) = -1.0f;
Eigen::Matrix<float, 3, 3> r = u * s * v.transpose();
Eigen::Vector3f t = mean2_ - r*mean1_;
Eigen::Affine3f ret;
ret(0,0)=r(0,0); ret(0,1)=r(0,1); ret(0,2)=r(0,2); ret(0,3)=t(0);
ret(1,0)=r(1,0); ret(1,1)=r(1,1); ret(1,2)=r(1,2); ret(1,3)=t(1);
ret(2,0)=r(2,0); ret(2,1)=r(2,1); ret(2,2)=r(2,2); ret(2,3)=t(2);
ret(3,0)=0.0f; ret(3,1)=0.0f; ret(3,2)=0.0f; ret(3,3)=1.0f;
return (ret);
}
示例12: pseudo_inverse_svd
// typename DerivedA::Scalar
void pseudo_inverse_svd(const Eigen::MatrixBase<DerivedA>& M,
Eigen::MatrixBase<OutputMatrixType>& Minv,
typename DerivedA::Scalar epsilon = 1e-6)//std::numeric_limits<typename DerivedA::Scalar>::epsilon())
{
// CONTROLIT_INFO << "Method called!\n epsilon = " << epsilon << ", M = \n" << M;
// Ensure matrix Minv has the correct size. Its size should be equal to M.transpose().
assert_msg(M.rows() == Minv.cols(), "Minv has invalid number of columns. Expected " << M.rows() << " got " << Minv.cols());
assert_msg(M.cols() == Minv.rows(), "Minv has invalid number of rows. Expected " << M.cols() << " got " << Minv.rows());
// According to Eigen documentation, "If the input matrix has inf or nan coefficients, the result of the
// computation is undefined, but the computation is guaranteed to terminate in finite (and reasonable) time."
Eigen::JacobiSVD<DerivedA> svd = M.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
// Get the max singular value
typename DerivedA::Scalar maxSingularValue = svd.singularValues().array().abs().maxCoeff();
// Use Minv to temporarily hold sigma
Minv.setZero();
typename DerivedA::Scalar tolerance = 0;
// Only compute sigma if the max singular value is greater than zero.
if (maxSingularValue > epsilon)
{
tolerance = epsilon * std::max(M.cols(), M.rows()) * maxSingularValue;
// For each singular value of matrix M's SVD decomposition, check if it is greater than
// the tolerance value. If it is, save 1/(singular value) in the sigma vector.
// Otherwise save zero in the sigma vector.
DerivedA sigmaVector = DerivedA( (svd.singularValues().array().abs() > tolerance).select(svd.singularValues().array().inverse(), 0) );
// DerivedA zeroSVs = DerivedA( (svd.singularValues().array().abs() <= tolerance).select(svd.singularValues().array().inverse(), 0) );
// CONTROLIT_INFO << "epsilon: " << epsilon << ", std::max(M.cols(), M.rows()): " << std::max(M.cols(), M.rows()) << ", maxSingularValue: " << maxSingularValue << ", tolerance: " << tolerance;
// CONTROLIT_INFO << "sigmaVector = " << sigmaVector.transpose();
// CONTROLIT_INFO << "zeroSigmaVector : "<< zeroSVs.transpose();
Minv.block(0, 0, sigmaVector.rows(), sigmaVector.rows()) = sigmaVector.asDiagonal();
}
// Double check to make sure the matrices have the correct dimensions
assert_msg(svd.matrixV().cols() == Minv.rows(),
"Matrix dimension mismatch, svd.matrixV().cols() = " << svd.matrixV().cols() << ", Minv.rows() = " << Minv.rows() << ".");
assert_msg(Minv.cols() == svd.matrixU().adjoint().rows(),
"Matrix dimension mismatch, Minv.cols() = " << Minv.cols() << ", svd.matrixU().adjoint().rows() = " << svd.matrixU().adjoint().rows() << ".");
Minv = svd.matrixV() *
Minv *
svd.matrixU().adjoint(); // take the transpose of matrix U
// CONTROLIT_INFO << "Done method call! Minv = " << Minv;
// typename DerivedA::Scalar errorNorm = std::abs((M * Minv - DerivedA::Identity(M.rows(), Minv.cols())).norm());
// if (tolerance != 0 && errorNorm > tolerance * 10)
// {
// CONTROLIT_WARN << "Problems computing pseudoinverse. Perhaps the tolerance is too high?\n"
// << " - epsilon: " << epsilon << "\n"
// << " - tolerance: " << tolerance << "\n"
// << " - maxSingularValue: " << maxSingularValue << "\n"
// << " - errorNorm: " << errorNorm << "\n"
// << " - M:\n" << M << "\n"
// << " - Minv:\n" << Minv;
// }
// return errorNorm;
}
示例13: min_quad_dense_precompute
IGL_INLINE void igl::min_quad_dense_precompute(
const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& A,
const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& Aeq,
const bool use_lu_decomposition,
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& S)
{
typedef Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> Mat;
// This threshold seems to matter a lot but I'm not sure how to
// set it
const T treshold = igl::FLOAT_EPS;
//const T treshold = igl::DOUBLE_EPS;
const int n = A.rows();
assert(A.cols() == n);
const int m = Aeq.rows();
assert(Aeq.cols() == n);
// Lagrange multipliers method:
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> LM(n + m, n + m);
LM.block(0, 0, n, n) = A;
LM.block(0, n, n, m) = Aeq.transpose();
LM.block(n, 0, m, n) = Aeq;
LM.block(n, n, m, m).setZero();
Mat LMpinv;
if(use_lu_decomposition)
{
// if LM is close to singular, use at your own risk :)
LMpinv = LM.inverse();
}else
{
// use SVD
typedef Eigen::Matrix<T, Eigen::Dynamic, 1> Vec;
Vec singValues;
Eigen::JacobiSVD<Mat> svd;
svd.compute(LM, Eigen::ComputeFullU | Eigen::ComputeFullV );
const Mat& u = svd.matrixU();
const Mat& v = svd.matrixV();
const Vec& singVals = svd.singularValues();
Vec pi_singVals(n + m);
int zeroed = 0;
for (int i=0; i<n + m; i++)
{
T sv = singVals(i, 0);
assert(sv >= 0);
// printf("sv: %lg ? %lg\n",(double) sv,(double)treshold);
if (sv > treshold) pi_singVals(i, 0) = T(1) / sv;
else
{
pi_singVals(i, 0) = T(0);
zeroed++;
}
}
printf("min_quad_dense_precompute: %i singular values zeroed (threshold = %e)\n", zeroed, treshold);
Eigen::DiagonalMatrix<T, Eigen::Dynamic> pi_diag(pi_singVals);
LMpinv = v * pi_diag * u.transpose();
}
S = LMpinv.block(0, 0, n, n + m);
//// debug:
//mlinit(&g_pEngine);
//
//mlsetmatrix(&g_pEngine, "A", A);
//mlsetmatrix(&g_pEngine, "Aeq", Aeq);
//mlsetmatrix(&g_pEngine, "LM", LM);
//mlsetmatrix(&g_pEngine, "u", u);
//mlsetmatrix(&g_pEngine, "v", v);
//MatrixXd svMat = singVals;
//mlsetmatrix(&g_pEngine, "singVals", svMat);
//mlsetmatrix(&g_pEngine, "LMpinv", LMpinv);
//mlsetmatrix(&g_pEngine, "S", S);
//int hu = 1;
}
示例14: solveGasSubclass
//.........这里部分代码省略.........
}
/// STEP #4: Compute new grid velocities
//Temporary variables for plasticity and force calculation
//We need one set of variables for each thread that will be running
eigen_matrix3 def_elastic, def_plastic, energy, svd_u, svd_v;
Eigen::JacobiSVD<eigen_matrix3, Eigen::NoQRPreconditioner> svd;
eigen_vector3 svd_e;
matrix3 HDK_def_plastic, HDK_def_elastic, HDK_energy;
freal* data_dp = HDK_def_plastic.data();
freal* data_de = HDK_def_elastic.data();
freal* data_energy = HDK_energy.data();
//Map Eigen matrices to HDK matrices
Eigen::Map<eigen_matrix3> data_dp_map(data_dp);
Eigen::Map<eigen_matrix3> data_de_map(data_de);
Eigen::Map<eigen_matrix3> data_energy_map(data_energy);
//Compute force at each particle and transfer to Eulerian grid
//We use "nvel" to hold the grid force, since that variable is not in use
for (GA_Iterator it(gdp_in->getPointRange()); !it.atEnd(); it.advance()){
int pid = it.getOffset();
//Apply plasticity to deformation gradient, before computing forces
//We need to use the Eigen lib to do the SVD; transfer houdini matrices to Eigen matrices
HDK_def_plastic = p_Fp.get(pid);
HDK_def_elastic = p_Fe.get(pid);
def_plastic = Eigen::Map<eigen_matrix3>(data_dp);
def_elastic = Eigen::Map<eigen_matrix3>(data_de);
//Compute singular value decomposition (uev*)
svd.compute(def_elastic, Eigen::ComputeFullV | Eigen::ComputeFullU);
svd_e = svd.singularValues();
svd_u = svd.matrixU();
svd_v = svd.matrixV();
//Clamp singular values
for (int i=0; i<3; i++){
if (svd_e[i] < CRIT_COMPRESS)
svd_e[i] = CRIT_COMPRESS;
else if (svd_e[i] > CRIT_STRETCH)
svd_e[i] = CRIT_STRETCH;
}
//Put SVD back together for new elastic and plastic gradients
def_plastic = svd_v * svd_e.asDiagonal().inverse() * svd_u.transpose() * def_elastic * def_plastic;
svd_v.transposeInPlace();
def_elastic = svd_u * svd_e.asDiagonal() * svd_v;
//Now compute the energy partial derivative (which we use to get force at each grid node)
energy = 2*mu*(def_elastic - svd_u*svd_v)*def_elastic.transpose();
//Je is the determinant of def_elastic (equivalent to svd_e.prod())
freal Je = svd_e.prod(),
contour = lambda*Je*(Je-1),
jp = def_plastic.determinant(),
particle_vol = p_volume.get(pid);
for (int i=0; i<3; i++)
energy(i,i) += contour;
energy *= particle_vol * exp(HARDENING*(1-jp));
//Transfer Eigen matrices back to HDK
data_dp_map = def_plastic;
data_de_map = def_elastic;
data_energy_map = energy;
p_Fp.set(pid,HDK_def_plastic);
p_Fe.set(pid,HDK_def_elastic);
示例15: estimateTransform
Types::Transform PlaneToPlaneCalibration::estimateTransform(const std::vector<PlanePair> & plane_pair_vector)
{
const int size = plane_pair_vector.size();
Eigen::MatrixXd normals_1(3, size);
Eigen::MatrixXd normals_2(3, size);
Eigen::VectorXd distances_1(size);
Eigen::VectorXd distances_2(size);
for (int i = 0; i < size; ++i)
{
const Types::Plane &plane_1 = plane_pair_vector[i].plane_1_;
const Types::Plane &plane_2 = plane_pair_vector[i].plane_2_;
if (plane_1.offset() > 0)
{
normals_1.col(i) = -plane_1.normal();
distances_1(i) = plane_1.offset();
}
else
{
normals_1.col(i) = plane_1.normal();
distances_1(i) = -plane_1.offset();
}
if (plane_2.offset() > 0)
{
normals_2.col(i) = -plane_2.normal();
distances_2(i) = plane_2.offset();
}
else
{
normals_2.col(i) = plane_2.normal();
distances_2(i) = -plane_2.offset();
}
}
// std::cout << normals_1 << std::endl;
// std::cout << distances_1.transpose() << std::endl;
// std::cout << normals_2 << std::endl;
// std::cout << distances_2.transpose() << std::endl;
Eigen::Matrix3d USV = normals_2 * normals_1.transpose();
Eigen::JacobiSVD<Eigen::Matrix3d> svd;
svd.compute(USV, Eigen::ComputeFullU | Eigen::ComputeFullV);
Types::Pose pose;
pose.translation() = (normals_1 * normals_1.transpose()).inverse() * normals_1 * (distances_1 - distances_2);
pose.linear() = svd.matrixV() * svd.matrixU().transpose();
// // Point-Plane Constraints
//
// // Initial system (Eq. 10)
//
// Eigen::MatrixXd system(size * 3, 13);
// for (int i = 0; i < size; ++i)
// {
// const double d = plane_pair_vector[i].plane_1_.offset();
// const Eigen::Vector3d n = plane_pair_vector[i].plane_1_.normal();
//
// const Point3d x = -plane_pair_vector[i].plane_2_.normal() * plane_pair_vector[i].plane_2_.offset();
//
// Eigen::Matrix3d X(Eigen::Matrix3d::Random());
// while (X.determinant() < 1e-5)
// X = Eigen::Matrix3d::Random();
//
// const Eigen::Vector3d & n2 = plane_pair_vector[i].plane_2_.normal();
//// X.col(1)[2] = -n2.head<2>().dot(X.col(1).head<2>()) / n2[2];
//// X.col(2)[2] = -n2.head<2>().dot(X.col(2).head<2>()) / n2[2];
// X.col(1) -= n2 * n2.dot(X.col(1));
// X.col(2) -= n2 * n2.dot(X.col(2));
//
// X.col(0) = x;
// X.col(1) += x;
// X.col(2) += x;
//
// for (int j = 0; j < 3; ++j)
// {
// const Point3d & x = X.col(j);
//
// system.row(i + size * j) << d + n[0] * x[0] + n[1] * x[1] + n[2] * x[2], // q_0^2
// 2 * n[2] * x[1] - 2 * n[1] * x[2], // q_0 * q_1
// 2 * n[0] * x[2] - 2 * n[2] * x[0], // q_0 * q_2
// 2 * n[1] * x[0] - 2 * n[0] * x[1], // q_0 * q_3
// d + n[0] * x[0] - n[1] * x[1] - n[2] * x[2], // q_1^2
// 2 * n[0] * x[1] + 2 * n[1] * x[0], // q_1 * q_2
// 2 * n[0] * x[2] + 2 * n[2] * x[0], // q_1 * q_3
// d - n[0] * x[0] + n[1] * x[1] - n[2] * x[2], // q_2^2
// 2 * n[1] * x[2] + 2 * n[2] * x[1], // q_2 * q_3
// d - n[0] * x[0] - n[1] * x[1] + n[2] * x[2], // q_3^2
// n[0], n[1], n[2]; // q'*q*t
// }
// }
//
// //std::cout << system << std::endl;
//
// // Gaussian reduction
// for (int k = 0; k < 3; ++k)
// for (int i = k + 1; i < size * 3; ++i)
// system.row(i) = system.row(i) - system.row(k) * system.row(i)[10 + k] / system.row(k)[10 + k];
//.........这里部分代码省略.........