CwiseNullaryOp.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_CWISE_NULLARY_OP_H
00026 #define EIGEN_CWISE_NULLARY_OP_H
00027 
00028 namespace Eigen {
00029 
00048 namespace internal {
00049 template<typename NullaryOp, typename PlainObjectType>
00050 struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
00051 {
00052   enum {
00053     Flags = (traits<PlainObjectType>::Flags
00054       & (  HereditaryBits
00055          | (functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
00056          | (functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0)))
00057       | (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
00058     CoeffReadCost = functor_traits<NullaryOp>::Cost
00059   };
00060 };
00061 }
00062 
00063 template<typename NullaryOp, typename PlainObjectType>
00064 class CwiseNullaryOp : internal::no_assignment_operator,
00065   public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type
00066 {
00067   public:
00068 
00069     typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
00070     EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
00071 
00072     CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
00073       : m_rows(rows), m_cols(cols), m_functor(func)
00074     {
00075       eigen_assert(rows >= 0
00076             && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
00077             &&  cols >= 0
00078             && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
00079     }
00080 
00081     EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
00082     EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
00083 
00084     EIGEN_STRONG_INLINE const Scalar coeff(Index rows, Index cols) const
00085     {
00086       return m_functor(rows, cols);
00087     }
00088 
00089     template<int LoadMode>
00090     EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
00091     {
00092       return m_functor.packetOp(row, col);
00093     }
00094 
00095     EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
00096     {
00097       return m_functor(index);
00098     }
00099 
00100     template<int LoadMode>
00101     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00102     {
00103       return m_functor.packetOp(index);
00104     }
00105 
00107     const NullaryOp& functor() const { return m_functor; }
00108 
00109   protected:
00110     const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
00111     const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
00112     const NullaryOp m_functor;
00113 };
00114 
00115 
00129 template<typename Derived>
00130 template<typename CustomNullaryOp>
00131 EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
00132 DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
00133 {
00134   return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func);
00135 }
00136 
00152 template<typename Derived>
00153 template<typename CustomNullaryOp>
00154 EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
00155 DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
00156 {
00157   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00158   if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func);
00159   else return CwiseNullaryOp<CustomNullaryOp, Derived>(size, 1, func);
00160 }
00161 
00171 template<typename Derived>
00172 template<typename CustomNullaryOp>
00173 EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
00174 DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
00175 {
00176   return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func);
00177 }
00178 
00192 template<typename Derived>
00193 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00194 DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
00195 {
00196   return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
00197 }
00198 
00214 template<typename Derived>
00215 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00216 DenseBase<Derived>::Constant(Index size, const Scalar& value)
00217 {
00218   return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value));
00219 }
00220 
00230 template<typename Derived>
00231 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00232 DenseBase<Derived>::Constant(const Scalar& value)
00233 {
00234   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
00235   return DenseBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op<Scalar>(value));
00236 }
00237 
00255 template<typename Derived>
00256 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType
00257 DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
00258 {
00259   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00260   return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
00261 }
00262 
00267 template<typename Derived>
00268 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType
00269 DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
00270 {
00271   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00272   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
00273   return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,false>(low,high,Derived::SizeAtCompileTime));
00274 }
00275 
00289 template<typename Derived>
00290 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
00291 DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
00292 {
00293   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00294   return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,true>(low,high,size));
00295 }
00296 
00301 template<typename Derived>
00302 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
00303 DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
00304 {
00305   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00306   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
00307   return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,true>(low,high,Derived::SizeAtCompileTime));
00308 }
00309 
00311 template<typename Derived>
00312 bool DenseBase<Derived>::isApproxToConstant
00313 (const Scalar& value, RealScalar prec) const
00314 {
00315   for(Index j = 0; j < cols(); ++j)
00316     for(Index i = 0; i < rows(); ++i)
00317       if(!internal::isApprox(this->coeff(i, j), value, prec))
00318         return false;
00319   return true;
00320 }
00321 
00325 template<typename Derived>
00326 bool DenseBase<Derived>::isConstant
00327 (const Scalar& value, RealScalar prec) const
00328 {
00329   return isApproxToConstant(value, prec);
00330 }
00331 
00336 template<typename Derived>
00337 EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& value)
00338 {
00339   setConstant(value);
00340 }
00341 
00346 template<typename Derived>
00347 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& value)
00348 {
00349   return derived() = Constant(rows(), cols(), value);
00350 }
00351 
00361 template<typename Derived>
00362 EIGEN_STRONG_INLINE Derived&
00363 PlainObjectBase<Derived>::setConstant(Index size, const Scalar& value)
00364 {
00365   resize(size);
00366   return setConstant(value);
00367 }
00368 
00380 template<typename Derived>
00381 EIGEN_STRONG_INLINE Derived&
00382 PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& value)
00383 {
00384   resize(rows, cols);
00385   return setConstant(value);
00386 }
00387 
00401 template<typename Derived>
00402 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index size, const Scalar& low, const Scalar& high)
00403 {
00404   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00405   return derived() = Derived::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
00406 }
00407 
00418 template<typename Derived>
00419 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high)
00420 {
00421   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00422   return setLinSpaced(size(), low, high);
00423 }
00424 
00425 // zero:
00426 
00441 template<typename Derived>
00442 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00443 DenseBase<Derived>::Zero(Index rows, Index cols)
00444 {
00445   return Constant(rows, cols, Scalar(0));
00446 }
00447 
00464 template<typename Derived>
00465 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00466 DenseBase<Derived>::Zero(Index size)
00467 {
00468   return Constant(size, Scalar(0));
00469 }
00470 
00481 template<typename Derived>
00482 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00483 DenseBase<Derived>::Zero()
00484 {
00485   return Constant(Scalar(0));
00486 }
00487 
00496 template<typename Derived>
00497 bool DenseBase<Derived>::isZero(RealScalar prec) const
00498 {
00499   for(Index j = 0; j < cols(); ++j)
00500     for(Index i = 0; i < rows(); ++i)
00501       if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<Scalar>(1), prec))
00502         return false;
00503   return true;
00504 }
00505 
00513 template<typename Derived>
00514 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
00515 {
00516   return setConstant(Scalar(0));
00517 }
00518 
00528 template<typename Derived>
00529 EIGEN_STRONG_INLINE Derived&
00530 PlainObjectBase<Derived>::setZero(Index size)
00531 {
00532   resize(size);
00533   return setConstant(Scalar(0));
00534 }
00535 
00546 template<typename Derived>
00547 EIGEN_STRONG_INLINE Derived&
00548 PlainObjectBase<Derived>::setZero(Index rows, Index cols)
00549 {
00550   resize(rows, cols);
00551   return setConstant(Scalar(0));
00552 }
00553 
00554 // ones:
00555 
00570 template<typename Derived>
00571 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00572 DenseBase<Derived>::Ones(Index rows, Index cols)
00573 {
00574   return Constant(rows, cols, Scalar(1));
00575 }
00576 
00593 template<typename Derived>
00594 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00595 DenseBase<Derived>::Ones(Index size)
00596 {
00597   return Constant(size, Scalar(1));
00598 }
00599 
00610 template<typename Derived>
00611 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
00612 DenseBase<Derived>::Ones()
00613 {
00614   return Constant(Scalar(1));
00615 }
00616 
00625 template<typename Derived>
00626 bool DenseBase<Derived>::isOnes
00627 (RealScalar prec) const
00628 {
00629   return isApproxToConstant(Scalar(1), prec);
00630 }
00631 
00639 template<typename Derived>
00640 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
00641 {
00642   return setConstant(Scalar(1));
00643 }
00644 
00654 template<typename Derived>
00655 EIGEN_STRONG_INLINE Derived&
00656 PlainObjectBase<Derived>::setOnes(Index size)
00657 {
00658   resize(size);
00659   return setConstant(Scalar(1));
00660 }
00661 
00672 template<typename Derived>
00673 EIGEN_STRONG_INLINE Derived&
00674 PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
00675 {
00676   resize(rows, cols);
00677   return setConstant(Scalar(1));
00678 }
00679 
00680 // Identity:
00681 
00696 template<typename Derived>
00697 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
00698 MatrixBase<Derived>::Identity(Index rows, Index cols)
00699 {
00700   return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
00701 }
00702 
00713 template<typename Derived>
00714 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
00715 MatrixBase<Derived>::Identity()
00716 {
00717   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
00718   return MatrixBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op<Scalar>());
00719 }
00720 
00730 template<typename Derived>
00731 bool MatrixBase<Derived>::isIdentity
00732 (RealScalar prec) const
00733 {
00734   for(Index j = 0; j < cols(); ++j)
00735   {
00736     for(Index i = 0; i < rows(); ++i)
00737     {
00738       if(i == j)
00739       {
00740         if(!internal::isApprox(this->coeff(i, j), static_cast<Scalar>(1), prec))
00741           return false;
00742       }
00743       else
00744       {
00745         if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<RealScalar>(1), prec))
00746           return false;
00747       }
00748     }
00749   }
00750   return true;
00751 }
00752 
00753 namespace internal {
00754 
00755 template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
00756 struct setIdentity_impl
00757 {
00758   static EIGEN_STRONG_INLINE Derived& run(Derived& m)
00759   {
00760     return m = Derived::Identity(m.rows(), m.cols());
00761   }
00762 };
00763 
00764 template<typename Derived>
00765 struct setIdentity_impl<Derived, true>
00766 {
00767   typedef typename Derived::Index Index;
00768   static EIGEN_STRONG_INLINE Derived& run(Derived& m)
00769   {
00770     m.setZero();
00771     const Index size = (std::min)(m.rows(), m.cols());
00772     for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
00773     return m;
00774   }
00775 };
00776 
00777 } // end namespace internal
00778 
00786 template<typename Derived>
00787 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
00788 {
00789   return internal::setIdentity_impl<Derived>::run(derived());
00790 }
00791 
00802 template<typename Derived>
00803 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
00804 {
00805   derived().resize(rows, cols);
00806   return setIdentity();
00807 }
00808 
00815 template<typename Derived>
00816 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index size, Index i)
00817 {
00818   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00819   return BasisReturnType(SquareMatrixType::Identity(size,size), i);
00820 }
00821 
00830 template<typename Derived>
00831 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
00832 {
00833   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00834   return BasisReturnType(SquareMatrixType::Identity(),i);
00835 }
00836 
00843 template<typename Derived>
00844 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
00845 { return Derived::Unit(0); }
00846 
00853 template<typename Derived>
00854 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
00855 { return Derived::Unit(1); }
00856 
00863 template<typename Derived>
00864 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
00865 { return Derived::Unit(2); }
00866 
00873 template<typename Derived>
00874 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
00875 { return Derived::Unit(3); }
00876 
00877 } // end namespace Eigen
00878 
00879 #endif // EIGEN_CWISE_NULLARY_OP_H