1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11 #ifndef EIGEN_DENSESTORAGEBASE_H
12 #define EIGEN_DENSESTORAGEBASE_H
13
14 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
15 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
16 #else
17 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
18 #endif
19
20 namespace Eigen {
21
22 namespace internal {
23
24 template<typename Index>
check_rows_cols_for_overflow(Index rows,Index cols)25 EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols)
26 {
27 // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
28 // we assume Index is signed
29 Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
30 bool error = (rows < 0 || cols < 0) ? true
31 : (rows == 0 || cols == 0) ? false
32 : (rows > max_index / cols);
33 if (error)
34 throw_std_bad_alloc();
35 }
36
37 template <typename Derived, typename OtherDerived = Derived, bool IsVector = bool(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
38
39 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
40
41 } // end namespace internal
42
43 /** \class PlainObjectBase
44 * \brief %Dense storage base class for matrices and arrays.
45 *
46 * This class can be extended with the help of the plugin mechanism described on the page
47 * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN.
48 *
49 * \sa \ref TopicClassHierarchy
50 */
51 #ifdef EIGEN_PARSED_BY_DOXYGEN
52 namespace internal {
53
54 // this is a warkaround to doxygen not being able to understand the inheritence logic
55 // when it is hidden by the dense_xpr_base helper struct.
56 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {};
57 /** This class is just a workaround for Doxygen and it does not not actually exist. */
58 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
59 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
60 : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
61 /** This class is just a workaround for Doxygen and it does not not actually exist. */
62 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
63 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
64 : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
65
66 } // namespace internal
67
68 template<typename Derived>
69 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
70 #else
71 template<typename Derived>
72 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
73 #endif
74 {
75 public:
76 enum { Options = internal::traits<Derived>::Options };
77 typedef typename internal::dense_xpr_base<Derived>::type Base;
78
79 typedef typename internal::traits<Derived>::StorageKind StorageKind;
80 typedef typename internal::traits<Derived>::Index Index;
81 typedef typename internal::traits<Derived>::Scalar Scalar;
82 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
83 typedef typename NumTraits<Scalar>::Real RealScalar;
84 typedef Derived DenseType;
85
86 using Base::RowsAtCompileTime;
87 using Base::ColsAtCompileTime;
88 using Base::SizeAtCompileTime;
89 using Base::MaxRowsAtCompileTime;
90 using Base::MaxColsAtCompileTime;
91 using Base::MaxSizeAtCompileTime;
92 using Base::IsVectorAtCompileTime;
93 using Base::Flags;
94
95 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
96 friend class Eigen::Map<Derived, Unaligned>;
97 typedef Eigen::Map<Derived, Unaligned> MapType;
98 friend class Eigen::Map<const Derived, Unaligned>;
99 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
100 friend class Eigen::Map<Derived, Aligned>;
101 typedef Eigen::Map<Derived, Aligned> AlignedMapType;
102 friend class Eigen::Map<const Derived, Aligned>;
103 typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
104 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
105 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
106 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
107 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
108
109 protected:
110 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
111
112 public:
113 enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
114 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
115
116 Base& base() { return *static_cast<Base*>(this); }
117 const Base& base() const { return *static_cast<const Base*>(this); }
118
119 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
120 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
121
122 EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const
123 {
124 if(Flags & RowMajorBit)
125 return m_storage.data()[col + row * m_storage.cols()];
126 else // column-major
127 return m_storage.data()[row + col * m_storage.rows()];
128 }
129
130 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
131 {
132 return m_storage.data()[index];
133 }
134
135 EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
136 {
137 if(Flags & RowMajorBit)
138 return m_storage.data()[col + row * m_storage.cols()];
139 else // column-major
140 return m_storage.data()[row + col * m_storage.rows()];
141 }
142
143 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
144 {
145 return m_storage.data()[index];
146 }
147
148 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const
149 {
150 if(Flags & RowMajorBit)
151 return m_storage.data()[col + row * m_storage.cols()];
152 else // column-major
153 return m_storage.data()[row + col * m_storage.rows()];
154 }
155
156 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
157 {
158 return m_storage.data()[index];
159 }
160
161 /** \internal */
162 template<int LoadMode>
163 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
164 {
165 return internal::ploadt<PacketScalar, LoadMode>
166 (m_storage.data() + (Flags & RowMajorBit
167 ? col + row * m_storage.cols()
168 : row + col * m_storage.rows()));
169 }
170
171 /** \internal */
172 template<int LoadMode>
173 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
174 {
175 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
176 }
177
178 /** \internal */
179 template<int StoreMode>
180 EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x)
181 {
182 internal::pstoret<Scalar, PacketScalar, StoreMode>
183 (m_storage.data() + (Flags & RowMajorBit
184 ? col + row * m_storage.cols()
185 : row + col * m_storage.rows()), x);
186 }
187
188 /** \internal */
189 template<int StoreMode>
190 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x)
191 {
192 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
193 }
194
195 /** \returns a const pointer to the data array of this matrix */
196 EIGEN_STRONG_INLINE const Scalar *data() const
197 { return m_storage.data(); }
198
199 /** \returns a pointer to the data array of this matrix */
200 EIGEN_STRONG_INLINE Scalar *data()
201 { return m_storage.data(); }
202
203 /** Resizes \c *this to a \a rows x \a cols matrix.
204 *
205 * This method is intended for dynamic-size matrices, although it is legal to call it on any
206 * matrix as long as fixed dimensions are left unchanged. If you only want to change the number
207 * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t).
208 *
209 * If the current number of coefficients of \c *this exactly matches the
210 * product \a rows * \a cols, then no memory allocation is performed and
211 * the current values are left unchanged. In all other cases, including
212 * shrinking, the data is reallocated and all previous values are lost.
213 *
214 * Example: \include Matrix_resize_int_int.cpp
215 * Output: \verbinclude Matrix_resize_int_int.out
216 *
217 * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
218 */
219 EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
220 {
221 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
222 internal::check_rows_cols_for_overflow(rows, cols);
223 Index size = rows*cols;
224 bool size_changed = size != this->size();
225 m_storage.resize(size, rows, cols);
226 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
227 #else
228 internal::check_rows_cols_for_overflow(rows, cols);
229 m_storage.resize(rows*cols, rows, cols);
230 #endif
231 }
232
233 /** Resizes \c *this to a vector of length \a size
234 *
235 * \only_for_vectors. This method does not work for
236 * partially dynamic matrices when the static dimension is anything other
237 * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
238 *
239 * Example: \include Matrix_resize_int.cpp
240 * Output: \verbinclude Matrix_resize_int.out
241 *
242 * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t)
243 */
244 inline void resize(Index size)
245 {
246 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
247 eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
248 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
249 bool size_changed = size != this->size();
250 #endif
251 if(RowsAtCompileTime == 1)
252 m_storage.resize(size, 1, size);
253 else
254 m_storage.resize(size, size, 1);
255 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
256 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
257 #endif
258 }
259
260 /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
261 * as in the example below.
262 *
263 * Example: \include Matrix_resize_NoChange_int.cpp
264 * Output: \verbinclude Matrix_resize_NoChange_int.out
265 *
266 * \sa resize(Index,Index)
267 */
268 inline void resize(NoChange_t, Index cols)
269 {
270 resize(rows(), cols);
271 }
272
273 /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
274 * as in the example below.
275 *
276 * Example: \include Matrix_resize_int_NoChange.cpp
277 * Output: \verbinclude Matrix_resize_int_NoChange.out
278 *
279 * \sa resize(Index,Index)
280 */
281 inline void resize(Index rows, NoChange_t)
282 {
283 resize(rows, cols());
284 }
285
286 /** Resizes \c *this to have the same dimensions as \a other.
287 * Takes care of doing all the checking that's needed.
288 *
289 * Note that copying a row-vector into a vector (and conversely) is allowed.
290 * The resizing, if any, is then done in the appropriate way so that row-vectors
291 * remain row-vectors and vectors remain vectors.
292 */
293 template<typename OtherDerived>
294 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
295 {
296 const OtherDerived& other = _other.derived();
297 internal::check_rows_cols_for_overflow(other.rows(), other.cols());
298 const Index othersize = other.rows()*other.cols();
299 if(RowsAtCompileTime == 1)
300 {
301 eigen_assert(other.rows() == 1 || other.cols() == 1);
302 resize(1, othersize);
303 }
304 else if(ColsAtCompileTime == 1)
305 {
306 eigen_assert(other.rows() == 1 || other.cols() == 1);
307 resize(othersize, 1);
308 }
309 else resize(other.rows(), other.cols());
310 }
311
312 /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
313 *
314 * The method is intended for matrices of dynamic size. If you only want to change the number
315 * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
316 * conservativeResize(Index, NoChange_t).
317 *
318 * Matrices are resized relative to the top-left element. In case values need to be
319 * appended to the matrix they will be uninitialized.
320 */
321 EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
322 {
323 internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
324 }
325
326 /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
327 *
328 * As opposed to conservativeResize(Index rows, Index cols), this version leaves
329 * the number of columns unchanged.
330 *
331 * In case the matrix is growing, new rows will be uninitialized.
332 */
333 EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
334 {
335 // Note: see the comment in conservativeResize(Index,Index)
336 conservativeResize(rows, cols());
337 }
338
339 /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
340 *
341 * As opposed to conservativeResize(Index rows, Index cols), this version leaves
342 * the number of rows unchanged.
343 *
344 * In case the matrix is growing, new columns will be uninitialized.
345 */
346 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
347 {
348 // Note: see the comment in conservativeResize(Index,Index)
349 conservativeResize(rows(), cols);
350 }
351
352 /** Resizes the vector to \a size while retaining old values.
353 *
354 * \only_for_vectors. This method does not work for
355 * partially dynamic matrices when the static dimension is anything other
356 * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
357 *
358 * When values are appended, they will be uninitialized.
359 */
360 EIGEN_STRONG_INLINE void conservativeResize(Index size)
361 {
362 internal::conservative_resize_like_impl<Derived>::run(*this, size);
363 }
364
365 /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
366 *
367 * The method is intended for matrices of dynamic size. If you only want to change the number
368 * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
369 * conservativeResize(Index, NoChange_t).
370 *
371 * Matrices are resized relative to the top-left element. In case values need to be
372 * appended to the matrix they will copied from \c other.
373 */
374 template<typename OtherDerived>
375 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
376 {
377 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
378 }
379
380 /** This is a special case of the templated operator=. Its purpose is to
381 * prevent a default operator= from hiding the templated operator=.
382 */
383 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
384 {
385 return _set(other);
386 }
387
388 /** \sa MatrixBase::lazyAssign() */
389 template<typename OtherDerived>
390 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
391 {
392 _resize_to_match(other);
393 return Base::lazyAssign(other.derived());
394 }
395
396 template<typename OtherDerived>
397 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
398 {
399 resize(func.rows(), func.cols());
400 return Base::operator=(func);
401 }
402
403 EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage()
404 {
405 // _check_template_params();
406 // EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
407 }
408
409 #ifndef EIGEN_PARSED_BY_DOXYGEN
410 // FIXME is it still needed ?
411 /** \internal */
412 PlainObjectBase(internal::constructor_without_unaligned_array_assert)
413 : m_storage(internal::constructor_without_unaligned_array_assert())
414 {
415 // _check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
416 }
417 #endif
418
419 EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
420 : m_storage(size, rows, cols)
421 {
422 // _check_template_params();
423 // EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
424 }
425
426 /** \copydoc MatrixBase::operator=(const EigenBase<OtherDerived>&)
427 */
428 template<typename OtherDerived>
429 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
430 {
431 _resize_to_match(other);
432 Base::operator=(other.derived());
433 return this->derived();
434 }
435
436 /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
437 template<typename OtherDerived>
438 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
439 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
440 {
441 _check_template_params();
442 internal::check_rows_cols_for_overflow(other.derived().rows(), other.derived().cols());
443 Base::operator=(other.derived());
444 }
445
446 /** \name Map
447 * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
448 * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
449 * \a data pointers.
450 *
451 * \see class Map
452 */
453 //@{
454 static inline ConstMapType Map(const Scalar* data)
455 { return ConstMapType(data); }
456 static inline MapType Map(Scalar* data)
457 { return MapType(data); }
458 static inline ConstMapType Map(const Scalar* data, Index size)
459 { return ConstMapType(data, size); }
460 static inline MapType Map(Scalar* data, Index size)
461 { return MapType(data, size); }
462 static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
463 { return ConstMapType(data, rows, cols); }
464 static inline MapType Map(Scalar* data, Index rows, Index cols)
465 { return MapType(data, rows, cols); }
466
467 static inline ConstAlignedMapType MapAligned(const Scalar* data)
468 { return ConstAlignedMapType(data); }
469 static inline AlignedMapType MapAligned(Scalar* data)
470 { return AlignedMapType(data); }
471 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
472 { return ConstAlignedMapType(data, size); }
473 static inline AlignedMapType MapAligned(Scalar* data, Index size)
474 { return AlignedMapType(data, size); }
475 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
476 { return ConstAlignedMapType(data, rows, cols); }
477 static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
478 { return AlignedMapType(data, rows, cols); }
479
480 template<int Outer, int Inner>
481 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
482 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
483 template<int Outer, int Inner>
484 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
485 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
486 template<int Outer, int Inner>
487 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
488 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
489 template<int Outer, int Inner>
490 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
491 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
492 template<int Outer, int Inner>
493 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
494 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
495 template<int Outer, int Inner>
496 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
497 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
498
499 template<int Outer, int Inner>
500 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
501 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
502 template<int Outer, int Inner>
503 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
504 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
505 template<int Outer, int Inner>
506 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
507 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
508 template<int Outer, int Inner>
509 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
510 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
511 template<int Outer, int Inner>
512 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
513 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
514 template<int Outer, int Inner>
515 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
516 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
517 //@}
518
519 using Base::setConstant;
520 Derived& setConstant(Index size, const Scalar& value);
521 Derived& setConstant(Index rows, Index cols, const Scalar& value);
522
523 using Base::setZero;
524 Derived& setZero(Index size);
525 Derived& setZero(Index rows, Index cols);
526
527 using Base::setOnes;
528 Derived& setOnes(Index size);
529 Derived& setOnes(Index rows, Index cols);
530
531 using Base::setRandom;
532 Derived& setRandom(Index size);
533 Derived& setRandom(Index rows, Index cols);
534
535 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
536 #include EIGEN_PLAINOBJECTBASE_PLUGIN
537 #endif
538
539 protected:
540 /** \internal Resizes *this in preparation for assigning \a other to it.
541 * Takes care of doing all the checking that's needed.
542 *
543 * Note that copying a row-vector into a vector (and conversely) is allowed.
544 * The resizing, if any, is then done in the appropriate way so that row-vectors
545 * remain row-vectors and vectors remain vectors.
546 */
547 template<typename OtherDerived>
548 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
549 {
550 #ifdef EIGEN_NO_AUTOMATIC_RESIZING
551 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
552 : (rows() == other.rows() && cols() == other.cols())))
553 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
554 #else
555 resizeLike(other);
556 #endif
557 }
558
559 /**
560 * \brief Copies the value of the expression \a other into \c *this with automatic resizing.
561 *
562 * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
563 * it will be initialized.
564 *
565 * Note that copying a row-vector into a vector (and conversely) is allowed.
566 * The resizing, if any, is then done in the appropriate way so that row-vectors
567 * remain row-vectors and vectors remain vectors.
568 *
569 * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
570 *
571 * \internal
572 */
573 template<typename OtherDerived>
574 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
575 {
576 _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
577 return this->derived();
578 }
579
580 template<typename OtherDerived>
581 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
582
583 template<typename OtherDerived>
584 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
585
586 /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
587 * is the case when creating a new matrix) so one can enforce lazy evaluation.
588 *
589 * \sa operator=(const MatrixBase<OtherDerived>&), _set()
590 */
591 template<typename OtherDerived>
592 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
593 {
594 // I don't think we need this resize call since the lazyAssign will anyways resize
595 // and lazyAssign will be called by the assign selector.
596 //_resize_to_match(other);
597 // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
598 // it wouldn't allow to copy a row-vector into a column-vector.
599 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
600 }
601
602 template<typename T0, typename T1>
603 EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
604 {
605 EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
606 bool(NumTraits<T1>::IsInteger),
607 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
608 eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
609 && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
610 internal::check_rows_cols_for_overflow(rows, cols);
611 m_storage.resize(rows*cols,rows,cols);
612 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
613 }
614 template<typename T0, typename T1>
615 EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
616 {
617 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
618 m_storage.data()[0] = x;
619 m_storage.data()[1] = y;
620 }
621
622 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
623 friend struct internal::matrix_swap_impl;
624
625 /** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the
626 * data pointers.
627 */
628 template<typename OtherDerived>
629 void _swap(DenseBase<OtherDerived> const & other)
630 {
631 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
632 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
633 }
634
635 public:
636 #ifndef EIGEN_PARSED_BY_DOXYGEN
637 static EIGEN_STRONG_INLINE void _check_template_params()
638 {
639 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
640 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
641 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
642 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
643 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
644 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
645 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
646 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
647 && (Options & (DontAlign|RowMajor)) == Options),
648 INVALID_MATRIX_TEMPLATE_PARAMETERS)
649 }
650 #endif
651
652 private:
653 enum { ThisConstantIsPrivateInPlainObjectBase };
654 };
655
656 template <typename Derived, typename OtherDerived, bool IsVector>
657 struct internal::conservative_resize_like_impl
658 {
659 typedef typename Derived::Index Index;
660 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
661 {
662 if (_this.rows() == rows && _this.cols() == cols) return;
663 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
664
665 if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
666 (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
667 {
668 internal::check_rows_cols_for_overflow(rows, cols);
669 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
670 }
671 else
672 {
673 // The storage order does not allow us to use reallocation.
674 typename Derived::PlainObject tmp(rows,cols);
675 const Index common_rows = (std::min)(rows, _this.rows());
676 const Index common_cols = (std::min)(cols, _this.cols());
677 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
678 _this.derived().swap(tmp);
679 }
680 }
681
682 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
683 {
684 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
685
686 // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
687 // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
688 // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
689 // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
690 // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
691 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
692 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
693
694 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
695 (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns
696 {
697 const Index new_rows = other.rows() - _this.rows();
698 const Index new_cols = other.cols() - _this.cols();
699 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
700 if (new_rows>0)
701 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
702 else if (new_cols>0)
703 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
704 }
705 else
706 {
707 // The storage order does not allow us to use reallocation.
708 typename Derived::PlainObject tmp(other);
709 const Index common_rows = (std::min)(tmp.rows(), _this.rows());
710 const Index common_cols = (std::min)(tmp.cols(), _this.cols());
711 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
712 _this.derived().swap(tmp);
713 }
714 }
715 };
716
717 namespace internal {
718
719 template <typename Derived, typename OtherDerived>
720 struct conservative_resize_like_impl<Derived,OtherDerived,true>
721 {
722 typedef typename Derived::Index Index;
723 static void run(DenseBase<Derived>& _this, Index size)
724 {
725 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
726 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
727 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
728 }
729
730 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
731 {
732 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
733
734 const Index num_new_elements = other.size() - _this.size();
735
736 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
737 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
738 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
739
740 if (num_new_elements > 0)
741 _this.tail(num_new_elements) = other.tail(num_new_elements);
742 }
743 };
744
745 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
746 struct matrix_swap_impl
747 {
748 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
749 {
750 a.base().swap(b);
751 }
752 };
753
754 template<typename MatrixTypeA, typename MatrixTypeB>
755 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
756 {
757 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
758 {
759 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
760 }
761 };
762
763 } // end namespace internal
764
765 } // end namespace Eigen
766
767 #endif // EIGEN_DENSESTORAGEBASE_H
768