CwiseNullaryOp.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef EIGEN_CWISE_NULLARY_OP_H
26 #define EIGEN_CWISE_NULLARY_OP_H
27 
28 namespace Eigen {
29 
48 namespace internal {
49 template<typename NullaryOp, typename PlainObjectType>
50 struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
51 {
52  enum {
54  & ( HereditaryBits
55  | (functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
56  | (functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0)))
57  | (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
58  CoeffReadCost = functor_traits<NullaryOp>::Cost
59  };
60 };
61 }
62 
63 template<typename NullaryOp, typename PlainObjectType>
64 class CwiseNullaryOp : internal::no_assignment_operator,
65  public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type
66 {
67  public:
68 
69  typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
71 
72  CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
73  : m_rows(rows), m_cols(cols), m_functor(func)
74  {
75  eigen_assert(rows >= 0
76  && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
77  && cols >= 0
78  && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
79  }
80 
81  EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
82  EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
83 
84  EIGEN_STRONG_INLINE const Scalar coeff(Index rows, Index cols) const
85  {
86  return m_functor(rows, cols);
87  }
88 
89  template<int LoadMode>
90  EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
91  {
92  return m_functor.packetOp(row, col);
93  }
94 
95  EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
96  {
97  return m_functor(index);
98  }
99 
100  template<int LoadMode>
101  EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
102  {
103  return m_functor.packetOp(index);
104  }
105 
107  const NullaryOp& functor() const { return m_functor; }
108 
109  protected:
110  const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
111  const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
112  const NullaryOp m_functor;
113 };
114 
115 
129 template<typename Derived>
130 template<typename CustomNullaryOp>
132 DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
133 {
134  return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func);
135 }
136 
152 template<typename Derived>
153 template<typename CustomNullaryOp>
155 DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
156 {
158  if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func);
159  else return CwiseNullaryOp<CustomNullaryOp, Derived>(size, 1, func);
160 }
161 
171 template<typename Derived>
172 template<typename CustomNullaryOp>
174 DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
175 {
176  return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func);
177 }
178 
192 template<typename Derived>
195 {
196  return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
197 }
198 
214 template<typename Derived>
217 {
218  return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value));
219 }
220 
230 template<typename Derived>
233 {
235  return DenseBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op<Scalar>(value));
236 }
237 
255 template<typename Derived>
258 {
260  return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
261 }
262 
267 template<typename Derived>
270 {
273  return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,false>(low,high,Derived::SizeAtCompileTime));
274 }
275 
289 template<typename Derived>
291 DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
292 {
294  return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,true>(low,high,size));
295 }
296 
301 template<typename Derived>
304 {
307  return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,true>(low,high,Derived::SizeAtCompileTime));
308 }
309 
311 template<typename Derived>
313 (const Scalar& value, RealScalar prec) const
314 {
315  for(Index j = 0; j < cols(); ++j)
316  for(Index i = 0; i < rows(); ++i)
317  if(!internal::isApprox(this->coeff(i, j), value, prec))
318  return false;
319  return true;
320 }
321 
325 template<typename Derived>
327 (const Scalar& value, RealScalar prec) const
328 {
329  return isApproxToConstant(value, prec);
330 }
331 
336 template<typename Derived>
338 {
339  setConstant(value);
340 }
341 
346 template<typename Derived>
348 {
349  return derived() = Constant(rows(), cols(), value);
350 }
351 
361 template<typename Derived>
362 EIGEN_STRONG_INLINE Derived&
364 {
365  resize(size);
366  return setConstant(value);
367 }
368 
380 template<typename Derived>
381 EIGEN_STRONG_INLINE Derived&
383 {
384  resize(rows, cols);
385  return setConstant(value);
386 }
387 
401 template<typename Derived>
403 {
405  return derived() = Derived::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
406 }
407 
418 template<typename Derived>
420 {
422  return setLinSpaced(size(), low, high);
423 }
424 
425 // zero:
426 
441 template<typename Derived>
444 {
445  return Constant(rows, cols, Scalar(0));
446 }
447 
464 template<typename Derived>
467 {
468  return Constant(size, Scalar(0));
469 }
470 
481 template<typename Derived>
484 {
485  return Constant(Scalar(0));
486 }
487 
496 template<typename Derived>
498 {
499  for(Index j = 0; j < cols(); ++j)
500  for(Index i = 0; i < rows(); ++i)
501  if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<Scalar>(1), prec))
502  return false;
503  return true;
504 }
505 
513 template<typename Derived>
515 {
516  return setConstant(Scalar(0));
517 }
518 
528 template<typename Derived>
529 EIGEN_STRONG_INLINE Derived&
531 {
532  resize(size);
533  return setConstant(Scalar(0));
534 }
535 
546 template<typename Derived>
547 EIGEN_STRONG_INLINE Derived&
549 {
550  resize(rows, cols);
551  return setConstant(Scalar(0));
552 }
553 
554 // ones:
555 
570 template<typename Derived>
573 {
574  return Constant(rows, cols, Scalar(1));
575 }
576 
593 template<typename Derived>
596 {
597  return Constant(size, Scalar(1));
598 }
599 
610 template<typename Derived>
613 {
614  return Constant(Scalar(1));
615 }
616 
625 template<typename Derived>
627 (RealScalar prec) const
628 {
629  return isApproxToConstant(Scalar(1), prec);
630 }
631 
639 template<typename Derived>
641 {
642  return setConstant(Scalar(1));
643 }
644 
654 template<typename Derived>
655 EIGEN_STRONG_INLINE Derived&
657 {
658  resize(size);
659  return setConstant(Scalar(1));
660 }
661 
672 template<typename Derived>
673 EIGEN_STRONG_INLINE Derived&
675 {
676  resize(rows, cols);
677  return setConstant(Scalar(1));
678 }
679 
680 // Identity:
681 
696 template<typename Derived>
699 {
700  return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
701 }
702 
713 template<typename Derived>
716 {
718  return MatrixBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op<Scalar>());
719 }
720 
730 template<typename Derived>
732 (RealScalar prec) const
733 {
734  for(Index j = 0; j < cols(); ++j)
735  {
736  for(Index i = 0; i < rows(); ++i)
737  {
738  if(i == j)
739  {
740  if(!internal::isApprox(this->coeff(i, j), static_cast<Scalar>(1), prec))
741  return false;
742  }
743  else
744  {
745  if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<RealScalar>(1), prec))
746  return false;
747  }
748  }
749  }
750  return true;
751 }
752 
753 namespace internal {
754 
755 template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
756 struct setIdentity_impl
757 {
758  static EIGEN_STRONG_INLINE Derived& run(Derived& m)
759  {
760  return m = Derived::Identity(m.rows(), m.cols());
761  }
762 };
763 
764 template<typename Derived>
765 struct setIdentity_impl<Derived, true>
766 {
767  typedef typename Derived::Index Index;
768  static EIGEN_STRONG_INLINE Derived& run(Derived& m)
769  {
770  m.setZero();
771  const Index size = (std::min)(m.rows(), m.cols());
772  for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
773  return m;
774  }
775 };
776 
777 } // end namespace internal
778 
786 template<typename Derived>
788 {
789  return internal::setIdentity_impl<Derived>::run(derived());
790 }
791 
802 template<typename Derived>
804 {
805  derived().resize(rows, cols);
806  return setIdentity();
807 }
808 
815 template<typename Derived>
817 {
819  return BasisReturnType(SquareMatrixType::Identity(size,size), i);
820 }
821 
830 template<typename Derived>
832 {
834  return BasisReturnType(SquareMatrixType::Identity(),i);
835 }
836 
843 template<typename Derived>
845 { return Derived::Unit(0); }
846 
853 template<typename Derived>
855 { return Derived::Unit(1); }
856 
863 template<typename Derived>
865 { return Derived::Unit(2); }
866 
873 template<typename Derived>
875 { return Derived::Unit(3); }
876 
877 } // end namespace Eigen
878 
879 #endif // EIGEN_CWISE_NULLARY_OP_H