STK++ 0.9.13
STK_ProductOperators.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: 20 oct. 2012
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
35#ifndef STK_PRODUCTOPERATORS_H
36#define STK_PRODUCTOPERATORS_H
37
38// forward declaration
39namespace STK
40{
41 template<class Derived> class ExprBase;
42 template<typename Type, int SizeRows_, int SizeCols_, bool Orient_> class CAllocator;
43}
44
45#define EGAL(arg1, arg2) ((arg1::structure_ == int(Arrays::arg2)))
46
47namespace STK
48{
61template<typename Lhs, typename Rhs> class ArrayByDiagonalProduct;
62
75template<typename Lhs, typename Rhs> class DiagonalByArrayProduct;
76
89template<typename Lhs, typename Rhs> class VectorByPointProduct;
90
103template<typename Lhs, typename Rhs> class PointByArrayProduct;
104
117template<typename Lhs, typename Rhs> class ArrayByVectorProduct;
118
137template<typename Lhs, typename Rhs> class ArrayByArrayProduct;
138
139namespace hidden
140{
144template< typename Lhs, typename Rhs>
146{
147 enum
148 {
149 structure_ = Lhs::structure_,
150 sizeRows_ = Lhs::sizeRows_ ,
151 sizeCols_ = Rhs::sizeCols_,
152 orient_ = Lhs::orient_,
153 storage_ = Lhs::storage_
154 };
157};
158
159} // namespace hidden
160
176template<typename Lhs, typename Rhs>
177class ArrayByDiagonalProduct: public ExprBase< ArrayByDiagonalProduct<Lhs, Rhs> >
178 , public TRef<1>
179{
180 public:
184
185 enum
186 {
192 };
197
198 inline ArrayByDiagonalProduct( const Lhs& lhs, const Rhs& rhs)
199 : Base(), lhs_(lhs), rhs_(rhs)
200 {
201 if (lhs.cols() != rhs.rows())
203 }
205 inline RowRange const& rowsImpl() const { return lhs_.rows();}
207 inline ColRange const& colsImpl() const { return rhs_.cols();}
208
210 inline TypeConst elt2Impl(int i, int j) const { return lhs_.elt(i,j)*rhs_.elt(j);}
215 inline TypeConst elt1Impl(int i) const { return lhs_.elt(i)*rhs_.elt(i);}
216
218 inline Lhs const& lhs() const { return lhs_; }
220 inline Rhs const& rhs() const { return rhs_; }
221
222 protected:
223 Lhs const& lhs_;
224 Rhs const& rhs_;
225};
226
227namespace hidden
228{
232template< typename Lhs, typename Rhs>
234{
235 enum
236 {
237 structure_ = Rhs::structure_,
238 sizeRows_ = Lhs::sizeRows_,
239 sizeCols_ = Rhs::sizeCols_,
240 orient_ = Rhs::orient_,
241 storage_ = Rhs::storage_
242 };
244 typedef typename RemoveConst<Type>::Type TypeConst; // not a reference as it is a temporary
245};
246
247} // namespace hidden
248
267template<typename Lhs, typename Rhs>
268class DiagonalByArrayProduct: public ExprBase< DiagonalByArrayProduct<Lhs, Rhs> >
269 , public TRef<1>
270{
271 public:
275
276 enum
277 {
283 };
288
289 inline DiagonalByArrayProduct( const Lhs& lhs, const Rhs& rhs)
290 : Base(), lhs_(lhs), rhs_(rhs)
291 {
292 if (lhs.cols() != rhs.rows())
294 }
296 inline RowRange const& rowsImpl() const { return lhs_.rows();}
298 inline ColRange const& colsImpl() const { return rhs_.cols();}
299
301 inline TypeConst elt2Impl(int i, int j) const { return lhs_.elt(i)*rhs_.elt(i,j);}
306 inline TypeConst elt1Impl(int i) const { return lhs_.elt(i)*rhs_.elt(i);}
307
309 inline Lhs const& lhs() const { return lhs_; }
311 inline Rhs const& rhs() const { return rhs_; }
312
313 protected:
314 Lhs const& lhs_;
315 Rhs const& rhs_;
316};
317
318
319namespace hidden
320{
325template< typename Lhs, typename Rhs>
340
341} // namespace hidden
342
358template<typename Lhs, typename Rhs>
359
360class VectorByPointProduct: public ExprBase< VectorByPointProduct<Lhs, Rhs> >
361 , public TRef<1>
362{
363 public:
367
368 enum
369 {
375 };
380
382 VectorByPointProduct( const Lhs& lhs, const Rhs& rhs): Base(), lhs_(lhs), rhs_(rhs){}
384 inline RowRange const& rowsImpl() const { return lhs_.rows();}
386 inline ColRange const& colsImpl() const { return rhs_.cols();}
387
389 inline TypeConst elt2Impl(int i, int j) const { return lhs_.elt(i)*rhs_.elt(j);}
391 inline TypeConst elt0Impl() const { return lhs_.elt()*rhs_.elt();}
392
394 inline Lhs const& lhs() const { return lhs_; }
396 inline Rhs const& rhs() const { return rhs_; }
397
398 protected:
399 Lhs const& lhs_;
400 Rhs const& rhs_;
401};
402
403
404
405namespace hidden
406{
410template< typename Lhs, typename Rhs>
428
429} // namespace hidden
430
446template<typename Lhs, typename Rhs>
447class PointByArrayProduct: public ExprBase< PointByArrayProduct<Lhs, Rhs> >
448 , public TRef<1>
449{
450 public:
455
456 enum
457 {
463 };
468
469 inline PointByArrayProduct( const Lhs& lhs, const Rhs& rhs)
470 : Base(), lhs_(lhs), rhs_(rhs)
471 , result_(1, rhs.sizeCols(), Type(0))
472 {
473 if (lhs.range() != rhs.rows())
475 result_.shift(lhs_.beginRows(), rhs_.beginCols());
477 }
479 inline RowRange const& rowsImpl() const { return result_.rows();}
481 inline ColRange const& colsImpl() const { return result_.cols();}
482
484 inline TypeConst elt2Impl(int i, int j) const { return result_.elt(i, j);}
486 inline TypeConst elt1Impl(int i) const { return result_.elt(i);}
488 inline TypeConst elt0Impl() const { return result_.elt();}
489
491 inline Lhs const& lhs() const { return lhs_; }
493 inline Rhs const& rhs() const { return rhs_; }
495 Allocator const& result() const { return result_; }
496
497 protected:
498 Lhs const& lhs_;
499 Rhs const& rhs_;
500
501 private:
503};
504
505namespace hidden
506{
510template< typename Lhs, typename Rhs>
528
529} // nmaespace hidden
530
546template<typename Lhs, typename Rhs>
547class ArrayByVectorProduct: public ExprBase< ArrayByVectorProduct<Lhs, Rhs> >
548 , public TRef<1>
549{
550 public:
555 enum
556 {
562 };
567
569 : Base(), lhs_(lhs), rhs_(rhs)
570 , result_(lhs.sizeRows(), 1, Type(0)) // create result
571 {
572 if (lhs.cols() != rhs.range())
574 result_.shift(lhs_.beginRows(), rhs_.beginCols());
576 }
578 inline RowRange const& rowsImpl() const { return result_.rows();}
580 inline ColRange const& colsImpl() const { return result_.cols();}
581
583 inline TypeConst elt2Impl(int i, int j) const { return result_.elt(i, j);}
585 inline TypeConst elt1Impl(int i) const { return result_.elt(i);}
587 inline TypeConst elt0Impl() const { return result_.elt();}
588
590 inline Lhs const& lhs() const { return lhs_; }
592 inline Rhs const& rhs() const { return rhs_; }
594 inline Allocator const& result() const { return result_; }
595
596 protected:
597 Lhs const& lhs_;
598 Rhs const& rhs_;
599
600 private:
602};
603
604
605namespace hidden
606{
610template< typename Lhs, typename Rhs>
612{
613 // delegate to ProductTraits all the stuff
615
616 enum
617 {
618 lhs_structure_ = Traits<Lhs>::structure_,
619 rhs_structure_ = Traits<Rhs>::structure_,
620 structure_ = Base::structure_,
621 sizeRows_ = Base::sizeRows_,
622 sizeCols_ = Base::sizeCols_,
623 orient_ = Base::orient_,
624 storage_ = Base::storage_,
625 useForRows_ = Base::useForRows_,
626 useForCols_ = Base::useForCols_
627 };
628
629 typedef typename Base::Type Type;
630 typedef typename Base::TypeConst TypeConst;
631 typedef typename Base::Allocator Allocator;
632};
633
634} // namespace hidden
635
651template<typename Lhs, typename Rhs>
652class ArrayByArrayProduct: public ExprBase< ArrayByArrayProduct<Lhs, Rhs> >, public TRef<1>
653{
654 public:
655 enum
656 {
657 // All the valid cases for ArrayByArray operator
658 isValid_ = ( EGAL(Lhs,array2D_)||EGAL(Lhs,square_)
659 ||EGAL(Lhs,lower_triangular_)||EGAL(Lhs,upper_triangular_)
660 ||EGAL(Lhs,symmetric_)||EGAL(Lhs,lower_symmetric_)||EGAL(Lhs,upper_symmetric_)
661 )
662 &&
663 ( EGAL(Rhs,array2D_)||EGAL(Rhs,square_)
664 ||EGAL(Rhs,lower_triangular_)||EGAL(Rhs,upper_triangular_)
665 ||EGAL(Rhs,symmetric_)||EGAL(Rhs,lower_symmetric_)||EGAL(Rhs,upper_symmetric_)
666 ),
676 };
677
681
684
687
693 ArrayByArrayProduct( Lhs const& lhs, Rhs const& rhs);
694
696 inline RowRange const& rowsImpl() const { return RowsImpl::rowsImpl(lhs_, rhs_);}
698 inline ColRange const& colsImpl() const { return ColsImpl::colsImpl(lhs_, rhs_);}
699
701 inline Lhs const& lhs() const { return lhs_; }
703 inline Rhs const& rhs() const { return rhs_; }
705 inline Allocator const& result() const { return result_; }
706
708 inline TypeConst elt2Impl(int i, int j) const { return result_.elt(i,j);}
710 inline TypeConst elt1Impl(int i) const { return result_.elt(i);}
712 inline TypeConst elt0Impl() const { return result_.elt();}
713
714 protected:
715 Lhs const& lhs_;
716 Rhs const& rhs_;
717
718 private:
720};
721
722template<typename Lhs, typename Rhs>
724 : Base(), lhs_(lhs), rhs_(rhs)
725 , result_(lhs.sizeRows(), rhs.sizeCols(), Type(0))
726{
728 if (lhs.cols() != rhs.rows())
730 result_.shift(lhs_.beginRows(), rhs_.beginCols());
731 // general sizes
733}
734
735} // namespace STK
736
737#undef EGAL
738
739#endif /* STK_PRODUCTOPERATORS_H */
#define EGAL(arg1, arg2)
#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_PRODUCT_OPERATOR_MISMATCH(COND)
Generic expression where a product operator is applied to two expressions.
Allocator const & result() const
hidden::BinaryRowsImpl< Lhs, Rhs, sizeRows_, useForRows_ > RowsImpl
ExprBase< ArrayByArrayProduct< Lhs, Rhs > > Base
hidden::BinaryColsImpl< Lhs, Rhs, sizeCols_, useForCols_ > ColsImpl
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
hidden::ProductDispatcher< Lhs, Rhs, Allocator, lhs_structure_, rhs_structure_ > Dispatcher
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
hidden::Traits< ArrayByArrayProduct >::TypeConst TypeConst
ColRange const & colsImpl() const
hidden::Traits< ArrayByArrayProduct >::Type Type
TypeConst elt2Impl(int i, int j) const
ArrayByArrayProduct(Lhs const &lhs, Rhs const &rhs)
Constructor.
hidden::Traits< ArrayByArrayProduct< Lhs, Rhs > >::Allocator Allocator
TypeConst elt1Impl(int i) const
RowRange const & rowsImpl() const
Generic expression where a product operator is applied to two expressions.
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
ArrayByDiagonalProduct(const Lhs &lhs, const Rhs &rhs)
hidden::Traits< ArrayByDiagonalProduct >::Type Type
RowRange const & rowsImpl() const
ExprBase< ArrayByDiagonalProduct< Lhs, Rhs > > Base
ColRange const & colsImpl() const
hidden::Traits< ArrayByDiagonalProduct >::TypeConst TypeConst
TypeConst elt2Impl(int i, int j) const
TypeConst elt1Impl(int i) const
Generic expression where a product operator is applied to two expressions.
ExprBase< ArrayByVectorProduct< Lhs, Rhs > > Base
ColRange const & colsImpl() const
hidden::Traits< ArrayByVectorProduct >::Allocator Allocator
hidden::Traits< ArrayByVectorProduct >::Type Type
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
TypeConst elt1Impl(int i) const
ArrayByVectorProduct(const Lhs &lhs, const Rhs &rhs)
Allocator const & result() const
RowRange const & rowsImpl() const
hidden::Traits< ArrayByVectorProduct >::TypeConst TypeConst
TypeConst elt2Impl(int i, int j) const
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
Generic expression where a product operator is applied to two expressions.
hidden::Traits< DiagonalByArrayProduct >::TypeConst TypeConst
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
hidden::Traits< DiagonalByArrayProduct >::Type Type
DiagonalByArrayProduct(const Lhs &lhs, const Rhs &rhs)
RowRange const & rowsImpl() const
TypeConst elt2Impl(int i, int j) const
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
TypeConst elt1Impl(int i) const
ColRange const & colsImpl() const
ExprBase< DiagonalByArrayProduct< Lhs, Rhs > > Base
base class for template evaluation expressions and visitors.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Generic expression where a product operator is applied to two expressions.
hidden::Traits< PointByArrayProduct >::Type Type
hidden::Traits< PointByArrayProduct >::Allocator Allocator
ColRange const & colsImpl() const
Allocator const & result() const
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
RowRange const & rowsImpl() const
PointByArrayProduct(const Lhs &lhs, const Rhs &rhs)
hidden::Traits< PointByArrayProduct >::TypeConst TypeConst
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
ExprBase< PointByArrayProduct< Lhs, Rhs > > Base
TypeConst elt1Impl(int i) const
TypeConst elt2Impl(int i, int j) const
Generic expression where a product operator is applied to two expressions.
RowRange const & rowsImpl() const
hidden::Traits< VectorByPointProduct >::Type Type
VectorByPointProduct(const Lhs &lhs, const Rhs &rhs)
constructor
hidden::Traits< VectorByPointProduct >::TypeConst TypeConst
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
ColRange const & colsImpl() const
TypeConst elt2Impl(int i, int j) const
ExprBase< VectorByPointProduct< Lhs, Rhs > > Base
@ sparse_
sparse matrix/vector/array/expression
@ dense_
dense matrix/vector/array/expression
@ array2D_
general matrix/array/expression
@ point_
row oriented vector/array/expression
@ vector_
column oriented vector/array/expression
@ by_row_
storage by row
@ by_col_
storage by column
The namespace STK is the main domain space of the Statistical ToolKit project.
Base class for all referencing containers.
implement the access to the columns of the BinaryOperator Possible cases are:
implement the access to the rows of the BinaryOperator Possible cases are:
Dispatcher allowing to choose th e way to multiply two expressions.
static void run(Lhs const &lhs, Rhs const &rhs, Result &res)
loop over the columns of rhs first
If<(sizeof(Type1)>sizeof(Type2)), Type1, Type2 >::Result result_type
ProductTraits< Lhs, Rhs, Traits< Lhs >::structure_, Traits< Rhs >::structure_ > Base
Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
CAllocator< Type, sizeRows_, sizeCols_, orient_ > Allocator
Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
CAllocator< Type, sizeRows_, sizeCols_, orient_ > Allocator
Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type