Cytnx v1.0.0
Loading...
Searching...
No Matches
Tensor.hpp
Go to the documentation of this file.
1#ifndef CYTNX_TENSOR_H_
2#define CYTNX_TENSOR_H_
3
4#include "Type.hpp"
5#include "cytnx_error.hpp"
6#include "Device.hpp"
8#include <iostream>
9#include <fstream>
10#include "utils/dynamic_arg_resolver.hpp"
11#include "Accessor.hpp"
12#include <utility>
13#include <vector>
14#include <initializer_list>
15#include <string>
16
17#ifdef BACKEND_TORCH
18#else
19
20 #include "backend/Scalar.hpp"
21 #include "backend/Storage.hpp"
22 #include "backend/Tensor_impl.hpp"
23
24namespace cytnx {
25
26 class Tensor;
27
29 // [Note] these are fwd from linalg.hpp
30 template <class T>
31 Tensor operator+(const Tensor &lhs, const T &rc);
32 template <class T>
33 Tensor operator-(const Tensor &lhs, const T &rhs);
34 template <class T>
35 Tensor operator*(const Tensor &lhs, const T &rhs);
36 template <class T>
37 Tensor operator/(const Tensor &lhs, const T &rhs);
39
41 class Tensor {
42 private:
43 public:
45 // this is a proxy class to allow get/set element using [] as python!
46 struct Tproxy {
47 boost::intrusive_ptr<Tensor_impl> _insimpl;
48 std::vector<cytnx::Accessor> _accs;
49 Tproxy(boost::intrusive_ptr<Tensor_impl> _ptr, const std::vector<cytnx::Accessor> &accs)
50 : _insimpl(std::move(_ptr)), _accs(accs) {}
51
52 // when used to set elems:
53 const Tensor &operator=(const Tensor &rhs) {
54 this->_insimpl->set(_accs, rhs._impl);
55 return rhs;
56 }
57
58 template <class T>
59 const T &operator=(const T &rc) {
60 this->_insimpl->set(_accs, rc);
61 return rc;
62 }
63 const Tproxy &operator=(const Tproxy &rc) {
65 this->_insimpl->set(_accs, tmp._impl);
66 return rc;
67 }
68
69 template <class T>
70 Tensor operator+=(const T &rc) {
72 self._impl = _insimpl->get(_accs);
73 self += rc;
74 _insimpl->set(_accs, self._impl);
75 self._impl = this->_insimpl;
76 return self;
77 }
78 Tensor operator+=(const Tproxy &rc);
79
80 template <class T>
81 Tensor operator-=(const T &rc) {
83 self._impl = _insimpl->get(_accs);
84 self -= rc;
85 _insimpl->set(_accs, self._impl);
86 self._impl = this->_insimpl;
87 return self;
88 }
89 Tensor operator-=(const Tproxy &rc);
90
91 template <class T>
92 Tensor operator/=(const T &rc) {
94 self._impl = _insimpl->get(_accs);
95 self /= rc;
96 _insimpl->set(_accs, self._impl);
97 self._impl = this->_insimpl;
98 return self;
99 }
100 Tensor operator/=(const Tproxy &rc);
101
102 template <class T>
103 Tensor operator*=(const T &rc) {
104 Tensor self;
105 self._impl = _insimpl->get(_accs);
106 self *= rc;
107 _insimpl->set(_accs, self._impl);
108 self._impl = this->_insimpl;
109 return self;
110 }
111 Tensor operator*=(const Tproxy &rc);
112
113 // alias to resolve conflict with op ovld for rc=Tensor
114 /*
115 template<class T>
116 Tensor _operatorADD(const T &rc) const{
117 Tensor out;
118 out._impl = _insimpl->get(_accs);
119 return out.Add(rc);
120 }
121 */
122 Tensor operator+(const cytnx_complex128 &rc) const; //{return this->_operatorADD(rc);};
123 Tensor operator+(const cytnx_complex64 &rc) const; //{return this->_operatorADD(rc);};
124 Tensor operator+(const cytnx_double &rc) const; //{return this->_operatorADD(rc);};
125 Tensor operator+(const cytnx_float &rc) const; //{return this->_operatorADD(rc);};
126 Tensor operator+(const cytnx_uint64 &rc) const; //{return this->_operatorADD(rc);};
127 Tensor operator+(const cytnx_int64 &rc) const; //{return this->_operatorADD(rc);};
128 Tensor operator+(const cytnx_uint32 &rc) const; //{return this->_operatorADD(rc);};
129 Tensor operator+(const cytnx_int32 &rc) const; //{return this->_operatorADD(rc);};
130 Tensor operator+(const cytnx_uint16 &rc) const; //{return this->_operatorADD(rc);};
131 Tensor operator+(const cytnx_int16 &rc) const; //{return this->_operatorADD(rc);};
132 Tensor operator+(const cytnx_bool &rc) const; //{return this->_operatorADD(rc);};
133 Tensor operator+(const Tproxy &rc) const;
134
135 /*
136 template<class T>
137 Tensor _operatorSUB(const T &rc) const{
138 Tensor out;
139 out._impl = _insimpl->get(_accs);
140 return out.Sub(rc);
141 }
142 */
143 Tensor operator-(const cytnx_complex128 &rc) const; //{return this->_operatorSUB(rc);};
144 Tensor operator-(const cytnx_complex64 &rc) const; //{return this->_operatorSUB(rc);};
145 Tensor operator-(const cytnx_double &rc) const; //{return this->_operatorSUB(rc);};
146 Tensor operator-(const cytnx_float &rc) const; //{return this->_operatorSUB(rc);};
147 Tensor operator-(const cytnx_uint64 &rc) const; //{return this->_operatorSUB(rc);};
148 Tensor operator-(const cytnx_int64 &rc) const; //{return this->_operatorSUB(rc);};
149 Tensor operator-(const cytnx_uint32 &rc) const; //{return this->_operatorSUB(rc);};
150 Tensor operator-(const cytnx_int32 &rc) const; //{return this->_operatorSUB(rc);};
151 Tensor operator-(const cytnx_uint16 &rc) const; //{return this->_operatorSUB(rc);};
152 Tensor operator-(const cytnx_int16 &rc) const; //{return this->_operatorSUB(rc);};
153 Tensor operator-(const cytnx_bool &rc) const; //{return this->_operatorSUB(rc);};
154 Tensor operator-(const Tproxy &rc) const;
155
156 Tensor operator-() const;
157
158 /*
159 template<class T>
160 Tensor _operatorMUL(const T &rc) const{
161 Tensor out;
162 out._impl = _insimpl->get(_accs);
163 return out.Mul(rc);
164 }
165 */
166 Tensor operator*(const cytnx_complex128 &rc) const; //{return this->_operatorMUL(rc);};
167 Tensor operator*(const cytnx_complex64 &rc) const; //{return this->_operatorMUL(rc);};
168 Tensor operator*(const cytnx_double &rc) const; //{return this->_operatorMUL(rc);};
169 Tensor operator*(const cytnx_float &rc) const; //{return this->_operatorMUL(rc);};
170 Tensor operator*(const cytnx_uint64 &rc) const; //{return this->_operatorMUL(rc);};
171 Tensor operator*(const cytnx_int64 &rc) const; //{return this->_operatorMUL(rc);};
172 Tensor operator*(const cytnx_uint32 &rc) const; //{return this->_operatorMUL(rc);};
173 Tensor operator*(const cytnx_int32 &rc) const; //{return this->_operatorMUL(rc);};
174 Tensor operator*(const cytnx_uint16 &rc) const; //{return this->_operatorMUL(rc);};
175 Tensor operator*(const cytnx_int16 &rc) const; //{return this->_operatorMUL(rc);};
176 Tensor operator*(const cytnx_bool &rc) const; //{return this->_operatorMUL(rc);};
177 Tensor operator*(const Tproxy &rc) const;
178
179 /*
180 template<class T>
181 Tensor _operatorDIV(const T &rc) const{
182 Tensor out;
183 out._impl = _insimpl->get(_accs);
184 return out.Div(rc);
185 }
186 */
187 Tensor operator/(const cytnx_complex128 &rc) const; //{return this->_operatorDIV(rc);};
188 Tensor operator/(const cytnx_complex64 &rc) const; //{return this->_operatorDIV(rc);};
189 Tensor operator/(const cytnx_double &rc) const; //{return this->_operatorDIV(rc);};
190 Tensor operator/(const cytnx_float &rc) const; //{return this->_operatorDIV(rc);};
191 Tensor operator/(const cytnx_uint64 &rc) const; //{return this->_operatorDIV(rc);};
192 Tensor operator/(const cytnx_int64 &rc) const; //{return this->_operatorDIV(rc);};
193 Tensor operator/(const cytnx_uint32 &rc) const; //{return this->_operatorDIV(rc);};
194 Tensor operator/(const cytnx_int32 &rc) const; //{return this->_operatorDIV(rc);};
195 Tensor operator/(const cytnx_uint16 &rc) const; //{return this->_operatorDIV(rc);};
196 Tensor operator/(const cytnx_int16 &rc) const; //{return this->_operatorDIV(rc);};
197 Tensor operator/(const cytnx_bool &rc) const; //{return this->_operatorDIV(rc);};
198 Tensor operator/(const Tproxy &rc) const;
199
200 template <class T>
201 T item() const {
202 Tensor out;
203 out._impl = _insimpl->get(_accs);
204 return out.item<T>();
205 }
206
207 Scalar::Sproxy item() const {
208 Tensor out;
209 out._impl = _insimpl->get(_accs);
210 return out.item();
211 }
212
213 // when used to get elems:
214 operator Tensor() const {
215 Tensor out;
216 out._impl = _insimpl->get(_accs);
217 return out;
218 }
219
220 Storage storage() const {
221 Tensor out;
222 out._impl = _insimpl->get(_accs);
223 return out.storage();
224 }
225
226 }; // proxy class of Tensor.
227
229
231 // these two are using the python way!
232 //----------------------------------------
233 template <class... Ts>
234 Tproxy operator()(const std::string &e1, const Ts &...elems) {
235 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
236 return (*this)[tmp];
237 }
238 template <class... Ts>
239 Tproxy operator()(const cytnx_int64 &e1, const Ts &...elems) {
240 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
241 return (*this)[tmp];
242 }
243 template <class... Ts>
244 Tproxy operator()(const cytnx::Accessor &e1, const Ts &...elems) {
245 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
246 return (*this)[tmp];
247 }
248 template <class... Ts>
249 const Tproxy operator()(const std::string &e1, const Ts &...elems) const {
250 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
251 return (*this)[tmp];
252 }
253 template <class... Ts>
254 const Tproxy operator()(const cytnx_int64 &e1, const Ts &...elems) const {
255 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
256 return (*this)[tmp];
257 }
258 template <class... Ts>
259 const Tproxy operator()(const cytnx::Accessor &e1, const Ts &...elems) const {
260 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
261 return (*this)[tmp];
262 }
263
264 //-----------------------------------------
265
266 Tproxy operator[](const std::initializer_list<cytnx::Accessor> &accs) {
267 std::vector<cytnx::Accessor> tmp = accs;
268 return (*this)[tmp];
269 }
270 Tproxy operator[](const std::vector<cytnx::Accessor> &accs) {
271 return Tproxy(this->_impl, accs);
272 }
273
274 const Tproxy operator[](const std::vector<cytnx::Accessor> &accs) const {
275 return Tproxy(this->_impl, accs);
276 }
277 const Tproxy operator[](const std::initializer_list<cytnx::Accessor> &accs) const {
278 std::vector<cytnx::Accessor> tmp = accs;
279 return (*this)[tmp];
280 }
281
282 Tproxy operator[](const std::initializer_list<cytnx_int64> &accs) {
283 std::vector<cytnx_int64> tmp = accs;
284 return (*this)[tmp];
285 }
286 Tproxy operator[](const std::vector<cytnx_int64> &accs) {
287 std::vector<cytnx::Accessor> acc_in;
288 for (int i = 0; i < accs.size(); i++) {
289 acc_in.push_back(cytnx::Accessor(accs[i]));
290 }
291 return Tproxy(this->_impl, acc_in);
292 }
293 const Tproxy operator[](const std::initializer_list<cytnx_int64> &accs) const {
294 std::vector<cytnx_int64> tmp = accs;
295 return (*this)[tmp];
296 }
297 const Tproxy operator[](const std::vector<cytnx_uint64> &accs) const {
298 std::vector<cytnx::Accessor> acc_in;
299 for (int i = 0; i < accs.size(); i++) {
300 acc_in.push_back(cytnx::Accessor(accs[i]));
301 }
302 return Tproxy(this->_impl, acc_in);
303 }
304 const Tproxy operator[](const std::vector<cytnx_int64> &accs) const {
305 std::vector<cytnx::Accessor> acc_in;
306 for (int i = 0; i < accs.size(); i++) {
307 acc_in.push_back(cytnx::Accessor(accs[i]));
308 }
309 return Tproxy(this->_impl, acc_in);
310 }
312 //-------------------------------------------
313
315 void _Save(std::fstream &f) const;
316 void _Load(std::fstream &f);
317
319
328 void Save(const std::string &fname) const;
332 void Save(const char *fname) const;
333
342 void Tofile(const std::string &fname) const;
343
347 void Tofile(const char *fname) const;
348
352 void Tofile(std::fstream &f) const;
353
362 static Tensor Load(const std::string &fname);
366 static Tensor Load(const char *fname);
367
388 static Tensor Fromfile(const std::string &fname, const unsigned int &dtype,
389 const cytnx_int64 &count = -1);
390 static Tensor Fromfile(const char *fname, const unsigned int &dtype,
391 const cytnx_int64 &count = -1);
392
393 // static Tensor Frombinary(const std::string &fname);
394
396 boost::intrusive_ptr<Tensor_impl> _impl;
397 Tensor() : _impl(new Tensor_impl()){};
398 Tensor(const Tensor &rhs) { _impl = rhs._impl; }
399
400 /*
401 template<class Tp>
402 Tensor(const std::initializer_list<Tp> &rhs){
403 Storage stmp = std::vector<Tp>(rhs);
404 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
405 tmp->Init(stmp);
406 this->_impl = tmp;
407 }
408 */
409
410 Tensor &operator=(const Tensor &rhs) {
411 _impl = rhs._impl;
412 return *this;
413 }
414
415 void operator=(const Tproxy &rhsp) { // this is used to handle proxy assignment
416 this->_impl = rhsp._insimpl->get(rhsp._accs);
417 }
419
421 // default device==Device.cpu (-1)
446 void Init(const std::vector<cytnx_uint64> &shape, unsigned int dtype = Type.Double,
447 int device = -1, bool init_zero = true) {
448 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
449 this->_impl = tmp;
450 this->_impl->Init(shape, dtype, device, init_zero);
451 }
452 void Init(std::initializer_list<cytnx_uint64> shape, unsigned int dtype = Type.Double,
453 int device = -1, bool init_zero = true) {
454 this->Init(std::vector<cytnx_uint64>(shape), dtype, device, init_zero);
455 }
456 // void Init(const Storage& storage) {
457 // boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
458 // this->_impl = tmp;
459 // this->_impl->Init(storage);
460 // }
461 // void Init(const Storage& storage, const std::vector<cytnx_uint64> &shape,
462 // const unsigned int &dtype = Type.Double, const int &device = -1) {
463 // boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
464 // this->_impl = tmp;
465 // this->_impl->Init(storage, shape, dtype, device);
466 // }
467
480 Tensor(const std::vector<cytnx_uint64> &shape, unsigned int dtype = Type.Double,
481 int device = -1, bool init_zero = true)
482 : _impl(new Tensor_impl()) {
483 this->Init(shape, dtype, device, init_zero);
484 }
485 Tensor(std::initializer_list<cytnx_uint64> shape, unsigned int dtype = Type.Double,
486 int device = -1, bool init_zero = true)
487 : _impl(new Tensor_impl()) {
488 this->Init(shape, dtype, device, init_zero);
489 }
490 // Tensor(const Storage& storage)
491 // : _impl(new Tensor_impl()) {
492 // this->Init(storage);
493 // }
494 // Tensor(const Storage& storage, const std::vector<cytnx_uint64> &shape,
495 // const unsigned int &dtype = Type.Double, const int &device = -1)
496 // : _impl(new Tensor_impl()) {
497 // this->Init(storage, shape, dtype, device);
498 // }
500
501 // This mechanism is to remove the 'void' type from Type_list. Taking advantage of it
502 // appearing first ...
503
505 struct internal {
506 template <typename Variant>
507 struct exclude_first;
508
509 template <typename First, typename... Rest>
510 struct exclude_first<std::variant<First, Rest...>> {
511 using type = std::variant<Rest...>;
512 };
513 }; // internal
515
516 // std::variant of pointers to Type_list, without void ....
519 std::add_pointer>;
520
521 // convert this->_impl->_storage._impl->Mem to a typed variant of pointers, excluding void*
523
524 // Convert storage to the logical Cytnx element pointer type.
525 //
526 // Use ptr_as<T>() for host code and raw memory copies. For complex tensors, T is
527 // std::complex<...>. Use gpu_ptr_as<T>() for CUDA kernel code; for complex tensors, T is
528 // cuda::std::complex<...>. CUDA library APIs that require cuComplex ABI pointers should cast
529 // explicitly at the library-call boundary.
530 template <typename T>
531 T *ptr_as() const {
532 cytnx_error_msg(this->dtype() != Type_class::cy_typeid_v<std::remove_cv_t<T>>,
533 "[ERROR] Attempt to convert dtype %d (%s) to pointer of type %s",
534 this->dtype(), Type_class::getname(this->dtype()).c_str(),
535 Type_class::getname(Type_class::cy_typeid_v<std::remove_cv_t<T>>).c_str());
536 return static_cast<T *>(this->_impl->_storage._impl->data());
537 }
538
539 #ifdef UNI_GPU
540 // std::variant of pointers to Type_list_gpu, without void ....
541 using gpu_pointer_types =
543 std::add_pointer>;
544
545 // convert this->_impl->_storage->Mem to a typed variant of pointers, excluding void*
547
548 // Convert storage to the CUDA kernel element pointer type.
549 //
550 // This is for CUDA kernel interfaces. Generic host code should use ptr_as<T>() so the logical
551 // Cytnx dtype mapping is checked. CUDA library APIs that require cuComplex ABI pointers should
552 // cast explicitly at the library-call boundary.
553 template <typename T>
554 T *gpu_ptr_as() const {
556 this->dtype() != Type_class::cy_typeid_gpu_v<std::remove_cv_t<T>>,
557 "[ERROR] Attempt to convert dtype %d (%s) to GPU pointer of type %s", this->dtype(),
558 Type_class::getname(this->dtype()).c_str(),
559 Type_class::getname(Type_class::cy_typeid_gpu_v<std::remove_cv_t<T>>).c_str());
560 return static_cast<T *>(this->_impl->_storage._impl->data());
561 }
562 #endif
563
569 static Tensor from_storage(const Storage &in) {
570 Tensor out;
571 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
572 out._impl = tmp;
573 out._impl->Init(in);
574 return out;
575 }
576
582 unsigned int dtype() const { return this->_impl->dtype(); }
583
589 int device() const { return this->_impl->device(); }
590
596 std::string dtype_str() const { return this->_impl->dtype_str(); }
597
603 std::string device_str() const { return this->_impl->device_str(); }
604
609 const std::vector<cytnx_uint64> &shape() const { return this->_impl->shape(); }
610
620 std::vector<cytnx_int64> strides() const;
621
626 cytnx_uint64 rank() const { return this->_impl->rank(); }
627
632 cytnx_uint64 size() const { return this->_impl->storage().size(); }
633
638 bool is_void() const { return this->_impl->is_void(); }
639
644 bool is_scalar() const { return this->_impl->is_scalar(); }
645
650 bool is_empty() const { return !this->is_void() && this->size() == 0; }
651
669 Tensor clone() const {
670 Tensor out;
671 out._impl = this->_impl->clone();
672 return out;
673 }
674
695 Tensor to(const int &device) const {
696 Tensor out;
697 out._impl = this->_impl->to(device);
698 return out;
699 }
700
718 void to_(const int &device) { this->_impl->to_(device); }
719
724 const bool &is_contiguous() const { return this->_impl->is_contiguous(); }
725
726 Tensor &permute_(const std::vector<cytnx_uint64> &rnks) {
727 this->_impl->permute_(rnks);
728 return *this;
729 }
731 template <class... Ts>
732 Tensor &permute_(const cytnx_uint64 &e1, const Ts &...elems) {
733 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
734 this->_impl->permute_(argv);
735 return *this;
736 }
738
757 Tensor permute(const std::vector<cytnx_uint64> &rnks) const {
758 Tensor out;
759 out._impl = this->_impl->permute(rnks);
760 return out;
761 }
763 template <class... Ts>
764 Tensor permute(const cytnx_uint64 &e1, const Ts &...elems) const {
765 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
766 return this->permute(argv);
767 }
769
788 Tensor out;
789 out._impl = this->_impl->contiguous();
790 return out;
791 }
792
808 this->_impl->contiguous_();
809 return *this;
810 }
811
832 Tensor &reshape_(const std::vector<cytnx_int64> &new_shape) {
833 this->_impl->reshape_(new_shape);
834 return *this;
835 }
837 Tensor &reshape_(const std::vector<cytnx_uint64> &new_shape) {
838 std::vector<cytnx_int64> shape(new_shape.begin(), new_shape.end());
839 this->_impl->reshape_(shape);
840 return *this;
841 }
842 Tensor &reshape_(const std::initializer_list<cytnx_int64> &new_shape) {
843 std::vector<cytnx_int64> shape = new_shape;
844 this->_impl->reshape_(shape);
845 return *this;
846 }
847 template <class... Ts>
848 Tensor &reshape_(const cytnx_int64 &e1, const Ts... elems) {
849 std::vector<cytnx_int64> shape = dynamic_arg_int64_resolver(e1, elems...);
850 this->_impl->reshape_(shape);
851 return *this;
852 }
854
878 Tensor reshape(const std::vector<cytnx_int64> &new_shape) const {
879 Tensor out;
880 out._impl = this->_impl->reshape(new_shape);
881 return out;
882 }
883
887 Tensor reshape(const std::vector<cytnx_uint64> &new_shape) const {
888 std::vector<cytnx_int64> tmp(new_shape.begin(), new_shape.end());
889 Tensor out;
890 out._impl = this->_impl->reshape(tmp);
891 return out;
892 }
893
897 Tensor reshape(const std::initializer_list<cytnx_int64> &new_shape) const {
898 return this->reshape(std::vector<cytnx_int64>(new_shape));
899 }
900
902 template <class... Ts>
903 Tensor reshape(const cytnx_int64 &e1, const Ts &...elems) const {
904 std::vector<cytnx_int64> argv = dynamic_arg_int64_resolver(e1, elems...);
905 return this->reshape(argv);
906 }
908
930 Tensor astype(const int &new_type) const {
931 Tensor out;
932 out._impl = this->_impl->astype(new_type);
933 return out;
934 }
935
936 // Tensor diagonal(){
937 // for(unsigned int i=0;i<this->shape().size();i++){
938 // if(this->shape()[i] != this->shape()[0],"[ERROR] Tensor.diagonal() can only be called
939 // when the subject has equal dimension in each rank.%s","\n");
940 // }
941 //
942 // }
943
964 template <class T>
965 T &at(const std::vector<cytnx_uint64> &locator) {
966 return this->_impl->at<T>(locator);
967 }
968
972 template <class T>
973 const T &at(const std::vector<cytnx_uint64> &locator) const {
974 return this->_impl->at<T>(locator);
975 }
977 template <class T>
978 T &at(const std::initializer_list<cytnx_uint64> &locator) {
979 return this->at<T>(std::vector<cytnx_uint64>(locator));
980 }
981 template <class T>
982 const T &at(const std::initializer_list<cytnx_uint64> &locator) const {
983 return this->at<T>(std::vector<cytnx_uint64>(locator));
984 }
985 template <class T, class... Ts>
986 const T &at(const cytnx_uint64 &e1, const Ts &...elems) const {
987 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
988 return this->at<T>(argv);
989 }
990 template <class T, class... Ts>
991 T &at(const cytnx_uint64 &e1, const Ts &...elems) {
992 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
993 return this->at<T>(argv);
994 }
995
996 const Scalar::Sproxy at(const std::vector<cytnx_uint64> &locator) const {
997 return this->_impl->at(locator);
998 }
999
1000 Scalar::Sproxy at(const std::vector<cytnx_uint64> &locator) { return this->_impl->at(locator); }
1001 const Scalar::Sproxy at(const std::initializer_list<cytnx_uint64> &locator) const {
1002 return this->at(std::vector<cytnx_uint64>(locator));
1003 }
1004 Scalar::Sproxy at(const std::initializer_list<cytnx_uint64> &locator) {
1005 return this->at(std::vector<cytnx_uint64>(locator));
1006 }
1008
1034 template <class T>
1035 T &item() {
1036 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item<T>]%s",
1037 "item can only be called from a Tensor with only one element\n");
1038 return this->_impl->storage().at<T>(0);
1039 }
1040
1042 template <class T>
1043 const T &item() const {
1044 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item<T>]%s",
1045 "item can only be called from a Tensor with only one element\n");
1046 return this->_impl->storage().at<T>(0);
1047 }
1048
1049 const Scalar::Sproxy item() const {
1050 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item]%s",
1051 "item can only be called from a Tensor with only one element\n");
1052 Scalar::Sproxy out(this->storage()._impl, 0);
1053 return out;
1054 }
1055
1056 Scalar::Sproxy item() {
1057 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item]%s",
1058 "item can only be called from a Tensor with only one element\n");
1059 Scalar::Sproxy out(this->storage()._impl, 0);
1060 return out;
1061 }
1062
1064
1089 Tensor get(const std::vector<cytnx::Accessor> &accessors,
1090 std::vector<cytnx_int64> &removed) const {
1091 Tensor out;
1092 out._impl = this->_impl->get(accessors, removed);
1093 return out;
1094 }
1095 Tensor get(const std::vector<cytnx::Accessor> &accessors) const {
1096 Tensor out;
1097 std::vector<cytnx_int64> removed;
1098 out._impl = this->_impl->get(accessors, removed);
1099 return out;
1100 }
1101
1102 /*
1103 Tensor get_v2(const std::vector<cytnx::Accessor> &accessors) const{
1104 Tensor out;
1105 out._impl = this->_impl->get_v2(accessors);
1106 return out;
1107 }
1108 */
1109
1128 void set(const std::vector<cytnx::Accessor> &accessors, const Tensor &rhs) {
1129 this->_impl->set(accessors, rhs._impl);
1130 }
1131
1150 template <class T>
1151 void set(const std::vector<cytnx::Accessor> &accessors, const T &rc) {
1152 this->_impl->set(accessors, rc);
1153 }
1155 template <class T>
1156 void set(const std::initializer_list<cytnx::Accessor> &accessors, const T &rc) {
1157 std::vector<cytnx::Accessor> args = accessors;
1158 this->set(args, rc);
1159 }
1161
1171 Storage &storage() const { return this->_impl->storage(); }
1172
1187 template <class T>
1188 void fill(const T &val) {
1189 this->_impl->fill(val);
1190 }
1191
1196 bool equivshape(const Tensor &rhs) {
1197 if (this->shape() != rhs.shape()) return false;
1198 return true;
1199 }
1200
1209
1218
1219 // Arithmic:
1236 template <class T>
1238
1255 template <class T>
1257
1274 template <class T>
1276
1294 template <class T>
1296
1297 // Tensor &operator+=(const Tproxy &rc);
1298 // Tensor &operator-=(const Tproxy &rc);
1299 // Tensor &operator*=(const Tproxy &rc);
1300 // Tensor &operator/=(const Tproxy &rc);
1301 /*
1302 Tensor operator+(const Tproxy &rc){
1303 return *this + Tensor(rc);
1304 }
1305 Tensor operator-(const Tproxy &rc){
1306 return *this - Tensor(rc);
1307 }
1308 Tensor operator*(const Tproxy &rc){
1309 return *this * Tensor(rc);
1310 }
1311 Tensor operator/(const Tproxy &rc){
1312 return *this / Tensor(rc);
1313 }
1314 */
1320 template <class T>
1321 Tensor Add(const T &rhs) {
1322 return *this + rhs;
1323 }
1324
1330 template <class T>
1331 Tensor &Add_(const T &rhs) {
1332 return *this += rhs;
1333 }
1334
1340 template <class T>
1341 Tensor Sub(const T &rhs) {
1342 return *this - rhs;
1343 }
1344
1350 template <class T>
1351 Tensor &Sub_(const T &rhs) {
1352 return *this -= rhs;
1353 }
1354
1360 template <class T>
1361 Tensor Mul(const T &rhs) {
1362 return *this * rhs;
1363 }
1364
1370 template <class T>
1371 Tensor &Mul_(const T &rhs) {
1372 return *this *= rhs;
1373 }
1374
1381 template <class T>
1382 Tensor Div(const T &rhs) {
1383 return *this / rhs;
1384 }
1385
1392 template <class T>
1393 Tensor &Div_(const T &rhs) {
1394 return *this /= rhs;
1395 }
1396
1403 template <class T>
1404 Tensor Cpr(const T &rhs) {
1405 return *this == rhs;
1406 }
1407
1408 // /**
1409 // * @brief Compare each element of the current tensor with the input tensor.
1410 // * @details This function Compare each element of the current tensor with the input tensor.
1411 // * @param[in] rhs the compared tensor.
1412 // */
1413 // bool approx_eq(const Tensor &rhs, const cytnx_double tol = 0) {
1414 // if (this->device() != rhs.device()) {
1415 // if (User_debug)
1416 // std::cout << "[approx_eq] Tensor device " << this->device()
1417 // << "not equal to rhs tensor device " << rhs.device() << std::endl;
1418 // return false;
1419 // }
1420 // // if (this->dtype() != rhs.dtype()) {
1421 // // std::cout << "[approx_eq] Tensor dtype " << this->dtype()
1422 // // << "not equal to rhs tensor dtype " << rhs.dtype() << std::endl;
1423 // // return false;
1424 // // }
1425 // if (this->shape() != rhs.shape()) {
1426 // if (User_debug)
1427 // std::cout << "[approx_eq] Tensor shape " << this->shape()
1428 // << "not equal to rhs tensor shape " << rhs.shape() << std::endl;
1429 // return false;
1430 // }
1431 // if (this->is_contiguous() != rhs.is_contiguous()) {
1432 // if (User_debug)
1433 // std::cout << "[AreNearlyEqTensor] Tensor contiguous flag " << this->is_contiguous()
1434 // << "not equal to rhs tensor flag " << rhs.is_contiguous() << std::endl;
1435 // return false;
1436 // }
1437 // return this->_impl->_storage.approx_eq(rhs._impl->_storage._impl, tol);
1438 // }
1439
1440 // template<class T>
1441 // Tensor& Cpr_(const T &rhs){
1442 //
1443 // return *this == rhs;
1444 // }
1445
1446 template <class T>
1447 Tensor Mod(const T &rhs) {
1448 return *this % rhs;
1449 }
1450
1457 Tensor operator-() { return this->Mul(-1.); }
1458
1466 Tensor flatten() const {
1467 Tensor out = this->clone();
1468 out.contiguous_();
1469 out.reshape_({-1});
1470 return out;
1471 }
1472
1480 void flatten_() {
1481 this->contiguous_();
1482 this->reshape_({-1});
1483 }
1484
1511 void append(const Tensor &rhs) {
1512 // Tensor in;
1513 // check Tensor in shape:
1514 cytnx_error_msg(rhs.is_void() || this->is_void(), "[ERROR] try to append a null Tensor.%s",
1515 "\n");
1516 cytnx_error_msg(this->is_scalar(), "[ERROR] try to append to a rank-0 Tensor.%s", "\n");
1517 if (!this->is_contiguous()) this->contiguous_();
1518
1519 cytnx_error_msg(rhs.rank() != this->rank() - 1,
1520 "[ERROR] try to append a Tensor with rank not match.%s", "\n");
1521 cytnx_uint64 Nelem = 1;
1522 for (unsigned int i = 0; i < rhs.shape().size(); i++) {
1523 cytnx_error_msg(rhs.shape()[i] != this->shape()[i + 1],
1524 "[ERROR] dimension mismatch @ rhs.rank: [%d] this: [%d] rhs: [%d]\n", i,
1525 this->shape()[i + 1], rhs.shape()[i]);
1526 Nelem *= rhs.shape()[i];
1527 }
1528
1529 // check type:
1530 Tensor in;
1531 if (rhs.dtype() != this->dtype()) {
1532 in = rhs.astype(this->dtype());
1533 if (!in.is_contiguous()) in.contiguous_();
1534 } else {
1535 if (!rhs.is_contiguous())
1536 in = rhs.contiguous();
1537 else
1538 in = rhs;
1539 }
1540 this->_impl->_shape[0] += 1;
1541 cytnx_uint64 oldsize = this->_impl->_storage.size();
1542 this->_impl->_storage.resize(oldsize + Nelem);
1543 memcpy(((char *)this->_impl->_storage.data()) +
1544 oldsize * Type.typeSize(this->dtype()) / sizeof(char),
1545 in._impl->_storage.data(), Type.typeSize(in.dtype()) * Nelem);
1546 }
1574 void append(const Storage &srhs) {
1575 // check Tensor in shape:
1576 cytnx_error_msg(this->is_void(), "[ERROR] try to append to an uninitialized Tensor.%s", "\n");
1577 cytnx_error_msg(srhs.size() == 0, "[ERROR] try to append an empty Storage.%s", "\n");
1578 cytnx_error_msg(this->rank() != 2,
1579 "[ERROR] append a storage to Tensor can only accept rank-2 Tensor.%s", "\n");
1580 if (!this->is_contiguous()) this->contiguous_();
1581
1582 cytnx_error_msg(this->shape().back() != srhs.size(), "[ERROR] Tensor dmension mismatch!%s",
1583 "\n");
1584
1585 // check type:
1586 Storage in;
1587 if (srhs.dtype() != this->dtype()) {
1588 in = srhs.astype(this->dtype());
1589 } else {
1590 in = srhs;
1591 }
1592 this->_impl->_shape[0] += 1;
1593 cytnx_uint64 oldsize = this->_impl->_storage.size();
1594 this->_impl->_storage.resize(oldsize + in.size());
1595 memcpy(((char *)this->_impl->_storage.data()) +
1596 oldsize * Type.typeSize(this->dtype()) / sizeof(char),
1597 in._impl->data(), Type.typeSize(in.dtype()) * in.size());
1598 }
1599 /*
1600 void append(const Tensor &rhs){
1601 // convert to the same type.
1602 Tensor in;
1603 if(rhs.dtype() != this->dtype()){
1604 in = rhs.astype(this->dtype());
1605 }else{
1606 in = rhs;
1607 }
1608
1609 // 1) check rank
1610 if(this->shape().size()==1){
1611 // check if rhs is a scalar tensor (only one element)
1612 cytnx_error_msg(!(rhs.shape().size()==1 && rhs.shape()[0]==1),"[ERROR] trying to append
1613 a scalar into multidimentional Tensor is not allow.\n Only rank-1 Tensor can accept scalar
1614 append.%s","\n"); this->_impl->_shape[0]+=1; this->_impl->_storage.append(0);
1615
1616 }else{
1617 cytnx_error_msg(rhs.shape().size() != this->shape().size()-1,"[ERROR] try to append a
1618 Tensor with rank not match.%s","\n");
1619
1620 }
1621 cytnx_error_msg(!this->is_contiguous(),"[ERROR] append require the Tensor to be contiguous.
1622 suggestion: call contiguous() or contiguous_() first.","\n");
1623 }
1624 */
1636 template <class T>
1637 void append(const T &rhs) {
1638 cytnx_error_msg(this->is_void(), "[ERROR] try to append to an uninitialized Tensor.%s", "\n");
1639 cytnx_error_msg(this->rank() != 1,
1640 "[ERROR] trying to append a scalar into multidimentional Tensor is not "
1641 "allow.\n Only rank-1 Tensor can accept scalar append.%s",
1642 "\n");
1644 "[ERROR] append require the Tensor to be contiguous. suggestion: call "
1645 "contiguous() or contiguous_() first.",
1646 "\n");
1647 this->_impl->_shape[0] += 1;
1648 this->_impl->_storage.append(rhs);
1649 }
1650
1659 bool same_data(const Tensor &rhs) const;
1660
1661 // linalg:
1667 std::vector<Tensor> Svd(const bool &is_UvT = true) const;
1668
1674 std::vector<Tensor> Eigh(const bool &is_V = true, const bool &row_v = false) const;
1675
1681
1686 Tensor InvM() const;
1687
1696 Tensor &Inv_(const double &clip = -1.);
1697
1706 Tensor Inv(const double &clip = -1.) const;
1707
1713
1718 Tensor Conj() const;
1719
1725
1730 Tensor Exp() const;
1731
1737 [[deprecated("use norm() (returns Scalar) instead")]] Tensor Norm() const;
1738
1745 Scalar norm() const;
1746
1751 Tensor Pow(const cytnx_double &p) const;
1752
1758
1763 Tensor Trace(const cytnx_uint64 &a = 0, const cytnx_uint64 &b = 1) const;
1764
1769 Tensor Abs() const;
1770
1776
1781 Tensor Max() const;
1782
1787 Tensor Min() const;
1788
1789 }; // class Tensor
1790
1791 Tensor operator+(const Tensor &lhs, const Tensor::Tproxy &rhs);
1792 Tensor operator-(const Tensor &lhs, const Tensor::Tproxy &rhs);
1793 Tensor operator*(const Tensor &lhs, const Tensor::Tproxy &rhs);
1794 Tensor operator/(const Tensor &lhs, const Tensor::Tproxy &rhs);
1795
1796 Tensor operator+(const Tensor &lhs, const Scalar::Sproxy &rhs);
1797 Tensor operator-(const Tensor &lhs, const Scalar::Sproxy &rhs);
1798 Tensor operator*(const Tensor &lhs, const Scalar::Sproxy &rhs);
1799 Tensor operator/(const Tensor &lhs, const Scalar::Sproxy &rhs);
1800
1802 std::ostream &operator<<(std::ostream &os, const Tensor &in);
1803 std::ostream &operator<<(std::ostream &os, const Tensor::Tproxy &in);
1805 //{ os << Tensor(in);};
1806} // namespace cytnx
1807
1808#endif // BACKEND_TORCH
1809
1810#endif // CYTNX_TENSOR_H_
constexpr Type_class Type
data type
Definition Type.hpp:555
object that mimic the python slice to access elements in C++ [this is for c++ API only].
Definition Accessor.hpp:17
an tensor (multi-dimensional array)
Definition Tensor.hpp:41
void append(const Storage &srhs)
the append function of the Storage.
Definition Tensor.hpp:1574
bool is_void() const
whether the Tensor is uninitialized.
Definition Tensor.hpp:638
Tensor & operator*=(const T &rc)
multiplication assignment operator with a Tensor or a scalar.
Tensor & operator/=(const T &rc)
division assignment operator with a Tensor or a scalar.
Tensor operator-()
The negation function.
Definition Tensor.hpp:1457
void fill(const T &val)
fill all the element of current Tensor with the value.
Definition Tensor.hpp:1188
Tensor InvM() const
the InvM member function. Same as cytnx::linalg::InvM(const Tensor &Tin), where Tin is the current Te...
bool same_data(const Tensor &rhs) const
Check whether two tensors share the same internal memory.
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:718
Tensor & permute_(const std::vector< cytnx_uint64 > &rnks)
Definition Tensor.hpp:726
bool is_scalar() const
whether the Tensor is an initialized rank-0 scalar Tensor
Definition Tensor.hpp:644
Tensor reshape(const std::vector< cytnx_uint64 > &new_shape) const
Definition Tensor.hpp:887
void append(const T &rhs)
the append function of the scalar.
Definition Tensor.hpp:1637
Tensor & operator-=(const T &rc)
subtraction assignment operator with a Tensor or a scalar.
Tensor & Add_(const T &rhs)
Addition function with a Tensor or a scalar, inplacely. Same as operator+=(const T &rhs).
Definition Tensor.hpp:1331
std::vector< cytnx_int64 > strides() const
the storage strides of the Tensor
Tensor Abs() const
the Abs member function. Same as linalg::Abs(const Tensor &Tin), where Tin is the current Tensor.
Tensor reshape(const std::initializer_list< cytnx_int64 > &new_shape) const
Definition Tensor.hpp:897
std::string device_str() const
the device (in string) of the Tensor
Definition Tensor.hpp:603
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:807
Tensor Inv(const double &clip=-1.) const
Apply the inverse on each entry of the Tensor.
Tensor Mul(const T &rhs)
Multiplication function with a Tensor or a scalar. Same as cytnx::operator*(const Tensor &self,...
Definition Tensor.hpp:1361
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:582
Tensor Sub(const T &rhs)
Subtraction function with a Tensor or a scalar. Same as cytnx::operator-(const Tensor &self,...
Definition Tensor.hpp:1341
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:787
void Tofile(const std::string &fname) const
Save current Tensor to the binary file.
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition Tensor.hpp:965
Tensor reshape(const std::vector< cytnx_int64 > &new_shape) const
return a new Tensor that is reshaped.
Definition Tensor.hpp:878
static Tensor Fromfile(const std::string &fname, const unsigned int &dtype, const cytnx_int64 &count=-1)
Load current Tensor from the binary file.
T & item()
get the element from a rank-0 Tensor.
Definition Tensor.hpp:1035
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:669
Tensor(const std::vector< cytnx_uint64 > &shape, unsigned int dtype=Type.Double, int device=-1, bool init_zero=true)
Construct a new Tensor object.
Definition Tensor.hpp:480
std::vector< Tensor > Eigh(const bool &is_V=true, const bool &row_v=false) const
the Eigh member function. Same as cytnx::linalg::Eigh(const Tensor &Tin, const bool &is_V,...
void Tofile(const char *fname) const
void append(const Tensor &rhs)
the append function.
Definition Tensor.hpp:1511
static Tensor Load(const char *fname)
void Save(const char *fname) const
void set(const std::vector< cytnx::Accessor > &accessors, const Tensor &rhs)
set elements with the input Tensor using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1128
static Tensor Fromfile(const char *fname, const unsigned int &dtype, const cytnx_int64 &count=-1)
Tensor Norm() const
the Norm member function. Same as linalg::Norm(const Tensor &Tin), where Tin is the current Tensor.
Tensor astype(const int &new_type) const
return a new Tensor that cast to different dtype.
Definition Tensor.hpp:930
Tensor & Div_(const T &rhs)
Division function with a Tensor or a scalar, inplacely. Same as operator/=(const T &rhs).
Definition Tensor.hpp:1393
make_variant_from_transform_t< typename internal::exclude_first< Type_list >::type, std::add_pointer > pointer_types
Definition Tensor.hpp:519
pointer_types ptr() const
static Tensor Load(const std::string &fname)
Load current Tensor from file.
cytnx_uint64 size() const
Return the total number of logical elements in the Tensor.
Definition Tensor.hpp:632
Tensor & operator+=(const T &rc)
addition assignment operator with a Tensor or a scalar.
Tensor Conj() const
the Conj member function. Same as cytnx::linalg::Conj(const Tensor &Tin), where Tin is the current Te...
Tensor Trace(const cytnx_uint64 &a=0, const cytnx_uint64 &b=1) const
the Trace member function. Same as linalg::Trace(const Tensor &Tin, const cytnx_uint64 &a,...
bool is_empty() const
whether the Tensor is initialized and has no elements
Definition Tensor.hpp:650
bool equivshape(const Tensor &rhs)
compare the shape of two tensors.
Definition Tensor.hpp:1196
Tensor & Pow_(const cytnx_double &p)
the Pow_ member function. Same as linalg::Pow_(Tensor &Tin, const cytnx_double &p),...
std::vector< Tensor > Svd(const bool &is_UvT=true) const
the SVD member function. Same as cytnx::linalg::Svd(const Tensor &Tin, const bool &is_UvT) ,...
void Init(const std::vector< cytnx_uint64 > &shape, unsigned int dtype=Type.Double, int device=-1, bool init_zero=true)
initialize a Tensor
Definition Tensor.hpp:446
std::string dtype_str() const
the dtype (in string) of the Tensor
Definition Tensor.hpp:596
Tensor & Mul_(const T &rhs)
Multiplication function with a Tensor or a scalar, inplacely. Same as operator*=(const T &rhs).
Definition Tensor.hpp:1371
cytnx_uint64 rank() const
the rank of the Tensor
Definition Tensor.hpp:626
Tensor get(const std::vector< cytnx::Accessor > &accessors, std::vector< cytnx_int64 > &removed) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1089
const bool & is_contiguous() const
return whether the Tensor is contiguous or not.
Definition Tensor.hpp:724
Tensor Exp() const
the Exp member function. Same as linalg::Exp(const Tensor &Tin), where Tin is the current Tensor.
Tensor & Abs_()
the Abs_ member function. Same as linalg::Abs_(Tensor &Tin), where Tin is the current Tensor.
Tensor Add(const T &rhs)
Addition function with a Tensor or a scalar. Same as cytnx::operator+(const Tensor &self,...
Definition Tensor.hpp:1321
void flatten_()
The flatten function, inplacely.
Definition Tensor.hpp:1480
void Save(const std::string &fname) const
Save current Tensor to file.
Tensor flatten() const
The flatten function.
Definition Tensor.hpp:1466
Tensor(std::initializer_list< cytnx_uint64 > shape, unsigned int dtype=Type.Double, int device=-1, bool init_zero=true)
Definition Tensor.hpp:485
Tensor & Conj_()
the Conj_ member function. Same as cytnx::linalg::Conj_(Tensor &Tin), where Tin is the current Tensor...
T * ptr_as() const
Definition Tensor.hpp:531
Tensor Pow(const cytnx_double &p) const
the Pow member function. Same as linalg::Pow(const Tensor &Tin, const cytnx_double &p),...
int device() const
the device-id of the Tensor
Definition Tensor.hpp:589
Tensor real()
return the real part of the tensor.
Tensor imag()
return the imaginary part of the tensor.
void Init(std::initializer_list< cytnx_uint64 > shape, unsigned int dtype=Type.Double, int device=-1, bool init_zero=true)
Definition Tensor.hpp:452
Tensor to(const int &device) const
copy a tensor to new device
Definition Tensor.hpp:695
Tensor & reshape_(const std::vector< cytnx_int64 > &new_shape)
reshape the Tensor, inplacely
Definition Tensor.hpp:832
void Tofile(std::fstream &f) const
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
Definition Tensor.hpp:1095
Scalar norm() const
the norm member function. Same as linalg::norm(const Tensor &Tin), where Tin is the current Tensor....
void set(const std::vector< cytnx::Accessor > &accessors, const T &rc)
set elements with the input constant using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1151
Tensor Max() const
the Max member function. Same as linalg::Max(const Tensor &Tin), where Tin is the current Tensor.
Tensor permute(const std::vector< cytnx_uint64 > &rnks) const
perform tensor permute on the cytnx::Tensor and return a new instance.
Definition Tensor.hpp:757
Tensor Div(const T &rhs)
Division function with a Tensor or a scalar. Same as cytnx::operator/(const Tensor &self,...
Definition Tensor.hpp:1382
Tensor Mod(const T &rhs)
Definition Tensor.hpp:1447
Tensor Cpr(const T &rhs)
The comparison function.
Definition Tensor.hpp:1404
Tensor & Inv_(const double &clip=-1.)
Apply the inverse on each entry of the Tensor.
Tensor & Exp_()
the Exp_ member function. Same as linalg::Exp_(Tensor &Tin), where Tin is the current Tensor.
Tensor & InvM_()
the InvM_ member function. Same as cytnx::linalg::InvM_(Tensor &Tin), where Tin is the current Tensor...
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:609
Tensor Min() const
the Min member function. Same as linalg::Min(const Tensor &Tin), where Tin is the current Tensor.
const T & at(const std::vector< cytnx_uint64 > &locator) const
Definition Tensor.hpp:973
Storage & storage() const
return the storage of current Tensor.
Definition Tensor.hpp:1171
static Tensor from_storage(const Storage &in)
Convert a Storage to Tensor.
Definition Tensor.hpp:569
Tensor & Sub_(const T &rhs)
Subtraction function with a Tensor or a scalar, inplacely. Same as operator-=(const T &rhs).
Definition Tensor.hpp:1351
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:115
Definition Accessor.hpp:12
cytnx::UniTensor operator*(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The multiplication operator between two UniTensor.
cytnx::UniTensor operator-(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The subtraction operator between two UniTensor.
cytnx::UniTensor operator+(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The addition operator between two UniTensor.
cytnx::UniTensor operator/(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The division operator between two UniTensor.