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;}
101 auto res = std::find(this->_labels.begin(),this->_labels.end(),inx);
102 cytnx_error_msg(res==this->_labels.end(),
"[ERROR] label %d not exists.\n",inx);
103 idx = std::distance(this->_labels.begin(), res);
108 cytnx_error_msg(idx>=this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
"\n");
113 if(new_label == this->_labels[i]){is_dup =
true;
break;}
115 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
"\n");
116 this->_labels[idx] = new_label;
119 void set_labels(
const std::vector<cytnx_int64> &new_labels);
155 return this->uten_type_id;
157 std::string uten_type_str(){
158 return UTenType.getname(this->uten_type_id);
164 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,
const bool &no_alloc=
false);
165 virtual void Init_by_Tensor(
const Tensor& in,
const cytnx_uint64 &rowrank,
const bool &is_diag=
false);
166 virtual std::vector<cytnx_uint64> shape()
const;
167 virtual bool is_blockform()
const ;
168 virtual bool is_contiguous()
const;
169 virtual void to_(
const int &device);
170 virtual boost::intrusive_ptr<UniTensor_base> to(
const int &device);
171 virtual boost::intrusive_ptr<UniTensor_base> clone()
const;
172 virtual unsigned int dtype()
const;
173 virtual int device()
const;
174 virtual std::string dtype_str()
const;
175 virtual std::string device_str()
const;
176 virtual void set_rowrank(
const cytnx_uint64 &new_rowrank);
177 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
178 virtual void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
179 virtual boost::intrusive_ptr<UniTensor_base> contiguous_();
180 virtual boost::intrusive_ptr<UniTensor_base> contiguous();
181 virtual void print_diagram(
const bool &bond_info=
false);
183 virtual boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const;
187 virtual Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const;
190 virtual const Tensor& get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const;
192 virtual Tensor& get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force);
193 virtual bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const;
195 virtual std::vector<Tensor> get_blocks()
const;
196 virtual const std::vector<Tensor>& get_blocks_(
const bool &)
const;
197 virtual std::vector<Tensor>& get_blocks_(
const bool &);
201 virtual void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force);
202 virtual void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force);
205 virtual boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
208 virtual void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
210 virtual void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
211 virtual boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
212 virtual boost::intrusive_ptr<UniTensor_base> to_dense();
213 virtual void to_dense_();
214 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &permute_back=
false,
const bool &by_label=
true);
215 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);
216 virtual std::vector<Bond> getTotalQnums(
const bool &physical=
false);
217 virtual std::vector<std::vector<cytnx_int64> > get_blocks_qnums()
const;
220 virtual boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<cytnx_int64> &new_labels);
221 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
const cytnx_int64 &new_label,
const bool &by_label=
false);
224 virtual std::vector<Symmetry> syms()
const;
227 virtual void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
228 virtual void Add_(
const Scalar &rhs);
230 virtual void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
231 virtual void Mul_(
const Scalar &rhs);
233 virtual void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
234 virtual void Sub_(
const Scalar &rhs);
235 virtual void lSub_(
const Scalar &lhs);
237 virtual void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
238 virtual void Div_(
const Scalar &rhs);
239 virtual void lDiv_(
const Scalar &lhs);
246 virtual boost::intrusive_ptr<UniTensor_base>
Conj();
247 virtual void Conj_();
249 virtual boost::intrusive_ptr<UniTensor_base> Transpose();
250 virtual void Transpose_();
252 virtual boost::intrusive_ptr<UniTensor_base> Dagger();
253 virtual void Dagger_();
259 virtual bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
262 virtual Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
263 virtual const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
279 virtual const cytnx_float& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux)
const;
281 virtual const cytnx_int64& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux)
const;
283 virtual const cytnx_int32& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux)
const;
285 virtual const cytnx_int16& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux)
const;
287 virtual void _save_dispatch(std::fstream &f)
const;
288 virtual void _load_dispatch(std::fstream &f);
290 virtual ~UniTensor_base(){};
296 class DenseUniTensor:
public UniTensor_base{
300 std::vector<Tensor> _interface_block;
301 DenseUniTensor* clone_meta()
const{
302 DenseUniTensor* tmp =
new DenseUniTensor();
303 tmp->_bonds = vec_clone(this->_bonds);
304 tmp->_labels = this->_labels;
305 tmp->_is_braket_form = this->_is_braket_form;
306 tmp->_rowrank = this->_rowrank;
307 tmp->_is_diag = this->_is_diag;
308 tmp->_name = this->_name;
309 tmp->_is_tag = this->_is_tag;
314 DenseUniTensor(){this->uten_type_id =
UTenType.Dense;};
317 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,
const bool &no_alloc=
false);
319 void Init_by_Tensor(
const Tensor& in_tensor,
const cytnx_uint64 &rowrank,
const bool &is_diag=
false);
320 std::vector<cytnx_uint64> shape()
const{
322 std::vector<cytnx_uint64> shape = this->_block.
shape();
323 shape.push_back(shape[0]);
326 return this->_block.
shape();
329 bool is_blockform()
const{
return false;}
330 void to_(
const int &device){
331 this->_block.
to_(device);
333 boost::intrusive_ptr<UniTensor_base> to(
const int &device){
334 if(this->device() == device){
337 boost::intrusive_ptr<UniTensor_base> out = this->clone();
343 cytnx_error_msg(new_rowrank > this->_labels.size(),
"[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
344 this->_rowrank = new_rowrank;
347 boost::intrusive_ptr<UniTensor_base> clone()
const{
348 DenseUniTensor* tmp = this->clone_meta();
349 tmp->_block = this->_block.
clone();
350 boost::intrusive_ptr<UniTensor_base> out(tmp);
353 bool is_contiguous()
const{
return this->_block.
is_contiguous();}
354 unsigned int dtype()
const{
return this->_block.
dtype();}
355 int device()
const{
return this->_block.
device();}
356 std::string dtype_str()
const{
return Type.getname(this->_block.
dtype());}
357 std::string device_str()
const{
return Device.getname(this->_block.
device());}
358 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
359 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
360 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<cytnx_int64> &new_labels);
361 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
const cytnx_int64 &new_label,
const bool &by_label=
false);
363 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const{
364 DenseUniTensor* tmp = this->clone_meta();
365 tmp->_block = this->_block.
astype(dtype);
366 boost::intrusive_ptr<UniTensor_base> out(tmp);
370 std::vector<Symmetry> syms()
const{
371 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] dense unitensor does not have symmetry.%s",
"\n");
372 return std::vector<Symmetry>();
375 boost::intrusive_ptr<UniTensor_base> contiguous_(){this->_block.
contiguous_();
return boost::intrusive_ptr<UniTensor_base>(
this);}
376 boost::intrusive_ptr<UniTensor_base> contiguous(){
378 if(this->is_contiguous()){
379 boost::intrusive_ptr<UniTensor_base> out(
this);
382 DenseUniTensor* tmp = this->clone_meta();
384 boost::intrusive_ptr<UniTensor_base> out(tmp);
388 void print_diagram(
const bool &bond_info=
false);
391 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const{
cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to get_block() using qnum on a non-symmetry UniTensor%s",
"\n");
return Tensor();}
393 const Tensor& get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const{
cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
"\n");
return this->_block;}
394 Tensor& get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force){
cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
"\n");
return this->_block;}
406 std::vector<Tensor> get_blocks()
const {
407 std::vector<Tensor> out;
408 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] cannot use get_blocks(), use get_block() instead!%s",
"\n");
411 const std::vector<Tensor>& get_blocks_(
const bool &silent=
false)
const {
412 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
"\n");
413 return this->_interface_block;
415 std::vector<Tensor>& get_blocks_(
const bool &silent=
false){
416 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
"\n");
417 return this->_interface_block;
422 cytnx_error_msg(in.
shape() != this->_block.shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
423 this->_block = in.
clone();
425 cytnx_error_msg(in.
shape() != this->shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
426 this->_block = in.
clone();
432 cytnx_error_msg(in.
shape() != this->_block.shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
435 cytnx_error_msg(in.
shape() != this->shape(),
"[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
440 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force){
441 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
"\n");
443 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force){
444 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
"\n");
447 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors){
448 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
449 out->Init_by_Tensor(this->_block.
get(accessors),0);
453 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs){
454 this->_block.
set(accessors,rhs);
457 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
458 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0);
459 boost::intrusive_ptr<UniTensor_base> to_dense();
462 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &permute_back=
true,
const bool &by_label=
true);
463 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);
464 std::vector<Bond> getTotalQnums(
const bool &physical=
false){
465 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] %s",
"getTotalQnums can only operate on UniTensor with symmetry.\n");
466 return std::vector<Bond>();
470 std::vector<std::vector<cytnx_int64> > get_blocks_qnums()
const{
471 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] %s",
"get_blocks_qnums can only operate on UniTensor with symmetry.\n");
472 return std::vector<std::vector<cytnx_int64> >();
475 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const{
476 if(rhs->uten_type()!=
UTenType.Dense)
return false;
478 return this->get_block_().same_data(rhs->get_block_());
487 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
488 void Add_(
const Scalar &rhs);
490 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
491 void Mul_(
const Scalar &rhs);
493 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
494 void Sub_(
const Scalar &rhs);
495 void lSub_(
const Scalar &lhs);
497 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
498 void Div_(
const Scalar &rhs);
499 void lDiv_(
const Scalar &lhs);
503 this->_block.
Conj_();
506 boost::intrusive_ptr<UniTensor_base>
Conj(){
507 boost::intrusive_ptr<UniTensor_base> out = this->clone();
512 boost::intrusive_ptr<UniTensor_base> Transpose(){
513 boost::intrusive_ptr<UniTensor_base> out = this->clone();
519 boost::intrusive_ptr<UniTensor_base> Dagger(){
520 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
532 boost::intrusive_ptr<UniTensor_base> out = this->clone();
533 out->Trace_(a,b,by_label);
539 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const {
540 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
544 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
548 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
552 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
556 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
560 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 const cytnx_int32& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux)
const {
573 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
577 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
581 const cytnx_int16& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux)
const {
582 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
586 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator){
587 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
591 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
595 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
599 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
603 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
607 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
611 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
615 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
620 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
624 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
629 cytnx_error_msg(
true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
"\n");
634 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const{
635 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] elem_exists can only be used on UniTensor with Symmetry.%s",
"\n");
639 for(
int i=0;i<this->_rowrank;i++){
640 this->_bonds[i].set_type(BD_KET);
642 for(
int i=this->_rowrank;i<this->_bonds.size();i++){
643 this->_bonds[i].set_type(BD_BRA);
645 this->_is_tag =
true;
646 this->_is_braket_form = this->_update_braket();
651 void _save_dispatch(std::fstream &f)
const;
652 void _load_dispatch(std::fstream &f);
663 class SparseUniTensor:
public UniTensor_base{
669 std::vector<std::vector<cytnx_int64> > _blockqnums;
670 std::vector<cytnx_uint64> _mapper;
671 std::vector<cytnx_uint64> _inv_mapper;
672 std::vector<std::vector<cytnx_uint64> > _inner2outer_row;
673 std::vector<std::vector<cytnx_uint64> > _inner2outer_col;
674 std::map<cytnx_uint64,std::pair<cytnx_uint64,cytnx_uint64> > _outer2inner_row;
675 std::map<cytnx_uint64, std::pair<cytnx_uint64,cytnx_uint64> > _outer2inner_col;
677 std::vector<Tensor> _blocks;
680 void set_meta(SparseUniTensor *tmp,
const bool &inner,
const bool &outer)
const{
683 tmp->_bonds = vec_clone(this->_bonds);
684 tmp->_labels = this->_labels;
685 tmp->_is_braket_form = this->_is_braket_form;
686 tmp->_rowrank = this->_rowrank;
687 tmp->_name = this->_name;
690 tmp->_mapper = this->_mapper;
691 tmp->_inv_mapper = this->_inv_mapper;
692 tmp->_contiguous = this->_contiguous;
693 tmp->_is_diag = this->_is_diag;
697 tmp->_inner_rowrank = this->_inner_rowrank;
698 tmp->_inner2outer_row = this->_inner2outer_row;
699 tmp->_inner2outer_col = this->_inner2outer_col;
700 tmp->_outer2inner_row = this->_outer2inner_row;
701 tmp->_outer2inner_col = this->_outer2inner_col;
702 tmp->_blockqnums = this->_blockqnums;
706 SparseUniTensor* clone_meta(
const bool &inner,
const bool &outer)
const{
707 SparseUniTensor* tmp =
new SparseUniTensor();
708 this->set_meta(tmp,inner,outer);
719 this->uten_type_id =
UTenType.Sparse;
720 this->_is_tag =
true;
724 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,
const bool &no_alloc=
false);
725 void Init_by_Tensor(
const Tensor& in_tensor,
const cytnx_uint64 &rowrank,
const bool &is_diag=
false){
726 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] cannot use Init_by_tensor() on a SparseUniTensor.%s",
"\n");
728 std::vector<cytnx_uint64> shape()
const{
729 std::vector<cytnx_uint64> out(this->_bonds.size());
731 out[i] = this->_bonds[i].dim();
735 bool is_blockform()
const{
return true;}
736 void to_(
const int &device){
738 this->_blocks[i].to_(device);
741 boost::intrusive_ptr<UniTensor_base> to(
const int &device){
742 if(this->device() == device){
745 boost::intrusive_ptr<UniTensor_base> out = this->clone();
750 boost::intrusive_ptr<UniTensor_base> clone()
const{
751 SparseUniTensor* tmp = this->clone_meta(
true,
true);
752 tmp->_blocks = vec_clone(this->_blocks);
753 boost::intrusive_ptr<UniTensor_base> out(tmp);
757 bool is_contiguous()
const{
758 return this->_contiguous;
761 cytnx_error_msg((new_rowrank < 1) || (new_rowrank>= this->rank()),
"[ERROR][SparseUniTensor] rowrank should be [>=1] and [<UniTensor.rank].%s",
"\n");
762 cytnx_error_msg(new_rowrank >= this->_labels.size(),
"[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
763 if(this->_inner_rowrank!= new_rowrank)
764 this->_contiguous =
false;
766 this->_rowrank = new_rowrank;
767 this->_is_braket_form = this->_update_braket();
769 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<cytnx_int64> &new_labels);
770 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
const cytnx_int64 &new_label,
const bool &by_label=
false);
772 unsigned int dtype()
const{
774 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
776 return this->_blocks[0].dtype();
780 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
782 return this->_blocks[0].device();
784 std::string dtype_str()
const{
786 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
788 return this->_blocks[0].dtype_str();
790 std::string device_str()
const{
792 cytnx_error_msg(this->_blocks.size()==0,
"[ERROR][internal] empty blocks for blockform.%s",
"\n");
794 return this->_blocks[0].device_str();
797 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const{
798 SparseUniTensor* tmp = this->clone_meta(
true,
true);
799 tmp->_blocks.resize(this->_blocks.size());
800 for(
cytnx_int64 blk=0;blk<this->_blocks.size();blk++){
801 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
803 boost::intrusive_ptr<UniTensor_base> out(tmp);
807 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
808 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
809 boost::intrusive_ptr<UniTensor_base> contiguous();
810 boost::intrusive_ptr<UniTensor_base> contiguous_(){
811 if(!this->_contiguous){
812 boost::intrusive_ptr<UniTensor_base> titr = this->contiguous();
813 SparseUniTensor *tmp = (SparseUniTensor*)titr.get();
814 tmp->set_meta(
this,
true,
true);
815 this->_blocks = tmp->_blocks;
818 return boost::intrusive_ptr<UniTensor_base>(
this);
821 void print_diagram(
const bool &bond_info=
false);
824 std::vector<Symmetry> syms()
const;
827 cytnx_error_msg(idx>=this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
"\n");
828 if(this->_contiguous){
829 return this->_blocks[idx].clone();
831 cytnx_error_msg(
true,
"[Developing] get block from a non-contiguous SparseUniTensor is currently not support. Call contiguous()/contiguous_() first.%s",
"\n");
835 cytnx_uint64 Nblocks()
const{
return this->_blocks.size();};
836 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const{
838 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");
840 if(this->_contiguous){
844 for(
int i=0;i<this->_blockqnums.size();i++){
848 if(qnum==this->_blockqnums[i]){idx=i;
break;}
850 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
851 return this->get_block(idx);
853 cytnx_error_msg(
true,
"[Developing] get block from a non-contiguous SparseUniTensor is currently not support. Call contiguous()/contiguous_() first.%s",
"\n");
861 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");
863 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][SparseUniTensor] index exceed the number of blocks.%s",
"\n");
865 return this->_blocks[idx];
868 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");
870 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][SparseUniTensor] index exceed the number of blocks.%s",
"\n");
872 return this->_blocks[idx];
875 Tensor& get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force){
877 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");
879 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");
883 for(
int i=0;i<this->_blockqnums.size();i++){
884 if(qnum==this->_blockqnums[i]){idx=i;
break;}
886 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
887 return this->get_block_(idx);
890 const Tensor& get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const{
892 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");
894 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");
898 for(
int i=0;i<this->_blockqnums.size();i++){
899 if(qnum==this->_blockqnums[i]){idx=i;
break;}
901 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
902 return this->get_block_(idx);
905 std::vector<Tensor> get_blocks()
const {
906 if(this->_contiguous){
907 return vec_clone(this->_blocks);
910 boost::intrusive_ptr<UniTensor_base> tmp = this->clone();
912 SparseUniTensor *ttmp = (SparseUniTensor*)tmp.get();
913 return ttmp->_blocks;
917 const std::vector<Tensor>& get_blocks_(
const bool &silent=
false)
const {
919 if(this->_contiguous){
920 return this->_blocks;
924 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");
926 return this->_blocks;
929 std::vector<Tensor>& get_blocks_(
const bool &silent=
false){
931 if(this->_contiguous){
932 return this->_blocks;
935 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");
937 return this->_blocks;
941 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const{
942 if(rhs->uten_type()!=
UTenType.Sparse)
return false;
943 if(rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
945 for(
int i=0;i<rhs->get_blocks_(1).size();i++)
946 if(this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i])==
false)
return false;
955 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");
957 cytnx_error_msg(idx>=this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
"\n");
958 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);
959 this->_blocks[idx] = in;
962 cytnx_error_msg(idx>=this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
"\n");
963 if(this->_contiguous){
964 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);
965 this->_blocks[idx] = in.
clone();
967 cytnx_error_msg(
true,
"[Developing] put block to a non-contiguous SparseUniTensor is currently not support. Call contiguous()/contiguous_() first.%s",
"\n");
970 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force){
972 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");
976 for(
int i=0;i<this->_blockqnums.size();i++){
977 if(qnum==this->_blockqnums[i]){idx=i;
break;}
979 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
980 this->put_block(in,idx);
983 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force){
985 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");
989 for(
int i=0;i<this->_blockqnums.size();i++){
990 if(qnum==this->_blockqnums[i]){idx=i;
break;}
992 cytnx_error_msg(idx<0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
993 this->put_block_(in,idx);
997 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors){
998 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");
1002 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs){
1003 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");
1005 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0){
1006 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1008 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank=0){
1009 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1012 boost::intrusive_ptr<UniTensor_base> to_dense(){
1013 cytnx_error_msg(
true,
"[ERROR] cannot to_dense a UniTensor with symmetry.%s",
"\n");
1017 cytnx_error_msg(
true,
"[ERROR] cannot to_dense_ a UniTensor with symmetry.%s",
"\n");
1019 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &permute_back=
true,
const bool &by_label=
true){
1022 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);
1023 std::vector<Bond> getTotalQnums(
const bool &physical=
false);
1024 std::vector<std::vector<cytnx_int64> > get_blocks_qnums()
const{
1025 return this->_blockqnums;
1027 ~SparseUniTensor(){};
1031 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1032 void Add_(
const Scalar &rhs);
1034 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1035 void Mul_(
const Scalar &rhs);
1037 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1038 void Sub_(
const Scalar &rhs);
1039 void lSub_(
const Scalar &lhs);
1041 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1042 void Div_(
const Scalar &rhs);
1043 void lDiv_(
const Scalar &lhs);
1046 boost::intrusive_ptr<UniTensor_base>
Conj(){
1047 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1053 for(
int i=0;i<this->_blocks.size();i++){
1054 this->_blocks[i].Conj_();
1059 cytnx_error_msg(
true,
"[ERROR] Currently SparseUniTensor does not support inplace Trace!, call Trace() instead!%s",
"\n");
1063 boost::intrusive_ptr<UniTensor_base> Transpose(){
1064 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1069 boost::intrusive_ptr<UniTensor_base> Dagger(){
1070 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1086 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
1090 const cytnx_float& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux)
const;
1092 const cytnx_int64& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux)
const;
1094 const cytnx_int32& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux)
const;
1096 const cytnx_int16& at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux)
const;
1099 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
1111 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
1112 void _save_dispatch(std::fstream &f)
const;
1113 void _load_dispatch(std::fstream &f);
1128 boost::intrusive_ptr<UniTensor_base> _impl;
1131 this->_impl =
rhs._impl;
1134 this->_impl =
rhs._impl;
1190 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");
1201 else cytnx_error_msg(
is_sym,
"[ERROR] cannot have bonds with mixing of symmetry and non-symmetry.%s",
"\n");
1207 cytnx_warning_msg(
true,
"[DEBUG] message: entry dispatch: UniTensor: symmetric%s",
"\n");
1282 cytnx_error_msg(this->
is_blockform(),
"[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use get_block()/get_blocks() first.%s",
"\n");
1285 return tmp->_block.item<
T>();
1290 cytnx_error_msg(this->
is_blockform(),
"[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use get_block()/get_blocks() first.%s",
"\n");
1293 return tmp->_block.item();
1300 unsigned int dtype()
const{
return this->_impl->dtype(); }
1302 int device()
const{
return this->_impl->device(); }
1303 std::string
name()
const {
return this->_impl->name();}
1304 std::string
dtype_str()
const{
return this->_impl->dtype_str();}
1305 std::string
device_str()
const{
return this->_impl->device_str();}
1308 bool is_diag()
const{
return this->_impl->is_diag(); }
1309 bool is_tag()
const {
return this->_impl->is_tag();}
1310 std::vector<Symmetry>
syms()
const{
1311 return this->_impl->syms();
1314 return this->_impl->is_braket_form();
1316 const std::vector<cytnx_int64>&
labels()
const{
return this->_impl->labels();}
1317 const std::vector<Bond> &
bonds()
const {
return this->_impl->bonds();}
1318 std::vector<Bond> &
bonds() {
return this->_impl->bonds();}
1319 std::vector<cytnx_uint64>
shape()
const{
return this->_impl->shape();}
1346 if(this->
dtype()==dtype){
1347 out._impl = this->_impl;
1364 this->_impl = this->_impl->contiguous_();
1374 if(this->_impl->elem_exists(
locator)){
1376 return this->_impl->at_for_sparse(
locator,
aux);
1378 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
"\n");
1390 if(this->_impl->elem_exists(
locator)){
1392 return this->_impl->at_for_sparse(
locator,
aux);
1394 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
"\n");
1402 const Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator)
const{
1404 if(this->_impl->elem_exists(
locator)){
1405 return this->_impl->at_for_sparse(
locator);
1407 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
"\n");
1414 Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator){
1416 if(this->_impl->elem_exists(
locator)){
1417 return this->_impl->at_for_sparse(
locator);
1419 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
"\n");
1431 return this->_impl->get_block(
idx);
1436 return this->_impl->get_block(
qnum,
force);
1439 std::vector<cytnx_int64>
tmp =
qnum;
1445 return this->_impl->get_block_(
idx);
1450 return this->_impl->get_block_(
idx);
1455 return this->_impl->get_block_(
qnum,
force);
1458 std::vector<cytnx_int64>
tmp =
qnum;
1465 return this->_impl->get_block_(
qnum,
force);
1468 std::vector<cytnx_int64>
tmp =
qnum;
1469 return this->_impl->get_block_(
tmp,
force);
1475 return this->_impl->get_blocks();
1480 return this->_impl->get_blocks_(
silent);
1484 return this->_impl->get_blocks_(
silent);
1489 this->_impl->put_block(
in,
idx);
1497 this->_impl->put_block_(
in,
idx);
1525 this->_impl->to_dense_();
1536 return this->_impl->getTotalQnums(
physical);
1539 return this->_impl->get_blocks_qnums();
1545 if(this->_impl->uten_type() !=
rhs._impl->uten_type())
1550 return this->_impl->same_data(
rhs._impl);
1603 return this->_impl->
Norm();
1643 out._impl = this->_impl->
Conj();
1648 this->_impl->
Conj_();
1698 return this->_impl->elem_exists(
locator);
1704 return this->
at<T>(locator);
1711 this->
at(locator) =
rc;
1716 void Save(
const std::string &
fname)
const;
1733 void _Load(std::fstream &
f);
1734 void _Save(std::fstream &
f)
const;
Definition Scalar.hpp:1751
an tensor (multi-dimensional array)
Definition Tensor.hpp:333
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:819
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:906
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:712
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:885
T & at(const std::vector< cytnx_uint64 > &locator)
[C++ only] get an element at specific location.
Definition Tensor.hpp:1027
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:770
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
const bool & is_contiguous() const
Definition Tensor.hpp:823
Tensor & Conj_()
Definition Tensor.cpp:1180
int device() const
the device-id of the Tensor
Definition Tensor.hpp:719
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1122
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:740
An Enhanced tensor specifically designed for physical Tensor network simulation.
Definition UniTensor.hpp:1123
UniTensor to(const int &device) const
Definition UniTensor.hpp:1323
UniTensor & operator*=(const UniTensor &rhs)
Definition UniTensor.hpp:1618
UniTensor relabels(const std::vector< cytnx_int64 > &new_labels) const
Definition UniTensor.hpp:1333
std::vector< Tensor > & get_blocks_(const bool &silent=false)
Definition UniTensor.hpp:1483
UniTensor & operator/=(const UniTensor &rhs)
Definition UniTensor.hpp:1614
T & item()
Definition UniTensor.hpp:1280
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &permute_back=true, const bool &by_label=true)
Definition UniTensor.hpp:1527
bool is_contiguous() const
Definition UniTensor.hpp:1307
T get_elem(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:1703
UniTensor Div(const UniTensor &rhs) const
Definition UniTensor.cpp:32
const Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:1467
const std::vector< cytnx_int64 > & labels() const
Definition UniTensor.hpp:1316
Tensor & get_block_(const std::vector< cytnx_int64 > &qnum, const bool &force=false)
Definition UniTensor.hpp:1454
UniTensor & operator+=(const UniTensor &rhs)
Definition UniTensor.hpp:1606
void to_dense_()
Definition UniTensor.hpp:1524
UniTensor reshape(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Definition UniTensor.hpp:1511
std::vector< Tensor > get_blocks() const
Definition UniTensor.hpp:1474
bool is_tag() const
Definition UniTensor.hpp:1309
std::string uten_type_str() const
Definition UniTensor.hpp:1306
UniTensor permute(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1, const bool &by_label=false)
Definition UniTensor.hpp:1354
void put_block(const Tensor &in, const std::vector< cytnx_int64 > &qnum, const bool &force)
Definition UniTensor.hpp:1492
static UniTensor Load(const std::string &fname)
Definition UniTensor.cpp:152
UniTensor & tag()
Definition UniTensor.hpp:1685
UniTensor get(const std::vector< Accessor > &accessors) const
Definition UniTensor.hpp:1503
void Save(const std::string &fname) const
Definition UniTensor.cpp:131
UniTensor & operator-=(const Scalar &rhs)
Definition UniTensor.hpp:1626
cytnx_uint64 rowrank() const
Definition UniTensor.hpp:1299
Tensor Norm() const
Definition UniTensor.hpp:1602
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:1194
UniTensor & Sub_(const Scalar &rhs)
Definition UniTensor.hpp:1583
UniTensor & operator/=(const Scalar &rhs)
Definition UniTensor.hpp:1630
const bool & is_braket_form() const
Definition UniTensor.hpp:1313
void set_elem(const std::vector< cytnx_uint64 > &locator, const T2 &rc)
Definition UniTensor.hpp:1709
UniTensor relabel(const cytnx_int64 &inx, const cytnx_int64 &new_label, const bool &by_label=false) const
Definition UniTensor.hpp:1338
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:1188
std::vector< cytnx_uint64 > shape() const
Definition UniTensor.hpp:1319
UniTensor to_dense()
Definition UniTensor.hpp:1519
void reshape_(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Definition UniTensor.hpp:1516
const Tensor & get_block_(const std::vector< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:1464
std::string name() const
Definition UniTensor.hpp:1303
UniTensor & Add_(const Scalar &rhs)
Definition UniTensor.hpp:1573
std::vector< Bond > getTotalQnums(const bool physical=false) const
Definition UniTensor.hpp:1535
Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:1414
bool same_data(const UniTensor &rhs) const
Definition UniTensor.hpp:1542
UniTensor astype(const unsigned int &dtype) const
Definition UniTensor.hpp:1344
UniTensor Transpose() const
Definition UniTensor.hpp:1653
UniTensor & Dagger_()
Definition UniTensor.hpp:1680
void print_diagram(const bool &bond_info=false)
Definition UniTensor.hpp:1366
std::vector< Bond > & bonds()
Definition UniTensor.hpp:1318
T & at(const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:1371
UniTensor & truncate_(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim, const bool &by_label=false)
Definition UniTensor.hpp:1721
UniTensor & set_label(const cytnx_int64 &idx, const cytnx_int64 &new_label, const bool &by_label=false)
set a new label for bond at the assigned index.
Definition UniTensor.hpp:1239
std::vector< std::vector< cytnx_int64 > > get_blocks_qnums() const
Definition UniTensor.hpp:1538
UniTensor Trace(const cytnx_int64 &a=0, const cytnx_int64 &b=1, const bool &by_label=false) const
Definition UniTensor.hpp:1663
UniTensor contiguous() const
Definition UniTensor.hpp:1358
Tensor get_block(const cytnx_uint64 &idx=0) const
Definition UniTensor.hpp:1430
const T & at(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:1387
UniTensor & operator*=(const Scalar &rhs)
Definition UniTensor.hpp:1634
void contiguous_()
Definition UniTensor.hpp:1363
UniTensor & set_labels(const std::vector< cytnx_int64 > &new_labels)
change a new label for bond with original label.
Definition UniTensor.hpp:1270
std::vector< Symmetry > syms() const
Definition UniTensor.hpp:1310
UniTensor & Mul_(const UniTensor &rhs)
Definition UniTensor.hpp:1558
void put_block_(Tensor &in, const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:1496
void put_block_(Tensor &in, const std::vector< cytnx_int64 > &qnum, const bool &force)
Definition UniTensor.hpp:1500
bool is_diag() const
Definition UniTensor.hpp:1308
int device() const
Definition UniTensor.hpp:1302
UniTensor & Pow_(const double &p)
Definition UniTensor.cpp:14
void set(const std::vector< Accessor > &accessors, const Tensor &rhs)
Definition UniTensor.hpp:1508
std::string dtype_str() const
Definition UniTensor.hpp:1304
UniTensor & operator+=(const Scalar &rhs)
Definition UniTensor.hpp:1622
UniTensor & Div_(const UniTensor &rhs)
Definition UniTensor.hpp:1568
UniTensor & Div_(const Scalar &rhs)
Definition UniTensor.hpp:1588
cytnx_uint64 rank() const
Definition UniTensor.hpp:1298
void to_(const int &device)
Definition UniTensor.hpp:1322
UniTensor & set_name(const std::string &in)
set the name of the UniTensor
Definition UniTensor.hpp:1225
UniTensor & Add_(const UniTensor &rhs)
Definition UniTensor.hpp:1553
Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false)
Definition UniTensor.hpp:1457
unsigned int dtype() const
Definition UniTensor.hpp:1300
UniTensor Pow(const double &p) const
Definition UniTensor.cpp:11
UniTensor & Mul_(const Scalar &rhs)
Definition UniTensor.hpp:1578
UniTensor & operator-=(const UniTensor &rhs)
Definition UniTensor.hpp:1610
bool is_blockform() const
Definition UniTensor.hpp:1320
UniTensor Dagger() const
Definition UniTensor.hpp:1674
const std::vector< Tensor > & get_blocks_(const bool &silent=false) const
Definition UniTensor.hpp:1479
bool elem_exists(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:1697
UniTensor & Sub_(const UniTensor &rhs)
Definition UniTensor.hpp:1563
UniTensor contract(const UniTensor &inR, const bool &mv_elem_self=false, const bool &mv_elem_rhs=false) const
Definition UniTensor.hpp:1530
void put_block(const Tensor &in, const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:1488
const Tensor & get_block_(const cytnx_uint64 &idx=0) const
Definition UniTensor.hpp:1444
UniTensor Mul(const UniTensor &rhs) const
Definition UniTensor.cpp:39
UniTensor & Trace_(const cytnx_int64 &a=0, const cytnx_int64 &b=1, const bool &by_label=false)
Definition UniTensor.hpp:1669
Tensor get_block(const std::vector< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:1435
const std::vector< Bond > & bonds() const
Definition UniTensor.hpp:1317
UniTensor & Transpose_()
Definition UniTensor.hpp:1658
UniTensor clone() const
Definition UniTensor.hpp:1328
Scalar::Sproxy item() const
Definition UniTensor.hpp:1289
UniTensor truncate(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim, const bool &by_label=false) const
Definition UniTensor.hpp:1725
void Init(const Tensor &in_tensor, const cytnx_uint64 &rowrank, const bool &is_diag=false)
Definition UniTensor.hpp:1164
std::string device_str() const
Definition UniTensor.hpp:1305
UniTensor Sub(const UniTensor &rhs) const
Definition UniTensor.cpp:25
UniTensor & Conj_()
Definition UniTensor.hpp:1647
cytnx_uint64 Nblocks() const
Definition UniTensor.hpp:1297
UniTensor Conj()
Definition UniTensor.hpp:1641
UniTensor Add(const UniTensor &rhs) const
Definition UniTensor.cpp:18
UniTensor & set_rowrank(const cytnx_uint64 &new_rowrank)
Definition UniTensor.hpp:1274
void permute_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1, const bool &by_label=false)
Definition UniTensor.hpp:1355
UniTensor(const Tensor &in_tensor, const cytnx_uint64 &rowrank, const bool &is_diag=false)
Initialize a UniTensor with cytnx::Tensor.
Definition UniTensor.hpp:1161
Tensor get_block(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:1438
const Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:1402
int uten_type() const
Definition UniTensor.hpp:1301
Tensor & get_block_(const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:1449
#define cytnx_warning_msg(is_true, format,...)
Definition cytnx_error.hpp:37
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:18
Tensor Conj(const Tensor &Tin)
Conjugate all the element in Tensor.
Tensor Norm(const Tensor &Tl)
calculate the norm of a tensor.
cytnx::UniTensor Trace(const cytnx::UniTensor &Tin, const cytnx_int64 &a=0, const cytnx_int64 &b=1, const bool &by_label=false)
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:379
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