14#include <initializer_list>
24 #include "backend/Scalar.hpp"
32 using namespace cytnx;
34 class UniTensorType_class {
42 std::string getname(
const int &ut_type);
66 class UniTensor_base :
public intrusive_ptr_base<UniTensor_base> {
74 std::vector<std::string> _labels;
75 std::vector<Bond> _bonds;
77 bool _update_braket() {
78 if (_bonds.size() == 0)
return false;
80 if (this->_bonds[0].type() != bondType::BD_REG) {
82 for (
unsigned int i = 0; i < this->_bonds.size(); i++) {
83 if (i < this->_rowrank) {
84 if (this->_bonds[i].type() != bondType::BD_KET)
return false;
86 if (this->_bonds[i].type() != bondType::BD_BRA)
return false;
96 friend class DenseUniTensor;
98 friend class BlockUniTensor;
102 _name(std::string(
"")),
103 _is_braket_form(false),
109 UniTensor_base(
const UniTensor_base &rhs);
110 UniTensor_base &operator=(UniTensor_base &rhs);
113 bool is_diag()
const {
return this->_is_diag; }
114 const bool &is_braket_form()
const {
return this->_is_braket_form; }
115 const bool &is_tag()
const {
return this->_is_tag; }
116 const std::vector<std::string> &labels()
const {
return this->_labels; }
124 std::vector<std::string> labels = this->_labels;
126 if (labels[i] == label)
return i;
130 const std::vector<Bond> &bonds()
const {
return this->_bonds; }
131 std::vector<Bond> &bonds() {
return this->_bonds; }
134 cytnx_error_msg(idx >= this->_bonds.size(),
"[ERROR][bond] index %d out of bound, total %d\n",
135 idx, this->_bonds.size());
136 return this->_bonds[idx];
139 Bond &bond_(
const std::string &label) {
140 auto res = std::find(this->_labels.begin(), this->_labels.end(), label);
141 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n", label.c_str());
142 cytnx_uint64 idx = std::distance(this->_labels.begin(), res);
144 return this->bond_(idx);
147 const std::string &name()
const {
return this->_name; }
148 cytnx_uint64 rank()
const {
return this->_labels.size(); }
149 void set_name(
const std::string &in) { this->_name = in; }
161 void set_label(
const std::string &oldlabel,
const std::string &new_label) {
163 auto res = std::find(this->_labels.begin(), this->_labels.end(), oldlabel);
164 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n",
166 idx = std::distance(this->_labels.begin(), res);
168 cytnx_error_msg(idx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
172 for (
cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
173 if (i == idx)
continue;
174 if (new_label == this->_labels[i]) {
179 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
181 this->_labels[idx] = new_label;
183 void set_label(
const cytnx_int64 &inx,
const std::string &new_label) {
185 cytnx_error_msg(inx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
189 for (
cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
190 if (i == inx)
continue;
191 if (new_label == this->_labels[i]) {
196 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
198 this->_labels[inx] = new_label;
201 void set_labels(
const std::vector<std::string> &new_labels);
202 void relabels_(
const std::vector<std::string> &new_labels);
203 void relabels_(
const std::vector<std::string> &old_labels,
204 const std::vector<std::string> &new_labels);
205 void relabel_(
const std::string &old_label,
const std::string &new_label) {
206 this->set_label(old_label, new_label);
208 void relabel_(
const cytnx_int64 &inx,
const std::string &new_label) {
209 this->set_label(inx, new_label);
212 int uten_type() {
return this->uten_type_id; }
213 std::string uten_type_str() {
return UTenType.getname(this->uten_type_id); }
218 virtual void Init(
const std::vector<Bond> &bonds,
219 const std::vector<std::string> &in_labels = {},
220 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
221 const int &device =
Device.cpu,
const bool &is_diag =
false,
222 const bool &no_alloc =
false,
const std::string &name =
"");
224 virtual void Init_by_Tensor(
const Tensor &in,
const bool &is_diag =
false,
225 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
226 virtual std::vector<cytnx_uint64> shape()
const;
227 virtual bool is_blockform()
const;
228 virtual bool is_contiguous()
const;
229 virtual void to_(
const int &device);
230 virtual boost::intrusive_ptr<UniTensor_base> to(
const int &device);
231 virtual boost::intrusive_ptr<UniTensor_base> clone()
const;
232 virtual unsigned int dtype()
const;
233 virtual int device()
const;
234 virtual std::string dtype_str()
const;
235 virtual std::string device_str()
const;
236 virtual void set_rowrank_(
const cytnx_uint64 &new_rowrank);
237 virtual boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const;
239 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
241 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
246 virtual void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
247 virtual void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
251 virtual boost::intrusive_ptr<UniTensor_base> contiguous_();
252 virtual boost::intrusive_ptr<UniTensor_base> contiguous();
253 virtual void print_diagram(
const bool &bond_info =
false);
254 virtual void print_blocks(
const bool &full_info =
true)
const;
255 virtual void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
257 virtual boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const;
261 virtual Tensor get_block(
const std::vector<cytnx_int64> &qnum,
262 const bool &force)
const;
266 virtual const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
267 const bool &force)
const;
270 virtual Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
272 virtual bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const;
274 virtual std::vector<Tensor> get_blocks()
const;
275 virtual const std::vector<Tensor> &get_blocks_(
const bool &)
const;
276 virtual std::vector<Tensor> &get_blocks_(
const bool &);
280 virtual void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
282 virtual void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force);
285 virtual boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
288 virtual void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
290 virtual void reshape_(
const std::vector<cytnx_int64> &new_shape,
292 virtual boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
294 virtual boost::intrusive_ptr<UniTensor_base> to_dense();
295 virtual void to_dense_();
296 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
297 const bool &by_label);
298 virtual void combineBonds(
const std::vector<std::string> &indicators,
299 const bool &force =
false);
300 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
301 const bool &force =
false);
302 virtual boost::intrusive_ptr<UniTensor_base> contract(
303 const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self =
false,
304 const bool &mv_elem_rhs =
false);
305 virtual std::vector<Bond> getTotalQnums(
const bool &physical =
false);
306 virtual std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const;
307 virtual void Trace_(
const std::string &a,
const std::string &b);
310 virtual boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b);
313 virtual boost::intrusive_ptr<UniTensor_base> relabels(
314 const std::vector<std::string> &new_labels);
316 virtual boost::intrusive_ptr<UniTensor_base> relabels(
317 const std::vector<std::string> &old_labels,
const std::vector<std::string> &new_labels);
319 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
320 const std::string &new_label);
322 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
323 const std::string &new_label);
325 virtual std::vector<Symmetry> syms()
const;
328 virtual void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
329 virtual void Add_(
const Scalar &rhs);
331 virtual void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
332 virtual void Mul_(
const Scalar &rhs);
334 virtual void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
335 virtual void Sub_(
const Scalar &rhs);
336 virtual void lSub_(
const Scalar &lhs);
338 virtual void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
339 virtual void Div_(
const Scalar &rhs);
340 virtual void lDiv_(
const Scalar &lhs);
343 virtual boost::intrusive_ptr<UniTensor_base> normalize();
344 virtual void normalize_();
346 virtual boost::intrusive_ptr<UniTensor_base>
Conj();
347 virtual void Conj_();
349 virtual boost::intrusive_ptr<UniTensor_base> Transpose();
350 virtual void Transpose_();
352 virtual boost::intrusive_ptr<UniTensor_base> Dagger();
353 virtual void Dagger_();
357 virtual void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
360 virtual bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
363 virtual Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
364 virtual const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
366 virtual cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
368 virtual cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
370 virtual cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
372 virtual cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
374 virtual cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
376 virtual cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
378 virtual cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
380 virtual cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
382 virtual cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
384 virtual cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
387 virtual const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
389 virtual const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
391 virtual const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
393 virtual const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
395 virtual const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
397 virtual const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
399 virtual const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
401 virtual const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
403 virtual const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
405 virtual const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
408 virtual void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
410 virtual void group_basis_();
411 virtual const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const;
412 virtual std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx);
416 virtual void _save_dispatch(std::fstream &f)
const;
417 virtual void _load_dispatch(std::fstream &f);
419 virtual ~UniTensor_base(){};
425 class DenseUniTensor :
public UniTensor_base {
429 std::vector<Tensor> _interface_block;
430 DenseUniTensor *clone_meta()
const {
431 DenseUniTensor *
tmp =
new DenseUniTensor();
432 tmp->_bonds = vec_clone(this->_bonds);
433 tmp->_labels = this->_labels;
434 tmp->_is_braket_form = this->_is_braket_form;
435 tmp->_rowrank = this->_rowrank;
436 tmp->_is_diag = this->_is_diag;
437 tmp->_name = this->_name;
438 tmp->_is_tag = this->_is_tag;
443 DenseUniTensor() { this->uten_type_id =
UTenType.Dense; };
452 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
453 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
454 const int &device =
Device.cpu,
const bool &is_diag =
false,
455 const bool &no_alloc =
false,
const std::string &name =
"");
457 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
458 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
459 std::vector<cytnx_uint64> shape()
const {
460 if (this->_is_diag) {
461 std::vector<cytnx_uint64> shape = this->_block.
shape();
462 shape.push_back(shape[0]);
465 return this->_block.
shape();
468 bool is_blockform()
const {
return false; }
469 void to_(
const int &device) { this->_block.
to_(device); }
470 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
471 if (this->device() == device) {
472 std::vector<Tensor> _interface_block;
475 boost::intrusive_ptr<UniTensor_base> out = this->clone();
482 "[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
483 if (this->is_diag()) {
484 cytnx_error_msg(new_rowrank != 1,
"[ERROR] rowrank should be [==1] when is_diag =true!.%s",
488 this->_rowrank = new_rowrank;
491 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
492 DenseUniTensor *out_raw = this->clone_meta();
493 out_raw->_block = this->_block;
494 out_raw->set_rowrank_(new_rowrank);
495 boost::intrusive_ptr<UniTensor_base> out(out_raw);
499 boost::intrusive_ptr<UniTensor_base> clone()
const {
500 DenseUniTensor *
tmp = this->clone_meta();
502 boost::intrusive_ptr<UniTensor_base> out(tmp);
505 bool is_contiguous()
const {
return this->_block.
is_contiguous(); }
506 unsigned int dtype()
const {
return this->_block.
dtype(); }
507 int device()
const {
return this->_block.
device(); }
508 std::string dtype_str()
const {
return Type.getname(this->_block.
dtype()); }
509 std::string device_str()
const {
return Device.getname(this->_block.
device()); }
519 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
521 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
532 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
533 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
535 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
537 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
538 const std::vector<std::string> &new_labels);
550 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
551 const std::string &new_label);
552 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
553 const std::string &new_label);
555 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
556 DenseUniTensor *
tmp = this->clone_meta();
557 tmp->_block = this->_block.
astype(dtype);
558 boost::intrusive_ptr<UniTensor_base> out(tmp);
562 std::vector<Symmetry> syms()
const {
563 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] dense unitensor does not have symmetry.%s",
565 return std::vector<Symmetry>();
568 boost::intrusive_ptr<UniTensor_base> contiguous_() {
570 return boost::intrusive_ptr<UniTensor_base>(
this);
572 boost::intrusive_ptr<UniTensor_base> contiguous() {
574 if (this->is_contiguous()) {
575 boost::intrusive_ptr<UniTensor_base> out(
this);
578 DenseUniTensor *
tmp = this->clone_meta();
580 boost::intrusive_ptr<UniTensor_base> out(tmp);
584 void print_diagram(
const bool &bond_info =
false);
585 void print_blocks(
const bool &full_info =
true)
const;
586 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
589 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
591 true,
"[ERROR][DenseUniTensor] try to get_block() using qnum on a non-symmetry UniTensor%s",
596 const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
599 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
603 Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force) {
606 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
617 std::vector<Tensor> get_blocks()
const {
618 std::vector<Tensor> out;
620 true,
"[ERROR][DenseUniTensor] cannot use get_blocks(), use get_block() instead!%s",
"\n");
623 const std::vector<Tensor> &get_blocks_(
const bool &silent =
false)
const {
625 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
627 return this->_interface_block;
629 std::vector<Tensor> &get_blocks_(
const bool &silent =
false) {
631 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
633 return this->_interface_block;
645 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
650 if (this->is_diag()) {
652 in.
shape() != this->_block.shape(),
653 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
654 this->_block = in.
clone();
657 in.
shape() != this->shape(),
658 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
659 this->_block = in.
clone();
672 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
677 if (this->is_diag()) {
679 in.
shape() != this->_block.shape(),
680 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
684 in.
shape() != this->shape(),
685 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
690 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
692 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
695 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
697 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
701 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
702 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
703 out->Init_by_Tensor(this->_block.
get(accessors),
false, 0);
707 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
708 this->_block.
set(accessors, rhs);
711 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0);
712 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
714 boost::intrusive_ptr<UniTensor_base> to_dense();
725 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
726 const bool &by_label);
727 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
true);
728 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
true);
729 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
730 const bool &mv_elem_self =
false,
731 const bool &mv_elem_rhs =
false);
732 std::vector<Bond> getTotalQnums(
const bool &physical =
false) {
734 "getTotalQnums can only operate on UniTensor with symmetry.\n");
735 return std::vector<Bond>();
738 std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const {
740 "get_blocks_qnums can only operate on UniTensor with symmetry.\n");
741 return std::vector<std::vector<cytnx_int64>>();
744 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
745 if (rhs->uten_type() !=
UTenType.Dense)
return false;
747 return this->get_block_().same_data(rhs->get_block_());
753 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
754 void Add_(
const Scalar &rhs);
756 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
757 void Mul_(
const Scalar &rhs);
759 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
760 void Sub_(
const Scalar &rhs);
761 void lSub_(
const Scalar &lhs);
763 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
764 void Div_(
const Scalar &rhs);
765 void lDiv_(
const Scalar &lhs);
769 boost::intrusive_ptr<UniTensor_base>
Conj() {
770 boost::intrusive_ptr<UniTensor_base> out = this->clone();
775 boost::intrusive_ptr<UniTensor_base> Transpose() {
776 boost::intrusive_ptr<UniTensor_base> out = this->clone();
782 boost::intrusive_ptr<UniTensor_base> normalize() {
783 boost::intrusive_ptr<UniTensor_base> out = this->clone();
789 boost::intrusive_ptr<UniTensor_base> Dagger() {
790 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
808 void Trace_(
const std::string &a,
const std::string &b);
809 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
810 boost::intrusive_ptr<UniTensor_base> out = this->clone();
815 boost::intrusive_ptr<UniTensor_base> out = this->clone();
822 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const {
824 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
826 return Scalar::Sproxy();
828 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
831 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
835 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
838 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
842 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
845 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
849 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
852 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
856 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
859 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
863 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
866 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
870 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
873 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
877 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
880 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
884 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
887 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
891 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
894 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
899 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator) {
901 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
903 return Scalar::Sproxy();
908 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
912 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
915 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
921 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
927 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
933 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
939 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
945 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",
957 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
963 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
968 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const {
970 true,
"[ERROR][DenseUniTensor] elem_exists can only be used on UniTensor with Symmetry.%s",
974 if (!this->is_tag()) {
975 for (
int i = 0; i < this->_rowrank; i++) {
976 this->_bonds[i].set_type(BD_KET);
978 for (
int i = this->_rowrank; i < this->_bonds.size(); i++) {
979 this->_bonds[i].set_type(BD_BRA);
981 this->_is_tag =
true;
982 this->_is_braket_form = this->_update_braket();
995 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
997 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
999 void group_basis_() {
1000 cytnx_warning_msg(
true,
"[WARNING] group basis will not have any effect on DensUniTensor.%s",
1004 void _save_dispatch(std::fstream &f)
const;
1005 void _load_dispatch(std::fstream &f);
1007 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
1008 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
1011 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
1012 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
1017 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
1021 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
1031 class BlockUniTensor :
public UniTensor_base {
1034 std::vector<std::vector<cytnx_uint64>> _inner_to_outer_idx;
1035 std::vector<Tensor> _blocks;
1041 void _fx_get_total_fluxs(std::vector<cytnx_uint64> &loc,
const std::vector<Symmetry> &syms,
1042 std::vector<cytnx_int64> &total_qns) {
1043 memset(&total_qns[0], 0,
sizeof(
cytnx_int64) * total_qns.size());
1046 if (this->_bonds[0].type() == BD_BRA)
1047 total_qns[i] = syms[0].reverse_rule(this->_bonds[0]._impl->_qnums[loc[0]][i]);
1049 total_qns[i] = this->_bonds[0]._impl->_qnums[loc[0]][i];
1051 for (
auto j = 1; j < loc.size(); j++) {
1052 if (this->_bonds[j].type() == BD_BRA)
1053 total_qns[i] = syms[i].combine_rule(
1054 total_qns[i], syms[i].reverse_rule(this->_bonds[j]._impl->_qnums[loc[j]][i]));
1057 syms[i].combine_rule(total_qns[i], this->_bonds[j]._impl->_qnums[loc[j]][i]);
1063 void _fx_locate_elem(
cytnx_int64 &bidx, std::vector<cytnx_uint64> &loc_in_T,
1064 const std::vector<cytnx_uint64> &locator)
const;
1067 void _fx_group_duplicates(
const std::vector<cytnx_uint64> &dup_bond_idxs,
1068 const std::vector<std::vector<cytnx_uint64>> &idx_mappers);
1070 void set_meta(BlockUniTensor *tmp,
const bool &inner,
const bool &outer)
const {
1073 tmp->_bonds = vec_clone(this->_bonds);
1074 tmp->_labels = this->_labels;
1075 tmp->_is_braket_form = this->_is_braket_form;
1076 tmp->_rowrank = this->_rowrank;
1077 tmp->_name = this->_name;
1080 tmp->_is_diag = this->_is_diag;
1084 tmp->_inner_to_outer_idx = this->_inner_to_outer_idx;
1088 BlockUniTensor *clone_meta(
const bool &inner,
const bool &outer)
const {
1089 BlockUniTensor *
tmp =
new BlockUniTensor();
1090 this->set_meta(tmp, inner, outer);
1096 this->uten_type_id =
UTenType.Block;
1097 this->_is_tag =
true;
1106 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
1107 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
1108 const int &device =
Device.cpu,
const bool &is_diag =
false,
1109 const bool &no_alloc =
false,
const std::string &name =
"");
1111 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
1112 const cytnx_int64 &rowrank = -1,
const std::string &name =
"") {
1114 true,
"[ERROR][BlockUniTensor] cannot use Init_by_tensor() on a BlockUniTensor.%s",
"\n");
1117 std::vector<cytnx_uint64> shape()
const {
1118 std::vector<cytnx_uint64> out(this->_bonds.size());
1120 out[i] = this->_bonds[i].dim();
1125 bool is_blockform()
const {
return true; }
1126 bool is_contiguous()
const {
1128 for (
int i = 0; i < this->_blocks.size(); i++) {
1129 out &= this->_blocks[i].is_contiguous();
1134 cytnx_uint64 Nblocks()
const {
return this->_blocks.size(); };
1136 void to_(
const int &device) {
1137 for (
cytnx_uint64 i = 0; i < this->_blocks.size(); i++) {
1138 this->_blocks[i].to_(device);
1142 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
1143 if (this->device() == device) {
1146 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1152 boost::intrusive_ptr<UniTensor_base> clone()
const {
1153 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
1154 tmp->_blocks = vec_clone(this->_blocks);
1155 boost::intrusive_ptr<UniTensor_base> out(tmp);
1159 unsigned int dtype()
const {
1161 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1164 return this->_blocks[0].dtype();
1166 int device()
const {
1168 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1171 return this->_blocks[0].device();
1173 std::string dtype_str()
const {
1175 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1178 return this->_blocks[0].dtype_str();
1180 std::string device_str()
const {
1182 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1185 return this->_blocks[0].device_str();
1189 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1191 return this->_blocks[idx].clone();
1195 Tensor get_block(
const std::vector<cytnx_int64> &indices,
const bool &force_return)
const {
1197 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1198 "Tensor rank (number of legs).%s",
1201 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1205 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1206 if (inds == this->_inner_to_outer_idx[i]) {
1214 return NullRefTensor;
1217 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1218 "force_return=false, so "
1219 "error throws. \n If you want to return an empty block without "
1220 "error when block is "
1221 "not avaliable, set force_return=True.%s",
1225 return this->_blocks[b].clone();
1230 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1232 return this->_blocks[idx];
1236 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1238 return this->_blocks[idx];
1241 const Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
1242 const bool &force_return)
const {
1244 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1245 "Tensor rank (number of legs).%s",
1248 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1252 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1253 if (inds == this->_inner_to_outer_idx[i]) {
1261 return this->NullRefTensor;
1264 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1265 "force_return=false, so "
1266 "error throws. \n If you want to return an empty block without "
1267 "error when block is "
1268 "not avaliable, set force_return=True.%s",
1272 return this->_blocks[b];
1276 Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
const bool &force_return) {
1278 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1279 "Tensor rank (number of legs).%s",
1282 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1286 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1287 if (inds == this->_inner_to_outer_idx[i]) {
1295 return this->NullRefTensor;
1298 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1299 "force_return=false, so "
1300 "error throws. \n If you want to return an empty block without "
1301 "error when block is "
1302 "not avaliable, set force_return=True.%s",
1306 return this->_blocks[b];
1310 std::vector<Tensor> get_blocks()
const {
return vec_clone(this->_blocks); }
1311 const std::vector<Tensor> &get_blocks_(
const bool &)
const {
return this->_blocks; }
1312 std::vector<Tensor> &get_blocks_(
const bool &) {
return this->_blocks; }
1314 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
1315 if (rhs->uten_type() !=
UTenType.Block)
return false;
1316 if (rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
1318 for (
int i = 0; i < rhs->get_blocks_(1).size(); i++)
1319 if (this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i]) ==
false)
return false;
1326 "[ERROR][BlockUniTensor] rowrank should be [>=0] and [<=UniTensor.rank].%s",
1328 if (this->is_diag()) {
1330 "[ERROR][BlockUniTensor] rowrank should be [==1] when is_diag =true!.%s",
1333 this->_rowrank = new_rowrank;
1334 this->_is_braket_form = this->_update_braket();
1337 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
1338 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
1339 tmp->_blocks = this->_blocks;
1340 tmp->set_rowrank_(new_rowrank);
1341 boost::intrusive_ptr<UniTensor_base> out(tmp);
1345 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
1347 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
1350 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
1351 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
1353 boost::intrusive_ptr<UniTensor_base> contiguous_() {
1354 for (
unsigned int b = 0; b < this->_blocks.size(); b++) this->_blocks[b].contiguous_();
1355 return boost::intrusive_ptr<UniTensor_base>(
this);
1358 boost::intrusive_ptr<UniTensor_base> contiguous();
1360 void print_diagram(
const bool &bond_info =
false);
1361 void print_blocks(
const bool &full_info =
true)
const;
1362 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
1364 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
1365 const bool &mv_elem_self =
false,
1366 const bool &mv_elem_rhs =
false);
1368 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
1370 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
1371 const std::vector<std::string> &new_labels);
1373 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
1374 const std::string &new_label);
1375 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
1376 const std::string &new_label);
1378 std::vector<Symmetry> syms()
const;
1380 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0) {
1381 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1383 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
1385 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1389 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
1390 BlockUniTensor *
tmp = this->clone_meta(
true,
true);
1391 tmp->_blocks.resize(this->_blocks.size());
1392 for (
cytnx_int64 blk = 0; blk < this->_blocks.size(); blk++) {
1393 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
1395 boost::intrusive_ptr<UniTensor_base> out(tmp);
1400 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
1403 "[ERROR][BlockUniTensor][get] cannot use get on a UniTensor with "
1404 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
1410 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
1413 "[ERROR][BlockUniTensor][get] cannot use get on a UniTensor with "
1414 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
1420 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1423 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1428 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1431 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1432 "of block @ idx=%d\n",
1435 this->_blocks[idx] = in.
clone();
1439 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1442 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1447 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1450 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1451 "of block @ idx=%d\n",
1454 this->_blocks[idx] = in;
1456 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &indices,
const bool &check) {
1458 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1461 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1467 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1468 "Tensor rank (number of legs).%s",
1471 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1475 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1476 if (inds == this->_inner_to_outer_idx[i]) {
1485 "[ERROR][put_block][BlockUniTensor] no avaliable block exists, "
1486 "check=true, so error throws. \n If you want without error when block "
1487 "is not avaliable, set check=false.%s",
1492 in.
shape() != this->_blocks[b].shape(),
1493 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1494 "of block @ idx=%d\n",
1497 this->_blocks[b] = in.
clone();
1500 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &indices,
const bool &check) {
1502 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1505 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1511 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1512 "Tensor rank (number of legs).%s",
1515 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1519 for (
cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1520 if (inds == this->_inner_to_outer_idx[i]) {
1529 "[ERROR][put_block][BlockUniTensor] no avaliable block exists, "
1530 "check=true, so error throws. \n If you want without error when block "
1531 "is not avaliable, set check=false.%s",
1536 in.
shape() != this->_blocks[b].shape(),
1537 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1538 "of block @ idx=%d\n",
1540 this->_blocks[b] = in;
1548 boost::intrusive_ptr<UniTensor_base>
Conj() {
1549 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1555 for (
int i = 0; i < this->_blocks.size(); i++) {
1556 this->_blocks[i].Conj_();
1561 boost::intrusive_ptr<UniTensor_base> Transpose() {
1562 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1568 boost::intrusive_ptr<UniTensor_base> normalize() {
1569 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1574 boost::intrusive_ptr<UniTensor_base> Dagger() {
1575 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1584 void Trace_(
const std::string &a,
const std::string &b);
1587 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
1588 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1590 if (out->rank() == 0) {
1591 DenseUniTensor *
tmp =
new DenseUniTensor();
1592 tmp->_block = ((BlockUniTensor *)out.get())->_blocks[0];
1593 out = boost::intrusive_ptr<UniTensor_base>(tmp);
1598 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1600 if (out->rank() == 0) {
1601 DenseUniTensor *
tmp =
new DenseUniTensor();
1602 tmp->_block = ((BlockUniTensor *)out.get())->_blocks[0];
1603 out = boost::intrusive_ptr<UniTensor_base>(tmp);
1610 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
1612 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
1613 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1615 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1617 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1619 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1621 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1623 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1625 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1627 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1629 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1631 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1634 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
1637 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1648 void _save_dispatch(std::fstream &f)
const;
1649 void _load_dispatch(std::fstream &f);
1652 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &q_index);
1655 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1656 void Add_(
const Scalar &rhs) {
1659 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1661 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1662 "operation on the block(s).");
1665 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1666 void Mul_(
const Scalar &rhs);
1668 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1669 void Sub_(
const Scalar &rhs) {
1672 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1674 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1675 "operation on the block(s).");
1677 void lSub_(
const Scalar &lhs) {
1680 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1682 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1683 "operation on the block(s).");
1686 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs) {
1689 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1691 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1692 "operation on the block(s).");
1694 void Div_(
const Scalar &rhs);
1695 void lDiv_(
const Scalar &lhs) {
1698 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1700 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1701 "operation on the block(s).");
1703 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
1705 void group_basis_();
1707 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
false);
1708 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
1709 const bool &by_label);
1710 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
false);
1712 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
1714 bidx >= this->Nblocks(),
1715 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1717 return this->_inner_to_outer_idx[bidx];
1719 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
1721 bidx >= this->Nblocks(),
1722 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1724 return this->_inner_to_outer_idx[bidx];
1734 class UniTensor_options {
1741 UniTensor_options() {
1742 this->_is_diag =
false;
1743 this->_dtype =
Type.Double;
1744 this->_device =
Device.cpu;
1745 this->_rowrank = -1;
1748 UniTensor_options(
const UniTensor_options &rhs) {
1749 this->_is_diag = rhs._is_diag;
1750 this->_dtype = rhs._dtype;
1751 this->_device = rhs._device;
1752 this->_rowrank = rhs._rowrank;
1755 UniTensor_options &operator=(
const UniTensor_options &rhs) {
1756 this->_is_diag = rhs._is_diag;
1757 this->_dtype = rhs._dtype;
1758 this->_device = rhs._device;
1759 this->_rowrank = rhs._rowrank;
1763 UniTensor_options &is_diag(
const bool &in) {
1764 this->_is_diag = in;
1767 UniTensor_options &dtype(
const int &in) {
1771 UniTensor_options &device(
const int &in) {
1775 UniTensor_options &rowrank(
const int &in) {
1776 this->_rowrank = in;
1786 boost::intrusive_ptr<UniTensor_base>
_impl;
1790 this->_impl =
rhs._impl;
1824 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"")
1846 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"") {
1876 const std::string &
name =
"")
1881 "[DEBUG] message: entry for UniTensor(const std::vector<Bond> &bonds, const "
1882 "std::vector<std::string> &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned "
1884 "&dtype=Type.Double, const int &device = Device.cpu, const bool &is_diag=false)%s",
1927 const std::string &
name =
"") {
1942 "[ERROR] All the Bond when init a UniTensor with symmetric must be in "
1943 "the same format!%s",
1948 is_sym,
"[ERROR] cannot have bonds with mixing of symmetry and non-symmetry.%s",
"\n");
1954 cytnx_warning_msg(
true,
"[DEBUG] message: entry dispatch: UniTensor: symmetric%s",
"\n");
1962 "[ERROR] internal error! [legacy Sparse entry] the Bond is symmetry but "
1963 "the version is not properly determined!%s",
1967 "[ERROR] internal error! the Bond is symmetry but the version is not "
1968 "properly determined!%s",
2081 std::vector<std::string>
vs(
new_lbls.size());
2083 [](
char *x) -> std::string { return std::string(x); });
2085 this->_impl->set_labels(
vs);
2109 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2110 "get_block()/get_blocks() first.%s",
2114 return tmp->_block.item<
T>();
2119 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2120 "get_block()/get_blocks() first.%s",
2124 return tmp->_block.item();
2149 unsigned int dtype()
const {
return this->_impl->dtype(); }
2164 int device()
const {
return this->_impl->device(); }
2170 std::string
name()
const {
return this->_impl->name(); }
2177 std::string
dtype_str()
const {
return this->_impl->dtype_str(); }
2184 std::string
device_str()
const {
return this->_impl->device_str(); }
2204 bool is_diag()
const {
return this->_impl->is_diag(); }
2211 bool is_tag()
const {
return this->_impl->is_tag(); }
2218 std::vector<Symmetry>
syms()
const {
return this->_impl->syms(); }
2232 const std::vector<std::string> &
labels()
const {
return this->_impl->labels(); }
2245 const std::vector<Bond> &
bonds()
const {
return this->_impl->bonds(); }
2250 std::vector<Bond> &
bonds() {
return this->_impl->bonds(); }
2265 std::vector<cytnx_uint64>
shape()
const {
return this->_impl->shape(); }
2343 std::vector<std::string>
vs(
new_lbls.size());
2345 [](
char *x) -> std::string { return std::string(x); });
2356 std::vector<std::string>
vs(
new_lbls.size());
2358 [](
char *x) -> std::string { return std::string(x); });
2360 this->_impl->relabels_(
vs);
2372 const std::vector<std::string> &
new_labels)
const {
2394 const std::vector<std::string> &
new_labels) {
2404 const std::initializer_list<char *> &
new_labels)
const {
2406 std::vector<std::string>
vs(
new_lbls.size());
2408 [](
char *x) -> std::string { return std::string(x); });
2413 [](
char *x) -> std::string { return std::string(x); });
2423 const std::initializer_list<char *> &
new_labels) {
2425 std::vector<std::string>
vs(
new_lbls.size());
2427 [](
char *x) -> std::string { return std::string(x); });
2432 [](
char *x) -> std::string { return std::string(x); });
2511 if (this->
dtype() == dtype) {
2553 std::vector<std::string>
vs(
mprs.size());
2555 [](
char *x) -> std::string { return std::string(x); });
2654 if (this->
uten_type() == UTenType.Block) {
2657 return this->_impl->at_for_sparse(
locator,
aux);
2659 }
else if (this->
uten_type() == UTenType.Sparse) {
2660 if (this->_impl->elem_exists(
locator)) {
2662 return this->_impl->at_for_sparse(
locator,
aux);
2664 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2680 if (this->
uten_type() == UTenType.Block) {
2683 return this->_impl->at_for_sparse(
locator,
aux);
2685 }
else if (this->
uten_type() == UTenType.Sparse) {
2686 if (this->_impl->elem_exists(
locator)) {
2688 return this->_impl->at_for_sparse(
locator,
aux);
2690 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2700 const std::vector<cytnx_uint64> &
locator)
const {
2703 "[ERROR][at] length of list should be the same for label and locator.%s",
2707 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2710 for (
int i = 0;
i <
labels.size();
i++) {
2711 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2713 "[ERROR] label:%s does not exist in current UniTensor.\n",
2715 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2718 return this->
at<T>(new_locator);
2724 "[ERROR][at] length of list should be the same for label and locator.%s",
2728 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2731 for (
int i = 0;
i <
labels.size();
i++) {
2732 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2734 "[ERROR] label:%s does not exist in current UniTensor.\n",
2736 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2739 return this->
at<T>(new_locator);
2746 const Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator)
const {
2747 if (this->
uten_type() == UTenType.Block) {
2748 return this->_impl->at_for_sparse(
locator);
2749 }
else if (this->
uten_type() == UTenType.Sparse) {
2750 if (this->_impl->elem_exists(
locator)) {
2751 return this->_impl->at_for_sparse(
locator);
2753 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2765 Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator) {
2766 if (this->
uten_type() == UTenType.Block) {
2767 return this->_impl->at_for_sparse(
locator);
2768 }
else if (this->
uten_type() == UTenType.Sparse) {
2769 if (this->_impl->elem_exists(
locator)) {
2770 return this->_impl->at_for_sparse(
locator);
2772 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2780 Scalar::Sproxy
at(
const std::vector<std::string> &
labels,
2781 const std::vector<cytnx_uint64> &
locator) {
2784 "[ERROR][at] length of list should be the same for label and locator.%s",
2788 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2791 for (
int i = 0;
i <
labels.size();
i++) {
2792 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2794 "[ERROR] label:%s does not exist in current UniTensor.\n",
2796 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2799 return this->
at(new_locator);
2802 const Scalar::Sproxy
at(
const std::vector<std::string> &
labels,
2803 const std::vector<cytnx_uint64> &
locator)
const {
2806 "[ERROR][at] length of list should be the same for label and locator.%s",
2810 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2813 for (
int i = 0;
i <
labels.size();
i++) {
2814 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2816 "[ERROR] label:%s does not exist in current UniTensor.\n",
2818 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2821 return this->
at(new_locator);
2842 return this->_impl->get_block(
qidx,
force);
2846 const bool &
force =
false)
const {
2849 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
2851 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
2853 std::vector<cytnx_int64>
loc_id(this->
rank());
2858 for (
int i = 0;
i <
labels.size();
i++) {
2859 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2861 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
2863 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2877 const bool &
force =
false)
const {
2878 std::vector<cytnx_int64> tmp =
qnum;
2892 const bool &
force =
false)
const {
2903 return this->_impl->get_block_(
idx);
2921 return this->_impl->get_block_(
qidx,
force);
2941 const bool &
force =
false) {
2944 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
2946 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
2948 std::vector<cytnx_int64>
loc_id(this->
rank());
2953 for (
int i = 0;
i <
labels.size();
i++) {
2954 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2956 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
2958 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2963 if (
out.dtype() !=
Type.Void) {
2973 std::vector<cytnx_int64> tmp =
qidx;
2986 const bool &
force =
false) {
2997 const bool &
force =
false)
const {
2998 return this->_impl->get_block_(
qidx,
force);
3005 const bool &
force =
false)
const {
3006 std::vector<cytnx_int64> tmp =
qidx;
3007 return this->_impl->get_block_(tmp,
force);
3014 const bool &
force =
false)
const {
3029 std::vector<Tensor>
get_blocks()
const {
return this->_impl->get_blocks(); }
3038 return this->_impl->get_blocks_(
silent);
3046 return this->_impl->get_blocks_(
silent);
3055 this->_impl->put_block(
in,
idx);
3074 const std::vector<cytnx_int64> &
qidx,
const bool &
force =
false) {
3077 "[ERROR][put_block] length of lists must be the same for both lables and qnidices%s",
"\n");
3079 "[ERROR][put_block] length of lists must be the rank (# of legs)%s",
"\n");
3081 std::vector<cytnx_int64>
loc_id(this->
rank());
3087 for (
int i = 0;
i <
lbls.size();
i++) {
3088 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
3090 "[ERROR][put_block] label:%s does not exists in current Tensor.\n",
3092 new_loc = std::distance(this->_impl->_labels.begin(),
res);
3122 const std::vector<cytnx_int64> &
qidx,
const bool &
force =
false) {
3125 "[ERROR][put_block_] length of lists must be the same for both lables and qnidices%s",
3128 "[ERROR][put_block_] length of lists must be the rank (# of legs)%s",
"\n");
3130 std::vector<cytnx_int64>
loc_id(this->
rank());
3136 for (
int i = 0;
i <
lbls.size();
i++) {
3137 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
3139 "[ERROR][put_block_] label:%s does not exists in current Tensor.\n",
3141 new_loc = std::distance(this->_impl->_labels.begin(),
res);
3161 "[ERROR] cannot set elements from UniTensor with symmetry. Use at() instead.%s",
"\n");
3164 "[ERROR] cannot set UniTensor. incoming UniTensor is_diag=True.%s",
"\n");
3282 return this->_impl->getTotalQnums(
physical);
3289 return this->_impl->get_blocks_qnums();
3299 if (this->_impl->uten_type() !=
rhs._impl->uten_type())
return false;
3301 return this->_impl->same_data(
rhs._impl);
3727 out._impl = this->_impl->
Conj();
3739 this->_impl->
Conj_();
3834 if (this->
uten_type() == UTenType.Block) {
3836 if (this->
rank() == 0) {
3839 this->_impl = boost::intrusive_ptr<UniTensor_base>(tmp);
3856 if (this->
uten_type() == UTenType.Block) {
3858 if (this->
rank() == 0) {
3861 this->_impl = boost::intrusive_ptr<UniTensor_base>(tmp);
3930 return this->_impl->elem_exists(
locator);
3940 return this->
at<T>(locator);
3951 this->
at(locator) =
rc;
4054 return this->_impl->get_qindices(
bidx);
4064 return this->_impl->get_qindices(
bidx);
4077 void _Load(std::fstream &f);
4078 void _Save(std::fstream &f)
const;
4082 this->_impl->from_(
rhs._impl,
force);
4100 const std::vector<std::string> &
in_labels = {},
4102 const std::string &
name =
"") {
4120 const std::vector<std::string> &
in_labels = {},
4122 const std::string &
name =
"") {
4139 const std::string &
name =
"") {
4156 const std::vector<std::string> &
in_labels = {},
4158 const unsigned int &
dtype =
Type.Double,
4201 const std::vector<std::string> &
in_labels = {},
4203 const std::string &
name =
"") {
4221 const std::vector<std::string> &
in_labels = {},
4222 const std::string &
name =
"") {
4244 const std::vector<std::string> &
in_labels = {},
4246 const std::string &
name =
"") {
4271 const std::vector<std::string> &
in_labels = {},
4272 const unsigned int &
dtype =
Type.Double,
4298 const std::vector<std::string> &
in_labels = {},
4301 const std::string &
name =
"");
4322 const double &
std,
const std::vector<std::string> &
in_labels = {},
4325 const std::string &
name =
"");
4346 const std::vector<std::string> &
in_labels = {},
4348 const unsigned int &
dtype =
Type.Double,
4389 const double &
high,
const std::vector<std::string> &
in_labels = {},
4391 const unsigned int &
dtype =
Type.Double,
4428 std::ostream &operator<<(std::ostream &os,
const UniTensor &in);
4444 const bool &cacheR =
false);
4459 const bool &optimal);
4462 void _resolve_CT(std::vector<UniTensor> &TNlist);
4463 template <
class... T>
4464 void _resolve_CT(std::vector<UniTensor> &TNlist,
const UniTensor &in,
const T &...args) {
4465 TNlist.push_back(in);
4466 _resolve_CT(TNlist, args...);
4481 template <
class... T>
4483 const bool &optimal) {
4484 std::vector<UniTensor> TNlist;
4485 _resolve_CT(TNlist, in, args...);
4486 return Contracts(TNlist, order, optimal);
the object contains auxiliary properties for each Tensor rank (bond)
Definition Bond.hpp:176
Bond clone() const
return a copy of the instance Bond
Definition Bond.hpp:488
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:1783
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:3065
UniTensor to(const int &device) const
move the current UniTensor to the assigned device.
Definition UniTensor.hpp:2291
UniTensor & operator*=(const UniTensor &rhs)
The multiplication assignment operator of the UniTensor.
Definition UniTensor.hpp:3653
static UniTensor eye(const cytnx_uint64 &dim, const std::vector< std::string > &in_labels={}, const cytnx_bool &is_diag=false, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a 2-bond identity UniTensor.
Definition UniTensor.hpp:4182
Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:2972
std::vector< Tensor > & get_blocks_(const bool &silent=false)
Definition UniTensor.hpp:3045
Tensor & get_block_(const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:2980
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:2628
UniTensor & operator/=(const UniTensor &rhs)
The division assignment operator of the UniTensor.
Definition UniTensor.hpp:3633
T & item()
Definition UniTensor.hpp:2107
bool is_contiguous() const
To tell whether the UniTensor is contiguous.
Definition UniTensor.hpp:2198
T get_elem(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:3939
UniTensor Div(const UniTensor &rhs) const
The division function of the UniTensor.
Tensor get_block(const std::vector< std::string > &labels, const std::vector< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2845
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:4063
UniTensor & set_label(const cytnx_int64 &idx, const char *new_label)
Definition UniTensor.hpp:2010
UniTensor & operator+=(const UniTensor &rhs)
The addition assignment operator of the UniTensor.
Definition UniTensor.hpp:3593
void to_dense_()
Convert the UniTensor to non-diagonal form, inplacely.
Definition UniTensor.hpp:3212
UniTensor reshape(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor.
Definition UniTensor.hpp:3175
std::vector< Tensor > get_blocks() const
Get all the blocks of the UniTensor.
Definition UniTensor.hpp:3029
UniTensor permute(const std::initializer_list< char * > &mapper, const cytnx_int64 &rowrank=-1) const
Definition UniTensor.hpp:2550
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:2211
std::string uten_type_str() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor in 'string' form.
Definition UniTensor.hpp:2191
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:1873
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:2841
void permute_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:2568
UniTensor & tag()
Set the UniTensor as a tagged UniTensor.
Definition UniTensor.hpp:3898
const Bond & bond_(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:2252
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force=false)
Definition UniTensor.hpp:3243
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:2478
const T & at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:2699
UniTensor & relabels_(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2354
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:1822
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:2920
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:1845
static UniTensor zeros(const std::vector< cytnx_uint64 > &shape, const std::vector< std::string > &in_labels={}, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a UniTensor with all elements set to zero.
Definition UniTensor.hpp:4119
UniTensor get(const std::vector< Accessor > &accessors) const
Definition UniTensor.hpp:3150
T & at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:2721
UniTensor Conj() const
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:3725
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:2025
UniTensor set_rowrank(const cytnx_uint64 &new_rowrank) const
Definition UniTensor.hpp:2100
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:3683
cytnx_uint64 rowrank() const
Return the row rank of the UniTensor.
Definition UniTensor.hpp:2142
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:2393
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:3576
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:2079
UniTensor & Sub_(const Scalar &rhs)
The subtraction function for a given scalar.
Definition UniTensor.hpp:3428
UniTensor & relabel_(const cytnx_int64 &inx, const std::string &new_label)
rebable the lags in the UniTensor by given index.
Definition UniTensor.hpp:2465
UniTensor & operator/=(const Scalar &rhs)
The division assignment operator for a given scalar.
Definition UniTensor.hpp:3698
const bool & is_braket_form() const
Check whether the UniTensor is in braket form.
Definition UniTensor.hpp:2226
void set_elem(const std::vector< cytnx_uint64 > &locator, const T2 &rc)
Definition UniTensor.hpp:3949
UniTensor Add(const Scalar &rhs) const
The addition function for a given scalar.
static UniTensor linspace(const cytnx_double &start, const cytnx_double &end, const cytnx_uint64 &Nelem, const bool &endpoint=true, const std::vector< std::string > &in_labels={}, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a one-bond UniTensor with all elements are evenly spaced numbers over a specified interval.
Definition UniTensor.hpp:4269
std::vector< cytnx_uint64 > shape() const
Get the shape of the UniTensor.
Definition UniTensor.hpp:2265
UniTensor to_dense()
Convert the UniTensor to non-diagonal form.
Definition UniTensor.hpp:3202
Scalar::Sproxy at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:2780
static UniTensor normal(const std::vector< cytnx_uint64 > &shape, const double &mean, const double &std, const std::vector< std::string > &in_labels={}, const unsigned int &seed=cytnx::random::__static_random_device(), const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a UniTensor with all elements are random numbers sampled from a normal (Gaussian) distributi...
const Tensor & get_block_(const std::vector< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2996
void reshape_(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor, inplacely.
Definition UniTensor.hpp:3187
UniTensor & set_labels(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:2070
void permute_(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:2578
std::string name() const
Return the name of the UniTensor.
Definition UniTensor.hpp:2170
const Scalar::Sproxy at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:2802
UniTensor & Add_(const Scalar &rhs)
The addition function for a given scalar.
Definition UniTensor.hpp:3398
UniTensor & Trace_(const std::string &a, const std::string &b)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:3832
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:4011
Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition UniTensor.hpp:2765
UniTensor Trace(const std::string &a, const std::string &b) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:3802
bool same_data(const UniTensor &rhs) const
Check whether the Blocks address are the same.
Definition UniTensor.hpp:3297
UniTensor astype(const unsigned int &dtype) const
Return a new UniTensor that cast to different data type.
Definition UniTensor.hpp:2509
static UniTensor ones(const std::vector< cytnx_uint64 > &shape, const std::vector< std::string > &in_labels={}, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a UniTensor with all elements set to one.
Definition UniTensor.hpp:4200
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:4025
UniTensor Transpose() const
Take the transpose of the UniTensor.
Definition UniTensor.hpp:3753
static UniTensor arange(const cytnx_double &start, const cytnx_double &end, const cytnx_double &step=1, const std::vector< std::string > &in_labels={}, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a UniTensor with all elements are arange from start to end.
Definition UniTensor.hpp:4242
UniTensor & set_label(const char *old_label, const std::string &new_label)
Definition UniTensor.hpp:2033
static UniTensor Load(const char *fname)
load a UniTensor from file
UniTensor & Dagger_()
Take the conjugate transpose to the UniTensor, inplacely.
Definition UniTensor.hpp:3885
void print_diagram(const bool &bond_info=false)
Plot the diagram of the UniTensor.
Definition UniTensor.hpp:2615
std::vector< Bond > & bonds()
Definition UniTensor.hpp:2250
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition UniTensor.hpp:2652
UniTensor & set_rowrank_(const cytnx_uint64 &new_rowrank)
Set the row rank of the UniTensor.
Definition UniTensor.hpp:2095
void put_block(Tensor &in, const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx, const bool &force=false)
Put the block into the UniTensor with given quantum indices, will copy the input tensor.
Definition UniTensor.hpp:3073
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:2002
UniTensor contiguous() const
Make the UniTensor contiguous by coalescing the memory (storage).
Definition UniTensor.hpp:2599
Tensor get_block(const cytnx_uint64 &idx=0) const
Get the block of the UniTensor for a given index.
Definition UniTensor.hpp:2830
const T & at(const std::vector< cytnx_uint64 > &locator) const
Get an element at specific location.
Definition UniTensor.hpp:2678
UniTensor & operator*=(const Scalar &rhs)
The multiplication assignment operator for a given scalar.
Definition UniTensor.hpp:3713
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:2371
void contiguous_()
Make the UniTensor contiguous by coalescing the memory (storage), inplacely.
Definition UniTensor.hpp:2609
UniTensor normalize() const
normalize the current UniTensor instance with 2-norm.
Definition UniTensor.hpp:3776
static UniTensor ones(const cytnx_uint64 &Nelem, const std::vector< std::string > &in_labels={}, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a one-bond UniTensor with all elements set to one.
Definition UniTensor.hpp:4137
std::vector< Symmetry > syms() const
Return the symmetry type of the UniTensor.
Definition UniTensor.hpp:2218
UniTensor & Mul_(const UniTensor &rhs)
The multiplcation function of the UniTensor.
Definition UniTensor.hpp:3341
static UniTensor zeros(const cytnx_uint64 &Nelem, const std::vector< std::string > &in_labels={}, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a one-bond UniTensor with all elements set to zero.
Definition UniTensor.hpp:4099
void put_block_(Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index, inplacely.
Definition UniTensor.hpp:3105
void combineBonds(const std::vector< std::string > &indicators, const bool &force=false)
Combine the sevral bonds of the UniTensor.
Definition UniTensor.hpp:3234
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:2497
UniTensor & normalize_()
normalize the UniTensor, inplacely.
Definition UniTensor.hpp:3788
bool is_diag() const
To tell whether the UniTensor is in diagonal form.
Definition UniTensor.hpp:2204
int device() const
Return the device of the UniTensor.
Definition UniTensor.hpp:2164
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:3013
Tensor get_block_(const std::vector< std::string > &labels, 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:2940
void put_block_(Tensor &in, const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx, const bool &force=false)
Put the block into the UniTensor with given quantum indices, inplacely.
Definition UniTensor.hpp:3121
void set(const std::vector< Accessor > &accessors, const Tensor &rhs)
Definition UniTensor.hpp:3155
std::string dtype_str() const
Return the data type of the UniTensor in 'string' form.
Definition UniTensor.hpp:2177
UniTensor & operator+=(const Scalar &rhs)
The addition assignment operator for a given scalar.
Definition UniTensor.hpp:3668
UniTensor & Div_(const UniTensor &rhs)
The division function of the UniTensor.
Definition UniTensor.hpp:3383
UniTensor & Div_(const Scalar &rhs)
The division function for a given scalar.
Definition UniTensor.hpp:3443
Bond & bond_(const std::string &label)
Definition UniTensor.hpp:2256
cytnx_uint64 rank() const
Return the rank of the UniTensor.
Definition UniTensor.hpp:2136
Bond bond(const std::string &label) const
Definition UniTensor.hpp:2259
void group_basis_()
Group the same quantum number basis together.
Definition UniTensor.hpp:2638
void to_(const int &device)
move the current UniTensor to the assigned device (inplace).
Definition UniTensor.hpp:2280
UniTensor & Trace_(const cytnx_int64 &a=0, const cytnx_int64 &b=1)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:3854
UniTensor & set_name(const std::string &in)
Set the name of the UniTensor.
Definition UniTensor.hpp:1987
UniTensor Trace(const cytnx_int64 &a=0, const cytnx_int64 &b=1) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:3817
UniTensor & Add_(const UniTensor &rhs)
The addition function of the UniTensor.
Definition UniTensor.hpp:3320
void normal_(const double &mean, const double &std, const unsigned int &seed=cytnx::random::__static_random_device())
Generate a one-bond UniTensor with all elements are random numbers sampled from a normal (Gaussian) d...
UniTensor permute(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1) const
permute the lags of the UniTensor
Definition UniTensor.hpp:2527
UniTensor & set_label(const std::string &old_label, const char *new_label)
Definition UniTensor.hpp:2041
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:2540
unsigned int dtype() const
Return the data type of the UniTensor.
Definition UniTensor.hpp:2149
UniTensor Pow(const double &p) const
Power function.
UniTensor & Mul_(const Scalar &rhs)
The multiplication function for a given scalar.
Definition UniTensor.hpp:3413
UniTensor & operator-=(const UniTensor &rhs)
The subtraction assignment operator of the UniTensor.
Definition UniTensor.hpp:3613
Tensor get_block_(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:2985
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force, const bool &by_label)
Definition UniTensor.hpp:3219
UniTensor & set_label(const char *old_label, const char *new_label)
Definition UniTensor.hpp:2049
static UniTensor arange(const cytnx_int64 &Nelem, const std::vector< std::string > &in_labels={}, const std::string &name="")
Generate a one-bond UniTensor with all elements are arange from 0 to Nelem-1.
Definition UniTensor.hpp:4220
bool is_blockform() const
Check whether the UniTensor is in block form.
Definition UniTensor.hpp:2272
UniTensor group_basis() const
Definition UniTensor.hpp:2640
UniTensor Dagger() const
Take the conjugate transpose to the UniTensor.
Definition UniTensor.hpp:3873
static UniTensor uniform(const std::vector< cytnx_uint64 > &shape, const double &low, const double &high, const std::vector< std::string > &in_labels={}, const unsigned int &seed=cytnx::random::__static_random_device(), const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a UniTensor with all elements are random numbers sampled from a uniform distribution.
void set(const std::vector< Accessor > &accessors, const UniTensor &rhs)
Definition UniTensor.hpp:3158
const std::vector< Tensor > & get_blocks_(const bool &silent=false) const
Get all the blocks of the UniTensor, inplacely.
Definition UniTensor.hpp:3037
UniTensor & relabels_(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2422
const Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:3004
bool elem_exists(const std::vector< cytnx_uint64 > &locator) const
Geiven the locator, check if the element exists.
Definition UniTensor.hpp:3929
UniTensor & Sub_(const UniTensor &rhs)
The subtraction function of the UniTensor.
Definition UniTensor.hpp:3362
UniTensor relabels(const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:2341
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:3265
void put_block(const Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index.
Definition UniTensor.hpp:3054
const Tensor & get_block_(const cytnx_uint64 &idx=0) const
Get the shared view of block for the given index.
Definition UniTensor.hpp:2902
static UniTensor Load(const std::string &fname)
load a UniTensor from file
const Bond & bond_(const std::string &label) const
Definition UniTensor.hpp:2255
static UniTensor identity(const cytnx_uint64 &dim, const std::vector< std::string > &in_labels={}, const cytnx_bool &is_diag=false, const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a identity UniTensor.
Definition UniTensor.hpp:4155
Bond & bond_(const cytnx_uint64 &idx)
Definition UniTensor.hpp:2253
static UniTensor normal(const cytnx_uint64 &Nelem, const double &mean, const double &std, const std::vector< std::string > &in_labels={}, const unsigned int &seed=cytnx::random::__static_random_device(), const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a one-bond UniTensor with all elements are random numbers sampled from a normal (Gaussian) d...
UniTensor relabel(const cytnx_int64 &inx, const std::string &new_label) const
rebable the lags in the UniTensor by given index.
Definition UniTensor.hpp:2452
UniTensor Mul(const UniTensor &rhs) const
The multiplication function of the UniTensor.
void uniform_(const double &low=0, const double &high=1, const unsigned int &seed=cytnx::random::__static_random_device())
Generate a UniTensor with all elements are random numbers sampled from a uniform distribution,...
UniTensor relabels(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:2403
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:4053
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:2232
cytnx_int64 get_index(std::string label) const
Get the index of an desired label string.
Definition UniTensor.hpp:2239
const std::vector< Bond > & bonds() const
Get the bonds of the UniTensor.
Definition UniTensor.hpp:2245
Tensor get_block(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:2891
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:4040
UniTensor & Transpose_()
Take the transpose of the UniTensor, inplacely.
Definition UniTensor.hpp:3765
static UniTensor uniform(const cytnx_uint64 &Nelem, const double &low, const double &high, const std::vector< std::string > &in_labels={}, const unsigned int &seed=cytnx::random::__static_random_device(), const unsigned int &dtype=Type.Double, const int &device=Device.cpu, const std::string &name="")
Generate a one-bond UniTensor with all elements are random numbers sampled from a uniform distributio...
UniTensor clone() const
Clone (deep copy) the UniTensor.
Definition UniTensor.hpp:2301
vec2d< cytnx_uint64 > & get_itoi()
Definition UniTensor.hpp:4074
void print_blocks(const bool &full_info=true) const
Print all of the blocks in the UniTensor.
Definition UniTensor.hpp:2621
Scalar::Sproxy item() const
Definition UniTensor.hpp:2117
const vec2d< cytnx_uint64 > & get_itoi() const
get the q-indices on each leg for all the blocks
Definition UniTensor.hpp:4073
std::string device_str() const
Return the device of the UniTensor in 'string' form.
Definition UniTensor.hpp:2184
UniTensor & convert_from(const UniTensor &rhs, const bool &force=false)
Definition UniTensor.hpp:4081
UniTensor relabels(const std::vector< std::string > &new_labels) const
relables all of the labels in UniTensor.
Definition UniTensor.hpp:2332
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:3113
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:1924
UniTensor & Conj_()
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:3738
cytnx_uint64 Nblocks() const
Return the number of blocks in the UniTensor.
Definition UniTensor.hpp:2130
Tensor get_block(const std::vector< cytnx_uint64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:2886
void Save(const char *fname) const
save a UniTensor to file
Bond bond(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:2258
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:3998
Tensor get_block(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:2876
UniTensor & relabels_(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:2316
const Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator) const
Get an element at specific location.
Definition UniTensor.hpp:2746
int uten_type() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor.
Definition UniTensor.hpp:2157
Tensor & get_block_(const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:2910
#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.
std::random_device __static_random_device
Definition UniTensor.hpp:29
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
Tensor linspace(const cytnx_double &start, const cytnx_double &end, const cytnx_uint64 &Nelem, const bool &endpoint=true, const unsigned int &dtype=Type.Double, const int &device=Device.cpu)
UniTensorType_class UTenType
UniTensor type.
uint32_t cytnx_uint32
Definition Type.hpp:56
bool cytnx_bool
Definition Type.hpp:64
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
Tensor arange(const cytnx_int64 &Nelem)
create an rank-1 Tensor with incremental unsigned integer elements start with [0,Nelem)
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
Tensor ones(const cytnx_uint64 &Nelem, const unsigned int &dtype=Type.Double, const int &device=Device.cpu)
create an rank-1 Tensor with all the elements are initialized with one.
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.
Tensor zeros(const cytnx_uint64 &Nelem, const unsigned int &dtype=Type.Double, const int &device=Device.cpu)
create an rank-1 Tensor with all the elements are initialized with zero.
Tensor identity(const cytnx_uint64 &Dim, const unsigned int &dtype=Type.Double, const int &device=Device.cpu)
create an square rank-2 Tensor with all diagonal to be one.