fix #1 : need to nest by value the affine part in homogeneous product

This commit is contained in:
Gael Guennebaud 2009-05-18 17:55:50 +02:00
parent e0832d5d93
commit e186728867
4 changed files with 31 additions and 16 deletions

View File

@ -102,11 +102,11 @@ template<typename MatrixType,int Direction> class Homogeneous
template<typename Scalar, int Dim, int Mode> friend template<typename Scalar, int Dim, int Mode> friend
inline const ei_homogeneous_left_product_impl<Homogeneous, inline const ei_homogeneous_left_product_impl<Homogeneous,
typename Transform<Scalar,Dim,Mode>::AffinePart> typename Transform<Scalar,Dim,Mode>::AffinePartNested>
operator* (const Transform<Scalar,Dim,Mode>& tr, const Homogeneous& rhs) operator* (const Transform<Scalar,Dim,Mode>& tr, const Homogeneous& rhs)
{ {
ei_assert(Direction==Vertical); ei_assert(Direction==Vertical);
return ei_homogeneous_left_product_impl<Homogeneous,typename Transform<Scalar,Dim,Mode>::AffinePart> return ei_homogeneous_left_product_impl<Homogeneous,typename Transform<Scalar,Dim,Mode>::AffinePartNested >
(tr.affine(),rhs.m_matrix); (tr.affine(),rhs.m_matrix);
} }

View File

@ -184,6 +184,10 @@ public:
typedef typename ei_meta_if<int(Mode)==int(AffineCompact), typedef typename ei_meta_if<int(Mode)==int(AffineCompact),
MatrixType&, MatrixType&,
Block<MatrixType,Dim,HDim> >::ret AffinePart; Block<MatrixType,Dim,HDim> >::ret AffinePart;
/** type of read/write reference to the affine part of the transformation */
typedef typename ei_meta_if<int(Mode)==int(AffineCompact),
MatrixType&,
NestByValue<Block<MatrixType,Dim,HDim> > >::ret AffinePartNested;
/** type of a vector */ /** type of a vector */
typedef Matrix<Scalar,Dim,1> VectorType; typedef Matrix<Scalar,Dim,1> VectorType;
/** type of a read/write reference to the translation part of the rotation */ /** type of a read/write reference to the translation part of the rotation */

View File

@ -33,10 +33,10 @@ template<typename Scalar,int Size> void homogeneous(void)
typedef Matrix<Scalar,Size,Size> MatrixType; typedef Matrix<Scalar,Size,Size> MatrixType;
typedef Matrix<Scalar,Size,1> VectorType; typedef Matrix<Scalar,Size,1> VectorType;
typedef Matrix<Scalar,Size+1,Size> HMatrixType; typedef Matrix<Scalar,Size+1,Size> HMatrixType;
typedef Matrix<Scalar,Size+1,1> HVectorType; typedef Matrix<Scalar,Size+1,1> HVectorType;
typedef Matrix<Scalar,Size,Size+1> T1MatrixType; typedef Matrix<Scalar,Size,Size+1> T1MatrixType;
typedef Matrix<Scalar,Size+1,Size+1> T2MatrixType; typedef Matrix<Scalar,Size+1,Size+1> T2MatrixType;
typedef Matrix<Scalar,Size+1,Size> T3MatrixType; typedef Matrix<Scalar,Size+1,Size> T3MatrixType;
@ -51,17 +51,17 @@ template<typename Scalar,int Size> void homogeneous(void)
HVectorType hv0 = HVectorType::Random(), HVectorType hv0 = HVectorType::Random(),
hv1 = HVectorType::Random(); hv1 = HVectorType::Random();
MatrixType m0 = MatrixType::Random(), MatrixType m0 = MatrixType::Random(),
m1 = MatrixType::Random(); m1 = MatrixType::Random();
HMatrixType hm0 = HMatrixType::Random(), HMatrixType hm0 = HMatrixType::Random(),
hm1 = HMatrixType::Random(); hm1 = HMatrixType::Random();
hv0 << v0, 1; hv0 << v0, 1;
VERIFY_IS_APPROX(v0.homogeneous(), hv0); VERIFY_IS_APPROX(v0.homogeneous(), hv0);
VERIFY_IS_APPROX(v0, hv0.hnormalized()); VERIFY_IS_APPROX(v0, hv0.hnormalized());
hm0 << m0, ones.transpose(); hm0 << m0, ones.transpose();
VERIFY_IS_APPROX(m0.colwise().homogeneous(), hm0); VERIFY_IS_APPROX(m0.colwise().homogeneous(), hm0);
VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized()); VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());
@ -69,16 +69,16 @@ template<typename Scalar,int Size> void homogeneous(void)
for(int j=0; j<Size; ++j) for(int j=0; j<Size; ++j)
m0.col(j) = hm0.col(j).start(Size) / hm0(Size,j); m0.col(j) = hm0.col(j).start(Size) / hm0(Size,j);
VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized()); VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());
T1MatrixType t1 = T1MatrixType::Random(); T1MatrixType t1 = T1MatrixType::Random();
VERIFY_IS_APPROX(t1 * (v0.homogeneous().eval()), t1 * v0.homogeneous()); VERIFY_IS_APPROX(t1 * (v0.homogeneous().eval()), t1 * v0.homogeneous());
VERIFY_IS_APPROX(t1 * (m0.colwise().homogeneous().eval()), t1 * m0.colwise().homogeneous()); VERIFY_IS_APPROX(t1 * (m0.colwise().homogeneous().eval()), t1 * m0.colwise().homogeneous());
T2MatrixType t2 = T2MatrixType::Random(); T2MatrixType t2 = T2MatrixType::Random();
VERIFY_IS_APPROX(t2 * (v0.homogeneous().eval()), t2 * v0.homogeneous()); VERIFY_IS_APPROX(t2 * (v0.homogeneous().eval()), t2 * v0.homogeneous());
VERIFY_IS_APPROX(t2 * (m0.colwise().homogeneous().eval()), t2 * m0.colwise().homogeneous()); VERIFY_IS_APPROX(t2 * (m0.colwise().homogeneous().eval()), t2 * m0.colwise().homogeneous());
VERIFY_IS_APPROX((v0.transpose().rowwise().homogeneous().eval()) * t2, VERIFY_IS_APPROX((v0.transpose().rowwise().homogeneous().eval()) * t2,
v0.transpose().rowwise().homogeneous() * t2); v0.transpose().rowwise().homogeneous() * t2);
VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t2, VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t2,
m0.transpose().rowwise().homogeneous() * t2); m0.transpose().rowwise().homogeneous() * t2);
@ -88,6 +88,17 @@ template<typename Scalar,int Size> void homogeneous(void)
v0.transpose().rowwise().homogeneous() * t3); v0.transpose().rowwise().homogeneous() * t3);
VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t3, VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t3,
m0.transpose().rowwise().homogeneous() * t3); m0.transpose().rowwise().homogeneous() * t3);
// test product with a Transform object
Transform<Scalar, Size, Affine> Rt;
Matrix<Scalar, Size, Dynamic> pts, Rt_pts1;
Rt.setIdentity();
pts.setRandom(Size,5);
Rt_pts1 = Rt * pts.colwise().homogeneous();
std::cerr << (Rt_pts1 - pts).sum() << "\n";
VERIFY_IS_MUCH_SMALLER_THAN( (Rt_pts1 - pts).sum(), Scalar(1));
} }
void test_geo_homogeneous() void test_geo_homogeneous()

