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>
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;
76  typename ExprTrait<Right>::engine_type, Scalar,
79  typedef numeric_t<typename EngineTrait<engine_type>::eval_type>
81 };
82 
84 
87 template <typename Left, typename Right>
88 class AddExpr : public BinaryExpr<AddExpr<Left, Right> > {
89  public:
92  typedef typename ExprTrait<AddExpr_>::left_type
94  typedef typename ExprTrait<AddExpr_>::right_type
96  typedef typename ExprTrait<AddExpr_>::engine_type
98 
99  // Compiler generated functions
100  AddExpr(const AddExpr_&) = default;
101  AddExpr(AddExpr_&&) = default;
102  ~AddExpr() = default;
103  AddExpr_& operator=(const AddExpr_&) = delete;
105 
107 
110  AddExpr(const left_type& left, const right_type& right)
111  : BinaryExpr_(left, right) {}
112 
113 }; // class AddExpr
114 
116 
119 template <typename Left, typename Right, typename Scalar>
120 class ScalAddExpr : public BinaryExpr<ScalAddExpr<Left, Right, Scalar> > {
121  public:
124  typedef typename ExprTrait<ScalAddExpr_>::left_type
126  typedef typename ExprTrait<ScalAddExpr_>::right_type
128  typedef typename ExprTrait<ScalAddExpr_>::engine_type
130  typedef typename ExprTrait<ScalAddExpr_>::scalar_type
132 
133  private:
134  scalar_type factor_;
135 
136  public:
137  // Compiler generated functions
138  ScalAddExpr(const ScalAddExpr_&) = default;
139  ScalAddExpr(ScalAddExpr_&&) = default;
140  ~ScalAddExpr() = default;
143 
145 
148  ScalAddExpr(const left_type& left, const right_type& right,
149  const scalar_type factor)
150  : BinaryExpr_(left, right), factor_(factor) {}
151 
153 
155  scalar_type factor() const { return factor_; }
156 
157 }; // class ScalAddExpr
158 
160 
166 template <typename Left, typename Right>
168  const Expr<Right>& right) {
169  static_assert(
171  "no_alias() expressions are not allowed on the right-hand side of "
172  "the assignment operator.");
173  static_assert(
175  "no_alias() expressions are not allowed on the right-hand side of "
176  "the assignment operator.");
177  return AddExpr<Left, Right>(left.derived(), right.derived());
178 }
179 
181 
188 template <typename Left, typename Right, typename Scalar>
189 inline typename std::enable_if<TiledArray::detail::is_numeric_v<Scalar>,
190  ScalAddExpr<Left, Right, Scalar> >::type
191 operator*(const AddExpr<Left, Right>& expr, const Scalar& factor) {
192  return ScalAddExpr<Left, Right, Scalar>(expr.left(), expr.right(), factor);
193 }
194 
196 
203 template <typename Left, typename Right, typename Scalar>
204 inline typename std::enable_if<TiledArray::detail::is_numeric_v<Scalar>,
205  ScalAddExpr<Left, Right, Scalar> >::type
206 operator*(const Scalar& factor, const AddExpr<Left, Right>& expr) {
207  return ScalAddExpr<Left, Right, Scalar>(expr.left(), expr.right(), factor);
208 }
209 
211 
219 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
220  typename std::enable_if<
221  TiledArray::detail::is_numeric_v<Scalar2> >::type* = nullptr>
223  const ScalAddExpr<Left, Right, Scalar1>& expr, const Scalar2& factor) {
225  expr.left(), expr.right(), expr.factor() * factor);
226 }
227 
229 
237 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
238  typename std::enable_if<
239  TiledArray::detail::is_numeric_v<Scalar1> >::type* = nullptr>
241  const Scalar1& factor, const ScalAddExpr<Left, Right, Scalar2>& expr) {
243  expr.left(), expr.right(), expr.factor() * factor);
244 }
245 
247 
252 template <typename Left, typename Right>
253 inline ScalAddExpr<Left, Right,
254  typename ExprTrait<AddExpr<Left, Right> >::numeric_type>
256  return ScalAddExpr<Left, Right,
257  typename ExprTrait<AddExpr<Left, Right> >::numeric_type>(
258  expr.left(), expr.right(), -1);
259 }
260 
262 
268 template <typename Left, typename Right, typename Scalar>
270  const ScalAddExpr<Left, Right, Scalar>& expr) {
271  return ScalAddExpr<Left, Right, Scalar>(expr.left(), expr.right(), -1);
272 }
273 
275 
280 template <typename Left, typename Right>
282  return ConjAddExpr<Left, Right>(expr.left(), expr.right(), conj_op());
283 }
284 
286 
291 template <typename Left, typename Right>
293  return AddExpr<Left, Right>(expr.left(), expr.right());
294 }
295 
297 
303 template <typename Left, typename Right, typename Scalar>
305  const ScalAddExpr<Left, Right, Scalar>& expr) {
307  expr.left(), expr.right(),
309 }
310 
312 
318 template <typename Left, typename Right, typename Scalar>
322  expr.left(), expr.right(),
323  TiledArray::detail::conj(expr.factor().factor()));
324 }
325 
327 
334 template <typename Left, typename Right, typename Scalar,
335  typename std::enable_if<
336  TiledArray::detail::is_numeric_v<Scalar> >::type* = nullptr>
338  const ConjAddExpr<Left, Right>& expr, const Scalar& factor) {
339  return ScalConjAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
340  conj_op(factor));
341 }
342 
344 
351 template <typename Left, typename Right, typename Scalar,
352  typename std::enable_if<
353  TiledArray::detail::is_numeric_v<Scalar> >::type* = nullptr>
355  const Scalar& factor, const ConjAddExpr<Left, Right>& expr) {
356  return ScalConjAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
357  conj_op(factor));
358 }
359 
361 
369 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
370  typename std::enable_if<
371  TiledArray::detail::is_numeric_v<Scalar2> >::type* = nullptr>
373  const ScalConjAddExpr<Left, Right, Scalar1>& expr, const Scalar2& factor) {
375  expr.left(), expr.right(), conj_op(expr.factor().factor() * factor));
376 }
377 
379 
387 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
388  typename std::enable_if<
389  TiledArray::detail::is_numeric_v<Scalar1> >::type* = nullptr>
391  const Scalar1& factor, const ScalConjAddExpr<Left, Right, Scalar2>& expr) {
393  expr.left(), expr.right(), conj_op(expr.factor().factor() * factor));
394 }
395 
397 
402 template <typename Left, typename Right>
403 inline ScalConjAddExpr<
404  Left, Right, typename ExprTrait<ConjAddExpr<Left, Right> >::numeric_type>
406  typedef
407  typename ExprTrait<ConjAddExpr<Left, Right> >::numeric_type scalar_type;
408  return ScalConjAddExpr<Left, Right, scalar_type>(expr.left(), expr.right(),
409  conj_op<scalar_type>(-1));
410 }
411 
413 
419 template <typename Left, typename Right, typename Scalar>
422  return ScalConjAddExpr<Left, Right, Scalar>(expr.left(), expr.right(),
423  conj_op(-expr.factor().factor()));
424 }
425 
426 } // namespace expressions
427 } // namespace TiledArray
428 
429 #endif // TILEDARRAY_EXPRESSIONS_ADD_EXPR_H__INCLUDED
AddExpr_ & operator=(AddExpr_ &&)=delete
Add-then-scale expression.
Definition: add_expr.h:120
AddExpr(const AddExpr_ &)=default
scalar_type factor() const
Scaling factor accessor.
Definition: add_expr.h:155
ScalAddExpr(const ScalAddExpr_ &)=default
ScalAddExpr< Left, Right, typename ExprTrait< AddExpr< Left, Right > >::numeric_type > operator-(const AddExpr< Left, Right > &expr)
Negated addition expression factor.
Definition: add_expr.h:255
Right right_type
The right-hand expression type.
Definition: add_expr.h:51
typename TiledArray::detail::numeric_type< T >::type numeric_t
numeric_t<T> is an alias for numeric_type<T>::type
Definition: type_traits.h:730
decltype(std::declval< Scalar1 >() *std::declval< Scalar2 >()) mult_t
Definition: type_traits.h:1159
AddExpr(AddExpr_ &&)=default
ExprTrait< AddExpr_ >::right_type right_type
The right-hand expression type.
Definition: add_expr.h:95
ScalAddExpr(ScalAddExpr_ &&)=default
numeric_t< typename EngineTrait< engine_type >::eval_type > numeric_type
Addition numeric type.
Definition: add_expr.h:80
AddExpr< Left, Right > AddExpr_
This class type.
Definition: add_expr.h:90
Base class for expression evaluation.
Definition: expr.h:97
Binary expression object.
Definition: binary_expr.h:39
AddExpr< Left, Right > operator+(const Expr< Left > &left, const Expr< Right > &right)
Addition expression factor.
Definition: add_expr.h:167
ScalAddExpr< Left, Right, Scalar > ScalAddExpr_
This class type.
Definition: add_expr.h:122
std::enable_if< TiledArray::detail::is_numeric_v< Scalar >, ScalAddExpr< Left, Right, Scalar > >::type operator*(const AddExpr< Left, Right > &expr, const Scalar &factor)
Scaled-addition expression factor.
Definition: add_expr.h:191
Addition expression engine.
Definition: add_engine.h:219
scalar_t< typename EngineTrait< engine_type >::eval_type > scalar_type
Addition result scalar type.
Definition: add_expr.h:62
ConjAddExpr< Left, Right > conj(const AddExpr< Left, Right > &expr)
Conjugated addition expression factory.
Definition: add_expr.h:281
typename TiledArray::detail::scalar_type< T >::type scalar_t
scalar_t<T> is an alias for scalar_type<T>::type
Definition: type_traits.h:760
BinaryExpr< AddExpr_ > BinaryExpr_
Binary base class type.
Definition: add_expr.h:91
Addition expression.
Definition: add_expr.h:88
AddExpr_ & operator=(const AddExpr_ &)=delete
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
ExprTrait< ScalAddExpr_ >::engine_type engine_type
Expression engine type.
Definition: add_expr.h:129
ExprTrait< AddExpr_ >::engine_type engine_type
Expression engine type.
Definition: add_expr.h:97
BinaryExpr< ScalAddExpr_ > BinaryExpr_
Binary base class type.
Definition: add_expr.h:123
ScalAddExpr_ & operator=(const ScalAddExpr_ &)=delete
Left left_type
The left-hand expression type.
Definition: add_expr.h:50
ExprTrait< ScalAddExpr_ >::right_type right_type
The right-hand expression type.
Definition: add_expr.h:127
ExprTrait< ScalAddExpr_ >::left_type left_type
The left-hand expression type.
Definition: add_expr.h:125
ComplexConjugate< S > conj_op(const S factor)
ComplexConjugate operator factory function.
Definition: complex.h:204
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:74
decltype(add(std::declval< T >()...)) result_of_add_t
Definition: add.h:134
numeric_t< typename EngineTrait< engine_type >::eval_type > numeric_type
Addition result numeric type.
Definition: add_expr.h:60
Addition expression engine.
Definition: add_engine.h:129
AddEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, result_type > engine_type
Expression engine type.
Definition: add_expr.h:58
ScalAddExpr(const left_type &left, const right_type &right, const scalar_type factor)
Expression constructor.
Definition: add_expr.h:148
AddExpr(const left_type &left, const right_type &right)
Expression constructor.
Definition: add_expr.h:110
ScalAddExpr< Left, Right, TiledArray::detail::ComplexConjugate< Scalar > > ScalConjAddExpr
Definition: add_expr.h:41
TILEDARRAY_FORCE_INLINE R conj(const R r)
Wrapper function for std::conj
Definition: complex.h:45
ScalAddEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, Scalar, result_type > engine_type
Expression engine type.
Definition: add_expr.h:78
ExprTrait< AddExpr_ >::left_type left_type
The left-hand expression type.
Definition: add_expr.h:93
ScalAddExpr_ & operator=(ScalAddExpr_ &&)=delete
ExprTrait< ScalAddExpr_ >::scalar_type scalar_type
Scalar type.
Definition: add_expr.h:131
derived_type & derived()
Cast this object to its derived type.
Definition: expr.h:365