STK++ 0.9.13
STK_ProductDispatcher.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: 25 déc. 2012
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
35#ifndef STK_PRODUCTDISPATCHER_H
36#define STK_PRODUCTDISPATCHER_H
37
38#include "STK_ProductRaw.h"
41
42namespace STK
43{
44
45// forward declarations (needed because there is no CAllocator with this structure)
46template<typename> class Array2DUpperTriangular;
47template<typename> class Array2DLowerTriangular;
48template<typename Type, int SizeRows_, int SizeCols_, bool Orient_> class CAllocator;
49
50template<typename> class SArray2DUpperTriangular;
51template<typename> class SArray2DLowerTriangular;
52template<typename> class SArray2D;
53
54namespace hidden
55{
56
57//------------------------------------------------------------
58// general lhs case. result is general except if rhs is vector
60template<typename Lhs, typename Rhs, int RStructure_>
61struct ProductTraits<Lhs, Rhs, Arrays::array2D_, RStructure_>
62{
63 enum
64 {
65 structure_ = Arrays::array2D_,
68 // use rhs orientation by default, otherwise orientation of the panel size
71 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
72 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
73 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_))||(Traits<Rhs>::storage_ == int(Arrays::dense_))
74 ? int(Arrays::dense_) : int(Arrays::sparse_)
75 , useForRows_ = Arrays::useLhsSize_
76 , useForCols_ = Arrays::useRhsSize_
77 };
78
80 typedef typename RemoveConst<Type>::Type const& TypeConst;
81
82 typedef typename If< storage_ == int(Arrays::dense_)
85 >::Result Allocator;
86};
87
88//------------------------------------------------------------
89// general lhs case. result is general except if rhs is vector
91template<typename Lhs, typename Rhs>
92struct ProductTraits<Lhs, Rhs, Arrays::array2D_, Arrays::square_>
93{
94 enum
95 {
96 structure_ = Arrays::array2D_,
98 sizeCols_ = Traits<Lhs>::sizeCols_ != UnknownSize ?
100 // use rhs orientation by default, otherwise orientation of the panel size
101 orient_ = ( Traits<Lhs>::sizeRows_ == UnknownSize || Traits<Rhs>::sizeCols_ == UnknownSize)
102 ? Traits<Rhs>::orient_
103 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
104 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
105 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
106 ? int(Arrays::dense_) : int(Arrays::sparse_)
107 , useForRows_ = Arrays::useLhsSize_
108 , useForCols_ = Traits<Lhs>::sizeCols_ != UnknownSize ? Arrays::useLhsSize_ : Arrays::useRhsSize_
109 };
110
112 typedef typename RemoveConst<Type>::Type const& TypeConst;
113
114 typedef typename If< storage_ == int(Arrays::dense_)
117 >::Result Allocator;
118};
119
120//----------------------------------
121// square lhs case. result is general except if rhs square
122template<typename Lhs, typename Rhs, int RStructure_>
123struct ProductTraits<Lhs, Rhs, Arrays::square_, RStructure_>
124{
125 enum
126 {
127 structure_ = Arrays::array2D_,
129 ? int(Traits<Lhs>::sizeRows_) : int(Traits<Rhs>::sizeRows_),
130
131 sizeCols_ = Traits<Rhs>::sizeCols_,
132 // use rhs orientation by default, otherwise orientation of the panel size
133 orient_ = ( Traits<Lhs>::sizeRows_ == UnknownSize || Traits<Rhs>::sizeCols_ == UnknownSize)
134 ? Traits<Rhs>::orient_
135 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
136 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
137 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
138 ? int(Arrays::dense_) : int(Arrays::sparse_)
139 , useForRows_ = Traits<Lhs>::sizeRows_ != UnknownSize ? Arrays::useLhsSize_ : Arrays::useRhsSize_
140 , useForCols_ = Arrays::useRhsSize_
141 };
142
144 typedef typename RemoveConst<Type>::Type const& TypeConst;
145
146 typedef typename If< storage_ == int(Arrays::dense_)
149 >::Result Allocator;
150};
151
152//----------------------------------
153// square rhs case. result is general except if rhs square
154template<typename Lhs, typename Rhs, int LStructure_>
155struct ProductTraits<Lhs, Rhs, LStructure_, Arrays::square_>
156{
157 enum
158 {
159 structure_ = Arrays::array2D_,
161
163 ? int(Traits<Lhs>::sizeCols_) : int(Traits<Rhs>::sizeCols_),
164
165 // use rhs orientation by default, otherwise orientation of the panel size
166 orient_ = ( Traits<Lhs>::sizeRows_ == UnknownSize || Traits<Rhs>::sizeCols_ == UnknownSize)
167 ? Traits<Rhs>::orient_
168 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
169 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
170 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
171 ? int(Arrays::dense_) : int(Arrays::sparse_)
172 , useForRows_ = Arrays::useLhsSize_
173 , useForCols_ = Traits<Lhs>::sizeCols_ != UnknownSize ? Arrays::useLhsSize_ : Arrays::useRhsSize_
174 };
175
177 typedef typename RemoveConst<Type>::Type const& TypeConst;
178
179 typedef typename If< storage_ == int(Arrays::dense_)
182 >::Result Allocator;
183};
184
185template<typename Lhs, typename Rhs>
186struct ProductTraits<Lhs, Rhs, Arrays::square_, Arrays::square_>
187{
188 enum
189 {
190 structure_ = Arrays::square_,
195 // use rhs orientation by default, otherwise orientation of the panel size
198 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
199 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
200 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
201 ? int(Arrays::dense_) : int(Arrays::sparse_)
202 , useForRows_ = Traits<Lhs>::sizeRows_ != UnknownSize ? Arrays::useLhsSize_ : Arrays::useRhsSize_
203 , useForCols_ = Traits<Rhs>::sizeCols_ != UnknownSize ? Arrays::useRhsSize_ : Arrays::useLhsSize_
204 };
205
207 typedef typename RemoveConst<Type>::Type const& TypeConst;
208
209 typedef typename If< storage_ == int(Arrays::dense_)
212 >::Result Allocator;
213};
214
215//----------------------------------
216// lower triangular case
217template<typename Lhs, typename Rhs, int RStructure_>
218struct ProductTraits<Lhs, Rhs, Arrays::lower_triangular_, RStructure_>
219{
220 enum
221 {
222 structure_ = Arrays::array2D_,
225 // use rhs orientation by default, otherwise orientation of the panel size
228 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
229 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
230 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
231 ? int(Arrays::dense_) : int(Arrays::sparse_)
232 , useForRows_ = Arrays::useLhsSize_
233 , useForCols_ = Arrays::useRhsSize_
234 };
235
237 typedef typename RemoveConst<Type>::Type const& TypeConst;
238
239 typedef typename If< storage_ == int(Arrays::dense_)
242 >::Result Allocator;
243};
244
245template<typename Lhs, typename Rhs>
246struct ProductTraits<Lhs, Rhs, Arrays::lower_triangular_, Arrays::square_>
247{
248 enum
249 {
250 structure_ = Arrays::array2D_,
254 // use rhs orientation by default, otherwise orientation of the panel size
257 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
258 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
259 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
260 ? int(Arrays::dense_) : int(Arrays::sparse_)
261 , useForRows_ = Arrays::useLhsSize_
262 , useForCols_ = Traits<Lhs>::sizeCols_ != UnknownSize ? Arrays::useLhsSize_ : Arrays::useRhsSize_
263 };
264
266 typedef typename RemoveConst<Type>::Type const& TypeConst;
267
268 typedef typename If< storage_ == int(Arrays::dense_)
271 >::Result Allocator;
272};
273
274template<typename Lhs, typename Rhs>
275struct ProductTraits<Lhs, Rhs, Arrays::lower_triangular_, Arrays::lower_triangular_>
276{
277 enum
278 {
279 structure_ = Arrays::lower_triangular_,
282 // use rhs orientation by default, otherwise orientation of the panel size
285 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
286 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
287 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
288 ? int(Arrays::dense_) : int(Arrays::sparse_)
289 , useForRows_ = Arrays::useLhsSize_
290 , useForCols_ = Arrays::useRhsSize_
291};
293 typedef typename RemoveConst<Type>::Type const& TypeConst;
294
295 typedef typename If< storage_ == int(Arrays::dense_)
298 >::Result Allocator;
299};
300
301//----------------------------------
302// upper triangular case
303template<typename Lhs, typename Rhs, int RStructure_>
304struct ProductTraits<Lhs, Rhs, Arrays::upper_triangular_, RStructure_>
305{
306 enum
307 {
308 structure_ = Arrays::array2D_,
311 // use rhs orientation by default, otherwise orientation of the panel size
314 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
315 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
316 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
317 ? int(Arrays::dense_) : int(Arrays::sparse_)
318 , useForRows_ = Arrays::useLhsSize_
319 , useForCols_ = Arrays::useRhsSize_
320 };
322 typedef typename RemoveConst<Type>::Type const& TypeConst;
323
324 typedef typename If< storage_ == int(Arrays::dense_)
327 >::Result Allocator;
328};
329
330template<typename Lhs, typename Rhs>
331struct ProductTraits<Lhs, Rhs, Arrays::upper_triangular_, Arrays::square_>
332{
333 enum
334 {
335 structure_ = Arrays::array2D_,
339 // use rhs orientation by default, otherwise orientation of the panel size
342 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
343 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
344 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
345 ? int(Arrays::dense_) : int(Arrays::sparse_)
346 , useForRows_ = Arrays::useLhsSize_
347 , useForCols_ = Traits<Lhs>::sizeCols_ != UnknownSize ? Arrays::useLhsSize_ : Arrays::useRhsSize_
348 };
350 typedef typename RemoveConst<Type>::Type const& TypeConst;
351
352 typedef typename If< storage_ == int(Arrays::dense_)
355 >::Result Allocator;
356};
357
358template<typename Lhs, typename Rhs>
359struct ProductTraits<Lhs, Rhs, Arrays::upper_triangular_, Arrays::upper_triangular_>
360{
361 enum
362 {
363 structure_ = Arrays::upper_triangular_,
366 // use rhs orientation by default, otherwise orientation of the panel size
369 : int(Traits<Lhs>::sizeRows_) > int(Traits<Rhs>::sizeCols_)
370 ? int(Traits<Lhs>::orient_) : int(Traits<Rhs>::orient_),
371 storage_ = ( Traits<Lhs>::storage_ == int(Arrays::dense_)) || (Traits<Rhs>::storage_ == int(Arrays::dense_))
372 ? int(Arrays::dense_) : int(Arrays::sparse_)
373 , useForRows_ = Arrays::useLhsSize_
374 , useForCols_ = Arrays::useRhsSize_
375 };
377 typedef typename RemoveConst<Type>::Type const& TypeConst;
378
379 typedef typename If< storage_ == int(Arrays::dense_)
382 >::Result Allocator;
383};
384
393template < class Lhs, class Rhs, class Result
397{
398 enum
399 {
400 // structure_ = Traits<Result>::structure_,
404 storage_ = Traits<Result>::storage_
405 };
407
409 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
410 {
411 if (lhs.sizeRows()<rhs.sizeCols())
412 {
413 for (int j=rhs.beginCols(); j< rhs.endCols(); j++)
414 {
415 Range const r = res.rangeRowsInCol(j);
416// int const begin = res.rangeRowsInCol(j).begin(), end = res.rangeRowsInCol(j).end();
417 for (int i=r.begin(); i< r.end(); i++)
418 { MultCoeff::dot(lhs, rhs, res, i, j);}
419 }
420 }
421 else
422 {
423 for (int i=lhs.beginRows(); i< lhs.endRows(); i++)
424 {
425 Range const r = res.rangeColsInRow(i);
426 for (int j=r.begin(); j< r.end(); j++)
427 { MultCoeff::dot(lhs, rhs, res, i, j);}
428 // stk_cout << "(begin,end)=("<<begin<<","<<end<<")\n";
429 }
430 // stk_cout << "product done\n";
431 }
432 }
433};
434
436template <class Lhs, class Rhs, class Result>
437struct ProductDispatcher<Lhs, Rhs, Result, Arrays::array2D_, Arrays::array2D_>
438{
439 enum
440 {
441 structure_ = Arrays::array2D_,
445 storage_ = Traits<Result>::storage_
446 };
447 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
448 {
450 (lhs.sizeRows()<rhs.sizeCols()) ? BlockByPanel<Lhs,Rhs,Result>::run(lhs, rhs, res)
452 }
453};
454
455template <class Lhs, class Rhs, class Result>
456struct ProductDispatcher<Lhs, Rhs, Result, Arrays::array2D_, Arrays::square_>
457{
458 enum
459 {
460 structure_ = Arrays::array2D_,
464 storage_ = Traits<Result>::storage_
465 };
466 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
467 {
469 (lhs.sizeRows()<rhs.sizeCols()) ? BlockByPanel<Lhs,Rhs,Result>::run(lhs, rhs, res)
471 }
472};
473
474template <class Lhs, class Rhs, class Result>
475struct ProductDispatcher<Lhs, Rhs, Result, Arrays::square_, Arrays::square_>
476{
477 enum
478 {
479 structure_ = Arrays::square_,
483 storage_ = Traits<Result>::storage_
484 };
485 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
486 {
488 (lhs.sizeRows()<rhs.sizeCols()) ? BlockByPanel<Lhs,Rhs,Result>::run(lhs, rhs, res)
490 }
491};
492
493template <class Lhs, class Rhs, class Result>
494struct ProductDispatcher<Lhs, Rhs, Result, Arrays::square_, Arrays::array2D_>
495{
496 enum
497 {
498 structure_ = Arrays::array2D_,
502 storage_ = Traits<Result>::storage_
503 };
504 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
505 {
507 (lhs.sizeRows()<rhs.sizeCols()) ? BlockByPanel<Lhs,Rhs,Result>::run(lhs, rhs, res)
509 }
510};
511
512template <class Lhs, class Rhs, class Result>
513struct ProductDispatcher<Lhs, Rhs, Result, Arrays::array2D_, Arrays::vector_>
514{
515 enum
516 {
517 structure_ = Arrays::vector_,
521 storage_ = Traits<Result>::storage_
522 };
523 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
524 { bv<Lhs,Rhs,Result>::run(lhs, rhs, res);}
525};
526
527template <class Lhs, class Rhs, class Result>
528struct ProductDispatcher<Lhs, Rhs, Result, Arrays::square_, Arrays::vector_>
529{
530 enum
531 {
532 structure_ = Arrays::vector_,
536 storage_ = Traits<Result>::storage_
537 };
538 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
539 { bv<Lhs,Rhs,Result>::run(lhs, rhs, res);}
540};
541
542template <class Lhs, class Rhs, class Result, int lhsStructure_>
543struct ProductDispatcher<Lhs, Rhs, Result, lhsStructure_, Arrays::vector_>
544{
545 enum
546 {
547 structure_ = Arrays::vector_,
551 storage_ = Traits<Result>::storage_
552 };
554 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
555 {
556 for (int i=lhs.beginRows(); i< lhs.endRows(); i++)
557 { MultCoeff::dot(lhs, rhs, res, i);}
558 }
559};
560
561
562template <class Lhs, class Rhs, class Result, int RhsStructure_>
563struct ProductDispatcher<Lhs, Rhs, Result, Arrays::point_, RhsStructure_>
564{
565 enum
566 {
567 structure_ = Arrays::point_,
571 storage_ = Traits<Result>::storage_
572 };
574 static void run(Lhs const& lhs, Rhs const& rhs, Result& res )
575 {
576 for (int j=rhs.beginCols(); j< rhs.endCols(); j++)
577 { MultCoeff::dot(lhs, rhs, res, j);}
578 }
579};
580
581template <class Lhs, class Rhs, class Result>
582struct ProductDispatcher<Lhs, Rhs, Result, Arrays::point_, Arrays::array2D_>
583{
584 enum
585 {
586 structure_ = Arrays::point_,
590 storage_ = Traits<Result>::storage_
591 };
592 static void run(Lhs const& l, Rhs const& r, Result& res )
594};
595
596template <class Lhs, class Rhs, class Result>
597struct ProductDispatcher<Lhs, Rhs, Result, Arrays::point_, Arrays::square_>
598{
599 enum
600 {
601 structure_ = Arrays::point_,
605 storage_ = Traits<Result>::storage_
606 };
607 static void run(Lhs const& l, Rhs const& r, Result& res )
609};
610
611} // namespace hidden
612
613} // namespace STK
614
615#endif /* STK_PRODUCTDISPATCHER_H */
In this file we implement the General Array by Array product.
In this file we implement the General Array by Vector product.
In this file we implement the raw static methods used by the products methods.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
int begin() const
get the first index of the TRange.
Definition STK_Range.h:93
Index sub-vector region: Specialization when the size is unknown.
Definition STK_Range.h:265
int end() const
get the ending index of the TRange.
Definition STK_Range.h:299
@ dense_
dense matrix/vector/array/expression
@ array2D_
general matrix/array/expression
@ square_
square 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.
Methods to use for C=AB with A divided in blocks and B divided in panels.
This structure regroup the methods to used after block multiplication in order to perform the product...
This structure regroup the products between a point and different kind of array.
Methods to use for C=AB with A divided in panels and B divided in blocks.
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
MultCoefImpl< Lhs, Rhs, Result > MultCoeff
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If< storage_==int(Arrays::dense_), Array2DLowerTriangular< Type >, SArray2DLowerTriangular< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If< storage_==int(Arrays::dense_), Array2DUpperTriangular< Type >, SArray2DUpperTriangular< Type > >::Result Allocator
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
If< storage_==int(Arrays::dense_), CAllocator< Type, sizeRows_, sizeCols_, orient_ >, SArray2D< Type > >::Result Allocator
hidden::Promote< typenameLhs::Type, typenameRhs::Type >::result_type Type
If<(sizeof(Type1)>sizeof(Type2)), Type1, Type2 >::Result result_type
Methods to use for C=AV with A a general matrix and V a vector.