View File

@ -72,12 +72,12 @@ template<typename Scalar> void sparse_solvers(int rows, int cols)
initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords); initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);
VERIFY_IS_APPROX(refMat2.template marked<UpperTriangular>().solveTriangular(vec2), VERIFY_IS_APPROX(refMat2.template marked<UpperTriangular>().solveTriangular(vec2),
m2.template triangular<UpperTriangular>().solve(vec3)); m2.template triangular<UpperTriangular>().solve(vec3));
// TODO test row major // TODO test row major
SparseMatrix<Scalar> matB(rows, rows); SparseMatrix<Scalar> matB(rows, rows);
DenseMatrix refMatB = DenseMatrix::Zero(rows, rows); DenseMatrix refMatB = DenseMatrix::Zero(rows, rows);
// lower - sparse // lower - sparse
initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular); initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular);
initSparse<Scalar>(density, refMatB, matB); initSparse<Scalar>(density, refMatB, matB);
@ -91,7 +91,7 @@ template<typename Scalar> void sparse_solvers(int rows, int cols)
refMat2.template marked<UpperTriangular>().solveTriangularInPlace(refMatB); refMat2.template marked<UpperTriangular>().solveTriangularInPlace(refMatB);
m2.template triangular<UpperTriangular>().solveInPlace(matB); m2.template triangular<UpperTriangular>().solveInPlace(matB);
VERIFY_IS_APPROX(matB, refMatB); VERIFY_IS_APPROX(matB, refMatB);
// test deprecated API // test deprecated API
initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords); initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);
VERIFY_IS_APPROX(refMat2.template marked<LowerTriangular>().solveTriangular(vec2), VERIFY_IS_APPROX(refMat2.template marked<LowerTriangular>().solveTriangular(vec2),
@ -122,7 +122,7 @@ template<typename Scalar> void sparse_solvers(int rows, int cols)
SparseLLT<SparseSelfAdjointMatrix,Cholmod>(m2).solveInPlace(x); SparseLLT<SparseSelfAdjointMatrix,Cholmod>(m2).solveInPlace(x);
VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: cholmod"); VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: cholmod");
#endif #endif
#ifdef EIGEN_TAUCS_SUPPORT #ifdef EIGEN_TAUCS_SUPPORT
x = b; x = b;
SparseLLT<SparseSelfAdjointMatrix,Taucs>(m2,IncompleteFactorization).solveInPlace(x); SparseLLT<SparseSelfAdjointMatrix,Taucs>(m2,IncompleteFactorization).solveInPlace(x);