aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/SelfCwiseBinaryOp.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-11-20 15:39:38 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-11-20 15:39:38 +0100
commiteb8f4500719b52f410c545f738d8fda399cea587 (patch)
tree33ac90a04b6e6b3de516f2851895d92687b4db6a /Eigen/src/Core/SelfCwiseBinaryOp.h
parente3d890bc5a89798eff50ff6650292b4fa934f72e (diff)
Hey, finally the copyCoeff stuff is not only used to implement swap anymore :)
Add an internal pseudo expression allowing to optimize operators like +=, *= using the copyCoeff stuff. This allows to easily enforce aligned load for the destination matrix everywhere.
Diffstat (limited to 'Eigen/src/Core/SelfCwiseBinaryOp.h')
-rw-r--r--Eigen/src/Core/SelfCwiseBinaryOp.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/Eigen/src/Core/SelfCwiseBinaryOp.h b/Eigen/src/Core/SelfCwiseBinaryOp.h
new file mode 100644
index 000000000..ac0ccd963
--- /dev/null
+++ b/Eigen/src/Core/SelfCwiseBinaryOp.h
@@ -0,0 +1,113 @@
+// 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_SELFCWISEBINARYOP_H
+#define EIGEN_SELFCWISEBINARYOP_H
+
+/** \class SelfCwiseBinaryOp
+ *
+ * \internal
+ *
+ * \brief Internal helper class for optimizing operators like +=, -=
+ */
+template<typename BinaryOp, typename MatrixType>
+struct ei_traits<SelfCwiseBinaryOp<BinaryOp,MatrixType> > : ei_traits<MatrixType> {};
+
+template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp
+ : public MatrixBase<SelfCwiseBinaryOp<BinaryOp,MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
+ typedef typename ei_packet_traits<Scalar>::type Packet;
+
+ using Base::operator=;
+
+ inline SelfCwiseBinaryOp(MatrixType& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {}
+
+ inline int rows() const { return m_matrix.rows(); }
+ inline int cols() const { return m_matrix.cols(); }
+ inline int stride() const { return m_matrix.stride(); }
+
+ // note that this function is needed by assign to correctly align loads/stores
+ // TODO make Assign use .data()
+ inline Scalar& coeffRef(int row, int col)
+ {
+ return m_matrix.const_cast_derived().coeffRef(row, col);
+ }
+
+ // note that this function is needed by assign to correctly align loads/stores
+ // TODO make Assign use .data()
+ inline Scalar& coeffRef(int index)
+ {
+ return m_matrix.const_cast_derived().coeffRef(index);
+ }
+
+ template<typename OtherDerived>
+ void copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ Scalar& tmp = m_matrix.coeffRef(row,col);
+ tmp = m_functor(tmp, _other.coeff(row,col));
+ }
+
+ template<typename OtherDerived>
+ void copyCoeff(int index, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(index >= 0 && index < m_matrix.size());
+ Scalar& tmp = m_matrix.coeffRef(index);
+ tmp = m_functor(tmp, _other.coeff(index));
+ }
+
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ void copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ m_matrix.template writePacket<StoreMode>(row, col,
+ m_functor.packetOp(m_matrix.template packet<StoreMode>(row, col),_other.template packet<LoadMode>(row, col)) );
+ }
+
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ void copyPacket(int index, const MatrixBase<OtherDerived>& other)
+ {
+ OtherDerived& _other = other.const_cast_derived();
+ ei_internal_assert(index >= 0 && index < m_matrix.size());
+ m_matrix.template writePacket<StoreMode>(index,
+ m_functor.packetOp(m_matrix.template packet<StoreMode>(index),_other.template packet<LoadMode>(index)) );
+ }
+
+ protected:
+ MatrixType& m_matrix;
+ const BinaryOp& m_functor;
+
+ private:
+ SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&);
+};
+
+#endif // EIGEN_SELFCWISEBINARYOP_H