1#ifndef CYTNX_UNITENSOR_H_
2#define CYTNX_UNITENSOR_H_
8#include "utils/utils.hpp"
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);
112 cytnx_uint64 rowrank()
const {
return this->_rowrank; }
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; }
123 cytnx_int64 get_index(std::string label)
const {
124 std::vector<std::string> labels = this->_labels;
125 for (cytnx_uint64 i = 0; i < labels.size(); i++) {
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; }
133 Bond &bond_(
const cytnx_uint64 &idx) {
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 relabel_(
const std::vector<std::string> &new_labels);
203 void relabels_(
const std::vector<std::string> &new_labels);
204 void relabel_(
const std::vector<std::string> &old_labels,
205 const std::vector<std::string> &new_labels);
206 void relabels_(
const std::vector<std::string> &old_labels,
207 const std::vector<std::string> &new_labels);
208 void relabel_(
const std::string &old_label,
const std::string &new_label) {
209 this->set_label(old_label, new_label);
211 void relabel_(
const cytnx_int64 &inx,
const std::string &new_label) {
212 this->set_label(inx, new_label);
215 int uten_type() {
return this->uten_type_id; }
216 std::string uten_type_str() {
return UTenType.getname(this->uten_type_id); }
221 virtual void Init(
const std::vector<Bond> &bonds,
222 const std::vector<std::string> &in_labels = {},
223 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
224 const int &device =
Device.cpu,
const bool &is_diag =
false,
225 const bool &no_alloc =
false,
const std::string &name =
"");
227 virtual void Init_by_Tensor(
const Tensor &in,
const bool &is_diag =
false,
228 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
229 virtual std::vector<cytnx_uint64> shape()
const;
230 virtual bool is_blockform()
const;
231 virtual bool is_contiguous()
const;
232 virtual void to_(
const int &device);
233 virtual boost::intrusive_ptr<UniTensor_base> to(
const int &device);
234 virtual boost::intrusive_ptr<UniTensor_base> clone()
const;
235 virtual unsigned int dtype()
const;
236 virtual int device()
const;
237 virtual std::string dtype_str()
const;
238 virtual std::string device_str()
const;
239 virtual void set_rowrank_(
const cytnx_uint64 &new_rowrank);
240 virtual boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const;
242 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
243 const cytnx_int64 &rowrank = -1);
244 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
245 const cytnx_int64 &rowrank = -1);
249 virtual void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
250 virtual void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
254 virtual boost::intrusive_ptr<UniTensor_base> contiguous_();
255 virtual boost::intrusive_ptr<UniTensor_base> contiguous();
256 virtual void print_diagram(
const bool &bond_info =
false);
257 virtual void print_blocks(
const bool &full_info =
true)
const;
258 virtual void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
260 virtual boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const;
262 virtual cytnx_uint64 Nblocks()
const {
return 0; };
263 virtual Tensor get_block(
const cytnx_uint64 &idx = 0)
const;
264 virtual Tensor get_block(
const std::vector<cytnx_int64> &qnum,
265 const bool &force)
const;
267 virtual const Tensor &get_block_(
const cytnx_uint64 &idx = 0)
269 virtual const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
270 const bool &force)
const;
271 virtual Tensor &get_block_(
const cytnx_uint64 &idx = 0);
273 virtual Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
275 virtual bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const;
277 virtual std::vector<Tensor> get_blocks()
const;
278 virtual const std::vector<Tensor> &get_blocks_(
const bool &)
const;
279 virtual std::vector<Tensor> &get_blocks_(
const bool &);
281 virtual void put_block(
const Tensor &in,
const cytnx_uint64 &idx = 0);
282 virtual void put_block_(
Tensor &in,
const cytnx_uint64 &idx = 0);
283 virtual void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
285 virtual void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force);
288 virtual boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
291 virtual void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
293 virtual void reshape_(
const std::vector<cytnx_int64> &new_shape,
294 const cytnx_uint64 &rowrank = 0);
295 virtual boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
296 const cytnx_uint64 &rowrank = 0);
297 virtual boost::intrusive_ptr<UniTensor_base> to_dense();
298 virtual void to_dense_();
299 virtual void combineBond(
const std::vector<std::string> &indicators,
const bool &force =
false);
300 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
301 const bool &by_label);
302 virtual void combineBonds(
const std::vector<std::string> &indicators,
303 const bool &force =
false);
304 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
305 const bool &force =
false);
306 virtual boost::intrusive_ptr<UniTensor_base> contract(
307 const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self =
false,
308 const bool &mv_elem_rhs =
false);
309 virtual std::vector<Bond> getTotalQnums(
const bool &physical =
false);
310 virtual std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const;
311 virtual void Trace_(
const std::string &a,
const std::string &b);
312 virtual void Trace_(
const cytnx_int64 &a,
const cytnx_int64 &b);
314 virtual boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b);
315 virtual boost::intrusive_ptr<UniTensor_base>
Trace(
const cytnx_int64 &a,
const cytnx_int64 &b);
317 virtual boost::intrusive_ptr<UniTensor_base> relabel(
318 const std::vector<std::string> &new_labels);
319 virtual boost::intrusive_ptr<UniTensor_base> relabels(
320 const std::vector<std::string> &new_labels);
322 virtual boost::intrusive_ptr<UniTensor_base> relabel(
323 const std::vector<std::string> &old_labels,
const std::vector<std::string> &new_labels);
324 virtual boost::intrusive_ptr<UniTensor_base> relabels(
325 const std::vector<std::string> &old_labels,
const std::vector<std::string> &new_labels);
327 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
328 const std::string &new_label);
330 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
331 const std::string &new_label);
333 virtual std::vector<Symmetry> syms()
const;
336 virtual void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
337 virtual void Add_(
const Scalar &rhs);
339 virtual void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
340 virtual void Mul_(
const Scalar &rhs);
342 virtual void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
343 virtual void Sub_(
const Scalar &rhs);
344 virtual void lSub_(
const Scalar &lhs);
346 virtual void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
347 virtual void Div_(
const Scalar &rhs);
348 virtual void lDiv_(
const Scalar &lhs);
351 virtual boost::intrusive_ptr<UniTensor_base> normalize();
352 virtual void normalize_();
354 virtual boost::intrusive_ptr<UniTensor_base>
Conj();
355 virtual void Conj_();
357 virtual boost::intrusive_ptr<UniTensor_base> Transpose();
358 virtual void Transpose_();
360 virtual boost::intrusive_ptr<UniTensor_base> Dagger();
361 virtual void Dagger_();
365 virtual void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
366 virtual void truncate_(
const cytnx_int64 &bond_idx,
const cytnx_uint64 &dim);
368 virtual bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
371 virtual Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
372 virtual const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
374 virtual cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
375 const cytnx_complex128 &aux);
376 virtual cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
377 const cytnx_complex64 &aux);
378 virtual cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
379 const cytnx_double &aux);
380 virtual cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
381 const cytnx_float &aux);
382 virtual cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
383 const cytnx_uint64 &aux);
384 virtual cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
385 const cytnx_int64 &aux);
386 virtual cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
387 const cytnx_uint32 &aux);
388 virtual cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
389 const cytnx_int32 &aux);
390 virtual cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
391 const cytnx_uint16 &aux);
392 virtual cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
393 const cytnx_int16 &aux);
395 virtual const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
396 const cytnx_complex128 &aux)
const;
397 virtual const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
398 const cytnx_complex64 &aux)
const;
399 virtual const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
400 const cytnx_double &aux)
const;
401 virtual const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
402 const cytnx_float &aux)
const;
403 virtual const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
404 const cytnx_uint64 &aux)
const;
405 virtual const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
406 const cytnx_int64 &aux)
const;
407 virtual const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
408 const cytnx_uint32 &aux)
const;
409 virtual const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
410 const cytnx_int32 &aux)
const;
411 virtual const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
412 const cytnx_uint16 &aux)
const;
413 virtual const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
414 const cytnx_int16 &aux)
const;
416 virtual void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
418 virtual void group_basis_();
419 virtual const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const;
420 virtual std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx);
421 virtual const vec2d<cytnx_uint64> &get_itoi()
const;
422 virtual vec2d<cytnx_uint64> &get_itoi();
424 virtual void _save_dispatch(std::fstream &f)
const;
425 virtual void _load_dispatch(std::fstream &f);
427 virtual ~UniTensor_base(){};
433 class DenseUniTensor :
public UniTensor_base {
437 std::vector<Tensor> _interface_block;
438 DenseUniTensor *clone_meta()
const {
439 DenseUniTensor *tmp =
new DenseUniTensor();
440 tmp->_bonds = vec_clone(this->_bonds);
441 tmp->_labels = this->_labels;
442 tmp->_is_braket_form = this->_is_braket_form;
443 tmp->_rowrank = this->_rowrank;
444 tmp->_is_diag = this->_is_diag;
445 tmp->_name = this->_name;
446 tmp->_is_tag = this->_is_tag;
451 DenseUniTensor() { this->uten_type_id =
UTenType.Dense; };
460 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
461 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
462 const int &device =
Device.cpu,
const bool &is_diag =
false,
463 const bool &no_alloc =
false,
const std::string &name =
"");
465 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
466 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
467 std::vector<cytnx_uint64> shape()
const {
468 if (this->_is_diag) {
469 std::vector<cytnx_uint64> shape = this->_block.
shape();
470 shape.push_back(shape[0]);
473 return this->_block.
shape();
476 bool is_blockform()
const {
return false; }
477 void to_(
const int &device) { this->_block.
to_(device); }
478 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
479 if (this->device() == device) {
480 std::vector<Tensor> _interface_block;
483 boost::intrusive_ptr<UniTensor_base> out = this->clone();
488 void set_rowrank_(
const cytnx_uint64 &new_rowrank) {
490 "[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
491 if (this->is_diag()) {
492 cytnx_error_msg(new_rowrank != 1,
"[ERROR] rowrank should be [==1] when is_diag =true!.%s",
496 this->_rowrank = new_rowrank;
499 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
500 DenseUniTensor *out_raw = this->clone_meta();
501 out_raw->_block = this->_block;
502 out_raw->set_rowrank_(new_rowrank);
503 boost::intrusive_ptr<UniTensor_base> out(out_raw);
507 boost::intrusive_ptr<UniTensor_base> clone()
const {
508 DenseUniTensor *tmp = this->clone_meta();
509 tmp->_block = this->_block.
clone();
510 boost::intrusive_ptr<UniTensor_base> out(tmp);
513 bool is_contiguous()
const {
return this->_block.
is_contiguous(); }
514 unsigned int dtype()
const {
return this->_block.
dtype(); }
515 int device()
const {
return this->_block.
device(); }
516 std::string dtype_str()
const {
return Type.getname(this->_block.
dtype()); }
517 std::string device_str()
const {
return Device.getname(this->_block.
device()); }
527 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
528 const cytnx_int64 &rowrank = -1);
529 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
530 const cytnx_int64 &rowrank = -1);
540 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
541 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
543 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &new_labels);
544 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
546 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &old_labels,
547 const std::vector<std::string> &new_labels);
548 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
549 const std::vector<std::string> &new_labels);
561 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
562 const std::string &new_label);
563 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
564 const std::string &new_label);
566 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
567 DenseUniTensor *tmp = this->clone_meta();
568 tmp->_block = this->_block.
astype(dtype);
569 boost::intrusive_ptr<UniTensor_base> out(tmp);
573 std::vector<Symmetry> syms()
const {
574 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] dense unitensor does not have symmetry.%s",
576 return std::vector<Symmetry>();
579 boost::intrusive_ptr<UniTensor_base> contiguous_() {
581 return boost::intrusive_ptr<UniTensor_base>(
this);
583 boost::intrusive_ptr<UniTensor_base> contiguous() {
585 if (this->is_contiguous()) {
586 boost::intrusive_ptr<UniTensor_base> out(
this);
589 DenseUniTensor *tmp = this->clone_meta();
591 boost::intrusive_ptr<UniTensor_base> out(tmp);
595 void print_diagram(
const bool &bond_info =
false);
596 void print_blocks(
const bool &full_info =
true)
const;
597 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
598 Tensor get_block(
const cytnx_uint64 &idx = 0)
const {
return this->_block.
clone(); }
600 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
602 true,
"[ERROR][DenseUniTensor] try to get_block() using qnum on a non-symmetry UniTensor%s",
607 const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
610 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
614 Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force) {
617 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
623 Tensor &get_block_(
const cytnx_uint64 &idx = 0) {
return this->_block; }
625 const Tensor &get_block_(
const cytnx_uint64 &idx = 0)
const {
return this->_block; }
627 cytnx_uint64 Nblocks()
const {
return 1; };
628 std::vector<Tensor> get_blocks()
const {
629 std::vector<Tensor> out;
631 true,
"[ERROR][DenseUniTensor] cannot use get_blocks(), use get_block() instead!%s",
"\n");
634 const std::vector<Tensor> &get_blocks_(
const bool &silent =
false)
const {
636 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
638 return this->_interface_block;
640 std::vector<Tensor> &get_blocks_(
const bool &silent =
false) {
642 true,
"[ERROR][DenseUniTensor] cannot use get_blocks_(), use get_block_() instead!%s",
644 return this->_interface_block;
647 void put_block(
const Tensor &in,
const cytnx_uint64 &idx = 0) {
656 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
661 if (this->is_diag()) {
663 in.
shape() != this->_block.shape(),
664 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
665 this->_block = in.
clone();
668 in.
shape() != this->shape(),
669 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
670 this->_block = in.
clone();
674 void put_block_(
Tensor &in,
const cytnx_uint64 &idx = 0) {
683 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
688 if (this->is_diag()) {
690 in.
shape() != this->_block.shape(),
691 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
695 in.
shape() != this->shape(),
696 "[ERROR][DenseUniTensor] put_block, the input tensor shape does not match.%s",
"\n");
701 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
703 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
706 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &qnum,
const bool &force) {
708 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
712 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
713 boost::intrusive_ptr<UniTensor_base> out(
new DenseUniTensor());
714 out->Init_by_Tensor(this->_block.
get(accessors),
false, 0);
718 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
719 this->_block.
set(accessors, rhs);
722 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0);
723 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
724 const cytnx_uint64 &rowrank = 0);
725 boost::intrusive_ptr<UniTensor_base> to_dense();
727 void combineBond(
const std::vector<std::string> &indicators,
const bool &force =
true);
728 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
729 const bool &by_label);
730 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
true);
731 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
true);
732 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
733 const bool &mv_elem_self =
false,
734 const bool &mv_elem_rhs =
false);
735 std::vector<Bond> getTotalQnums(
const bool &physical =
false) {
737 "getTotalQnums can only operate on UniTensor with symmetry.\n");
738 return std::vector<Bond>();
741 std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const {
743 "get_blocks_qnums can only operate on UniTensor with symmetry.\n");
744 return std::vector<std::vector<cytnx_int64>>();
747 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
748 if (rhs->uten_type() !=
UTenType.Dense)
return false;
750 return this->get_block_().same_data(rhs->get_block_());
756 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
757 void Add_(
const Scalar &rhs);
759 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
760 void Mul_(
const Scalar &rhs);
762 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
763 void Sub_(
const Scalar &rhs);
764 void lSub_(
const Scalar &lhs);
766 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
767 void Div_(
const Scalar &rhs);
768 void lDiv_(
const Scalar &lhs);
772 boost::intrusive_ptr<UniTensor_base>
Conj() {
773 boost::intrusive_ptr<UniTensor_base> out = this->clone();
778 boost::intrusive_ptr<UniTensor_base> Transpose() {
779 boost::intrusive_ptr<UniTensor_base> out = this->clone();
785 boost::intrusive_ptr<UniTensor_base> normalize() {
786 boost::intrusive_ptr<UniTensor_base> out = this->clone();
792 boost::intrusive_ptr<UniTensor_base> Dagger() {
793 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
810 void Trace_(
const cytnx_int64 &a,
const cytnx_int64 &b);
811 void Trace_(
const std::string &a,
const std::string &b);
812 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
813 boost::intrusive_ptr<UniTensor_base> out = this->clone();
817 boost::intrusive_ptr<UniTensor_base>
Trace(
const cytnx_int64 &a,
const cytnx_int64 &b) {
818 boost::intrusive_ptr<UniTensor_base> out = this->clone();
825 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const {
827 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
829 return Scalar::Sproxy();
831 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
832 const cytnx_complex128 &aux)
const {
834 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
836 return cytnx_complex128(0, 0);
838 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
839 const cytnx_complex64 &aux)
const {
841 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
843 return cytnx_complex64(0, 0);
845 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
846 const cytnx_double &aux)
const {
848 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
852 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
853 const cytnx_float &aux)
const {
855 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
859 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
860 const cytnx_uint64 &aux)
const {
862 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
866 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
867 const cytnx_int64 &aux)
const {
869 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
873 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
874 const cytnx_uint32 &aux)
const {
876 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
880 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
881 const cytnx_int32 &aux)
const {
883 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
887 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
888 const cytnx_uint16 &aux)
const {
890 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
894 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
895 const cytnx_int16 &aux)
const {
897 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
902 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator) {
904 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
906 return Scalar::Sproxy();
908 cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
909 const cytnx_complex128 &aux) {
911 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
913 return *(cytnx_complex128 *)
nullptr;
915 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
916 const cytnx_complex64 &aux) {
918 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
920 return *(cytnx_complex64 *)
nullptr;
922 cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_double &aux) {
924 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
926 return *(cytnx_double *)
nullptr;
928 cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux) {
930 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
932 return *(cytnx_float *)
nullptr;
934 cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint64 &aux) {
936 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
938 return *(cytnx_uint64 *)
nullptr;
940 cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux) {
942 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
944 return *(cytnx_int64 *)
nullptr;
946 cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint32 &aux) {
948 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
950 return *(cytnx_uint32 *)
nullptr;
952 cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux) {
954 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
956 return *(cytnx_int32 *)
nullptr;
958 cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint16 &aux) {
960 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
962 return *(cytnx_uint16 *)
nullptr;
964 cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux) {
966 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
968 return *(cytnx_int16 *)
nullptr;
971 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const {
973 true,
"[ERROR][DenseUniTensor] elem_exists can only be used on UniTensor with Symmetry.%s",
977 if (!this->is_tag()) {
978 for (
int i = 0; i < this->_rowrank; i++) {
979 this->_bonds[i].set_type(BD_KET);
981 for (
int i = this->_rowrank; i < this->_bonds.size(); i++) {
982 this->_bonds[i].set_type(BD_BRA);
984 this->_is_tag =
true;
985 this->_is_braket_form = this->_update_braket();
997 void truncate_(
const cytnx_int64 &bond_idx,
const cytnx_uint64 &dim);
998 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &dim);
1000 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
1002 void group_basis_() {
1003 cytnx_warning_msg(
true,
"[WARNING] group basis will not have any effect on DensUniTensor.%s",
1007 void _save_dispatch(std::fstream &f)
const;
1008 void _load_dispatch(std::fstream &f);
1010 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
1011 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
1014 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
1015 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
1019 const vec2d<cytnx_uint64> &get_itoi()
const {
1020 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
1023 vec2d<cytnx_uint64> &get_itoi() {
1024 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
1034 class BlockUniTensor :
public UniTensor_base {
1037 std::vector<std::vector<cytnx_uint64>> _inner_to_outer_idx;
1038 std::vector<Tensor> _blocks;
1044 void _fx_get_total_fluxs(std::vector<cytnx_uint64> &loc,
const std::vector<Symmetry> &syms,
1045 std::vector<cytnx_int64> &total_qns) {
1046 memset(&total_qns[0], 0,
sizeof(cytnx_int64) * total_qns.size());
1048 for (cytnx_int32 i = 0; i < syms.size(); i++) {
1049 if (this->_bonds[0].type() == BD_BRA)
1050 total_qns[i] = syms[0].reverse_rule(this->_bonds[0]._impl->_qnums[loc[0]][i]);
1052 total_qns[i] = this->_bonds[0]._impl->_qnums[loc[0]][i];
1054 for (
auto j = 1; j < loc.size(); j++) {
1055 if (this->_bonds[j].type() == BD_BRA)
1056 total_qns[i] = syms[i].combine_rule(
1057 total_qns[i], syms[i].reverse_rule(this->_bonds[j]._impl->_qnums[loc[j]][i]));
1060 syms[i].combine_rule(total_qns[i], this->_bonds[j]._impl->_qnums[loc[j]][i]);
1066 void _fx_locate_elem(cytnx_int64 &bidx, std::vector<cytnx_uint64> &loc_in_T,
1067 const std::vector<cytnx_uint64> &locator)
const;
1070 void _fx_group_duplicates(
const std::vector<cytnx_uint64> &dup_bond_idxs,
1071 const std::vector<std::vector<cytnx_uint64>> &idx_mappers);
1073 void set_meta(BlockUniTensor *tmp,
const bool &inner,
const bool &outer)
const {
1076 tmp->_bonds = vec_clone(this->_bonds);
1077 tmp->_labels = this->_labels;
1078 tmp->_is_braket_form = this->_is_braket_form;
1079 tmp->_rowrank = this->_rowrank;
1080 tmp->_name = this->_name;
1083 tmp->_is_diag = this->_is_diag;
1087 tmp->_inner_to_outer_idx = this->_inner_to_outer_idx;
1091 BlockUniTensor *clone_meta(
const bool &inner,
const bool &outer)
const {
1092 BlockUniTensor *tmp =
new BlockUniTensor();
1093 this->set_meta(tmp, inner, outer);
1099 this->uten_type_id =
UTenType.Block;
1100 this->_is_tag =
true;
1109 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
1110 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
1111 const int &device =
Device.cpu,
const bool &is_diag =
false,
1112 const bool &no_alloc =
false,
const std::string &name =
"");
1114 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
1115 const cytnx_int64 &rowrank = -1,
const std::string &name =
"") {
1117 true,
"[ERROR][BlockUniTensor] cannot use Init_by_tensor() on a BlockUniTensor.%s",
"\n");
1120 std::vector<cytnx_uint64> shape()
const {
1121 std::vector<cytnx_uint64> out(this->_bonds.size());
1122 for (cytnx_uint64 i = 0; i < out.size(); i++) {
1123 out[i] = this->_bonds[i].dim();
1128 bool is_blockform()
const {
return true; }
1129 bool is_contiguous()
const {
1131 for (
int i = 0; i < this->_blocks.size(); i++) {
1132 out &= this->_blocks[i].is_contiguous();
1137 cytnx_uint64 Nblocks()
const {
return this->_blocks.size(); };
1139 void to_(
const int &device) {
1140 for (cytnx_uint64 i = 0; i < this->_blocks.size(); i++) {
1141 this->_blocks[i].to_(device);
1145 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
1146 if (this->device() == device) {
1149 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1155 boost::intrusive_ptr<UniTensor_base> clone()
const {
1156 BlockUniTensor *tmp = this->clone_meta(
true,
true);
1157 tmp->_blocks = vec_clone(this->_blocks);
1158 boost::intrusive_ptr<UniTensor_base> out(tmp);
1162 unsigned int dtype()
const {
1165 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1168 return this->_blocks.size() < 1 ?
Type.Void : this->_blocks[0].dtype();
1170 int device()
const {
1173 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1176 return this->_blocks.size() < 1 ? -404 : this->_blocks[0].device();
1178 std::string dtype_str()
const {
1181 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1184 return this->_blocks.size() < 1 ?
"Void, no valid blocks" : this->_blocks[0].dtype_str();
1186 std::string device_str()
const {
1189 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1192 return this->_blocks.size() < 1 ?
"None, no valid blocks" : this->_blocks[0].device_str();
1195 Tensor get_block(
const cytnx_uint64 &idx = 0)
const {
1196 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1198 return this->_blocks[idx].clone();
1202 Tensor get_block(
const std::vector<cytnx_int64> &indices,
const bool &force_return)
const {
1204 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1205 "Tensor rank (number of legs).%s",
1208 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1212 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1213 if (inds == this->_inner_to_outer_idx[i]) {
1221 return NullRefTensor;
1224 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1225 "force_return=false, so "
1226 "error throws. \n If you want to return an empty block without "
1227 "error when block is "
1228 "not avaliable, set force_return=True.%s",
1232 return this->_blocks[b].clone();
1236 const Tensor &get_block_(
const cytnx_uint64 &idx = 0)
const {
1237 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1239 return this->_blocks[idx];
1242 Tensor &get_block_(
const cytnx_uint64 &idx = 0) {
1243 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1245 return this->_blocks[idx];
1248 const Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
1249 const bool &force_return)
const {
1251 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1252 "Tensor rank (number of legs).%s",
1255 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1259 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1260 if (inds == this->_inner_to_outer_idx[i]) {
1268 return this->NullRefTensor;
1271 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1272 "force_return=false, so "
1273 "error throws. \n If you want to return an empty block without "
1274 "error when block is "
1275 "not avaliable, set force_return=True.%s",
1279 return this->_blocks[b];
1283 Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
const bool &force_return) {
1285 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1286 "Tensor rank (number of legs).%s",
1289 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1293 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1294 if (inds == this->_inner_to_outer_idx[i]) {
1302 return this->NullRefTensor;
1305 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1306 "force_return=false, so "
1307 "error throws. \n If you want to return an empty block without "
1308 "error when block is "
1309 "not avaliable, set force_return=True.%s",
1313 return this->_blocks[b];
1317 std::vector<Tensor> get_blocks()
const {
return vec_clone(this->_blocks); }
1318 const std::vector<Tensor> &get_blocks_(
const bool &)
const {
return this->_blocks; }
1319 std::vector<Tensor> &get_blocks_(
const bool &) {
return this->_blocks; }
1321 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
1322 if (rhs->uten_type() !=
UTenType.Block)
return false;
1323 if (rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
1325 for (
int i = 0; i < rhs->get_blocks_(1).size(); i++)
1326 if (this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i]) ==
false)
return false;
1331 void set_rowrank_(
const cytnx_uint64 &new_rowrank) {
1333 "[ERROR][BlockUniTensor] rowrank should be [>=0] and [<=UniTensor.rank].%s",
1335 if (this->is_diag()) {
1337 "[ERROR][BlockUniTensor] rowrank should be [==1] when is_diag =true!.%s",
1340 this->_rowrank = new_rowrank;
1341 this->_is_braket_form = this->_update_braket();
1344 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
1345 BlockUniTensor *tmp = this->clone_meta(
true,
true);
1346 tmp->_blocks = this->_blocks;
1347 tmp->set_rowrank_(new_rowrank);
1348 boost::intrusive_ptr<UniTensor_base> out(tmp);
1352 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
1353 const cytnx_int64 &rowrank = -1);
1354 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
1355 const cytnx_int64 &rowrank = -1);
1357 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
1358 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
1360 boost::intrusive_ptr<UniTensor_base> contiguous_() {
1361 for (
unsigned int b = 0; b < this->_blocks.size(); b++) this->_blocks[b].contiguous_();
1362 return boost::intrusive_ptr<UniTensor_base>(
this);
1365 boost::intrusive_ptr<UniTensor_base> contiguous();
1367 void print_diagram(
const bool &bond_info =
false);
1368 void print_blocks(
const bool &full_info =
true)
const;
1369 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
1371 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
1372 const bool &mv_elem_self =
false,
1373 const bool &mv_elem_rhs =
false);
1375 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &new_labels);
1376 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
1378 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &old_labels,
1379 const std::vector<std::string> &new_labels);
1380 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
1381 const std::vector<std::string> &new_labels);
1383 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
1384 const std::string &new_label);
1385 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
1386 const std::string &new_label);
1388 std::vector<Symmetry> syms()
const;
1390 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0) {
1391 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1393 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
1394 const cytnx_uint64 &rowrank = 0) {
1395 cytnx_error_msg(
true,
"[ERROR] cannot reshape a UniTensor with symmetry.%s",
"\n");
1399 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
1400 BlockUniTensor *tmp = this->clone_meta(
true,
true);
1401 tmp->_blocks.resize(this->_blocks.size());
1402 for (cytnx_int64 blk = 0; blk < this->_blocks.size(); blk++) {
1403 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
1405 boost::intrusive_ptr<UniTensor_base> out(tmp);
1410 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
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 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
1423 "[ERROR][BlockUniTensor][get] cannot use get on a UniTensor with "
1424 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
1428 void put_block(
const Tensor &in,
const cytnx_uint64 &idx = 0) {
1430 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1433 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1438 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1441 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1442 "of block @ idx=%d\n",
1445 this->_blocks[idx] = in.
clone();
1447 void put_block_(
Tensor &in,
const cytnx_uint64 &idx = 0) {
1449 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1452 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1457 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1460 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1461 "of block @ idx=%d\n",
1464 this->_blocks[idx] = in;
1466 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &indices,
const bool &check) {
1468 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1471 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1477 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1478 "Tensor rank (number of legs).%s",
1481 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1485 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1486 if (inds == this->_inner_to_outer_idx[i]) {
1495 "[ERROR][put_block][BlockUniTensor] no avaliable block exists, "
1496 "check=true, so error throws. \n If you want without error when block "
1497 "is not avaliable, set check=false.%s",
1502 in.
shape() != this->_blocks[b].shape(),
1503 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1504 "of block @ idx=%d\n",
1507 this->_blocks[b] = in.
clone();
1510 void put_block_(
Tensor &in,
const std::vector<cytnx_int64> &indices,
const bool &check) {
1512 "[ERROR][DenseUniTensor][put_block] The input tensor dtype does not match.%s",
1515 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
1521 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1522 "Tensor rank (number of legs).%s",
1525 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1529 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1530 if (inds == this->_inner_to_outer_idx[i]) {
1539 "[ERROR][put_block][BlockUniTensor] no avaliable block exists, "
1540 "check=true, so error throws. \n If you want without error when block "
1541 "is not avaliable, set check=false.%s",
1546 in.
shape() != this->_blocks[b].shape(),
1547 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1548 "of block @ idx=%d\n",
1550 this->_blocks[b] = in;
1558 boost::intrusive_ptr<UniTensor_base>
Conj() {
1559 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1565 for (
int i = 0; i < this->_blocks.size(); i++) {
1566 this->_blocks[i].Conj_();
1571 boost::intrusive_ptr<UniTensor_base> Transpose() {
1572 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1578 boost::intrusive_ptr<UniTensor_base> normalize() {
1579 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1584 boost::intrusive_ptr<UniTensor_base> Dagger() {
1585 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1594 void Trace_(
const std::string &a,
const std::string &b);
1595 void Trace_(
const cytnx_int64 &a,
const cytnx_int64 &b);
1597 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
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);
1607 boost::intrusive_ptr<UniTensor_base>
Trace(
const cytnx_int64 &a,
const cytnx_int64 &b) {
1608 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1610 if (out->rank() == 0) {
1611 DenseUniTensor *tmp =
new DenseUniTensor();
1612 tmp->_block = ((BlockUniTensor *)out.get())->_blocks[0];
1613 out = boost::intrusive_ptr<UniTensor_base>(tmp);
1620 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
1622 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
1623 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1624 const cytnx_complex128 &aux)
const;
1625 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1626 const cytnx_complex64 &aux)
const;
1627 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1628 const cytnx_double &aux)
const;
1629 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1630 const cytnx_float &aux)
const;
1631 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1632 const cytnx_uint64 &aux)
const;
1633 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1634 const cytnx_int64 &aux)
const;
1635 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1636 const cytnx_uint32 &aux)
const;
1637 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1638 const cytnx_int32 &aux)
const;
1639 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1640 const cytnx_uint16 &aux)
const;
1641 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1642 const cytnx_int16 &aux)
const;
1644 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
1645 cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1646 const cytnx_complex128 &aux);
1647 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1648 const cytnx_complex64 &aux);
1649 cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_double &aux);
1650 cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux);
1651 cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint64 &aux);
1652 cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux);
1653 cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint32 &aux);
1654 cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux);
1655 cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint16 &aux);
1656 cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux);
1658 void _save_dispatch(std::fstream &f)
const;
1659 void _load_dispatch(std::fstream &f);
1662 void truncate_(
const std::string &bond_idx,
const cytnx_uint64 &q_index);
1663 void truncate_(
const cytnx_int64 &bond_idx,
const cytnx_uint64 &q_index);
1665 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1666 void Add_(
const Scalar &rhs) {
1669 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1671 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1672 "operation on the block(s).");
1675 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1676 void Mul_(
const Scalar &rhs);
1678 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1679 void Sub_(
const Scalar &rhs) {
1682 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1684 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1685 "operation on the block(s).");
1687 void lSub_(
const Scalar &lhs) {
1690 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1692 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1693 "operation on the block(s).");
1696 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs) {
1699 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1701 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1702 "operation on the block(s).");
1704 void Div_(
const Scalar &rhs);
1705 void lDiv_(
const Scalar &lhs) {
1708 "[ERROR] cannot perform elementwise arithmetic '+' btwn Scalar and BlockUniTensor.\n %s "
1710 "This operation will destroy block structure. [Suggest] using get/set_block(s) to do "
1711 "operation on the block(s).");
1713 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &force);
1715 void group_basis_();
1717 void combineBond(
const std::vector<std::string> &indicators,
const bool &force =
false);
1718 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
false);
1719 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
1720 const bool &by_label);
1721 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
false);
1723 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
1725 bidx >= this->Nblocks(),
1726 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1728 return this->_inner_to_outer_idx[bidx];
1730 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
1732 bidx >= this->Nblocks(),
1733 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1735 return this->_inner_to_outer_idx[bidx];
1738 const vec2d<cytnx_uint64> &get_itoi()
const {
return this->_inner_to_outer_idx; }
1739 vec2d<cytnx_uint64> &get_itoi() {
return this->_inner_to_outer_idx; }
1745 class UniTensor_options {
1752 UniTensor_options() {
1753 this->_is_diag =
false;
1754 this->_dtype =
Type.Double;
1755 this->_device =
Device.cpu;
1756 this->_rowrank = -1;
1759 UniTensor_options(
const UniTensor_options &rhs) {
1760 this->_is_diag = rhs._is_diag;
1761 this->_dtype = rhs._dtype;
1762 this->_device = rhs._device;
1763 this->_rowrank = rhs._rowrank;
1766 UniTensor_options &operator=(
const UniTensor_options &rhs) {
1767 this->_is_diag = rhs._is_diag;
1768 this->_dtype = rhs._dtype;
1769 this->_device = rhs._device;
1770 this->_rowrank = rhs._rowrank;
1774 UniTensor_options &is_diag(
const bool &in) {
1775 this->_is_diag = in;
1778 UniTensor_options &dtype(
const int &in) {
1782 UniTensor_options &device(
const int &in) {
1786 UniTensor_options &rowrank(
const int &in) {
1787 this->_rowrank = in;
1797 boost::intrusive_ptr<UniTensor_base>
_impl;
1801 this->_impl =
rhs._impl;
1835 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"")
1857 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"") {
1887 const std::string &
name =
"")
1892 "[DEBUG] message: entry for UniTensor(const std::vector<Bond> &bonds, const "
1893 "std::vector<std::string> &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned "
1895 "&dtype=Type.Double, const int &device = Device.cpu, const bool &is_diag=false)%s",
1938 const std::string &
name =
"") {
1953 "[ERROR] All the Bond when init a UniTensor with symmetric must be in "
1954 "the same format!%s",
1959 is_sym,
"[ERROR] cannot have bonds with mixing of symmetry and non-symmetry.%s",
"\n");
1965 cytnx_warning_msg(
true,
"[DEBUG] message: entry dispatch: UniTensor: symmetric%s",
"\n");
1973 "[ERROR] internal error! [legacy Sparse entry] the Bond is symmetry but "
1974 "the version is not properly determined!%s",
1978 "[ERROR] internal error! the Bond is symmetry but the version is not "
1979 "properly determined!%s",
2092 std::vector<std::string>
vs(
new_lbls.size());
2094 [](
char *
x) -> std::string { return std::string(x); });
2096 this->_impl->set_labels(
vs);
2120 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2121 "get_block()/get_blocks() first.%s",
2125 return tmp->_block.item<
T>();
2130 "[ERROR] cannot use item on UniTensor with Symmetry.\n suggestion: use "
2131 "get_block()/get_blocks() first.%s",
2135 return tmp->_block.item();
2160 unsigned int dtype()
const {
return this->_impl->dtype(); }
2175 int device()
const {
return this->_impl->device(); }
2181 std::string
name()
const {
return this->_impl->name(); }
2188 std::string
dtype_str()
const {
return this->_impl->dtype_str(); }
2195 std::string
device_str()
const {
return this->_impl->device_str(); }
2215 bool is_diag()
const {
return this->_impl->is_diag(); }
2222 bool is_tag()
const {
return this->_impl->is_tag(); }
2229 std::vector<Symmetry>
syms()
const {
return this->_impl->syms(); }
2243 const std::vector<std::string> &
labels()
const {
return this->_impl->labels(); }
2256 const std::vector<Bond> &
bonds()
const {
return this->_impl->bonds(); }
2261 std::vector<Bond> &
bonds() {
return this->_impl->bonds(); }
2276 std::vector<cytnx_uint64>
shape()
const {
return this->_impl->shape(); }
2339 "UniTensor &relabel_(const std::vector<std::string> &old_labels, const "
2340 "std::vector<std::string> &new_labels) "
2370 "UniTensor relabel(const std::vector<std::string> &new_labels) const "
2384 std::vector<std::string>
vs(
new_lbls.size());
2386 [](
char *
x) -> std::string { return std::string(x); });
2399 "UniTensor relabel(const std::initializer_list<char *> &new_labels) const "
2403 std::vector<std::string>
vs(
new_lbls.size());
2405 [](
char *
x) -> std::string { return std::string(x); });
2416 std::vector<std::string>
vs(
new_lbls.size());
2418 [](
char *
x) -> std::string { return std::string(x); });
2420 this->_impl->relabel_(
vs);
2430 "UniTensor &relabel_(const std::initializer_list<char *> &new_labels) "
2434 std::vector<std::string>
vs(
new_lbls.size());
2436 [](
char *
x) -> std::string { return std::string(x); });
2438 this->_impl->relabels_(
vs);
2450 const std::vector<std::string> &
new_labels)
const {
2462 "UniTensor relabel(const std::vector<std::string> &old_labels, const "
2463 "std::vector<std::string> &new_labels) const "
2466 const std::vector<std::string> &
new_labels)
const {
2488 const std::vector<std::string> &
new_labels) {
2499 "UniTensor &relabel_(const std::vector<std::string> &old_labels, const "
2500 "std::vector<std::string> &new_labels) "
2503 const std::vector<std::string> &
new_labels) {
2513 const std::initializer_list<char *> &
new_labels)
const {
2515 std::vector<std::string>
vs(
new_lbls.size());
2517 [](
char *
x) -> std::string { return std::string(x); });
2522 [](
char *
x) -> std::string { return std::string(x); });
2534 "UniTensor relabel(const std::initializer_list<char *> &old_labels, const "
2535 "std::initializer_list<char *> &new_labels) const "
2538 const std::initializer_list<char *> &
new_labels)
const {
2540 std::vector<std::string>
vs(
new_lbls.size());
2542 [](
char *
x) -> std::string { return std::string(x); });
2547 [](
char *
x) -> std::string { return std::string(x); });
2557 const std::initializer_list<char *> &
new_labels) {
2559 std::vector<std::string>
vs(
new_lbls.size());
2561 [](
char *
x) -> std::string { return std::string(x); });
2566 [](
char *
x) -> std::string { return std::string(x); });
2578 "UniTensor &relabel_(const std::initializer_list<char *> &old_labels, const "
2579 "std::initializer_list<char *> &new_labels) "
2582 const std::initializer_list<char *> &
new_labels) {
2584 std::vector<std::string>
vs(
new_lbls.size());
2586 [](
char *
x) -> std::string { return std::string(x); });
2591 [](
char *
x) -> std::string { return std::string(x); });
2670 if (this->
dtype() == dtype) {
2712 std::vector<std::string>
vs(
mprs.size());
2714 [](
char *
x) -> std::string { return std::string(x); });
2730 "UniTensor &permute_(const std::vector<std::string> &mapper, const cytnx_int64 &rowrank) "
2820 if (this->
uten_type() == UTenType.Block) {
2823 return this->_impl->at_for_sparse(
locator,
aux);
2825 }
else if (this->
uten_type() == UTenType.Sparse) {
2826 if (this->_impl->elem_exists(
locator)) {
2828 return this->_impl->at_for_sparse(
locator,
aux);
2830 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2846 if (this->
uten_type() == UTenType.Block) {
2849 return this->_impl->at_for_sparse(
locator,
aux);
2851 }
else if (this->
uten_type() == UTenType.Sparse) {
2852 if (this->_impl->elem_exists(
locator)) {
2854 return this->_impl->at_for_sparse(
locator,
aux);
2856 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2866 const std::vector<cytnx_uint64> &
locator)
const {
2869 "[ERROR][at] length of list should be the same for label and locator.%s",
2873 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2876 for (
int i = 0;
i <
labels.size();
i++) {
2877 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2879 "[ERROR] label:%s does not exist in current UniTensor.\n",
2881 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2884 return this->
at<T>(new_locator);
2890 "[ERROR][at] length of list should be the same for label and locator.%s",
2894 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2897 for (
int i = 0;
i <
labels.size();
i++) {
2898 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2900 "[ERROR] label:%s does not exist in current UniTensor.\n",
2902 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2905 return this->
at<T>(new_locator);
2912 const Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator)
const {
2913 if (this->
uten_type() == UTenType.Block) {
2914 return this->_impl->at_for_sparse(
locator);
2915 }
else if (this->
uten_type() == UTenType.Sparse) {
2916 if (this->_impl->elem_exists(
locator)) {
2917 return this->_impl->at_for_sparse(
locator);
2919 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2931 Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator) {
2932 if (this->
uten_type() == UTenType.Block) {
2933 return this->_impl->at_for_sparse(
locator);
2934 }
else if (this->
uten_type() == UTenType.Sparse) {
2935 if (this->_impl->elem_exists(
locator)) {
2936 return this->_impl->at_for_sparse(
locator);
2938 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
2946 Scalar::Sproxy
at(
const std::vector<std::string> &
labels,
2947 const std::vector<cytnx_uint64> &
locator) {
2950 "[ERROR][at] length of list should be the same for label and locator.%s",
2954 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2957 for (
int i = 0;
i <
labels.size();
i++) {
2958 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2960 "[ERROR] label:%s does not exist in current UniTensor.\n",
2962 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2965 return this->
at(new_locator);
2968 const Scalar::Sproxy
at(
const std::vector<std::string> &
labels,
2969 const std::vector<cytnx_uint64> &
locator)
const {
2972 "[ERROR][at] length of list should be the same for label and locator.%s",
2976 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
2979 for (
int i = 0;
i <
labels.size();
i++) {
2980 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
2982 "[ERROR] label:%s does not exist in current UniTensor.\n",
2984 new_loc = std::distance(this->_impl->_labels.begin(),
res);
2987 return this->
at(new_locator);
3008 return this->_impl->get_block(
qidx,
force);
3012 const bool &
force =
false)
const {
3015 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
3017 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
3019 std::vector<cytnx_int64>
loc_id(this->
rank());
3024 for (
int i = 0;
i <
labels.size();
i++) {
3025 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
3027 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
3029 new_loc = std::distance(this->_impl->_labels.begin(),
res);
3043 const bool &
force =
false)
const {
3044 std::vector<cytnx_int64>
tmp =
qnum;
3058 const bool &
force =
false)
const {
3069 return this->_impl->get_block_(
idx);
3087 return this->_impl->get_block_(
qidx,
force);
3107 const bool &
force =
false) {
3110 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
3112 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
3114 std::vector<cytnx_int64>
loc_id(this->
rank());
3119 for (
int i = 0;
i <
labels.size();
i++) {
3120 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
3122 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
3124 new_loc = std::distance(this->_impl->_labels.begin(),
res);
3129 if (
out.dtype() !=
Type.Void) {
3139 std::vector<cytnx_int64>
tmp =
qidx;
3152 const bool &
force =
false) {
3163 const bool &
force =
false)
const {
3164 return this->_impl->get_block_(
qidx,
force);
3171 const bool &
force =
false)
const {
3172 std::vector<cytnx_int64>
tmp =
qidx;
3173 return this->_impl->get_block_(
tmp,
force);
3180 const bool &
force =
false)
const {
3195 std::vector<Tensor>
get_blocks()
const {
return this->_impl->get_blocks(); }
3204 return this->_impl->get_blocks_(
silent);
3212 return this->_impl->get_blocks_(
silent);
3221 this->_impl->put_block(
in,
idx);
3240 const std::vector<cytnx_int64> &
qidx,
const bool &
force =
false) {
3243 "[ERROR][put_block] length of lists must be the same for both lables and qnidices%s",
"\n");
3245 "[ERROR][put_block] length of lists must be the rank (# of legs)%s",
"\n");
3247 std::vector<cytnx_int64>
loc_id(this->
rank());
3253 for (
int i = 0;
i <
lbls.size();
i++) {
3254 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
3256 "[ERROR][put_block] label:%s does not exists in current Tensor.\n",
3258 new_loc = std::distance(this->_impl->_labels.begin(),
res);
3288 const std::vector<cytnx_int64> &
qidx,
const bool &
force =
false) {
3291 "[ERROR][put_block_] length of lists must be the same for both lables and qnidices%s",
3294 "[ERROR][put_block_] length of lists must be the rank (# of legs)%s",
"\n");
3296 std::vector<cytnx_int64>
loc_id(this->
rank());
3302 for (
int i = 0;
i <
lbls.size();
i++) {
3303 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
3305 "[ERROR][put_block_] label:%s does not exists in current Tensor.\n",
3307 new_loc = std::distance(this->_impl->_labels.begin(),
res);
3327 "[ERROR] cannot set elements from UniTensor with symmetry. Use at() instead.%s",
"\n");
3330 "[ERROR] cannot set UniTensor. incoming UniTensor is_diag=True.%s",
"\n");
3389 "combineBond(const std::vector<std::string> &indicators, const bool &force) "
3403 "combineBond(const std::vector<std::string> &indicators, const bool &force) "
3416 "combineBond(const std::vector<std::string> &indicators, const bool &force) "
3471 return this->_impl->getTotalQnums(
physical);
3478 return this->_impl->get_blocks_qnums();
3488 if (this->_impl->uten_type() !=
rhs._impl->uten_type())
return false;
3490 return this->_impl->same_data(
rhs._impl);
3916 out._impl = this->_impl->
Conj();
3928 this->_impl->
Conj_();
4023 if (this->
uten_type() == UTenType.Block) {
4025 if (this->
rank() == 0) {
4028 this->_impl = boost::intrusive_ptr<UniTensor_base>(
tmp);
4045 if (this->
uten_type() == UTenType.Block) {
4047 if (this->
rank() == 0) {
4050 this->_impl = boost::intrusive_ptr<UniTensor_base>(
tmp);
4119 return this->_impl->elem_exists(
locator);
4129 return this->
at<T>(locator);
4140 this->
at(locator) =
rc;
4243 return this->_impl->get_qindices(
bidx);
4253 return this->_impl->get_qindices(
bidx);
4266 void _Load(std::fstream &
f);
4267 void _Save(std::fstream &
f)
const;
4271 this->_impl->from_(
rhs._impl,
force);
4289 const std::vector<std::string> &
in_labels = {},
4291 const std::string &
name =
"") {
4309 const std::vector<std::string> &
in_labels = {},
4311 const std::string &
name =
"") {
4328 const std::string &
name =
"") {
4345 const std::vector<std::string> &
in_labels = {},
4347 const unsigned int &
dtype =
Type.Double,
4390 const std::vector<std::string> &
in_labels = {},
4392 const std::string &
name =
"") {
4410 const std::vector<std::string> &
in_labels = {},
4411 const std::string &
name =
"") {
4433 const std::vector<std::string> &
in_labels = {},
4435 const std::string &
name =
"") {
4460 const std::vector<std::string> &
in_labels = {},
4461 const unsigned int &
dtype =
Type.Double,
4487 const std::vector<std::string> &
in_labels = {},
4490 const std::string &
name =
"");
4511 const double &
std,
const std::vector<std::string> &
in_labels = {},
4514 const std::string &
name =
"");
4535 const std::vector<std::string> &
in_labels = {},
4537 const unsigned int &
dtype =
Type.Double,
4578 const double &
high,
const std::vector<std::string> &
in_labels = {},
4580 const unsigned int &
dtype =
Type.Double,
4617 std::ostream &operator<<(std::ostream &os,
const UniTensor &in);
4633 const bool &cacheR =
false);
4648 const bool &optimal);
4657 "UniTensor Contract(const std::vector<UniTensor> &TNs, const std::string &order, const bool "
4660 Contracts(
const std::vector<UniTensor> &TNs,
const std::string &order,
const bool &optimal);
4663 void _resolve_CT(std::vector<UniTensor> &TNlist);
4664 template <
class... T>
4665 void _resolve_CT(std::vector<UniTensor> &TNlist,
const UniTensor &in,
const T &...args) {
4666 TNlist.push_back(in);
4667 _resolve_CT(TNlist, args...);
4682 template <
class... T>
4684 const bool &optimal) {
4685 std::vector<UniTensor> TNlist;
4686 _resolve_CT(TNlist, in, args...);
4687 return Contract(TNlist, order, optimal);
4695 template <
class... T>
4698 "UniTensor Contract(const UniTensor &in, const T &...args, const std::string &order, const "
4702 const bool &optimal) {
4703 std::vector<UniTensor> TNlist;
4704 _resolve_CT(TNlist, in, args...);
4705 return Contracts(TNlist, order, optimal);
constexpr Type_class Type
data type
Definition Type.hpp:426
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:671
Tensor contiguous_()
Make the Tensor contiguous by coalescing the memory (storage), inplacely.
Definition Tensor.hpp:758
unsigned int dtype() const
the dtype-id of the Tensor
Definition Tensor.hpp:570
Tensor contiguous() const
Make the Tensor contiguous by coalescing the memory (storage).
Definition Tensor.hpp:738
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition Tensor.hpp:920
Tensor clone() const
return a clone of the current Tensor.
Definition Tensor.hpp:622
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:1055
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:885
const bool & is_contiguous() const
return whether the Tensor is contiguous or not.
Definition Tensor.hpp:677
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:577
Tensor get(const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition Tensor.hpp:1023
const std::vector< cytnx_uint64 > & shape() const
the shape of the Tensor
Definition Tensor.hpp:597
An Enhanced tensor specifically designed for physical Tensor network simulation.
Definition UniTensor.hpp:1794
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:3231
UniTensor to(const int &device) const
move the current UniTensor to the assigned device.
Definition UniTensor.hpp:2302
UniTensor & operator*=(const UniTensor &rhs)
The multiplication assignment operator of the UniTensor.
Definition UniTensor.hpp:3842
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:4371
Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:3138
std::vector< Tensor > & get_blocks_(const bool &silent=false)
Definition UniTensor.hpp:3211
Tensor & get_block_(const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:3146
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:2794
UniTensor & operator/=(const UniTensor &rhs)
The division assignment operator of the UniTensor.
Definition UniTensor.hpp:3822
T & item()
Definition UniTensor.hpp:2118
bool is_contiguous() const
To tell whether the UniTensor is contiguous.
Definition UniTensor.hpp:2209
T get_elem(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:4128
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:3011
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:4252
UniTensor & set_label(const cytnx_int64 &idx, const char *new_label)
Definition UniTensor.hpp:2021
UniTensor & operator+=(const UniTensor &rhs)
The addition assignment operator of the UniTensor.
Definition UniTensor.hpp:3782
void to_dense_()
Convert the UniTensor to non-diagonal form, inplacely.
Definition UniTensor.hpp:3380
UniTensor reshape(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor.
Definition UniTensor.hpp:3341
std::vector< Tensor > get_blocks() const
Get all the blocks of the UniTensor.
Definition UniTensor.hpp:3195
void combineBond(const std::vector< std::string > &indicators, const bool &force=false)
Combine the sevral bonds of the UniTensor.
Definition UniTensor.hpp:3432
UniTensor permute(const std::initializer_list< char * > &mapper, const cytnx_int64 &rowrank=-1) const
Definition UniTensor.hpp:2709
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:2222
std::string uten_type_str() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor in 'string' form.
Definition UniTensor.hpp:2202
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:1884
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:3007
UniTensor & tag()
Set the UniTensor as a tagged UniTensor.
Definition UniTensor.hpp:4087
const Bond & bond_(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:2263
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force=false)
Definition UniTensor.hpp:3418
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:2637
const T & at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:2865
UniTensor & relabels_(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2432
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:1833
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:3086
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:1856
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:4308
UniTensor get(const std::vector< Accessor > &accessors) const
Definition UniTensor.hpp:3316
T & at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:2887
UniTensor Conj() const
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:3914
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:2036
UniTensor set_rowrank(const cytnx_uint64 &new_rowrank) const
Definition UniTensor.hpp:2111
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:3872
cytnx_uint64 rowrank() const
Return the row rank of the UniTensor.
Definition UniTensor.hpp:2153
UniTensor & relabels_(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels)
Definition UniTensor.hpp:2502
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:3765
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:2090
UniTensor & relabel_(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2414
UniTensor & Sub_(const Scalar &rhs)
The subtraction function for a given scalar.
Definition UniTensor.hpp:3617
UniTensor & relabel_(const cytnx_int64 &inx, const std::string &new_label)
rebable the lags in the UniTensor by given index.
Definition UniTensor.hpp:2624
UniTensor & operator/=(const Scalar &rhs)
The division assignment operator for a given scalar.
Definition UniTensor.hpp:3887
const bool & is_braket_form() const
Check whether the UniTensor is in braket form.
Definition UniTensor.hpp:2237
void set_elem(const std::vector< cytnx_uint64 > &locator, const T2 &rc)
Definition UniTensor.hpp:4138
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:4458
std::vector< cytnx_uint64 > shape() const
Get the shape of the UniTensor.
Definition UniTensor.hpp:2276
UniTensor to_dense()
Convert the UniTensor to non-diagonal form.
Definition UniTensor.hpp:3370
UniTensor & permute_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:2732
Scalar::Sproxy at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:2946
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:3162
UniTensor & set_labels(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:2081
std::string name() const
Return the name of the UniTensor.
Definition UniTensor.hpp:2181
const Scalar::Sproxy at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:2968
UniTensor & Add_(const Scalar &rhs)
The addition function for a given scalar.
Definition UniTensor.hpp:3587
UniTensor & Trace_(const std::string &a, const std::string &b)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:4021
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:4200
Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition UniTensor.hpp:2931
UniTensor Trace(const std::string &a, const std::string &b) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:3991
bool same_data(const UniTensor &rhs) const
Check whether the Blocks address are the same.
Definition UniTensor.hpp:3486
UniTensor astype(const unsigned int &dtype) const
Return a new UniTensor that cast to different data type.
Definition UniTensor.hpp:2668
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:4389
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:4214
UniTensor Transpose() const
Take the transpose of the UniTensor.
Definition UniTensor.hpp:3942
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:4431
UniTensor & set_label(const char *old_label, const std::string &new_label)
Definition UniTensor.hpp:2044
static UniTensor Load(const char *fname)
load a UniTensor from file
UniTensor & Dagger_()
Take the conjugate transpose to the UniTensor, inplacely.
Definition UniTensor.hpp:4074
void print_diagram(const bool &bond_info=false)
Plot the diagram of the UniTensor.
Definition UniTensor.hpp:2781
std::vector< Bond > & bonds()
Definition UniTensor.hpp:2261
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition UniTensor.hpp:2818
UniTensor & set_rowrank_(const cytnx_uint64 &new_rowrank)
Set the row rank of the UniTensor.
Definition UniTensor.hpp:2106
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:3239
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:2013
UniTensor contiguous() const
Make the UniTensor contiguous by coalescing the memory (storage).
Definition UniTensor.hpp:2765
Tensor get_block(const cytnx_uint64 &idx=0) const
Get the block of the UniTensor for a given index.
Definition UniTensor.hpp:2996
const T & at(const std::vector< cytnx_uint64 > &locator) const
Get an element at specific location.
Definition UniTensor.hpp:2844
UniTensor & operator*=(const Scalar &rhs)
The multiplication assignment operator for a given scalar.
Definition UniTensor.hpp:3902
UniTensor relabels(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels) const
Definition UniTensor.hpp:2465
void contiguous_()
Make the UniTensor contiguous by coalescing the memory (storage), inplacely.
Definition UniTensor.hpp:2775
UniTensor normalize() const
normalize the current UniTensor instance with 2-norm.
Definition UniTensor.hpp:3965
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:4326
UniTensor & relabel_(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:2327
std::vector< Symmetry > syms() const
Return the symmetry type of the UniTensor.
Definition UniTensor.hpp:2229
UniTensor relabel(const std::vector< std::string > &new_labels) const
relable all of the labels in UniTensor.
Definition UniTensor.hpp:2358
UniTensor & Mul_(const UniTensor &rhs)
The multiplcation function of the UniTensor.
Definition UniTensor.hpp:3530
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:4288
void put_block_(Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index, inplacely.
Definition UniTensor.hpp:3271
void combineBonds(const std::vector< std::string > &indicators, const bool &force=false)
Definition UniTensor.hpp:3405
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:2656
UniTensor & normalize_()
normalize the UniTensor, inplacely.
Definition UniTensor.hpp:3977
bool is_diag() const
To tell whether the UniTensor is in diagonal form.
Definition UniTensor.hpp:2215
int device() const
Return the device of the UniTensor.
Definition UniTensor.hpp:2175
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:3179
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:3106
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:3287
void set(const std::vector< Accessor > &accessors, const Tensor &rhs)
Definition UniTensor.hpp:3321
std::string dtype_str() const
Return the data type of the UniTensor in 'string' form.
Definition UniTensor.hpp:2188
UniTensor & operator+=(const Scalar &rhs)
The addition assignment operator for a given scalar.
Definition UniTensor.hpp:3857
UniTensor & Div_(const UniTensor &rhs)
The division function of the UniTensor.
Definition UniTensor.hpp:3572
UniTensor & Div_(const Scalar &rhs)
The division function for a given scalar.
Definition UniTensor.hpp:3632
Bond & bond_(const std::string &label)
Definition UniTensor.hpp:2267
cytnx_uint64 rank() const
Return the rank of the UniTensor.
Definition UniTensor.hpp:2147
Bond bond(const std::string &label) const
Definition UniTensor.hpp:2270
void group_basis_()
Group the same quantum number basis together.
Definition UniTensor.hpp:2804
void to_(const int &device)
move the current UniTensor to the assigned device (inplace).
Definition UniTensor.hpp:2291
UniTensor & Trace_(const cytnx_int64 &a=0, const cytnx_int64 &b=1)
Take the partial trance to the UniTensor, inplacely.
Definition UniTensor.hpp:4043
UniTensor relabel(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:2449
UniTensor & set_name(const std::string &in)
Set the name of the UniTensor.
Definition UniTensor.hpp:1998
UniTensor Trace(const cytnx_int64 &a=0, const cytnx_int64 &b=1) const
Take the partial trance to the UniTensor.
Definition UniTensor.hpp:4006
UniTensor & Add_(const UniTensor &rhs)
The addition function of the UniTensor.
Definition UniTensor.hpp:3509
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:2686
UniTensor & set_label(const std::string &old_label, const char *new_label)
Definition UniTensor.hpp:2052
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:2699
unsigned int dtype() const
Return the data type of the UniTensor.
Definition UniTensor.hpp:2160
UniTensor Pow(const double &p) const
Power function.
UniTensor & Mul_(const Scalar &rhs)
The multiplication function for a given scalar.
Definition UniTensor.hpp:3602
UniTensor & operator-=(const UniTensor &rhs)
The subtraction assignment operator of the UniTensor.
Definition UniTensor.hpp:3802
Tensor get_block_(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:3151
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force, const bool &by_label)
Definition UniTensor.hpp:3391
UniTensor & set_label(const char *old_label, const char *new_label)
Definition UniTensor.hpp:2060
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:4409
bool is_blockform() const
Check whether the UniTensor is in block form.
Definition UniTensor.hpp:2283
UniTensor group_basis() const
Definition UniTensor.hpp:2806
UniTensor Dagger() const
Take the conjugate transpose to the UniTensor.
Definition UniTensor.hpp:4062
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:3324
const std::vector< Tensor > & get_blocks_(const bool &silent=false) const
Get all the blocks of the UniTensor, inplacely.
Definition UniTensor.hpp:3203
UniTensor & relabels_(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2581
const Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:3170
bool elem_exists(const std::vector< cytnx_uint64 > &locator) const
Geiven the locator, check if the element exists.
Definition UniTensor.hpp:4118
UniTensor & Sub_(const UniTensor &rhs)
The subtraction function of the UniTensor.
Definition UniTensor.hpp:3551
UniTensor relabels(const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:2401
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:3454
void put_block(const Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index.
Definition UniTensor.hpp:3220
const Tensor & get_block_(const cytnx_uint64 &idx=0) const
Get the shared view of block for the given index.
Definition UniTensor.hpp:3068
UniTensor & relabel_(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels)
relable part or all of the labels in UniTensor by given new labels
Definition UniTensor.hpp:2487
static UniTensor Load(const std::string &fname)
load a UniTensor from file
UniTensor & permute_(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1)
permute the lags of the UniTensor, inplacely.
Definition UniTensor.hpp:2743
const Bond & bond_(const std::string &label) const
Definition UniTensor.hpp:2266
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:4344
Bond & bond_(const cytnx_uint64 &idx)
Definition UniTensor.hpp:2264
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:2611
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 & reshape_(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor, inplacely.
Definition UniTensor.hpp:3353
UniTensor relabels(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:2537
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:4242
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:2243
UniTensor & relabel_(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2556
cytnx_int64 get_index(std::string label) const
Get the index of an desired label string.
Definition UniTensor.hpp:2250
const std::vector< Bond > & bonds() const
Get the bonds of the UniTensor.
Definition UniTensor.hpp:2256
Tensor get_block(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:3057
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:4229
UniTensor & Transpose_()
Take the transpose of the UniTensor, inplacely.
Definition UniTensor.hpp:3954
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:2312
vec2d< cytnx_uint64 > & get_itoi()
Definition UniTensor.hpp:4263
void print_blocks(const bool &full_info=true) const
Print all of the blocks in the UniTensor.
Definition UniTensor.hpp:2787
Scalar::Sproxy item() const
Definition UniTensor.hpp:2128
const vec2d< cytnx_uint64 > & get_itoi() const
get the q-indices on each leg for all the blocks
Definition UniTensor.hpp:4262
std::string device_str() const
Return the device of the UniTensor in 'string' form.
Definition UniTensor.hpp:2195
UniTensor & convert_from(const UniTensor &rhs, const bool &force=false)
Definition UniTensor.hpp:4270
UniTensor relabels(const std::vector< std::string > &new_labels) const
Definition UniTensor.hpp:2372
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:3279
UniTensor relabel(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:2512
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:1935
UniTensor & Conj_()
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:3927
UniTensor relabel(const std::initializer_list< char * > &new_labels) const
relables all of the labels in UniTensor.
Definition UniTensor.hpp:2382
cytnx_uint64 Nblocks() const
Return the number of blocks in the UniTensor.
Definition UniTensor.hpp:2141
Tensor get_block(const std::vector< cytnx_uint64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:3052
void Save(const char *fname) const
save a UniTensor to file
Bond bond(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:2269
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:4187
Tensor get_block(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:3042
UniTensor & relabels_(const std::vector< std::string > &new_labels)
Definition UniTensor.hpp:2342
const Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator) const
Get an element at specific location.
Definition UniTensor.hpp:2912
int uten_type() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor.
Definition UniTensor.hpp:2168
Tensor & get_block_(const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:3076
#define cytnx_warning_msg(is_true, format,...)
Definition cytnx_error.hpp:52
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:18
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
Definition Accessor.hpp:12
Device_class Device
data on which devices.
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.
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.
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.
UniTensor Contracts(const std::vector< UniTensor > &TNs, const std::string &order, const bool &optimal)
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.