STK++ 0.9.13
STK_ReshapeOperators.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23*/
24
25/*
26 * Project: stkpp::Arrays
27 * created on: 17 oct. 2012
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
37#ifndef STK_RESHAPEOPERATORS_H
38#define STK_RESHAPEOPERATORS_H
39
40
41#define EGAL(arg1, arg2) ((arg1::structure_ == int(Arrays::arg2)))
42
43namespace STK
44{
45// forward declaration
46template< typename Lhs> class DiagonalizeOperator;
47template< typename Lhs> class DiagonalGetterOperator;
48template< typename Lhs> class UpperTriangularizeOperator;
49template< typename Lhs> class LowerTriangularizeOperator;
50template< typename Lhs> class SymmetrizeOperator;
51template< typename Lhs> class UpperSymmetrizeOperator;
52template< typename Lhs> class LowerSymmetrizeOperator;
53
54namespace hidden
55{
59template<typename Lhs>
61{
62 enum
63 {
64 structure_ = Arrays::diagonal_,
65 orient_ = Lhs::orient_,
66 sizeRows_ = (Lhs::structure_== int(Arrays::diagonal_) )
67 ? Lhs::sizeRows_ != UnknownSize ? Lhs::sizeRows_ : Lhs::sizeCols_
68 : Lhs::structure_== int(Arrays::point_) ? int(Lhs::sizeCols_) : int(Lhs::sizeRows_),
69 sizeCols_ = (Lhs::structure_== int(Arrays::diagonal_) )
70 ? Lhs::sizeRows_ != UnknownSize ? Lhs::sizeRows_ : Lhs::sizeCols_
71 : Lhs::structure_== int(Arrays::point_) ? Lhs::sizeCols_ : Lhs::sizeRows_,
72 storage_ = Lhs::storage_
73 };
76 typedef typename Lhs::Type Type;
77 typedef typename Lhs::TypeConst TypeConst;
78};
79} // namespace hidden
80
97template< typename Lhs>
98class DiagonalizeOperator: public ExprBase< DiagonalizeOperator< Lhs> >, public TRef<1>
99{
100 public:
104 enum
105 {
111 // this is safe as we can use DiagonalizeOperator only on 1D container
112 size_ = (sizeRows_ != UnknownSize) ? sizeRows_ : sizeCols_
113 };
119 inline DiagonalizeOperator( Lhs const& lhs): Base(), lhs_(lhs)
120 {
122 }
124 inline RowRange const& rowsImpl() const { return lhs().range();}
126 inline ColRange const& colsImpl() const { return lhs().range();}
128 inline Lhs const& lhs() const { return lhs_; }
129
133 inline TypeConst elt2Impl(int i, int j) const
134 {
135#ifdef STK_BOUNDS_CHECK
136 if (i != j) { STKOUT_OF_RANGE_2ARG(DiagonalizeOperator::elt, i, j, i != j);}
137#endif
138 return (lhs_.elt(i));
139 }
143 inline TypeConst elt1Impl(int i) const { return (lhs_.elt(i));}
145 inline TypeConst elt0Impl() const { return (lhs_.elt());}
146
147 protected:
148 Lhs const& lhs_;
149};
150
151
152namespace hidden
153{
157template<typename Lhs>
159{
160 enum
161 {
162 structure_ = Arrays::diagonal_,
163 orient_ = Lhs::orient_,
164 sizeRows_ = ((Lhs::sizeRows_ < Lhs::sizeCols_)) ? Lhs::sizeRows_ : Lhs::sizeCols_,
165 sizeCols_ = sizeRows_,
166 storage_ = Lhs::storage_,
167 isValid_ = ( hidden::Traits<Lhs>::structure_==(int)Arrays::array2D_)
168 ||(hidden::Traits<Lhs>::structure_==(int)Arrays::square_)
169 ||(hidden::Traits<Lhs>::structure_==(int)Arrays::diagonal_)
170 ||(hidden::Traits<Lhs>::structure_==(int)Arrays::lower_triangular_)
171 ||(hidden::Traits<Lhs>::structure_==(int)Arrays::upper_triangular_)
172 ||(hidden::Traits<Lhs>::structure_==(int)Arrays::symmetric_)
173 ||(hidden::Traits<Lhs>::structure_==(int)Arrays::lower_symmetric_)
174 ||(hidden::Traits<Lhs>::structure_==(int)Arrays::upper_symmetric_)
176 use_ = (sizeRows_ != UnknownSize) ? Arrays::useLhsSize_ : Arrays::useLhsOtherSize_,
177 size_ = (sizeRows_ != UnknownSize) ? sizeRows_ : sizeCols_
178 };
181 typedef typename Lhs::Type Type;
182 typedef typename Lhs::TypeConst TypeConst;
183};
184
185} // namespace hidden
186
187
203template< typename Lhs>
204class DiagonalGetterOperator: public ExprBase< DiagonalGetterOperator< Lhs> >, public TRef<1>
205{
206 public:
210
211 enum
212 {
221 };
227
229 inline DiagonalGetterOperator( Lhs const& lhs): Base(), lhs_(lhs)
230 {
231 STK_STATIC_ASSERT(isValid_,YOU_TRIED_CALLING_A_MATRIX_METHOD_ON_A_VECTOR);
232#ifdef STK_BOUNDS_CHECK
233 if (lhs.rows()!=lhs.cols())
235#endif
236 }
238 inline Lhs const& lhs() const { return lhs_; }
240 inline RowRange const& rowsImpl() const { return RangeImpl::rangeImpl(lhs_);}
242 inline ColRange const& colsImpl() const { return RangeImpl::rangeImpl(lhs_);}
243
247 inline TypeConst elt2Impl(int i, int j) const { return (lhs_.elt(i, j));}
251 inline TypeConst elt1Impl(int i) const { return (lhs_.elt(i,i));}
253 inline TypeConst elt0Impl() const { return (lhs_.elt());}
254
255 protected:
256 Lhs const& lhs_;
257};
258
259
260namespace hidden
261{
265template<typename Lhs>
267{
268 enum
269 {
270 structure_ = Arrays::upper_triangular_,
271 orient_ = Lhs::orient_,
272 sizeRows_ = Lhs::sizeRows_,
273 sizeCols_ = Lhs::sizeCols_,
274 storage_ = Lhs::storage_
275 };
278 typedef typename Lhs::Type Type;
279 typedef typename Lhs::TypeConst TypeConst;
280};
281
282} // namespace hidden
283
300template< typename Lhs>
301class UpperTriangularizeOperator: public ExprBase< UpperTriangularizeOperator< Lhs> >, public TRef<1>
302{
303 public:
307
308 enum
309 {
315 };
320
322 inline UpperTriangularizeOperator( Lhs const& lhs): Base(), lhs_(lhs) {}
324 inline Lhs const& lhs() const { return lhs_; }
326 inline RowRange const& rowsImpl() const { return lhs().rows();}
328 inline ColRange const& colsImpl() const { return lhs().cols();}
329
333 inline TypeConst elt2Impl(int i, int j) const
334 {
335#ifdef STK_BOUNDS_CHECK
336 if (j<i)
337 STKRUNTIME_ERROR_2ARG(UpperTriangularizeOperator::elt2Impl,i,j,use of the lower part);
338#endif
339 return (lhs_.elt(i, j));
340 }
341
342 protected:
343 Lhs const& lhs_;
344};
345
346
347namespace hidden
348{
352template<typename Lhs>
354{
355 enum
356 {
357 structure_ = Arrays::lower_triangular_,
358 orient_ = Lhs::orient_,
359 sizeRows_ = Lhs::sizeRows_,
360 sizeCols_ = Lhs::sizeCols_,
361 storage_ = Lhs::storage_
362 };
365 typedef typename Lhs::Type Type;
366 typedef typename Lhs::TypeConst TypeConst;
367};
368} // namespace hidden
369
386template< typename Lhs>
387class LowerTriangularizeOperator: public ExprBase< LowerTriangularizeOperator< Lhs> >, public TRef<1>
388{
389 public:
393
394 enum
395 {
401 };
406
408 inline LowerTriangularizeOperator( Lhs const& lhs): Base(), lhs_(lhs) {}
410 inline Lhs const& lhs() const { return lhs_; }
412 inline RowRange const& rowsImpl() const { return lhs().rows();}
414 inline ColRange const& colsImpl() const { return lhs().cols();}
415
419 inline TypeConst elt2Impl(int i, int j) const
420 {
421#ifdef STK_BOUNDS_CHECK
422 if (j>i)
423 STKRUNTIME_ERROR_2ARG(LowerTriangularizeOperator::elt2Impl,i,j,use of the upper part);
424#endif
425 return (lhs_.elt(i, j));
426 }
427
428 protected:
429 Lhs const& lhs_;
430};
431
432namespace hidden
433{
437template<typename Lhs>
439{
440 enum
441 {
442 structure_ = Arrays::symmetric_,
443 orient_ = Lhs::orient_,
444 sizeRows_ = Lhs::sizeRows_,
445 sizeCols_ = Lhs::sizeCols_,
446 storage_ = Lhs::storage_
447 };
450 typedef typename Lhs::Type Type;
451 typedef typename Lhs::TypeConst TypeConst;
452};
453
454} // namespace hidden
455
472template< typename Lhs>
473class SymmetrizeOperator: public ExprBase< SymmetrizeOperator< Lhs> >, public TRef<1>
474{
475 public:
479
480 enum
481 {
482 structure_ = hidden::Traits< SymmetrizeOperator<Lhs> >::structure_,
486 storage_ = hidden::Traits< SymmetrizeOperator<Lhs> >::storage_
487 };
492
494 inline SymmetrizeOperator( Lhs const& lhs): Base(), lhs_(lhs)
497 inline Lhs const& lhs() const { return lhs_; }
499 inline RowRange const& rowsImpl() const { return lhs().rows();}
501 inline ColRange const& colsImpl() const { return lhs().cols();}
502
506 inline TypeConst elt2Impl(int i, int j) const
507 { return (lhs_.elt(i, j));}
508
509 protected:
510 Lhs const& lhs_;
511};
512
513
514namespace hidden
515{
519template<typename Lhs>
521{
522 enum
523 {
524 structure_ = Arrays::upper_symmetric_,
525 orient_ = Lhs::orient_,
526 sizeRows_ = Lhs::sizeRows_,
527 sizeCols_ = Lhs::sizeCols_,
528 storage_ = Lhs::storage_
529 };
532 typedef typename Lhs::Type Type;
533 typedef typename Lhs::TypeConst TypeConst;
534};
535
536} // namespace hidden
537
554template< typename Lhs>
555class UpperSymmetrizeOperator: public ExprBase< UpperSymmetrizeOperator< Lhs> >, public TRef<1>
556{
557 public:
561
562 enum
563 {
569 };
574
579 inline Lhs const& lhs() const { return lhs_; }
581 inline RowRange const& rowsImpl() const { return lhs().rows();}
583 inline ColRange const& colsImpl() const { return lhs().cols();}
584
588 inline TypeConst elt2Impl(int i, int j) const
589 { return ((j<i) ? lhs_.elt(j, i) : lhs_.elt(i, j));}
590
591 protected:
592 Lhs const& lhs_;
593};
594
595namespace hidden
596{
600template<typename Lhs>
602{
603 enum
604 {
605 structure_ = Arrays::lower_symmetric_,
606 orient_ = Lhs::orient_,
607 sizeRows_ = Lhs::sizeRows_,
608 sizeCols_ = Lhs::sizeCols_,
609 storage_ = Lhs::storage_
610 };
613 typedef typename Lhs::Type Type;
614 typedef typename Lhs::TypeConst TypeConst;
615};
616
617} // end namespace hidden
618
635template< typename Lhs>
636class LowerSymmetrizeOperator: public ExprBase< LowerSymmetrizeOperator< Lhs> >, public TRef<1>
637{
638 public:
642
643 enum
644 {
650 };
655
660 inline Lhs const& lhs() const { return lhs_; }
662 inline RowRange const& rowsImpl() const { return lhs().rows();}
664 inline ColRange const& colsImpl() const { return lhs().cols();}
665
669 inline TypeConst elt2Impl(int i, int j) const
670 { return ((j>i) ? lhs_.elt(j, i) : lhs_.elt(i, j));}
671
672 protected:
673 Lhs const& lhs_;
674};
675
676} // namespace STK
677
678
679#undef EGAL
680
681#endif /* STK_RESHAPEOPERATORS_H */
#define STKOUT_OF_RANGE_2ARG(Where, Arg1, Arg2, Error)
Definition STK_Macros.h:102
#define STKRUNTIME_ERROR_NO_ARG(Where, Error)
Definition STK_Macros.h:138
#define STKRUNTIME_ERROR_2ARG(Where, Arg1, Arg2, Error)
Definition STK_Macros.h:120
#define STK_STATIC_ASSERT(COND, MSG)
#define STK_STATIC_ASSERT_ONE_DIMENSION_ONLY(EXPR)
#define STK_STATIC_ASSERT_TWO_DIMENSIONS_ONLY(EXPR)
Generic expression when we want to get the diagonal of a two-dimensional square expression.
TRange< size_ > RowRange
Type of the Range for the rows.
TRange< size_ > ColRange
Type of the Range for the columns.
hidden::DiagonalRangeImpl< Lhs, size_, use_ > RangeImpl
TypeConst elt1Impl(int i) const
DiagonalGetterOperator(Lhs const &lhs)
Constructor.
hidden::Traits< DiagonalGetterOperator< Lhs > >::Type Type
ExprBase< DiagonalGetterOperator< Lhs > > Base
ColRange const & colsImpl() const
RowRange const & rowsImpl() const
hidden::Traits< DiagonalGetterOperator< Lhs > >::TypeConst TypeConst
TypeConst elt2Impl(int i, int j) const
Generic expression when a one dimensional vector/point/idagonal expression is "diagonalized".
ExprBase< DiagonalizeOperator< Lhs > > Base
TypeConst elt1Impl(int i) const
TypeConst elt2Impl(int i, int j) const
DiagonalizeOperator(Lhs const &lhs)
Constructor.
TRange< size_ > RowRange
Type of the Range for the rows.
RowRange const & rowsImpl() const
TRange< size_ > ColRange
Type of the Range for the columns.
hidden::Traits< DiagonalizeOperator< Lhs > >::Type Type
ColRange const & colsImpl() const
hidden::Traits< DiagonalizeOperator< Lhs > >::TypeConst TypeConst
base class for template evaluation expressions and visitors.
Generic expression when we want to get the lower-part of a two-dimensional symmetric expression.
hidden::Traits< LowerSymmetrizeOperator< Lhs > >::TypeConst TypeConst
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
TypeConst elt2Impl(int i, int j) const
hidden::Traits< LowerSymmetrizeOperator< Lhs > >::Type Type
LowerSymmetrizeOperator(Lhs const &lhs)
Constructor.
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
ExprBase< LowerSymmetrizeOperator< Lhs > > Base
ColRange const & colsImpl() const
RowRange const & rowsImpl() const
Generic expression when we want to get the lower-part of a two-dimensional expression.
LowerTriangularizeOperator(Lhs const &lhs)
Constructor.
hidden::Traits< LowerTriangularizeOperator< Lhs > >::Type Type
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
TypeConst elt2Impl(int i, int j) const
ExprBase< LowerTriangularizeOperator< Lhs > > Base
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
hidden::Traits< LowerTriangularizeOperator< Lhs > >::TypeConst TypeConst
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Generic expression when we want to get the upper-part of a two-dimensional symmetric expression.
TypeConst elt2Impl(int i, int j) const
RowRange const & rowsImpl() const
hidden::Traits< SymmetrizeOperator< Lhs > >::Type Type
SymmetrizeOperator(Lhs const &lhs)
Constructor.
ExprBase< SymmetrizeOperator< Lhs > > Base
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
ColRange const & colsImpl() const
hidden::Traits< SymmetrizeOperator< Lhs > >::TypeConst TypeConst
Generic expression when we want to get the upper-part of a two-dimensional symmetric expression.
TypeConst elt2Impl(int i, int j) const
hidden::Traits< UpperSymmetrizeOperator< Lhs > >::TypeConst TypeConst
UpperSymmetrizeOperator(Lhs const &lhs)
Constructor.
hidden::Traits< UpperSymmetrizeOperator< Lhs > >::Type Type
ExprBase< UpperSymmetrizeOperator< Lhs > > Base
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
ColRange const & colsImpl() const
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
RowRange const & rowsImpl() const
Generic expression when we want to get the upper-part of a two-dimensional expression.
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
UpperTriangularizeOperator(Lhs const &lhs)
Constructor.
hidden::Traits< UpperTriangularizeOperator< Lhs > >::Type Type
hidden::Traits< UpperTriangularizeOperator< Lhs > >::TypeConst TypeConst
TypeConst elt2Impl(int i, int j) const
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
ExprBase< UpperTriangularizeOperator< Lhs > > Base
@ diagonal_
diagonal matrix/array/expression
const int UnknownSize
This value means that an integer is not known at compile-time, and that instead the value is stored i...
The namespace STK is the main domain space of the Statistical ToolKit project.
Base class for all referencing containers.
Allow to disambiguate the call to range to use.
ColOperator< DiagonalGetterOperator< Lhs > > Col
RowOperator< DiagonalGetterOperator< Lhs > > Row
RowOperator< DiagonalizeOperator< Lhs > > Row
ColOperator< DiagonalizeOperator< Lhs > > Col
RowOperator< LowerSymmetrizeOperator< Lhs > > Row
ColOperator< LowerSymmetrizeOperator< Lhs > > Col
RowOperator< LowerTriangularizeOperator< Lhs > > Row
ColOperator< LowerTriangularizeOperator< Lhs > > Col
RowOperator< SymmetrizeOperator< Lhs > > Row
ColOperator< SymmetrizeOperator< Lhs > > Col
RowOperator< UpperSymmetrizeOperator< Lhs > > Row
ColOperator< UpperSymmetrizeOperator< Lhs > > Col
ColOperator< UpperTriangularizeOperator< Lhs > > Col
RowOperator< UpperTriangularizeOperator< Lhs > > Row