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>
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<
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 MultExpr : public BinaryExpr<MultExpr<Left, Right> > {
89  public:
92  typedef typename ExprTrait<MultExpr_>::left_type
94  typedef typename ExprTrait<MultExpr_>::right_type
96  typedef typename ExprTrait<MultExpr_>::engine_type
98 
99  // Compiler generated functions
100  MultExpr(const MultExpr_&) = default;
101  MultExpr(MultExpr_&&) = default;
102  ~MultExpr() = default;
103  MultExpr_& operator=(const MultExpr_&) = delete;
105 
107 
110  MultExpr(const left_type& left, const right_type& right)
111  : BinaryExpr_(left, right) {}
112 
114 
117  template <typename Numeric,
118  typename std::enable_if<
119  TiledArray::detail::is_numeric_v<Numeric> >::type* = nullptr>
120  explicit operator Numeric() const {
121  auto result = BinaryExpr_::left().dot(BinaryExpr_::right());
122  return result.get();
123  }
124 
126 
129  template <typename Numeric,
130  typename std::enable_if<
131  TiledArray::detail::is_numeric_v<Numeric> >::type* = nullptr>
132  explicit operator Future<Numeric>() const {
133  return BinaryExpr_::left().dot(BinaryExpr_::right());
134  }
135 
136 }; // class MultExpr
137 
139 
142 template <typename Left, typename Right, typename Scalar>
143 class ScalMultExpr : public BinaryExpr<ScalMultExpr<Left, Right, Scalar> > {
144  public:
148  typedef typename ExprTrait<ScalMultExpr_>::left_type
150  typedef typename ExprTrait<ScalMultExpr_>::right_type
156 
157  private:
158  scalar_type factor_;
159 
160  public:
161  // Compiler generated functions
162  ScalMultExpr(const ScalMultExpr_&) = default;
164  ~ScalMultExpr() = default;
167 
169 
172  ScalMultExpr(const left_type& left, const right_type& right,
173  const scalar_type factor)
174  : BinaryExpr_(left, right), factor_(factor) {}
175 
177 
179  scalar_type factor() const { return factor_; }
180 
181 }; // class ScalMultExpr
182 
184 
190 template <typename Left, typename Right>
192  const Expr<Right>& right) {
193  static_assert(
195  "no_alias() expressions are not allowed on the right-hand side of the "
196  "assignment operator.");
197  static_assert(
199  "no_alias() expressions are not allowed on the right-hand side of the "
200  "assignment operator.");
201  return MultExpr<Left, Right>(left.derived(), right.derived());
202 }
203 
205 
212 template <typename Left, typename Right, typename Scalar,
213  typename std::enable_if<
214  TiledArray::detail::is_numeric_v<Scalar> >::type* = nullptr>
216  const MultExpr<Left, Right>& expr, const Scalar& factor) {
217  return ScalMultExpr<Left, Right, Scalar>(expr.left(), expr.right(), factor);
218 }
219 
221 
228 template <typename Left, typename Right, typename Scalar,
229  typename std::enable_if<
230  TiledArray::detail::is_numeric_v<Scalar> >::type* = nullptr>
232  const Scalar& factor, const MultExpr<Left, Right>& expr) {
233  return ScalMultExpr<Left, Right, Scalar>(expr.left(), expr.right(), factor);
234 }
235 
237 
245 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
246  typename std::enable_if<
247  TiledArray::detail::is_numeric_v<Scalar2> >::type* = nullptr>
249  const ScalMultExpr<Left, Right, Scalar1>& expr, const Scalar2& factor) {
251  expr.left(), expr.right(), expr.factor() * factor);
252 }
253 
255 
263 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
264  typename std::enable_if<
265  TiledArray::detail::is_numeric_v<Scalar1> >::type* = nullptr>
267  const Scalar1& factor, const ScalMultExpr<Left, Right, Scalar2>& expr) {
269  expr.left(), expr.right(), expr.factor() * factor);
270 }
271 
273 
278 template <typename Left, typename Right>
279 inline ScalMultExpr<Left, Right,
280  typename ExprTrait<MultExpr<Left, Right> >::numeric_type>
282  return ScalMultExpr<Left, Right,
283  typename ExprTrait<MultExpr<Left, Right> >::numeric_type>(
284  expr.left(), expr.right(), -1);
285 }
286 
288 
293 template <typename Left, typename Right, typename Scalar>
295  const ScalMultExpr<Left, Right, Scalar>& expr) {
296  return ScalMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
297  -expr.factor());
298 }
299 
301 
306 template <typename Left, typename Right>
308  return ConjMultExpr<Left, Right>(expr.left(), expr.right(), conj_op());
309 }
310 
312 
317 template <typename Left, typename Right>
319  return MultExpr<Left, Right>(expr.left(), expr.right());
320 }
321 
323 
329 template <typename Left, typename Right, typename Scalar>
331  const ScalMultExpr<Left, Right, Scalar>& expr) {
333  expr.left(), expr.right(),
335 }
336 
338 
344 template <typename Left, typename Right, typename Scalar>
348  expr.left(), expr.right(),
349  TiledArray::detail::conj(expr.factor().factor()));
350 }
351 
353 
360 template <typename Left, typename Right, typename Scalar,
361  typename std::enable_if<
362  TiledArray::detail::is_numeric_v<Scalar> >::type* = nullptr>
364  const ConjMultExpr<Left, Right>& expr, const Scalar& factor) {
365  return ScalConjMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
366  conj_op(factor));
367 }
368 
370 
377 template <typename Left, typename Right, typename Scalar,
378  typename std::enable_if<
379  TiledArray::detail::is_numeric_v<Scalar> >::type* = nullptr>
381  const Scalar& factor, const ConjMultExpr<Left, Right>& expr) {
382  return ScalConjMultExpr<Left, Right, Scalar>(expr.left(), expr.right(),
383  conj_op(factor));
384 }
385 
387 
395 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
396  typename std::enable_if<
397  TiledArray::detail::is_numeric_v<Scalar2> >::type* = nullptr>
399  const ScalConjMultExpr<Left, Right, Scalar1>& expr, const Scalar2& factor) {
401  expr.left(), expr.right(), conj_op(expr.factor().factor() * factor));
402 }
403 
405 
413 template <typename Left, typename Right, typename Scalar1, typename Scalar2,
414  typename std::enable_if<
415  TiledArray::detail::is_numeric_v<Scalar1> >::type* = nullptr>
417  const Scalar1& factor, const ScalConjMultExpr<Left, Right, Scalar2>& expr) {
419  expr.left(), expr.right(), conj_op(expr.factor().factor() * factor));
420 }
421 
423 
428 template <typename Left, typename Right>
429 inline ScalConjMultExpr<
430  Left, Right, typename ExprTrait<ConjMultExpr<Left, Right> >::numeric_type>
432  typedef
433  typename ExprTrait<ConjMultExpr<Left, Right> >::numeric_type scalar_type;
434  return ScalConjMultExpr<Left, Right, scalar_type>(expr.left(), expr.right(),
435  conj_op<scalar_type>(-1));
436 }
437 
439 
445 template <typename Left, typename Right, typename Scalar>
449  expr.left(), expr.right(), conj_op(-expr.factor().factor()));
450 }
451 
453 
460 template <typename Numeric, typename Left, typename Right,
461  typename std::enable_if<
462  TiledArray::detail::is_numeric_v<Numeric> >::type* = nullptr>
463 inline Numeric& operator+=(Numeric& result, const MultExpr<Left, Right>& expr) {
464  result += expr.left().dot(expr.right()).get();
465  return result;
466 }
467 
469 
476 template <typename Numeric, typename Left, typename Right,
477  typename std::enable_if<
478  TiledArray::detail::is_numeric_v<Numeric> >::type* = nullptr>
479 inline Numeric& operator-=(Numeric& result, const MultExpr<Left, Right>& expr) {
480  result -= expr.left().dot(expr.right()).get();
481  return result;
482 }
483 
485 
492 template <typename Numeric, typename Left, typename Right,
493  typename std::enable_if<
494  TiledArray::detail::is_numeric_v<Numeric> >::type* = nullptr>
495 inline Numeric& operator*=(Numeric& result, const MultExpr<Left, Right>& expr) {
496  result *= expr.left().dot(expr.right()).get();
497  return result;
498 }
499 
500 } // namespace expressions
501 } // namespace TiledArray
502 
503 #endif // TILEDARRAY_EXPRESSIONS_MULT_EXPR_H__INCLUDED
ExprTrait< ScalMultExpr_ >::right_type right_type
The right-hand expression type.
Definition: mult_expr.h:151
ScalMultExpr(ScalMultExpr_ &&)=default
Multiplication expression engine.
Definition: mult_engine.h:202
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
ExprTrait< MultExpr_ >::right_type right_type
The right-hand expression type.
Definition: mult_expr.h:95
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
MultExpr(const left_type &left, const right_type &right)
Expression constructor.
Definition: mult_expr.h:110
MultExpr(MultExpr_ &&)=default
decltype(std::declval< Scalar1 >() *std::declval< Scalar2 >()) mult_t
Definition: type_traits.h:1159
BinaryExpr< ScalMultExpr_ > BinaryExpr_
Binary expression base type.
Definition: mult_expr.h:147
ScalMultExpr(const left_type &left, const right_type &right, const scalar_type factor)
Expression constructor.
Definition: mult_expr.h:172
MultExpr_ & operator=(const MultExpr_ &)=delete
Base class for expression evaluation.
Definition: expr.h:97
ScalMultExpr(const ScalMultExpr_ &)=default
Binary expression object.
Definition: binary_expr.h:39
numeric_t< typename EngineTrait< engine_type >::eval_type > numeric_type
Multiplication result numeric type.
Definition: mult_expr.h:80
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
Numeric & operator+=(Numeric &result, const MultExpr< Left, Right > &expr)
Dot product add-to operator.
Definition: mult_expr.h:463
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
ConjAddExpr< Left, Right > conj(const AddExpr< Left, Right > &expr)
Conjugated addition expression factory.
Definition: add_expr.h:281
Right right_type
The right-hand expression type.
Definition: mult_expr.h:51
MultExpr(const MultExpr_ &)=default
Multiplication expression.
Definition: mult_expr.h:143
ScalMultExpr< Left, Right, TiledArray::detail::ComplexConjugate< Scalar > > ScalConjMultExpr
Definition: mult_expr.h:41
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
MultExpr_ & operator=(MultExpr_ &&)=delete
BinaryExpr< MultExpr_ > BinaryExpr_
Binary expression base type.
Definition: mult_expr.h:91
scalar_t< typename EngineTrait< engine_type >::eval_type > scalar_type
Multiplication result scalar type.
Definition: mult_expr.h:62
ScalMultExpr< Left, Right, Scalar > ScalMultExpr_
This class type.
Definition: mult_expr.h:145
ExprTrait< ScalMultExpr_ >::engine_type engine_type
Expression engine type.
Definition: mult_expr.h:153
Numeric & operator-=(Numeric &result, const MultExpr< Left, Right > &expr)
Dot product subtract-to operator.
Definition: mult_expr.h:479
ScalMultExpr_ & operator=(ScalMultExpr_ &&)=delete
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
Numeric & operator*=(Numeric &result, const MultExpr< Left, Right > &expr)
Dot product multiply-to operator.
Definition: mult_expr.h:495
MultEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, result_type > engine_type
Expression engine type.
Definition: mult_expr.h:58
ComplexConjugate< S > conj_op(const S factor)
ComplexConjugate operator factory function.
Definition: complex.h:204
ExprTrait< MultExpr_ >::engine_type engine_type
Expression engine type.
Definition: mult_expr.h:97
ScalMultEngine< typename ExprTrait< Left >::engine_type, typename ExprTrait< Right >::engine_type, Scalar, result_type > engine_type
Expression engine type.
Definition: mult_expr.h:78
MultExpr< Left, Right > MultExpr_
This class type.
Definition: mult_expr.h:90
ExprTrait< MultExpr_ >::left_type left_type
The left-hand expression type.
Definition: mult_expr.h:93
scalar_type factor() const
Scaling factor accessor.
Definition: mult_expr.h:179
Multiplication expression.
Definition: mult_expr.h:88
ScalMultExpr_ & operator=(const ScalMultExpr_ &)=delete
decltype(mult(std::declval< T >()...)) result_of_mult_t
ExprTrait< ScalMultExpr_ >::left_type left_type
The left-hand expression type.
Definition: mult_expr.h:149
TILEDARRAY_FORCE_INLINE R conj(const R r)
Wrapper function for std::conj
Definition: complex.h:45
ExprTrait< ScalMultExpr_ >::scalar_type scalar_type
Tile scalar type.
Definition: mult_expr.h:155
Scaled multiplication expression engine.
Definition: mult_engine.h:475
const right_type & right() const
Right-hand expression argument accessor.
Definition: binary_expr.h:71
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:74
derived_type & derived()
Cast this object to its derived type.
Definition: expr.h:365