Cytnx v0.9.3
Loading...
Searching...
No Matches
Tensor.hpp
Go to the documentation of this file.
1#ifndef _H_Tensor_
2#define _H_Tensor_
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) {
64 Tensor tmp = Tensor(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::cout << e1 << std::endl;
236 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
237 return (*this)[tmp];
238 }
239 template <class... Ts>
240 Tproxy operator()(const cytnx_int64 &e1, const Ts &...elems) {
241 // std::cout << e1<< std::endl;
242 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
243 return (*this)[tmp];
244 }
245 template <class... Ts>
246 Tproxy operator()(const cytnx::Accessor &e1, const Ts &...elems) {
247 // std::cout << e1 << std::endl;
248 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
249 return (*this)[tmp];
250 }
251 template <class... Ts>
252 const Tproxy operator()(const std::string &e1, const Ts &...elems) const {
253 // std::cout << e1 << std::endl;
254 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
255 return (*this)[tmp];
256 }
257 template <class... Ts>
258 const Tproxy operator()(const cytnx_int64 &e1, const Ts &...elems) const {
259 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
260 return (*this)[tmp];
261 }
262 template <class... Ts>
263 const Tproxy operator()(const cytnx::Accessor &e1, const Ts &...elems) const {
264 std::vector<cytnx::Accessor> tmp = Indices_resolver(e1, elems...);
265 return (*this)[tmp];
266 }
267
268 //-----------------------------------------
269
270 Tproxy operator[](const std::initializer_list<cytnx::Accessor> &accs) {
271 std::vector<cytnx::Accessor> tmp = accs;
272 return (*this)[tmp];
273 }
274 Tproxy operator[](const std::vector<cytnx::Accessor> &accs) {
275 return Tproxy(this->_impl, accs);
276 }
277
278 const Tproxy operator[](const std::vector<cytnx::Accessor> &accs) const {
279 return Tproxy(this->_impl, accs);
280 }
281 const Tproxy operator[](const std::initializer_list<cytnx::Accessor> &accs) const {
282 std::vector<cytnx::Accessor> tmp = accs;
283 return (*this)[tmp];
284 }
285
286 Tproxy operator[](const std::initializer_list<cytnx_int64> &accs) {
287 std::vector<cytnx_int64> tmp = accs;
288 return (*this)[tmp];
289 }
290 Tproxy operator[](const std::vector<cytnx_int64> &accs) {
291 std::vector<cytnx::Accessor> acc_in;
292 for (int i = 0; i < accs.size(); i++) {
293 acc_in.push_back(cytnx::Accessor(accs[i]));
294 }
295 return Tproxy(this->_impl, acc_in);
296 }
297 const Tproxy operator[](const std::initializer_list<cytnx_int64> &accs) const {
298 std::vector<cytnx_int64> tmp = accs;
299 return (*this)[tmp];
300 }
301 const Tproxy operator[](const std::vector<cytnx_uint64> &accs) const {
302 std::vector<cytnx::Accessor> acc_in;
303 for (int i = 0; i < accs.size(); i++) {
304 acc_in.push_back(cytnx::Accessor(accs[i]));
305 }
306 return Tproxy(this->_impl, acc_in);
307 }
308 const Tproxy operator[](const std::vector<cytnx_int64> &accs) const {
309 std::vector<cytnx::Accessor> acc_in;
310 for (int i = 0; i < accs.size(); i++) {
311 acc_in.push_back(cytnx::Accessor(accs[i]));
312 }
313 return Tproxy(this->_impl, acc_in);
314 }
316 //-------------------------------------------
317
319 void _Save(std::fstream &f) const;
320 void _Load(std::fstream &f);
321
323
332 void Save(const std::string &fname) const;
336 void Save(const char *fname) const;
337
346 void Tofile(const std::string &fname) const;
347
351 void Tofile(const char *fname) const;
352
356 void Tofile(std::fstream &f) const;
357
366 static Tensor Load(const std::string &fname);
370 static Tensor Load(const char *fname);
371
392 static Tensor Fromfile(const std::string &fname, const unsigned int &dtype,
393 const cytnx_int64 &count = -1);
394 static Tensor Fromfile(const char *fname, const unsigned int &dtype,
395 const cytnx_int64 &count = -1);
396
397 // static Tensor Frombinary(const std::string &fname);
398
400 boost::intrusive_ptr<Tensor_impl> _impl;
401 Tensor() : _impl(new Tensor_impl()){};
402 Tensor(const Tensor &rhs) { _impl = rhs._impl; }
403
404 /*
405 template<class Tp>
406 Tensor(const std::initializer_list<Tp> &rhs){
407 Storage stmp = std::vector<Tp>(rhs);
408 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
409 tmp->Init(stmp);
410 this->_impl = tmp;
411 }
412 */
413
414 Tensor &operator=(const Tensor &rhs) {
415 _impl = rhs._impl;
416 return *this;
417 }
418
419 void operator=(const Tproxy &rhsp) { // this is used to handle proxy assignment
420 this->_impl = rhsp._insimpl->get(rhsp._accs);
421 }
423
425 // default device==Device.cpu (-1)
450 void Init(const std::vector<cytnx_uint64> &shape, const unsigned int &dtype = Type.Double,
451 const int &device = -1, const bool &init_zero = true) {
452 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
453 this->_impl = tmp;
454 this->_impl->Init(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, const unsigned int &dtype = Type.Double,
481 const int &device = -1, const bool &init_zero = 1)
482 : _impl(new Tensor_impl()) {
483 this->Init(shape, dtype, device, init_zero);
484 }
485 // Tensor(const Storage& storage)
486 // : _impl(new Tensor_impl()) {
487 // this->Init(storage);
488 // }
489 // Tensor(const Storage& storage, const std::vector<cytnx_uint64> &shape,
490 // const unsigned int &dtype = Type.Double, const int &device = -1)
491 // : _impl(new Tensor_impl()) {
492 // this->Init(storage, shape, dtype, device);
493 // }
495
501 static Tensor from_storage(const Storage &in) {
502 Tensor out;
503 boost::intrusive_ptr<Tensor_impl> tmp(new Tensor_impl());
504 out._impl = tmp;
505 out._impl->Init(in);
506 return out;
507 }
508
514 unsigned int dtype() const { return this->_impl->dtype(); }
515
521 int device() const { return this->_impl->device(); }
522
528 std::string dtype_str() const { return this->_impl->dtype_str(); }
529
535 std::string device_str() const { return this->_impl->device_str(); }
536
541 const std::vector<cytnx_uint64> &shape() const { return this->_impl->shape(); }
542
547 cytnx_uint64 rank() const { return this->_impl->shape().size(); }
548
566 Tensor clone() const {
567 Tensor out;
568 out._impl = this->_impl->clone();
569 return out;
570 }
571
592 Tensor to(const int &device) const {
593 Tensor out;
594 out._impl = this->_impl->to(device);
595 return out;
596 }
597
615 void to_(const int &device) { this->_impl->to_(device); }
616
621 const bool &is_contiguous() const { return this->_impl->is_contiguous(); }
622
623 Tensor permute_(const std::vector<cytnx_uint64> &rnks) {
624 this->_impl->permute_(rnks);
625 return *this;
626 }
628 template <class... Ts>
629 Tensor permute_(const cytnx_uint64 &e1, const Ts &...elems) {
630 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
631 this->_impl->permute_(argv);
632 return *this;
633 }
635
654 Tensor permute(const std::vector<cytnx_uint64> &rnks) const {
655 Tensor out;
656 out._impl = this->_impl->permute(rnks);
657 return out;
658 }
660 template <class... Ts>
661 Tensor permute(const cytnx_uint64 &e1, const Ts &...elems) const {
662 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
663 return this->permute(argv);
664 }
666
683 Tensor out;
684 out._impl = this->_impl->contiguous();
685 return out;
686 }
687
703 this->_impl->contiguous_();
704 return *this;
705 }
706
728 void reshape_(const std::vector<cytnx_int64> &new_shape) { this->_impl->reshape_(new_shape); }
730 void reshape_(const std::vector<cytnx_uint64> &new_shape) {
731 std::vector<cytnx_int64> shape(new_shape.begin(), new_shape.end());
732 this->_impl->reshape_(shape);
733 }
734 void reshape_(const std::initializer_list<cytnx_int64> &new_shape) {
735 std::vector<cytnx_int64> shape = new_shape;
736 this->_impl->reshape_(shape);
737 }
738 template <class... Ts>
739 void reshape_(const cytnx_int64 &e1, const Ts... elems) {
740 std::vector<cytnx_int64> shape = dynamic_arg_int64_resolver(e1, elems...);
741 // std::cout << shape << std::endl;
742 this->_impl->reshape_(shape);
743 }
745
770 Tensor reshape(const std::vector<cytnx_int64> &new_shape) const {
771 Tensor out;
772 out._impl = this->_impl->reshape(new_shape);
773 return out;
774 }
775
779 Tensor reshape(const std::vector<cytnx_uint64> &new_shape) const {
780 std::vector<cytnx_int64> tmp(new_shape.size());
781 memcpy(&tmp[0], &new_shape[0], sizeof(cytnx_uint64) * new_shape.size());
782 Tensor out;
783 out._impl = this->_impl->reshape(tmp);
784 return out;
785 }
786
790 Tensor reshape(const std::initializer_list<cytnx_int64> &new_shape) const {
791 return this->reshape(std::vector<cytnx_int64>(new_shape));
792 }
793
795 template <class... Ts>
796 Tensor reshape(const cytnx_int64 &e1, const Ts &...elems) const {
797 std::vector<cytnx_int64> argv = dynamic_arg_int64_resolver(e1, elems...);
798 return this->reshape(argv);
799 }
801
823 Tensor astype(const int &new_type) const {
824 Tensor out;
825 out._impl = this->_impl->astype(new_type);
826 return out;
827 }
828
829 // Tensor diagonal(){
830 // for(unsigned int i=0;i<this->shape().size();i++){
831 // if(this->shape()[i] != this->shape()[0],"[ERROR] Tensor.diagonal() can only be called
832 // when the subject has equal dimension in each rank.%s","\n");
833 // }
834 //
835 // }
836
857 template <class T>
858 T &at(const std::vector<cytnx_uint64> &locator) {
859 return this->_impl->at<T>(locator);
860 }
861
865 template <class T>
866 const T &at(const std::vector<cytnx_uint64> &locator) const {
867 return this->_impl->at<T>(locator);
868 }
870 template <class T, class... Ts>
871 const T &at(const cytnx_uint64 &e1, const Ts &...elems) const {
872 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
873 return this->at<T>(argv);
874 }
875 template <class T, class... Ts>
876 T &at(const cytnx_uint64 &e1, const Ts &...elems) {
877 std::vector<cytnx_uint64> argv = dynamic_arg_uint64_resolver(e1, elems...);
878 return this->at<T>(argv);
879 }
880
881 const Scalar::Sproxy at(const std::vector<cytnx_uint64> &locator) const {
882 return this->_impl->at(locator);
883 }
884
885 Scalar::Sproxy at(const std::vector<cytnx_uint64> &locator) { return this->_impl->at(locator); }
887
913 template <class T>
914 T &item() {
915 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item<T>]%s",
916 "item can only be called from a Tensor with only one element\n");
917 return this->_impl->storage().at<T>(0);
918 }
919
921 template <class T>
922 const T &item() const {
923 cytnx_error_msg(this->_impl->storage().size() != 1, "[ERROR][Tensor.item<T>]%s",
924 "item can only be called from a Tensor with only one element\n");
925 return this->_impl->storage().at<T>(0);
926 }
927
928 const Scalar::Sproxy item() const {
929 Scalar::Sproxy out(this->storage()._impl, 0);
930 return out;
931 }
932
933 Scalar::Sproxy item() {
934 Scalar::Sproxy out(this->storage()._impl, 0);
935 return out;
936 }
937
939
961 Tensor get(const std::vector<cytnx::Accessor> &accessors) const {
962 Tensor out;
963 out._impl = this->_impl->get(accessors);
964 return out;
965 }
966
967 /*
968 Tensor get_v2(const std::vector<cytnx::Accessor> &accessors) const{
969 Tensor out;
970 out._impl = this->_impl->get_v2(accessors);
971 return out;
972 }
973 */
974
993 void set(const std::vector<cytnx::Accessor> &accessors, const Tensor &rhs) {
994 this->_impl->set(accessors, rhs._impl);
995 }
996
1015 template <class T>
1016 void set(const std::vector<cytnx::Accessor> &accessors, const T &rc) {
1017 this->_impl->set(accessors, rc);
1018 }
1020 template <class T>
1021 void set(const std::initializer_list<cytnx::Accessor> &accessors, const T &rc) {
1022 std::vector<cytnx::Accessor> args = accessors;
1023 this->set(args, rc);
1024 }
1026
1036 Storage &storage() const { return this->_impl->storage(); }
1037
1052 template <class T>
1053 void fill(const T &val) {
1054 this->_impl->fill(val);
1055 }
1056
1061 bool equivshape(const Tensor &rhs) {
1062 if (this->shape() != rhs.shape()) return false;
1063 return true;
1064 }
1065
1074
1083
1084 // Arithmic:
1101 template <class T>
1103
1120 template <class T>
1122
1139 template <class T>
1141
1159 template <class T>
1161
1162 // Tensor &operator+=(const Tproxy &rc);
1163 // Tensor &operator-=(const Tproxy &rc);
1164 // Tensor &operator*=(const Tproxy &rc);
1165 // Tensor &operator/=(const Tproxy &rc);
1166 /*
1167 Tensor operator+(const Tproxy &rc){
1168 return *this + Tensor(rc);
1169 }
1170 Tensor operator-(const Tproxy &rc){
1171 return *this - Tensor(rc);
1172 }
1173 Tensor operator*(const Tproxy &rc){
1174 return *this * Tensor(rc);
1175 }
1176 Tensor operator/(const Tproxy &rc){
1177 return *this / Tensor(rc);
1178 }
1179 */
1185 template <class T>
1186 Tensor Add(const T &rhs) {
1187 return *this + rhs;
1188 }
1189
1195 template <class T>
1196 Tensor &Add_(const T &rhs) {
1197 return *this += rhs;
1198 }
1199
1205 template <class T>
1206 Tensor Sub(const T &rhs) {
1207 return *this - rhs;
1208 }
1209
1215 template <class T>
1216 Tensor &Sub_(const T &rhs) {
1217 return *this -= rhs;
1218 }
1219
1225 template <class T>
1226 Tensor Mul(const T &rhs) {
1227 return *this * rhs;
1228 }
1229
1235 template <class T>
1236 Tensor &Mul_(const T &rhs) {
1237 return *this *= rhs;
1238 }
1239
1246 template <class T>
1247 Tensor Div(const T &rhs) {
1248 return *this / rhs;
1249 }
1250
1257 template <class T>
1258 Tensor &Div_(const T &rhs) {
1259 return *this /= rhs;
1260 }
1261
1268 template <class T>
1269 Tensor Cpr(const T &rhs) {
1270 return *this == rhs;
1271 }
1272
1273 // /**
1274 // * @brief Compare each element of the current tensor with the input tensor.
1275 // * @details This function Compare each element of the current tensor with the input tensor.
1276 // * @param[in] rhs the compared tensor.
1277 // */
1278 // bool approx_eq(const Tensor &rhs, const cytnx_double tol = 0) {
1279 // if (this->device() != rhs.device()) {
1280 // if (User_debug)
1281 // std::cout << "[approx_eq] Tensor device " << this->device()
1282 // << "not equal to rhs tensor device " << rhs.device() << std::endl;
1283 // return false;
1284 // }
1285 // // if (this->dtype() != rhs.dtype()) {
1286 // // std::cout << "[approx_eq] Tensor dtype " << this->dtype()
1287 // // << "not equal to rhs tensor dtype " << rhs.dtype() << std::endl;
1288 // // return false;
1289 // // }
1290 // if (this->shape() != rhs.shape()) {
1291 // if (User_debug)
1292 // std::cout << "[approx_eq] Tensor shape " << this->shape()
1293 // << "not equal to rhs tensor shape " << rhs.shape() << std::endl;
1294 // return false;
1295 // }
1296 // if (this->is_contiguous() != rhs.is_contiguous()) {
1297 // if (User_debug)
1298 // std::cout << "[AreNearlyEqTensor] Tensor contiguous flag " << this->is_contiguous()
1299 // << "not equal to rhs tensor flag " << rhs.is_contiguous() << std::endl;
1300 // return false;
1301 // }
1302 // return this->_impl->_storage.approx_eq(rhs._impl->_storage._impl, tol);
1303 // }
1304
1305 // template<class T>
1306 // Tensor& Cpr_(const T &rhs){
1307 //
1308 // return *this == rhs;
1309 // }
1310
1311 template <class T>
1312 Tensor Mod(const T &rhs) {
1313 return *this % rhs;
1314 }
1315
1322 Tensor operator-() { return this->Mul(-1.); }
1323
1331 Tensor flatten() const {
1332 Tensor out = this->clone();
1333 out.contiguous_();
1334 out.reshape_({-1});
1335 return out;
1336 }
1337
1345 void flatten_() {
1346 this->contiguous_();
1347 this->reshape_({-1});
1348 }
1349
1376 void append(const Tensor &rhs) {
1377 // Tensor in;
1378 if (!this->is_contiguous()) this->contiguous_();
1379
1380 // check Tensor in shape:
1381 cytnx_error_msg(rhs.shape().size() == 0 || this->shape().size() == 0,
1382 "[ERROR] try to append a null Tensor.%s", "\n");
1383 cytnx_error_msg(rhs.shape().size() != (this->shape().size() - 1),
1384 "[ERROR] try to append a Tensor with rank not match.%s", "\n");
1385 cytnx_uint64 Nelem = 1;
1386 for (unsigned int i = 0; i < rhs.shape().size(); i++) {
1387 cytnx_error_msg(rhs.shape()[i] != this->shape()[i + 1],
1388 "[ERROR] dimension mismatch @ rhs.rank: [%d] this: [%d] rhs: [%d]\n", i,
1389 this->shape()[i + 1], rhs.shape()[i]);
1390 Nelem *= rhs.shape()[i];
1391 }
1392
1393 // check type:
1394 Tensor in;
1395 if (rhs.dtype() != this->dtype()) {
1396 in = rhs.astype(this->dtype());
1397 if (!in.is_contiguous()) in.contiguous_();
1398 } else {
1399 if (!in.is_contiguous())
1400 in = rhs.contiguous();
1401 else
1402 in = rhs;
1403 }
1404 this->_impl->_shape[0] += 1;
1405 cytnx_uint64 oldsize = this->_impl->_storage.size();
1406 this->_impl->_storage.resize(oldsize + Nelem);
1407 memcpy(((char *)this->_impl->_storage.data()) +
1408 oldsize * Type.typeSize(this->dtype()) / sizeof(char),
1409 in._impl->_storage.data(), Type.typeSize(in.dtype()) * Nelem);
1410 }
1438 void append(const Storage &srhs) {
1439 if (!this->is_contiguous()) this->contiguous_();
1440
1441 // check Tensor in shape:
1442 cytnx_error_msg(srhs.size() == 0 || this->shape().size() == 0,
1443 "[ERROR] try to append a null Tensor.%s", "\n");
1444 cytnx_error_msg((this->shape().size() - 1) != 1,
1445 "[ERROR] append a storage to Tensor can only accept rank-2 Tensor.%s", "\n");
1446 cytnx_error_msg(this->shape().back() != srhs.size(), "[ERROR] Tensor dmension mismatch!%s",
1447 "\n");
1448
1449 // check type:
1450 Storage in;
1451 if (srhs.dtype() != this->dtype()) {
1452 in = srhs.astype(this->dtype());
1453 } else {
1454 in = srhs;
1455 }
1456 this->_impl->_shape[0] += 1;
1457 cytnx_uint64 oldsize = this->_impl->_storage.size();
1458 this->_impl->_storage.resize(oldsize + in.size());
1459 memcpy(((char *)this->_impl->_storage.data()) +
1460 oldsize * Type.typeSize(this->dtype()) / sizeof(char),
1461 in._impl->Mem, Type.typeSize(in.dtype()) * in.size());
1462 }
1463 /*
1464 void append(const Tensor &rhs){
1465 // convert to the same type.
1466 Tensor in;
1467 if(rhs.dtype() != this->dtype()){
1468 in = rhs.astype(this->dtype());
1469 }else{
1470 in = rhs;
1471 }
1472
1473 // 1) check rank
1474 if(this->shape().size()==1){
1475 // check if rhs is a scalar tensor (only one element)
1476 cytnx_error_msg(!(rhs.shape().size()==1 && rhs.shape()[0]==1),"[ERROR] trying to append
1477 a scalar into multidimentional Tensor is not allow.\n Only rank-1 Tensor can accept scalar
1478 append.%s","\n"); this->_impl->_shape[0]+=1; this->_impl->_storage.append(0);
1479
1480 }else{
1481 cytnx_error_msg(rhs.shape().size() != this->shape().size()-1,"[ERROR] try to append a
1482 Tensor with rank not match.%s","\n");
1483
1484 }
1485 cytnx_error_msg(!this->is_contiguous(),"[ERROR] append require the Tensor to be contiguous.
1486 suggestion: call contiguous() or contiguous_() first.","\n");
1487 }
1488 */
1500 template <class T>
1501 void append(const T &rhs) {
1502 cytnx_error_msg(this->shape().size() != 1,
1503 "[ERROR] trying to append a scalar into multidimentional Tensor is not "
1504 "allow.\n Only rank-1 Tensor can accept scalar append.%s",
1505 "\n");
1507 "[ERROR] append require the Tensor to be contiguous. suggestion: call "
1508 "contiguous() or contiguous_() first.",
1509 "\n");
1510 this->_impl->_shape[0] += 1;
1511 this->_impl->_storage.append(rhs);
1512 }
1513
1522 bool same_data(const Tensor &rhs) const;
1523
1524 // linalg:
1530 std::vector<Tensor> Svd(const bool &is_UvT = true) const;
1531
1537 std::vector<Tensor> Eigh(const bool &is_V = true, const bool &row_v = false) const;
1538
1544
1549 Tensor InvM() const;
1550
1555 Tensor &Inv_(const double &clip);
1556
1561 Tensor Inv(const double &clip) const;
1562
1568
1573 Tensor Conj() const;
1574
1580
1585 Tensor Exp() const;
1586
1591 Tensor Norm() const;
1592
1597 Tensor Pow(const cytnx_double &p) const;
1598
1604
1609 Tensor Trace(const cytnx_uint64 &a = 0, const cytnx_uint64 &b = 1) const;
1610
1615 Tensor Abs() const;
1616
1622
1627 Tensor Max() const;
1628
1633 Tensor Min() const;
1634
1635 }; // class Tensor
1636
1637 Tensor operator+(const Tensor &lhs, const Tensor::Tproxy &rhs);
1638 Tensor operator-(const Tensor &lhs, const Tensor::Tproxy &rhs);
1639 Tensor operator*(const Tensor &lhs, const Tensor::Tproxy &rhs);
1640 Tensor operator/(const Tensor &lhs, const Tensor::Tproxy &rhs);
1641
1642 Tensor operator+(const Tensor &lhs, const Scalar::Sproxy &rhs);
1643 Tensor operator-(const Tensor &lhs, const Scalar::Sproxy &rhs);
1644 Tensor operator*(const Tensor &lhs, const Scalar::Sproxy &rhs);
1645 Tensor operator/(const Tensor &lhs, const Scalar::Sproxy &rhs);
1646
1648 std::ostream &operator<<(std::ostream &os, const Tensor &in);
1649 std::ostream &operator<<(std::ostream &os, const Tensor::Tproxy &in);
1651 //{ os << Tensor(in);};
1652} // namespace cytnx
1653
1654#endif // BACKEND_TORCH
1655
1656#endif
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:1438
Tensor & operator*=(const T &rc)
multiplication assignment operator with a Tensor or a scalar.
Tensor & Inv_(const double &clip)
the Inv_ member function. Same as cytnx::linalg::Inv_(Tensor &Tin, const double &clip)
Tensor & operator/=(const T &rc)
division assignment operator with a Tensor or a scalar.
Tensor operator-()
The negation function.
Definition Tensor.hpp:1322
void fill(const T &val)
fill all the element of current Tensor with the value.
Definition Tensor.hpp:1053
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:615
Tensor reshape(const std::vector< cytnx_uint64 > &new_shape) const
Definition Tensor.hpp:779
Tensor(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1, const bool &init_zero=1)
Construct a new Tensor object.
Definition Tensor.hpp:480
void append(const T &rhs)
the append function of the scalar.
Definition Tensor.hpp:1501
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:1196
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:790
std::string device_str() const
the device (in string) of the Tensor
Definition Tensor.hpp:535
void reshape_(const std::vector< cytnx_int64 > &new_shape)
reshape the Tensor, inplacely
Definition Tensor.hpp:728
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:702
Tensor permute_(const std::vector< cytnx_uint64 > &rnks)
Definition Tensor.hpp:623
Tensor Mul(const T &rhs)
Multiplication function with a Tensor or a scalar. Same as cytnx::operator*(const Tensor &self,...
Definition Tensor.hpp:1226
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:514
Tensor Sub(const T &rhs)
Subtraction function with a Tensor or a scalar. Same as cytnx::operator-(const Tensor &self,...
Definition Tensor.hpp:1206
Tensor Inv(const double &clip) const
the Inv member function. Same as cytnx::linalg::Inv(const Tensor &Tin, const double &clip)
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:682
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:858
Tensor reshape(const std::vector< cytnx_int64 > &new_shape) const
return a new Tensor that is reshaped.
Definition Tensor.hpp:770
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:914
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:566
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:1376
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:993
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:823
Tensor & Div_(const T &rhs)
Division function with a Tensor or a scalar, inplacely. Same as operator/=(const T &rhs).
Definition Tensor.hpp:1258
static Tensor Load(const std::string &fname)
Load current Tensor from file.
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 equivshape(const Tensor &rhs)
compare the shape of two tensors.
Definition Tensor.hpp:1061
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) ,...
std::string dtype_str() const
the dtype (in string) of the Tensor
Definition Tensor.hpp:528
Tensor & Mul_(const T &rhs)
Multiplication function with a Tensor or a scalar, inplacely. Same as operator*=(const T &rhs).
Definition Tensor.hpp:1236
cytnx_uint64 rank() const
the rank of the Tensor
Definition Tensor.hpp:547
const bool & is_contiguous() const
return whether the Tensor is contiguous or not.
Definition Tensor.hpp:621
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:1186
void flatten_()
The flatten function, inplacely.
Definition Tensor.hpp:1345
void Save(const std::string &fname) const
Save current Tensor to file.
Tensor flatten() const
The flatten function.
Definition Tensor.hpp:1331
Tensor & Conj_()
the Conj_ member function. Same as cytnx::linalg::Conj_(Tensor &Tin), where Tin is the current Tensor...
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:521
Tensor real()
return the real part of the tensor.
Tensor imag()
return the imaginary part of the tensor.
Tensor to(const int &device) const
copy a tensor to new device
Definition Tensor.hpp:592
void Tofile(std::fstream &f) const
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:961
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:1016
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:654
Tensor Div(const T &rhs)
Division function with a Tensor or a scalar. Same as cytnx::operator/(const Tensor &self,...
Definition Tensor.hpp:1247
Tensor Mod(const T &rhs)
Definition Tensor.hpp:1312
void Init(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1, const bool &init_zero=true)
initialize a Tensor
Definition Tensor.hpp:450
Tensor Cpr(const T &rhs)
The comparison function.
Definition Tensor.hpp:1269
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:541
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:866
Storage & storage() const
return the storage of current Tensor.
Definition Tensor.hpp:1036
static Tensor from_storage(const Storage &in)
Convert a Storage to Tensor.
Definition Tensor.hpp:501
Tensor & Sub_(const T &rhs)
Subtraction function with a Tensor or a scalar, inplacely. Same as operator-=(const T &rhs).
Definition Tensor.hpp:1216
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:16
Helper function to print vector with ODT:
Definition Accessor.hpp:12
cytnx::UniTensor operator*(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The multiplication operator between two UniTensor.
double cytnx_double
Definition Type.hpp:53
uint32_t cytnx_uint32
Definition Type.hpp:56
bool cytnx_bool
Definition Type.hpp:64
std::complex< double > cytnx_complex128
Definition Type.hpp:63
float cytnx_float
Definition Type.hpp:54
int16_t cytnx_int16
Definition Type.hpp:60
std::complex< float > cytnx_complex64
Definition Type.hpp:62
cytnx::UniTensor operator-(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The subtraction operator between two UniTensor.
int32_t cytnx_int32
Definition Type.hpp:59
uint16_t cytnx_uint16
Definition Type.hpp:57
uint64_t cytnx_uint64
Definition Type.hpp:55
int64_t cytnx_int64
Definition Type.hpp:58
Type_class Type
data type
cytnx::UniTensor operator+(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The addtion operator between two UniTensor.
cytnx::UniTensor operator/(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
The division operator between two UniTensor.