- many updates after Cwise change

- fix compilation in product.cpp with std::complex
- fix bug in MatrixBase::operator!=
This commit is contained in:
Benoit Jacob 2008-07-08 07:56:01 +00:00
parent f5791eeb70
commit 6f09d3a67d
21 changed files with 40 additions and 56 deletions

View File

@ -50,7 +50,7 @@ struct ei_functor_traits<ei_scalar_add_op<Scalar> >
*
* \brief Template functor to compute the square root of a scalar
*
* \sa class CwiseUnaryOp, MatrixBase::cwiseSqrt()
* \sa class CwiseUnaryOp, Cwise::sqrt()
*/
template<typename Scalar> struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
@ -65,7 +65,7 @@ struct ei_functor_traits<ei_scalar_sqrt_op<Scalar> >
*
* \brief Template functor to compute the exponential of a scalar
*
* \sa class CwiseUnaryOp, MatrixBase::cwiseExp()
* \sa class CwiseUnaryOp, Cwise::exp()
*/
template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
@ -80,7 +80,7 @@ struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
*
* \brief Template functor to compute the logarithm of a scalar
*
* \sa class CwiseUnaryOp, MatrixBase::cwiseLog()
* \sa class CwiseUnaryOp, Cwise::log()
*/
template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
@ -95,7 +95,7 @@ struct ei_functor_traits<ei_scalar_log_op<Scalar> >
*
* \brief Template functor to compute the cosine of a scalar
*
* \sa class CwiseUnaryOp, MatrixBase::cwiseCos()
* \sa class CwiseUnaryOp, Cwise::cos()
*/
template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_cos(a); }
@ -110,7 +110,7 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
*
* \brief Template functor to compute the sine of a scalar
*
* \sa class CwiseUnaryOp, MatrixBase::cwiseSin()
* \sa class CwiseUnaryOp, Cwise::sin()
*/
template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
@ -125,7 +125,7 @@ struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
*
* \brief Template functor to raise a scalar to a power
*
* \sa class CwiseUnaryOp, MatrixBase::cwisePow
* \sa class CwiseUnaryOp, Cwise::pow
*/
template<typename Scalar>
struct ei_scalar_pow_op {

View File

@ -35,7 +35,7 @@
* \param Rhs the type of the right-hand side
*
* This class represents an expression of a generic binary operator of two matrices or vectors.
* It is the return type of the operator+, operator-, cwiseProduct, cwiseQuotient between matrices or vectors, and most
* It is the return type of the operator+, operator-, and the Cwise methods, and most
* of the time this is the only way it is used.
*
* However, if you want to write a function returning such an expression, you
@ -232,7 +232,7 @@ Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const
* \include class_CwiseBinaryOp.cpp
* Output: \verbinclude class_CwiseBinaryOp.out
*
* \sa class CwiseBinaryOp, MatrixBase::operator+, MatrixBase::operator-, MatrixBase::cwiseProduct, MatrixBase::cwiseQuotient
* \sa class CwiseBinaryOp, MatrixBase::operator+, MatrixBase::operator-, Cwise::operator*, Cwise::operator/
*/
template<typename Derived>
template<typename CustomBinaryOp, typename OtherDerived>

View File

@ -113,7 +113,7 @@ class CwiseUnaryOp : ei_no_assignment_operator,
* \include class_CwiseUnaryOp.cpp
* Output: \verbinclude class_CwiseUnaryOp.out
*
* \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, MatrixBase::cwiseAbs
* \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs
*/
template<typename Derived>
template<typename CustomUnaryOp>

View File

@ -49,7 +49,7 @@ struct ei_functor_traits<ei_scalar_sum_op<Scalar> > {
/** \internal
* \brief Template functor to compute the product of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseProduct(), class PartialRedux, MatrixBase::redux()
* \sa class CwiseBinaryOp, Cwise::operator*(), class PartialRedux, MatrixBase::redux()
*/
template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
@ -128,7 +128,7 @@ struct ei_functor_traits<ei_scalar_difference_op<Scalar> > {
/** \internal
* \brief Template functor to compute the quotient of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseQuotient()
* \sa class CwiseBinaryOp, Cwise::operator/()
*/
template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
@ -161,7 +161,7 @@ struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
/** \internal
* \brief Template functor to compute the absolute value of a scalar
*
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs
* \sa class CwiseUnaryOp, Cwise::abs
*/
template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
typedef typename NumTraits<Scalar>::Real result_type;
@ -179,7 +179,7 @@ struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
/** \internal
* \brief Template functor to compute the squared absolute value of a scalar
*
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs2
* \sa class CwiseUnaryOp, Cwise::abs2
*/
template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
typedef typename NumTraits<Scalar>::Real result_type;

View File

@ -30,7 +30,8 @@
* \brief Base class for all matrices, vectors, and expressions
*
* This class is the base that is inherited by all matrix, vector, and expression
* types. Most of the Eigen API is contained in this class.
* types. Most of the Eigen API is contained in this class. Other important classes for
* the Eigen API are Matrix, Cwise, and Part.
*
* \param Derived is the derived type, e.g. a matrix type, or an expression, etc.
*
@ -422,11 +423,11 @@ template<typename Derived> class MatrixBase
template<typename OtherDerived>
inline bool operator==(const MatrixBase<OtherDerived>& other) const
{ return derived().cwiseEqualTo(other.derived()).all(); }
{ return (cwise() == other).all(); }
template<typename OtherDerived>
inline bool operator!=(const MatrixBase<OtherDerived>& other) const
{ return derived().cwiseNotEqualTo(other.derived()).all(); }
{ return (cwise() != other).any(); }
template<typename NewType>

View File

@ -120,8 +120,8 @@ template<typename Scalar>
typename EulerAngles<Scalar>::Matrix3
EulerAngles<Scalar>::toRotationMatrix(void) const
{
Vector3 c = m_angles.cwiseCos();
Vector3 s = m_angles.cwiseSin();
Vector3 c = m_angles.cwise().cos();
Vector3 s = m_angles.cwise().sin();
return Matrix3() <<
c.y()*c.z(), -c.y()*s.z(), s.y(),
c.z()*s.x()*s.y()+c.x()*s.z(), c.x()*c.z()-s.x()*s.y()*s.z(), -c.y()*s.x(),

View File

@ -356,8 +356,8 @@ template<typename Scalar, int Dim>
typename Transform<Scalar,Dim>::AffineMatrixType
Transform<Scalar,Dim>::extractRotationNoShear() const
{
return affine().cwiseAbs2()
.verticalRedux(ei_scalar_sum_op<Scalar>()).cwiseSqrt();
return affine().cwise().abs2()
.verticalRedux(ei_scalar_sum_op<Scalar>()).cwise().sqrt();
}
/** Convenient method to set \c *this from a position, orientation and scale

View File

@ -105,7 +105,7 @@ void EigenSolver<MatrixType>::orthes(MatrixType& matH, RealVectorType& ort)
for (int m = low+1; m <= high-1; m++)
{
// Scale column.
Scalar scale = matH.block(m, m-1, high-m+1, 1).cwiseAbs().sum();
Scalar scale = matH.block(m, m-1, high-m+1, 1).cwise().abs().sum();
if (scale != 0.0)
{
// Compute Householder transformation.
@ -193,7 +193,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
// Store roots isolated by balanc and compute matrix norm
// FIXME to be efficient the following would requires a triangular reduxion code
// Scalar norm = matH.upper().cwiseAbs().sum() + matH.corner(BottomLeft,n,n).diagonal().cwiseAbs().sum();
// Scalar norm = matH.upper().cwise().abs().sum() + matH.corner(BottomLeft,n,n).diagonal().cwise().abs().sum();
Scalar norm = 0.0;
for (int j = 0; j < nn; j++)
{
@ -203,7 +203,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
m_eivalues.coeffRef(j).real() = matH.coeff(j,j);
m_eivalues.coeffRef(j).imag() = 0.0;
}
norm += matH.col(j).start(std::min(j+1,nn)).cwiseAbs().sum();
norm += matH.col(j).start(std::min(j+1,nn)).cwise().abs().sum();
}
// Outer loop over eigenvalue index

View File

@ -54,7 +54,7 @@ template<typename MatrixType> class QR
}
/** \returns whether or not the matrix is of full rank */
bool isFullRank() const { return ei_isMuchSmallerThan(m_hCoeffs.cwiseAbs().minCoeff(), Scalar(1)); }
bool isFullRank() const { return ei_isMuchSmallerThan(m_hCoeffs.cwise().abs().minCoeff(), Scalar(1)); }
/** \returns a read-only expression of the matrix R of the actual the QR decomposition */
const Extract<NestByValue<MatrixRBlockType>, Upper>

View File

@ -251,7 +251,7 @@ struct ei_matrixNorm_selector
{
// FIXME if it is really guaranteed that the eigenvalues are already sorted,
// then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
return m.eigenvalues().cwiseAbs().maxCoeff();
return m.eigenvalues().cwise().abs().maxCoeff();
}
};

View File

@ -27,7 +27,7 @@ int main(int argc, char *argv[])
}
for(int a = 0; a < REPEAT; a++)
{
m = VECTYPE::ones(VECSIZE) + 0.00005 * (m.cwiseProduct(m) + m/4);
m = VECTYPE::ones(VECSIZE) + 0.00005 * (m.cwise().square() + m/4);
}
cout << m[0] << endl;
return 0;

View File

@ -87,13 +87,13 @@ template<typename Real> void MandelbrotThread::render(int img_width, int img_hei
{
# define ITERATE \
pzr_buf = pzr; \
pzr = pzr.cwiseAbs2() - pzi.cwiseAbs2() + pcr; \
pzi = 2 * pzr_buf.cwiseProduct(pzi) + pci;
pzr = pzr.cwise().square() - pzi.cwise().square() + pcr; \
pzi = (2*pzr_buf).cwise()*pzi + pci;
ITERATE ITERATE ITERATE ITERATE
}
pix_dont_diverge = (pzr.cwiseAbs2() + pzi.cwiseAbs2())
pix_dont_diverge = ((pzr.cwise().square() + pzi.cwise().square())
.eval() // temporary fix as what follows is not yet vectorized by Eigen
.cwiseLessThan(Packet::constant(4))
.cwise() <= Packet::constant(4))
// the 4 here is not a magic value, it's a math fact that if
// the square modulus is >4 then divergence is inevitable.
.template cast<int>();

View File

@ -4,11 +4,11 @@ o /** \mainpage Eigen
This is the API documentation for Eigen.
Most of the API is available as methods in MatrixBase, so this is a good starting point for browsing. Also have a look at Matrix, as a few methods and the matrix constructors are there.
Most of the API is available as methods in MatrixBase, so this is a good starting point for browsing. Also have a look at Matrix, as a few methods and the matrix constructors are there. Other notable classes for the Eigen API are Cwise, which contains the methods for doing certain coefficient-wise operations, and Part.
For a first contact with Eigen, it is enough to look at Matrix and MatrixBase. In fact, except for advanced use, the only class that you'll have to explicitly name in your program, i.e. of which you'll explicitly contruct objects, is Matrix. For instance, vectors are handled as a special case of Matrix with one column.
For a first contact with Eigen, it is enough to look at Matrix, MatrixBase, and Cwise. In fact, except for advanced use, the only class that you'll have to explicitly name in your program, i.e. of which you'll explicitly contruct objects, is Matrix. For instance, vectors are handled as a special case of Matrix with one column. Typedefs are provided, e.g. Vector2f is a typedef for Matrix<float, 2, 1>.
The many other classes are typically return types for MatrixBase methods.
Most of the other classes are just return types for MatrixBase methods.
*/

View File

@ -22,7 +22,7 @@ struct unroll_echelon
unroll_echelon<Derived, Step-1>::run(m);
int rowOfBiggest, colOfBiggest;
m.template corner<CornerRows, CornerCols>(BottomRight)
.cwiseAbs()
.cwise().abs()
.maxCoeff(&rowOfBiggest, &colOfBiggest);
m.row(k).swap(m.row(k+rowOfBiggest));
m.col(k).swap(m.col(k+colOfBiggest));
@ -54,7 +54,7 @@ struct unroll_echelon<Derived, Dynamic>
int rowOfBiggest, colOfBiggest;
int cornerRows = m.rows()-k, cornerCols = m.cols()-k;
m.corner(BottomRight, cornerRows, cornerCols)
.cwiseAbs()
.cwise().abs()
.maxCoeff(&rowOfBiggest, &colOfBiggest);
m.row(k).swap(m.row(k+rowOfBiggest));
m.col(k).swap(m.col(k+colOfBiggest));

View File

@ -7,12 +7,11 @@ using namespace std;
template<typename Scalar> struct MakeComplexOp EIGEN_EMPTY_STRUCT {
typedef complex<Scalar> result_type;
complex<Scalar> operator()(const Scalar& a, const Scalar& b) const { return complex<Scalar>(a,b); }
enum { Cost = 0 };
};
int main(int, char**)
{
Matrix4d m1 = Matrix4d::random(), m2 = Matrix4d::random();
cout << m1.cwise(m2, MakeComplexOp<double>()) << endl;
cout << m1.binaryExpr(m2, MakeComplexOp<double>()) << endl;
return 0;
}

View File

@ -9,12 +9,11 @@ struct CwiseClampOp {
CwiseClampOp(const Scalar& inf, const Scalar& sup) : m_inf(inf), m_sup(sup) {}
const Scalar operator()(const Scalar& x) const { return x<m_inf ? m_inf : (x>m_sup ? m_sup : x); }
Scalar m_inf, m_sup;
enum { Cost = Eigen::ConditionalJumpCost + Eigen::NumTraits<Scalar>::AddCost };
};
int main(int, char**)
{
Matrix4d m1 = Matrix4d::random();
cout << m1 << endl << "becomes: " << endl << m1.cwise(CwiseClampOp<double>(-0.5,0.5)) << endl;
cout << m1 << endl << "becomes: " << endl << m1.unaryExpr(CwiseClampOp<double>(-0.5,0.5)) << endl;
return 0;
}

View File

@ -1,5 +0,0 @@
int data[4] = {1,3,0,2};
cout << Matrix2i::map(data) << endl;
Matrix2i::map(data) *= 2;
cout << "The data is now:" << endl;
for(int i = 0; i < 4; i++) cout << data[i] << endl;

View File

@ -1,5 +0,0 @@
int data[4] = {1,3,0,2};
cout << VectorXi::map(data, 4) << endl;
VectorXi::map(data, 4) *= 2;
cout << "The data is now:" << endl;
for(int i = 0; i < 4; i++) cout << data[i] << endl;

View File

@ -1,5 +0,0 @@
int data[4] = {1,3,0,2};
cout << MatrixXi::map(data, 2, 2) << endl;
MatrixXi::map(data, 2, 2) *= 2;
cout << "The data is now:" << endl;
for(int i = 0; i < 4; i++) cout << data[i] << endl;

View File

@ -59,7 +59,7 @@ template<typename MatrixType> void nullDeterminant(const MatrixType& m)
std::cout << notInvertibleCovarianceMatrix << "\n" << notInvertibleCovarianceMatrix.determinant() << "\n";
VERIFY_IS_MUCH_SMALLER_THAN(notInvertibleCovarianceMatrix.determinant(),
notInvertibleCovarianceMatrix.cwiseAbs().maxCoeff());
notInvertibleCovarianceMatrix.cwise().abs().maxCoeff());
VERIFY(invertibleCovarianceMatrix.inverse().exists());

View File

@ -26,7 +26,7 @@
#include <Eigen/QR>
template<typename Derived1, typename Derived2>
bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::Scalar epsilon = precision<typename Derived1::Scalar>())
bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = precision<typename Derived1::RealScalar>())
{
return !((m1-m2).matrixNorm() < epsilon * std::max(m1.matrixNorm(), m2.matrixNorm()));
}