16#include <initializer_list>
25 using namespace cytnx;
27 class UniTensorType_class{
34 std::string getname(
const int &ut_type);
42 class UniTensor_base:
public intrusive_ptr_base<UniTensor_base>{
51 std::vector<cytnx_int64> _labels;
52 std::vector< Bond > _bonds;
56 bool _update_braket(){
57 if(_bonds.size()==0)
return false;
59 if(this->_bonds[0].type()!= bondType::BD_REG){
61 for(
unsigned int i=0;i<this->_bonds.size();i++){
63 if(this->_bonds[i].type()!=bondType::BD_KET)
return false;
65 if(this->_bonds[i].type()!=bondType::BD_BRA)
return false;
75 friend class DenseUniTensor;
76 friend class SparseUniTensor;
78 UniTensor_base(): _is_tag(false), _name(std::string(
"")), _is_braket_form(false), _rowrank(-1), _is_diag(false), uten_type_id(
UTenType.Void){};
81 UniTensor_base(
const UniTensor_base &rhs);
82 UniTensor_base& operator=(UniTensor_base &rhs);
85 bool is_diag()
const{
return this->_is_diag; }
86 const bool& is_braket_form()
const{
87 return this->_is_braket_form;
89 const bool& is_tag()
const{
92 const std::vector<cytnx_int64>& labels()
const{
return this->_labels;}
93 const std::vector<Bond> &bonds()
const {
return this->_bonds;}
94 std::vector<Bond> &bonds(){
return this->_bonds;}
95 const std::string& name()
const {
return this->_name;}
97 void set_name(
const std::string &in){ this->_name = in;}
99 cytnx_error_msg(idx>=this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
"\n");
104 if(new_label == this->_labels[i]){is_dup =
true;
break;}
106 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
"\n");
107 this->_labels[idx] = new_label;
109 void set_labels(
const std::vector<cytnx_int64> &new_labels);
114 T& at(
const std::vector<cytnx_uint64> &locator){
116 if(this->is_blockform()){
117 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] UniTensor with Symmetry cannot get element with at(). Use get_elem()/set_elem() instead.%s",
"\n");
119 return this->get_block_().at<T>(locator);
125 const T& at(
const std::vector<cytnx_uint64> &locator)
const{
127 if(this->is_blockform()){
128 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] UniTensor with Symmetry cannot get element with at(). Use get_elem()/set_elem() instead.%s",
"\n");
130 return this->get_block_().at<T>(locator);
137 T get_elem(
const std::vector<cytnx_uint64> &locator)
const{
138 if(this->is_blockform()){
139 if(this->elem_exists(locator)){
141 return this->at_for_sparse(locator,aux);
146 return this->at<T>(locator);
150 void set_elem(
const std::vector<cytnx_uint64> &locator,
const T &input){
151 if(this->is_blockform()){
152 if(this->elem_exists(locator)){
154 this->at_for_sparse(locator,aux) = input;
156 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
"\n");
159 this->at<T>(locator) = input;
164 return this->uten_type_id;
166 std::string uten_type_str(){
167 return UTenType.getname(this->uten_type_id);
173 virtual void Init(
const std::vector<Bond> &bonds,
const std::vector<cytnx_int64> &in_labels={},
const cytnx_int64 &rowrank=-1,
const unsigned int &dtype=
Type.Double,
const int &device =
Device.cpu,
const bool &is_diag=
false);
174 virtual void Init_by_Tensor(
const Tensor& in,
const cytnx_uint64 &rowrank,
const bool &is_diag=
false);
175 virtual std::vector<cytnx_uint64> shape()
const;
176 virtual bool is_blockform()
const ;
177 virtual bool is_contiguous()
const;
178 virtual void to_(
const int &device);
179 virtual boost::intrusive_ptr<UniTensor_base> to(
const int &device);
180 virtual boost::intrusive_ptr<UniTensor_base> clone()
const;
181 virtual unsigned int dtype()
const;
182 virtual int device()
const;
183 virtual std::string dtype_str()
const;
184 virtual std::string device_str()
const;
185 virtual void set_rowrank(
const cytnx_uint64 &new_rowrank);
186 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
187 virtual void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
188 virtual boost::intrusive_ptr<UniTensor_base> contiguous_();
189 virtual boost::intrusive_ptr<UniTensor_base> contiguous();
190 virtual void print_diagram(
const bool &bond_info=
false);
193 virtual Tensor get_block(
const std::vector<cytnx_int64> &qnum)
const;
196 virtual const Tensor& get_block_(
const std::vector<cytnx_int64> &qnum)
const;
198 virtual Tensor& get_block_(
const std::vector<cytnx_int64> &qnum);
199 virtual bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const;
201 virtual std::vector<Tensor> get_blocks()
const;
202 virtual const std::vector<Tensor>& get_blocks_(
const bool &)
const;
203 virtual std::vector<Tensor>& get_blocks_(
const bool &);
207 virtual void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum);
208 virtual void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum);
211 virtual boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
214 virtual void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
216 virtual void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
217 virtual boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
218 virtual boost::intrusive_ptr<UniTensor_base> to_dense();
219 virtual void to_dense_();
220 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &permute_back=
false,
const bool &by_label=
true);
221 virtual boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self=
false,
const bool &mv_elem_rhs=
false);
222 virtual std::vector<Bond> getTotalQnums(
const bool &physical=
false);
223 virtual std::vector<std::vector<cytnx_int64> > get_blocks_qnums()
const;
229 virtual void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
230 virtual void Add_(
const Scalar &rhs);
232 virtual void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
233 virtual void Mul_(
const Scalar &rhs);
235 virtual void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
236 virtual void Sub_(
const Scalar &rhs);
237 virtual void lSub_(
const Scalar &lhs);
239 virtual void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
240 virtual void Div_(
const Scalar &rhs);
241 virtual void lDiv_(
const Scalar &lhs);
248 virtual boost::intrusive_ptr<UniTensor_base>
Conj();
249 virtual void Conj_();
251 virtual boost::intrusive_ptr<UniTensor_base> Transpose();
252 virtual void Transpose_();
254 virtual boost::intrusive_ptr<UniTensor_base> Dagger();
255 virtual void Dagger_();
261 virtual bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
278 virtual const cytnx_float& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux)
const;
280 virtual const cytnx_int64& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux)
const;
282 virtual const cytnx_int32& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux)
const;
284 virtual const cytnx_int16& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux)
const;
286 virtual void _save_dispatch(std::fstream &f)
const;
287 virtual void _load_dispatch(std::fstream &f);
289 virtual ~UniTensor_base(){};
295 class DenseUniTensor:
public UniTensor_base{
299 std::vector<Tensor> _interface_block;
300 DenseUniTensor* clone_meta()
const{
301 DenseUniTensor* tmp =
new DenseUniTensor();
302 tmp->_bonds = vec_clone(this->_bonds);
303 tmp->_labels = this->_labels;
304 tmp->_is_braket_form = this->_is_braket_form;
305 tmp->_rowrank = this->_rowrank;
306 tmp->_is_diag = this->_is_diag;
307 tmp->_name = this->_name;
308 tmp->_is_tag = this->_is_tag;
313 DenseUniTensor(){this->uten_type_id =
UTenType.Dense;};
316 void Init(
const std::vector<Bond> &bonds,
const std::vector<cytnx_int64> &in_labels={},
const cytnx_int64 &rowrank=-1,
const unsigned int &dtype=
Type.Double,
const int &device =
Device.cpu,
const bool &is_diag=
false);
318 void Init_by_Tensor(
const Tensor& in_tensor,
const cytnx_uint64 &rowrank,
const bool &is_diag=
false);
319 std::vector<cytnx_uint64> shape()
const{
321 std::vector<cytnx_uint64> shape = this->_block.
shape();
322 shape.push_back(shape[0]);
325 return this->_block.
shape();
328 bool is_blockform()
const{
return false;}
329 void to_(
const int &device){
330 this->_block.
to_(device);
332 boost::intrusive_ptr<UniTensor_base> to(
const int &device){
333 if(this->device() == device){
336 boost::intrusive_ptr<UniTensor_base> out = this->clone();
342 cytnx_error_msg(new_rowrank > this->_labels.size(),
"[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
343 this->_rowrank = new_rowrank;
346 boost::intrusive_ptr<UniTensor_base> clone()
const{
347 DenseUniTensor* tmp = this->clone_meta();
348 tmp->_block = this->_block.
clone();
349 boost::intrusive_ptr<UniTensor_base> out(tmp);
352 bool is_contiguous()
const{
return this->_block.
is_contiguous();}
353 unsigned int dtype()
const{
return this->_block.
dtype();}
354 int device()
const{
return this->_block.
device();}
355 std::string dtype_str()
const{
return Type.getname(this->_block.
dtype());}
356 std::string device_str()
const{
return Device.getname(this->_block.
device());}
357 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
358 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
359 boost::intrusive_ptr<UniTensor_base> contiguous_(){this->_block.
contiguous_();
return boost::intrusive_ptr<UniTensor_base>(
this);}
360 boost::intrusive_ptr<UniTensor_base> contiguous(){
362 if(this->is_contiguous()){
363 boost::intrusive_ptr<UniTensor_base> out(
this);
366 DenseUniTensor* tmp = this->clone_meta();
368 boost::intrusive_ptr<UniTensor_base> out(tmp);
372 void print_diagram(
const bool &bond_info=
false);
375 Tensor get_block(
const std::vector<cytnx_int64> &qnum)
const{
cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to get_block() using qnum on a non-symmetry UniTensor%s",
"\n");
return Tensor();}
377 const Tensor& get_block_(
const std::vector<cytnx_int64> &qnum)
const{
cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
"\n");
return this->_block;}
378 Tensor& get_block_(
const std::vector<cytnx_int64> &qnum){
cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
"\n");
return this->_block;}
390 std::vector<Tensor> get_blocks()
const {
391 std::vector<Tensor> out;
392 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] cannot use get_blocks(), use get_block() instead!%s",
"\n");
395 const std::vector<Tensor>& get_blocks_(
const bool &silent=
false)
const {
396 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
"\n");
397 return this->_interface_block;
399 std::vector<Tensor>& get_blocks_(
const bool &silent=
false){
400 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
"\n");
401 return this->_interface_block;
406 cytnx_error_msg(in.
shape() != this->_block.shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
407 this->_block = in.
clone();
409 cytnx_error_msg(in.
shape() != this->shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
410 this->_block = in.
clone();
416 cytnx_error_msg(in.
shape() != this->_block.shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
419 cytnx_error_msg(in.
shape() != this->shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
424 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum){
425 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
"\n");
427 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum){
428 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
"\n");
431 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors){
432 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
433 out->Init_by_Tensor(this->_block.
get(accessors),0);
437 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs){
438 this->_block.
set(accessors,rhs);
441 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
442 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
443 boost::intrusive_ptr<UniTensor_base> to_dense();
446 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &permute_back=
true,
const bool &by_label=
true);
447 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self=
false,
const bool &mv_elem_rhs=
false);
448 std::vector<Bond> getTotalQnums(
const bool &physical=
false){
449 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] %s",
"getTotalQnums can only operate on UniTensor with symmetry.\n");
450 return std::vector<Bond>();
454 std::vector<std::vector<cytnx_int64> > get_blocks_qnums()
const{
455 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] %s",
"get_blocks_qnums can only operate on UniTensor with symmetry.\n");
456 return std::vector<std::vector<cytnx_int64> >();
459 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const{
460 if(rhs->uten_type()!=
UTenType.Dense)
return false;
462 return this->get_block_().same_data(rhs->get_block_());
471 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
472 void Add_(
const Scalar &rhs);
474 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
475 void Mul_(
const Scalar &rhs);
477 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
478 void Sub_(
const Scalar &rhs);
479 void lSub_(
const Scalar &lhs);
481 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
482 void Div_(
const Scalar &rhs);
483 void lDiv_(
const Scalar &lhs);
487 this->_block.
Conj_();
490 boost::intrusive_ptr<UniTensor_base>
Conj(){
491 boost::intrusive_ptr<UniTensor_base> out = this->clone();
496 boost::intrusive_ptr<UniTensor_base> Transpose(){
497 boost::intrusive_ptr<UniTensor_base> out = this->clone();
503 boost::intrusive_ptr<UniTensor_base> Dagger(){
504 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
516 boost::intrusive_ptr<UniTensor_base> out = this->clone();
517 out->Trace_(a,b,by_label);
521 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
525 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
529 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
533 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
537 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
541 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
545 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
549 const cytnx_int32& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux)
const {
550 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
554 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
558 const cytnx_int16& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux)
const {
559 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
564 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
568 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
572 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
576 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
580 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
584 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
588 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
593 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
597 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
602 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
607 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const{
608 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] elem_exists can only be used on UniTensor with Symmetry.%s",
"\n");
612 for(
int i=0;i<this->_rowrank;i++){
613 this->_bonds[i].set_type(BD_KET);
615 for(
int i=this->_rowrank;i<this->_bonds.size();i++){
616 this->_bonds[i].set_type(BD_BRA);
618 this->_is_tag =
true;
619 this->_is_braket_form = this->_update_braket();
624 void _save_dispatch(std::fstream &f)
const;
625 void _load_dispatch(std::fstream &f);
636 class SparseUniTensor:
public UniTensor_base{
642 std::vector<std::vector<cytnx_int64> > _blockqnums;
643 std::vector<cytnx_uint64> _mapper;
644 std::vector<cytnx_uint64> _inv_mapper;
645 std::vector<std::vector<cytnx_uint64> > _inner2outer_row;
646 std::vector<std::vector<cytnx_uint64> > _inner2outer_col;
647 std::map<cytnx_uint64,std::pair<cytnx_uint64,cytnx_uint64> > _outer2inner_row;
648 std::map<cytnx_uint64, std::pair<cytnx_uint64,cytnx_uint64> > _outer2inner_col;
650 std::vector<Tensor> _blocks;
653 void set_meta(SparseUniTensor *tmp,
const bool &inner,
const bool &outer)
const{
656 tmp->_bonds = vec_clone(this->_bonds);
657 tmp->_labels = this->_labels;
658 tmp->_is_braket_form = this->_is_braket_form;
659 tmp->_rowrank = this->_rowrank;
660 tmp->_name = this->_name;
663 tmp->_mapper = this->_mapper;
664 tmp->_inv_mapper = this->_inv_mapper;
665 tmp->_contiguous = this->_contiguous;
666 tmp->_is_diag = this->_is_diag;
670 tmp->_inner_rowrank = this->_inner_rowrank;
671 tmp->_inner2outer_row = this->_inner2outer_row;
672 tmp->_inner2outer_col = this->_inner2outer_col;
673 tmp->_outer2inner_row = this->_outer2inner_row;
674 tmp->_outer2inner_col = this->_outer2inner_col;
675 tmp->_blockqnums = this->_blockqnums;
679 SparseUniTensor* clone_meta(
const bool &inner,
const bool &outer)
const{
680 SparseUniTensor* tmp =
new SparseUniTensor();
681 this->set_meta(tmp,inner,outer);
692 this->uten_type_id =
UTenType.Sparse;
693 this->_is_tag =
true;
697 void Init(
const std::vector<Bond> &bonds,
const std::vector<cytnx_int64> &in_labels={},
const cytnx_int64 &rowrank=-1,
const unsigned int &dtype=
Type.Double,
const int &device =
Device.cpu,
const bool &is_diag=
false);
698 void Init_by_Tensor(
const Tensor& in_tensor,
const cytnx_uint64 &rowrank,
const bool &is_diag=
false){
699 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] cannot use Init_by_tensor() on a SparseUniTensor.%s",
"\n");
701 std::vector<cytnx_uint64> shape()
const{
702 std::vector<cytnx_uint64> out(this->_bonds.size());
704 out[i] = this->_bonds[i].dim();
708 bool is_blockform()
const{
return true;}
709 void to_(
const int &device){
711 this->_blocks[i].to_(device);
714 boost::intrusive_ptr<UniTensor_base> to(
const int &device){
715 if(this->device() == device){
718 boost::intrusive_ptr<UniTensor_base> out = this->clone();
723 boost::intrusive_ptr<UniTensor_base> clone()
const{
724 SparseUniTensor* tmp = this->clone_meta(
true,
true);
725 tmp->_blocks = vec_clone(this->_blocks);
726 boost::intrusive_ptr<UniTensor_base> out(tmp);
729 bool is_contiguous()
const{
730 return this->_contiguous;
733 cytnx_error_msg((new_rowrank < 1) || (new_rowrank>= this->rank()),
"[ERROR][SparseUniTensor] rowrank should be [>=1] and [<UniTensor.rank].%s",
"\n");
734 cytnx_error_msg(new_rowrank >= this->_labels.size(),
"[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
735 if(this->_rowrank!= new_rowrank)
736 this->_contiguous =
false;
737 this->_rowrank = new_rowrank;
738 this->_is_braket_form = this->_update_braket();
741 unsigned int dtype()
const{
743 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
745 return this->_blocks[0].dtype();
749 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
751 return this->_blocks[0].device();
753 std::string dtype_str()
const{
755 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
757 return this->_blocks[0].dtype_str();
759 std::string device_str()
const{
761 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
763 return this->_blocks[0].device_str();
765 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
766 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
767 boost::intrusive_ptr<UniTensor_base> contiguous();
768 boost::intrusive_ptr<UniTensor_base> contiguous_(){
769 if(!this->_contiguous){
770 boost::intrusive_ptr<UniTensor_base> titr = this->contiguous();
771 SparseUniTensor *tmp = (SparseUniTensor*)titr.get();
772 tmp->set_meta(
this,
true,
true);
773 this->_blocks = tmp->_blocks;
776 return boost::intrusive_ptr<UniTensor_base>(
this);
779 void print_diagram(
const bool &bond_info=
false);
782 cytnx_error_msg(idx>=this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
"\n");
783 if(this->_contiguous){
784 return this->_blocks[idx].clone();
786 cytnx_error_msg(
true,
"[Developing] get block from a non-contiguous SparseUniTensor is currently not support. Call contiguous()/contiguous_() first.%s",
"\n");
791 Tensor get_block(
const std::vector<cytnx_int64> &qnum)
const{
792 cytnx_error_msg(!this->is_braket_form(),
"[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch the row/col space.\n permute to the correct physical space first, then get block.%s",
"\n");
794 if(this->_contiguous){
798 for(
int i=0;i<this->_blockqnums.size();i++){
802 if(qnum==this->_blockqnums[i]){idx=i;
break;}
804 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
805 return this->get_block(idx);
807 cytnx_error_msg(
true,
"[Developing] get block from a non-contiguous SparseUniTensor is currently not support. Call contiguous()/contiguous_() first.%s",
"\n");
815 cytnx_error_msg(this->is_contiguous()==
false,
"[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call get_block_()\n 2) Try get_block()/get_blocks()%s",
"\n");
817 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][SparseUniTensor] index exceed the number of blocks.%s",
"\n");
819 return this->_blocks[idx];
822 cytnx_error_msg(this->is_contiguous()==
false,
"[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call get_block_()\n 2) Try get_block()/get_blocks()%s",
"\n");
824 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][SparseUniTensor] index exceed the number of blocks.%s",
"\n");
826 return this->_blocks[idx];
829 Tensor& get_block_(
const std::vector<cytnx_int64> &qnum){
830 cytnx_error_msg(!this->is_braket_form(),
"[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch the row/col space.\n permute to the correct physical space first, then get block.%s",
"\n");
831 cytnx_error_msg(this->is_contiguous()==
false,
"[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call get_blocks_()\n 2) Try get_block()/get_blocks()%s",
"\n");
835 for(
int i=0;i<this->_blockqnums.size();i++){
836 if(qnum==this->_blockqnums[i]){idx=i;
break;}
838 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
839 return this->get_block_(idx);
842 const Tensor& get_block_(
const std::vector<cytnx_int64> &qnum)
const{
843 cytnx_error_msg(!this->is_braket_form(),
"[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch the row/col space.\n permute to the correct physical space first, then get block.%s",
"\n");
844 cytnx_error_msg(this->is_contiguous()==
false,
"[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call get_blocks_()\n 2) Try get_block()/get_blocks()%s",
"\n");
848 for(
int i=0;i<this->_blockqnums.size();i++){
849 if(qnum==this->_blockqnums[i]){idx=i;
break;}
851 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
852 return this->get_block_(idx);
855 std::vector<Tensor> get_blocks()
const {
856 if(this->_contiguous){
857 return vec_clone(this->_blocks);
860 boost::intrusive_ptr<UniTensor_base> tmp = this->clone();
862 SparseUniTensor *ttmp = (SparseUniTensor*)tmp.get();
863 return ttmp->_blocks;
867 const std::vector<Tensor>& get_blocks_(
const bool &silent=
false)
const {
869 if(this->_contiguous){
870 return this->_blocks;
874 cytnx_warning_msg(
true,
"[WARNING][SparseUniTensor] call get_blocks_() with a non-contiguous UniTensor should be used with caution. \ntry: \n1) get_blocks()\n2) call contiguous/contiguous_() first, then get_blocks_() to get concise results%s",
"\n");
876 return this->_blocks;
879 std::vector<Tensor>& get_blocks_(
const bool &silent=
false){
881 if(this->_contiguous){
882 return this->_blocks;
885 cytnx_warning_msg(
true,
"[WARNING][SparseUniTensor] call get_blocks_() with a non-contiguous UniTensor should be used with caution. \ntry: \n1) get_blocks()\n2) call contiguous/contiguous_() first, then get_blocks_() to get concise results%s",
"\n");
887 return this->_blocks;
891 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const{
892 if(rhs->uten_type()!=
UTenType.Sparse)
return false;
893 if(rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
895 for(
int i=0;i<rhs->get_blocks_(1).size();i++)
896 if(this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i])==
false)
return false;
905 cytnx_error_msg(this->is_contiguous()==
false,
"[ERROR][SparseUniTensor] cannot use put_block_() on non-contiguous UniTensor with symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call put_blocks_()\n 2) Try put_block()/put_blocks()%s",
"\n");
907 cytnx_error_msg(idx>=this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
"\n");
908 cytnx_error_msg(in.
shape()!=this->_blocks[idx].shape(),
"[ERROR][SparseUniTensor] the shape of input tensor does not match the shape of block @ idx=%d\n",idx);
909 this->_blocks[idx] = in;
912 cytnx_error_msg(idx>=this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
"\n");
913 if(this->_contiguous){
914 cytnx_error_msg(in.
shape()!=this->_blocks[idx].shape(),
"[ERROR][SparseUniTensor] the shape of input tensor does not match the shape of block @ idx=%d\n",idx);
915 this->_blocks[idx] = in.
clone();
917 cytnx_error_msg(
true,
"[Developing] put block to a non-contiguous SparseUniTensor is currently not support. Call contiguous()/contiguous_() first.%s",
"\n");
920 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum){
921 cytnx_error_msg(!this->is_braket_form(),
"[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch the row/col space.\n permute to the correct physical space first, then get block.%s",
"\n");
925 for(
int i=0;i<this->_blockqnums.size();i++){
926 if(qnum==this->_blockqnums[i]){idx=i;
break;}
928 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
929 this->put_block(in,idx);
932 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum){
933 cytnx_error_msg(!this->is_braket_form(),
"[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch the row/col space.\n permute to the correct physical space first, then get block.%s",
"\n");
934 cytnx_error_msg(this->is_contiguous()==
false,
"[ERROR][SparseUniTensor] cannot use put_block_() on non-contiguous UniTensor with symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call get_blocks_()\n 2) Try get_block()/get_blocks()%s",
"\n");
938 for(
int i=0;i<this->_blockqnums.size();i++){
939 if(qnum==this->_blockqnums[i]){idx=i;
break;}
941 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
942 this->put_block_(in,idx);
946 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors){
947 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor][get] cannot use get on a UniTensor with Symmetry.\n suggestion: try get_block()/get_blocks() first.%s",
"\n");
951 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs){
952 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor][set] cannot use set on a UniTensor with Symmetry.\n suggestion: try get_block()/get_blocks() first.%s",
"\n");
954 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0){
955 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
957 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0){
958 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
961 boost::intrusive_ptr<UniTensor_base> to_dense(){
962 cytnx_error_msg(
true,
"[ERROR] cannot to_dense a UniTensor with symmetry.%s",
"\n");
966 cytnx_error_msg(
true,
"[ERROR] cannot to_dense_ a UniTensor with symmetry.%s",
"\n");
968 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &permute_back=
true,
const bool &by_label=
true){
971 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self=
false,
const bool &mv_elem_rhs=
false);
972 std::vector<Bond> getTotalQnums(
const bool &physical=
false);
973 std::vector<std::vector<cytnx_int64> > get_blocks_qnums()
const{
974 return this->_blockqnums;
976 ~SparseUniTensor(){};
980 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
981 void Add_(
const Scalar &rhs);
983 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
984 void Mul_(
const Scalar &rhs);
986 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
987 void Sub_(
const Scalar &rhs);
988 void lSub_(
const Scalar &lhs);
990 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
991 void Div_(
const Scalar &rhs);
992 void lDiv_(
const Scalar &lhs);
995 boost::intrusive_ptr<UniTensor_base>
Conj(){
996 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1002 for(
int i=0;i<this->_blocks.size();i++){
1003 this->_blocks[i].Conj_();
1016 boost::intrusive_ptr<UniTensor_base> Transpose(){
1017 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1022 boost::intrusive_ptr<UniTensor_base> Dagger(){
1023 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1041 const cytnx_float& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux)
const;
1043 const cytnx_int64& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux)
const;
1045 const cytnx_int32& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux)
const;
1047 const cytnx_int16& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux)
const;
1060 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
1061 void _save_dispatch(std::fstream &f)
const;
1062 void _load_dispatch(std::fstream &f);
1077 boost::intrusive_ptr<UniTensor_base> _impl;
1080 this->_impl =
rhs._impl;
1083 this->_impl =
rhs._impl;
1139 cytnx_warning_msg(
true,
"[DEBUG] message: entry for UniTensor(const std::vector<Bond> &bonds, const std::vector<cytnx_int64> &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int &dtype=Type.Double, const int &device = Device.cpu, const bool &is_diag=false)%s",
"\n");
1150 else cytnx_error_msg(
is_sym,
"[ERROR] cannot have bonds with mixing of symmetry and non-symmetry.%s",
"\n");
1156 cytnx_warning_msg(
true,
"[DEBUG] message: entry dispatch: UniTensor: symmetric%s",
"\n");
1213 cytnx_error_msg(this->
is_blockform(),
"[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use get_block()/get_blocks() first.%s",
"\n");
1216 return tmp->_block.item<
T>();
1222 unsigned int dtype()
const{
return this->_impl->dtype(); }
1224 int device()
const{
return this->_impl->device(); }
1225 std::string
name()
const {
return this->_impl->name();}
1226 std::string
dtype_str()
const{
return this->_impl->dtype_str();}
1227 std::string
device_str()
const{
return this->_impl->device_str();}
1230 bool is_diag()
const{
return this->_impl->is_diag(); }
1231 bool is_tag()
const {
return this->_impl->is_tag();}
1233 return this->_impl->is_braket_form();
1235 const std::vector<cytnx_int64>&
labels()
const{
return this->_impl->labels();}
1236 const std::vector<Bond> &
bonds()
const {
return this->_impl->bonds();}
1237 std::vector<Bond> &
bonds() {
return this->_impl->bonds();}
1238 std::vector<cytnx_uint64>
shape()
const{
return this->_impl->shape();}
1262 this->_impl = this->_impl->contiguous_();
1270 return this->_impl->at<
T>(
locator);
1276 return this->_impl->get_block(
idx);
1281 return this->_impl->get_block(
qnum);
1284 std::vector<cytnx_int64>
tmp =
qnum;
1290 return this->_impl->get_block_(
idx);
1295 return this->_impl->get_block_(
idx);
1300 return this->_impl->get_block_(
qnum);
1303 std::vector<cytnx_int64>
tmp =
qnum;
1310 return this->_impl->get_block_(
qnum);
1313 std::vector<cytnx_int64>
tmp =
qnum;
1314 return this->_impl->get_block_(
tmp);
1320 return this->_impl->get_blocks();
1325 return this->_impl->get_blocks_(
silent);
1329 return this->_impl->get_blocks_(
silent);
1334 this->_impl->put_block(
in,
idx);
1338 this->_impl->put_block(
in,
qnum);
1342 this->_impl->put_block_(
in,
idx);
1346 this->_impl->put_block_(
in,
qnum);
1370 this->_impl->to_dense_();
1381 return this->_impl->getTotalQnums(
physical);
1384 return this->_impl->get_blocks_qnums();
1390 if(this->_impl->uten_type() !=
rhs._impl->uten_type())
1395 return this->_impl->same_data(
rhs._impl);
1485 out._impl = this->_impl->
Conj();
1490 this->_impl->
Conj_();
1540 return this->_impl->elem_exists(
locator);
1545 return this->_impl->get_elem<
T>(
locator);
1548 template<
class T,
class T2>
1555 void Save(
const std::string &
fname)
const;
1572 void _Load(std::fstream &
f);
1573 void _Save(std::fstream &
f)
const;
Definition Scalar.hpp:1630
an tensor (multi-dimensional array)
Definition Tensor.hpp:289
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:768
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:855
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:661
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:834
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:719
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:1096
const bool & is_contiguous() const
Definition Tensor.hpp:772
Tensor & Conj_()
Definition Tensor.cpp:1174
int device() const
the device-id of the Tensor
Definition Tensor.hpp:668
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1063
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:689
An Enhanced tensor specifically designed for physical Tensor network simulation.
Definition UniTensor.hpp:1072
UniTensor to(const int &device) const
Definition UniTensor.hpp:1242
UniTensor & operator*=(const UniTensor &rhs)
Definition UniTensor.hpp:1460
std::vector< Tensor > & get_blocks_(const bool &silent=false)
Definition UniTensor.hpp:1328
UniTensor & operator/=(const UniTensor &rhs)
Definition UniTensor.hpp:1456
T & item()
Definition UniTensor.hpp:1211
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &permute_back=true, const bool &by_label=true)
Definition UniTensor.hpp:1372
bool is_contiguous() const
Definition UniTensor.hpp:1229
T get_elem(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:1544
UniTensor Div(const UniTensor &rhs) const
Definition UniTensor.cpp:32
const std::vector< cytnx_int64 > & labels() const
Definition UniTensor.hpp:1235
UniTensor & operator+=(const UniTensor &rhs)
Definition UniTensor.hpp:1448
void to_dense_()
Definition UniTensor.hpp:1369
UniTensor reshape(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Definition UniTensor.hpp:1356
std::vector< Tensor > get_blocks() const
Definition UniTensor.hpp:1319
bool is_tag() const
Definition UniTensor.hpp:1231
std::string uten_type_str() const
Definition UniTensor.hpp:1228
UniTensor permute(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1, const bool &by_label=false)
Definition UniTensor.hpp:1252
static UniTensor Load(const std::string &fname)
Definition UniTensor.cpp:152
UniTensor & tag()
Definition UniTensor.hpp:1527
UniTensor & Trace_(const cytnx_int64 &a, const cytnx_int64 &b, const bool &by_label=false)
Definition UniTensor.hpp:1511
UniTensor get(const std::vector< Accessor > &accessors) const
Definition UniTensor.hpp:1348
void Save(const std::string &fname) const
Definition UniTensor.cpp:131
UniTensor & operator-=(const Scalar &rhs)
Definition UniTensor.hpp:1468
cytnx_uint64 rowrank() const
Definition UniTensor.hpp:1221
void Init(const std::vector< Bond > &bonds, const std::vector< cytnx_int64 > &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const bool &is_diag=false)
Definition UniTensor.hpp:1143
UniTensor & Sub_(const Scalar &rhs)
Definition UniTensor.hpp:1428
UniTensor & operator/=(const Scalar &rhs)
Definition UniTensor.hpp:1472
const bool & is_braket_form() const
Definition UniTensor.hpp:1232
UniTensor(const std::vector< Bond > &bonds, const std::vector< cytnx_int64 > &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const bool &is_diag=false)
Initialize a UniTensor.
Definition UniTensor.hpp:1137
std::vector< cytnx_uint64 > shape() const
Definition UniTensor.hpp:1238
UniTensor to_dense()
Definition UniTensor.hpp:1364
UniTensor & set_label(const cytnx_uint64 &idx, const cytnx_int64 &new_label)
set a new label for bond at the assigned index.
Definition UniTensor.hpp:1188
void reshape_(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Definition UniTensor.hpp:1361
std::string name() const
Definition UniTensor.hpp:1225
UniTensor & Add_(const Scalar &rhs)
Definition UniTensor.hpp:1418
std::vector< Bond > getTotalQnums(const bool physical=false) const
Definition UniTensor.hpp:1380
bool same_data(const UniTensor &rhs) const
Definition UniTensor.hpp:1387
Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qnum)
Definition UniTensor.hpp:1302
void set_elem(const std::vector< cytnx_uint64 > &locator, const T2 &rc)
Definition UniTensor.hpp:1549
UniTensor Transpose() const
Definition UniTensor.hpp:1495
UniTensor & Dagger_()
Definition UniTensor.hpp:1522
void print_diagram(const bool &bond_info=false)
Definition UniTensor.hpp:1264
std::vector< Bond > & bonds()
Definition UniTensor.hpp:1237
T & at(const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:1269
UniTensor & truncate_(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim, const bool &by_label=false)
Definition UniTensor.hpp:1560
std::vector< std::vector< cytnx_int64 > > get_blocks_qnums() const
Definition UniTensor.hpp:1383
UniTensor contiguous() const
Definition UniTensor.hpp:1256
Tensor get_block(const cytnx_uint64 &idx=0) const
Definition UniTensor.hpp:1275
UniTensor & operator*=(const Scalar &rhs)
Definition UniTensor.hpp:1476
void contiguous_()
Definition UniTensor.hpp:1261
UniTensor & set_labels(const std::vector< cytnx_int64 > &new_labels)
set new labels for all the bonds.
Definition UniTensor.hpp:1201
UniTensor & Mul_(const UniTensor &rhs)
Definition UniTensor.hpp:1403
void put_block_(Tensor &in, const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:1341
bool is_diag() const
Definition UniTensor.hpp:1230
int device() const
Definition UniTensor.hpp:1224
UniTensor & Pow_(const double &p)
Definition UniTensor.cpp:14
void set(const std::vector< Accessor > &accessors, const Tensor &rhs)
Definition UniTensor.hpp:1353
std::string dtype_str() const
Definition UniTensor.hpp:1226
UniTensor & operator+=(const Scalar &rhs)
Definition UniTensor.hpp:1464
UniTensor & Div_(const UniTensor &rhs)
Definition UniTensor.hpp:1413
UniTensor & Div_(const Scalar &rhs)
Definition UniTensor.hpp:1433
cytnx_uint64 rank() const
Definition UniTensor.hpp:1220
const Tensor & get_block_(const std::vector< cytnx_int64 > &qnum) const
Definition UniTensor.hpp:1309
void to_(const int &device)
Definition UniTensor.hpp:1241
void put_block(const Tensor &in, const std::vector< cytnx_int64 > &qnum)
Definition UniTensor.hpp:1337
Tensor get_block(const std::vector< cytnx_int64 > &qnum) const
Definition UniTensor.hpp:1280
UniTensor & set_name(const std::string &in)
set the name of the UniTensor
Definition UniTensor.hpp:1174
UniTensor & Add_(const UniTensor &rhs)
Definition UniTensor.hpp:1398
unsigned int dtype() const
Definition UniTensor.hpp:1222
UniTensor Pow(const double &p) const
Definition UniTensor.cpp:11
UniTensor & Mul_(const Scalar &rhs)
Definition UniTensor.hpp:1423
UniTensor & operator-=(const UniTensor &rhs)
Definition UniTensor.hpp:1452
bool is_blockform() const
Definition UniTensor.hpp:1239
UniTensor Dagger() const
Definition UniTensor.hpp:1516
const std::vector< Tensor > & get_blocks_(const bool &silent=false) const
Definition UniTensor.hpp:1324
bool elem_exists(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:1539
UniTensor & Sub_(const UniTensor &rhs)
Definition UniTensor.hpp:1408
UniTensor contract(const UniTensor &inR, const bool &mv_elem_self=false, const bool &mv_elem_rhs=false) const
Definition UniTensor.hpp:1375
void put_block(const Tensor &in, const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:1333
const Tensor & get_block_(const cytnx_uint64 &idx=0) const
Definition UniTensor.hpp:1289
Tensor get_block(const std::initializer_list< cytnx_int64 > &qnum) const
Definition UniTensor.hpp:1283
const Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qnum) const
Definition UniTensor.hpp:1312
UniTensor Mul(const UniTensor &rhs) const
Definition UniTensor.cpp:39
const std::vector< Bond > & bonds() const
Definition UniTensor.hpp:1236
void put_block_(Tensor &in, const std::vector< cytnx_int64 > &qnum)
Definition UniTensor.hpp:1345
UniTensor & Transpose_()
Definition UniTensor.hpp:1500
UniTensor clone() const
Definition UniTensor.hpp:1247
UniTensor Trace(const cytnx_int64 &a, const cytnx_int64 &b, const bool &by_label=false) const
Definition UniTensor.hpp:1505
UniTensor truncate(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim, const bool &by_label=false) const
Definition UniTensor.hpp:1564
void Init(const Tensor &in_tensor, const cytnx_uint64 &rowrank, const bool &is_diag=false)
Definition UniTensor.hpp:1113
std::string device_str() const
Definition UniTensor.hpp:1227
UniTensor Sub(const UniTensor &rhs) const
Definition UniTensor.cpp:25
UniTensor & Conj_()
Definition UniTensor.hpp:1489
Tensor & get_block_(const std::vector< cytnx_int64 > &qnum)
Definition UniTensor.hpp:1299
UniTensor Conj()
Definition UniTensor.hpp:1483
UniTensor Add(const UniTensor &rhs) const
Definition UniTensor.cpp:18
UniTensor & set_rowrank(const cytnx_uint64 &new_rowrank)
Definition UniTensor.hpp:1205
void permute_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1, const bool &by_label=false)
Definition UniTensor.hpp:1253
UniTensor(const Tensor &in_tensor, const cytnx_uint64 &rowrank, const bool &is_diag=false)
Initialize a UniTensor with cytnx::Tensor.
Definition UniTensor.hpp:1110
int uten_type() const
Definition UniTensor.hpp:1223
Tensor & get_block_(const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:1294
#define cytnx_warning_msg(is_true, format,...)
Definition cytnx_error.hpp:37
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:18
cytnx::UniTensor Trace(const cytnx::UniTensor &Tin, const cytnx_int64 &a, const cytnx_int64 &b, const bool &by_label=false)
Tensor Conj(const Tensor &Tin)
Conjugate all the element in Tensor.
void Conj_(Tensor &Tin)
inplace perform Conjugate on all the element in Tensor.
Definition Accessor.hpp:12
Device_class Device
Definition Device.cpp:105
double cytnx_double
Definition Type.hpp:20
UniTensorType_class UTenType
Definition UniTensor_base.cpp:21
uint32_t cytnx_uint32
Definition Type.hpp:23
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
int32_t cytnx_int32
Definition Type.hpp:26
UniTensor Contract(const UniTensor &inL, const UniTensor &inR, const bool &cacheL=false, const bool &cacheR=false)
Contract two UniTensor by tracing the ranks with common labels.
Definition UniTensor_base.cpp:352
uint16_t cytnx_uint16
Definition Type.hpp:24
uint64_t cytnx_uint64
Definition Type.hpp:22
int64_t cytnx_int64
Definition Type.hpp:25
Type_class Type
Definition Type.cpp:137