16#include <initializer_list>
25 using namespace cytnx;
27 class UniTensorType_class {
35 std::string getname(
const int &ut_type);
59 class UniTensor_base :
public intrusive_ptr_base<UniTensor_base> {
67 std::vector<std::string> _labels;
68 std::vector<Bond> _bonds;
70 bool _update_braket() {
71 if (_bonds.size() == 0)
return false;
73 if (this->_bonds[0].type() != bondType::BD_REG) {
75 for (
unsigned int i = 0; i < this->_bonds.size(); i++) {
76 if (i < this->_rowrank) {
77 if (this->_bonds[i].type() != bondType::BD_KET)
return false;
79 if (this->_bonds[i].type() != bondType::BD_BRA)
return false;
89 friend class DenseUniTensor;
90 friend class SparseUniTensor;
91 friend class BlockUniTensor;
96 _name(std::string(
"")),
97 _is_braket_form(false),
103 UniTensor_base(
const UniTensor_base &rhs);
104 UniTensor_base &operator=(UniTensor_base &rhs);
107 bool is_diag()
const {
return this->_is_diag; }
108 const bool &is_braket_form()
const {
return this->_is_braket_form; }
109 const bool &is_tag()
const {
return this->_is_tag; }
110 const std::vector<std::string> &labels()
const {
return this->_labels; }
118 std::vector<std::string> lbls = this->_labels;
120 if (lbls[i] == lbl)
return i;
124 const std::vector<Bond> &bonds()
const {
return this->_bonds; }
125 std::vector<Bond> &bonds() {
return this->_bonds; }
126 const std::string &name()
const {
return this->_name; }
127 cytnx_uint64 rank()
const {
return this->_labels.size(); }
128 void set_name(
const std::string &in) { this->_name = in; }
139 void set_label(
const std::string &oldlbl,
const std::string &new_label) {
141 auto res = std::find(this->_labels.begin(), this->_labels.end(), oldlbl);
142 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n", oldlbl.c_str());
143 idx = std::distance(this->_labels.begin(), res);
145 cytnx_error_msg(idx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
149 for (
cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
150 if (i == idx)
continue;
151 if (new_label == this->_labels[i]) {
156 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
158 this->_labels[idx] = new_label;
160 void set_label(
const cytnx_int64 &inx,
const std::string &new_label) {
163 cytnx_error_msg(inx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
167 for (
cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
168 if (i == inx)
continue;
169 if (new_label == this->_labels[i]) {
174 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
176 this->_labels[inx] = new_label;
187 set_label(inx, std::to_string(new_label));
197 std::string new_label = std::to_string(_new_label);
200 auto res = std::find(this->_labels.begin(), this->_labels.end(), std::to_string(inx));
201 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n", inx);
202 idx = std::distance(this->_labels.begin(), res);
207 set_label(idx,new_label);
217 void set_labels(
const std::vector<cytnx_int64> &new_labels);
218 void set_labels(
const std::vector<std::string> &new_labels);
252 int uten_type() {
return this->uten_type_id; }
253 std::string uten_type_str() {
return UTenType.getname(this->uten_type_id); }
259 virtual void Init(
const std::vector<Bond> &bonds,
260 const std::vector<std::string> &in_labels = {},
261 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
262 const int &device =
Device.cpu,
const bool &is_diag =
false,
263 const bool &no_alloc =
false,
const std::string &name =
"");
265 virtual void Init_by_Tensor(
const Tensor &in,
const bool &is_diag =
false,
266 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
267 virtual std::vector<cytnx_uint64> shape()
const;
268 virtual bool is_blockform()
const;
269 virtual bool is_contiguous()
const;
270 virtual void to_(
const int &device);
271 virtual boost::intrusive_ptr<UniTensor_base> to(
const int &device);
272 virtual boost::intrusive_ptr<UniTensor_base> clone()
const;
273 virtual unsigned int dtype()
const;
274 virtual int device()
const;
275 virtual std::string dtype_str()
const;
276 virtual std::string device_str()
const;
277 virtual void set_rowrank(
const cytnx_uint64 &new_rowrank);
281 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
283 const bool &by_label=
false);
284 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
289 virtual void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
290 const bool &by_label=
false);
291 virtual void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
293 virtual boost::intrusive_ptr<UniTensor_base> contiguous_();
294 virtual boost::intrusive_ptr<UniTensor_base> contiguous();
295 virtual void print_diagram(
const bool &bond_info =
false);
296 virtual void print_blocks(
const bool &full_info=
true)
const;
297 virtual void print_block(
const cytnx_int64 &idx,
const bool &full_info=
true)
const;
299 virtual boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const;
303 virtual Tensor get_block(
const std::vector<cytnx_int64> &qnum,
304 const bool &force)
const;
308 virtual const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
309 const bool &force)
const;
312 virtual Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
314 virtual bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const;
316 virtual std::vector<Tensor> get_blocks()
const;
317 virtual const std::vector<Tensor> &get_blocks_(
const bool &)
const;
318 virtual std::vector<Tensor> &get_blocks_(
const bool &);
322 virtual void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
324 virtual void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force);
327 virtual boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
330 virtual void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
332 virtual void reshape_(
const std::vector<cytnx_int64> &new_shape,
334 virtual boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
336 virtual boost::intrusive_ptr<UniTensor_base> to_dense();
337 virtual void to_dense_();
338 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
339 const bool &by_label);
340 virtual void combineBonds(
const std::vector<std::string> &indicators,
341 const bool &force =
false);
342 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
343 const bool &force =
false);
344 virtual boost::intrusive_ptr<UniTensor_base> contract(
345 const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self =
false,
346 const bool &mv_elem_rhs =
false);
347 virtual std::vector<Bond> getTotalQnums(
const bool &physical =
false);
348 virtual std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const;
349 virtual void Trace_(
const std::string &a,
const std::string &b);
352 virtual boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b);
355 const bool &by_label);
356 virtual boost::intrusive_ptr<UniTensor_base> relabels(
357 const std::vector<cytnx_int64> &new_labels);
358 virtual boost::intrusive_ptr<UniTensor_base> relabels(
359 const std::vector<std::string> &new_labels);
360 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
362 const bool &by_label);
363 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &inx,
364 const std::string &new_label);
365 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
367 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
368 const std::string &new_label);
370 virtual std::vector<Symmetry> syms()
const;
373 virtual void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
374 virtual void Add_(
const Scalar &rhs);
376 virtual void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
377 virtual void Mul_(
const Scalar &rhs);
379 virtual void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
380 virtual void Sub_(
const Scalar &rhs);
381 virtual void lSub_(
const Scalar &lhs);
383 virtual void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
384 virtual void Div_(
const Scalar &rhs);
385 virtual void lDiv_(
const Scalar &lhs);
388 virtual boost::intrusive_ptr<UniTensor_base> normalize();
389 virtual void normalize_();
391 virtual boost::intrusive_ptr<UniTensor_base>
Conj();
392 virtual void Conj_();
394 virtual boost::intrusive_ptr<UniTensor_base> Transpose();
395 virtual void Transpose_();
397 virtual boost::intrusive_ptr<UniTensor_base> Dagger();
398 virtual void Dagger_();
403 const bool &by_label);
404 virtual void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
407 virtual bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
410 virtual Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
411 virtual const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
413 virtual cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
415 virtual cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
417 virtual cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
419 virtual cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
421 virtual cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
423 virtual cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
425 virtual cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
427 virtual cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
429 virtual cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
431 virtual cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
434 virtual const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
436 virtual const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
438 virtual const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
440 virtual const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
442 virtual const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
444 virtual const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
446 virtual const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
448 virtual const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
450 virtual const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
452 virtual const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
455 virtual void group_basis_();
456 virtual const std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx)
const;
457 virtual std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx);
462 virtual void _save_dispatch(std::fstream &f)
const;
463 virtual void _load_dispatch(std::fstream &f);
465 virtual ~UniTensor_base(){};
471 class DenseUniTensor :
public UniTensor_base {
475 std::vector<Tensor> _interface_block;
476 DenseUniTensor *clone_meta()
const {
477 DenseUniTensor *
tmp =
new DenseUniTensor();
478 tmp->_bonds = vec_clone(this->_bonds);
479 tmp->_labels = this->_labels;
480 tmp->_is_braket_form = this->_is_braket_form;
481 tmp->_rowrank = this->_rowrank;
482 tmp->_is_diag = this->_is_diag;
483 tmp->_name = this->_name;
484 tmp->_is_tag = this->_is_tag;
489 DenseUniTensor() { this->uten_type_id =
UTenType.Dense; };
498 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
499 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
500 const int &device =
Device.cpu,
const bool &is_diag =
false,
501 const bool &no_alloc =
false,
const std::string &name =
"");
503 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
504 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
505 std::vector<cytnx_uint64> shape()
const {
506 if (this->_is_diag) {
507 std::vector<cytnx_uint64> shape = this->_block.
shape();
508 shape.push_back(shape[0]);
511 return this->_block.
shape();
514 bool is_blockform()
const {
return false; }
515 void to_(
const int &device) { this->_block.
to_(device); }
516 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
517 if (this->device() == device) {
518 std::vector<Tensor> _interface_block;
521 boost::intrusive_ptr<UniTensor_base> out = this->clone();
528 "[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
531 "[ERROR] rowrank should be [==1] when is_diag =true!.%s",
535 this->_rowrank = new_rowrank;
538 boost::intrusive_ptr<UniTensor_base> clone()
const {
539 DenseUniTensor *
tmp = this->clone_meta();
541 boost::intrusive_ptr<UniTensor_base> out(tmp);
544 bool is_contiguous()
const {
return this->_block.
is_contiguous(); }
545 unsigned int dtype()
const {
return this->_block.
dtype(); }
546 int device()
const {
return this->_block.
device(); }
547 std::string dtype_str()
const {
return Type.getname(this->_block.
dtype()); }
548 std::string device_str()
const {
return Device.getname(this->_block.
device()); }
559 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
560 const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
561 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
574 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
575 const bool &by_label=
false);
576 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
578 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
587 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<cytnx_int64> &new_labels);
598 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
600 const bool &by_label);
601 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &inx,
602 const std::string &new_label);
603 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
604 const std::string &new_label);
605 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
608 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
609 DenseUniTensor *
tmp = this->clone_meta();
610 tmp->_block = this->_block.
astype(dtype);
611 boost::intrusive_ptr<UniTensor_base> out(tmp);
615 std::vector<Symmetry> syms()
const {
616 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] dense unitensor does not have symmetry.%s",
618 return std::vector<Symmetry>();
621 boost::intrusive_ptr<UniTensor_base> contiguous_() {
623 return boost::intrusive_ptr<UniTensor_base>(
this);
625 boost::intrusive_ptr<UniTensor_base> contiguous() {
627 if (this->is_contiguous()) {
628 boost::intrusive_ptr<UniTensor_base> out(
this);
631 DenseUniTensor *
tmp = this->clone_meta();
633 boost::intrusive_ptr<UniTensor_base> out(tmp);
637 void print_diagram(
const bool &bond_info =
false);
638 void print_blocks(
const bool &full_info=
true)
const;
639 void print_block(
const cytnx_int64 &idx,
const bool &full_info=
true)
const;
642 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
644 true,
"[ERROR][DenseUniTensor] try to get_block() using qnum on a non-symmetry UniTensor%s",
649 const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
652 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
656 Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force) {
659 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
670 std::vector<Tensor> get_blocks()
const {
671 std::vector<Tensor> out;
673 true,
"[ERROR][DenseUniTensor] cannot use get_blocks(), use get_block() instead!%s",
"\n");
676 const std::vector<Tensor> &get_blocks_(
const bool &silent =
false)
const {
678 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
680 return this->_interface_block;
682 std::vector<Tensor> &get_blocks_(
const bool &silent =
false) {
684 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
686 return this->_interface_block;
690 if (this->is_diag()) {
692 in.
shape() != this->_block.shape(),
693 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
694 this->_block = in.
clone();
697 in.
shape() != this->shape(),
698 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
699 this->_block = in.
clone();
704 if (this->is_diag()) {
706 in.
shape() != this->_block.shape(),
707 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
711 in.
shape() != this->shape(),
712 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
717 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
719 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
722 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
724 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
728 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
729 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
730 out->Init_by_Tensor(this->_block.
get(accessors),
false, 0);
734 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
735 this->_block.
set(accessors, rhs);
738 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0);
739 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
741 boost::intrusive_ptr<UniTensor_base> to_dense();
752 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
753 const bool &by_label);
754 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
true);
755 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
true);
756 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
757 const bool &mv_elem_self =
false,
758 const bool &mv_elem_rhs =
false);
759 std::vector<Bond> getTotalQnums(
const bool &physical =
false) {
761 "getTotalQnums can only operate on UniTensor with symmetry.\n");
762 return std::vector<Bond>();
765 std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const {
767 "get_blocks_qnums can only operate on UniTensor with symmetry.\n");
768 return std::vector<std::vector<cytnx_int64>>();
771 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
772 if (rhs->uten_type() !=
UTenType.Dense)
return false;
774 return this->get_block_().same_data(rhs->get_block_());
780 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
781 void Add_(
const Scalar &rhs);
783 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
784 void Mul_(
const Scalar &rhs);
786 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
787 void Sub_(
const Scalar &rhs);
788 void lSub_(
const Scalar &lhs);
790 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
791 void Div_(
const Scalar &rhs);
792 void lDiv_(
const Scalar &lhs);
796 boost::intrusive_ptr<UniTensor_base>
Conj() {
797 boost::intrusive_ptr<UniTensor_base> out = this->clone();
802 boost::intrusive_ptr<UniTensor_base> Transpose() {
803 boost::intrusive_ptr<UniTensor_base> out = this->clone();
809 boost::intrusive_ptr<UniTensor_base> normalize() {
810 boost::intrusive_ptr<UniTensor_base> out = this->clone();
816 boost::intrusive_ptr<UniTensor_base> Dagger() {
817 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
836 void Trace_(
const std::string &a,
const std::string &b);
837 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
838 boost::intrusive_ptr<UniTensor_base> out = this->clone();
843 boost::intrusive_ptr<UniTensor_base> out = this->clone();
857 const bool &by_label) {
858 boost::intrusive_ptr<UniTensor_base> out = this->clone();
859 out->Trace_(a, b, by_label);
865 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const {
867 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
871 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
874 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
878 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
881 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
885 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
888 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
892 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
895 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
899 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
902 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
906 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
909 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
913 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
916 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
920 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
923 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
927 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
930 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
934 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
937 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
942 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator) {
944 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
951 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
955 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
958 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
964 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
970 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
976 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
982 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
988 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
994 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1000 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1006 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1011 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const {
1013 true,
"[ERROR][DenseUniTensor] elem_exists can only be used on UniTensor with Symmetry.%s",
1017 if (!this->is_tag()) {
1018 for (
int i = 0; i < this->_rowrank; i++) {
1019 this->_bonds[i].set_type(BD_KET);
1021 for (
int i = this->_rowrank; i < this->_bonds.size(); i++) {
1022 this->_bonds[i].set_type(BD_BRA);
1024 this->_is_tag =
true;
1025 this->_is_braket_form = this->_update_braket();
1039 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
1041 void group_basis_(){
1042 cytnx_warning_msg(
true,
"[WARNING] group basis will not have any effect on DensUniTensor.%s",
"\n");
1045 void _save_dispatch(std::fstream &f)
const;
1046 void _load_dispatch(std::fstream &f);
1048 const std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx)
const{
1049 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
"\n");
1052 std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx){
1053 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
"\n");
1057 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
"\n");
1060 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
"\n");
1070 class SparseUniTensor :
public UniTensor_base {
1074 std::vector<std::vector<cytnx_int64>> _blockqnums;
1075 std::vector<cytnx_uint64> _mapper;
1076 std::vector<cytnx_uint64> _inv_mapper;
1077 std::vector<std::vector<cytnx_uint64>> _inner2outer_row;
1078 std::vector<std::vector<cytnx_uint64>> _inner2outer_col;
1079 std::map<cytnx_uint64, std::pair<cytnx_uint64, cytnx_uint64>> _outer2inner_row;
1080 std::map<cytnx_uint64, std::pair<cytnx_uint64, cytnx_uint64>> _outer2inner_col;
1082 std::vector<Tensor> _blocks;
1085 void set_meta(SparseUniTensor *tmp,
const bool &inner,
const bool &outer)
const {
1088 tmp->_bonds = vec_clone(this->_bonds);
1089 tmp->_labels = this->_labels;
1090 tmp->_is_braket_form = this->_is_braket_form;
1091 tmp->_rowrank = this->_rowrank;
1092 tmp->_name = this->_name;
1095 tmp->_mapper = this->_mapper;
1096 tmp->_inv_mapper = this->_inv_mapper;
1097 tmp->_contiguous = this->_contiguous;
1098 tmp->_is_diag = this->_is_diag;
1102 tmp->_inner_rowrank = this->_inner_rowrank;
1103 tmp->_inner2outer_row = this->_inner2outer_row;
1104 tmp->_inner2outer_col = this->_inner2outer_col;
1105 tmp->_outer2inner_row = this->_outer2inner_row;
1106 tmp->_outer2inner_col = this->_outer2inner_col;
1107 tmp->_blockqnums = this->_blockqnums;
1110 SparseUniTensor *clone_meta(
const bool &inner,
const bool &outer)
const {
1111 SparseUniTensor *
tmp =
new SparseUniTensor();
1112 this->set_meta(tmp, inner, outer);
1119 this->uten_type_id =
UTenType.Sparse;
1120 this->_is_tag =
true;
1128 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
1129 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
1130 const int &device =
Device.cpu,
const bool &is_diag =
false,
1131 const bool &no_alloc =
false,
const std::string &name =
"");
1133 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
1134 const cytnx_int64 &rowrank = -1,
const std::string &name =
"") {
1136 true,
"[ERROR][SparseUniTensor] cannot use Init_by_tensor() on a SparseUniTensor.%s",
"\n");
1138 std::vector<cytnx_uint64> shape()
const {
1139 std::vector<cytnx_uint64> out(this->_bonds.size());
1141 out[i] = this->_bonds[i].dim();
1145 bool is_blockform()
const {
return true; }
1146 void to_(
const int &device) {
1147 for (
cytnx_uint64 i = 0; i < this->_blocks.size(); i++) {
1148 this->_blocks[i].to_(device);
1151 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
1152 if (this->device() == device) {
1155 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1160 boost::intrusive_ptr<UniTensor_base> clone()
const {
1161 SparseUniTensor *
tmp = this->clone_meta(
true,
true);
1162 tmp->_blocks = vec_clone(this->_blocks);
1163 boost::intrusive_ptr<UniTensor_base> out(tmp);
1167 bool is_contiguous()
const {
return this->_contiguous; };
1170 "[ERROR][SparseUniTensor] rowrank should be [>=1] and [<UniTensor.rank].%s",
1173 "[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
1174 if (this->_inner_rowrank != new_rowrank) this->_contiguous =
false;
1176 this->_rowrank = new_rowrank;
1177 this->_is_braket_form = this->_update_braket();
1187 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<cytnx_int64> &new_labels);
1188 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
1199 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
1201 const bool &by_label);
1202 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
1204 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
1205 const std::string &new_label);
1206 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &inx,
1207 const std::string &new_label);
1208 unsigned int dtype()
const {
1210 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1213 return this->_blocks[0].dtype();
1215 int device()
const {
1217 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1220 return this->_blocks[0].device();
1222 std::string dtype_str()
const {
1224 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1227 return this->_blocks[0].dtype_str();
1229 std::string device_str()
const {
1231 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1234 return this->_blocks[0].device_str();
1237 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
1238 SparseUniTensor *
tmp = this->clone_meta(
true,
true);
1239 tmp->_blocks.resize(this->_blocks.size());
1240 for (
cytnx_int64 blk = 0; blk < this->_blocks.size(); blk++) {
1241 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
1243 boost::intrusive_ptr<UniTensor_base> out(tmp);
1256 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
1257 const bool &by_label=
false);
1259 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
1270 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
1271 const cytnx_int64 &rowrank=-1,
const bool &by_label=
false);
1274 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
1276 boost::intrusive_ptr<UniTensor_base> contiguous();
1277 boost::intrusive_ptr<UniTensor_base> contiguous_() {
1278 if (!this->_contiguous) {
1279 boost::intrusive_ptr<UniTensor_base> titr = this->contiguous();
1280 SparseUniTensor *
tmp = (SparseUniTensor *)titr.get();
1281 tmp->set_meta(
this,
true,
true);
1282 this->_blocks =
tmp->_blocks;
1284 return boost::intrusive_ptr<UniTensor_base>(
this);
1286 void print_diagram(
const bool &bond_info =
false);
1287 void print_blocks(
const bool &full_info=
true)
const;
1288 void print_block(
const cytnx_int64 &idx,
const bool &full_info=
true)
const;
1289 std::vector<Symmetry> syms()
const;
1292 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
1294 if (this->_contiguous) {
1295 return this->_blocks[idx].clone();
1298 "[Developing] get block from a non-contiguous SparseUniTensor is currently "
1299 "not support. Call contiguous()/contiguous_() first.%s",
1304 cytnx_uint64 Nblocks()
const {
return this->_blocks.size(); };
1305 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
1308 !this->is_braket_form(),
1309 "[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch "
1310 "the row/col space.\n permute to the correct physical space first, then get block.%s",
1313 if (this->_contiguous) {
1317 for (
int i = 0; i < this->_blockqnums.size(); i++) {
1321 if (qnum == this->_blockqnums[i]) {
1328 "[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
"\n");
1329 return this->get_block(idx);
1332 "[Developing] get block from a non-contiguous SparseUniTensor is currently "
1333 "not support. Call contiguous()/contiguous_() first.%s",
1343 this->is_contiguous() ==
false,
1344 "[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with "
1345 "symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call "
1346 "get_block_()\n 2) Try get_block()/get_blocks()%s",
1350 "[ERROR][SparseUniTensor] index exceed the number of blocks.%s",
"\n");
1352 return this->_blocks[idx];
1356 this->is_contiguous() ==
false,
1357 "[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with "
1358 "symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call "
1359 "get_block_()\n 2) Try get_block()/get_blocks()%s",
1363 "[ERROR][SparseUniTensor] index exceed the number of blocks.%s",
"\n");
1365 return this->_blocks[idx];
1368 Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force) {
1371 !this->is_braket_form(),
1372 "[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch "
1373 "the row/col space.\n permute to the correct physical space first, then get block.%s",
1377 this->is_contiguous() ==
false,
1378 "[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with "
1379 "symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call "
1380 "get_blocks_()\n 2) Try get_block()/get_blocks()%s",
1385 for (
int i = 0; i < this->_blockqnums.size(); i++) {
1386 if (qnum == this->_blockqnums[i]) {
1392 idx < 0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
1394 return this->get_block_(idx);
1397 const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
1400 !this->is_braket_form(),
1401 "[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch "
1402 "the row/col space.\n permute to the correct physical space first, then get block.%s",
1406 this->is_contiguous() ==
false,
1407 "[ERROR][SparseUniTensor] cannot use get_block_() on non-contiguous UniTensor with "
1408 "symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call "
1409 "get_blocks_()\n 2) Try get_block()/get_blocks()%s",
1414 for (
int i = 0; i < this->_blockqnums.size(); i++) {
1415 if (qnum == this->_blockqnums[i]) {
1421 idx < 0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
1423 return this->get_block_(idx);
1426 std::vector<Tensor> get_blocks()
const {
1427 if (this->_contiguous) {
1428 return vec_clone(this->_blocks);
1431 boost::intrusive_ptr<UniTensor_base>
tmp = this->clone();
1433 SparseUniTensor *ttmp = (SparseUniTensor *)
tmp.get();
1434 return ttmp->_blocks;
1438 const std::vector<Tensor> &get_blocks_(
const bool &silent =
false)
const {
1440 if (this->_contiguous) {
1441 return this->_blocks;
1447 "[WARNING][SparseUniTensor] call get_blocks_() with a non-contiguous UniTensor should "
1448 "be used with caution. \ntry: \n1) get_blocks()\n2) call contiguous/contiguous_() "
1449 "first, then get_blocks_() to get concise results%s",
1452 return this->_blocks;
1455 std::vector<Tensor> &get_blocks_(
const bool &silent =
false) {
1457 if (this->_contiguous) {
1458 return this->_blocks;
1463 "[WARNING][SparseUniTensor] call get_blocks_() with a non-contiguous UniTensor should "
1464 "be used with caution. \ntry: \n1) get_blocks()\n2) call contiguous/contiguous_() "
1465 "first, then get_blocks_() to get concise results%s",
1468 return this->_blocks;
1472 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
1473 if (rhs->uten_type() !=
UTenType.Sparse)
return false;
1474 if (rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
1476 for (
int i = 0; i < rhs->get_blocks_(1).size(); i++)
1477 if (this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i]) ==
false)
return false;
1484 this->is_contiguous() ==
false,
1485 "[ERROR][SparseUniTensor] cannot use put_block_() on non-contiguous UniTensor with "
1486 "symmetry.\n suggest options: \n 1) Call contiguous_()/contiguous() first, then call "
1487 "put_blocks_()\n 2) Try put_block()/put_blocks()%s",
1490 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
1493 "[ERROR][SparseUniTensor] the shape of input tensor does not match the shape "
1494 "of block @ idx=%d\n",
1496 this->_blocks[idx] = in;
1499 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][SparseUniTensor] index out of range%s",
1501 if (this->_contiguous) {
1503 "[ERROR][SparseUniTensor] the shape of input tensor does not match the "
1504 "shape of block @ idx=%d\n",
1506 this->_blocks[idx] = in.
clone();
1509 "[Developing] put block to a non-contiguous SparseUniTensor is currently "
1510 "not support. Call contiguous()/contiguous_() first.%s",
1514 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
1517 !this->is_braket_form(),
1518 "[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch "
1519 "the row/col space.\n permute to the correct physical space first, then get block.%s",
1524 for (
int i = 0; i < this->_blockqnums.size(); i++) {
1525 if (qnum == this->_blockqnums[i]) {
1531 idx < 0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
1533 this->put_block(in, idx);
1535 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
1538 !this->is_braket_form(),
1539 "[ERROR][Un-physical] cannot get the block by qnums when bra-ket/in-out bonds mismatch "
1540 "the row/col space.\n permute to the correct physical space first, then get block.%s",
1545 for (
int i = 0; i < this->_blockqnums.size(); i++) {
1546 if (qnum == this->_blockqnums[i]) {
1552 idx < 0,
"[ERROR][SparseUniTensor] no block with [qnum] exists in the current UniTensor.%s",
1554 this->put_block_(in, idx);
1558 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
1560 "[ERROR][SparseUniTensor][get] cannot use get on a UniTensor with "
1561 "Symmetry.\n suggestion: try get_block()/get_blocks() first.%s",
1566 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
1568 "[ERROR][SparseUniTensor][set] cannot use set on a UniTensor with "
1569 "Symmetry.\n suggestion: try get_block()/get_blocks() first.%s",
1572 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0) {
1573 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1575 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
1577 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1580 boost::intrusive_ptr<UniTensor_base> to_dense() {
1581 cytnx_error_msg(
true,
"[ERROR] cannot to_dense a UniTensor with symmetry.%s",
"\n");
1585 cytnx_error_msg(
true,
"[ERROR] cannot to_dense_ a UniTensor with symmetry.%s",
"\n");
1596 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
1597 const bool &by_label) {
1600 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
true) {
1603 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
true) {
1606 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
1607 const bool &mv_elem_self =
false,
1608 const bool &mv_elem_rhs =
false);
1609 std::vector<Bond> getTotalQnums(
const bool &physical =
false);
1610 std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const {
return this->_blockqnums; }
1611 ~SparseUniTensor(){};
1614 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1615 void Add_(
const Scalar &rhs);
1617 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1618 void Mul_(
const Scalar &rhs);
1620 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1621 void Sub_(
const Scalar &rhs);
1622 void lSub_(
const Scalar &lhs);
1624 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1625 void Div_(
const Scalar &rhs);
1626 void lDiv_(
const Scalar &lhs);
1628 boost::intrusive_ptr<UniTensor_base>
Conj() {
1629 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1635 for (
int i = 0; i < this->_blocks.size(); i++) {
1636 this->_blocks[i].Conj_();
1640 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b);
1652 const bool &by_label);
1655 "[ERROR] Currently SparseUniTensor does not support inplace Trace!, call "
1656 "Trace() instead!%s",
1659 void Trace_(
const std::string &a,
const std::string &b) {
1661 "[ERROR] Currently SparseUniTensor does not support inplace Trace!, call "
1662 "Trace() instead!%s",
1676 "[ERROR] Currently SparseUniTensor does not support inplace Trace!, call "
1677 "Trace() instead!%s",
1682 boost::intrusive_ptr<UniTensor_base> Transpose() {
1683 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1688 boost::intrusive_ptr<UniTensor_base> Dagger() {
1689 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1700 boost::intrusive_ptr<UniTensor_base> normalize() {
1701 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1706 cytnx_error_msg(
true,
"[ERROR] SparseUniTensor is about to deprecated.%s",
"\n");
1723 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
1724 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
1725 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1727 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1729 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1731 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1733 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1735 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1737 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1739 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1741 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1743 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1746 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
1749 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1760 void group_basis_(){
1761 cytnx_warning_msg(
true,
"[WARNING] group basis will not have any effect on SparseUniTensor.%s",
"\n");
1764 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
1765 void _save_dispatch(std::fstream &f)
const;
1766 void _load_dispatch(std::fstream &f);
1768 const std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx)
const{
1769 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] get_qindices can only be unsed on BlockUniTensor with Symmetry.%s",
"\n");
1771 std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx){
1772 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] get_qindices can only be unsed on BlockUniTensor.%s",
"\n");
1775 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] get_itoi can only be unsed on BlockUniTensor with Symmetry.%s",
"\n");
1778 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] get_itoi can only be unsed on BlockUniTensor with Symmetry.%s",
"\n");
1789 class BlockUniTensor :
public UniTensor_base {
1793 std::vector<std::vector<cytnx_uint64> > _inner_to_outer_idx;
1794 std::vector<Tensor> _blocks;
1800 void _fx_get_total_fluxs(std::vector<cytnx_uint64> &loc,
const std::vector<Symmetry> &syms, std::vector<cytnx_int64> &total_qns){
1801 memset(&total_qns[0],0,
sizeof(
cytnx_int64)*total_qns.size());
1804 if(this->_bonds[0].type() == BD_BRA)
1805 total_qns[i] = syms[0].reverse_rule(this->_bonds[0]._impl->_qnums[loc[0]][i]);
1807 total_qns[i] = this->_bonds[0]._impl->_qnums[loc[0]][i];
1809 for(
auto j=1;j<loc.size();j++){
1810 if(this->_bonds[j].type() == BD_BRA)
1811 total_qns[i] = syms[i].combine_rule(total_qns[i],syms[i].reverse_rule(this->_bonds[j]._impl->_qnums[loc[j]][i]));
1813 total_qns[i] = syms[i].combine_rule(total_qns[i],this->_bonds[j]._impl->_qnums[loc[j]][i]);
1821 void _fx_locate_elem(
cytnx_int64 &bidx, std::vector<cytnx_uint64> &loc_in_T,
const std::vector<cytnx_uint64> &locator)
const;
1824 void _fx_group_duplicates(
const std::vector<cytnx_uint64> &dup_bond_idxs,
const std::vector<std::vector<cytnx_uint64> > &idx_mappers);
1827 void set_meta(BlockUniTensor *tmp,
const bool &inner,
const bool &outer)
const {
1830 tmp->_bonds = vec_clone(this->_bonds);
1831 tmp->_labels = this->_labels;
1832 tmp->_is_braket_form = this->_is_braket_form;
1833 tmp->_rowrank = this->_rowrank;
1834 tmp->_name = this->_name;
1837 tmp->_is_diag = this->_is_diag;
1841 tmp->_inner_to_outer_idx = this->_inner_to_outer_idx;
1846 BlockUniTensor *clone_meta(
const bool &inner,
const bool &outer)
const {
1847 BlockUniTensor *
tmp =
new BlockUniTensor();
1848 this->set_meta(tmp, inner, outer);
1856 this->uten_type_id =
UTenType.Block;
1857 this->_is_tag =
true;
1866 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
1867 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
1868 const int &device =
Device.cpu,
const bool &is_diag =
false,
1869 const bool &no_alloc =
false,
const std::string &name =
"");
1871 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
1872 const cytnx_int64 &rowrank = -1,
const std::string &name =
"") {
1874 true,
"[ERROR][BlockUniTensor] cannot use Init_by_tensor() on a BlockUniTensor.%s",
"\n");
1878 std::vector<cytnx_uint64> shape()
const {
1879 std::vector<cytnx_uint64> out(this->_bonds.size());
1881 out[i] = this->_bonds[i].dim();
1886 bool is_blockform()
const {
return true; }
1887 bool is_contiguous()
const {
1889 for(
int i=0;i<this->_blocks.size();i++){
1890 out &= this->_blocks[i].is_contiguous();
1895 cytnx_uint64 Nblocks()
const {
return this->_blocks.size(); };
1897 void to_(
const int &device) {
1898 for (
cytnx_uint64 i = 0; i < this->_blocks.size(); i++) {
1899 this->_blocks[i].to_(device);
1903 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
1904 if (this->device() == device) {
1907 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1913 boost::intrusive_ptr<UniTensor_base> clone()
const {
1914 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
1915 tmp->_blocks = vec_clone(this->_blocks);
1916 boost::intrusive_ptr<UniTensor_base> out(tmp);
1920 unsigned int dtype()
const {
1922 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1925 return this->_blocks[0].dtype();
1927 int device()
const {
1929 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1932 return this->_blocks[0].device();
1934 std::string dtype_str()
const {
1936 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1939 return this->_blocks[0].dtype_str();
1941 std::string device_str()
const {
1943 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1946 return this->_blocks[0].device_str();
1951 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1953 return this->_blocks[idx].clone();
1957 Tensor get_block(
const std::vector<cytnx_int64> &indices,
const bool &force_return)
const {
1959 cytnx_error_msg(indices.size()!=this->rank(),
"[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the Tensor rank (number of legs).%s",
"\n");
1961 std::vector<cytnx_uint64> inds(indices.begin(),indices.end());
1966 for(
cytnx_uint64 i=0;i<this->_inner_to_outer_idx.size();i++){
1967 if(inds == this->_inner_to_outer_idx[i]){
1975 return NullRefTensor;
1977 cytnx_error_msg(
true,
"[ERROR][get_block][BlockUniTensor] no avaliable block exists, force_return=false, so error throws. \n If you want to return an empty block without error when block is not avaliable, set force_return=True.%s",
"\n");
1980 return this->_blocks[b].clone();
1985 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1987 return this->_blocks[idx];
1991 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1993 return this->_blocks[idx];
1996 const Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
const bool &force_return)
const {
1997 cytnx_error_msg(indices.size()!=this->rank(),
"[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the Tensor rank (number of legs).%s",
"\n");
1999 std::vector<cytnx_uint64> inds(indices.begin(),indices.end());
2003 for(
cytnx_uint64 i=0;i<this->_inner_to_outer_idx.size();i++){
2004 if(inds == this->_inner_to_outer_idx[i]){
2012 return this->NullRefTensor;
2014 cytnx_error_msg(
true,
"[ERROR][get_block][BlockUniTensor] no avaliable block exists, force_return=false, so error throws. \n If you want to return an empty block without error when block is not avaliable, set force_return=True.%s",
"\n");
2017 return this->_blocks[b];
2022 Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
const bool &force_return){
2023 cytnx_error_msg(indices.size()!=this->rank(),
"[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the Tensor rank (number of legs).%s",
"\n");
2025 std::vector<cytnx_uint64> inds(indices.begin(),indices.end());
2029 for(
cytnx_uint64 i=0;i<this->_inner_to_outer_idx.size();i++){
2030 if(inds == this->_inner_to_outer_idx[i]){
2038 return this->NullRefTensor;
2040 cytnx_error_msg(
true,
"[ERROR][get_block][BlockUniTensor] no avaliable block exists, force_return=false, so error throws. \n If you want to return an empty block without error when block is not avaliable, set force_return=True.%s",
"\n");
2043 return this->_blocks[b];
2048 std::vector<Tensor> get_blocks()
const{
2049 return vec_clone(this->_blocks);
2051 const std::vector<Tensor> &get_blocks_(
const bool &)
const{
2052 return this->_blocks;
2054 std::vector<Tensor> &get_blocks_(
const bool &){
2055 return this->_blocks;
2060 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
2061 if (rhs->uten_type() !=
UTenType.Block)
return false;
2062 if (rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
2064 for (
int i = 0; i < rhs->get_blocks_(1).size(); i++)
2065 if (this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i]) ==
false)
return false;
2074 "[ERROR][BlockUniTensor] rowrank should be [>=0] and [<=UniTensor.rank].%s",
2076 if(this->is_diag()){
2078 "[ERROR][BlockUniTensor] rowrank should be [==1] when is_diag =true!.%s",
2081 this->_rowrank = new_rowrank;
2082 this->_is_braket_form = this->_update_braket();
2085 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
2087 const bool &by_label=
false);
2088 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
2093 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank=-1,
2094 const bool &by_label=
false);
2095 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
2099 boost::intrusive_ptr<UniTensor_base> contiguous_() {
2100 for(
unsigned int b=0;b<this->_blocks.size();b++)
2101 this->_blocks[b].contiguous_();
2102 return boost::intrusive_ptr<UniTensor_base>(
this);
2105 boost::intrusive_ptr<UniTensor_base> contiguous();
2108 void print_diagram(
const bool &bond_info =
false);
2109 void print_blocks(
const bool &full_info=
true)
const;
2110 void print_block(
const cytnx_int64 &idx,
const bool &full_info=
true)
const;
2112 boost::intrusive_ptr<UniTensor_base> contract(
2113 const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self =
false,
2114 const bool &mv_elem_rhs =
false);
2117 boost::intrusive_ptr<UniTensor_base> relabels(
2118 const std::vector<cytnx_int64> &new_labels);
2119 boost::intrusive_ptr<UniTensor_base> relabels(
2120 const std::vector<std::string> &new_labels);
2121 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
2123 const bool &by_label);
2124 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &inx,
2125 const std::string &new_label);
2126 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
2128 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
2129 const std::string &new_label);
2131 std::vector<Symmetry> syms()
const;
2133 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0) {
2134 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
2136 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
2138 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
2142 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
2143 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
2144 tmp->_blocks.resize(this->_blocks.size());
2145 for (
cytnx_int64 blk = 0; blk < this->_blocks.size(); blk++) {
2146 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
2148 boost::intrusive_ptr<UniTensor_base> out(tmp);
2153 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors){
2155 "[ERROR][BlockUniTensor][get] cannot use get on a UniTensor with "
2156 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
2163 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs){
2165 "[ERROR][BlockUniTensor][get] cannot use get on a UniTensor with "
2166 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
2171 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
2174 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
2175 "of block @ idx=%d\n",
2178 this->_blocks[idx] = in.
clone();
2181 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
2184 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
2185 "of block @ idx=%d\n",
2188 this->_blocks[idx] = in;
2191 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &indices,
2194 cytnx_error_msg(indices.size()!=this->rank(),
"[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the Tensor rank (number of legs).%s",
"\n");
2196 std::vector<cytnx_uint64> inds(indices.begin(),indices.end());
2200 for(
cytnx_uint64 i=0;i<this->_inner_to_outer_idx.size();i++){
2201 if(inds == this->_inner_to_outer_idx[i]){
2209 cytnx_error_msg(
true,
"[ERROR][put_block][BlockUniTensor] no avaliable block exists, check=true, so error throws. \n If you want without error when block is not avaliable, set check=false.%s",
"\n");
2213 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
2214 "of block @ idx=%d\n",
2217 this->_blocks[b] = in.
clone();
2222 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &indices,
const bool &check){
2223 cytnx_error_msg(indices.size()!=this->rank(),
"[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the Tensor rank (number of legs).%s",
"\n");
2225 std::vector<cytnx_uint64> inds(indices.begin(),indices.end());
2229 for(
cytnx_uint64 i=0;i<this->_inner_to_outer_idx.size();i++){
2230 if(inds == this->_inner_to_outer_idx[i]){
2238 cytnx_error_msg(
true,
"[ERROR][put_block][BlockUniTensor] no avaliable block exists, check=true, so error throws. \n If you want without error when block is not avaliable, set check=false.%s",
"\n");
2242 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
2243 "of block @ idx=%d\n",
2245 this->_blocks[b] = in;
2255 boost::intrusive_ptr<UniTensor_base>
Conj() {
2256 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2262 for (
int i = 0; i < this->_blocks.size(); i++) {
2263 this->_blocks[i].Conj_();
2268 boost::intrusive_ptr<UniTensor_base> Transpose() {
2269 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2275 boost::intrusive_ptr<UniTensor_base> normalize() {
2276 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2282 boost::intrusive_ptr<UniTensor_base> Dagger() {
2283 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
2292 void Trace_(
const std::string &a,
const std::string &b);
2296 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
2297 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2300 DenseUniTensor *
tmp =
new DenseUniTensor();
2301 tmp->_block = ((BlockUniTensor*)out.get())->_blocks[0];
2302 out = boost::intrusive_ptr<UniTensor_base>(tmp);
2307 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2310 DenseUniTensor *
tmp =
new DenseUniTensor();
2311 tmp->_block = ((BlockUniTensor*)out.get())->_blocks[0];
2312 out = boost::intrusive_ptr<UniTensor_base>(tmp);
2326 const bool &by_label) {
2327 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2328 out->Trace_(a, b, by_label);
2330 DenseUniTensor *
tmp =
new DenseUniTensor();
2331 tmp->_block = ((BlockUniTensor*)out.get())->_blocks[0];
2332 out = boost::intrusive_ptr<UniTensor_base>(tmp);
2339 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
2341 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
2342 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2344 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2346 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2348 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2350 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2352 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2354 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2356 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2358 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2360 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2363 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
2366 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2377 void _save_dispatch(std::fstream &f)
const;
2378 void _load_dispatch(std::fstream &f);
2382 const bool &by_label);
2383 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &q_index);
2387 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
2388 void Add_(
const Scalar &rhs){
2389 cytnx_error_msg(
true,
"[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
2390 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do operation on the block(s).");
2393 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
2394 void Mul_(
const Scalar &rhs);
2396 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
2397 void Sub_(
const Scalar &rhs){
2398 cytnx_error_msg(
true,
"[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
2399 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do operation on the block(s).");
2401 void lSub_(
const Scalar &lhs){
2402 cytnx_error_msg(
true,
"[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
2403 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do operation on the block(s).");
2406 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs){
2407 cytnx_error_msg(
true,
"[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
2408 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do operation on the block(s).");
2411 void Div_(
const Scalar &rhs);
2412 void lDiv_(
const Scalar &lhs){
2413 cytnx_error_msg(
true,
"[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
2414 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do operation on the block(s).");
2417 void group_basis_();
2419 void combineBonds(
const std::vector<cytnx_int64> &indicators,
2420 const bool &force =
false);
2421 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
2422 const bool &by_label);
2423 void combineBonds(
const std::vector<std::string> &indicators,
2424 const bool &force =
false);
2426 const std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx)
const{
2427 cytnx_error_msg(bidx>=this->Nblocks(),
"[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",this->Nblocks());
2428 return this->_inner_to_outer_idx[bidx];
2430 std::vector<cytnx_uint64>& get_qindices(
const cytnx_uint64 &bidx){
2431 cytnx_error_msg(bidx>=this->Nblocks(),
"[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",this->Nblocks());
2432 return this->_inner_to_outer_idx[bidx];
2436 return this->_inner_to_outer_idx;
2439 return this->_inner_to_outer_idx;
2452 boost::intrusive_ptr<UniTensor_base> _impl;
2453 UniTensor() : _impl(
new UniTensor_base()){};
2456 this->_impl = rhs._impl;
2490 : _impl(new UniTensor_base()) {
2513 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
2536 UniTensor(
const std::vector<Bond> &
bonds,
const std::vector<std::string> &in_labels = {},
2539 : _impl(new UniTensor_base()) {
2543 "[DEBUG] message: entry for UniTensor(const std::vector<Bond> &bonds, const "
2544 "std::vector<std::string> &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int "
2545 "&dtype=Type.Double, const int &device = Device.cpu, const bool &is_diag=false)%s",
2561 : _impl(new UniTensor_base()) {
2565 "[DEBUG] message: entry for UniTensor(const std::vector<Bond> &bonds, const "
2566 "std::vector<cytnx_int64> &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int "
2567 "&dtype=Type.Double, const int &device = Device.cpu, const bool &is_diag=false)%s",
2570 std::vector<std::string> vs;
2571 for (
int i = 0; i < (int)in_labels.size(); i++) vs.push_back(std::to_string(in_labels[i]));
2597 void Init(
const std::vector<Bond> &
bonds,
const std::vector<std::string> &in_labels = {},
2601 bool is_sym =
false;
2608 if(sym_fver == -1) sym_fver =
bonds[i]._impl->_degs.size();
2612 cytnx_error_msg((
bool(sym_fver)^
bool(
bonds[i]._impl->_degs.size())),
"[ERROR] All the Bond when init a UniTensor with symmetric must be in the same format!%s",
"\n");
2616 is_sym,
"[ERROR] cannot have bonds with mixing of symmetry and non-symmetry.%s",
"\n");
2622 cytnx_warning_msg(
true,
"[DEBUG] message: entry dispatch: UniTensor: symmetric%s",
"\n");
2627 boost::intrusive_ptr<UniTensor_base> out(
new SparseUniTensor());
2629 }
else if(sym_fver==-1){
2630 cytnx_error_msg(
true,
"[ERROR] internal error! the Bond is symmetry but the version is not properly determined!%s",
"\n");
2632 boost::intrusive_ptr<UniTensor_base> out(
new BlockUniTensor());
2636 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
2649 void Init(
const std::vector<Bond> &
bonds,
const std::vector<cytnx_int64> &in_labels,
2652 std::vector<std::string> vs;
2653 cytnx_warning_msg(
true,
"[Deprecated warning] specify label with integers will be depreated soon. use string instead.%s",
"\n");
2654 for (
int i = 0; i < (int)in_labels.size(); i++) vs.push_back(std::to_string(in_labels[i]));
2679 const bool &by_label) {
2680 this->_impl->
set_label(idx, new_label, by_label);
2714 this->_impl->
set_label(idx, std::string(new_label));
2727 this->_impl->
set_label(old_label, new_label);
2735 this->_impl->
set_label(std::string(old_label), new_label);
2743 this->_impl->
set_label(old_label, std::string(new_label));
2751 this->_impl->
set_label(std::string(old_label), std::string(new_label));
2799 std::vector<char*> new_lbls(new_labels);
2800 std::vector<std::string> vs(new_lbls.size());
2801 transform(new_lbls.begin(),new_lbls.end(), vs.begin(),[](
char * x) -> std::string { return std::string(x); });
2803 this->_impl->set_labels(vs);
2821 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2822 "get_block()/get_blocks() first.%s",
2825 DenseUniTensor *tmp =
static_cast<DenseUniTensor *
>(this->_impl.get());
2826 return tmp->_block.item<T>();
2831 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2832 "get_block()/get_blocks() first.%s",
2835 DenseUniTensor *tmp =
static_cast<DenseUniTensor *
>(this->_impl.get());
2836 return tmp->_block.item();
2861 unsigned int dtype()
const {
return this->_impl->dtype(); }
2876 int device()
const {
return this->_impl->device(); }
2882 std::string
name()
const {
return this->_impl->name(); }
2889 std::string
dtype_str()
const {
return this->_impl->dtype_str(); }
2896 std::string
device_str()
const {
return this->_impl->device_str(); }
2916 bool is_diag()
const {
return this->_impl->is_diag(); }
2917 bool is_tag()
const {
return this->_impl->is_tag(); }
2924 std::vector<Symmetry>
syms()
const {
return this->_impl->syms(); }
2931 const std::vector<std::string> &
labels()
const {
return this->_impl->labels(); }
2944 const std::vector<Bond> &
bonds()
const {
return this->_impl->bonds(); }
2949 std::vector<Bond> &
bonds() {
return this->_impl->bonds(); }
2955 std::vector<cytnx_uint64>
shape()
const {
return this->_impl->shape(); }
2977 out._impl = this->_impl->
to(
device);
2987 out._impl = this->_impl->
clone();
2998 out._impl = this->_impl->
relabels(new_labels);
3008 out._impl = this->_impl->
relabels(new_labels);
3016 std::vector<char*> new_labels(new_lbls);
3017 std::vector<std::string> vs(new_labels.size());
3018 transform(new_labels.begin(),new_labels.end(), vs.begin(),[](
char * x) -> std::string { return std::string(x); });
3023 out._impl = this->_impl->
relabels(vs);
3033 const bool &by_label=
false)
const {
3035 out._impl = this->_impl->
relabel(inx, new_label, by_label);
3046 out._impl = this->_impl->
relabel(inx, new_label);
3057 out._impl = this->_impl->
relabel(old_label, new_label);
3069 if (this->
dtype() == dtype) {
3070 out._impl = this->_impl;
3088 const bool &by_label=
false)
const {
3115 std::vector<char*> mprs = mapper;
3116 std::vector<std::string> vs(mprs.size());
3117 transform(mprs.begin(),mprs.end(),vs.begin(),[](
char * x) -> std::string { return std::string(x); });
3132 const bool &by_label=
false) {
3133 this->_impl->permute_(mapper,
rowrank, by_label);
3143 this->_impl->permute_(mapper,
rowrank);
3178 void print_diagram(
const bool &bond_info =
false) { this->_impl->print_diagram(bond_info); }
3184 void print_blocks(
const bool &full_info=
true)
const{ this->_impl->print_blocks(full_info); }
3194 this->_impl->group_basis_();
3210 T &
at(
const std::vector<cytnx_uint64> &locator){
3212 if (this->
uten_type() ==UTenType.Block){
3215 return this->_impl->at_for_sparse(locator, aux);
3217 }
else if (this->
uten_type() == UTenType.Sparse) {
3218 if (this->_impl->elem_exists(locator)) {
3220 return this->_impl->at_for_sparse(locator, aux);
3222 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
3236 const T &
at(
const std::vector<cytnx_uint64> &locator)
const {
3238 if (this->
uten_type() ==UTenType.Block){
3241 return this->_impl->at_for_sparse(locator, aux);
3243 }
else if (this->
uten_type() == UTenType.Sparse) {
3244 if (this->_impl->elem_exists(locator)) {
3246 return this->_impl->at_for_sparse(locator, aux);
3248 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
3256 const Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &locator)
const {
3257 if (this->
uten_type() == UTenType.Block){
3258 return this->_impl->at_for_sparse(locator);
3259 }
else if (this->
uten_type() == UTenType.Sparse) {
3260 if (this->_impl->elem_exists(locator)) {
3261 return this->_impl->at_for_sparse(locator);
3263 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
3271 Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &locator) {
3272 if (this->
uten_type() == UTenType.Block){
3273 return this->_impl->at_for_sparse(locator);
3274 }
else if (this->
uten_type() == UTenType.Sparse) {
3275 if (this->_impl->elem_exists(locator)) {
3276 return this->_impl->at_for_sparse(locator);
3278 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
3304 return this->_impl->get_block(qnum, force);
3312 const bool &force =
false)
const {
3313 std::vector<cytnx_int64> tmp = qnum;
3321 Tensor get_block(
const std::vector<cytnx_uint64> &qnum,
const bool &force =
false)
const {
3322 std::vector<cytnx_int64> iqnum(qnum.begin(),qnum.end());
3323 return this->_impl->get_block(iqnum, force);
3333 return this->_impl->get_block_(idx);
3352 return this->_impl->get_block_(qnum, force);
3358 Tensor &
get_block_(
const std::initializer_list<cytnx_int64> &qnum,
const bool &force =
false) {
3359 std::vector<cytnx_int64> tmp = qnum;
3367 std::vector<cytnx_int64> iqnum(qnum.begin(),qnum.end());
3377 const bool &force =
false)
const {
3378 return this->_impl->get_block_(qnum, force);
3385 const bool &force =
false)
const {
3386 std::vector<cytnx_int64> tmp = qnum;
3387 return this->_impl->get_block_(tmp, force);
3393 const Tensor &
get_block_(
const std::vector<cytnx_uint64> &qnum,
const bool &force =
false)
const{
3394 std::vector<cytnx_int64> iqnum(qnum.begin(),qnum.end());
3408 std::vector<Tensor>
get_blocks()
const {
return this->_impl->get_blocks(); }
3416 const std::vector<Tensor> &
get_blocks_(
const bool &silent =
false)
const {
3417 return this->_impl->get_blocks_(silent);
3425 return this->_impl->get_blocks_(silent);
3435 this->_impl->put_block(in, idx);
3444 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
3445 this->_impl->put_block(in, qnum, force);
3461 this->_impl->put_block_(in, qnum, force);
3465 out._impl = this->_impl->
get(accessors);
3468 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
3469 this->_impl->set(accessors, rhs);
3488 this->_impl->reshape_(new_shape,
rowrank);
3504 out._impl = this->_impl->
to_dense();
3519 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
3520 const bool &by_label) {
3521 this->_impl->combineBonds(indicators, force, by_label);
3532 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
false) {
3533 this->_impl->combineBonds(indicators, force);
3541 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
false) {
3542 this->_impl->combineBonds(indicators, force);
3566 const bool &mv_elem_rhs =
false)
const {
3568 out._impl = this->_impl->
contract(inR._impl, mv_elem_self, mv_elem_rhs);
3581 return this->_impl->getTotalQnums(physical);
3588 return this->_impl->get_blocks_qnums();
3593 if (this->_impl->uten_type() != rhs._impl->
uten_type())
return false;
3595 return this->_impl->same_data(rhs._impl);
3615 this->_impl->
Add_(rhs._impl);
3636 this->_impl->
Mul_(rhs._impl);
3657 this->_impl->
Sub_(rhs._impl);
3678 this->_impl->
Div_(rhs._impl);
3693 this->_impl->
Add_(rhs);
3708 this->_impl->
Mul_(rhs);
3723 this->_impl->
Sub_(rhs);
3738 this->_impl->
Div_(rhs);
4021 out._impl = this->_impl->
Conj();
4033 this->_impl->
Conj_();
4095 out._impl = this->_impl->
Trace(a, b);
4110 out._impl = this->_impl->
Trace(a, b);
4122 return Trace(std::to_string(a),std::to_string(b));
4138 this->_impl->
Trace_(a, b);
4141 if(this->
rank()==0){
4142 DenseUniTensor *tmp =
new DenseUniTensor();
4144 this->_impl = boost::intrusive_ptr<UniTensor_base>(tmp);
4160 this->_impl->
Trace_(a, b);
4163 if(this->
rank()==0){
4164 DenseUniTensor *tmp =
new DenseUniTensor();
4166 this->_impl = boost::intrusive_ptr<UniTensor_base>(tmp);
4179 this->_impl->
Trace_(a, b, by_label);
4182 if(this->
rank()==0){
4183 DenseUniTensor *tmp =
new DenseUniTensor();
4185 this->_impl = boost::intrusive_ptr<UniTensor_base>(tmp);
4199 out._impl = this->_impl->
Dagger();
4240 return this->_impl->elem_exists(locator);
4249 T
get_elem(
const std::vector<cytnx_uint64> &locator)
const {
4250 return this->at<T>(locator);
4259 void set_elem(
const std::vector<cytnx_uint64> &locator,
const T2 &rc) {
4261 this->
at(locator) = rc;
4269 void Save(
const std::string &fname)
const;
4276 void Save(
const char *fname)
const;
4307 const bool &by_label) {
4308 this->_impl->
truncate_(bond_idx, dim, by_label);
4330 const bool &by_label)
const {
4354 return this->_impl->get_qindices(bidx);
4364 return this->_impl->get_qindices(bidx);
4376 return this->_impl->get_itoi();
4379 return this->_impl->get_itoi();
4385 void _Load(std::fstream &f);
4386 void _Save(std::fstream &f)
const;
4408 const bool &cacheR =
false);
4422 UniTensor Contracts(
const std::vector<UniTensor> &TNs,
const std::string &order,
const bool &optimal);
4426 template <
class... T>
4428 TNlist.push_back(in);
4444 template <
class... T>
4446 std::vector<UniTensor> TNlist;
4448 return Contracts(TNlist, order, optimal);
A class to represent a scalar.
Definition Scalar.hpp:2470
an tensor (multi-dimensional array)
Definition Tensor.hpp:345
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:869
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:952
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:768
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:932
T & at(const std::vector< cytnx_uint64 > &locator)
[C++ only] get an element at specific location.
Definition Tensor.hpp:1101
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:820
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:1234
Tensor Norm() const
the Norm member function. Same as linalg::Norm(const Tensor &Tin), where Tin is the current Tensor.
Definition Tensor.cpp:1336
Tensor astype(const int &new_type) const
return a new Tensor that cast to different dtype.
Definition Tensor.hpp:1068
const bool & is_contiguous() const
Definition Tensor.hpp:871
Tensor & Conj_()
the Conj_ member function. Same as cytnx::linalg::Conj_(Tensor &Tin), where Tin is the current Tensor...
Definition Tensor.cpp:1325
int device() const
the device-id of the Tensor
Definition Tensor.hpp:775
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1202
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:795
An Enhanced tensor specifically designed for physical Tensor network simulation.
Definition UniTensor.hpp:2449
UniTensor to(const int &device) const
move the current UniTensor to the assigned device.
Definition UniTensor.hpp:2975
UniTensor & operator*=(const UniTensor &rhs)
The multiplication assignment operator of the UniTensor.
Definition UniTensor.hpp:3947
void Init(const Tensor &in_tensor, const bool &is_diag=false, const cytnx_int64 &rowrank=-1, const std::string &name="")
Initialize a UniTensor with cytnx::Tensor.
Definition UniTensor.hpp:2510
UniTensor relabels(const std::vector< cytnx_int64 > &new_labels) const
Definition UniTensor.hpp:2996
std::vector< Tensor > & get_blocks_(const bool &silent=false)
Definition UniTensor.hpp:3424
void print_block(const cytnx_int64 &idx, const bool &full_info=true) const
Given a index and print out the corresponding block of the UniTensor.
Definition UniTensor.hpp:3191
UniTensor & operator/=(const UniTensor &rhs)
The division assignment operator of the UniTensor.
Definition UniTensor.hpp:3927
T & item()
Definition UniTensor.hpp:2819
bool is_contiguous() const
To tell whether the UniTensor is contiguous.
Definition UniTensor.hpp:2910
T get_elem(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:4249
UniTensor Div(const UniTensor &rhs) const
The division function of the UniTensor.
Definition UniTensor.cpp:25
const Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:3384
UniTensor & set_label(const cytnx_int64 &idx, const cytnx_int64 &new_label)
Definition UniTensor.hpp:2693
std::vector< cytnx_uint64 > & get_qindices(const cytnx_uint64 &bidx)
get the q-indices on each leg for the [bidx]-th block
Definition UniTensor.hpp:4363
Tensor & get_block_(const std::vector< cytnx_int64 > &qnum, const bool &force=false)
Get the shared view of block for the given quantum number.
Definition UniTensor.hpp:3351
UniTensor & set_label(const cytnx_int64 &idx, const char *new_label)
Definition UniTensor.hpp:2713
UniTensor & operator+=(const UniTensor &rhs)
The addition assignment operator of the UniTensor.
Definition UniTensor.hpp:3887
void to_dense_()
Convert the UniTensor to non-diagonal form, inplacely.
Definition UniTensor.hpp:3512
UniTensor reshape(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor.
Definition UniTensor.hpp:3477
std::vector< Tensor > get_blocks() const
Get all the blocks of the UniTensor.
Definition UniTensor.hpp:3408
UniTensor permute(const std::initializer_list< char * > &mapper, const cytnx_int64 &rowrank=-1) const
Definition UniTensor.hpp:3114
bool is_tag() const
Definition UniTensor.hpp:2917
cytnx_int64 get_index(std::string lbl) const
Get the index of an desired label string.
Definition UniTensor.hpp:2938
std::string uten_type_str() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor in 'string' form.
Definition UniTensor.hpp:2903
void put_block(const Tensor &in, const std::vector< cytnx_int64 > &qnum, const bool &force)
Put the block into the UniTensor with given quantum number.
Definition UniTensor.hpp:3444
UniTensor truncate(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim, const bool &by_label) const
Definition UniTensor.hpp:4329
UniTensor(const std::vector< Bond > &bonds, const std::vector< std::string > &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const bool &is_diag=false, const std::string &name="")
Construct a UniTensor.
Definition UniTensor.hpp:2536
static UniTensor Load(const std::string &fname)
load a UniTensor from file
Definition UniTensor.cpp:158
UniTensor & tag()
Definition UniTensor.hpp:4214
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force=false)
Definition UniTensor.hpp:3541
UniTensor get(const std::vector< Accessor > &accessors) const
Definition UniTensor.hpp:3463
UniTensor & set_label(const std::string &old_label, const std::string &new_label)
set a new label for bond to replace one of the current label.
Definition UniTensor.hpp:2726
UniTensor(const Tensor &in_tensor, const bool &is_diag=false, const cytnx_int64 &rowrank=-1, const std::string &name="")
Construct a UniTensor from a cytnx::Tensor.
Definition UniTensor.hpp:2488
void Save(const std::string &fname) const
save a UniTensor to file
Definition UniTensor.cpp:138
UniTensor & operator-=(const Scalar &rhs)
The subtraction assignment operator for a given scalar.
Definition UniTensor.hpp:3977
cytnx_uint64 rowrank() const
Return the row rank of the UniTensor.
Definition UniTensor.hpp:2854
Tensor Norm() const
Return the norm of the UniTensor.
Definition UniTensor.hpp:3870
UniTensor & set_labels(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2798
UniTensor & Sub_(const Scalar &rhs)
The subtraction function for a given scalar.
Definition UniTensor.hpp:3722
UniTensor & operator/=(const Scalar &rhs)
The division assignment operator for a given scalar.
Definition UniTensor.hpp:3992
const bool & is_braket_form() const
Definition UniTensor.hpp:2925
void set_elem(const std::vector< cytnx_uint64 > &locator, const T2 &rc)
Definition UniTensor.hpp:4259
UniTensor relabel(const cytnx_int64 &inx, const cytnx_int64 &new_label, const bool &by_label=false) const
Definition UniTensor.hpp:3032
std::vector< cytnx_uint64 > shape() const
Get the shape of the UniTensor.
Definition UniTensor.hpp:2955
UniTensor to_dense()
Convert the UniTensor to non-diagonal form.
Definition UniTensor.hpp:3502
UniTensor relabels(const std::initializer_list< char * > &new_lbls) const
Definition UniTensor.hpp:3015
UniTensor truncate(const std::string &bond_idx, const cytnx_uint64 &dim) const
Definition UniTensor.hpp:4335
void reshape_(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor, inplacely.
Definition UniTensor.hpp:3487
const Tensor & get_block_(const std::vector< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:3376
UniTensor & set_labels(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:2790
void permute_(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:3142
std::string name() const
Return the name of the UniTensor.
Definition UniTensor.hpp:2882
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 std::string &name="")
Definition UniTensor.hpp:2649
UniTensor & Add_(const Scalar &rhs)
The addition function for a given scalar.
Definition UniTensor.hpp:3692
UniTensor Trace(const cytnx_int64 &a, const cytnx_int64 &b, const bool &by_label) const
Definition UniTensor.hpp:4120
UniTensor & Trace_(const std::string &a, const std::string &b)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:4137
UniTensor & truncate_(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim)
Definition UniTensor.hpp:4315
std::vector< Bond > getTotalQnums(const bool physical=false) const
Get the total quantum number of the UniTensor.
Definition UniTensor.hpp:3580
Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:3271
UniTensor Trace(const std::string &a, const std::string &b) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:4093
bool same_data(const UniTensor &rhs) const
Definition UniTensor.hpp:3591
UniTensor astype(const unsigned int &dtype) const
Return a new UniTensor that cast to different data type.
Definition UniTensor.hpp:3067
UniTensor Transpose() const
Take the transpose of the UniTensor.
Definition UniTensor.hpp:4043
Tensor & get_block_(const std::vector< cytnx_uint64 > &qnum, const bool &force=false)
Definition UniTensor.hpp:3366
UniTensor & set_label(const char *old_label, const std::string &new_label)
Definition UniTensor.hpp:2734
UniTensor & Dagger_()
Take the conjugate transpose to the UniTensor, inplacely.
Definition UniTensor.hpp:4209
void print_diagram(const bool &bond_info=false)
Plot the diagram of the UniTensor.
Definition UniTensor.hpp:3178
std::vector< Bond > & bonds()
Definition UniTensor.hpp:2949
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition UniTensor.hpp:3210
UniTensor & set_label(const cytnx_int64 &idx, const std::string &new_label)
Set a new label for bond at the assigned index.
Definition UniTensor.hpp:2705
std::vector< std::vector< cytnx_int64 > > get_blocks_qnums() const
Definition UniTensor.hpp:3587
UniTensor contiguous() const
Make the UniTensor contiguous by coalescing the memory (storage).
Definition UniTensor.hpp:3162
Tensor get_block(const cytnx_uint64 &idx=0) const
Get the block of the UniTensor for a given index.
Definition UniTensor.hpp:3292
const T & at(const std::vector< cytnx_uint64 > &locator) const
Get an element at specific location.
Definition UniTensor.hpp:3236
UniTensor & operator*=(const Scalar &rhs)
The multiplication assignment operator for a given scalar.
Definition UniTensor.hpp:4007
void contiguous_()
Make the UniTensor contiguous by coalescing the memory (storage), inplacely.
Definition UniTensor.hpp:3172
UniTensor normalize() const
normalize the current UniTensor instance with 2-norm.
Definition UniTensor.hpp:4066
UniTensor & set_labels(const std::vector< cytnx_int64 > &new_labels)
change a new label for bond with original label.
Definition UniTensor.hpp:2779
std::vector< Symmetry > syms() const
Return the symmetry type of the UniTensor.
Definition UniTensor.hpp:2924
UniTensor & Mul_(const UniTensor &rhs)
The multiplcation function of the UniTensor.
Definition UniTensor.hpp:3635
UniTensor & Trace_(const cytnx_int64 &a, const cytnx_int64 &b, const bool &by_label)
Definition UniTensor.hpp:4178
UniTensor permute(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1, const bool &by_label=false) const
permute the lags of the UniTensor
Definition UniTensor.hpp:3087
void put_block_(Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index, inplacely.
Definition UniTensor.hpp:3453
UniTensor & set_label(const cytnx_int64 &idx, const cytnx_int64 &new_label, const bool &by_label)
Definition UniTensor.hpp:2678
void combineBonds(const std::vector< std::string > &indicators, const bool &force=false)
Combine the sevral bonds of the UniTensor.
Definition UniTensor.hpp:3532
void put_block_(Tensor &in, const std::vector< cytnx_int64 > &qnum, const bool &force)
Put the block into the UniTensor with given quantum number, inplacely.
Definition UniTensor.hpp:3460
UniTensor relabel(const std::string &old_label, const std::string &new_label) const
rebable the lags in the UniTensor by a given label.
Definition UniTensor.hpp:3055
UniTensor & normalize_()
normalize the UniTensor, inplacely.
Definition UniTensor.hpp:4078
UniTensor & truncate_(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim, const bool &by_label)
Definition UniTensor.hpp:4306
bool is_diag() const
To tell whether the UniTensor is in diagonal form.
Definition UniTensor.hpp:2916
int device() const
Return the device of the UniTensor.
Definition UniTensor.hpp:2876
UniTensor & Pow_(const double &p)
Power function.
Definition UniTensor.cpp:12
void set(const std::vector< Accessor > &accessors, const Tensor &rhs)
Definition UniTensor.hpp:3468
std::string dtype_str() const
Return the data type of the UniTensor in 'string' form.
Definition UniTensor.hpp:2889
UniTensor & operator+=(const Scalar &rhs)
The addition assignment operator for a given scalar.
Definition UniTensor.hpp:3962
UniTensor & Div_(const UniTensor &rhs)
The division function of the UniTensor.
Definition UniTensor.hpp:3677
UniTensor & Div_(const Scalar &rhs)
The division function for a given scalar.
Definition UniTensor.hpp:3737
cytnx_uint64 rank() const
Return the rank of the UniTensor.
Definition UniTensor.hpp:2848
void group_basis_()
Definition UniTensor.hpp:3193
void to_(const int &device)
move the current UniTensor to the assigned device (inplace).
Definition UniTensor.hpp:2964
UniTensor & Trace_(const cytnx_int64 &a=0, const cytnx_int64 &b=1)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:4159
UniTensor & set_name(const std::string &in)
Set the name of the UniTensor.
Definition UniTensor.hpp:2666
UniTensor Trace(const cytnx_int64 &a=0, const cytnx_int64 &b=1) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:4108
UniTensor & Add_(const UniTensor &rhs)
The addition function of the UniTensor.
Definition UniTensor.hpp:3614
Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false)
Definition UniTensor.hpp:3358
UniTensor & set_label(const std::string &old_label, const char *new_label)
Definition UniTensor.hpp:2742
UniTensor permute(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1) const
permute the lags of the UniTensor by labels
Definition UniTensor.hpp:3105
unsigned int dtype() const
Return the data type of the UniTensor.
Definition UniTensor.hpp:2861
UniTensor Pow(const double &p) const
Power function.
Definition UniTensor.cpp:11
UniTensor & Mul_(const Scalar &rhs)
The multiplication function for a given scalar.
Definition UniTensor.hpp:3707
UniTensor & operator-=(const UniTensor &rhs)
The subtraction assignment operator of the UniTensor.
Definition UniTensor.hpp:3907
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force, const bool &by_label)
Definition UniTensor.hpp:3519
UniTensor & set_label(const char *old_label, const char *new_label)
Definition UniTensor.hpp:2750
bool is_blockform() const
Definition UniTensor.hpp:2956
UniTensor group_basis() const
Definition UniTensor.hpp:3197
UniTensor Dagger() const
Take the conjugate transpose to the UniTensor.
Definition UniTensor.hpp:4197
const std::vector< Tensor > & get_blocks_(const bool &silent=false) const
Get all the blocks of the UniTensor, inplacely.
Definition UniTensor.hpp:3416
bool elem_exists(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:4239
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, const std::string &name="")
Definition UniTensor.hpp:2558
UniTensor & Sub_(const UniTensor &rhs)
The subtraction function of the UniTensor.
Definition UniTensor.hpp:3656
UniTensor contract(const UniTensor &inR, const bool &mv_elem_self=false, const bool &mv_elem_rhs=false) const
Contract the UniTensor with common labels.
Definition UniTensor.hpp:3565
void put_block(const Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index.
Definition UniTensor.hpp:3434
const Tensor & get_block_(const cytnx_uint64 &idx=0) const
Get the shared view of block for the given index.
Definition UniTensor.hpp:3332
UniTensor & truncate_(const std::string &bond_idx, const cytnx_uint64 &dim)
Definition UniTensor.hpp:4311
UniTensor relabel(const cytnx_int64 &inx, const std::string &new_label) const
rebable the lags in the UniTensor by given index.
Definition UniTensor.hpp:3044
UniTensor Mul(const UniTensor &rhs) const
The multiplication function of the UniTensor.
Definition UniTensor.cpp:28
const std::vector< cytnx_uint64 > & get_qindices(const cytnx_uint64 &bidx) const
get the q-indices on each leg for the [bidx]-th block
Definition UniTensor.hpp:4353
const std::vector< std::string > & labels() const
Return the labels of the UniTensor.
Definition UniTensor.hpp:2931
Tensor get_block(const std::vector< cytnx_int64 > &qnum, const bool &force=false) const
Get the block of the UniTensor for the given quantun number.
Definition UniTensor.hpp:3303
const std::vector< Bond > & bonds() const
Get the bonds of the UniTensor.
Definition UniTensor.hpp:2944
UniTensor truncate(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim) const
Definition UniTensor.hpp:4340
UniTensor & Transpose_()
Take the transpose of the UniTensor, inplacely.
Definition UniTensor.hpp:4055
UniTensor clone() const
Clone (deep copy) the UniTensor.
Definition UniTensor.hpp:2985
vec2d< cytnx_uint64 > & get_itoi()
Definition UniTensor.hpp:4378
void print_blocks(const bool &full_info=true) const
Print all of the blocks in the UniTensor.
Definition UniTensor.hpp:3184
Scalar::Sproxy item() const
Definition UniTensor.hpp:2829
const vec2d< cytnx_uint64 > & get_itoi() const
get the q-indices on each leg for all the blocks
Definition UniTensor.hpp:4375
std::string device_str() const
Return the device of the UniTensor in 'string' form.
Definition UniTensor.hpp:2896
UniTensor relabels(const std::vector< std::string > &new_labels) const
rebables all of the labels in UniTensor.
Definition UniTensor.hpp:3006
UniTensor Sub(const UniTensor &rhs) const
The subtraction function of the UniTensor.
Definition UniTensor.cpp:22
void Init(const std::vector< Bond > &bonds, const std::vector< std::string > &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const bool &is_diag=false, const std::string &name="")
Initialize the UniTensor with the given arguments.
Definition UniTensor.hpp:2597
UniTensor & Conj_()
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:4032
cytnx_uint64 Nblocks() const
Return the blocks' number.
Definition UniTensor.hpp:2842
Tensor get_block(const std::vector< cytnx_uint64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:3321
UniTensor Conj()
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:4019
const Tensor & get_block_(const std::vector< cytnx_uint64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:3393
UniTensor Add(const UniTensor &rhs) const
The addition function of the UniTensor.
Definition UniTensor.cpp:16
UniTensor & set_rowrank(const cytnx_uint64 &new_rowrank)
Set the row rank of the UniTensor.
Definition UniTensor.hpp:2813
void permute_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1, const bool &by_label=false)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:3131
Tensor get_block(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:3311
const Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:3256
int uten_type() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor.
Definition UniTensor.hpp:2869
Tensor & get_block_(const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:3340
#define cytnx_warning_msg(is_true, format,...)
Definition cytnx_error.hpp:40
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:16
cytnx::UniTensor Trace(const cytnx::UniTensor &Tin, const cytnx_int64 &a=0, const cytnx_int64 &b=1)
Tensor Conj(const Tensor &Tin)
Conjugate all the element in Tensor.
Tensor Norm(const Tensor &Tl)
Calculate the norm of a tensor.
void Conj_(Tensor &Tin)
inplace perform Conjugate on all the element in Tensor.
Definition Accessor.hpp:12
Device_class Device
data on which devices.
Definition Device.cpp:140
double cytnx_double
Definition Type.hpp:43
UniTensorType_class UTenType
UniTensor type.
Definition UniTensor_base.cpp:24
uint32_t cytnx_uint32
Definition Type.hpp:46
std::complex< double > cytnx_complex128
Definition Type.hpp:53
float cytnx_float
Definition Type.hpp:44
std::ostream & operator<<(std::ostream &os, const Scalar &in)
The stream operator for Scalar objects.
Definition Scalar.cpp:10
int16_t cytnx_int16
Definition Type.hpp:50
std::complex< float > cytnx_complex64
Definition Type.hpp:52
int32_t cytnx_int32
Definition Type.hpp:49
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:601
uint16_t cytnx_uint16
Definition Type.hpp:47
void _resolve_CT(std::vector< UniTensor > &TNlist)
Definition UniTensor_base.cpp:607
uint64_t cytnx_uint64
Definition Type.hpp:45
int64_t cytnx_int64
Definition Type.hpp:48
std::vector< std::vector< T > > vec2d
Definition Type.hpp:40
UniTensor Contracts(const std::vector< UniTensor > &TNs, const std::string &order, const bool &optimal)
Contract multiple UniTensor by tracing the ranks with common labels with pairwise operation.
Definition UniTensor_base.cpp:608
Type_class Type
data type
Definition Type.cpp:23