mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-09-18 12:23:13 +08:00
remove disabled/ directory. It's useless. It remains in the hg history anyways.
This commit is contained in:
parent
a4f9ca44ab
commit
4502afeedf
@ -1,43 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_ARRAYBASE_H
|
|
||||||
#define EIGEN_ARRAYBASE_H
|
|
||||||
|
|
||||||
template<typename Derived> class ArrayBase<Derived,true>
|
|
||||||
{
|
|
||||||
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
|
||||||
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
|
||||||
inline Derived& const_cast_derived() const
|
|
||||||
{ return *static_cast<Derived*>(const_cast<ArrayBase*>(this)); }
|
|
||||||
public:
|
|
||||||
template<typename OtherDerived>
|
|
||||||
const Product<Derived,OtherDerived>
|
|
||||||
matrixProduct(const MatrixBase<OtherDerived> &other) const
|
|
||||||
{
|
|
||||||
return Product<Derived,OtherDerived>(derived(), other.derived());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_ARRAYBASE_H
|
|
@ -1,164 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_EULERANGLES_H
|
|
||||||
#define EIGEN_EULERANGLES_H
|
|
||||||
|
|
||||||
template<typename Other,
|
|
||||||
int OtherRows=Other::RowsAtCompileTime,
|
|
||||||
int OtherCols=Other::ColsAtCompileTime>
|
|
||||||
struct ei_eulerangles_assign_impl;
|
|
||||||
|
|
||||||
// enum {
|
|
||||||
// XYZ,
|
|
||||||
// XYX,
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// };
|
|
||||||
|
|
||||||
/** \class EulerAngles
|
|
||||||
*
|
|
||||||
* \brief Represents a rotation in a 3 dimensional space as three Euler angles
|
|
||||||
*
|
|
||||||
* \param _Scalar the scalar type, i.e., the type of the angles.
|
|
||||||
*
|
|
||||||
* \sa class Quaternion, class AngleAxis, class Transform
|
|
||||||
*/
|
|
||||||
template<typename _Scalar>
|
|
||||||
class EulerAngles
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum { Dim = 3 };
|
|
||||||
/** the scalar type of the coefficients */
|
|
||||||
typedef _Scalar Scalar;
|
|
||||||
typedef Matrix<Scalar,3,3> Matrix3;
|
|
||||||
typedef Matrix<Scalar,3,1> Vector3;
|
|
||||||
typedef Quaternion<Scalar> QuaternionType;
|
|
||||||
typedef AngleAxis<Scalar> AngleAxisType;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Vector3 m_angles;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
EulerAngles() {}
|
|
||||||
inline EulerAngles(Scalar a0, Scalar a1, Scalar a2) : m_angles(a0, a1, a2) {}
|
|
||||||
inline EulerAngles(const QuaternionType& q) { *this = q; }
|
|
||||||
inline EulerAngles(const AngleAxisType& aa) { *this = aa; }
|
|
||||||
template<typename Derived>
|
|
||||||
inline EulerAngles(const MatrixBase<Derived>& m) { *this = m; }
|
|
||||||
|
|
||||||
Scalar angle(int i) const { return m_angles.coeff(i); }
|
|
||||||
Scalar& angle(int i) { return m_angles.coeffRef(i); }
|
|
||||||
|
|
||||||
const Vector3& coeffs() const { return m_angles; }
|
|
||||||
Vector3& coeffs() { return m_angles; }
|
|
||||||
|
|
||||||
EulerAngles& operator=(const QuaternionType& q);
|
|
||||||
EulerAngles& operator=(const AngleAxisType& ea);
|
|
||||||
template<typename Derived>
|
|
||||||
EulerAngles& operator=(const MatrixBase<Derived>& m);
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
EulerAngles& fromRotationMatrix(const MatrixBase<Derived>& m);
|
|
||||||
Matrix3 toRotationMatrix(void) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Set \c *this from a quaternion.
|
|
||||||
* The axis is normalized.
|
|
||||||
*/
|
|
||||||
template<typename Scalar>
|
|
||||||
EulerAngles<Scalar>& EulerAngles<Scalar>::operator=(const QuaternionType& q)
|
|
||||||
{
|
|
||||||
Scalar y2 = q.y() * q.y();
|
|
||||||
m_angles.coeffRef(0) = std::atan2(2*(q.w()*q.x() + q.y()*q.z()), (1 - 2*(q.x()*q.x() + y2)));
|
|
||||||
m_angles.coeffRef(1) = std::asin( 2*(q.w()*q.y() - q.z()*q.x()));
|
|
||||||
m_angles.coeffRef(2) = std::atan2(2*(q.w()*q.z() + q.x()*q.y()), (1 - 2*(y2 + q.z()*q.z())));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set \c *this from Euler angles \a ea.
|
|
||||||
*/
|
|
||||||
template<typename Scalar>
|
|
||||||
EulerAngles<Scalar>& EulerAngles<Scalar>::operator=(const AngleAxisType& aa)
|
|
||||||
{
|
|
||||||
return *this = QuaternionType(aa);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set \c *this from the expression \a xpr:
|
|
||||||
* - if \a xpr is a 3x1 vector, then \a xpr is assumed to be a vector of angles
|
|
||||||
* - if \a xpr is a 3x3 matrix, then \a xpr is assumed to be rotation matrix
|
|
||||||
* and \a xpr is converted to Euler angles
|
|
||||||
*/
|
|
||||||
template<typename Scalar>
|
|
||||||
template<typename Derived>
|
|
||||||
EulerAngles<Scalar>& EulerAngles<Scalar>::operator=(const MatrixBase<Derived>& other)
|
|
||||||
{
|
|
||||||
ei_eulerangles_assign_impl<Derived>::run(*this,other.derived());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructs and \returns an equivalent 3x3 rotation matrix.
|
|
||||||
*/
|
|
||||||
template<typename Scalar>
|
|
||||||
typename EulerAngles<Scalar>::Matrix3
|
|
||||||
EulerAngles<Scalar>::toRotationMatrix(void) const
|
|
||||||
{
|
|
||||||
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(),
|
|
||||||
-c.x()*c.z()*s.y()+s.x()*s.z(), c.z()*s.x()+c.x()*s.y()*s.z(), c.x()*c.y();
|
|
||||||
}
|
|
||||||
|
|
||||||
// set from a rotation matrix
|
|
||||||
template<typename Other>
|
|
||||||
struct ei_eulerangles_assign_impl<Other,3,3>
|
|
||||||
{
|
|
||||||
typedef typename Other::Scalar Scalar;
|
|
||||||
inline static void run(EulerAngles<Scalar>& ea, const Other& mat)
|
|
||||||
{
|
|
||||||
// mat = cy*cz -cy*sz sy
|
|
||||||
// cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx
|
|
||||||
// -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy
|
|
||||||
ea.angle(1) = std::asin(mat.coeff(0,2));
|
|
||||||
ea.angle(0) = std::atan2(-mat.coeff(1,2),mat.coeff(2,2));
|
|
||||||
ea.angle(2) = std::atan2(-mat.coeff(0,1),mat.coeff(0,0));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// set from a vector of angles
|
|
||||||
template<typename Other>
|
|
||||||
struct ei_eulerangles_assign_impl<Other,3,1>
|
|
||||||
{
|
|
||||||
typedef typename Other::Scalar Scalar;
|
|
||||||
inline static void run(EulerAngles<Scalar>& ea, const Other& vec)
|
|
||||||
{
|
|
||||||
ea.coeffs() = vec;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_EULERANGLES_H
|
|
109
disabled/Eval.h
109
disabled/Eval.h
@ -1,109 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_EVAL_H
|
|
||||||
#define EIGEN_EVAL_H
|
|
||||||
|
|
||||||
/** \class Eval
|
|
||||||
*
|
|
||||||
* \brief Evaluation of an expression
|
|
||||||
*
|
|
||||||
* The template parameter Expression is the type of the expression that we are evaluating.
|
|
||||||
*
|
|
||||||
* This class is the return
|
|
||||||
* type of MatrixBase::eval() and most of the time this is the only way it
|
|
||||||
* is used.
|
|
||||||
*
|
|
||||||
* However, if you want to write a function returning an evaluation of an expression, you
|
|
||||||
* will need to use this class.
|
|
||||||
*
|
|
||||||
* Here is an example illustrating this:
|
|
||||||
* \include class_Eval.cpp
|
|
||||||
* Output: \verbinclude class_Eval.out
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::eval()
|
|
||||||
*/
|
|
||||||
template<typename ExpressionType>
|
|
||||||
struct ei_traits<Eval<ExpressionType> >
|
|
||||||
{
|
|
||||||
typedef typename ExpressionType::Scalar Scalar;
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = ExpressionType::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = ExpressionType::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime,
|
|
||||||
Flags = ExpressionType::Flags & ~LazyBit
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ExpressionType> class Eval : ei_no_assignment_operator,
|
|
||||||
public Matrix< typename ExpressionType::Scalar,
|
|
||||||
ExpressionType::RowsAtCompileTime,
|
|
||||||
ExpressionType::ColsAtCompileTime,
|
|
||||||
ExpressionType::Flags,
|
|
||||||
ExpressionType::MaxRowsAtCompileTime,
|
|
||||||
ExpressionType::MaxColsAtCompileTime>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** The actual matrix type to evaluate to. This type can be used independently
|
|
||||||
* of the rest of this class to get the actual matrix type to evaluate and store
|
|
||||||
* the value of an expression.
|
|
||||||
*
|
|
||||||
* Here is an example illustrating this:
|
|
||||||
* \include Eval_MatrixType.cpp
|
|
||||||
* Output: \verbinclude Eval_MatrixType.out
|
|
||||||
*/
|
|
||||||
typedef Matrix<typename ExpressionType::Scalar,
|
|
||||||
ExpressionType::RowsAtCompileTime,
|
|
||||||
ExpressionType::ColsAtCompileTime,
|
|
||||||
ExpressionType::Flags,
|
|
||||||
ExpressionType::MaxRowsAtCompileTime,
|
|
||||||
ExpressionType::MaxColsAtCompileTime> MatrixType;
|
|
||||||
|
|
||||||
_EIGEN_GENERIC_PUBLIC_INTERFACE(Eval, MatrixType)
|
|
||||||
|
|
||||||
explicit Eval(const ExpressionType& expr) : MatrixType(expr) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Evaluates *this, which can be any expression, and returns the obtained matrix.
|
|
||||||
*
|
|
||||||
* A common use case for this is the following. In an expression-templates library
|
|
||||||
* like Eigen, the coefficients of an expression are only computed as they are
|
|
||||||
* accessed, they are not computed when the expression itself is constructed. This is
|
|
||||||
* usually a good thing, as this "lazy evaluation" improves performance, but can also
|
|
||||||
* in certain cases lead to wrong results and/or to redundant computations. In such
|
|
||||||
* cases, one can restore the classical immediate-evaluation behavior by calling eval().
|
|
||||||
*
|
|
||||||
* Example: \include MatrixBase_eval.cpp
|
|
||||||
* Output: \verbinclude MatrixBase_eval.out
|
|
||||||
*
|
|
||||||
* \sa class Eval */
|
|
||||||
template<typename Derived>
|
|
||||||
const typename ei_eval_unless_lazy<Derived>::type MatrixBase<Derived>::eval() const
|
|
||||||
{
|
|
||||||
return typename ei_eval_unless_lazy<Derived>::type(derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_EVAL_H
|
|
@ -1,132 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_EVAL_OMP_H
|
|
||||||
#define EIGEN_EVAL_OMP_H
|
|
||||||
|
|
||||||
/** \class EvalOMP
|
|
||||||
*
|
|
||||||
* \brief Parallel evaluation of an expression using OpenMP
|
|
||||||
*
|
|
||||||
* The template parameter Expression is the type of the expression that we are evaluating.
|
|
||||||
*
|
|
||||||
* This class is the return type of MatrixBase::evalOMP() and most of the time this is the
|
|
||||||
* only way it is used.
|
|
||||||
*
|
|
||||||
* Note that if OpenMP is not enabled, then this class is equivalent to Eval.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::evalOMP(), class Eval, MatrixBase::eval()
|
|
||||||
*/
|
|
||||||
template<typename ExpressionType>
|
|
||||||
struct ei_traits<EvalOMP<ExpressionType> >
|
|
||||||
{
|
|
||||||
typedef typename ExpressionType::Scalar Scalar;
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = ExpressionType::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = ExpressionType::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime,
|
|
||||||
Flags = ExpressionType::Flags & ~LazyBit
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ExpressionType> class EvalOMP : ei_no_assignment_operator,
|
|
||||||
public Matrix< typename ExpressionType::Scalar,
|
|
||||||
ExpressionType::RowsAtCompileTime,
|
|
||||||
ExpressionType::ColsAtCompileTime,
|
|
||||||
ExpressionType::Flags,
|
|
||||||
ExpressionType::MaxRowsAtCompileTime,
|
|
||||||
ExpressionType::MaxColsAtCompileTime>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** The actual matrix type to evaluate to. This type can be used independently
|
|
||||||
* of the rest of this class to get the actual matrix type to evaluate and store
|
|
||||||
* the value of an expression.
|
|
||||||
*/
|
|
||||||
typedef Matrix<typename ExpressionType::Scalar,
|
|
||||||
ExpressionType::RowsAtCompileTime,
|
|
||||||
ExpressionType::ColsAtCompileTime,
|
|
||||||
ExpressionType::Flags,
|
|
||||||
ExpressionType::MaxRowsAtCompileTime,
|
|
||||||
ExpressionType::MaxColsAtCompileTime> MatrixType;
|
|
||||||
|
|
||||||
_EIGEN_GENERIC_PUBLIC_INTERFACE(EvalOMP, MatrixType)
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
|
||||||
explicit EvalOMP(const ExpressionType& other)
|
|
||||||
: MatrixType(other.rows(), other.cols())
|
|
||||||
{
|
|
||||||
#ifdef __INTEL_COMPILER
|
|
||||||
#pragma omp parallel default(none) shared(other)
|
|
||||||
#else
|
|
||||||
#pragma omp parallel default(none)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (this->cols()>this->rows())
|
|
||||||
{
|
|
||||||
#pragma omp for
|
|
||||||
for(int j = 0; j < this->cols(); j++)
|
|
||||||
for(int i = 0; i < this->rows(); i++)
|
|
||||||
this->coeffRef(i, j) = other.coeff(i, j);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#pragma omp for
|
|
||||||
for(int i = 0; i < this->rows(); i++)
|
|
||||||
for(int j = 0; j < this->cols(); j++)
|
|
||||||
this->coeffRef(i, j) = other.coeff(i, j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
explicit EvalOMP(const ExpressionType& other) : MatrixType(other) {}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Evaluates *this in a parallel fashion using OpenMP and returns the obtained matrix.
|
|
||||||
*
|
|
||||||
* Of course, it only makes sense to call this function for complex expressions, and/or
|
|
||||||
* large matrices (>32x32), \b and if there is no outer loop which can be parallelized.
|
|
||||||
*
|
|
||||||
* It is the responsibility of the user manage the OpenMP parameters, for instance:
|
|
||||||
* \code
|
|
||||||
* #include <omp.h>
|
|
||||||
* // ...
|
|
||||||
* omp_set_num_threads(omp_get_num_procs());
|
|
||||||
* \endcode
|
|
||||||
* You also need to enable OpenMP on your compiler (e.g., -fopenmp) during both compilation and linking.
|
|
||||||
*
|
|
||||||
* Note that if OpenMP is not enabled, then evalOMP() is equivalent to eval().
|
|
||||||
*
|
|
||||||
* \sa class EvalOMP, eval()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
const EvalOMP<Derived> MatrixBase<Derived>::evalOMP() const
|
|
||||||
{
|
|
||||||
return EvalOMP<Derived>(*static_cast<const Derived*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_EVAL_OMP_H
|
|
@ -1,13 +0,0 @@
|
|||||||
typedef Matrix3i MyMatrixType;
|
|
||||||
MyMatrixType m = MyMatrixType::random(3, 3);
|
|
||||||
cout << "Here's the matrix m:" << endl << m << endl;
|
|
||||||
typedef Eigen::Eval<Eigen::Block<MyMatrixType,1,MyMatrixType::ColsAtCompileTime> >::MatrixType MyRowType;
|
|
||||||
// now MyRowType is just the same typedef as RowVector3i
|
|
||||||
MyRowType r = m.row(0);
|
|
||||||
cout << "Here's r:" << endl << r << endl;
|
|
||||||
typedef Eigen::Eval<Eigen::Block<MyMatrixType> >::MatrixType MyBlockType;
|
|
||||||
MyBlockType c = m.corner(Eigen::TopRight, 2, 2);
|
|
||||||
// now MyBlockType is a a matrix type where the number of rows and columns
|
|
||||||
// are dynamic, but know at compile-time to be <= 2. Therefore no dynamic memory
|
|
||||||
// allocation occurs.
|
|
||||||
cout << "Here's c:" << endl << c << endl;
|
|
@ -1,166 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_HASHMATRIX_H
|
|
||||||
#define EIGEN_HASHMATRIX_H
|
|
||||||
|
|
||||||
template<typename _Scalar, int _Flags>
|
|
||||||
struct ei_traits<HashMatrix<_Scalar, _Flags> >
|
|
||||||
{
|
|
||||||
typedef _Scalar Scalar;
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = Dynamic,
|
|
||||||
ColsAtCompileTime = Dynamic,
|
|
||||||
MaxRowsAtCompileTime = Dynamic,
|
|
||||||
MaxColsAtCompileTime = Dynamic,
|
|
||||||
Flags = SparseBit | _Flags,
|
|
||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
|
||||||
SupportedAccessPatterns = RandomAccessPattern
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO reimplement this class using custom linked lists
|
|
||||||
template<typename _Scalar, int _Flags>
|
|
||||||
class HashMatrix
|
|
||||||
: public SparseMatrixBase<HashMatrix<_Scalar, _Flags> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(HashMatrix)
|
|
||||||
class InnerIterator;
|
|
||||||
protected:
|
|
||||||
|
|
||||||
typedef typename std::map<int, Scalar>::iterator MapIterator;
|
|
||||||
typedef typename std::map<int, Scalar>::const_iterator ConstMapIterator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline int rows() const { return m_innerSize; }
|
|
||||||
inline int cols() const { return m_data.size(); }
|
|
||||||
|
|
||||||
inline const Scalar& coeff(int row, int col) const
|
|
||||||
{
|
|
||||||
const MapIterator it = m_data[col].find(row);
|
|
||||||
if (it!=m_data[col].end())
|
|
||||||
return Scalar(0);
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Scalar& coeffRef(int row, int col)
|
|
||||||
{
|
|
||||||
return m_data[col][row];
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
inline void startFill(int /*reserveSize = 1000 --- currently unused, don't generate a warning*/) {}
|
|
||||||
|
|
||||||
inline Scalar& fill(int row, int col) { return coeffRef(row, col); }
|
|
||||||
|
|
||||||
inline void endFill() {}
|
|
||||||
|
|
||||||
~HashMatrix()
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline void shallowCopy(const HashMatrix& other)
|
|
||||||
{
|
|
||||||
EIGEN_DBG_SPARSE(std::cout << "HashMatrix:: shallowCopy\n");
|
|
||||||
// FIXME implement a true shallow copy !!
|
|
||||||
resize(other.rows(), other.cols());
|
|
||||||
for (int j=0; j<this->outerSize(); ++j)
|
|
||||||
m_data[j] = other.m_data[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(int _rows, int _cols)
|
|
||||||
{
|
|
||||||
if (cols() != _cols)
|
|
||||||
{
|
|
||||||
m_data.resize(_cols);
|
|
||||||
}
|
|
||||||
m_innerSize = _rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline HashMatrix(int rows, int cols)
|
|
||||||
: m_innerSize(0)
|
|
||||||
{
|
|
||||||
resize(rows, cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline HashMatrix(const MatrixBase<OtherDerived>& other)
|
|
||||||
: m_innerSize(0)
|
|
||||||
{
|
|
||||||
*this = other.derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline HashMatrix& operator=(const HashMatrix& other)
|
|
||||||
{
|
|
||||||
if (other.isRValue())
|
|
||||||
{
|
|
||||||
shallowCopy(other);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resize(other.rows(), other.cols());
|
|
||||||
for (int col=0; col<cols(); ++col)
|
|
||||||
m_data[col] = other.m_data[col];
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline HashMatrix& operator=(const MatrixBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
return SparseMatrixBase<HashMatrix>::operator=(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector<std::map<int, Scalar> > m_data;
|
|
||||||
int m_innerSize;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar, int _Flags>
|
|
||||||
class HashMatrix<Scalar,_Flags>::InnerIterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
InnerIterator(const HashMatrix& mat, int col)
|
|
||||||
: m_matrix(mat), m_it(mat.m_data[col].begin()), m_end(mat.m_data[col].end())
|
|
||||||
{}
|
|
||||||
|
|
||||||
InnerIterator& operator++() { m_it++; return *this; }
|
|
||||||
|
|
||||||
Scalar value() { return m_it->second; }
|
|
||||||
|
|
||||||
int index() const { return m_it->first; }
|
|
||||||
|
|
||||||
operator bool() const { return m_it!=m_end; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const HashMatrix& m_matrix;
|
|
||||||
typename HashMatrix::ConstMapIterator m_it;
|
|
||||||
typename HashMatrix::ConstMapIterator m_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_HASHMATRIX_H
|
|
@ -1,33 +0,0 @@
|
|||||||
#include<Eigen/Core>
|
|
||||||
|
|
||||||
using namespace Eigen;
|
|
||||||
|
|
||||||
/** From Golub & van Loan Algorithm 5.1.1 page 210
|
|
||||||
*/
|
|
||||||
template<typename InputVector, typename OutputVector>
|
|
||||||
void ei_compute_householder(const InputVector& x, OutputVector *v, typename OutputVector::RealScalar *beta)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT(ei_is_same_type<typename InputVector::Scalar, typename OutputVector::Scalar>::ret,
|
|
||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
|
||||||
EIGEN_STATIC_ASSERT((InputVector::SizeAtCompileTime == OutputVector::SizeAtCompileTime+1)
|
|
||||||
|| InputVector::SizeAtCompileTime == Dynamic
|
|
||||||
|| OutputVector::SizeAtCompileTime == Dynamic,
|
|
||||||
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES)
|
|
||||||
typedef typename OutputVector::RealScalar RealScalar;
|
|
||||||
ei_assert(x.size() == v->size()+1);
|
|
||||||
int n = x.size();
|
|
||||||
RealScalar sigma = x.tail(n-1).squaredNorm();
|
|
||||||
*v = x.tail(n-1);
|
|
||||||
// the big assumption in this code is that ei_abs2(x->coeff(0)) is not much smaller than sigma.
|
|
||||||
if(ei_isMuchSmallerThan(sigma, ei_abs2(x.coeff(0))))
|
|
||||||
{
|
|
||||||
// in this case x is approx colinear to (1,0,....,0)
|
|
||||||
// fixme, implement this trivial case
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RealScalar mu = ei_sqrt(ei_abs2(x.coeff(0)) + sigma);
|
|
||||||
RealScalar kappa = -sigma/(x.coeff(0)+mu);
|
|
||||||
*beta =
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,317 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_LINKEDVECTORMATRIX_H
|
|
||||||
#define EIGEN_LINKEDVECTORMATRIX_H
|
|
||||||
|
|
||||||
template<typename _Scalar, int _Flags>
|
|
||||||
struct ei_traits<LinkedVectorMatrix<_Scalar,_Flags> >
|
|
||||||
{
|
|
||||||
typedef _Scalar Scalar;
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = Dynamic,
|
|
||||||
ColsAtCompileTime = Dynamic,
|
|
||||||
MaxRowsAtCompileTime = Dynamic,
|
|
||||||
MaxColsAtCompileTime = Dynamic,
|
|
||||||
Flags = SparseBit | _Flags,
|
|
||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
|
||||||
SupportedAccessPatterns = InnerCoherentAccessPattern
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Element, int ChunkSize = 8>
|
|
||||||
struct LinkedVectorChunk
|
|
||||||
{
|
|
||||||
LinkedVectorChunk() : next(0), prev(0), size(0) {}
|
|
||||||
Element data[ChunkSize];
|
|
||||||
LinkedVectorChunk* next;
|
|
||||||
LinkedVectorChunk* prev;
|
|
||||||
int size;
|
|
||||||
bool isFull() const { return size==ChunkSize; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _Scalar, int _Flags>
|
|
||||||
class LinkedVectorMatrix
|
|
||||||
: public SparseMatrixBase<LinkedVectorMatrix<_Scalar,_Flags> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(LinkedVectorMatrix)
|
|
||||||
class InnerIterator;
|
|
||||||
protected:
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RowMajor = Flags&RowMajorBit ? 1 : 0
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ValueIndex
|
|
||||||
{
|
|
||||||
ValueIndex() : value(0), index(0) {}
|
|
||||||
ValueIndex(Scalar v, int i) : value(v), index(i) {}
|
|
||||||
Scalar value;
|
|
||||||
int index;
|
|
||||||
};
|
|
||||||
typedef LinkedVectorChunk<ValueIndex,8> VectorChunk;
|
|
||||||
|
|
||||||
inline int find(VectorChunk** _el, int id)
|
|
||||||
{
|
|
||||||
VectorChunk* el = *_el;
|
|
||||||
while (el && el->data[el->size-1].index<id)
|
|
||||||
el = el->next;
|
|
||||||
*_el = el;
|
|
||||||
if (el)
|
|
||||||
{
|
|
||||||
// binary search
|
|
||||||
int maxI = el->size-1;
|
|
||||||
int minI = 0;
|
|
||||||
int i = el->size/2;
|
|
||||||
const ValueIndex* data = el->data;
|
|
||||||
while (data[i].index!=id)
|
|
||||||
{
|
|
||||||
if (data[i].index<id)
|
|
||||||
{
|
|
||||||
minI = i+1;
|
|
||||||
i = (maxI + minI)+2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxI = i-1;
|
|
||||||
i = (maxI + minI)+2;
|
|
||||||
}
|
|
||||||
if (minI>=maxI)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (data[i].index==id)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline int rows() const { return RowMajor ? m_data.size() : m_innerSize; }
|
|
||||||
inline int cols() const { return RowMajor ? m_innerSize : m_data.size(); }
|
|
||||||
|
|
||||||
inline const Scalar& coeff(int row, int col) const
|
|
||||||
{
|
|
||||||
const int outer = RowMajor ? row : col;
|
|
||||||
const int inner = RowMajor ? col : row;
|
|
||||||
|
|
||||||
VectorChunk* el = m_data[outer];
|
|
||||||
int id = find(&el, inner);
|
|
||||||
if (id<0)
|
|
||||||
return Scalar(0);
|
|
||||||
return el->data[id].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Scalar& coeffRef(int row, int col)
|
|
||||||
{
|
|
||||||
const int outer = RowMajor ? row : col;
|
|
||||||
const int inner = RowMajor ? col : row;
|
|
||||||
|
|
||||||
VectorChunk* el = m_data[outer];
|
|
||||||
int id = find(&el, inner);
|
|
||||||
ei_assert(id>=0);
|
|
||||||
// if (id<0)
|
|
||||||
// return Scalar(0);
|
|
||||||
return el->data[id].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
inline void startFill(int reserveSize = 1000)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
for (unsigned int i=0; i<m_data.size(); ++i)
|
|
||||||
m_ends[i] = m_data[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Scalar& fill(int row, int col)
|
|
||||||
{
|
|
||||||
const int outer = RowMajor ? row : col;
|
|
||||||
const int inner = RowMajor ? col : row;
|
|
||||||
// std::cout << " ll fill " << outer << "," << inner << "\n";
|
|
||||||
if (m_ends[outer]==0)
|
|
||||||
{
|
|
||||||
m_data[outer] = m_ends[outer] = new VectorChunk();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ei_assert(m_ends[outer]->data[m_ends[outer]->size-1].index < inner);
|
|
||||||
if (m_ends[outer]->isFull())
|
|
||||||
{
|
|
||||||
|
|
||||||
VectorChunk* el = new VectorChunk();
|
|
||||||
m_ends[outer]->next = el;
|
|
||||||
el->prev = m_ends[outer];
|
|
||||||
m_ends[outer] = el;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_ends[outer]->data[m_ends[outer]->size].index = inner;
|
|
||||||
return m_ends[outer]->data[m_ends[outer]->size++].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void endFill() { }
|
|
||||||
|
|
||||||
void printDbg()
|
|
||||||
{
|
|
||||||
for (int j=0; j<m_data.size(); ++j)
|
|
||||||
{
|
|
||||||
VectorChunk* el = m_data[j];
|
|
||||||
while (el)
|
|
||||||
{
|
|
||||||
for (int i=0; i<el->size; ++i)
|
|
||||||
std::cout << j << "," << el->data[i].index << " = " << el->data[i].value << "\n";
|
|
||||||
el = el->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int j=0; j<m_data.size(); ++j)
|
|
||||||
{
|
|
||||||
InnerIterator it(*this,j);
|
|
||||||
while (it)
|
|
||||||
{
|
|
||||||
std::cout << j << "," << it.index() << " = " << it.value() << "\n";
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~LinkedVectorMatrix()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
for (unsigned int i=0; i<m_data.size(); ++i)
|
|
||||||
{
|
|
||||||
VectorChunk* el = m_data[i];
|
|
||||||
while (el)
|
|
||||||
{
|
|
||||||
VectorChunk* tmp = el;
|
|
||||||
el = el->next;
|
|
||||||
delete tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(int rows, int cols)
|
|
||||||
{
|
|
||||||
const int outers = RowMajor ? rows : cols;
|
|
||||||
const int inners = RowMajor ? cols : rows;
|
|
||||||
|
|
||||||
if (this->outerSize() != outers)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
m_data.resize(outers);
|
|
||||||
m_ends.resize(outers);
|
|
||||||
for (unsigned int i=0; i<m_data.size(); ++i)
|
|
||||||
m_ends[i] = m_data[i] = 0;
|
|
||||||
}
|
|
||||||
m_innerSize = inners;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline LinkedVectorMatrix(int rows, int cols)
|
|
||||||
: m_innerSize(0)
|
|
||||||
{
|
|
||||||
resize(rows, cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline LinkedVectorMatrix(const MatrixBase<OtherDerived>& other)
|
|
||||||
: m_innerSize(0)
|
|
||||||
{
|
|
||||||
*this = other.derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void swap(LinkedVectorMatrix& other)
|
|
||||||
{
|
|
||||||
EIGEN_DBG_SPARSE(std::cout << "LinkedVectorMatrix:: swap\n");
|
|
||||||
resize(other.rows(), other.cols());
|
|
||||||
m_data.swap(other.m_data);
|
|
||||||
m_ends.swap(other.m_ends);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline LinkedVectorMatrix& operator=(const LinkedVectorMatrix& other)
|
|
||||||
{
|
|
||||||
if (other.isRValue())
|
|
||||||
{
|
|
||||||
swap(other.const_cast_derived());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO implement a specialized deep copy here
|
|
||||||
return operator=<LinkedVectorMatrix>(other);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline LinkedVectorMatrix& operator=(const MatrixBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
return SparseMatrixBase<LinkedVectorMatrix>::operator=(other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// outer vector of inner linked vector chunks
|
|
||||||
std::vector<VectorChunk*> m_data;
|
|
||||||
// stores a reference to the last vector chunk for efficient filling
|
|
||||||
std::vector<VectorChunk*> m_ends;
|
|
||||||
int m_innerSize;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Scalar, int _Flags>
|
|
||||||
class LinkedVectorMatrix<Scalar,_Flags>::InnerIterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
InnerIterator(const LinkedVectorMatrix& mat, int col)
|
|
||||||
: m_matrix(mat), m_el(mat.m_data[col]), m_it(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
InnerIterator& operator++()
|
|
||||||
{
|
|
||||||
m_it++;
|
|
||||||
if (m_it>=m_el->size)
|
|
||||||
{
|
|
||||||
m_el = m_el->next;
|
|
||||||
m_it = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scalar value() { return m_el->data[m_it].value; }
|
|
||||||
|
|
||||||
int index() const { return m_el->data[m_it].index; }
|
|
||||||
|
|
||||||
operator bool() const { return m_el && (m_el->next || m_it<m_el->size); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const LinkedVectorMatrix& m_matrix;
|
|
||||||
VectorChunk* m_el;
|
|
||||||
int m_it;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_LINKEDVECTORMATRIX_H
|
|
@ -1,489 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_PRODUCT_H
|
|
||||||
#define EIGEN_PRODUCT_H
|
|
||||||
|
|
||||||
template<int Index, int Size, typename Lhs, typename Rhs>
|
|
||||||
struct ei_product_unroller
|
|
||||||
{
|
|
||||||
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs,
|
|
||||||
typename Lhs::Scalar &res)
|
|
||||||
{
|
|
||||||
ei_product_unroller<Index-1, Size, Lhs, Rhs>::run(row, col, lhs, rhs, res);
|
|
||||||
res += lhs.coeff(row, Index) * rhs.coeff(Index, col);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Size, typename Lhs, typename Rhs>
|
|
||||||
struct ei_product_unroller<0, Size, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs,
|
|
||||||
typename Lhs::Scalar &res)
|
|
||||||
{
|
|
||||||
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Index, typename Lhs, typename Rhs>
|
|
||||||
struct ei_product_unroller<Index, Dynamic, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
inline static void run(int, int, const Lhs&, const Rhs&, typename Lhs::Scalar&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// prevent buggy user code from causing an infinite recursion
|
|
||||||
template<int Index, typename Lhs, typename Rhs>
|
|
||||||
struct ei_product_unroller<Index, 0, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
inline static void run(int, int, const Lhs&, const Rhs&, typename Lhs::Scalar&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct ei_product_unroller<0, Dynamic, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
static void run(int, int, const Lhs&, const Rhs&, typename Lhs::Scalar&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool RowMajor, int Index, int Size, typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller;
|
|
||||||
|
|
||||||
template<int Index, int Size, typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller<true, Index, Size, Lhs, Rhs, PacketScalar>
|
|
||||||
{
|
|
||||||
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
|
|
||||||
{
|
|
||||||
ei_packet_product_unroller<true, Index-1, Size, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, res);
|
|
||||||
res = ei_pmadd(ei_pset1(lhs.coeff(row, Index)), rhs.template packet<Aligned>(Index, col), res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Index, int Size, typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller<false, Index, Size, Lhs, Rhs, PacketScalar>
|
|
||||||
{
|
|
||||||
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
|
|
||||||
{
|
|
||||||
ei_packet_product_unroller<false, Index-1, Size, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, res);
|
|
||||||
res = ei_pmadd(lhs.template packet<Aligned>(row, Index), ei_pset1(rhs.coeff(Index, col)), res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Size, typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller<true, 0, Size, Lhs, Rhs, PacketScalar>
|
|
||||||
{
|
|
||||||
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
|
|
||||||
{
|
|
||||||
res = ei_pmul(ei_pset1(lhs.coeff(row, 0)),rhs.template packet<Aligned>(0, col));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Size, typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller<false, 0, Size, Lhs, Rhs, PacketScalar>
|
|
||||||
{
|
|
||||||
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
|
|
||||||
{
|
|
||||||
res = ei_pmul(lhs.template packet<Aligned>(row, 0), ei_pset1(rhs.coeff(0, col)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool RowMajor, int Index, typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller<RowMajor, Index, Dynamic, Lhs, Rhs, PacketScalar>
|
|
||||||
{
|
|
||||||
inline static void run(int, int, const Lhs&, const Rhs&, PacketScalar&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Index, typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller<false, Index, Dynamic, Lhs, Rhs, PacketScalar>
|
|
||||||
{
|
|
||||||
inline static void run(int, int, const Lhs&, const Rhs&, PacketScalar&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename PacketScalar>
|
|
||||||
struct ei_packet_product_unroller<false, 0, Dynamic, Lhs, Rhs, PacketScalar>
|
|
||||||
{
|
|
||||||
static void run(int, int, const Lhs&, const Rhs&, PacketScalar&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Product, bool RowMajor = true> struct ProductPacketImpl {
|
|
||||||
inline static typename Product::PacketScalar execute(const Product& product, int row, int col)
|
|
||||||
{ return product._packetRowMajor(row,col); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Product> struct ProductPacketImpl<Product, false> {
|
|
||||||
inline static typename Product::PacketScalar execute(const Product& product, int row, int col)
|
|
||||||
{ return product._packetColumnMajor(row,col); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class Product
|
|
||||||
*
|
|
||||||
* \brief Expression of the product of two matrices
|
|
||||||
*
|
|
||||||
* \param Lhs the type of the left-hand side
|
|
||||||
* \param Rhs the type of the right-hand side
|
|
||||||
* \param EvalMode internal use only
|
|
||||||
*
|
|
||||||
* This class represents an expression of the product of two matrices.
|
|
||||||
* It is the return type of the operator* between matrices, and most of the time
|
|
||||||
* this is the only way it is used.
|
|
||||||
*
|
|
||||||
* \sa class Sum, class Difference
|
|
||||||
*/
|
|
||||||
template<typename Lhs, typename Rhs> struct ei_product_eval_mode
|
|
||||||
{
|
|
||||||
enum{ value = Lhs::MaxRowsAtCompileTime >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|
|
||||||
&& Rhs::MaxColsAtCompileTime >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|
|
||||||
&& (!( (Lhs::Flags&RowMajorBit) && ((Rhs::Flags&RowMajorBit) ^ RowMajorBit)))
|
|
||||||
? CacheFriendlyProduct : NormalProduct };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int EvalMode>
|
|
||||||
struct ei_traits<Product<Lhs, Rhs, EvalMode> >
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Scalar Scalar;
|
|
||||||
typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
|
|
||||||
typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
|
|
||||||
typedef typename ei_unref<LhsNested>::type _LhsNested;
|
|
||||||
typedef typename ei_unref<RhsNested>::type _RhsNested;
|
|
||||||
enum {
|
|
||||||
LhsCoeffReadCost = _LhsNested::CoeffReadCost,
|
|
||||||
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
|
|
||||||
LhsFlags = _LhsNested::Flags,
|
|
||||||
RhsFlags = _RhsNested::Flags,
|
|
||||||
RowsAtCompileTime = Lhs::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = Rhs::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = Rhs::MaxColsAtCompileTime,
|
|
||||||
_RhsPacketAccess = (RhsFlags & RowMajorBit) && (RhsFlags & PacketAccessBit) && (ColsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
|
|
||||||
_LhsPacketAccess = (!(LhsFlags & RowMajorBit)) && (LhsFlags & PacketAccessBit) && (RowsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
|
|
||||||
_PacketAccess = (_LhsPacketAccess || _RhsPacketAccess) ? 1 : 0,
|
|
||||||
_RowMajor = (RhsFlags & RowMajorBit)
|
|
||||||
&& (EvalMode==(int)CacheFriendlyProduct ? (int)LhsFlags & RowMajorBit : (!_LhsPacketAccess)),
|
|
||||||
_LostBits = HereditaryBits & ~(
|
|
||||||
(_RowMajor ? 0 : RowMajorBit)
|
|
||||||
| ((RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic) ? 0 : LargeBit)),
|
|
||||||
Flags = ((unsigned int)(LhsFlags | RhsFlags) & _LostBits)
|
|
||||||
| EvalBeforeAssigningBit
|
|
||||||
| EvalBeforeNestingBit
|
|
||||||
| (_PacketAccess ? PacketAccessBit : 0),
|
|
||||||
CoeffReadCost
|
|
||||||
= Lhs::ColsAtCompileTime == Dynamic
|
|
||||||
? Dynamic
|
|
||||||
: Lhs::ColsAtCompileTime
|
|
||||||
* (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
|
|
||||||
+ (Lhs::ColsAtCompileTime - 1) * NumTraits<Scalar>::AddCost
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int EvalMode> class Product : ei_no_assignment_operator,
|
|
||||||
public MatrixBase<Product<Lhs, Rhs, EvalMode> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
|
|
||||||
friend class ProductPacketImpl<Product,Flags&RowMajorBit>;
|
|
||||||
typedef typename ei_traits<Product>::LhsNested LhsNested;
|
|
||||||
typedef typename ei_traits<Product>::RhsNested RhsNested;
|
|
||||||
typedef typename ei_traits<Product>::_LhsNested _LhsNested;
|
|
||||||
typedef typename ei_traits<Product>::_RhsNested _RhsNested;
|
|
||||||
|
|
||||||
inline Product(const Lhs& lhs, const Rhs& rhs)
|
|
||||||
: m_lhs(lhs), m_rhs(rhs)
|
|
||||||
{
|
|
||||||
ei_assert(lhs.cols() == rhs.rows());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal */
|
|
||||||
template<typename DestDerived, int AlignedMode>
|
|
||||||
void _cacheOptimalEval(DestDerived& res, ei_meta_false) const;
|
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
template<typename DestDerived, int AlignedMode>
|
|
||||||
void _cacheOptimalEval(DestDerived& res, ei_meta_true) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
inline int _rows() const { return m_lhs.rows(); }
|
|
||||||
inline int _cols() const { return m_rhs.cols(); }
|
|
||||||
|
|
||||||
const Scalar _coeff(int row, int col) const
|
|
||||||
{
|
|
||||||
Scalar res;
|
|
||||||
const bool unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT;
|
|
||||||
if(unroll)
|
|
||||||
{
|
|
||||||
ei_product_unroller<Lhs::ColsAtCompileTime-1,
|
|
||||||
unroll ? Lhs::ColsAtCompileTime : Dynamic,
|
|
||||||
_LhsNested, _RhsNested>
|
|
||||||
::run(row, col, m_lhs, m_rhs, res);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res = m_lhs.coeff(row, 0) * m_rhs.coeff(0, col);
|
|
||||||
for(int i = 1; i < m_lhs.cols(); i++)
|
|
||||||
res += m_lhs.coeff(row, i) * m_rhs.coeff(i, col);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
const PacketScalar _packet(int row, int col) const
|
|
||||||
{
|
|
||||||
if(Lhs::ColsAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
|
||||||
{
|
|
||||||
PacketScalar res;
|
|
||||||
ei_packet_product_unroller<Flags&RowMajorBit, Lhs::ColsAtCompileTime-1,
|
|
||||||
Lhs::ColsAtCompileTime <= EIGEN_UNROLLING_LIMIT
|
|
||||||
? Lhs::ColsAtCompileTime : Dynamic,
|
|
||||||
_LhsNested, _RhsNested, PacketScalar>
|
|
||||||
::run(row, col, m_lhs, m_rhs, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return ProductPacketImpl<Product,Flags&RowMajorBit>::execute(*this, row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
const PacketScalar _packetRowMajor(int row, int col) const
|
|
||||||
{
|
|
||||||
PacketScalar res;
|
|
||||||
res = ei_pmul(ei_pset1(m_lhs.coeff(row, 0)),m_rhs.template packet<Aligned>(0, col));
|
|
||||||
for(int i = 1; i < m_lhs.cols(); i++)
|
|
||||||
res = ei_pmadd(ei_pset1(m_lhs.coeff(row, i)), m_rhs.template packet<Aligned>(i, col), res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PacketScalar _packetColumnMajor(int row, int col) const
|
|
||||||
{
|
|
||||||
PacketScalar res;
|
|
||||||
res = ei_pmul(m_lhs.template packet<Aligned>(row, 0), ei_pset1(m_rhs.coeff(0, col)));
|
|
||||||
for(int i = 1; i < m_lhs.cols(); i++)
|
|
||||||
res = ei_pmadd(m_lhs.template packet<Aligned>(row, i), ei_pset1(m_rhs.coeff(i, col)), res);
|
|
||||||
return res;
|
|
||||||
// const PacketScalar tmp[4];
|
|
||||||
// ei_punpack(m_rhs.packet(0,col), tmp);
|
|
||||||
//
|
|
||||||
// return
|
|
||||||
// ei_pmadd(m_lhs.packet(row, 0), tmp[0],
|
|
||||||
// ei_pmadd(m_lhs.packet(row, 1), tmp[1],
|
|
||||||
// ei_pmadd(m_lhs.packet(row, 2), tmp[2]
|
|
||||||
// ei_pmul(m_lhs.packet(row, 3), tmp[3]))));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const LhsNested m_lhs;
|
|
||||||
const RhsNested m_rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \returns the matrix product of \c *this and \a other.
|
|
||||||
*
|
|
||||||
* \note This function causes an immediate evaluation. If you want to perform a matrix product
|
|
||||||
* without immediate evaluation, call .lazy() on one of the matrices before taking the product.
|
|
||||||
*
|
|
||||||
* \sa lazy(), operator*=(const MatrixBase&)
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline const Product<Derived,OtherDerived>
|
|
||||||
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|
||||||
{
|
|
||||||
return Product<Derived,OtherDerived>(derived(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** replaces \c *this by \c *this * \a other.
|
|
||||||
*
|
|
||||||
* \returns a reference to \c *this
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline Derived &
|
|
||||||
MatrixBase<Derived>::operator*=(const MatrixBase<OtherDerived> &other)
|
|
||||||
{
|
|
||||||
return *this = *this * other;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
inline Derived& MatrixBase<Derived>::lazyAssign(const Product<Lhs,Rhs,CacheFriendlyProduct>& product)
|
|
||||||
{
|
|
||||||
product.template _cacheOptimalEval<Derived, Aligned>(derived(),
|
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
typename ei_meta_if<Flags & PacketAccessBit, ei_meta_true, ei_meta_false>::ret()
|
|
||||||
#else
|
|
||||||
ei_meta_false()
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int EvalMode>
|
|
||||||
template<typename DestDerived, int AlignedMode>
|
|
||||||
void Product<Lhs,Rhs,EvalMode>::_cacheOptimalEval(DestDerived& res, ei_meta_false) const
|
|
||||||
{
|
|
||||||
res.setZero();
|
|
||||||
const int cols4 = m_lhs.cols() & 0xfffffffC;
|
|
||||||
if (Lhs::Flags&RowMajorBit)
|
|
||||||
{
|
|
||||||
// std::cout << "opt rhs\n";
|
|
||||||
int j=0;
|
|
||||||
for(; j<cols4; j+=4)
|
|
||||||
{
|
|
||||||
for(int k=0; k<this->rows(); ++k)
|
|
||||||
{
|
|
||||||
const Scalar tmp0 = m_lhs.coeff(k,j );
|
|
||||||
const Scalar tmp1 = m_lhs.coeff(k,j+1);
|
|
||||||
const Scalar tmp2 = m_lhs.coeff(k,j+2);
|
|
||||||
const Scalar tmp3 = m_lhs.coeff(k,j+3);
|
|
||||||
for (int i=0; i<this->cols(); ++i)
|
|
||||||
res.coeffRef(k,i) += tmp0 * m_rhs.coeff(j+0,i) + tmp1 * m_rhs.coeff(j+1,i)
|
|
||||||
+ tmp2 * m_rhs.coeff(j+2,i) + tmp3 * m_rhs.coeff(j+3,i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(; j<m_lhs.cols(); ++j)
|
|
||||||
{
|
|
||||||
for(int k=0; k<this->rows(); ++k)
|
|
||||||
{
|
|
||||||
const Scalar tmp = m_rhs.coeff(k,j);
|
|
||||||
for (int i=0; i<this->cols(); ++i)
|
|
||||||
res.coeffRef(k,i) += tmp * m_lhs.coeff(j,i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// std::cout << "opt lhs\n";
|
|
||||||
int j = 0;
|
|
||||||
for(; j<cols4; j+=4)
|
|
||||||
{
|
|
||||||
for(int k=0; k<this->cols(); ++k)
|
|
||||||
{
|
|
||||||
const Scalar tmp0 = m_rhs.coeff(j ,k);
|
|
||||||
const Scalar tmp1 = m_rhs.coeff(j+1,k);
|
|
||||||
const Scalar tmp2 = m_rhs.coeff(j+2,k);
|
|
||||||
const Scalar tmp3 = m_rhs.coeff(j+3,k);
|
|
||||||
for (int i=0; i<this->rows(); ++i)
|
|
||||||
res.coeffRef(i,k) += tmp0 * m_lhs.coeff(i,j+0) + tmp1 * m_lhs.coeff(i,j+1)
|
|
||||||
+ tmp2 * m_lhs.coeff(i,j+2) + tmp3 * m_lhs.coeff(i,j+3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(; j<m_lhs.cols(); ++j)
|
|
||||||
{
|
|
||||||
for(int k=0; k<this->cols(); ++k)
|
|
||||||
{
|
|
||||||
const Scalar tmp = m_rhs.coeff(j,k);
|
|
||||||
for (int i=0; i<this->rows(); ++i)
|
|
||||||
res.coeffRef(i,k) += tmp * m_lhs.coeff(i,j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
template<typename Lhs, typename Rhs, int EvalMode>
|
|
||||||
template<typename DestDerived, int AlignedMode>
|
|
||||||
void Product<Lhs,Rhs,EvalMode>::_cacheOptimalEval(DestDerived& res, ei_meta_true) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (((Lhs::Flags&RowMajorBit) && (_cols() % ei_packet_traits<Scalar>::size != 0))
|
|
||||||
|| (_rows() % ei_packet_traits<Scalar>::size != 0))
|
|
||||||
{
|
|
||||||
return _cacheOptimalEval<DestDerived, AlignedMode>(res, ei_meta_false());
|
|
||||||
}
|
|
||||||
|
|
||||||
res.setZero();
|
|
||||||
const int cols4 = m_lhs.cols() & 0xfffffffC;
|
|
||||||
if (Lhs::Flags&RowMajorBit)
|
|
||||||
{
|
|
||||||
// std::cout << "packet rhs\n";
|
|
||||||
int j=0;
|
|
||||||
for(; j<cols4; j+=4)
|
|
||||||
{
|
|
||||||
for(int k=0; k<this->rows(); k++)
|
|
||||||
{
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp0 = ei_pset1(m_lhs.coeff(k,j+0));
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp1 = ei_pset1(m_lhs.coeff(k,j+1));
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp2 = ei_pset1(m_lhs.coeff(k,j+2));
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp3 = ei_pset1(m_lhs.coeff(k,j+3));
|
|
||||||
for (int i=0; i<this->cols(); i+=ei_packet_traits<Scalar>::size)
|
|
||||||
{
|
|
||||||
res.template writePacket<AlignedMode>(k,i,
|
|
||||||
ei_pmadd(tmp0, m_rhs.template packet<AlignedMode>(j+0,i),
|
|
||||||
ei_pmadd(tmp1, m_rhs.template packet<AlignedMode>(j+1,i),
|
|
||||||
ei_pmadd(tmp2, m_rhs.template packet<AlignedMode>(j+2,i),
|
|
||||||
ei_pmadd(tmp3, m_rhs.template packet<AlignedMode>(j+3,i),
|
|
||||||
res.template packet<AlignedMode>(k,i)))))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(; j<m_lhs.cols(); ++j)
|
|
||||||
{
|
|
||||||
for(int k=0; k<this->rows(); k++)
|
|
||||||
{
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp = ei_pset1(m_lhs.coeff(k,j));
|
|
||||||
for (int i=0; i<this->cols(); i+=ei_packet_traits<Scalar>::size)
|
|
||||||
res.template writePacket<AlignedMode>(k,i,
|
|
||||||
ei_pmadd(tmp, m_rhs.template packet<AlignedMode>(j,i), res.template packet<AlignedMode>(k,i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// std::cout << "packet lhs\n";
|
|
||||||
int k=0;
|
|
||||||
for(; k<cols4; k+=4)
|
|
||||||
{
|
|
||||||
for(int j=0; j<this->cols(); j+=1)
|
|
||||||
{
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp0 = ei_pset1(m_rhs.coeff(k+0,j));
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp1 = ei_pset1(m_rhs.coeff(k+1,j));
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp2 = ei_pset1(m_rhs.coeff(k+2,j));
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp3 = ei_pset1(m_rhs.coeff(k+3,j));
|
|
||||||
|
|
||||||
for (int i=0; i<this->rows(); i+=ei_packet_traits<Scalar>::size)
|
|
||||||
{
|
|
||||||
res.template writePacket<AlignedMode>(i,j,
|
|
||||||
ei_pmadd(tmp0, m_lhs.template packet<AlignedMode>(i,k),
|
|
||||||
ei_pmadd(tmp1, m_lhs.template packet<AlignedMode>(i,k+1),
|
|
||||||
ei_pmadd(tmp2, m_lhs.template packet<AlignedMode>(i,k+2),
|
|
||||||
ei_pmadd(tmp3, m_lhs.template packet<AlignedMode>(i,k+3),
|
|
||||||
res.template packet<AlignedMode>(i,j)))))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(; k<m_lhs.cols(); ++k)
|
|
||||||
{
|
|
||||||
for(int j=0; j<this->cols(); j++)
|
|
||||||
{
|
|
||||||
const typename ei_packet_traits<Scalar>::type tmp = ei_pset1(m_rhs.coeff(k,j));
|
|
||||||
for (int i=0; i<this->rows(); i+=ei_packet_traits<Scalar>::size)
|
|
||||||
res.template writePacket<AlignedMode>(k,j,
|
|
||||||
ei_pmadd(tmp, m_lhs.template packet<AlignedMode>(i,k), res.template packet<AlignedMode>(i,j)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // EIGEN_VECTORIZE
|
|
||||||
|
|
||||||
#endif // EIGEN_PRODUCT_H
|
|
@ -1,154 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_BANDMATRIX_H
|
|
||||||
#define EIGEN_BANDMATRIX_H
|
|
||||||
|
|
||||||
/** \nonstableyet
|
|
||||||
* \class BandMatrix
|
|
||||||
*
|
|
||||||
* \brief
|
|
||||||
*
|
|
||||||
* \param
|
|
||||||
*
|
|
||||||
* \sa
|
|
||||||
*/
|
|
||||||
template<typename _Scalar, int Size, int Supers, int Subs, int Options>
|
|
||||||
struct ei_traits<BandMatrix<_Scalar,Size,Supers,Subs,Options> >
|
|
||||||
{
|
|
||||||
typedef _Scalar Scalar;
|
|
||||||
enum {
|
|
||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
|
||||||
RowsAtCompileTime = Size,
|
|
||||||
ColsAtCompileTime = Size,
|
|
||||||
MaxRowsAtCompileTime = Size,
|
|
||||||
MaxColsAtCompileTime = Size,
|
|
||||||
Flags = 0
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _Scalar, int Size, int Supers, int Subs, int Options>
|
|
||||||
class BandMatrix : public MultiplierBase<BandMatrix<_Scalar,Supers,Subs,Options> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum {
|
|
||||||
Flags = ei_traits<BandMatrix>::Flags,
|
|
||||||
CoeffReadCost = ei_traits<BandMatrix>::CoeffReadCost,
|
|
||||||
RowsAtCompileTime = ei_traits<BandMatrix>::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = ei_traits<BandMatrix>::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = ei_traits<BandMatrix>::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = ei_traits<BandMatrix>::MaxColsAtCompileTime
|
|
||||||
};
|
|
||||||
typedef typename ei_traits<BandMatrix>::Scalar Scalar;
|
|
||||||
typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> PlainObject;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
enum {
|
|
||||||
DataSizeAtCompileTime = ((Size!=Dynamic) && (Supers!=Dynamic) && (Subs!=Dynamic))
|
|
||||||
? Size*(Supers+Subs+1) - (Supers*Supers+Subs*Subs)/2
|
|
||||||
: Dynamic
|
|
||||||
};
|
|
||||||
typedef Matrix<Scalar,DataSizeAtCompileTime,1> DataType;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// inline BandMatrix() { }
|
|
||||||
|
|
||||||
inline BandMatrix(int size=Size, int supers=Supers, int subs=Subs)
|
|
||||||
: m_data(size*(supers+subs+1) - (supers*supers+subs*subs)/2),
|
|
||||||
m_size(size), m_supers(supers), m_subs(subs)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline int rows() const { return m_size.value(); }
|
|
||||||
inline int cols() const { return m_size.value(); }
|
|
||||||
|
|
||||||
inline int supers() const { return m_supers.value(); }
|
|
||||||
inline int subs() const { return m_subs.value(); }
|
|
||||||
|
|
||||||
inline VectorBlock<DataType,Size> diagonal()
|
|
||||||
{ return VectorBlock<DataType,Size>(m_data,0,m_size.value()); }
|
|
||||||
|
|
||||||
inline const VectorBlock<DataType,Size> diagonal() const
|
|
||||||
{ return VectorBlock<DataType,Size>(m_data,0,m_size.value()); }
|
|
||||||
|
|
||||||
template<int Index>
|
|
||||||
VectorBlock<DataType,Size==Dynamic?Dynamic:Size-(Index<0?-Index:Index)>
|
|
||||||
diagonal()
|
|
||||||
{
|
|
||||||
return VectorBlock<DataType,Size==Dynamic?Dynamic:Size-(Index<0?-Index:Index)>
|
|
||||||
(m_data,Index<0 ? subDiagIndex(-Index) : superDiagIndex(Index), m_size.value()-ei_abs(Index));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int Index>
|
|
||||||
const VectorBlock<DataType,Size==Dynamic?Dynamic:Size-(Index<0?-Index:Index)>
|
|
||||||
diagonal() const
|
|
||||||
{
|
|
||||||
return VectorBlock<DataType,Size==Dynamic?Dynamic:Size-(Index<0?-Index:Index)>
|
|
||||||
(m_data,Index<0 ? subDiagIndex(-Index) : superDiagIndex(Index), m_size.value()-ei_abs(Index));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline VectorBlock<DataType,Dynamic> diagonal(int index)
|
|
||||||
{
|
|
||||||
ei_assert((index<0 && -index<=subs()) || (index>=0 && index<=supers()));
|
|
||||||
return VectorBlock<DataType,Dynamic>(m_data,
|
|
||||||
index<0 ? subDiagIndex(-index) : superDiagIndex(index), m_size.value()-ei_abs(index));
|
|
||||||
}
|
|
||||||
const VectorBlock<DataType,Dynamic> diagonal(int index) const
|
|
||||||
{
|
|
||||||
ei_assert((index<0 && -index<=subs()) || (index>=0 && index<=supers()));
|
|
||||||
return VectorBlock<DataType,Dynamic>(m_data,
|
|
||||||
index<0 ? subDiagIndex(-index) : superDiagIndex(index), m_size.value()-ei_abs(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
// inline VectorBlock<DataType,Size> subDiagonal()
|
|
||||||
// { return VectorBlock<DataType,Size>(m_data,0,m_size.value()); }
|
|
||||||
|
|
||||||
PlainObject toDense() const
|
|
||||||
{
|
|
||||||
PlainObject res(rows(),cols());
|
|
||||||
res.setZero();
|
|
||||||
res.diagonal() = diagonal();
|
|
||||||
for (int i=1; i<=supers();++i)
|
|
||||||
res.diagonal(i) = diagonal(i);
|
|
||||||
for (int i=1; i<=subs();++i)
|
|
||||||
res.diagonal(-i) = diagonal(-i);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
inline int subDiagIndex(int i) const
|
|
||||||
{ return m_size.value()*(m_supers.value()+i)-(ei_abs2(i-1) + ei_abs2(m_supers.value()))/2; }
|
|
||||||
|
|
||||||
inline int superDiagIndex(int i) const
|
|
||||||
{ return m_size.value()*i-ei_abs2(i-1)/2; }
|
|
||||||
|
|
||||||
DataType m_data;
|
|
||||||
ei_int_if_dynamic<Size> m_size;
|
|
||||||
ei_int_if_dynamic<Supers> m_supers;
|
|
||||||
ei_int_if_dynamic<Subs> m_subs;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_BANDMATRIX_H
|
|
@ -1,138 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_SPARSESETTER_H
|
|
||||||
#define EIGEN_SPARSESETTER_H
|
|
||||||
|
|
||||||
template<typename MatrixType, int AccessPattern,
|
|
||||||
int IsSupported = ei_support_access_pattern<MatrixType,AccessPattern>::ret>
|
|
||||||
struct ei_sparse_setter_selector;
|
|
||||||
|
|
||||||
/** \class SparseSetter
|
|
||||||
*
|
|
||||||
* Goal: provides a unified API to fill/update a dense or sparse matrix.
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* \code
|
|
||||||
* {
|
|
||||||
* SparseSetter<MatrixType, RandomAccessPattern> w(m);
|
|
||||||
* for (...) w->coeffRef(rand(),rand()) = rand();
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In the above example we want to fill a matrix m (could be a SparseMatrix or whatever other matrix type)
|
|
||||||
* in a random fashion (whence the RandomAccessPattern). Internally, if \a MatrixType supports random writes
|
|
||||||
* then \c w behaves as a pointer to m, and m is filled directly. Otherwise, a temporary matrix supporting
|
|
||||||
* random writes is created and \c w behaves as a pointer to this temporary object. When the object \c w
|
|
||||||
* is deleted (at the end of the block), then the temporary object is assigned to the matrix m.
|
|
||||||
*
|
|
||||||
* So far we can distinghished 4 types of access pattern:
|
|
||||||
* - FullyCoherentAccessPattern (if col major, i+j*rows must increase)
|
|
||||||
* - InnerCoherentAccessPattern (if col major, i must increase for each column j)
|
|
||||||
* - OuterCoherentAccessPattern (if col major, the column j is set in a random order, but j must increase)
|
|
||||||
* - RandomAccessPattern
|
|
||||||
*
|
|
||||||
* See the wiki for more details.
|
|
||||||
*
|
|
||||||
* The template class ei_support_access_pattern is used to determine the type of the temporary object (which
|
|
||||||
* can be a reference to \a MatrixType if \a MatrixType support \a AccessPattern)
|
|
||||||
*
|
|
||||||
* Currently only the RandomAccessPattern seems to work as expected.
|
|
||||||
*
|
|
||||||
* \todo define the API for each kind of access pattern
|
|
||||||
* \todo allows both update and set modes (set start a new matrix)
|
|
||||||
* \todo implement the OuterCoherentAccessPattern
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template<typename MatrixType,
|
|
||||||
int AccessPattern,
|
|
||||||
typename WrapperType = typename ei_sparse_setter_selector<MatrixType,AccessPattern>::type>
|
|
||||||
class SparseSetter
|
|
||||||
{
|
|
||||||
typedef typename ei_unref<WrapperType>::type _WrapperType;
|
|
||||||
public:
|
|
||||||
|
|
||||||
inline SparseSetter(MatrixType& matrix) : m_wrapper(matrix), mp_matrix(&matrix) {}
|
|
||||||
|
|
||||||
~SparseSetter()
|
|
||||||
{ *mp_matrix = m_wrapper; }
|
|
||||||
|
|
||||||
inline _WrapperType* operator->() { return &m_wrapper; }
|
|
||||||
|
|
||||||
inline _WrapperType& operator*() { return m_wrapper; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
WrapperType m_wrapper;
|
|
||||||
MatrixType* mp_matrix;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename MatrixType, int AccessPattern>
|
|
||||||
struct ei_sparse_setter_selector<MatrixType, AccessPattern, AccessPatternSupported>
|
|
||||||
{
|
|
||||||
typedef MatrixType& type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// forward each derived of SparseMatrixBase to the generic SparseMatrixBase specializations
|
|
||||||
template<typename Scalar, int Flags, int AccessPattern>
|
|
||||||
struct ei_sparse_setter_selector<SparseMatrix<Scalar,Flags>, AccessPattern, AccessPatternNotSupported>
|
|
||||||
: public ei_sparse_setter_selector<SparseMatrixBase<SparseMatrix<Scalar,Flags> >,AccessPattern, AccessPatternNotSupported>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename Scalar, int Flags, int AccessPattern>
|
|
||||||
struct ei_sparse_setter_selector<LinkedVectorMatrix<Scalar,Flags>, AccessPattern, AccessPatternNotSupported>
|
|
||||||
: public ei_sparse_setter_selector<LinkedVectorMatrix<SparseMatrix<Scalar,Flags> >,AccessPattern, AccessPatternNotSupported>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename Scalar, int Flags, int AccessPattern>
|
|
||||||
struct ei_sparse_setter_selector<HashMatrix<Scalar,Flags>, AccessPattern, AccessPatternNotSupported>
|
|
||||||
: public ei_sparse_setter_selector<HashMatrix<SparseMatrix<Scalar,Flags> >,AccessPattern, AccessPatternNotSupported>
|
|
||||||
{};
|
|
||||||
|
|
||||||
// generic SparseMatrixBase specializations
|
|
||||||
template<typename Derived>
|
|
||||||
struct ei_sparse_setter_selector<SparseMatrixBase<Derived>, RandomAccessPattern, AccessPatternNotSupported>
|
|
||||||
{
|
|
||||||
typedef HashMatrix<typename Derived::Scalar, Derived::Flags> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
struct ei_sparse_setter_selector<SparseMatrixBase<Derived>, OuterCoherentAccessPattern, AccessPatternNotSupported>
|
|
||||||
{
|
|
||||||
typedef HashMatrix<typename Derived::Scalar, Derived::Flags> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
struct ei_sparse_setter_selector<SparseMatrixBase<Derived>, InnerCoherentAccessPattern, AccessPatternNotSupported>
|
|
||||||
{
|
|
||||||
typedef LinkedVectorMatrix<typename Derived::Scalar, Derived::Flags> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
struct ei_sparse_setter_selector<SparseMatrixBase<Derived>, FullyCoherentAccessPattern, AccessPatternNotSupported>
|
|
||||||
{
|
|
||||||
typedef SparseMatrix<typename Derived::Scalar, Derived::Flags> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_SPARSESETTER_H
|
|
@ -1,44 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
CXX=`which g++`
|
|
||||||
SRC=$1
|
|
||||||
mkdir -p eigen2/out
|
|
||||||
|
|
||||||
if expr match $SRC ".*\/examples\/.*" > /dev/null ; then
|
|
||||||
|
|
||||||
# DST=`echo $SRC | sed 's/examples/out/' | sed 's/cpp$/out/'`
|
|
||||||
DST=`echo $SRC | sed 's/.*\/examples/eigen2\/out/' | sed 's/cpp$/out/'`
|
|
||||||
INC=`echo $SRC | sed 's/\/doc\/examples\/.*/\//'`
|
|
||||||
|
|
||||||
if ! test -e $DST || test $SRC -nt $DST ; then
|
|
||||||
$CXX $SRC -I. -I$INC -o eitmp_example && ./eitmp_example > $DST
|
|
||||||
rm eitmp_example
|
|
||||||
fi
|
|
||||||
|
|
||||||
elif expr match $SRC ".*\/snippets\/.*" > /dev/null ; then
|
|
||||||
|
|
||||||
# DST=`echo $SRC | sed 's/snippets/out/' | sed 's/cpp$/out/'`
|
|
||||||
DST=`echo $SRC | sed 's/.*\/snippets/eigen2\/out/' | sed 's/cpp$/out/'`
|
|
||||||
INC=`echo $SRC | sed 's/\/doc\/snippets\/.*/\//'`
|
|
||||||
|
|
||||||
if ! test -e $DST || test $SRC -nt $DST ; then
|
|
||||||
echo "#include <Eigen/Core>" > .ei_in.cpp
|
|
||||||
echo "#include <Eigen/Array>" >> .ei_in.cpp
|
|
||||||
echo "#include <Eigen/LU>" >> .ei_in.cpp
|
|
||||||
echo "#include <Eigen/Cholesky>" >> .ei_in.cpp
|
|
||||||
echo "#include <Eigen/Geometry>" >> .ei_in.cpp
|
|
||||||
echo "using namespace Eigen; using namespace std;" >> .ei_in.cpp
|
|
||||||
echo "int main(int, char**){cout.precision(3);" >> .ei_in.cpp
|
|
||||||
cat $SRC >> .ei_in.cpp
|
|
||||||
echo "return 0;}" >> .ei_in.cpp
|
|
||||||
echo " " >> .ei_in.cpp
|
|
||||||
|
|
||||||
$CXX .ei_in.cpp -I. -I$INC -o eitmp_example && ./eitmp_example > $DST
|
|
||||||
rm eitmp_example
|
|
||||||
rm .ei_in.cpp
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat $SRC
|
|
||||||
exit 0
|
|
@ -1,15 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
echo "namespace Eigen {"
|
|
||||||
echo "/** \page ExampleList"
|
|
||||||
echo "<h1>Selected list of examples</h1>"
|
|
||||||
|
|
||||||
grep \\addexample $1/Eigen/src/*/*.h -R | cut -d \\ -f 2- | \
|
|
||||||
while read example;
|
|
||||||
do
|
|
||||||
anchor=`echo "$example" | cut -d " " -f 2`
|
|
||||||
text=`echo "$example" | cut -d " " -f 4-`
|
|
||||||
echo "\\\li \\\ref $anchor \"$text\""
|
|
||||||
done
|
|
||||||
echo "*/"
|
|
||||||
echo "}"
|
|
@ -1,28 +0,0 @@
|
|||||||
#include <Eigen/Core>
|
|
||||||
using namespace Eigen;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
const Eigen::Eval<Eigen::Transpose<Derived> >
|
|
||||||
evaluatedTranspose(const MatrixBase<Derived>& m)
|
|
||||||
{
|
|
||||||
return m.transpose().eval();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int, char**)
|
|
||||||
{
|
|
||||||
Matrix2f M = Matrix2f::random();
|
|
||||||
Matrix2f m;
|
|
||||||
m = M;
|
|
||||||
cout << "Here is the matrix m:" << endl << m << endl;
|
|
||||||
cout << "Now we want to replace m by its own transpose." << endl;
|
|
||||||
cout << "If we do m = m.transpose(), then m becomes:" << endl;
|
|
||||||
m = m.transpose();
|
|
||||||
cout << m << endl << "which is wrong!" << endl;
|
|
||||||
cout << "Now let us instead do m = evaluatedTranspose(m). Then m becomes" << endl;
|
|
||||||
m = M;
|
|
||||||
m = evaluatedTranspose(m);
|
|
||||||
cout << m << endl << "which is right." << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
sed -i 's/^.li.*MatrixBase\<.*gt.*a.$/ /g' $1
|
|
||||||
sed -i 's/^.li.*MapBase\<.*gt.*a.$/ /g' $1
|
|
||||||
sed -i 's/^.li.*RotationBase\<.*gt.*a.$/ /g' $1
|
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG -finline-limit=10000 -fopenmp"
|
|
||||||
|
|
||||||
# CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG -finline-limit=10000 -fopenmp"
|
|
||||||
|
|
||||||
CLIST[((g++))]="icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -openmp"
|
|
@ -1,81 +0,0 @@
|
|||||||
// g++ -O3 -DNDEBUG -I.. -fopenmp benchOpenMP.cpp -o benchOpenMP && ./benchOpenMP 2> /dev/null
|
|
||||||
// icpc -fast -fno-exceptions -DNDEBUG -I.. -openmp benchOpenMP.cpp -o benchOpenMP && ./benchOpenMP 2> /dev/null
|
|
||||||
|
|
||||||
#include <omp.h>
|
|
||||||
#include "BenchUtil.h"
|
|
||||||
#include "basicbenchmark.h"
|
|
||||||
|
|
||||||
// #include <Eigen/Core>
|
|
||||||
// #include "BenchTimer.h"
|
|
||||||
//
|
|
||||||
// using namespace std;
|
|
||||||
// using namespace Eigen;
|
|
||||||
//
|
|
||||||
// enum {LazyEval, EarlyEval, OmpEval};
|
|
||||||
//
|
|
||||||
// template<int Mode, typename MatrixType>
|
|
||||||
// double benchSingleProc(const MatrixType& mat, int iterations, int tries) __attribute__((noinline));
|
|
||||||
//
|
|
||||||
// template<int Mode, typename MatrixType>
|
|
||||||
// double benchBasic(const MatrixType& mat, int iterations, int tries)
|
|
||||||
// {
|
|
||||||
// const int rows = mat.rows();
|
|
||||||
// const int cols = mat.cols();
|
|
||||||
//
|
|
||||||
// Eigen::BenchTimer timer;
|
|
||||||
// for(uint t=0; t<tries; ++t)
|
|
||||||
// {
|
|
||||||
// MatrixType I = MatrixType::identity(rows, cols);
|
|
||||||
// MatrixType m = MatrixType::random(rows, cols);
|
|
||||||
//
|
|
||||||
// timer.start();
|
|
||||||
// for(int a = 0; a < iterations; a++)
|
|
||||||
// {
|
|
||||||
// if(Mode==LazyEval)
|
|
||||||
// m = (I + 0.00005 * (m + m.lazyProduct(m))).eval();
|
|
||||||
// else if(Mode==OmpEval)
|
|
||||||
// m = (I + 0.00005 * (m + m.lazyProduct(m))).evalOMP();
|
|
||||||
// else
|
|
||||||
// m = I + 0.00005 * (m + m * m);
|
|
||||||
// }
|
|
||||||
// timer.stop();
|
|
||||||
// cerr << m;
|
|
||||||
// }
|
|
||||||
// return timer.value();
|
|
||||||
// };
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
// disable floating point exceptions
|
|
||||||
// this leads to more stable bench results
|
|
||||||
{
|
|
||||||
int aux;
|
|
||||||
asm(
|
|
||||||
"stmxcsr %[aux] \n\t"
|
|
||||||
"orl $32832, %[aux] \n\t"
|
|
||||||
"ldmxcsr %[aux] \n\t"
|
|
||||||
: : [aux] "m" (aux));
|
|
||||||
}
|
|
||||||
|
|
||||||
// commented since the default setting is use as many threads as processors
|
|
||||||
//omp_set_num_threads(omp_get_num_procs());
|
|
||||||
|
|
||||||
std::cout << "double, fixed-size 4x4: "
|
|
||||||
<< benchBasic<LazyEval>(Matrix4d(), 10000, 10) << "s "
|
|
||||||
<< benchBasic<OmpEval>(Matrix4d(), 10000, 10) << "s \n";
|
|
||||||
|
|
||||||
#define BENCH_MATRIX(TYPE, SIZE, ITERATIONS, TRIES) {\
|
|
||||||
double single = benchBasic<LazyEval>(Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic>(SIZE,SIZE), ITERATIONS, TRIES); \
|
|
||||||
double omp = benchBasic<OmpEval> (Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic>(SIZE,SIZE), ITERATIONS, TRIES); \
|
|
||||||
std::cout << #TYPE << ", " << #SIZE << "x" << #SIZE << ": " << single << "s " << omp << "s " \
|
|
||||||
<< " => x" << single/omp << " (" << omp_get_num_procs() << ")" << std::endl; \
|
|
||||||
}
|
|
||||||
|
|
||||||
BENCH_MATRIX(double, 32, 1000, 10);
|
|
||||||
BENCH_MATRIX(double, 128, 10, 10);
|
|
||||||
BENCH_MATRIX(double, 512, 1, 6);
|
|
||||||
BENCH_MATRIX(double, 1024, 1, 4);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user