TiledArray  0.7.0
add_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  * add_expr.h
22  * Apr 1, 2014
23  *
24  */
25 
26 #ifndef TILEDARRAY_EXPRESSIONS_ADD_EXPR_H__INCLUDED
27 #define TILEDARRAY_EXPRESSIONS_ADD_EXPR_H__INCLUDED
28 
31 
32 namespace TiledArray {
33  namespace expressions {
34 
35  template <typename Left, typename Right>
36  using ConjAddExpr =
38 
39  template <typename Left, typename Right, typename Scalar>
40  using ScalConjAddExpr =
42 
47 
48  template <typename Left, typename Right>
49  struct ExprTrait<AddExpr<Left, Right> > {
50  typedef Left left_type;
51  typedef Right right_type;
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<ScalAddExpr<Left, Right, Scalar> > {
67  typedef Left left_type;
68  typedef Right right_type;
69  typedef Scalar scalar_type;
77  typedef numeric_t<typename EngineTrait<engine_type>::eval_type>
79  };
80 
81 
83 
86  template <typename Left, typename Right>
87  class AddExpr : public BinaryExpr<AddExpr<Left, Right> > {
88  public:
91  typedef typename ExprTrait<AddExpr_>::left_type
93  typedef typename ExprTrait<AddExpr_>::right_type
95  typedef typename ExprTrait<AddExpr_>::engine_type
97 
98  // Compiler generated functions
99  AddExpr(const AddExpr_&) = default;
100  AddExpr(AddExpr_&&) = default;
101  ~AddExpr() = default;
102  AddExpr_& operator=(const AddExpr_&) = delete;
103  AddExpr_& operator=(AddExpr_&&) = delete;
104 
106 
111  { }
112 
113  }; // class AddExpr
114 
115 
117 
120  template <typename Left, typename Right, typename Scalar>
121  class ScalAddExpr : public BinaryExpr<ScalAddExpr<Left, Right, Scalar> > {
122  public:
123  typedef ScalAddExpr<Left, Right, Scalar>
127  typedef typename ExprTrait<ScalAddExpr_>::left_type
129  typedef typename ExprTrait<ScalAddExpr_>::right_type
131  typedef typename ExprTrait<ScalAddExpr_>::engine_type
133  typedef typename ExprTrait<ScalAddExpr_>::scalar_type
135 
136 
137  private:
138 
139  scalar_type factor_;
140 
141  public:
142 
143  // Compiler generated functions
144  ScalAddExpr(const ScalAddExpr_&) = default;
145  ScalAddExpr(ScalAddExpr_&&) = default;
146  ~ScalAddExpr() = default;
147  ScalAddExpr_& operator=(const ScalAddExpr_&) = delete;
148  ScalAddExpr_& operator=(ScalAddExpr_&&) = delete;
149 
151 
155  const scalar_type factor) :
156  BinaryExpr_(left, right), factor_(factor)
157  { }
158 
159 
161 
163  scalar_type factor() const { return factor_; }
164 
165  }; // class ScalAddExpr
166 
167 
169 
175  template <typename Left, typename Right>
176  inline AddExpr<Left, Right>
177  operator+(const Expr<Left>& left, const Expr<Right>& right) {
179  "no_alias() expressions are not allowed on the right-hand side of "
180  "the assignment operator.");
182  "no_alias() expressions are not allowed on the right-hand side of "
183  "the assignment operator.");
184  return AddExpr<Left, Right>(left.derived(), right.derived());
185  }
186 
188 
195  template <typename Left, typename Right, typename Scalar>
196  inline typename std::enable_if<TiledArray::detail::is_numeric<Scalar>::value,
197  ScalAddExpr<Left, Right, Scalar> >::type
198  operator*(const AddExpr<Left, Right>& expr, const Scalar& factor) {
199  return ScalAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
200  factor);
201  }
202 
204 
211  template <typename Left, typename Right, typename Scalar>
212  inline typename std::enable_if<TiledArray::detail::is_numeric<Scalar>::value,
213  ScalAddExpr<Left, Right, Scalar> >::type
214  operator*(const Scalar& factor, const AddExpr<Left, Right>& expr) {
215  return ScalAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
216  factor);
217  }
218 
220 
228  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
229  typename std::enable_if<
231  >::type* = nullptr>
232  inline ScalAddExpr<Left, Right, mult_t<Scalar1, Scalar2> >
233  operator*(const ScalAddExpr<Left, Right, Scalar1>& expr, const Scalar2& factor) {
235  expr.right(), expr.factor() * factor);
236  }
237 
239 
247  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
248  typename std::enable_if<
250  >::type* = nullptr>
251  inline ScalAddExpr<Left, Right, mult_t<Scalar2, Scalar1> >
252  operator*(const Scalar1& factor, const ScalAddExpr<Left, Right, Scalar2>& expr) {
254  expr.right(), expr.factor() * factor);
255  }
256 
258 
263  template <typename Left, typename Right>
264  inline ScalAddExpr<Left, Right,
265  typename ExprTrait<AddExpr<Left, Right> >::numeric_type>
267  return ScalAddExpr<Left, Right,
268  typename ExprTrait<AddExpr<Left, Right> >::numeric_type>(
269  expr.left(), expr.right(), -1);
270  }
271 
273 
279  template <typename Left, typename Right, typename Scalar>
280  inline ScalAddExpr<Left, Right, Scalar>
282  return ScalAddExpr<Left, Right, Scalar>(expr.left(), expr.right(), -1);
283  }
284 
286 
291  template <typename Left, typename Right>
293  return ConjAddExpr<Left, Right>(expr.left(), expr.right(), conj_op());
294  }
295 
297 
302  template <typename Left, typename Right>
304  return AddExpr<Left, Right>(expr.left(), expr.right());
305  }
306 
308 
314  template <typename Left, typename Right, typename Scalar>
315  inline ScalConjAddExpr<Left, Right, Scalar>
317  return ScalConjAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
318  conj_op(TiledArray::detail::conj(expr.factor())));
319  }
320 
322 
328  template <typename Left, typename Right, typename Scalar>
329  inline ScalAddExpr<Left, Right, Scalar>
331  return ScalAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
332  TiledArray::detail::conj(expr.factor().factor()));
333  }
334 
336 
343  template <typename Left, typename Right, typename Scalar,
344  typename std::enable_if<
346  >::type* = nullptr>
347  inline ScalConjAddExpr<Left, Right, Scalar>
348  operator*(const ConjAddExpr<Left, Right>& expr, const Scalar& factor) {
349  return ScalConjAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
350  conj_op(factor));
351  }
352 
354 
361  template <typename Left, typename Right, typename Scalar,
362  typename std::enable_if<
364  >::type* = nullptr>
365  inline ScalConjAddExpr<Left, Right, Scalar>
366  operator*(const Scalar& factor, const ConjAddExpr<Left, Right>& expr) {
367  return ScalConjAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
368  conj_op(factor));
369  }
370 
372 
380  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
381  typename std::enable_if<
383  >::type* = nullptr>
384  inline ScalConjAddExpr<Left, Right, mult_t<Scalar1, Scalar2> >
385  operator*(const ScalConjAddExpr<Left, Right, Scalar1>& expr, const Scalar2& factor) {
387  expr.right(), conj_op(expr.factor().factor() * factor));
388  }
389 
391 
399  template <typename Left, typename Right, typename Scalar1, typename Scalar2,
400  typename std::enable_if<
402  >::type* = nullptr>
403  inline ScalConjAddExpr<Left, Right, mult_t<Scalar2, Scalar1> >
404  operator*(const Scalar1& factor, const ScalConjAddExpr<Left, Right, Scalar2>& expr) {
406  expr.left(), expr.right(), conj_op(expr.factor().factor() * factor));
407  }
408 
410 
415  template <typename Left, typename Right>
416  inline ScalConjAddExpr<Left, Right,
417  typename ExprTrait<ConjAddExpr<Left, Right> >::numeric_type>
419  typedef typename ExprTrait<ConjAddExpr<Left, Right> >::numeric_type
420  scalar_type;
422  expr.right(), conj_op<scalar_type>(-1));
423  }
424 
426 
432  template <typename Left, typename Right, typename Scalar>
433  inline ScalConjAddExpr<Left, Right, Scalar>
435  return ScalConjAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
436  conj_op(-expr.factor().factor()));
437  }
438 
439  } // namespace expressions
440 } // namespace TiledArray
441 
442 #endif // TILEDARRAY_EXPRESSIONS_ADD_EXPR_H__INCLUDED
ExprTrait< ScalAddExpr_ >::scalar_type scalar_type
Scalar type.
Definition: add_expr.h:134
AddExpr< Left, Right > operator+(const Expr< Left > &left, const Expr< Right > &right)
Addition expression factor.
Definition: add_expr.h:177
Right right_type
The right-hand expression type.
Definition: add_expr.h:51
numeric_t< typename EngineTrait< engine_type >::eval_type > numeric_type
Addition numeric type.
Definition: add_expr.h:78
ScalAddExpr(const ScalAddExpr_ &)=default
ScalAddExpr< Left, Right, TiledArray::detail::ComplexConjugate< void > > ConjAddExpr
Definition: add_expr.h:37
ScalAddExpr< Left, Right, Scalar > ScalAddExpr_
This class type.
Definition: add_expr.h:124
ScalAddEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, Scalar, result_type > engine_type
Expression engine type.
Definition: add_expr.h:76
ScalAddExpr_ & operator=(const ScalAddExpr_ &)=delete
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
Addition expression.
Definition: add_engine.h:37
ScalAddExpr< Left, Right, TiledArray::detail::ComplexConjugate< Scalar > > ScalConjAddExpr
Definition: add_expr.h:41
decltype(std::declval< Scalar1 >() *std::declval< Scalar2 >()) mult_t
Definition: type_traits.h:748
ExprTrait< ScalAddExpr_ >::left_type left_type
The left-hand expression type.
Definition: add_expr.h:128
AddExpr< Left, Right > AddExpr_
This class type.
Definition: add_expr.h:89
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
scalar_t< typename EngineTrait< engine_type >::eval_type > scalar_type
Addition result scalar type.
Definition: add_expr.h:62
ExprTrait< AddExpr_ >::right_type right_type
The right-hand expression type.
Definition: add_expr.h:94
const left_type & left() const
Left-hand expression argument accessor.
Definition: binary_expr.h:66
TiledArray::tile_interface::result_of_add_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: add_expr.h:73
AddExpr_ & operator=(const AddExpr_ &)=delete
Binary expression object.
Definition: binary_engine.h:36
Add-then-scale expression.
Definition: add_engine.h:38
ExprTrait< ScalAddExpr_ >::engine_type engine_type
Expression engine type.
Definition: add_expr.h:132
BinaryExpr< AddExpr_ > BinaryExpr_
Binary base class type.
Definition: add_expr.h:90
typename TiledArray::detail::scalar_type< T >::type scalar_t
Definition: type_traits.h:555
ExprTrait< AddExpr_ >::engine_type engine_type
Expression engine type.
Definition: add_expr.h:96
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
TiledArray::tile_interface::result_of_add_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: add_expr.h:55
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
ComplexConjugate< S > conj_op(const S factor)
ComplexConjugate operator factory function.
Definition: complex.h:181
Left left_type
The left-hand expression type.
Definition: add_expr.h:50
decltype(add(std::declval< T >()...)) result_of_add_t
Definition: add.h:120
BinaryExpr< ScalAddExpr_ > BinaryExpr_
Binary base class type.
Definition: add_expr.h:126
Addition expression engine.
Definition: add_engine.h:39
ScalAddExpr(const left_type &left, const right_type &right, const scalar_type factor)
Expression constructor.
Definition: add_expr.h:154
numeric_t< typename EngineTrait< engine_type >::eval_type > numeric_type
Addition result numeric type.
Definition: add_expr.h:60
AddExpr(const left_type &left, const right_type &right)
Expression constructor.
Definition: add_expr.h:109
ExprTrait< ScalAddExpr_ >::right_type right_type
The right-hand expression type.
Definition: add_expr.h:130
ExprTrait< AddExpr_ >::left_type left_type
The left-hand expression type.
Definition: add_expr.h:92
Addition expression engine.
Definition: add_engine.h:40
AddEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, result_type > engine_type
Expression engine type.
Definition: add_expr.h:58
scalar_type factor() const
Scaling factor accessor.
Definition: add_expr.h:163
AddExpr(const AddExpr_ &)=default