37 #ifndef NUMCXX_EXPRESSION_HXX 38 #define NUMCXX_EXPRESSION_HXX 39 #include <type_traits> 47 class ExpressionBase { };
52 class MatrixExpressionBase { };
57 class SparseMatrixExpressionBase { };
62 template<
typename A,
typename B,
63 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
64 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
65 class AdditionExpression:
public ExpressionBase
70 typedef typename A::value_type value_type;
71 AdditionExpression(
const A& a,
const B& b):a(a), b(b){}
72 unsigned int size()
const {
return a.size(); }
73 const value_type operator[](
const unsigned int i)
const {
return a[i] + b[i];}
74 AdditionExpression& operator=(
const AdditionExpression&)=
delete;
77 template<
typename A,
typename B,
78 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
79 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
80 const AdditionExpression<A,B>
operator+(
const A& a,
const B& b)
82 return AdditionExpression<A,B>(a, b);
88 template<
typename A,
typename B,
89 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
90 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
91 class SubtractionExpression:
public ExpressionBase
96 typedef typename A::value_type value_type;
97 SubtractionExpression(
const A& a,
const B& b):a(a), b(b){}
98 unsigned int size()
const {
return a.size(); }
99 const value_type operator[](
const unsigned int i)
const {
return a[i] - b[i];}
102 template<
typename A,
typename B,
103 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
104 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
105 const SubtractionExpression<A,B>
operator-(
const A& a,
const B& b)
107 return SubtractionExpression<A,B>(a, b);
112 template<
typename A,
typename B,
113 typename=
typename std::enable_if<std::is_fundamental<A>::value, A>::type,
114 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
115 class LeftScalarMultiplicationExpression:
public ExpressionBase
120 typedef typename B::value_type value_type;
121 LeftScalarMultiplicationExpression(
const A& a,
const B& b):a(a), b(b){}
122 unsigned int size()
const {
return b.size(); }
123 const value_type operator[](
const unsigned int i)
const {
return a*b[i];}
126 template<
typename A,
typename B,
127 typename=
typename std::enable_if<std::is_fundamental<A>::value, A>::type,
128 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
129 const LeftScalarMultiplicationExpression<A,B>
operator*(
const A& a,
const B& b)
131 return LeftScalarMultiplicationExpression<A,B>(a, b);
137 template<
typename A,
typename B,
138 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
139 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
140 class RightScalarMultiplicationExpression:
public ExpressionBase
145 typedef typename A::value_type value_type;
146 RightScalarMultiplicationExpression(
const A& a,
const B& b):a(a),b(b){;}
147 unsigned int size()
const {
return a.size(); }
148 const value_type operator[](
const unsigned int i)
const {
return a[i]*b; }
151 template<
typename A,
typename B,
152 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
153 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
154 const RightScalarMultiplicationExpression<A,B>
operator*(
const A& a,
const B& b)
156 return RightScalarMultiplicationExpression<A,B>(a, b);
163 template<
typename A,
typename B,
164 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
165 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
166 class RightScalarAdditionExpression:
public ExpressionBase
171 typedef typename A::value_type value_type;
172 RightScalarAdditionExpression(
const A& a,
const B& b):a(a), b(b){}
173 unsigned int size()
const {
return a.size(); }
174 const value_type operator[](
const unsigned int i)
const {
return a[i]+b; }
177 template<
typename A,
typename B,
178 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
179 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
180 const RightScalarAdditionExpression<A,B>
operator+(
const A& a,
const B& b)
182 return RightScalarAdditionExpression<A,B>(a, b);
187 template<
typename A,
typename B,
188 typename=
typename std::enable_if<std::is_fundamental<A>::value, A>::type,
189 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
190 class LeftScalarAdditionExpression:
public ExpressionBase
195 typedef typename B::value_type value_type;
196 LeftScalarAdditionExpression(
const A& a,
const B& b):a(a), b(b){}
197 unsigned int size()
const {
return b.size(); }
198 const value_type operator[](
const unsigned int i)
const {
return a+b[i];}
201 template<
typename A,
typename B,
202 typename=
typename std::enable_if<std::is_fundamental<A>::value, A>::type,
203 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
204 const LeftScalarAdditionExpression<A,B>
operator+(
const A& a,
const B& b)
206 return LeftScalarAdditionExpression<A,B>(a, b);
211 template<
typename A,
typename B,
212 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
213 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
214 class RightScalarSubtractionExpression:
public ExpressionBase
219 typedef typename A::value_type value_type;
220 RightScalarSubtractionExpression(
const A& a,
const B& b):a(a), b(b){}
221 unsigned int size()
const {
return a.size(); }
222 const value_type operator[](
const unsigned int i)
const {
return a[i]-b; }
225 template<
typename A,
typename B,
226 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
227 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
228 const RightScalarSubtractionExpression<A,B>
operator-(
const A& a,
const B& b)
230 return RightScalarSubtractionExpression<A,B>(a, b);
235 template<
typename A,
typename B,
236 typename=
typename std::enable_if<std::is_fundamental<A>::value, A>::type,
237 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
238 class LeftScalarSubtractionExpression:
public ExpressionBase
243 typedef typename B::value_type value_type;
244 LeftScalarSubtractionExpression(
const A& a,
const B& b):a(a), b(b){}
245 unsigned int size()
const {
return b.size(); }
246 const value_type operator[](
const unsigned int i)
const {
return a-b[i];}
249 template<
typename A,
typename B,
250 typename=
typename std::enable_if<std::is_fundamental<A>::value, A>::type,
251 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
252 const LeftScalarSubtractionExpression<A,B>
operator-(
const A& a,
const B& b)
254 return LeftScalarSubtractionExpression<A,B>(a, b);
259 template<
typename A,
typename B,
260 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
261 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
262 class RightScalarDivisionExpression:
public ExpressionBase
267 typedef typename A::value_type value_type;
268 RightScalarDivisionExpression(
const A& a,
const B& b):a(a), b(b){}
269 unsigned int size()
const {
return a.size(); }
270 const value_type operator[](
const unsigned int i)
const {
return a[i]/b;}
273 template<
typename A,
typename B,
274 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,A>::value, A>::type,
275 typename=
typename std::enable_if<std::is_fundamental<B>::value, B>::type>
276 const RightScalarDivisionExpression<A,B>
operator/(
const A& a,
const B& b)
278 return RightScalarDivisionExpression<A,B>(a, b);
283 template<
typename A,
typename B,
284 typename=
typename std::enable_if<std::is_base_of<MatrixExpressionBase,A>::value, A>::type,
285 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
286 class LeftMatrixMultiplicationExpression:
public ExpressionBase
291 typedef typename A::value_type value_type;
292 LeftMatrixMultiplicationExpression(
const A& a,
const B& b):a(a), b(b){}
293 unsigned int size()
const {
return b.size(); }
294 const value_type operator[](
const unsigned int i)
const 297 for (
index j=0;j<a.shape(0);j++)
298 entry+=a.xentry(i,j)*b[j];
303 template<
typename A,
typename B,
304 typename=
typename std::enable_if<std::is_base_of<MatrixExpressionBase,A>::value, A>::type,
305 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
306 const LeftMatrixMultiplicationExpression<A,B>
operator*(
const A& a,
const B& b)
308 return LeftMatrixMultiplicationExpression<A,B>(a, b);
313 template<
typename A,
typename B,
314 typename=
typename std::enable_if<std::is_base_of<SparseMatrixExpressionBase,A>::value, A>::type,
315 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
316 class LeftSparseMatrixMultiplicationExpression:
public ExpressionBase
321 typedef typename A::value_type value_type;
322 LeftSparseMatrixMultiplicationExpression(
const A& a,
const B& b):a(a), b(b){}
323 unsigned int size()
const {
return b.size(); }
324 const value_type operator[](
const unsigned int i)
const 331 for (
index j=IA[i];j<IA[i+1];j++)
332 entry+=AA[j]*b[JA[j]];
337 template<
typename A,
typename B,
338 typename=
typename std::enable_if<std::is_base_of<SparseMatrixExpressionBase,A>::value, A>::type,
339 typename=
typename std::enable_if<std::is_base_of<ExpressionBase,B>::value, B>::type>
340 const LeftSparseMatrixMultiplicationExpression<A,B>
operator*(
const A& a,
const B& b)
342 return LeftSparseMatrixMultiplicationExpression<A,B>(a, b);
const LeftScalarMultiplicationExpression< A, B > operator*(const A &a, const B &b)
const SubtractionExpression< A, B > operator-(const A &a, const B &b)
const AdditionExpression< A, B > operator+(const A &a, const B &b)
const RightScalarDivisionExpression< A, B > operator/(const A &a, const B &b)