11#include "utils/vec_range.hpp"
12#include "utils/dynamic_arg_resolver.hpp"
16#include <initializer_list>
25 class Tensor_impl:
public intrusive_ptr_base<Tensor_impl>{
29 Storage_init_interface
__SII;
36 std::vector<cytnx_uint64> _shape;
39 std::vector<cytnx_uint64> _mapper;
40 std::vector<cytnx_uint64> _invmapper;
46 boost::intrusive_ptr<Tensor_impl> _clone_meta_only()
const{
47 boost::intrusive_ptr<Tensor_impl> out(
new Tensor_impl());
48 out->_mapper = this->_mapper;
49 out->_invmapper = this->_invmapper;
50 out->_shape = this->_shape;
51 out->_contiguous = this->_contiguous;
54 Tensor_impl(): _contiguous(true){};
56 void Init(
const std::vector<cytnx_uint64> &shape,
const unsigned int &dtype=
Type.Double,
int device=-1);
57 void Init(
const Storage &in);
69 Tensor_impl(
const Tensor_impl &rhs);
70 Tensor_impl& operator=(
const Tensor_impl &rhs);
72 unsigned int dtype()
const{
73 return this->_storage.dtype();
76 return this->_storage.device();
79 std::string dtype_str()
const {
80 return Type.getname(this->_storage.dtype());
82 std::string device_str()
const{
83 return Device.getname(this->_storage.device());
86 const std::vector<cytnx_uint64>& shape()
const{
90 const bool& is_contiguous()
const{
91 return this->_contiguous;
94 const std::vector<cytnx_uint64>& mapper()
const{
97 const std::vector<cytnx_uint64>& invmapper()
const{
98 return this->_invmapper;
104 const Storage& storage()
const{
108 boost::intrusive_ptr<Tensor_impl> clone()
const{
109 boost::intrusive_ptr<Tensor_impl> out = this->_clone_meta_only();
110 out->_storage = this->_storage.clone();
115 void to_(
const int &device){
116 this->_storage.to_(device);
118 boost::intrusive_ptr<Tensor_impl> to(
const int &device){
119 if(this->device()==device){
124 boost::intrusive_ptr<Tensor_impl> out = this->_clone_meta_only();
125 out->_storage = this->_storage.to(device);
130 void permute_(
const std::vector<cytnx_uint64> &rnks);
132 boost::intrusive_ptr<Tensor_impl> permute(
const std::vector<cytnx_uint64> &rnks);
135 T& at(
const std::vector<cytnx_uint64> &locator)
const {
136 cytnx_error_msg(locator.size() != this->_shape.size(),
"%s",
"The input index does not match Tensor's rank.");
139 std::vector<cytnx_uint64> c_shape(this->_shape.size());
140 std::vector<cytnx_uint64> c_loc(this->_shape.size());
145 for(cytnx_int64 i=this->_shape.size()-1; i>=0; i--){
146 if(locator[i]>=this->_shape[i]){
147 cytnx_error_msg(
true,
"%s",
"Attempting to access out-of-bound index in Tensor.");
149 c_shape[i] = this->_shape[this->_invmapper[i]];
150 c_loc[i] = locator[this->_invmapper[i]];
151 RealRank += mtplyr*c_loc[i];
152 mtplyr *= c_shape[i];
154 return this->_storage.at<T>(RealRank);
157 const Scalar::Sproxy at(
const std::vector<cytnx_uint64> &locator)
const{
158 cytnx_error_msg(locator.size() != this->_shape.size(),
"%s",
"The input index does not match Tensor's rank.");
161 std::vector<cytnx_uint64> c_shape(this->_shape.size());
162 std::vector<cytnx_uint64> c_loc(this->_shape.size());
167 for(cytnx_int64 i=this->_shape.size()-1; i>=0; i--){
168 if(locator[i]>=this->_shape[i]){
169 cytnx_error_msg(
true,
"%s",
"Attempting to access out-of-bound index in Tensor.");
171 c_shape[i] = this->_shape[this->_invmapper[i]];
172 c_loc[i] = locator[this->_invmapper[i]];
173 RealRank += mtplyr*c_loc[i];
174 mtplyr *= c_shape[i];
176 return this->_storage.at(RealRank);
179 Scalar::Sproxy at(
const std::vector<cytnx_uint64> &locator){
180 cytnx_error_msg(locator.size() != this->_shape.size(),
"%s",
"The input index does not match Tensor's rank.");
183 std::vector<cytnx_uint64> c_shape(this->_shape.size());
184 std::vector<cytnx_uint64> c_loc(this->_shape.size());
189 for(cytnx_int64 i=this->_shape.size()-1; i>=0; i--){
190 if(locator[i]>=this->_shape[i]){
191 cytnx_error_msg(
true,
"%s",
"Attempting to access out-of-bound index in Tensor.");
193 c_shape[i] = this->_shape[this->_invmapper[i]];
194 c_loc[i] = locator[this->_invmapper[i]];
195 RealRank += mtplyr*c_loc[i];
196 mtplyr *= c_shape[i];
198 return this->_storage.at(RealRank);
201 boost::intrusive_ptr<Tensor_impl> get(
const std::vector<cytnx::Accessor> &accessors);
202 boost::intrusive_ptr<Tensor_impl> get_deprecated(
const std::vector<cytnx::Accessor> &accessors);
203 void set(
const std::vector<cytnx::Accessor> &accessors,
const boost::intrusive_ptr<Tensor_impl> &rhs);
206 void set(
const std::vector<cytnx::Accessor> &accessors,
const T& rc);
208 void set(
const std::vector<cytnx::Accessor> &accessors,
const Scalar::Sproxy& rc);
211 void fill(
const Tx& val){
212 this->storage().fill(val);
215 boost::intrusive_ptr<Tensor_impl> contiguous(){
218 if(this->_contiguous){
219 boost::intrusive_ptr<Tensor_impl> out(
this);
223 boost::intrusive_ptr<Tensor_impl> out(
new Tensor_impl());
224 std::vector<cytnx_uint64> oldshape(this->_shape.size());
225 for(cytnx_uint64 i=0;i<this->_shape.size();i++){
226 oldshape[i] = this->_shape[this->_invmapper[i]];
229 out->_storage._impl = this->_storage._impl->Move_memory(oldshape,this->_mapper, this->_invmapper);
231 out->_invmapper = vec_range(this->_invmapper.size());
232 out->_mapper = out->_invmapper;
233 out->_shape = this->_shape;
234 out->_contiguous =
true;
242 if(!this->_contiguous){
243 std::vector<cytnx_uint64> oldshape(this->_shape.size());
244 for(cytnx_uint64 i=0;i<this->_shape.size();i++){
245 oldshape[i] = this->_shape[this->_invmapper[i]];
248 this->_storage._impl = this->_storage._impl->Move_memory(oldshape,this->_mapper, this->_invmapper);
249 this->_mapper = vec_range(this->_invmapper.size());
250 this->_invmapper = this->_mapper;
251 this->_contiguous =
true;
256 void reshape_(
const std::vector<cytnx_int64> &new_shape){
257 if(!this->_contiguous){
260 std::vector<cytnx_uint64> result_shape(new_shape.size());
262 bool has_undetermine =
false;
263 unsigned int Udet_id = 0;
264 for(
int i=0;i<new_shape.size();i++){
266 if(new_shape[i]!=-1)
cytnx_error_msg(new_shape[i]!=-1,
"%s",
"[ERROR] reshape can only have dimension > 0 and one undetermine rank specify as -1");
267 if(has_undetermine)
cytnx_error_msg(new_shape[i]!=-1,
"%s",
"[ERROR] reshape can only have dimension > 0 and one undetermine rank specify as -1");
269 has_undetermine =
true;
271 new_N *= new_shape[i];
272 result_shape[i] = new_shape[i];
278 cytnx_error_msg(new_N > this->_storage.size(),
"%s",
"[ERROR] new shape exceed the total number of elements.");
279 cytnx_error_msg(this->_storage.size()%new_N,
"%s",
"[ERROR] unmatch size when reshape with undetermine dimension");
280 result_shape[Udet_id] = this->_storage.size()/new_N;
282 cytnx_error_msg(new_N != this->_storage.size(),
"%s",
"[ERROR] new shape does not match the number of elements.");
285 this->_shape = result_shape;
286 this->_mapper = vec_range(result_shape.size());
287 this->_invmapper = this->_mapper;
291 boost::intrusive_ptr<Tensor_impl> reshape(
const std::vector<cytnx_int64> &new_shape){
292 boost::intrusive_ptr<Tensor_impl> out(
new Tensor_impl());
293 if(this->is_contiguous()){
294 out = this->_clone_meta_only();
295 out->_storage = this->_storage;
297 out = this->contiguous();
301 out->reshape_(new_shape);
307 boost::intrusive_ptr<Tensor_impl> astype(
const int& new_type){
310 if(this->dtype() == new_type){
313 boost::intrusive_ptr<Tensor_impl> out = this->_clone_meta_only();
314 out->_storage = this->_storage.astype(new_type);
326 template<
class T> Tensor
operator+(
const Tensor &lhs,
const T &rc);
327 template<
class T> Tensor
operator-(
const Tensor &lhs,
const T &rhs);
328 template<
class T> Tensor
operator*(
const Tensor &lhs,
const T &rhs);
329 template<
class T> Tensor
operator/(
const Tensor &lhs,
const T &rhs);
341 boost::intrusive_ptr<Tensor_impl>
_insimpl;
342 std::vector<cytnx::Accessor>
_accs;
352 const T& operator=(
const T &
rc){
358 this->_insimpl->set(
_accs,
tmp._impl);
502 Scalar::Sproxy
item()
const{
529 template<
class ...
Ts>
535 template<
class ...
Ts>
541 template<
class ...
Ts>
548 template<
class ...
Ts>
553 template<
class ...
Ts>
562 std::vector<cytnx::Accessor>
tmp =
accs;
574 std::vector<cytnx::Accessor>
tmp =
accs;
579 std::vector<cytnx_int64>
tmp =
accs;
583 std::vector<cytnx::Accessor>
acc_in;
584 for(
int i=0;
i<
accs.size();
i++){
590 std::vector<cytnx_int64>
tmp =
accs;
594 std::vector<cytnx::Accessor>
acc_in;
595 for(
int i=0;
i<
accs.size();
i++){
605 void _Save(std::fstream &
f)
const;
606 void _Load(std::fstream &
f);
617 void Save(
const std::string &
fname)
const;
640 boost::intrusive_ptr<Tensor_impl> _impl;
656 Tensor& operator=(
const Tensor &
rhs){
712 unsigned int dtype()
const {
return this->_impl->dtype();}
719 int device()
const {
return this->_impl->device();}
726 std::string
dtype_str()
const {
return this->_impl->dtype_str();}
733 std::string
device_str()
const{
return this->_impl->device_str();}
740 const std::vector<cytnx_uint64>&
shape()
const{
741 return this->_impl->shape();
749 return this->_impl->shape().size();
824 return this->_impl->is_contiguous();
832 template<
class ...
Ts>
835 this->_impl->permute_(
argv);
861 template<
class ...
Ts>
933 this->_impl->reshape_(
shape);
937 this->_impl->reshape_(
shape);
939 template<
class ...Ts>
943 this->_impl->reshape_(
shape);
970 template<
class ...
Ts>
1028 return this->_impl->at<
T>(
locator);
1032 return this->_impl->at<
T>(
locator);
1035 template<
class T,
class...Ts>
1038 return this->
at<T>(argv);
1040 template<
class T,
class...Ts>
1043 return this->
at<T>(argv);
1046 const Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator)
const{
1047 return this->_impl->at(
locator);
1050 Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator){
1051 return this->_impl->at(
locator);
1076 cytnx_error_msg(this->_impl->storage().size()!=1,
"[ERROR][Tensor.item<T>]%s",
"item can only be called from a Tensor with only one element\n");
1077 return this->_impl->storage().at<
T>(0);
1082 const T&
item()
const{
1083 cytnx_error_msg(this->_impl->storage().size()!=1,
"[ERROR][Tensor.item<T>]%s",
"item can only be called from a Tensor with only one element\n");
1084 return this->_impl->storage().at<
T>(0);
1087 const Scalar::Sproxy
item()
const{
1092 Scalar::Sproxy
item(){
1184 void set(
const std::initializer_list<cytnx::Accessor> &
accessors,
const T &
rc){
1199 return this->_impl->storage();
1219 this->_impl->fill(
val);
1224 if(this->
shape() != rhs.
shape())
return false;
1269 return *
this +=
rhs;
1278 return *
this -=
rhs;
1287 return *
this *=
rhs;
1296 return *
this /=
rhs;
1301 return *
this ==
rhs;
1316 return this->
Mul(-1.);
1340 cytnx_error_msg(
rhs.shape().size()!=(
this->shape().size()-1),
"[ERROR] try to append a Tensor with rank not match.%s",
"\n");
1342 for(
unsigned int i=0;
i<
rhs.shape().size();
i++){
1349 if(
rhs.dtype() !=
this->dtype()){
1354 if(!
in.is_contiguous())
1359 this->_impl->_shape[0]+=1;
1363 in._impl->_storage.data(),
1373 cytnx_error_msg((this->
shape().size()-1)!=1,
"[ERROR] append a storage to Tensor can only accept rank-2 Tensor.%s",
"\n");
1384 this->_impl->_shape[0]+=1;
1386 this->_impl->_storage.resize(
oldsize+
in.size());
1389 Type.typeSize(
in.dtype())*
in.size());
1418 cytnx_error_msg(this->
shape().size()!=1,
"[ERROR] trying to append a scalar into multidimentional Tensor is not allow.\n Only rank-1 Tensor can accept scalar append.%s",
"\n");
1419 cytnx_error_msg(!this->
is_contiguous(),
"[ERROR] append require the Tensor to be contiguous. suggestion: call contiguous() or contiguous_() first.",
"\n");
1420 this->_impl->_shape[0]+=1;
1421 this->_impl->_storage.append(
rhs);
1427 std::vector<Tensor>
Svd(
const bool &
is_U=
true,
const bool &
is_vT=
true)
const;
1428 std::vector<Tensor>
Eigh(
const bool &
is_V=
true,
const bool &
row_v=
false)
const;
1454 Tensor
operator+(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1455 Tensor
operator-(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1456 Tensor
operator*(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1457 Tensor
operator/(
const Tensor &lhs,
const Scalar::Sproxy &rhs);
1459 std::ostream&
operator<<(std::ostream& os,
const Tensor &in);
object that mimic the python slice to access elements in C++ [this is for c++ API only].
Definition Accessor.hpp:16
an memeory storage with multi-type/multi-device support
Definition Storage.hpp:934
Storage astype(const unsigned int &new_type) const
cast the type of current Storage
Definition Storage.hpp:1052
const unsigned long long & size() const
the size ( no. of elements ) in the Storage
Definition Storage.hpp:1201
an tensor (multi-dimensional array)
Definition Tensor.hpp:333
void append(const Storage &srhs)
Definition Tensor.hpp:1367
Tensor & operator*=(const T &rc)
Tensor & Inv_(const double &clip)
Definition Tensor.cpp:1171
Tensor & operator/=(const T &rc)
Tensor operator-()
Definition Tensor.hpp:1315
void fill(const T &val)
fill all the element of current Tensor with the value.
Definition Tensor.hpp:1218
Tensor InvM() const
Definition Tensor.cpp:1168
bool same_data(const Tensor &rhs) const
Definition Tensor.cpp:1227
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:819
void append(const T &rhs)
Definition Tensor.hpp:1417
Tensor & operator-=(const T &rc)
Tensor & Add_(const T &rhs)
Definition Tensor.hpp:1268
Tensor Abs() const
Definition Tensor.cpp:1212
std::string device_str() const
the device (in string) of the Tensor
Definition Tensor.hpp:733
void reshape_(const std::vector< cytnx_int64 > &new_shape)
reshape the Tensor, inplacely
Definition Tensor.hpp:927
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:906
static Tensor Load(const std::string &fname)
Load current Tensor to file.
Definition Tensor.cpp:847
Tensor permute_(const std::vector< cytnx_uint64 > &rnks)
Definition Tensor.hpp:827
Tensor Mul(const T &rhs)
Definition Tensor.hpp:1282
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:712
Tensor Sub(const T &rhs)
Definition Tensor.hpp:1273
Tensor Inv(const double &clip) const
Definition Tensor.cpp:1175
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:885
void Tofile(const std::string &fname) const
Definition Tensor.cpp:772
T & at(const std::vector< cytnx_uint64 > &locator)
[C++ only] get an element at specific location.
Definition Tensor.hpp:1027
Tensor reshape(const std::vector< cytnx_int64 > &new_shape) const
return a new Tensor that is reshaped.
Definition Tensor.hpp:964
T & item()
get an from a rank-0 Tensor
Definition Tensor.hpp:1075
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:770
std::vector< Tensor > Eigh(const bool &is_V=true, const bool &row_v=false) const
Definition Tensor.cpp:1159
void append(const Tensor &rhs)
Definition Tensor.hpp:1333
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:1155
Tensor Norm() const
Definition Tensor.cpp:1195
Tensor astype(const int &new_type) const
return a new Tensor that cast to different dtype.
Definition Tensor.hpp:995
Tensor & Div_(const T &rhs)
Definition Tensor.hpp:1295
Tensor & operator+=(const T &rc)
Tensor Conj() const
Definition Tensor.cpp:1184
Tensor Trace(const cytnx_uint64 &a=0, const cytnx_uint64 &b=1) const
Definition Tensor.cpp:1222
Tensor & Pow_(const cytnx_double &p)
Definition Tensor.cpp:1203
std::string dtype_str() const
the dtype (in string) of the Tensor
Definition Tensor.hpp:726
Tensor & Mul_(const T &rhs)
Definition Tensor.hpp:1286
cytnx_uint64 rank() const
the rank of the Tensor
Definition Tensor.hpp:748
const bool & is_contiguous() const
Definition Tensor.hpp:823
Tensor Exp() const
Definition Tensor.cpp:1192
Tensor & Abs_()
Definition Tensor.cpp:1208
Tensor Add(const T &rhs)
Definition Tensor.hpp:1264
void flatten_()
Definition Tensor.hpp:1326
void Save(const std::string &fname) const
Save current Tensor to file.
Definition Tensor.cpp:798
Tensor flatten() const
Definition Tensor.hpp:1319
Tensor & Conj_()
Definition Tensor.cpp:1180
Tensor Pow(const cytnx_double &p) const
Definition Tensor.cpp:1199
int device() const
the device-id of the Tensor
Definition Tensor.hpp:719
Tensor real()
Definition Tensor.cpp:898
Tensor imag()
Definition Tensor.cpp:905
Tensor to(const int &device) const
copy a tensor to new device
Definition Tensor.hpp:796
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:1122
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:1179
Tensor Max() const
Definition Tensor.cpp:1215
Tensor permute(const std::vector< cytnx_uint64 > &rnks) const
perform tensor permute on the cytnx::Tensor and return a new instance.
Definition Tensor.hpp:855
Tensor Div(const T &rhs)
Definition Tensor.hpp:1291
Tensor Mod(const T &rhs)
Definition Tensor.hpp:1311
bool equiv(const Tensor &rhs)
Definition Tensor.hpp:1223
Tensor Cpr(const T &rhs)
Definition Tensor.hpp:1300
Tensor & Exp_()
Definition Tensor.cpp:1188
Tensor & InvM_()
Definition Tensor.cpp:1164
std::vector< Tensor > Svd(const bool &is_U=true, const bool &is_vT=true) const
Definition Tensor.cpp:1156
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:740
Tensor Min() const
Definition Tensor.cpp:1218
const T & at(const std::vector< cytnx_uint64 > &locator) const
Definition Tensor.hpp:1031
Storage & storage() const
return the storage of current Tensor.
Definition Tensor.hpp:1198
static Tensor from_storage(const Storage &in)
Definition Tensor.hpp:698
static Tensor Fromfile(const std::string &fname, const unsigned int &dtype, const cytnx_int64 &count=-1)
Definition Tensor.cpp:841
void Init(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1)
initialize a Tensor
Definition Tensor.hpp:688
Tensor(const std::vector< cytnx_uint64 > &shape, const unsigned int &dtype=Type.Double, const int &device=-1)
Definition Tensor.hpp:693
Tensor & Sub_(const T &rhs)
Definition Tensor.hpp:1277
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:18
Definition Accessor.hpp:12
Device_class Device
Definition Device.cpp:105
cytnx::UniTensor operator*(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
double cytnx_double
Definition Type.hpp:20
uint32_t cytnx_uint32
Definition Type.hpp:23
bool cytnx_bool
Definition Type.hpp:31
std::complex< double > cytnx_complex128
Definition Type.hpp:30
float cytnx_float
Definition Type.hpp:21
std::ostream & operator<<(std::ostream &os, const Scalar &in)
Definition Scalar.cpp:14
int16_t cytnx_int16
Definition Type.hpp:27
std::complex< float > cytnx_complex64
Definition Type.hpp:29
cytnx::UniTensor operator-(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
int32_t cytnx_int32
Definition Type.hpp:26
uint16_t cytnx_uint16
Definition Type.hpp:24
uint64_t cytnx_uint64
Definition Type.hpp:22
int64_t cytnx_int64
Definition Type.hpp:25
Storage_init_interface __SII
Definition Storage.cpp:13
Type_class Type
Definition Type.cpp:137
cytnx::UniTensor operator+(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)
cytnx::UniTensor operator/(const cytnx::UniTensor &Lt, const cytnx::UniTensor &Rt)