TiledArray  0.7.0
tensor_interface.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2015 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  * tensor_view.h
22  * May 29, 2015
23  *
24  */
25 
26 #ifndef TILEDARRAY_TENSOR_TENSOR_VIEW_H__INCLUDED
27 #define TILEDARRAY_TENSOR_TENSOR_VIEW_H__INCLUDED
28 
31 
32 namespace Eigen {
33 
34  // Forward declarations
35  template <typename> class aligned_allocator;
36 
37 } // namespace Eigen
38 
39 namespace TiledArray {
40 
41  // Forward declarations
42  class Permutation;
43  template <typename, typename> class Tensor;
44  class Range;
45  namespace detail {
46  template <typename, typename>
48  }
49  template <typename T, typename Index>
50  void remap(detail::TensorInterface<T, Range> &, T* const, const Index&, const Index&);
51  template <typename T, typename Index>
53  const Index&, const Index&);
54  template <typename T>
56  const std::initializer_list<std::size_t>&,
57  const std::initializer_list<std::size_t>&);
58  template <typename T>
60  const std::initializer_list<std::size_t>&,
61  const std::initializer_list<std::size_t>&);
62 
63  namespace detail {
64 
66 
78  template <typename T, typename R>
79  class TensorInterface {
80  public:
82  typedef R range_type;
83  typedef typename range_type::size_type size_type;
84  typedef typename std::remove_const<T>::type
86  typedef typename std::add_lvalue_reference<T>::type
88  typedef typename std::add_lvalue_reference<typename std::add_const<T>::type>::type
90  typedef typename std::add_pointer<T>::type
92  typedef typename std::add_pointer<typename std::add_const<T>::type>::type
94  typedef typename std::ptrdiff_t difference_type;
99 
102 
103  private:
104 
105  template <typename X>
106  using numeric_t = typename TiledArray::detail::numeric_type<X>::type;
107 
108  template <typename, typename>
109  friend class TensorInterface;
110 
111  template <typename U, typename Index>
113  U* const, const Index&, const Index&);
114 
115  template <typename U, typename Index>
117  U* const, const Index&, const Index&);
118 
119  template <typename U>
121  U* const,
122  const std::initializer_list<std::size_t>&,
123  const std::initializer_list<std::size_t>&);
124 
125  template <typename U>
127  U* const,
128  const std::initializer_list<std::size_t>&,
129  const std::initializer_list<std::size_t>&);
130 
131  range_type range_;
132  pointer data_;
133 
134  public:
135 
137  TensorInterface() = delete;
138  ~TensorInterface() = default;
139  TensorInterface(const TensorInterface_&) = default;
140  TensorInterface(TensorInterface_&&) = default;
141  TensorInterface_& operator=(const TensorInterface_&) = delete;
143 
145 
148  template <typename U,
149  typename std::enable_if<std::is_convertible<
150  typename TensorInterface<U, R>::pointer, pointer>::value
151  >::type* = nullptr>
153  range_(other.range_), data_(other.data_)
154  { }
155 
157 
160  template <typename U,
161  typename std::enable_if<std::is_convertible<
162  typename TensorInterface<U, R>::pointer, pointer>::value
163  >::type* = nullptr>
165  range_(std::move(other.range_)), data_(other.data_)
166  {
167  other.data_ = nullptr;
168  }
169 
171 
175  range_(range), data_(data)
176  {
177  TA_ASSERT(data);
178  }
179 
181 
185  range_(std::move(range)), data_(data)
186  {
187  TA_ASSERT(data);
188  }
189 
190  template <typename T1,
191  typename std::enable_if<detail::is_tensor<T1>::value>::type* = nullptr>
192  TensorInterface_& operator=(const T1& other) {
193  TA_ASSERT(data_ != other.data());
194 
195  detail::inplace_tensor_op([] (numeric_type& MADNESS_RESTRICT result,
196  const numeric_t<T1> arg)
197  { result = arg; }, *this, other);
198 
199  return *this;
200  }
201 
203 
205  const range_type& range() const { return range_; }
206 
208 
210  size_type size() const { return range_.volume(); }
211 
212 
214 
216  pointer data() const { return data_; }
217 
219 
222  const_reference operator[](const size_type index) const {
223  TA_ASSERT(range_.includes(index));
224  return data_[range_.ordinal(index)];
225  }
226 
228 
232  TA_ASSERT(range_.includes(index));
233  return data_[range_.ordinal(index)];
234  }
235 
236 
238 
241  template<typename... Index>
242  reference operator()(const Index&... idx) {
243  TA_ASSERT(range_.includes(idx...));
244  return data_[range_.ordinal(idx...)];
245  }
246 
248 
251  template<typename... Index>
252  const_reference operator()(const Index&... idx) const {
253  TA_ASSERT(range_.includes(idx...));
254  return data_[range_.ordinal(idx...)];
255  }
256 
258 
260  constexpr bool empty() const { return false; }
261 
263 
265  void swap(TensorInterface_& other) {
266  range_.swap(other.range_);
267  std::swap(data_, other.data_);
268  }
269 
270 
272 
276  template <typename Index>
277  TensorInterface_& shift_to(const Index& bound_shift) {
278  range_.inplace_shift(bound_shift);
279  return *this;
280  }
281 
283 
287  template <typename Index>
288  result_tensor shift(const Index& bound_shift) const {
289  return result_tensor(range_.shift(bound_shift), data_);
290  }
291 
292  // Generic vector operations
293 
295 
302  template <typename Right, typename Op,
303  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
304  result_tensor binary(const Right& right, Op&& op) const {
305  return result_tensor(*this, right, op);
306  }
307 
309 
317  template <typename Right, typename Op,
318  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
319  result_tensor binary(const Right& right, Op&& op, const Permutation& perm) const {
320  return result_tensor(*this, right, op, perm);
321  }
322 
324 
335  template <typename Right, typename Op,
336  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
337  TensorInterface_& inplace_binary(const Right& right, Op&& op) {
338  detail::inplace_tensor_op(op, *this, right);
339  return *this;
340  }
341 
343 
349  template <typename Op>
350  result_tensor unary(Op&& op) const {
351  return result_tensor(*this, op);
352  }
353 
355 
363  template <typename Op>
364  result_tensor unary(Op&& op, const Permutation& perm) const {
365  return result_tensor(*this, op, perm);
366  }
367 
369 
374  template <typename Op>
376  detail::inplace_tensor_op(op, *this);
377  return *this;
378  }
379 
380  // Scale operation
381 
383 
388  template <typename Scalar,
389  typename std::enable_if<detail::is_numeric<Scalar>::value>::type* = nullptr>
390  result_tensor scale(const Scalar factor) const {
391  return unary([=] (const numeric_type a) -> numeric_type
392  { return a * factor; });
393  }
394 
396 
402  template <typename Scalar,
403  typename std::enable_if<detail::is_numeric<Scalar>::value>::type* = nullptr>
404  result_tensor scale(const Scalar factor, const Permutation& perm) const {
405  return unary([=] (const numeric_type a) -> numeric_type
406  { return a * factor; }, perm);
407  }
408 
410 
414  template <typename Scalar,
415  typename std::enable_if<detail::is_numeric<Scalar>::value>::type* = nullptr>
416  TensorInterface_& scale_to(const Scalar factor) {
417  return inplace_unary([=] (numeric_type& MADNESS_RESTRICT res) { res *= factor; });
418  }
419 
420 
421  // Addition operations
422 
424 
429  template <typename Right,
430  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
431  result_tensor add(const Right& right) const {
432  return binary(right, [] (const numeric_type l,
433  const numeric_t<Right> r)
434  -> numeric_type { return l + r; });
435  }
436 
438 
444  template <typename Right,
445  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
446  result_tensor add(const Right& right, const Permutation& perm) const {
447  return binary(right, [] (const numeric_type l,
448  const numeric_t<Right> r)
449  -> numeric_type { return l + r; }, perm);
450  }
451 
453 
460  template <typename Right, typename Scalar,
461  typename std::enable_if<is_tensor<Right>::value &&
462  detail::is_numeric<Scalar>::value>::type* = nullptr>
463  result_tensor add(const Right& right, const Scalar factor) const {
464  return binary(right, [=] (const numeric_type l,
465  const numeric_t<Right> r)
466  -> numeric_type { return (l + r) * factor; });
467  }
468 
470 
478  template <typename Right, typename Scalar,
479  typename std::enable_if<is_tensor<Right>::value &&
480  detail::is_numeric<Scalar>::value>::type* = nullptr>
481  result_tensor add(const Right& right, const Scalar factor,
482  const Permutation& perm) const
483  {
484  return binary(right, [=] (const numeric_type l,
485  const numeric_t<Right> r)
486  -> numeric_type { return (l + r) * factor; }, perm);
487  }
488 
490 
494  result_tensor add(const numeric_type value) const {
495  return unary([=] (const numeric_type a) -> numeric_type
496  { return a + value; });
497  }
498 
500 
505  result_tensor add(const numeric_type value, const Permutation& perm) const {
506  return unary([=] (const numeric_type a) -> numeric_type
507  { return a + value; }, perm);
508  }
509 
511 
515  template <typename Right,
516  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
517  TensorInterface_& add_to(const Right& right) {
518  return inplace_binary(right, [] (numeric_type& MADNESS_RESTRICT l,
519  const numeric_t<Right> r)
520  { l += r; });
521  }
522 
524 
530  template <typename Right, typename Scalar,
531  typename std::enable_if<is_tensor<Right>::value &&
532  detail::is_numeric<Scalar>::value>::type* = nullptr>
533  TensorInterface_& add_to(const Right& right, const Scalar factor) {
534  return inplace_binary(right, [=] (numeric_type& MADNESS_RESTRICT l,
535  const numeric_t<Right> r)
536  { (l += r) *= factor; });
537  }
538 
540 
544  return inplace_unary([=] (numeric_type& MADNESS_RESTRICT res) { res += value; });
545  }
546 
547  // Subtraction operations
548 
550 
555  template <typename Right,
556  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
557  result_tensor subt(const Right& right) const {
558  return binary(right, [] (const numeric_type l,
559  const numeric_t<Right> r)
560  -> numeric_type { return l - r; });
561  }
562 
564 
570  template <typename Right,
571  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
572  result_tensor subt(const Right& right, const Permutation& perm) const {
573  return binary(right, [] (const numeric_type l,
574  const numeric_t<Right> r)
575  -> numeric_type { return l - r; }, perm);
576  }
577 
579 
586  template <typename Right, typename Scalar,
587  typename std::enable_if<is_tensor<Right>::value &&
588  detail::is_numeric<Scalar>::value>::type* = nullptr>
589  result_tensor subt(const Right& right, const numeric_type factor) const {
590  return binary(right, [=] (const numeric_type l,
591  const numeric_t<Right> r)
592  -> numeric_type { return (l - r) * factor; });
593  }
594 
596 
604  template <typename Right, typename Scalar,
605  typename std::enable_if<is_tensor<Right>::value &&
606  detail::is_numeric<Scalar>::value>::type* = nullptr>
607  result_tensor subt(const Right& right, const Scalar factor,
608  const Permutation& perm) const
609  {
610  return binary(right, [=] (const numeric_type l,
611  const numeric_t<Right> r)
612  -> numeric_type { return (l - r) * factor; }, perm);
613  }
614 
616 
619  result_tensor subt(const numeric_type value) const {
620  return add(-value);
621  }
622 
624 
629  result_tensor subt(const numeric_type value, const Permutation& perm) const {
630  return add(-value, perm);
631  }
632 
634 
638  template <typename Right,
639  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
640  TensorInterface_& subt_to(const Right& right) {
641  return inplace_binary(right, [] (numeric_type& MADNESS_RESTRICT l,
642  const numeric_t<Right> r)
643  { l -= r; });
644  }
645 
647 
653  template <typename Right, typename Scalar,
654  typename std::enable_if<is_tensor<Right>::value &&
655  detail::is_numeric<Scalar>::value>::type* = nullptr>
656  TensorInterface_& subt_to(const Right& right, const Scalar factor) {
657  return inplace_binary(right, [=] (numeric_type& MADNESS_RESTRICT l,
658  const numeric_t<Right> r)
659  { (l -= r) *= factor; });
660  }
661 
663 
666  return add_to(-value);
667  }
668 
669  // Multiplication operations
670 
672 
677  template <typename Right,
678  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
679  result_tensor mult(const Right& right) const {
680  return binary(right, [] (const numeric_type l,
681  const numeric_t<Right> r)
682  -> numeric_type { return l * r; });
683  }
684 
686 
692  template <typename Right,
693  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
694  result_tensor mult(const Right& right, const Permutation& perm) const {
695  return binary(right, [] (const numeric_type l,
696  const numeric_t<Right> r)
697  -> numeric_type { return l * r; }, perm);
698  }
699 
701 
708  template <typename Right, typename Scalar,
709  typename std::enable_if<is_tensor<Right>::value &&
710  detail::is_numeric<Scalar>::value>::type* = nullptr>
711  result_tensor mult(const Right& right, const Scalar factor) const {
712  return binary(right, [=] (const numeric_type l,
713  const numeric_t<Right> r)
714  -> numeric_type { return (l * r) * factor; });
715  }
716 
718 
726  template <typename Right, typename Scalar,
727  typename std::enable_if<is_tensor<Right>::value &&
728  detail::is_numeric<Scalar>::value>::type* = nullptr>
729  result_tensor mult(const Right& right, const Scalar factor,
730  const Permutation& perm) const
731  {
732  return binary(right, [=] (const numeric_type l,
733  const numeric_t<Right> r)
734  -> numeric_type { return (l * r) * factor; }, perm);
735  }
736 
738 
742  template <typename Right,
743  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
744  TensorInterface_& mult_to(const Right& right) {
745  return inplace_binary(right, [] (numeric_type& MADNESS_RESTRICT l,
746  const numeric_t<Right> r)
747  { l *= r; });
748  }
749 
751 
757  template <typename Right, typename Scalar,
758  typename std::enable_if<is_tensor<Right>::value &&
759  detail::is_numeric<Scalar>::value>::type* = nullptr>
760  TensorInterface_& mult_to(const Right& right, const Scalar factor) {
761  return inplace_binary(right, [=] (numeric_type& MADNESS_RESTRICT l,
762  const numeric_t<Right> r)
763  { (l *= r) *= factor; });
764  }
765 
766  // Negation operations
767 
769 
771  result_tensor neg() const {
772  return unary([] (const numeric_type r) -> numeric_type { return -r; });
773  }
774 
776 
779  result_tensor neg(const Permutation& perm) const {
780  return unary([] (const numeric_type l) -> numeric_type { return -l; },
781  perm);
782  }
783 
785 
788  return inplace_unary([] (numeric_type& MADNESS_RESTRICT l) { l = -l; });
789  }
790 
791 
793 
796  result_tensor conj() const { return scale(conj_op()); }
797 
799 
804  template <typename Scalar,
805  typename std::enable_if<detail::is_numeric<Scalar>::value>::type* = nullptr>
806  result_tensor conj(const Scalar factor) const {
807  return scale(conj_op(factor));
808  }
809 
811 
815  result_tensor conj(const Permutation& perm) const {
816  return scale(conj_op(), perm);
817  }
818 
820 
826  template <typename Scalar,
827  typename std::enable_if<detail::is_numeric<Scalar>::value>::type* = nullptr>
828  result_tensor conj(const Scalar factor, const Permutation& perm) const {
829  return scale(conj_op(factor), perm);
830  }
831 
833 
836  return scale_to(conj_op());
837  }
838 
840 
844  template <typename Scalar,
845  typename std::enable_if<detail::is_numeric<Scalar>::value>::type* = nullptr>
846  TensorInterface_& conj_to(const Scalar factor) {
847  return scale_to(conj_op(factor));
848  }
849 
850 
852 
864  template <typename ReduceOp, typename JoinOp>
865  numeric_type reduce(ReduceOp&& reduce_op, JoinOp&& join_op,
866  const numeric_type identity) const
867  {
868  return detail::tensor_reduce(reduce_op, join_op, identity, *this);
869  }
870 
872 
886  template <typename Right, typename ReduceOp, typename JoinOp,
887  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
888  numeric_type reduce(const Right& other, ReduceOp&& reduce_op, JoinOp&& join_op,
889  const numeric_type identity) const
890  {
891  return detail::tensor_reduce(reduce_op, join_op, identity, *this, other);
892  }
893 
895 
897  numeric_type sum() const {
898  auto sum_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
899  { res += arg; };
900  return reduce(sum_op, sum_op, numeric_type(0));
901  }
902 
904 
907  auto mult_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
908  { res *= arg; };
909  return reduce(mult_op, mult_op, numeric_type(1));
910  }
911 
913 
916  auto square_op = [] (scalar_type& MADNESS_RESTRICT res, const numeric_type arg)
917  { res += TiledArray::detail::norm(arg); };
918  auto sum_op = [] (scalar_type& MADNESS_RESTRICT res, const scalar_type arg)
919  { res += arg; };
920  return reduce(square_op, sum_op, numeric_type(0));
921  }
922 
924 
926  numeric_type norm() const {
927  return std::sqrt(squared_norm());
928  }
929 
931 
933  numeric_type min() const {
934  auto min_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
935  { res = std::min(res, arg); };
936  return reduce(min_op, min_op, std::numeric_limits<numeric_type>::max());
937  }
938 
940 
942  numeric_type max() const {
943  auto max_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
944  { res = std::max(res, arg); };
945  return reduce(max_op, max_op, std::numeric_limits<numeric_type>::min());
946  }
947 
949 
952  auto abs_min_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
953  { res = std::min(res, std::abs(arg)); };
954  auto min_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
955  { res = std::min(res, arg); };
956  return reduce(abs_min_op, min_op, std::numeric_limits<numeric_type>::max());
957  }
958 
960 
963  auto abs_max_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
964  { res = std::max(res, std::abs(arg)); };
965  auto max_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type arg)
966  { res = std::max(res, arg); };
967  return reduce(abs_max_op, max_op, numeric_type(0));
968  }
969 
971 
975  template <typename Right,
976  typename std::enable_if<is_tensor<Right>::value>::type* = nullptr>
977  numeric_type dot(const Right& other) const {
978  auto mult_add_op = [] (numeric_type& res, const numeric_type l,
979  const numeric_t<Right> r)
980  { res += l * r; };
981  auto add_op = [] (numeric_type& MADNESS_RESTRICT res, const numeric_type value)
982  { res += value; };
983  return reduce(other, mult_add_op, add_op, numeric_type(0));
984  }
985 
986  }; // class TensorInterface
987 
988  } // namespace detail
989 } // namespace TiledArray
990 
991 #endif // TILEDARRAY_TENSOR_TENSOR_VIEW_H__INCLUDED
result_tensor neg() const
Create a negated copy of this tensor.
numeric_type reduce(ReduceOp &&reduce_op, JoinOp &&join_op, const numeric_type identity) const
Unary reduction operation.
result_tensor conj(const Permutation &perm) const
Create a complex conjugated and permuted copy of this tensor.
result_tensor unary(Op &&op) const
Use a unary, element wise operation to construct a new tensor.
TensorInterface_ & inplace_binary(const Right &right, Op &&op)
Use a binary, element wise operation to modify this tensor.
void inplace_tensor_op(Op &&op, TR &result, const Ts &... tensors)
In-place tensor operations with contiguous data.
Definition: kernels.h:163
result_tensor subt(const Right &right, const numeric_type factor) const
Scale and subtract this and right to construct a new tensor.
TensorInterface_ & mult_to(const Right &right)
Multiply this tensor by right.
TensorInterface_ & shift_to(const Index &bound_shift)
Shift the lower and upper bound of this tensor.
scalar_type squared_norm() const
Square of vector 2-norm.
result_tensor binary(const Right &right, Op &&op, const Permutation &perm) const
Use a binary, element wise operation to construct a new, permuted tensor.
reference operator()(const Index &... idx)
Element accessor.
An N-dimensional tensor object.
Definition: foreach.h:40
result_tensor shift(const Index &bound_shift) const
Shift the lower and upper bound of this range.
std::add_lvalue_reference< T >::type reference
Element reference type.
void swap(Bitset< B > &b0, Bitset< B > &b1)
Definition: bitset.h:593
TensorInterface_ & operator=(const TensorInterface_ &)=delete
result_tensor mult(const Right &right, const Permutation &perm) const
Multiply this by right to create a new, permuted tensor.
result_tensor neg(const Permutation &perm) const
Create a negated and permuted copy of this tensor.
result_tensor binary(const Right &right, Op &&op) const
Use a binary, element wise operation to construct a new tensor.
result_tensor subt(const numeric_type value) const
Subtract a constant from a copy of this tensor.
std::add_pointer< T >::type pointer
Element pointer type.
constexpr bool empty() const
Check for empty view.
TILEDARRAY_FORCE_INLINE R norm(const R r)
Wrapper function for std::norm
Definition: complex.h:89
TensorInterface(TensorInterface< U, R > &&other)
Type conversion move constructor.
result_tensor conj() const
Create a complex conjugated copy of this tensor.
detail::numeric_type< value_type >::type numeric_type
the numeric type that supports T
STL namespace.
Type trait for extracting the numeric type of tensors and arrays.
Definition: type_traits.h:479
TensorInterface_ & subt_to(const numeric_type value)
Subtract a constant from this tensor.
numeric_type sum() const
Sum of elements.
KroneckerDeltaTile< _N >::numeric_type max(const KroneckerDeltaTile< _N > &arg)
auto abs(const ComplexConjugate< T > &a)
Definition: complex.h:247
TensorInterface_ & mult_to(const Right &right, const Scalar factor)
Scale and multiply this tensor by right.
Type trait for extracting the scalar type of tensors and arrays.
Definition: type_traits.h:539
Forward declarations.
Definition: foreach.h:32
result_tensor add(const Right &right, const Scalar factor, const Permutation &perm) const
Scale and add this and other to construct a new, permuted tensor.
reference operator[](const size_type index)
Element subscript accessor.
TensorInterface_ & subt_to(const Right &right)
Subtract right from this tensor.
numeric_type dot(const Right &other) const
Vector dot product.
result_tensor add(const Right &right) const
Add this and other to construct a new tensors.
std::add_lvalue_reference< typename std::add_const< T >::type >::type const_reference
Element reference type.
TensorInterface_ & inplace_unary(Op &&op)
Use a unary, element wise operation to modify this tensor.
Tensor< T, Eigen::aligned_allocator< T > > result_tensor
Tensor type used as the return type from arithmetic operations.
void swap(TensorInterface_ &other)
Swap tensor views.
result_tensor add(const Right &right, const Permutation &perm) const
Add this and other to construct a new, permuted tensor.
TensorInterface(range_type &&range, pointer data)
Construct a new view of tensor.
result_tensor conj(const Scalar factor) const
Create a complex conjugated and scaled copy of this tensor.
std::ptrdiff_t difference_type
Difference type.
#define TA_ASSERT(a)
Definition: error.h:107
TensorInterface_ & neg_to()
Negate elements of this tensor.
result_tensor subt(const Right &right, const Permutation &perm) const
Subtract this and right to construct a new, permuted tensor.
result_tensor scale(const Scalar factor, const Permutation &perm) const
Construct a scaled and permuted copy of this tensor.
TensorInterface_ & scale_to(const Scalar factor)
Scale this tensor.
result_tensor add(const numeric_type value) const
Add a constant to a copy of this tensor.
T identity()
identity for group of objects of type T
TensorInterface(const range_type &range, pointer data)
Construct a new view of tensor.
numeric_type product() const
Product of elements.
TensorInterface()=delete
Compiler generated functions.
numeric_type min() const
Minimum element.
const_reference operator()(const Index &... idx) const
Element accessor.
std::remove_const< T >::type value_type
Array element type.
void reduce_op(ReduceOp &&reduce_op, JoinOp &&join_op, const Result &identity, const std::size_t n, Result &result, const Args *const ... args)
Definition: vector_op.h:640
result_tensor scale(const Scalar factor) const
Construct a scaled copy of this tensor.
const_reference operator[](const size_type index) const
Element subscript accessor.
Tensor interface for external data.
result_tensor subt(const Right &right, const Scalar factor, const Permutation &perm) const
Scale and subtract this and right to construct a new, permuted tensor.
result_tensor conj(const Scalar factor, const Permutation &perm) const
Create a complex conjugated, scaled, and permuted copy of this tensor.
void remap(detail::TensorInterface< T, Range > &, T *const, const Index &, const Index &)
result_tensor mult(const Right &right) const
Multiply this by right to create a new tensor.
TensorInterface_ & conj_to()
Complex conjugate this tensor.
std::add_pointer< typename std::add_const< T >::type >::type const_pointer
Element pointer type.
TensorInterface_ & subt_to(const Right &right, const Scalar factor)
Subtract right from and scale this tensor.
Permutation of a sequence of objects indexed by base-0 indices.
Definition: permutation.h:119
TensorInterface(const TensorInterface< U, R > &other)
Type conversion copy constructor.
ComplexConjugate< S > conj_op(const S factor)
ComplexConjugate operator factory function.
Definition: complex.h:181
const range_type & range() const
Tensor range object accessor.
TensorInterface_ & add_to(const Right &right, const Scalar factor)
Add other to this tensor, and scale the result.
numeric_type reduce(const Right &other, ReduceOp &&reduce_op, JoinOp &&join_op, const numeric_type identity) const
Binary reduction operation.
range_type::size_type size_type
size type
size_type size() const
Tensor dimension size accessor.
result_tensor unary(Op &&op, const Permutation &perm) const
Use a unary, element wise operation to construct a new, permuted tensor.
result_tensor subt(const numeric_type value, const Permutation &perm) const
Subtract a constant from a permuted copy of this tensor.
detail::scalar_type< value_type >::type scalar_type
the scalar type that supports T
TensorInterface_ & operator=(const T1 &other)
TensorInterface_ & add_to(const numeric_type value)
Add a constant to this tensor.
Scalar tensor_reduce(ReduceOp &&reduce_op, JoinOp &&join_op, Scalar identity, const T1 &tensor1, const Ts &... tensors)
Reduction operation for contiguous tensors.
Definition: kernels.h:579
result_tensor add(const Right &right, const Scalar factor) const
Scale and add this and other to construct a new tensor.
TensorInterface< T, R > TensorInterface_
This class type.
numeric_type max() const
Maximum element.
TensorInterface_ & conj_to(const Scalar factor)
Complex conjugate and scale this tensor.
result_tensor mult(const Right &right, const Scalar factor) const
Scale and multiply this by right to create a new tensor.
TensorInterface_ & add_to(const Right &right)
Add other to this tensor.
KroneckerDeltaTile< _N >::numeric_type min(const KroneckerDeltaTile< _N > &arg)
numeric_type abs_max() const
Absolute maximum element.
numeric_type abs_min() const
Absolute minimum element.
pointer data() const
Data pointer accessor.
result_tensor subt(const Right &right) const
Subtract this and right to construct a new tensor.
result_tensor add(const numeric_type value, const Permutation &perm) const
Add a constant to a permuted copy of this tensor.
numeric_type norm() const
Vector 2-norm.
result_tensor mult(const Right &right, const Scalar factor, const Permutation &perm) const
Scale and multiply this by right to create a new, permuted tensor.