TiledArray  0.7.0
mult_expr.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2013 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Justus Calvin
19  * Department of Chemistry, Virginia Tech
20  *
21  * mult_expr.h
22  * Mar 31, 2014
23  *
24  */
25 
26 #ifndef TILEDARRAY_EXPRESSIONS_MULT_EXPR_H__INCLUDED
27 #define TILEDARRAY_EXPRESSIONS_MULT_EXPR_H__INCLUDED
28 
31 
32 namespace TiledArray {
33  namespace expressions {
34 
35  template <typename Left, typename Right>
36  using ConjMultExpr =
38 
39  template <typename Left, typename Right, typename Scalar>
40  using ScalConjMultExpr =
42 
47 
48  template <typename Left, typename Right>
49  struct ExprTrait<MultExpr<Left, Right> > {
50  typedef Left left_type;
51  typedef Right right_type;
52  typedef result_of_mult_t<
59  typedef numeric_t<typename EngineTrait<engine_type>::eval_type>
61  typedef scalar_t<typename EngineTrait<engine_type>::eval_type>
63  };
64 
65  template <typename Left, typename Right, typename Scalar>
66  struct ExprTrait<ScalMultExpr<Left, Right, Scalar> > {
67  typedef Left left_type;
68  typedef Right right_type;
69  typedef Scalar scalar_type;
70  typedef result_of_mult_t<
77  typedef numeric_t<typename EngineTrait<engine_type>::eval_type>
79  };
80 
81 
83 
86  template <typename Left, typename Right>
87  class MultExpr : public BinaryExpr<MultExpr<Left, Right> > {
88  public:
94 
95  // Compiler generated functions
96  MultExpr(const MultExpr_&) = default;
97  MultExpr(MultExpr_&&) = default;
98  ~MultExpr() = default;
99  MultExpr_& operator=(const MultExpr_&) = delete;
100  MultExpr_& operator=(MultExpr_&&) = delete;
101 
103 
108  { }
109 
110 
112 
115  template <typename Numeric,
116  typename std::enable_if<
118  >::type* = nullptr>
119  explicit operator Numeric() const {
120  auto result = BinaryExpr_::left().dot(BinaryExpr_::right());
121  return result.get();
122  }
123 
125 
128  template <typename Numeric,
129  typename std::enable_if<
131  >::type* = nullptr>
132  explicit operator Future<Numeric>() const {
133  return BinaryExpr_::left().dot(BinaryExpr_::right());
134  }
135 
136  }; // class MultExpr
137 
138 
140 
143  template <typename Left, typename Right, typename Scalar>
144  class ScalMultExpr : public BinaryExpr<ScalMultExpr<Left, Right, Scalar> > {
145  public:
152 
153  private:
154 
155  scalar_type factor_;
156 
157  public:
158 
159  // Compiler generated functions
160  ScalMultExpr(const ScalMultExpr_&) = default;
161  ScalMultExpr(ScalMultExpr_&&) = default;
162  ~ScalMultExpr() = default;
163  ScalMultExpr_& operator=(const ScalMultExpr_&) = delete;
165 
167 
171  const scalar_type factor) :
172  BinaryExpr_(left, right), factor_(factor)
173  { }
174 
176 
178  scalar_type factor() const { return factor_; }
179 
180  }; // class ScalMultExpr
181 
182 
184 
190  template <typename Left, typename Right>
191  inline MultExpr<Left, Right>
192  operator*(const Expr<Left>& left, const Expr<Right>& right) {
194  "no_alias() expressions are not allowed on the right-hand side of the "
195  "assignment operator.");
197  "no_alias() expressions are not allowed on the right-hand side of the "
198  "assignment operator.");
199  return MultExpr<Left, Right>(left.derived(), right.derived());
200  }
201 
203 
210  template <typename Left, typename Right, typename Scalar,
211  typename std::enable_if<
213  >::type* = nullptr>
214  inline ScalMultExpr<Left, Right, Scalar>
215  operator*(const MultExpr<Left, Right>& expr, const Scalar& factor) {
216  return ScalMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
217  factor);
218  }
219 
221 
228  template <typename Left, typename Right, typename Scalar,
229  typename std::enable_if<
231  >::type* = nullptr>
232  inline ScalMultExpr<Left, Right, Scalar>
233  operator*(const Scalar& factor, const MultExpr<Left, Right>& expr) {
234  return ScalMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
235  factor);
236  }
237 
239 
247  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
248  typename std::enable_if<
250  >::type* = nullptr>
251  inline ScalMultExpr<Left, Right, mult_t<Scalar1, Scalar2> >
253  const Scalar2& factor)
254  {
256  expr.right(), expr.factor() * factor);
257  }
258 
260 
268  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
269  typename std::enable_if<
271  >::type* = nullptr>
272  inline ScalMultExpr<Left, Right, mult_t<Scalar2, Scalar1> >
273  operator*(const Scalar1& factor,
275  {
277  expr.right(), expr.factor() * factor);
278  }
279 
281 
286  template <typename Left, typename Right>
287  inline ScalMultExpr<Left, Right, typename ExprTrait<MultExpr<Left, Right> >::numeric_type>
289  return ScalMultExpr<Left, Right, typename ExprTrait<MultExpr<Left,
290  Right> >::numeric_type>(expr.left(), expr.right(), -1);
291  }
292 
294 
299  template <typename Left, typename Right, typename Scalar>
300  inline ScalMultExpr<Left, Right, Scalar>
302  return ScalMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
303  -expr.factor());
304  }
305 
307 
312  template <typename Left, typename Right>
314  return ConjMultExpr<Left, Right>(expr.left(), expr.right(), conj_op());
315  }
316 
318 
323  template <typename Left, typename Right>
325  return MultExpr<Left, Right>(expr.left(), expr.right());
326  }
327 
329 
335  template <typename Left, typename Right, typename Scalar>
336  inline ScalConjMultExpr<Left, Right, Scalar>
338  return ScalConjMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
339  conj_op(TiledArray::detail::conj(expr.factor())));
340  }
341 
343 
349  template <typename Left, typename Right, typename Scalar>
350  inline ScalMultExpr<Left, Right, Scalar>
352  return ScalMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
353  TiledArray::detail::conj(expr.factor().factor()));
354  }
355 
357 
364  template <typename Left, typename Right, typename Scalar,
365  typename std::enable_if<
367  >::type* = nullptr>
368  inline ScalConjMultExpr<Left, Right, Scalar>
369  operator*(const ConjMultExpr<Left, Right>& expr, const Scalar& factor) {
370  return ScalConjMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
371  conj_op(factor));
372  }
373 
375 
382  template <typename Left, typename Right, typename Scalar,
383  typename std::enable_if<
385  >::type* = nullptr>
386  inline ScalConjMultExpr<Left, Right, Scalar>
387  operator*(const Scalar& factor, const ConjMultExpr<Left, Right>& expr) {
388  return ScalConjMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
389  conj_op(factor));
390  }
391 
393 
401  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
402  typename std::enable_if<
404  >::type* = nullptr>
405  inline ScalConjMultExpr<Left, Right, mult_t<Scalar1, Scalar2> >
406  operator*(const ScalConjMultExpr<Left, Right, Scalar1>& expr, const Scalar2& factor) {
408  expr.right(), conj_op(expr.factor().factor() * factor));
409  }
410 
412 
420  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
421  typename std::enable_if<
423  >::type* = nullptr>
424  inline ScalConjMultExpr<Left, Right, mult_t<Scalar2, Scalar1> >
425  operator*(const Scalar1& factor, const ScalConjMultExpr<Left, Right, Scalar2>& expr) {
427  expr.left(), expr.right(), conj_op(expr.factor().factor() * factor));
428  }
429 
431 
436  template <typename Left, typename Right>
437  inline ScalConjMultExpr<Left, Right,
438  typename ExprTrait<ConjMultExpr<Left, Right> >::numeric_type>
440  typedef typename ExprTrait<ConjMultExpr<Left, Right> >::numeric_type
441  scalar_type;
443  expr.right(), conj_op<scalar_type>(-1));
444  }
445 
447 
453  template <typename Left, typename Right, typename Scalar>
454  inline ScalConjMultExpr<Left, Right, Scalar>
456  return ScalConjMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
457  conj_op(-expr.factor().factor()));
458  }
459 
460 
462 
469  template <typename Numeric, typename Left, typename Right,
470  typename std::enable_if<
472  >::type* = nullptr>
473  inline Numeric&
474  operator +=(Numeric& result, const MultExpr<Left, Right>& expr) {
475  result += expr.left().dot(expr.right()).get();
476  return result;
477  }
478 
480 
487  template <typename Numeric, typename Left, typename Right,
488  typename std::enable_if<
490  >::type* = nullptr>
491  inline Numeric&
492  operator -=(Numeric& result, const MultExpr<Left, Right>& expr) {
493  result -= expr.left().dot(expr.right()).get();
494  return result;
495  }
496 
498 
505  template <typename Numeric, typename Left, typename Right,
506  typename std::enable_if<
508  >::type* = nullptr>
509  inline Numeric&
510  operator *=(Numeric& result, const MultExpr<Left, Right>& expr) {
511  result *= expr.left().dot(expr.right()).get();
512  return result;
513  }
514 
515 
516  } // namespace expressions
517 } // namespace TiledArray
518 
519 #endif // TILEDARRAY_EXPRESSIONS_MULT_EXPR_H__INCLUDED
Multiplication expression.
Definition: cont_engine.h:39
scalar_type factor() const
Scaling factor accessor.
Definition: mult_expr.h:178
ScalMultExpr< Left, Right, TiledArray::detail::ComplexConjugate< Scalar > > ScalConjMultExpr
Definition: mult_expr.h:41
ExprTrait< ScalMultExpr_ >::left_type left_type
The left-hand expression type.
Definition: mult_expr.h:148
numeric_t< typename EngineTrait< engine_type >::eval_type > numeric_type
Multiplication result numeric type.
Definition: mult_expr.h:78
result_of_mult_t< typename EngineTrait< typename ExprTrait< Left >::engine_type >::eval_type, typename EngineTrait< typename ExprTrait< Right >::engine_type >::eval_type, scalar_type > result_type
Result tile type.
Definition: mult_expr.h:73
ScalMultExpr_ & operator=(const ScalMultExpr_ &)=delete
Right right_type
The right-hand expression type.
Definition: mult_expr.h:51
std::enable_if< TiledArray::detail::is_numeric< Scalar >::value, ScalAddExpr< Left, Right, Scalar > >::type operator*(const AddExpr< Left, Right > &expr, const Scalar &factor)
Scaled-addition expression factor.
Definition: add_expr.h:198
MultExpr_ & operator=(const MultExpr_ &)=delete
decltype(std::declval< Scalar1 >() *std::declval< Scalar2 >()) mult_t
Definition: type_traits.h:748
ExprTrait< ScalMultExpr_ >::scalar_type scalar_type
Tile scalar type.
Definition: mult_expr.h:151
Multiplication expression.
Definition: cont_engine.h:38
const right_type & right() const
Right-hand expression argument accessor.
Definition: binary_expr.h:71
typename TiledArray::detail::numeric_type< T >::type numeric_t
Definition: type_traits.h:525
ScalMultExpr(const left_type &left, const right_type &right, const scalar_type factor)
Expression constructor.
Definition: mult_expr.h:170
ScalMultExpr< Left, Right, TiledArray::detail::ComplexConjugate< void > > ConjMultExpr
Definition: mult_expr.h:37
decltype(mult(std::declval< T >()...)) result_of_mult_t
BinaryExpr< MultExpr_ > BinaryExpr_
Binary expression base type.
Definition: mult_expr.h:90
ExprTrait< MultExpr_ >::engine_type engine_type
Expression engine type.
Definition: mult_expr.h:93
numeric_t< typename EngineTrait< engine_type >::eval_type > numeric_type
Multiplication result numeric type.
Definition: mult_expr.h:60
const left_type & left() const
Left-hand expression argument accessor.
Definition: binary_expr.h:66
MultExpr< Left, Right > MultExpr_
This class type.
Definition: mult_expr.h:89
ExprTrait< MultExpr_ >::right_type right_type
The right-hand expression type.
Definition: mult_expr.h:92
Binary expression object.
Definition: binary_engine.h:36
ExprTrait< ScalMultExpr_ >::right_type right_type
The right-hand expression type.
Definition: mult_expr.h:149
scalar_t< typename EngineTrait< engine_type >::eval_type > scalar_type
Multiplication result scalar type.
Definition: mult_expr.h:62
typename TiledArray::detail::scalar_type< T >::type scalar_t
Definition: type_traits.h:555
ScalMultExpr(const ScalMultExpr_ &)=default
Base class for expression evaluation.
Definition: expr.h:81
derived_type & derived()
Cast this object to it&#39;s derived type.
Definition: expr.h:273
ConjAddExpr< Left, Right > conj(const AddExpr< Left, Right > &expr)
Conjugated addition expression factory.
Definition: add_expr.h:292
ScalAddExpr< Left, Right, typename ExprTrait< AddExpr< Left, Right > >::numeric_type > operator-(const AddExpr< Left, Right > &expr)
Negated addition expression factor.
Definition: add_expr.h:266
TILEDARRAY_FORCE_INLINE R conj(const R r)
Wrapper function for std::conj
Definition: complex.h:44
MultExpr(const left_type &left, const right_type &right)
Expression constructor.
Definition: mult_expr.h:106
Numeric & operator*=(Numeric &result, const MultExpr< Left, Right > &expr)
Dot product multiply-to operator.
Definition: mult_expr.h:510
ComplexConjugate< S > conj_op(const S factor)
ComplexConjugate operator factory function.
Definition: complex.h:181
ScalMultExpr< Left, Right, Scalar > ScalMultExpr_
This class type.
Definition: mult_expr.h:146
ExprTrait< ScalMultExpr_ >::engine_type engine_type
Expression engine type.
Definition: mult_expr.h:150
ScalMultEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, Scalar, result_type > engine_type
Expression engine type.
Definition: mult_expr.h:76
BinaryExpr< ScalMultExpr_ > BinaryExpr_
Binary expression base type.
Definition: mult_expr.h:147
Numeric & operator-=(Numeric &result, const MultExpr< Left, Right > &expr)
Dot product subtract-to operator.
Definition: mult_expr.h:492
ExprTrait< MultExpr_ >::left_type left_type
The left-hand expression type.
Definition: mult_expr.h:91
Multiplication expression engine.
Definition: mult_engine.h:40
MultExpr(const MultExpr_ &)=default
Scaled multiplication expression engine.
Definition: mult_engine.h:41
Numeric & operator+=(Numeric &result, const MultExpr< Left, Right > &expr)
Dot product add-to operator.
Definition: mult_expr.h:474
MultEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, result_type > engine_type
Expression engine type.
Definition: mult_expr.h:58
result_of_mult_t< typename EngineTrait< typename ExprTrait< Left >::engine_type >::eval_type, typename EngineTrait< typename ExprTrait< Right >::engine_type >::eval_type > result_type
Result tile type.
Definition: mult_expr.h:55