14#include <initializer_list>
22 #include "backend/Scalar.hpp"
26 using namespace cytnx;
28 class UniTensorType_class {
36 std::string getname(
const int &ut_type);
60 class UniTensor_base :
public intrusive_ptr_base<UniTensor_base> {
68 std::vector<std::string> _labels;
69 std::vector<Bond> _bonds;
71 bool _update_braket() {
72 if (_bonds.size() == 0)
return false;
74 if (this->_bonds[0].type() != bondType::BD_REG) {
76 for (
unsigned int i = 0; i < this->_bonds.size(); i++) {
77 if (i < this->_rowrank) {
78 if (this->_bonds[i].type() != bondType::BD_KET)
return false;
80 if (this->_bonds[i].type() != bondType::BD_BRA)
return false;
90 friend class DenseUniTensor;
92 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; }
128 cytnx_error_msg(idx >= this->_bonds.size(),
"[ERROR][bond] index %d out of bound, total %d\n",
129 idx, this->_bonds.size());
130 return this->_bonds[idx];
133 Bond &bond_(
const std::string &lbl) {
134 auto res = std::find(this->_labels.begin(), this->_labels.end(), lbl);
135 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n", lbl.c_str());
136 cytnx_uint64 idx = std::distance(this->_labels.begin(), res);
138 return this->bond_(idx);
141 const std::string &name()
const {
return this->_name; }
142 cytnx_uint64 rank()
const {
return this->_labels.size(); }
143 void set_name(
const std::string &in) { this->_name = in; }
155 void set_label(
const std::string &oldlbl,
const std::string &new_label) {
157 auto res = std::find(this->_labels.begin(), this->_labels.end(), oldlbl);
158 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n", oldlbl.c_str());
159 idx = std::distance(this->_labels.begin(), res);
161 cytnx_error_msg(idx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
165 for (
cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
166 if (i == idx)
continue;
167 if (new_label == this->_labels[i]) {
172 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
174 this->_labels[idx] = new_label;
176 void set_label(
const cytnx_int64 &inx,
const std::string &new_label) {
178 cytnx_error_msg(inx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
182 for (
cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
183 if (i == inx)
continue;
184 if (new_label == this->_labels[i]) {
189 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
191 this->_labels[inx] = new_label;
194 void set_labels(
const std::vector<std::string> &new_labels);
195 void relabels_(
const std::vector<std::string> &new_labels);
196 void relabels_(
const std::vector<std::string> &old_labels,
197 const std::vector<std::string> &new_labels);
198 void relabel_(
const std::string &old_label,
const std::string &new_label) {
199 this->set_label(old_label, new_label);
201 void relabel_(
const cytnx_int64 &inx,
const std::string &new_label) {
202 this->set_label(inx, new_label);
205 int uten_type() {
return this->uten_type_id; }
206 std::string uten_type_str() {
return UTenType.getname(this->uten_type_id); }
211 virtual void Init(
const std::vector<Bond> &bonds,
212 const std::vector<std::string> &in_labels = {},
213 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
214 const int &device =
Device.cpu,
const bool &is_diag =
false,
215 const bool &no_alloc =
false,
const std::string &name =
"");
217 virtual void Init_by_Tensor(
const Tensor &in,
const bool &is_diag =
false,
218 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
219 virtual std::vector<cytnx_uint64> shape()
const;
220 virtual bool is_blockform()
const;
221 virtual bool is_contiguous()
const;
222 virtual void to_(
const int &device);
223 virtual boost::intrusive_ptr<UniTensor_base> to(
const int &device);
224 virtual boost::intrusive_ptr<UniTensor_base> clone()
const;
225 virtual unsigned int dtype()
const;
226 virtual int device()
const;
227 virtual std::string dtype_str()
const;
228 virtual std::string device_str()
const;
229 virtual void set_rowrank_(
const cytnx_uint64 &new_rowrank);
230 virtual boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const;
232 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
234 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
239 virtual void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
240 virtual void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
244 virtual boost::intrusive_ptr<UniTensor_base> contiguous_();
245 virtual boost::intrusive_ptr<UniTensor_base> contiguous();
246 virtual void print_diagram(
const bool &bond_info =
false);
247 virtual void print_blocks(
const bool &full_info =
true)
const;
248 virtual void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
250 virtual boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const;
254 virtual Tensor get_block(
const std::vector<cytnx_int64> &qnum,
255 const bool &force)
const;
259 virtual const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
260 const bool &force)
const;
263 virtual Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
265 virtual bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const;
267 virtual std::vector<Tensor> get_blocks()
const;
268 virtual const std::vector<Tensor> &get_blocks_(
const bool &)
const;
269 virtual std::vector<Tensor> &get_blocks_(
const bool &);
273 virtual void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
275 virtual void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force);
278 virtual boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
281 virtual void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
283 virtual void reshape_(
const std::vector<cytnx_int64> &new_shape,
285 virtual boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
287 virtual boost::intrusive_ptr<UniTensor_base> to_dense();
288 virtual void to_dense_();
289 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
290 const bool &by_label);
291 virtual void combineBonds(
const std::vector<std::string> &indicators,
292 const bool &force =
false);
293 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
294 const bool &force =
false);
295 virtual boost::intrusive_ptr<UniTensor_base> contract(
296 const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self =
false,
297 const bool &mv_elem_rhs =
false);
298 virtual std::vector<Bond> getTotalQnums(
const bool &physical =
false);
299 virtual std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const;
300 virtual void Trace_(
const std::string &a,
const std::string &b);
303 virtual boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b);
306 virtual boost::intrusive_ptr<UniTensor_base> relabels(
307 const std::vector<std::string> &new_labels);
309 virtual boost::intrusive_ptr<UniTensor_base> relabels(
310 const std::vector<std::string> &old_labels,
const std::vector<std::string> &new_labels);
312 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &inx,
313 const std::string &new_label);
315 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
316 const std::string &new_label);
318 virtual std::vector<Symmetry> syms()
const;
321 virtual void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
322 virtual void Add_(
const Scalar &rhs);
324 virtual void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
325 virtual void Mul_(
const Scalar &rhs);
327 virtual void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
328 virtual void Sub_(
const Scalar &rhs);
329 virtual void lSub_(
const Scalar &lhs);
331 virtual void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
332 virtual void Div_(
const Scalar &rhs);
333 virtual void lDiv_(
const Scalar &lhs);
336 virtual boost::intrusive_ptr<UniTensor_base> normalize();
337 virtual void normalize_();
339 virtual boost::intrusive_ptr<UniTensor_base>
Conj();
340 virtual void Conj_();
342 virtual boost::intrusive_ptr<UniTensor_base> Transpose();
343 virtual void Transpose_();
345 virtual boost::intrusive_ptr<UniTensor_base> Dagger();
346 virtual void Dagger_();
350 virtual void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
353 virtual bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
356 virtual Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
357 virtual const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
359 virtual cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
361 virtual cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
363 virtual cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
365 virtual cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
367 virtual cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
369 virtual cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
371 virtual cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
373 virtual cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
375 virtual cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
377 virtual cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
380 virtual const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
382 virtual const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
384 virtual const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
386 virtual const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
388 virtual const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
390 virtual const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
392 virtual const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
394 virtual const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
396 virtual const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
398 virtual const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
401 virtual void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
403 virtual void group_basis_();
404 virtual const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const;
405 virtual std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx);
409 virtual void _save_dispatch(std::fstream &f)
const;
410 virtual void _load_dispatch(std::fstream &f);
412 virtual ~UniTensor_base(){};
418 class DenseUniTensor :
public UniTensor_base {
422 std::vector<Tensor> _interface_block;
423 DenseUniTensor *clone_meta()
const {
424 DenseUniTensor *
tmp =
new DenseUniTensor();
425 tmp->_bonds = vec_clone(this->_bonds);
426 tmp->_labels = this->_labels;
427 tmp->_is_braket_form = this->_is_braket_form;
428 tmp->_rowrank = this->_rowrank;
429 tmp->_is_diag = this->_is_diag;
430 tmp->_name = this->_name;
431 tmp->_is_tag = this->_is_tag;
436 DenseUniTensor() { this->uten_type_id =
UTenType.Dense; };
445 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
446 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
447 const int &device =
Device.cpu,
const bool &is_diag =
false,
448 const bool &no_alloc =
false,
const std::string &name =
"");
450 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
451 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
452 std::vector<cytnx_uint64> shape()
const {
453 if (this->_is_diag) {
454 std::vector<cytnx_uint64> shape = this->_block.
shape();
455 shape.push_back(shape[0]);
458 return this->_block.
shape();
461 bool is_blockform()
const {
return false; }
462 void to_(
const int &device) { this->_block.
to_(device); }
463 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
464 if (this->device() == device) {
465 std::vector<Tensor> _interface_block;
468 boost::intrusive_ptr<UniTensor_base> out = this->clone();
475 "[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
476 if (this->is_diag()) {
477 cytnx_error_msg(new_rowrank != 1,
"[ERROR] rowrank should be [==1] when is_diag =true!.%s",
481 this->_rowrank = new_rowrank;
484 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
485 DenseUniTensor *out_raw = this->clone_meta();
486 out_raw->_block = this->_block;
487 out_raw->set_rowrank_(new_rowrank);
488 boost::intrusive_ptr<UniTensor_base> out(out_raw);
492 boost::intrusive_ptr<UniTensor_base> clone()
const {
493 DenseUniTensor *
tmp = this->clone_meta();
495 boost::intrusive_ptr<UniTensor_base> out(tmp);
498 bool is_contiguous()
const {
return this->_block.
is_contiguous(); }
499 unsigned int dtype()
const {
return this->_block.
dtype(); }
500 int device()
const {
return this->_block.
device(); }
501 std::string dtype_str()
const {
return Type.getname(this->_block.
dtype()); }
502 std::string device_str()
const {
return Device.getname(this->_block.
device()); }
512 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
514 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
525 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
526 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
528 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
530 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
531 const std::vector<std::string> &new_labels);
543 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
544 const std::string &new_label);
545 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
546 const std::string &new_label);
548 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
549 DenseUniTensor *
tmp = this->clone_meta();
550 tmp->_block = this->_block.
astype(dtype);
551 boost::intrusive_ptr<UniTensor_base> out(tmp);
555 std::vector<Symmetry> syms()
const {
556 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] dense unitensor does not have symmetry.%s",
558 return std::vector<Symmetry>();
561 boost::intrusive_ptr<UniTensor_base> contiguous_() {
563 return boost::intrusive_ptr<UniTensor_base>(
this);
565 boost::intrusive_ptr<UniTensor_base> contiguous() {
567 if (this->is_contiguous()) {
568 boost::intrusive_ptr<UniTensor_base> out(
this);
571 DenseUniTensor *
tmp = this->clone_meta();
573 boost::intrusive_ptr<UniTensor_base> out(tmp);
577 void print_diagram(
const bool &bond_info =
false);
578 void print_blocks(
const bool &full_info =
true)
const;
579 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
582 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
584 true,
"[ERROR][DenseUniTensor] try to get_block() using qnum on a non-symmetry UniTensor%s",
589 const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
592 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
596 Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force) {
599 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
610 std::vector<Tensor> get_blocks()
const {
611 std::vector<Tensor> out;
613 true,
"[ERROR][DenseUniTensor] cannot use get_blocks(), use get_block() instead!%s",
"\n");
616 const std::vector<Tensor> &get_blocks_(
const bool &silent =
false)
const {
618 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
620 return this->_interface_block;
622 std::vector<Tensor> &get_blocks_(
const bool &silent =
false) {
624 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
626 return this->_interface_block;
630 if (this->is_diag()) {
632 in.
shape() != this->_block.shape(),
633 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
634 this->_block = in.
clone();
637 in.
shape() != this->shape(),
638 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
639 this->_block = in.
clone();
644 if (this->is_diag()) {
646 in.
shape() != this->_block.shape(),
647 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
651 in.
shape() != this->shape(),
652 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
657 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
659 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
662 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
664 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
668 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
669 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
670 out->Init_by_Tensor(this->_block.
get(accessors),
false, 0);
674 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
675 this->_block.
set(accessors, rhs);
678 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0);
679 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
681 boost::intrusive_ptr<UniTensor_base> to_dense();
692 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
693 const bool &by_label);
694 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
true);
695 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
true);
696 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
697 const bool &mv_elem_self =
false,
698 const bool &mv_elem_rhs =
false);
699 std::vector<Bond> getTotalQnums(
const bool &physical =
false) {
701 "getTotalQnums can only operate on UniTensor with symmetry.\n");
702 return std::vector<Bond>();
705 std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const {
707 "get_blocks_qnums can only operate on UniTensor with symmetry.\n");
708 return std::vector<std::vector<cytnx_int64>>();
711 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
712 if (rhs->uten_type() !=
UTenType.Dense)
return false;
714 return this->get_block_().same_data(rhs->get_block_());
720 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
721 void Add_(
const Scalar &rhs);
723 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
724 void Mul_(
const Scalar &rhs);
726 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
727 void Sub_(
const Scalar &rhs);
728 void lSub_(
const Scalar &lhs);
730 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
731 void Div_(
const Scalar &rhs);
732 void lDiv_(
const Scalar &lhs);
736 boost::intrusive_ptr<UniTensor_base>
Conj() {
737 boost::intrusive_ptr<UniTensor_base> out = this->clone();
742 boost::intrusive_ptr<UniTensor_base> Transpose() {
743 boost::intrusive_ptr<UniTensor_base> out = this->clone();
749 boost::intrusive_ptr<UniTensor_base> normalize() {
750 boost::intrusive_ptr<UniTensor_base> out = this->clone();
756 boost::intrusive_ptr<UniTensor_base> Dagger() {
757 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
775 void Trace_(
const std::string &a,
const std::string &b);
776 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
777 boost::intrusive_ptr<UniTensor_base> out = this->clone();
782 boost::intrusive_ptr<UniTensor_base> out = this->clone();
789 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const {
791 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
793 return Scalar::Sproxy();
795 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
798 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
802 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
805 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
809 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
812 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
816 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
819 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
823 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
826 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
830 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
833 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
837 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
840 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
844 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
847 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
851 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
854 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
858 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
861 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
866 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator) {
868 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
870 return Scalar::Sproxy();
875 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
879 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
882 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
888 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
894 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
900 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
906 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
912 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
918 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
924 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
930 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
935 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const {
937 true,
"[ERROR][DenseUniTensor] elem_exists can only be used on UniTensor with Symmetry.%s",
941 if (!this->is_tag()) {
942 for (
int i = 0; i < this->_rowrank; i++) {
943 this->_bonds[i].set_type(BD_KET);
945 for (
int i = this->_rowrank; i < this->_bonds.size(); i++) {
946 this->_bonds[i].set_type(BD_BRA);
948 this->_is_tag =
true;
949 this->_is_braket_form = this->_update_braket();
962 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
964 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
966 void group_basis_() {
967 cytnx_warning_msg(
true,
"[WARNING] group basis will not have any effect on DensUniTensor.%s",
971 void _save_dispatch(std::fstream &f)
const;
972 void _load_dispatch(std::fstream &f);
974 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
975 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
978 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
979 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
984 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
988 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
998 class BlockUniTensor :
public UniTensor_base {
1001 std::vector<std::vector<cytnx_uint64>> _inner_to_outer_idx;
1002 std::vector<Tensor> _blocks;
1008 void _fx_get_total_fluxs(std::vector<cytnx_uint64> &loc,
const std::vector<Symmetry> &syms,
1009 std::vector<cytnx_int64> &total_qns) {
1010 memset(&total_qns[0], 0,
sizeof(
cytnx_int64) * total_qns.size());
1013 if (this->_bonds[0].type() == BD_BRA)
1014 total_qns[i] = syms[0].reverse_rule(this->_bonds[0]._impl->_qnums[loc[0]][i]);
1016 total_qns[i] = this->_bonds[0]._impl->_qnums[loc[0]][i];
1018 for (
auto j = 1; j < loc.size(); j++) {
1019 if (this->_bonds[j].type() == BD_BRA)
1020 total_qns[i] = syms[i].combine_rule(
1021 total_qns[i], syms[i].reverse_rule(this->_bonds[j]._impl->_qnums[loc[j]][i]));
1024 syms[i].combine_rule(total_qns[i], this->_bonds[j]._impl->_qnums[loc[j]][i]);
1030 void _fx_locate_elem(
cytnx_int64 &bidx, std::vector<cytnx_uint64> &loc_in_T,
1031 const std::vector<cytnx_uint64> &locator)
const;
1034 void _fx_group_duplicates(
const std::vector<cytnx_uint64> &dup_bond_idxs,
1035 const std::vector<std::vector<cytnx_uint64>> &idx_mappers);
1037 void set_meta(BlockUniTensor *tmp,
const bool &inner,
const bool &outer)
const {
1040 tmp->_bonds = vec_clone(this->_bonds);
1041 tmp->_labels = this->_labels;
1042 tmp->_is_braket_form = this->_is_braket_form;
1043 tmp->_rowrank = this->_rowrank;
1044 tmp->_name = this->_name;
1047 tmp->_is_diag = this->_is_diag;
1051 tmp->_inner_to_outer_idx = this->_inner_to_outer_idx;
1055 BlockUniTensor *clone_meta(
const bool &inner,
const bool &outer)
const {
1056 BlockUniTensor *
tmp =
new BlockUniTensor();
1057 this->set_meta(tmp, inner, outer);
1063 this->uten_type_id =
UTenType.Block;
1064 this->_is_tag =
true;
1073 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
1074 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
1075 const int &device =
Device.cpu,
const bool &is_diag =
false,
1076 const bool &no_alloc =
false,
const std::string &name =
"");
1078 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
1079 const cytnx_int64 &rowrank = -1,
const std::string &name =
"") {
1081 true,
"[ERROR][BlockUniTensor] cannot use Init_by_tensor() on a BlockUniTensor.%s",
"\n");
1084 std::vector<cytnx_uint64> shape()
const {
1085 std::vector<cytnx_uint64> out(this->_bonds.size());
1087 out[i] = this->_bonds[i].dim();
1092 bool is_blockform()
const {
return true; }
1093 bool is_contiguous()
const {
1095 for (
int i = 0; i < this->_blocks.size(); i++) {
1096 out &= this->_blocks[i].is_contiguous();
1101 cytnx_uint64 Nblocks()
const {
return this->_blocks.size(); };
1103 void to_(
const int &device) {
1104 for (
cytnx_uint64 i = 0; i < this->_blocks.size(); i++) {
1105 this->_blocks[i].to_(device);
1109 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
1110 if (this->device() == device) {
1113 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1119 boost::intrusive_ptr<UniTensor_base> clone()
const {
1120 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
1121 tmp->_blocks = vec_clone(this->_blocks);
1122 boost::intrusive_ptr<UniTensor_base> out(tmp);
1126 unsigned int dtype()
const {
1128 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1131 return this->_blocks[0].dtype();
1133 int device()
const {
1135 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1138 return this->_blocks[0].device();
1140 std::string dtype_str()
const {
1142 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1145 return this->_blocks[0].dtype_str();
1147 std::string device_str()
const {
1149 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1152 return this->_blocks[0].device_str();
1156 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1158 return this->_blocks[idx].clone();
1162 Tensor get_block(
const std::vector<cytnx_int64> &indices,
const bool &force_return)
const {
1164 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1165 "Tensor rank (number of legs).%s",
1168 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1172 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1173 if (inds == this->_inner_to_outer_idx[i]) {
1181 return NullRefTensor;
1185 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, force_return=false, so "
1186 "error throws. \n If you want to return an empty block without error when block is "
1187 "not avaliable, set force_return=True.%s",
1191 return this->_blocks[b].clone();
1196 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1198 return this->_blocks[idx];
1202 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1204 return this->_blocks[idx];
1207 const Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
1208 const bool &force_return)
const {
1210 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1211 "Tensor rank (number of legs).%s",
1214 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1218 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1219 if (inds == this->_inner_to_outer_idx[i]) {
1227 return this->NullRefTensor;
1231 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, force_return=false, so "
1232 "error throws. \n If you want to return an empty block without error when block is "
1233 "not avaliable, set force_return=True.%s",
1237 return this->_blocks[b];
1241 Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
const bool &force_return) {
1243 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1244 "Tensor rank (number of legs).%s",
1247 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1251 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1252 if (inds == this->_inner_to_outer_idx[i]) {
1260 return this->NullRefTensor;
1264 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, force_return=false, so "
1265 "error throws. \n If you want to return an empty block without error when block is "
1266 "not avaliable, set force_return=True.%s",
1270 return this->_blocks[b];
1274 std::vector<Tensor> get_blocks()
const {
return vec_clone(this->_blocks); }
1275 const std::vector<Tensor> &get_blocks_(
const bool &)
const {
return this->_blocks; }
1276 std::vector<Tensor> &get_blocks_(
const bool &) {
return this->_blocks; }
1278 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
1279 if (rhs->uten_type() !=
UTenType.Block)
return false;
1280 if (rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
1282 for (
int i = 0; i < rhs->get_blocks_(1).size(); i++)
1283 if (this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i]) ==
false)
return false;
1290 "[ERROR][BlockUniTensor] rowrank should be [>=0] and [<=UniTensor.rank].%s",
1292 if (this->is_diag()) {
1294 "[ERROR][BlockUniTensor] rowrank should be [==1] when is_diag =true!.%s",
1297 this->_rowrank = new_rowrank;
1298 this->_is_braket_form = this->_update_braket();
1301 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
1302 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
1303 tmp->_blocks = this->_blocks;
1304 tmp->set_rowrank_(new_rowrank);
1305 boost::intrusive_ptr<UniTensor_base> out(tmp);
1309 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
1311 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
1314 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
1315 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
1317 boost::intrusive_ptr<UniTensor_base> contiguous_() {
1318 for (
unsigned int b = 0; b < this->_blocks.size(); b++) this->_blocks[b].contiguous_();
1319 return boost::intrusive_ptr<UniTensor_base>(
this);
1322 boost::intrusive_ptr<UniTensor_base> contiguous();
1324 void print_diagram(
const bool &bond_info =
false);
1325 void print_blocks(
const bool &full_info =
true)
const;
1326 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
1328 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
1329 const bool &mv_elem_self =
false,
1330 const bool &mv_elem_rhs =
false);
1332 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
1334 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
1335 const std::vector<std::string> &new_labels);
1337 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
1338 const std::string &new_label);
1339 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
1340 const std::string &new_label);
1342 std::vector<Symmetry> syms()
const;
1344 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0) {
1345 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1347 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
1349 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1353 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
1354 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
1355 tmp->_blocks.resize(this->_blocks.size());
1356 for (
cytnx_int64 blk = 0; blk < this->_blocks.size(); blk++) {
1357 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
1359 boost::intrusive_ptr<UniTensor_base> out(tmp);
1364 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
1367 "[ERROR][BlockUniTensor][get] cannot use get on a UniTensor with "
1368 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
1374 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
1377 "[ERROR][BlockUniTensor][get] cannot use get on a UniTensor with "
1378 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
1383 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1386 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1387 "of block @ idx=%d\n",
1390 this->_blocks[idx] = in.
clone();
1393 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1396 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1397 "of block @ idx=%d\n",
1400 this->_blocks[idx] = in;
1402 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &indices,
const bool &check) {
1404 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1405 "Tensor rank (number of legs).%s",
1408 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1412 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1413 if (inds == this->_inner_to_outer_idx[i]) {
1422 "[ERROR][put_block][BlockUniTensor] no avaliable block exists, "
1423 "check=true, so error throws. \n If you want without error when block "
1424 "is not avaliable, set check=false.%s",
1429 in.
shape() != this->_blocks[b].shape(),
1430 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1431 "of block @ idx=%d\n",
1434 this->_blocks[b] = in.
clone();
1437 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &indices,
const bool &check) {
1439 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1440 "Tensor rank (number of legs).%s",
1443 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1447 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1448 if (inds == this->_inner_to_outer_idx[i]) {
1457 "[ERROR][put_block][BlockUniTensor] no avaliable block exists, "
1458 "check=true, so error throws. \n If you want without error when block "
1459 "is not avaliable, set check=false.%s",
1464 in.
shape() != this->_blocks[b].shape(),
1465 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1466 "of block @ idx=%d\n",
1468 this->_blocks[b] = in;
1476 boost::intrusive_ptr<UniTensor_base>
Conj() {
1477 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1483 for (
int i = 0; i < this->_blocks.size(); i++) {
1484 this->_blocks[i].Conj_();
1489 boost::intrusive_ptr<UniTensor_base> Transpose() {
1490 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1496 boost::intrusive_ptr<UniTensor_base> normalize() {
1497 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1502 boost::intrusive_ptr<UniTensor_base> Dagger() {
1503 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1512 void Trace_(
const std::string &a,
const std::string &b);
1515 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
1516 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1518 if (out->rank() == 0) {
1519 DenseUniTensor *
tmp =
new DenseUniTensor();
1520 tmp->_block = ((BlockUniTensor *)out.get())->_blocks[0];
1521 out = boost::intrusive_ptr<UniTensor_base>(tmp);
1526 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1528 if (out->rank() == 0) {
1529 DenseUniTensor *
tmp =
new DenseUniTensor();
1530 tmp->_block = ((BlockUniTensor *)out.get())->_blocks[0];
1531 out = boost::intrusive_ptr<UniTensor_base>(tmp);
1538 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
1540 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
1541 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1543 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1545 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1547 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1549 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1551 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1553 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1555 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1557 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1559 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1562 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
1565 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1576 void _save_dispatch(std::fstream &f)
const;
1577 void _load_dispatch(std::fstream &f);
1580 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &q_index);
1583 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1584 void Add_(
const Scalar &rhs) {
1587 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
1588 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1589 "operation on the block(s).");
1592 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1593 void Mul_(
const Scalar &rhs);
1595 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1596 void Sub_(
const Scalar &rhs) {
1599 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
1600 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1601 "operation on the block(s).");
1603 void lSub_(
const Scalar &lhs) {
1606 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
1607 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1608 "operation on the block(s).");
1611 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs) {
1614 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
1615 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1616 "operation on the block(s).");
1618 void Div_(
const Scalar &rhs);
1619 void lDiv_(
const Scalar &lhs) {
1622 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s \n",
1623 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1624 "operation on the block(s).");
1626 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
1628 void group_basis_();
1630 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
false);
1631 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
1632 const bool &by_label);
1633 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
false);
1635 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
1637 bidx >= this->Nblocks(),
1638 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1640 return this->_inner_to_outer_idx[bidx];
1642 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
1644 bidx >= this->Nblocks(),
1645 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1647 return this->_inner_to_outer_idx[bidx];
1657 class UniTensor_options {
1664 UniTensor_options() {
1665 this->_is_diag =
false;
1666 this->_dtype =
Type.Double;
1667 this->_device =
Device.cpu;
1668 this->_rowrank = -1;
1671 UniTensor_options(
const UniTensor_options &rhs) {
1672 this->_is_diag = rhs._is_diag;
1673 this->_dtype = rhs._dtype;
1674 this->_device = rhs._device;
1675 this->_rowrank = rhs._rowrank;
1678 UniTensor_options &operator=(
const UniTensor_options &rhs) {
1679 this->_is_diag = rhs._is_diag;
1680 this->_dtype = rhs._dtype;
1681 this->_device = rhs._device;
1682 this->_rowrank = rhs._rowrank;
1686 UniTensor_options &is_diag(
const bool &in) {
1687 this->_is_diag = in;
1690 UniTensor_options &dtype(
const int &in) {
1694 UniTensor_options &device(
const int &in) {
1698 UniTensor_options &rowrank(
const int &in) {
1699 this->_rowrank = in;
1709 boost::intrusive_ptr<UniTensor_base>
_impl;
1713 this->_impl =
rhs._impl;
1747 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"")
1769 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"") {
1799 const std::string &
name =
"")
1804 "[DEBUG] message: entry for UniTensor(const std::vector<Bond> &bonds, const "
1805 "std::vector<std::string> &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned int "
1806 "&dtype=Type.Double, const int &device = Device.cpu, const bool &is_diag=false)%s",
1849 const std::string &
name =
"") {
1864 "[ERROR] All the Bond when init a UniTensor with symmetric must be in "
1865 "the same format!%s",
1870 is_sym,
"[ERROR] cannot have bonds with mixing of symmetry and non-symmetry.%s",
"\n");
1876 cytnx_warning_msg(
true,
"[DEBUG] message: entry dispatch: UniTensor: symmetric%s",
"\n");
1884 "[ERROR] internal error! [legacy Sparse entry] the Bond is symmetry but "
1885 "the version is not properly determined!%s",
1889 "[ERROR] internal error! the Bond is symmetry but the version is not "
1890 "properly determined!%s",
2003 std::vector<std::string>
vs(
new_lbls.size());
2005 [](
char *x) -> std::string { return std::string(x); });
2007 this->_impl->set_labels(
vs);
2031 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2032 "get_block()/get_blocks() first.%s",
2036 return tmp->_block.item<
T>();
2041 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2042 "get_block()/get_blocks() first.%s",
2046 return tmp->_block.item();
2071 unsigned int dtype()
const {
return this->_impl->dtype(); }
2086 int device()
const {
return this->_impl->device(); }
2092 std::string
name()
const {
return this->_impl->name(); }
2099 std::string
dtype_str()
const {
return this->_impl->dtype_str(); }
2106 std::string
device_str()
const {
return this->_impl->device_str(); }
2126 bool is_diag()
const {
return this->_impl->is_diag(); }
2133 bool is_tag()
const {
return this->_impl->is_tag(); }
2140 std::vector<Symmetry>
syms()
const {
return this->_impl->syms(); }
2154 const std::vector<std::string> &
labels()
const {
return this->_impl->labels(); }
2167 const std::vector<Bond> &
bonds()
const {
return this->_impl->bonds(); }
2172 std::vector<Bond> &
bonds() {
return this->_impl->bonds(); }
2187 std::vector<cytnx_uint64>
shape()
const {
return this->_impl->shape(); }
2267 [](
char *x) -> std::string { return std::string(x); });
2280 [](
char *x) -> std::string { return std::string(x); });
2282 this->_impl->relabels_(
vs);
2294 const std::vector<std::string> &
new_labels)
const {
2316 const std::vector<std::string> &
new_labels) {
2326 const std::initializer_list<char *> &
new_lbls)
const {
2330 [](
char *x) -> std::string { return std::string(x); });
2335 [](
char *x) -> std::string { return std::string(x); });
2345 const std::initializer_list<char *> &
new_lbls) {
2349 [](
char *x) -> std::string { return std::string(x); });
2354 [](
char *x) -> std::string { return std::string(x); });
2433 if (this->
dtype() == dtype) {
2475 std::vector<std::string>
vs(
mprs.size());
2477 [](
char *x) -> std::string { return std::string(x); });
2576 if (this->
uten_type() == UTenType.Block) {
2579 return this->_impl->at_for_sparse(
locator,
aux);
2581 }
else if (this->
uten_type() == UTenType.Sparse) {
2582 if (this->_impl->elem_exists(
locator)) {
2584 return this->_impl->at_for_sparse(
locator,
aux);
2586 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2602 if (this->
uten_type() == UTenType.Block) {
2605 return this->_impl->at_for_sparse(
locator,
aux);
2607 }
else if (this->
uten_type() == UTenType.Sparse) {
2608 if (this->_impl->elem_exists(
locator)) {
2610 return this->_impl->at_for_sparse(
locator,
aux);
2612 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2622 const std::vector<cytnx_uint64> &
locator)
const {
2625 "[ERROR][at] length of list should be the same for label and locator.%s",
2629 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2632 for (
int i = 0;
i <
lbls.size();
i++) {
2633 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
2635 "[ERROR] lbl:%s does not exist in current UniTensor.\n",
lbls[
i].c_str());
2636 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2639 return this->
at<T>(new_locator);
2642 T &
at(
const std::vector<std::string> &
lbls,
const std::vector<cytnx_uint64> &
locator) {
2645 "[ERROR][at] length of list should be the same for label and locator.%s",
2649 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2652 for (
int i = 0;
i <
lbls.size();
i++) {
2653 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
2655 "[ERROR] lbl:%s does not exist in current UniTensor.\n",
lbls[
i].c_str());
2656 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2659 return this->
at<T>(new_locator);
2666 const Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator)
const {
2667 if (this->
uten_type() == UTenType.Block) {
2668 return this->_impl->at_for_sparse(
locator);
2669 }
else if (this->
uten_type() == UTenType.Sparse) {
2670 if (this->_impl->elem_exists(
locator)) {
2671 return this->_impl->at_for_sparse(
locator);
2673 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2685 Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator) {
2686 if (this->
uten_type() == UTenType.Block) {
2687 return this->_impl->at_for_sparse(
locator);
2688 }
else if (this->
uten_type() == UTenType.Sparse) {
2689 if (this->_impl->elem_exists(
locator)) {
2690 return this->_impl->at_for_sparse(
locator);
2692 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2700 Scalar::Sproxy
at(
const std::vector<std::string> &
lbls,
2701 const std::vector<cytnx_uint64> &
locator) {
2704 "[ERROR][at] length of list should be the same for label and locator.%s",
2708 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2711 for (
int i = 0;
i <
lbls.size();
i++) {
2712 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
2714 "[ERROR] lbl:%s does not exist in current UniTensor.\n",
lbls[
i].c_str());
2715 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2718 return this->
at(new_locator);
2721 const Scalar::Sproxy
at(
const std::vector<std::string> &
lbls,
2722 const std::vector<cytnx_uint64> &
locator)
const {
2725 "[ERROR][at] length of list should be the same for label and locator.%s",
2729 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2732 for (
int i = 0;
i <
lbls.size();
i++) {
2733 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
2735 "[ERROR] lbl:%s does not exist in current UniTensor.\n",
lbls[
i].c_str());
2736 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2739 return this->
at(new_locator);
2760 return this->_impl->get_block(
qidx,
force);
2764 const bool &
force =
false)
const {
2767 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
2769 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
2771 std::vector<cytnx_int64>
loc_id(this->
rank());
2776 for (
int i = 0;
i <
lbls.size();
i++) {
2777 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
2779 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
2781 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2795 const bool &
force =
false)
const {
2796 std::vector<cytnx_int64> tmp =
qnum;
2810 const bool &
force =
false)
const {
2821 return this->_impl->get_block_(
idx);
2839 return this->_impl->get_block_(
qidx,
force);
2858 const bool &
force =
false) {
2861 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
2863 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
2865 std::vector<cytnx_int64>
loc_id(this->
rank());
2870 for (
int i = 0;
i <
lbls.size();
i++) {
2871 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
2873 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
2875 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2880 if (
out.dtype() !=
Type.Void) {
2890 std::vector<cytnx_int64> tmp =
qidx;
2903 const bool &
force =
false) {
2914 const bool &
force =
false)
const {
2915 return this->_impl->get_block_(
qidx,
force);
2922 const bool &
force =
false)
const {
2923 std::vector<cytnx_int64> tmp =
qidx;
2924 return this->_impl->get_block_(tmp,
force);
2931 const bool &
force =
false)
const {
2946 std::vector<Tensor>
get_blocks()
const {
return this->_impl->get_blocks(); }
2955 return this->_impl->get_blocks_(
silent);
2963 return this->_impl->get_blocks_(
silent);
2973 this->_impl->put_block(
in,
idx);
3127 return this->_impl->getTotalQnums(
physical);
3134 return this->_impl->get_blocks_qnums();
3144 if (this->_impl->uten_type() !=
rhs._impl->uten_type())
return false;
3146 return this->_impl->same_data(
rhs._impl);
3572 out._impl = this->_impl->
Conj();
3584 this->_impl->
Conj_();
3679 if (this->
uten_type() == UTenType.Block) {
3681 if (this->
rank() == 0) {
3684 this->_impl = boost::intrusive_ptr<UniTensor_base>(tmp);
3701 if (this->
uten_type() == UTenType.Block) {
3703 if (this->
rank() == 0) {
3706 this->_impl = boost::intrusive_ptr<UniTensor_base>(tmp);
3774 return this->_impl->elem_exists(
locator);
3784 return this->
at<T>(locator);
3795 this->
at(locator) =
rc;
3898 return this->_impl->get_qindices(
bidx);
3908 return this->_impl->get_qindices(
bidx);
3921 void _Load(std::fstream &f);
3922 void _Save(std::fstream &f)
const;
3926 this->_impl->from_(
rhs._impl,
force);
3933 std::ostream &operator<<(std::ostream &os,
const UniTensor &in);
3949 const bool &cacheR =
false);
3964 const bool &optimal);
3967 void _resolve_CT(std::vector<UniTensor> &TNlist);
3968 template <
class... T>
3969 void _resolve_CT(std::vector<UniTensor> &TNlist,
const UniTensor &in,
const T &...args) {
3970 TNlist.push_back(in);
3971 _resolve_CT(TNlist, args...);
3986 template <
class... T>
3988 const bool &optimal) {
3989 std::vector<UniTensor> TNlist;
3990 _resolve_CT(TNlist, in, args...);
3991 return Contracts(TNlist, order, optimal);
the object contains auxiliary properties for each Tensor rank (bond)
Definition Bond.hpp:178
Bond clone() const
return a copy of the instance Bond
Definition Bond.hpp:490
an tensor (multi-dimensional array)
Definition Tensor.hpp:41
void to_(const int &device)
move the current Tensor to the device.
Definition Tensor.hpp:615
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:702
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:514
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:682
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition Tensor.hpp:858
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:566
void set(const std::vector< cytnx::Accessor > &accessors, const Tensor &rhs)
set elements with the input Tensor using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:993
Tensor Norm() const
the Norm member function. Same as linalg::Norm(const Tensor &Tin), where Tin is the current Tensor.
Tensor astype(const int &new_type) const
return a new Tensor that cast to different dtype.
Definition Tensor.hpp:823
const bool & is_contiguous() const
return whether the Tensor is contiguous or not.
Definition Tensor.hpp:621
Tensor & Conj_()
the Conj_ member function. Same as cytnx::linalg::Conj_(Tensor &Tin), where Tin is the current Tensor...
int device() const
the device-id of the Tensor
Definition Tensor.hpp:521
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:961
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:541
An Enhanced tensor specifically designed for physical Tensor network simulation.
Definition UniTensor.hpp:1706
void put_block(const Tensor &in_tens, const std::vector< cytnx_int64 > &qidx, const bool &force)
Put the block into the UniTensor with given quantum number.
Definition UniTensor.hpp:2984
UniTensor to(const int &device) const
move the current UniTensor to the assigned device.
Definition UniTensor.hpp:2213
UniTensor & operator*=(const UniTensor &rhs)
The multiplication assignment operator of the UniTensor.
Definition UniTensor.hpp:3498
Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:2889
std::vector< Tensor > & get_blocks_(const bool &silent=false)
Definition UniTensor.hpp:2962
Tensor & get_block_(const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:2897
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:2550
UniTensor & operator/=(const UniTensor &rhs)
The division assignment operator of the UniTensor.
Definition UniTensor.hpp:3478
T & item()
Definition UniTensor.hpp:2029
bool is_contiguous() const
To tell whether the UniTensor is contiguous.
Definition UniTensor.hpp:2120
T get_elem(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:3783
UniTensor Div(const UniTensor &rhs) const
The division function of the UniTensor.
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:3907
UniTensor & set_label(const cytnx_int64 &idx, const char *new_label)
Definition UniTensor.hpp:1932
UniTensor & operator+=(const UniTensor &rhs)
The addition assignment operator of the UniTensor.
Definition UniTensor.hpp:3438
void to_dense_()
Convert the UniTensor to non-diagonal form, inplacely.
Definition UniTensor.hpp:3057
UniTensor reshape(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor.
Definition UniTensor.hpp:3020
std::vector< Tensor > get_blocks() const
Get all the blocks of the UniTensor.
Definition UniTensor.hpp:2946
UniTensor permute(const std::initializer_list< char * > &mapper, const cytnx_int64 &rowrank=-1) const
Definition UniTensor.hpp:2472
bool is_tag() const
To tell whether the UniTensor is tagged. That is, all of the Bond in the UniTensor is directional (al...
Definition UniTensor.hpp:2133
cytnx_int64 get_index(std::string lbl) const
Get the index of an desired label string.
Definition UniTensor.hpp:2161
std::string uten_type_str() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor in 'string' form.
Definition UniTensor.hpp:2113
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:1796
Tensor get_block(const std::vector< cytnx_int64 > &qidx, const bool &force=false) const
Get the block of the UniTensor for the given quantun indices.
Definition UniTensor.hpp:2759
void permute_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:2490
UniTensor & tag()
Set the UniTensor as a tagged UniTensor.
Definition UniTensor.hpp:3742
const Bond & bond_(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:2174
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force=false)
Definition UniTensor.hpp:3088
UniTensor & relabel_(const std::string &old_label, const std::string &new_label)
relabel the lags in the UniTensor by a given label.
Definition UniTensor.hpp:2400
UniTensor(const Tensor &in_tensor, const bool &is_diag=false, const cytnx_int64 &rowrank=-1, const std::vector< std::string > &in_labels={}, const std::string &name="")
Construct a UniTensor from a cytnx::Tensor.
Definition UniTensor.hpp:1745
Tensor & get_block_(const std::vector< cytnx_int64 > &qidx, const bool &force=false)
Get the shared view of block for the given quantum indices.
Definition UniTensor.hpp:2838
void Init(const Tensor &in_tensor, const bool &is_diag=false, const cytnx_int64 &rowrank=-1, const std::vector< std::string > &in_labels={}, const std::string &name="")
Initialize a UniTensor with cytnx::Tensor.
Definition UniTensor.hpp:1768
UniTensor get(const std::vector< Accessor > &accessors) const
Definition UniTensor.hpp:3004
UniTensor relabels(const std::initializer_list< char * > &old_lbls, const std::initializer_list< char * > &new_lbls) const
Definition UniTensor.hpp:2325
UniTensor Conj() const
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:3570
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:1947
UniTensor set_rowrank(const cytnx_uint64 &new_rowrank) const
Definition UniTensor.hpp:2022
void Save(const std::string &fname) const
save a UniTensor to file
UniTensor & operator-=(const Scalar &rhs)
The subtraction assignment operator for a given scalar.
Definition UniTensor.hpp:3528
cytnx_uint64 rowrank() const
Return the row rank of the UniTensor.
Definition UniTensor.hpp:2064
UniTensor & relabels_(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels)
relables part or all of the labels in UniTensor by given new labels
Definition UniTensor.hpp:2315
const T & at(const std::vector< std::string > &lbls, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:2621
UniTensor Sub(const Scalar &rhs) const
The subtraction function for a given scalar.
Tensor Norm() const
Return the norm of the UniTensor.
Definition UniTensor.hpp:3421
UniTensor Mul(const Scalar &rhs) const
The multiplication function for a given scalar.
UniTensor & set_labels(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2001
UniTensor & Sub_(const Scalar &rhs)
The subtraction function for a given scalar.
Definition UniTensor.hpp:3273
UniTensor & relabel_(const cytnx_int64 &inx, const std::string &new_label)
rebable the lags in the UniTensor by given index.
Definition UniTensor.hpp:2387
UniTensor & operator/=(const Scalar &rhs)
The division assignment operator for a given scalar.
Definition UniTensor.hpp:3543
const bool & is_braket_form() const
Check whether the UniTensor is in braket form.
Definition UniTensor.hpp:2148
void set_elem(const std::vector< cytnx_uint64 > &locator, const T2 &rc)
Definition UniTensor.hpp:3793
UniTensor Add(const Scalar &rhs) const
The addition function for a given scalar.
std::vector< cytnx_uint64 > shape() const
Get the shape of the UniTensor.
Definition UniTensor.hpp:2187
UniTensor to_dense()
Convert the UniTensor to non-diagonal form.
Definition UniTensor.hpp:3047
UniTensor relabels(const std::initializer_list< char * > &new_lbls) const
Definition UniTensor.hpp:2263
const Tensor & get_block_(const std::vector< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2913
void reshape_(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor, inplacely.
Definition UniTensor.hpp:3032
UniTensor & set_labels(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:1992
void permute_(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:2500
std::string name() const
Return the name of the UniTensor.
Definition UniTensor.hpp:2092
UniTensor & Add_(const Scalar &rhs)
The addition function for a given scalar.
Definition UniTensor.hpp:3243
UniTensor & Trace_(const std::string &a, const std::string &b)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:3677
UniTensor & truncate_(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim)
truncate bond dimension of the UniTensor by the given bond index and dimension.
Definition UniTensor.hpp:3855
Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition UniTensor.hpp:2685
UniTensor Trace(const std::string &a, const std::string &b) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:3647
Tensor get_block(const std::vector< std::string > &lbls, const std::vector< cytnx_uint64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2809
bool same_data(const UniTensor &rhs) const
Check whether the Blocks address are the same.
Definition UniTensor.hpp:3142
UniTensor astype(const unsigned int &dtype) const
Return a new UniTensor that cast to different data type.
Definition UniTensor.hpp:2431
UniTensor truncate(const std::string &label, const cytnx_uint64 &dim) const
truncate bond dimension of the UniTensor by the given bond label and dimension.
Definition UniTensor.hpp:3869
UniTensor Transpose() const
Take the transpose of the UniTensor.
Definition UniTensor.hpp:3598
UniTensor & set_label(const char *old_label, const std::string &new_label)
Definition UniTensor.hpp:1955
static UniTensor Load(const char *fname)
load a UniTensor from file
UniTensor & Dagger_()
Take the conjugate transpose to the UniTensor, inplacely.
Definition UniTensor.hpp:3730
void print_diagram(const bool &bond_info=false)
Plot the diagram of the UniTensor.
Definition UniTensor.hpp:2537
std::vector< Bond > & bonds()
Definition UniTensor.hpp:2172
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition UniTensor.hpp:2574
UniTensor & set_rowrank_(const cytnx_uint64 &new_rowrank)
Set the row rank of the UniTensor.
Definition UniTensor.hpp:2017
Bond bond(const std::string &lbl) const
Definition UniTensor.hpp:2181
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:1924
UniTensor & from(const UniTensor &rhs, const bool &force=false)
Definition UniTensor.hpp:3925
Bond & bond_(const std::string &lbl)
Definition UniTensor.hpp:2178
UniTensor contiguous() const
Make the UniTensor contiguous by coalescing the memory (storage).
Definition UniTensor.hpp:2521
UniTensor & relabels_(const std::initializer_list< char * > &new_lbls)
Definition UniTensor.hpp:2276
Tensor get_block(const cytnx_uint64 &idx=0) const
Get the block of the UniTensor for a given index.
Definition UniTensor.hpp:2748
const T & at(const std::vector< cytnx_uint64 > &locator) const
Get an element at specific location.
Definition UniTensor.hpp:2600
UniTensor & operator*=(const Scalar &rhs)
The multiplication assignment operator for a given scalar.
Definition UniTensor.hpp:3558
UniTensor relabels(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels) const
replace part or all labels by given new labels for the bonds.
Definition UniTensor.hpp:2293
void contiguous_()
Make the UniTensor contiguous by coalescing the memory (storage), inplacely.
Definition UniTensor.hpp:2531
UniTensor normalize() const
normalize the current UniTensor instance with 2-norm.
Definition UniTensor.hpp:3621
std::vector< Symmetry > syms() const
Return the symmetry type of the UniTensor.
Definition UniTensor.hpp:2140
UniTensor & Mul_(const UniTensor &rhs)
The multiplcation function of the UniTensor.
Definition UniTensor.hpp:3186
void put_block_(Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index, inplacely.
Definition UniTensor.hpp:2993
void combineBonds(const std::vector< std::string > &indicators, const bool &force=false)
Combine the sevral bonds of the UniTensor.
Definition UniTensor.hpp:3079
UniTensor relabel(const std::string &old_label, const std::string &new_label) const
relabel the lags in the UniTensor by a given label.
Definition UniTensor.hpp:2419
UniTensor & normalize_()
normalize the UniTensor, inplacely.
Definition UniTensor.hpp:3633
bool is_diag() const
To tell whether the UniTensor is in diagonal form.
Definition UniTensor.hpp:2126
int device() const
Return the device of the UniTensor.
Definition UniTensor.hpp:2086
UniTensor & Pow_(const double &p)
Power function.
const Tensor & get_block_(const std::vector< cytnx_uint64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2930
void set(const std::vector< Accessor > &accessors, const Tensor &rhs)
Definition UniTensor.hpp:3009
std::string dtype_str() const
Return the data type of the UniTensor in 'string' form.
Definition UniTensor.hpp:2099
UniTensor & operator+=(const Scalar &rhs)
The addition assignment operator for a given scalar.
Definition UniTensor.hpp:3513
UniTensor & Div_(const UniTensor &rhs)
The division function of the UniTensor.
Definition UniTensor.hpp:3228
UniTensor & Div_(const Scalar &rhs)
The division function for a given scalar.
Definition UniTensor.hpp:3288
cytnx_uint64 rank() const
Return the rank of the UniTensor.
Definition UniTensor.hpp:2058
void group_basis_()
Group the same quantum number basis together.
Definition UniTensor.hpp:2560
void to_(const int &device)
move the current UniTensor to the assigned device (inplace).
Definition UniTensor.hpp:2202
UniTensor & Trace_(const cytnx_int64 &a=0, const cytnx_int64 &b=1)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:3699
Tensor get_block_(const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx, const bool &force=false)
Get the shared (data) view of block for the given quantum indices on given labels.
Definition UniTensor.hpp:2857
UniTensor & set_name(const std::string &in)
Set the name of the UniTensor.
Definition UniTensor.hpp:1909
UniTensor Trace(const cytnx_int64 &a=0, const cytnx_int64 &b=1) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:3662
UniTensor & Add_(const UniTensor &rhs)
The addition function of the UniTensor.
Definition UniTensor.hpp:3165
UniTensor permute(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1) const
permute the lags of the UniTensor
Definition UniTensor.hpp:2449
UniTensor & set_label(const std::string &old_label, const char *new_label)
Definition UniTensor.hpp:1963
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:2462
unsigned int dtype() const
Return the data type of the UniTensor.
Definition UniTensor.hpp:2071
UniTensor Pow(const double &p) const
Power function.
UniTensor & Mul_(const Scalar &rhs)
The multiplication function for a given scalar.
Definition UniTensor.hpp:3258
UniTensor & operator-=(const UniTensor &rhs)
The subtraction assignment operator of the UniTensor.
Definition UniTensor.hpp:3458
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force, const bool &by_label)
Definition UniTensor.hpp:3064
UniTensor & set_label(const char *old_label, const char *new_label)
Definition UniTensor.hpp:1971
bool is_blockform() const
Check whether the UniTensor is in block form.
Definition UniTensor.hpp:2194
UniTensor group_basis() const
Definition UniTensor.hpp:2562
Scalar::Sproxy at(const std::vector< std::string > &lbls, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:2700
UniTensor Dagger() const
Take the conjugate transpose to the UniTensor.
Definition UniTensor.hpp:3718
T & at(const std::vector< std::string > &lbls, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:2642
const std::vector< Tensor > & get_blocks_(const bool &silent=false) const
Get all the blocks of the UniTensor, inplacely.
Definition UniTensor.hpp:2954
const Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2921
bool elem_exists(const std::vector< cytnx_uint64 > &locator) const
Geiven the locator, check if the element exists.
Definition UniTensor.hpp:3773
UniTensor & Sub_(const UniTensor &rhs)
The subtraction function of the UniTensor.
Definition UniTensor.hpp:3207
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:3110
void put_block(const Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index.
Definition UniTensor.hpp:2972
const Tensor & get_block_(const cytnx_uint64 &idx=0) const
Get the shared view of block for the given index.
Definition UniTensor.hpp:2820
static UniTensor Load(const std::string &fname)
load a UniTensor from file
const Bond & bond_(const std::string &lbl) const
Definition UniTensor.hpp:2177
Bond & bond_(const cytnx_uint64 &idx)
Definition UniTensor.hpp:2175
UniTensor relabel(const cytnx_int64 &inx, const std::string &new_label) const
rebable the lags in the UniTensor by given index.
Definition UniTensor.hpp:2374
UniTensor Mul(const UniTensor &rhs) const
The multiplication function of the UniTensor.
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:3897
UniTensor Div(const Scalar &rhs) const
The division function for a given scalar.
const std::vector< std::string > & labels() const
Return the labels of the UniTensor.
Definition UniTensor.hpp:2154
UniTensor & relabels_(const std::initializer_list< char * > &old_lbls, const std::initializer_list< char * > &new_lbls)
Definition UniTensor.hpp:2344
const std::vector< Bond > & bonds() const
Get the bonds of the UniTensor.
Definition UniTensor.hpp:2167
UniTensor truncate(const cytnx_int64 &bond_idx, const cytnx_uint64 &dim) const
truncate bond dimension of the UniTensor by the given bond index and dimension.
Definition UniTensor.hpp:3884
UniTensor & Transpose_()
Take the transpose of the UniTensor, inplacely.
Definition UniTensor.hpp:3610
UniTensor clone() const
Clone (deep copy) the UniTensor.
Definition UniTensor.hpp:2223
vec2d< cytnx_uint64 > & get_itoi()
Definition UniTensor.hpp:3918
void print_blocks(const bool &full_info=true) const
Print all of the blocks in the UniTensor.
Definition UniTensor.hpp:2543
Scalar::Sproxy item() const
Definition UniTensor.hpp:2039
const vec2d< cytnx_uint64 > & get_itoi() const
get the q-indices on each leg for all the blocks
Definition UniTensor.hpp:3917
std::string device_str() const
Return the device of the UniTensor in 'string' form.
Definition UniTensor.hpp:2106
const Scalar::Sproxy at(const std::vector< std::string > &lbls, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:2721
UniTensor relabels(const std::vector< std::string > &new_labels) const
relables all of the labels in UniTensor.
Definition UniTensor.hpp:2254
void put_block_(Tensor &in, const std::vector< cytnx_int64 > &qidx, const bool &force)
Put the block into the UniTensor with given quantum indices, inplacely.
Definition UniTensor.hpp:3001
UniTensor Sub(const UniTensor &rhs) const
The subtraction function of the UniTensor.
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:1846
UniTensor & Conj_()
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:3583
cytnx_uint64 Nblocks() const
Return the number of blocks in the UniTensor.
Definition UniTensor.hpp:2052
Tensor get_block(const std::vector< cytnx_uint64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:2804
void Save(const char *fname) const
save a UniTensor to file
Tensor get_block_(const std::vector< std::string > &lbls, const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:2902
Bond bond(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:2180
Tensor get_block(const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2763
UniTensor Add(const UniTensor &rhs) const
The addition function of the UniTensor.
UniTensor & truncate_(const std::string &label, const cytnx_uint64 &dim)
truncate bond dimension of the UniTensor by the given bond label and dimension.
Definition UniTensor.hpp:3842
Tensor get_block(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:2794
UniTensor & relabels_(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:2238
const Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator) const
Get an element at specific location.
Definition UniTensor.hpp:2666
int uten_type() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor.
Definition UniTensor.hpp:2079
Tensor & get_block_(const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:2828
#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 Conj(const cytnx::UniTensor &UT)
Elementwise conjugate of the UniTensor.
cytnx::UniTensor Trace(const cytnx::UniTensor &Tin, const cytnx_int64 &a=0, const cytnx_int64 &b=1)
void Conj_(cytnx::UniTensor &UT)
Inplace elementwise conjugate of the UniTensor.
Tensor Norm(const Tensor &Tl)
Calculate the norm of a tensor.
Helper function to print vector with ODT:
Definition Accessor.hpp:12
Device_class Device
data on which devices.
double cytnx_double
Definition Type.hpp:53
UniTensorType_class UTenType
UniTensor type.
uint32_t cytnx_uint32
Definition Type.hpp:56
std::complex< double > cytnx_complex128
Definition Type.hpp:63
float cytnx_float
Definition Type.hpp:54
int16_t cytnx_int16
Definition Type.hpp:60
std::complex< float > cytnx_complex64
Definition Type.hpp:62
int32_t cytnx_int32
Definition Type.hpp:59
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.
uint16_t cytnx_uint16
Definition Type.hpp:57
uint64_t cytnx_uint64
Definition Type.hpp:55
int64_t cytnx_int64
Definition Type.hpp:58
std::vector< std::vector< T > > vec2d
Definition Type.hpp:51
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.