CwiseNullaryOp.h
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 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_CWISE_NULLARY_OP_H
11 #define EIGEN_CWISE_NULLARY_OP_H
12 
13 namespace Eigen {
14 
33 namespace internal {
34 template<typename NullaryOp, typename PlainObjectType>
35 struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
36 {
37  enum {
38  Flags = (traits<PlainObjectType>::Flags
39  & ( HereditaryBits
40  | (functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
41  | (functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0)))
42  | (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
43  CoeffReadCost = functor_traits<NullaryOp>::Cost
44  };
45 };
46 }
47 
48 template<typename NullaryOp, typename PlainObjectType>
49 class CwiseNullaryOp : internal::no_assignment_operator,
50  public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type
51 {
52  public:
53 
54  typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
55  EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
56 
57  CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
58  : m_rows(rows), m_cols(cols), m_functor(func)
59  {
60  eigen_assert(rows >= 0
61  && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
62  && cols >= 0
63  && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
64  }
65 
66  EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
67  EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
68 
69  EIGEN_STRONG_INLINE const Scalar coeff(Index rows, Index cols) const
70  {
71  return m_functor(rows, cols);
72  }
73 
74  template<int LoadMode>
75  EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
76  {
77  return m_functor.packetOp(row, col);
78  }
79 
80  EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
81  {
82  return m_functor(index);
83  }
84 
85  template<int LoadMode>
86  EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
87  {
88  return m_functor.packetOp(index);
89  }
90 
92  const NullaryOp& functor() const { return m_functor; }
93 
94  protected:
95  const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
96  const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
97  const NullaryOp m_functor;
98 };
99 
100 
114 template<typename Derived>
115 template<typename CustomNullaryOp>
116 EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
117 DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
118 {
119  return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func);
120 }
121 
137 template<typename Derived>
138 template<typename CustomNullaryOp>
139 EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
140 DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
141 {
142  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
143  if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func);
144  else return CwiseNullaryOp<CustomNullaryOp, Derived>(size, 1, func);
145 }
146 
156 template<typename Derived>
157 template<typename CustomNullaryOp>
158 EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
159 DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
160 {
161  return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func);
162 }
163 
177 template<typename Derived>
178 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
179 DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
180 {
181  return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
182 }
183 
199 template<typename Derived>
200 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
201 DenseBase<Derived>::Constant(Index size, const Scalar& value)
202 {
203  return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value));
204 }
205 
215 template<typename Derived>
216 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
217 DenseBase<Derived>::Constant(const Scalar& value)
218 {
219  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
220  return DenseBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op<Scalar>(value));
221 }
222 
240 template<typename Derived>
241 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType
242 DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
243 {
244  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
245  return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
246 }
247 
252 template<typename Derived>
253 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType
254 DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
255 {
256  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
257  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
258  return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,false>(low,high,Derived::SizeAtCompileTime));
259 }
260 
274 template<typename Derived>
275 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
276 DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
277 {
278  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
279  return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,true>(low,high,size));
280 }
281 
286 template<typename Derived>
287 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
288 DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
289 {
290  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
291  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
292  return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,true>(low,high,Derived::SizeAtCompileTime));
293 }
294 
296 template<typename Derived>
298 (const Scalar& value, RealScalar prec) const
299 {
300  for(Index j = 0; j < cols(); ++j)
301  for(Index i = 0; i < rows(); ++i)
302  if(!internal::isApprox(this->coeff(i, j), value, prec))
303  return false;
304  return true;
305 }
306 
310 template<typename Derived>
312 (const Scalar& value, RealScalar prec) const
313 {
314  return isApproxToConstant(value, prec);
315 }
316 
321 template<typename Derived>
322 EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& value)
323 {
324  setConstant(value);
325 }
326 
331 template<typename Derived>
332 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& value)
333 {
334  return derived() = Constant(rows(), cols(), value);
335 }
336 
346 template<typename Derived>
347 EIGEN_STRONG_INLINE Derived&
348 PlainObjectBase<Derived>::setConstant(Index size, const Scalar& value)
349 {
350  resize(size);
351  return setConstant(value);
352 }
353 
365 template<typename Derived>
366 EIGEN_STRONG_INLINE Derived&
367 PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& value)
368 {
369  resize(rows, cols);
370  return setConstant(value);
371 }
372 
386 template<typename Derived>
387 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index size, const Scalar& low, const Scalar& high)
388 {
389  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
390  return derived() = Derived::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
391 }
392 
403 template<typename Derived>
404 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high)
405 {
406  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
407  return setLinSpaced(size(), low, high);
408 }
409 
410 // zero:
411 
426 template<typename Derived>
427 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
429 {
430  return Constant(rows, cols, Scalar(0));
431 }
432 
449 template<typename Derived>
450 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
452 {
453  return Constant(size, Scalar(0));
454 }
455 
466 template<typename Derived>
467 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
469 {
470  return Constant(Scalar(0));
471 }
472 
481 template<typename Derived>
482 bool DenseBase<Derived>::isZero(RealScalar prec) const
483 {
484  for(Index j = 0; j < cols(); ++j)
485  for(Index i = 0; i < rows(); ++i)
486  if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<Scalar>(1), prec))
487  return false;
488  return true;
489 }
490 
498 template<typename Derived>
499 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
500 {
501  return setConstant(Scalar(0));
502 }
503 
513 template<typename Derived>
514 EIGEN_STRONG_INLINE Derived&
516 {
517  resize(size);
518  return setConstant(Scalar(0));
519 }
520 
531 template<typename Derived>
532 EIGEN_STRONG_INLINE Derived&
533 PlainObjectBase<Derived>::setZero(Index rows, Index cols)
534 {
535  resize(rows, cols);
536  return setConstant(Scalar(0));
537 }
538 
539 // ones:
540 
555 template<typename Derived>
556 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
558 {
559  return Constant(rows, cols, Scalar(1));
560 }
561 
578 template<typename Derived>
579 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
581 {
582  return Constant(size, Scalar(1));
583 }
584 
595 template<typename Derived>
596 EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
598 {
599  return Constant(Scalar(1));
600 }
601 
610 template<typename Derived>
612 (RealScalar prec) const
613 {
614  return isApproxToConstant(Scalar(1), prec);
615 }
616 
624 template<typename Derived>
625 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
626 {
627  return setConstant(Scalar(1));
628 }
629 
639 template<typename Derived>
640 EIGEN_STRONG_INLINE Derived&
642 {
643  resize(size);
644  return setConstant(Scalar(1));
645 }
646 
657 template<typename Derived>
658 EIGEN_STRONG_INLINE Derived&
659 PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
660 {
661  resize(rows, cols);
662  return setConstant(Scalar(1));
663 }
664 
665 // Identity:
666 
681 template<typename Derived>
682 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
684 {
685  return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
686 }
687 
698 template<typename Derived>
699 EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
701 {
702  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
703  return MatrixBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op<Scalar>());
704 }
705 
715 template<typename Derived>
717 (RealScalar prec) const
718 {
719  for(Index j = 0; j < cols(); ++j)
720  {
721  for(Index i = 0; i < rows(); ++i)
722  {
723  if(i == j)
724  {
725  if(!internal::isApprox(this->coeff(i, j), static_cast<Scalar>(1), prec))
726  return false;
727  }
728  else
729  {
730  if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<RealScalar>(1), prec))
731  return false;
732  }
733  }
734  }
735  return true;
736 }
737 
738 namespace internal {
739 
740 template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
741 struct setIdentity_impl
742 {
743  static EIGEN_STRONG_INLINE Derived& run(Derived& m)
744  {
745  return m = Derived::Identity(m.rows(), m.cols());
746  }
747 };
748 
749 template<typename Derived>
750 struct setIdentity_impl<Derived, true>
751 {
752  typedef typename Derived::Index Index;
753  static EIGEN_STRONG_INLINE Derived& run(Derived& m)
754  {
755  m.setZero();
756  const Index size = (std::min)(m.rows(), m.cols());
757  for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
758  return m;
759  }
760 };
761 
762 } // end namespace internal
763 
771 template<typename Derived>
772 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
773 {
774  return internal::setIdentity_impl<Derived>::run(derived());
775 }
776 
787 template<typename Derived>
788 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
789 {
790  derived().resize(rows, cols);
791  return setIdentity();
792 }
793 
800 template<typename Derived>
802 {
803  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
804  return BasisReturnType(SquareMatrixType::Identity(size,size), i);
805 }
806 
815 template<typename Derived>
817 {
818  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
819  return BasisReturnType(SquareMatrixType::Identity(),i);
820 }
821 
828 template<typename Derived>
830 { return Derived::Unit(0); }
831 
838 template<typename Derived>
840 { return Derived::Unit(1); }
841 
848 template<typename Derived>
850 { return Derived::Unit(2); }
851 
858 template<typename Derived>
860 { return Derived::Unit(3); }
861 
862 } // end namespace Eigen
863 
864 #endif // EIGEN_CWISE_NULLARY_OP_H