1 /*!
2  * \file   include/TFEL/Math/Matrix/MatrixConceptOperations.hxx
3  * \brief  This file implements operations that can be applied to matrices.
4  * \author Thomas Helfer
5  * \date   01 jui 2006
6  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
7  * reserved.
8  * This project is publicly released under either the GNU GPL Licence
9  * or the CECILL-A licence. A copy of thoses licences are delivered
10  * with the sources of TFEL. CEA or EDF may also distribute this
11  * project under specific licensing conditions.
12  */
13 
14 #ifndef LIB_TFEL_MATRIX_OPERATIONS_HXX
15 #define LIB_TFEL_MATRIX_OPERATIONS_HXX
16 
17 #include <cmath>
18 
19 #include"TFEL/Config/TFELConfig.hxx"
20 #include"TFEL/TypeTraits/IsInvalid.hxx"
21 #include"TFEL/Math/ExpressionTemplates/Expr.hxx"
22 #include"TFEL/Math/Vector/VectorConcept.hxx"
23 
24 namespace tfel{
25 
26   namespace math{
27 
28 
29     template<typename T>
30     struct MatrixType
31     {
32       typedef T type;
33     };
34 
35     template<typename T_type, typename Operation>
36     struct MatrixType<Expr<T_type,Operation> >
37     {
38       typedef T_type type;
39     };
40 
41     template<typename T_type, typename Operation>
42     struct MatrixTraits<Expr<T_type,Operation>>
43     {
44       typedef typename MatrixTraits<T_type>::NumType   NumType;
45       typedef typename MatrixTraits<T_type>::IndexType IndexType;
46     };
47 
48     template<typename AType,typename BType,
49 	     typename A,typename B>
50     class MatrixVectorHandle
51     {
52       struct DummyHandle
53       {};
54     public:
55       typedef DummyHandle type;
56     };
57 
58     template<typename AType,typename BType,
59 	     typename A,typename B>
60     class VectorMatrixHandle
61     {
62       struct DummyHandle
63       {};
64     public:
65       typedef DummyHandle type;
66     };
67 
68     /*
69      * Partial Specialisation of ComputeBinaryResult_ for matrix's operation
70      */
71     template<typename A, typename B,typename Op>
72     class ComputeBinaryResult_<MatrixTag,MatrixTag,A,B,Op>
73     {
74       struct DummyHandle{};
75       typedef typename MatrixType<typename std::decay<A>::type>::type MatA;
76       typedef typename MatrixType<typename std::decay<B>::type>::type MatB;
77     public:
78       typedef typename ResultType<MatA,MatB,Op>::type Result;
79       typedef typename std::conditional<tfel::typetraits::IsInvalid<Result>::cond,
80 					DummyHandle,
81 					Expr<Result,BinaryOperation<A,B,Op>>>::type Handle;
82     };
83 
84     /*
85      * Partial Specialisation of ComputeBinaryResult_ for scalar-matrix operations
86      */
87     template<typename A, typename B,typename Op>
88     class ComputeBinaryResult_<ScalarTag,MatrixTag,A,B,Op>
89     {
90       struct DummyHandle{};
91       typedef typename MatrixType<typename std::decay<B>::type>::type MatB;
92     public:
93       typedef typename ResultType<A,MatB,Op>::type Result;
94       typedef typename std::conditional<tfel::typetraits::IsInvalid<Result>::cond,
95 					DummyHandle,
96 					Expr<Result,ScalarObjectOperation<A,B,Op>>>::type Handle;
97     };
98 
99     /*
100      * Partial Specialisation of ComputeBinaryResult_ for matrix-scalar operations
101      */
102     template<typename A, typename B,typename Op>
103     struct ComputeBinaryResult_<MatrixTag,ScalarTag,A,B,Op>
104     {
105       struct DummyHandle{};
106       typedef typename MatrixType<typename std::decay<A>::type>::type MatA;
107     public:
108       typedef typename ResultType<MatA,B,Op>::type Result;
109       typedef typename std::conditional<tfel::typetraits::IsInvalid<Result>::cond,
110 					DummyHandle,
111 					Expr<Result,ObjectScalarOperation<A,B,Op>>>::type Handle;
112     };
113 
114     /*
115      * Partial Specialisation of ComputeBinaryResult_ for matrix-vector multiplication
116      */
117     template<typename A, typename B>
118     struct ComputeBinaryResult_<MatrixTag,VectorTag,A,B,OpMult>
119     {
120       struct DummyHandle{};
121       typedef typename MatrixType<typename std::decay<A>::type>::type MatA;
122       typedef typename VectorType<typename std::decay<B>::type>::type VecB;
123     public:
124       typedef typename ResultType<MatA,VecB,OpMult>::type Result;
125       typedef typename std::conditional<tfel::typetraits::IsInvalid<Result>::cond,
126 					DummyHandle,
127 					typename MatrixVectorHandle<MatA,VecB,
128 								    A,B>::type >::type Handle;
129     };
130 
131     /*
132      * Partial Specialisation of ComputeBinaryResult_ for vector-matrix multiplication
133      */
134     template<typename A, typename B>
135     struct ComputeBinaryResult_<VectorTag,MatrixTag,A,B,OpMult>
136     {
137       struct DummyHandle{};
138       typedef typename VectorType<typename std::decay<A>::type>::type VecA;
139       typedef typename MatrixType<typename std::decay<B>::type>::type MatB;
140     public:
141       typedef typename ResultType<VecA,MatB,OpMult>::type Result;
142       typedef typename std::conditional<tfel::typetraits::IsInvalid<Result>::cond,
143 				      DummyHandle,
144 				      typename MatrixVectorHandle<VecA,MatB,
145 								  A,B>::type >::type Handle;
146     };
147 
148     /*
149      * Partial Specialisation of ComputeUnaryResult_ for matrices
150      */
151     template<typename A>
152     class ComputeUnaryResult_<MatrixTag,UnaryOperatorTag,A,OpNeg>
153     {
154       struct DummyHandle{};
155       typedef typename MatrixType<typename std::decay<A>::type>::type MatA;
156     public:
157       typedef typename UnaryResultType<MatA,OpNeg>::type Result;
158       typedef typename std::conditional<tfel::typetraits::IsInvalid<Result>::cond,
159 					DummyHandle,
160 					Expr<Result,UnaryOperation<A,OpNeg>>>::type Handle;
161     };
162 
163   } // end of namespace math
164 
165 } // end of namespace tfel
166 
167 #endif /* LIB_TFEL_MATRIX_OPERATIONS_HXX */
168 
169