1#ifndef CYTNX_UNITENSOR_H_
2#define CYTNX_UNITENSOR_H_
8#include "utils/utils.hpp"
14#include <initializer_list>
24 #include "backend/Scalar.hpp"
33 class UniTensorType_class {
35 enum :
int {
Void = -99, Dense = 0, Sparse = 1, Block = 2, BlockFermionic = 3 };
36 std::string getname(
const int &ut_type)
const;
61 class UniTensor_base :
public intrusive_ptr_base<UniTensor_base> {
69 std::vector<std::string> _labels;
70 std::vector<Bond> _bonds;
72 bool _update_braket() {
73 if (_bonds.size() == 0)
return false;
75 if (this->_bonds[0].type() != bondType::BD_REG) {
77 for (
unsigned int i = 0; i < this->_bonds.size(); i++) {
78 if (i < this->_rowrank) {
79 if (this->_bonds[i].type() != bondType::BD_KET)
return false;
81 if (this->_bonds[i].type() != bondType::BD_BRA)
return false;
90 friend class UniTensor;
91 friend class DenseUniTensor;
93 friend class BlockUniTensor;
94 friend class BlockFermionicUniTensor;
98 _name(std::string(
"")),
99 _is_braket_form(false),
105 UniTensor_base(
const UniTensor_base &rhs);
106 UniTensor_base &operator=(UniTensor_base &rhs);
108 cytnx_uint64 rowrank()
const {
return this->_rowrank; }
109 bool is_diag()
const {
return this->_is_diag; }
110 const bool &is_braket_form()
const {
return this->_is_braket_form; }
111 const bool &is_tag()
const {
return this->_is_tag; }
112 const std::vector<std::string> &labels()
const {
return this->_labels; }
119 cytnx_int64 get_index(std::string label)
const {
120 std::vector<std::string> labels = this->_labels;
121 for (cytnx_uint64 i = 0; i < labels.size(); i++) {
122 if (labels[i] == label)
return i;
126 const std::vector<Bond> &bonds()
const {
return this->_bonds; }
127 std::vector<Bond> &bonds() {
return this->_bonds; }
129 Bond &bond_(
const cytnx_uint64 &idx) {
130 cytnx_error_msg(idx >= this->_bonds.size(),
"[ERROR][bond] index %d out of bound, total %d\n",
131 idx, this->_bonds.size());
132 return this->_bonds[idx];
135 Bond &bond_(
const std::string &label) {
136 auto res = std::find(this->_labels.begin(), this->_labels.end(), label);
137 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n", label.c_str());
138 cytnx_uint64 idx = std::distance(this->_labels.begin(), res);
140 return this->bond_(idx);
143 const std::string &name()
const {
return this->_name; }
144 cytnx_uint64 rank()
const {
return this->_labels.size(); }
145 void set_name(
const std::string &in) { this->_name = in; }
158 void set_label(
const std::string &oldlabel,
const std::string &new_label) {
160 auto res = std::find(this->_labels.begin(), this->_labels.end(), oldlabel);
161 cytnx_error_msg(res == this->_labels.end(),
"[ERROR] label %s not exists.\n",
163 idx = std::distance(this->_labels.begin(), res);
165 cytnx_error_msg(idx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
169 for (cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
170 if (i == idx)
continue;
171 if (new_label == this->_labels[i]) {
176 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
178 this->_labels[idx] = new_label;
180 void set_label(
const cytnx_int64 &inx,
const std::string &new_label) {
182 cytnx_error_msg(inx >= this->_labels.size(),
"[ERROR] index exceed the rank of UniTensor%s",
186 for (cytnx_uint64 i = 0; i < this->_labels.size(); i++) {
187 if (i == inx)
continue;
188 if (new_label == this->_labels[i]) {
193 cytnx_error_msg(is_dup,
"[ERROR] alreay has a label that is the same as the input label%s",
195 this->_labels[inx] = new_label;
198 [[deprecated(
"Please use relabel_(const std::vector<std::string> &new_labels) instead.")]]
void
199 set_labels(
const std::vector<std::string> &new_labels);
200 void relabel_(
const std::vector<std::string> &new_labels);
201 [[deprecated(
"Please use relabel_(const std::vector<std::string> &new_labels) instead.")]]
void
202 relabels_(
const std::vector<std::string> &new_labels);
203 void relabel_(
const std::vector<std::string> &old_labels,
204 const std::vector<std::string> &new_labels);
206 "Please use relabel_(const std::vector<std::string> &old_labels, const "
207 "std::vector<std::string> &new_labels) instead.")]]
void
208 relabels_(
const std::vector<std::string> &old_labels,
209 const std::vector<std::string> &new_labels);
210 void relabel_(
const std::string &old_label,
const std::string &new_label) {
211 this->set_label(old_label, new_label);
213 void relabel_(
const cytnx_int64 &inx,
const std::string &new_label) {
214 this->set_label(inx, new_label);
217 int uten_type() {
return this->uten_type_id; }
218 std::string uten_type_str()
const {
return UTenType.getname(this->uten_type_id); }
223 virtual void Init(
const std::vector<Bond> &bonds,
224 const std::vector<std::string> &in_labels = {},
225 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
226 const int &device =
Device.cpu,
const bool &is_diag =
false,
227 const bool &no_alloc =
false,
const std::string &name =
"");
229 virtual void Init_by_Tensor(
const Tensor &in,
const bool &is_diag =
false,
230 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
231 virtual std::vector<cytnx_uint64> shape()
const;
232 virtual std::vector<bool> signflip()
const;
233 virtual std::vector<bool> &signflip_();
234 virtual bool is_blockform()
const;
235 virtual bool is_contiguous()
const;
236 virtual void to_(
const int &device);
237 virtual boost::intrusive_ptr<UniTensor_base> to(
const int &device);
238 virtual boost::intrusive_ptr<UniTensor_base> clone()
const;
239 virtual unsigned int dtype()
const;
240 virtual int device()
const;
241 virtual std::string dtype_str()
const;
242 virtual std::string device_str()
const;
243 virtual void set_rowrank_(
const cytnx_uint64 &new_rowrank);
244 virtual boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const;
246 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
247 const cytnx_int64 &rowrank = -1);
248 virtual boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
249 const cytnx_int64 &rowrank = -1);
253 virtual void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
254 virtual void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
256 virtual boost::intrusive_ptr<UniTensor_base> permute_nosignflip(
257 const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
258 virtual boost::intrusive_ptr<UniTensor_base> permute_nosignflip(
259 const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
260 virtual void permute_nosignflip_(
const std::vector<cytnx_int64> &mapper,
261 const cytnx_int64 &rowrank = -1);
262 virtual void permute_nosignflip_(
const std::vector<std::string> &mapper,
263 const cytnx_int64 &rowrank = -1);
267 virtual void twist_(
const cytnx_int64 &idx);
268 virtual void twist_(
const std::string &label);
269 virtual void fermion_twists_();
271 virtual boost::intrusive_ptr<UniTensor_base> contiguous_();
272 virtual boost::intrusive_ptr<UniTensor_base> contiguous();
273 virtual boost::intrusive_ptr<UniTensor_base> apply_();
274 virtual boost::intrusive_ptr<UniTensor_base> apply();
275 virtual void print_diagram(
const bool &bond_info =
false)
const;
276 virtual void print_blocks(
const bool &full_info =
true)
const;
277 virtual void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
279 virtual boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const;
281 virtual cytnx_uint64 Nblocks()
const {
return 0; };
282 virtual Tensor get_block(
const cytnx_uint64 &idx = 0)
const;
283 virtual Tensor get_block(
const std::vector<cytnx_int64> &qnum,
284 const bool &force)
const;
286 virtual const Tensor &get_block_(
const cytnx_uint64 &idx = 0)
288 virtual const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
289 const bool &force)
const;
290 virtual Tensor &get_block_(
const cytnx_uint64 &idx = 0);
292 virtual Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
294 virtual bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const;
296 virtual std::vector<Tensor> get_blocks()
const;
297 virtual const std::vector<Tensor> &get_blocks_(
const bool &)
const;
298 virtual std::vector<Tensor> &get_blocks_(
const bool &);
300 virtual void put_block(
const Tensor &in,
const cytnx_uint64 &idx = 0);
301 virtual void put_block_(Tensor &in,
const cytnx_uint64 &idx = 0);
302 virtual void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum);
303 virtual void put_block_(Tensor &in,
const std::vector<cytnx_int64> &qnum);
306 virtual boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
309 virtual void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
311 virtual void reshape_(
const std::vector<cytnx_int64> &new_shape,
312 const cytnx_uint64 &rowrank = 0);
313 virtual boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
314 const cytnx_uint64 &rowrank = 0);
315 virtual boost::intrusive_ptr<UniTensor_base> to_dense();
316 virtual void to_dense_();
317 virtual void combineBond(
const std::vector<std::string> &indicators,
const bool &force =
false);
318 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
319 const bool &by_label);
320 virtual void combineBonds(
const std::vector<std::string> &indicators,
321 const bool &force =
false);
322 virtual void combineBonds(
const std::vector<cytnx_int64> &indicators,
323 const bool &force =
false);
324 virtual boost::intrusive_ptr<UniTensor_base> contract(
325 const boost::intrusive_ptr<UniTensor_base> &rhs,
const bool &mv_elem_self =
false,
326 const bool &mv_elem_rhs =
false);
327 virtual std::vector<Bond> getTotalQnums(
const bool &physical =
false);
328 virtual std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const;
329 virtual void Trace_(
const std::string &a,
const std::string &b);
330 virtual void Trace_(
const cytnx_int64 &a,
const cytnx_int64 &b);
332 virtual boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b);
333 virtual boost::intrusive_ptr<UniTensor_base>
Trace(
const cytnx_int64 &a,
const cytnx_int64 &b);
335 virtual boost::intrusive_ptr<UniTensor_base> relabel(
336 const std::vector<std::string> &new_labels);
337 virtual boost::intrusive_ptr<UniTensor_base> relabels(
338 const std::vector<std::string> &new_labels);
340 virtual boost::intrusive_ptr<UniTensor_base> relabel(
341 const std::vector<std::string> &old_labels,
const std::vector<std::string> &new_labels);
342 virtual boost::intrusive_ptr<UniTensor_base> relabels(
343 const std::vector<std::string> &old_labels,
const std::vector<std::string> &new_labels);
345 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
346 const std::string &new_label);
348 virtual boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
349 const std::string &new_label);
351 virtual std::vector<Symmetry> syms()
const;
354 virtual void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
355 virtual void Add_(
const Scalar &rhs);
357 virtual void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
358 virtual void Mul_(
const Scalar &rhs);
360 virtual void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
361 virtual void Sub_(
const Scalar &rhs);
362 virtual void lSub_(
const Scalar &lhs);
364 virtual void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
365 virtual void Div_(
const Scalar &rhs);
366 virtual void lDiv_(
const Scalar &lhs);
368 virtual Tensor
Norm()
const;
369 virtual boost::intrusive_ptr<UniTensor_base> normalize();
370 virtual void normalize_();
372 virtual boost::intrusive_ptr<UniTensor_base>
Conj();
373 virtual void Conj_();
375 virtual boost::intrusive_ptr<UniTensor_base> Transpose();
376 virtual void Transpose_();
378 virtual boost::intrusive_ptr<UniTensor_base> Dagger();
379 virtual void Dagger_();
383 virtual void truncate_(
const std::string &label,
const cytnx_uint64 &dim);
384 virtual void truncate_(
const cytnx_int64 &bond_idx,
const cytnx_uint64 &dim);
386 virtual bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
389 virtual Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
390 virtual const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
392 virtual cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
393 const cytnx_complex128 &aux);
394 virtual cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
395 const cytnx_complex64 &aux);
396 virtual cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
397 const cytnx_double &aux);
398 virtual cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
399 const cytnx_float &aux);
400 virtual cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
401 const cytnx_uint64 &aux);
402 virtual cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
403 const cytnx_int64 &aux);
404 virtual cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
405 const cytnx_uint32 &aux);
406 virtual cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
407 const cytnx_int32 &aux);
408 virtual cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
409 const cytnx_uint16 &aux);
410 virtual cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
411 const cytnx_int16 &aux);
413 virtual const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
414 const cytnx_complex128 &aux)
const;
415 virtual const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
416 const cytnx_complex64 &aux)
const;
417 virtual const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
418 const cytnx_double &aux)
const;
419 virtual const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
420 const cytnx_float &aux)
const;
421 virtual const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
422 const cytnx_uint64 &aux)
const;
423 virtual const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
424 const cytnx_int64 &aux)
const;
425 virtual const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
426 const cytnx_uint32 &aux)
const;
427 virtual const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
428 const cytnx_int32 &aux)
const;
429 virtual const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
430 const cytnx_uint16 &aux)
const;
431 virtual const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
432 const cytnx_int16 &aux)
const;
434 virtual void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
bool force,
435 cytnx_double tol = 0.);
437 virtual void group_basis_();
438 virtual const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const;
439 virtual std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx);
440 virtual const vec2d<cytnx_uint64> &get_itoi()
const;
441 virtual vec2d<cytnx_uint64> &get_itoi();
443 virtual void _save_dispatch(std::fstream &f)
const;
444 virtual void _load_dispatch(std::fstream &f);
446 virtual ~UniTensor_base(){};
452 class DenseUniTensor :
public UniTensor_base {
456 std::vector<Tensor> _interface_block;
457 DenseUniTensor *clone_meta()
const {
458 DenseUniTensor *tmp =
new DenseUniTensor();
459 tmp->_bonds = vec_clone(this->_bonds);
460 tmp->_labels = this->_labels;
461 tmp->_is_braket_form = this->_is_braket_form;
462 tmp->_rowrank = this->_rowrank;
463 tmp->_is_diag = this->_is_diag;
464 tmp->_name = this->_name;
465 tmp->_is_tag = this->_is_tag;
470 DenseUniTensor() { this->uten_type_id =
UTenType.Dense; };
471 friend class UniTensor;
479 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
480 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
481 const int &device =
Device.cpu,
const bool &is_diag =
false,
482 const bool &no_alloc =
false,
const std::string &name =
"");
484 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
485 const cytnx_int64 &rowrank = -1,
const std::string &name =
"");
486 std::vector<cytnx_uint64> shape()
const {
487 if (this->_is_diag) {
488 std::vector<cytnx_uint64> shape = this->_block.shape();
489 shape.push_back(shape[0]);
492 return this->_block.shape();
495 bool is_blockform()
const {
return false; }
496 void to_(
const int &device) { this->_block.to_(device); }
497 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
498 if (this->device() == device) {
499 std::vector<Tensor> _interface_block;
502 boost::intrusive_ptr<UniTensor_base> out = this->clone();
507 void set_rowrank_(
const cytnx_uint64 &new_rowrank) {
509 "[ERROR] rowrank cannot exceed the rank of UniTensor.%s",
"\n");
510 if (this->is_diag()) {
511 cytnx_error_msg(new_rowrank != 1,
"[ERROR] rowrank should be [==1] when is_diag =true!.%s",
515 this->_rowrank = new_rowrank;
518 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
519 DenseUniTensor *out_raw = this->clone_meta();
520 out_raw->_block = this->_block;
521 out_raw->set_rowrank_(new_rowrank);
522 boost::intrusive_ptr<UniTensor_base> out(out_raw);
526 boost::intrusive_ptr<UniTensor_base> clone()
const {
527 DenseUniTensor *tmp = this->clone_meta();
528 tmp->_block = this->_block.clone();
529 boost::intrusive_ptr<UniTensor_base> out(tmp);
532 bool is_contiguous()
const {
return this->_block.is_contiguous(); }
533 unsigned int dtype()
const {
return this->_block.dtype(); }
534 int device()
const {
return this->_block.device(); }
535 std::string dtype_str()
const {
return Type.getname(this->_block.dtype()); }
536 std::string device_str()
const {
return Device.getname(this->_block.device()); }
546 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
547 const cytnx_int64 &rowrank = -1);
548 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
549 const cytnx_int64 &rowrank = -1);
559 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
560 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
562 void twist_(
const cytnx_int64 &idx)
override {
566 void twist_(
const std::string &label)
override {
571 void fermion_twists_()
override {
576 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &new_labels);
577 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
579 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &old_labels,
580 const std::vector<std::string> &new_labels);
581 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
582 const std::vector<std::string> &new_labels);
594 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
595 const std::string &new_label);
596 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
597 const std::string &new_label);
599 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
600 DenseUniTensor *tmp = this->clone_meta();
601 tmp->_block = this->_block.astype(dtype);
602 boost::intrusive_ptr<UniTensor_base> out(tmp);
606 std::vector<Symmetry> syms()
const {
607 cytnx_error_msg(
true,
"[ERROR][DenseUniTensor] dense unitensor does not have symmetry.%s",
609 return std::vector<Symmetry>();
612 boost::intrusive_ptr<UniTensor_base> contiguous_() {
613 this->_block.contiguous_();
614 return boost::intrusive_ptr<UniTensor_base>(
this);
616 boost::intrusive_ptr<UniTensor_base> contiguous() {
618 if (this->is_contiguous()) {
619 boost::intrusive_ptr<UniTensor_base> out(
this);
622 DenseUniTensor *tmp = this->clone_meta();
623 tmp->_block = this->_block.contiguous();
624 boost::intrusive_ptr<UniTensor_base> out(tmp);
629 boost::intrusive_ptr<UniTensor_base> apply_() {
630 return boost::intrusive_ptr<UniTensor_base>(
this);
632 boost::intrusive_ptr<UniTensor_base> apply() {
634 boost::intrusive_ptr<UniTensor_base> out(
this);
638 void print_diagram(
const bool &bond_info =
false)
const;
639 void print_blocks(
const bool &full_info =
true)
const;
640 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
641 Tensor get_block()
const {
return this->_block.clone(); }
642 Tensor get_block(
const cytnx_uint64 &idx)
const {
644 "[ERROR][DenseUniTensor] Dense tensor has only one block, block number %llu "
645 "invalid. Use get_block(0).\n",
646 (
unsigned long long)idx);
647 return this->_block.clone();
650 Tensor get_block(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
652 true,
"[ERROR][DenseUniTensor] try to get_block() using qnum on a non-symmetry UniTensor%s",
657 const Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force)
const {
660 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
664 Tensor &get_block_(
const std::vector<cytnx_int64> &qnum,
const bool &force) {
667 "[ERROR][DenseUniTensor] try to get_block_() using qnum on a non-symmetry UniTensor%s",
673 Tensor &get_block_() {
return this->_block; }
674 Tensor &get_block_(
const cytnx_uint64 &idx) {
676 "[ERROR][DenseUniTensor] Dense tensor has only one block, block number %llu "
677 "invalid. Use get_block_(0).\n",
678 (
unsigned long long)idx);
682 const Tensor &get_block_()
const {
return this->_block; }
683 const Tensor &get_block_(
const cytnx_uint64 &idx)
const {
685 "[ERROR][DenseUniTensor] Dense tensor has only one block, block number %llu "
686 "invalid. Use get_block_(0).\n",
687 (
unsigned long long)idx);
691 cytnx_uint64 Nblocks()
const {
return 1; };
692 std::vector<Tensor> get_blocks()
const {
693 std::vector<Tensor> out;
695 true,
"[ERROR][DenseUniTensor] Cannot use get_blocks(), use get_block() instead!%s",
"\n");
698 const std::vector<Tensor> &get_blocks_(
const bool &silent =
false)
const {
700 true,
"[ERROR][DenseUniTensor] Cannot use get_blocks_(), use get_block_() instead!%s",
702 return this->_interface_block;
704 std::vector<Tensor> &get_blocks_(
const bool &silent =
false) {
706 true,
"[ERROR][DenseUniTensor] Cannot use get_blocks_(), use get_block_() instead!%s",
708 return this->_interface_block;
711 void put_block(
const Tensor &in) {
720 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
725 if (this->is_diag()) {
727 in.shape() != this->_block.shape(),
728 "[ERROR][DenseUniTensor][put_block] the input tensor shape does not match.%s",
"\n");
729 this->_block = in.clone();
732 in.shape() != this->shape(),
733 "[ERROR][DenseUniTensor][put_block] the input tensor shape does not match.%s",
"\n");
734 this->_block = in.clone();
737 void put_block(
const Tensor &in,
const cytnx_uint64 &idx) {
739 "[ERROR][DenseUniTensor] Dense tensor has only one block, block number %llu "
740 "invalid. Use put_block(0).\n",
741 (
unsigned long long)idx);
745 void put_block_(Tensor &in) {
754 "[ERROR][DenseUniTensor][put_block] The input tensor device does not "
759 if (this->is_diag()) {
761 in.shape() != this->_block.shape(),
762 "[ERROR][DenseUniTensor][put_block] the input tensor shape does not match.%s",
"\n");
766 in.shape() != this->shape(),
767 "[ERROR][DenseUniTensor][put_block] the input tensor shape does not match.%s",
"\n");
771 void put_block_(Tensor &in,
const cytnx_uint64 &idx) {
773 "[ERROR][DenseUniTensor] Dense tensor has only one block, block number %llu "
774 "invalid. Use put_block_(0).\n",
775 (
unsigned long long)idx);
779 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &qnum) {
781 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
784 void put_block_(Tensor &in,
const std::vector<cytnx_int64> &qnum) {
786 true,
"[ERROR][DenseUniTensor] try to put_block using qnum on a non-symmetry UniTensor%s",
790 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors);
791 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs);
793 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0);
794 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
795 const cytnx_uint64 &rowrank = 0);
796 boost::intrusive_ptr<UniTensor_base> to_dense();
798 void combineBond(
const std::vector<std::string> &indicators,
const bool &force =
true);
799 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
800 const bool &by_label);
801 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
true);
802 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
true);
803 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
804 const bool &mv_elem_self =
false,
805 const bool &mv_elem_rhs =
false);
806 std::vector<Bond> getTotalQnums(
const bool &physical =
false) {
808 "getTotalQnums can only operate on UniTensor with symmetry.\n");
809 return std::vector<Bond>();
812 std::vector<std::vector<cytnx_int64>> get_blocks_qnums()
const {
814 "get_blocks_qnums can only operate on UniTensor with symmetry.\n");
815 return std::vector<std::vector<cytnx_int64>>();
818 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
819 if (rhs->uten_type() !=
UTenType.Dense)
return false;
821 return this->get_block_().same_data(rhs->get_block_());
827 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
828 void Add_(
const Scalar &rhs);
830 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
831 void Mul_(
const Scalar &rhs);
833 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
834 void Sub_(
const Scalar &rhs);
835 void lSub_(
const Scalar &lhs);
837 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
838 void Div_(
const Scalar &rhs);
839 void lDiv_(
const Scalar &lhs);
841 void Conj_() { this->_block.Conj_(); };
843 boost::intrusive_ptr<UniTensor_base>
Conj() {
844 boost::intrusive_ptr<UniTensor_base> out = this->clone();
849 boost::intrusive_ptr<UniTensor_base> Transpose() {
850 boost::intrusive_ptr<UniTensor_base> out = this->clone();
856 boost::intrusive_ptr<UniTensor_base> normalize() {
857 boost::intrusive_ptr<UniTensor_base> out = this->clone();
863 boost::intrusive_ptr<UniTensor_base> Dagger() {
864 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
881 void Trace_(
const cytnx_int64 &a,
const cytnx_int64 &b);
882 void Trace_(
const std::string &a,
const std::string &b);
883 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
884 boost::intrusive_ptr<UniTensor_base> out = this->clone();
888 boost::intrusive_ptr<UniTensor_base>
Trace(
const cytnx_int64 &a,
const cytnx_int64 &b) {
889 boost::intrusive_ptr<UniTensor_base> out = this->clone();
896 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const {
898 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
900 return Scalar::Sproxy();
902 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
903 const cytnx_complex128 &aux)
const {
905 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
907 return cytnx_complex128(0, 0);
909 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
910 const cytnx_complex64 &aux)
const {
912 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
914 return cytnx_complex64(0, 0);
916 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
917 const cytnx_double &aux)
const {
919 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
923 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
924 const cytnx_float &aux)
const {
926 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
930 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
931 const cytnx_uint64 &aux)
const {
933 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
937 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
938 const cytnx_int64 &aux)
const {
940 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
944 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
945 const cytnx_uint32 &aux)
const {
947 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
951 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
952 const cytnx_int32 &aux)
const {
954 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
958 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
959 const cytnx_uint16 &aux)
const {
961 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
965 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
966 const cytnx_int16 &aux)
const {
968 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
973 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator) {
975 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
977 return Scalar::Sproxy();
979 cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
980 const cytnx_complex128 &aux) {
982 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
984 return *(cytnx_complex128 *)
nullptr;
986 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
987 const cytnx_complex64 &aux) {
989 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
991 return *(cytnx_complex64 *)
nullptr;
993 cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_double &aux) {
995 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
997 return *(cytnx_double *)
nullptr;
999 cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux) {
1001 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1003 return *(cytnx_float *)
nullptr;
1005 cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint64 &aux) {
1007 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1009 return *(cytnx_uint64 *)
nullptr;
1011 cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux) {
1013 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1015 return *(cytnx_int64 *)
nullptr;
1017 cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint32 &aux) {
1019 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1021 return *(cytnx_uint32 *)
nullptr;
1023 cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux) {
1025 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1027 return *(cytnx_int32 *)
nullptr;
1029 cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint16 &aux) {
1031 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1033 return *(cytnx_uint16 *)
nullptr;
1035 cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux) {
1037 true,
"[ERROR][Internal] This shouldn't be called by DenseUniTensor, something wrong.%s",
1039 return *(cytnx_int16 *)
nullptr;
1042 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const {
1044 true,
"[ERROR][DenseUniTensor] elem_exists can only be used on UniTensor with Symmetry.%s",
1048 if (!this->is_tag()) {
1049 for (
int i = 0; i < this->_rowrank; i++) {
1050 this->_bonds[i].set_type(BD_KET);
1052 for (
int i = this->_rowrank; i < this->_bonds.size(); i++) {
1053 this->_bonds[i].set_type(BD_BRA);
1055 this->_is_tag =
true;
1056 this->_is_braket_form = this->_update_braket();
1068 void truncate_(
const cytnx_int64 &bond_idx,
const cytnx_uint64 &dim);
1069 void truncate_(
const std::string &label,
const cytnx_uint64 &dim);
1071 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
bool force, cytnx_double tol = 0.);
1073 void group_basis_() {
1074 cytnx_warning_msg(
true,
"[WARNING] group basis will not have any effect on DensUniTensor.%s",
1078 void _save_dispatch(std::fstream &f)
const;
1079 void _load_dispatch(std::fstream &f);
1081 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
1082 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
1085 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
1086 cytnx_error_msg(
true,
"[ERROR] get_qindices can only be unsed on UniTensor with Symmetry.%s",
1090 const vec2d<cytnx_uint64> &get_itoi()
const {
1091 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
1094 vec2d<cytnx_uint64> &get_itoi() {
1095 cytnx_error_msg(
true,
"[ERROR] get_itoi can only be unsed on UniTensor with Symmetry.%s",
1105 class BlockUniTensor :
public UniTensor_base {
1108 std::vector<std::vector<cytnx_uint64>>
1109 _inner_to_outer_idx;
1110 std::vector<Tensor> _blocks;
1111 Tensor NullRefTensor;
1116 void _fx_get_total_fluxs(std::vector<cytnx_uint64> &loc,
const std::vector<Symmetry> &syms,
1117 std::vector<cytnx_int64> &total_qns) {
1118 memset(&total_qns[0], 0,
sizeof(cytnx_int64) * total_qns.size());
1120 for (cytnx_int32 i = 0; i < syms.size(); i++) {
1121 if (this->_bonds[0].type() == BD_BRA)
1122 total_qns[i] = syms[i].reverse_rule(this->_bonds[0]._impl->_qnums[loc[0]][i]);
1124 total_qns[i] = this->_bonds[0]._impl->_qnums[loc[0]][i];
1126 for (
auto j = 1; j < loc.size(); j++) {
1127 if (this->_bonds[j].type() == BD_BRA)
1128 total_qns[i] = syms[i].combine_rule(
1129 total_qns[i], syms[i].reverse_rule(this->_bonds[j]._impl->_qnums[loc[j]][i]));
1132 syms[i].combine_rule(total_qns[i], this->_bonds[j]._impl->_qnums[loc[j]][i]);
1138 void _fx_locate_elem(cytnx_int64 &bidx, std::vector<cytnx_uint64> &loc_in_T,
1139 const std::vector<cytnx_uint64> &locator)
const;
1142 void _fx_group_duplicates(
const std::vector<cytnx_uint64> &dup_bond_idxs,
1143 const std::vector<std::vector<cytnx_uint64>> &idx_mappers);
1145 void set_meta(BlockUniTensor *tmp,
const bool &inner,
const bool &outer)
const {
1148 tmp->_bonds = vec_clone(this->_bonds);
1149 tmp->_labels = this->_labels;
1150 tmp->_is_braket_form = this->_is_braket_form;
1151 tmp->_rowrank = this->_rowrank;
1152 tmp->_name = this->_name;
1155 tmp->_is_diag = this->_is_diag;
1159 tmp->_inner_to_outer_idx = this->_inner_to_outer_idx;
1163 BlockUniTensor *clone_meta(
const bool &inner,
const bool &outer)
const {
1164 BlockUniTensor *tmp =
new BlockUniTensor();
1165 this->set_meta(tmp, inner, outer);
1169 friend class UniTensor;
1171 this->uten_type_id =
UTenType.Block;
1172 this->_is_tag =
true;
1181 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
1182 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
1183 const int &device =
Device.cpu,
const bool &is_diag =
false,
1184 const bool &no_alloc =
false,
const std::string &name =
"");
1186 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
1187 const cytnx_int64 &rowrank = -1,
const std::string &name =
"") {
1189 true,
"[ERROR][BlockUniTensor] Cannot use Init_by_tensor() on a BlockUniTensor.%s",
"\n");
1192 std::vector<cytnx_uint64> shape()
const {
1193 std::vector<cytnx_uint64> out(this->_bonds.size());
1194 for (cytnx_uint64 i = 0; i < out.size(); i++) {
1195 out[i] = this->_bonds[i].dim();
1200 bool is_blockform()
const {
return true; }
1201 bool is_contiguous()
const {
1203 for (
int i = 0; i < this->_blocks.size(); i++) {
1204 out &= this->_blocks[i].is_contiguous();
1209 cytnx_uint64 Nblocks()
const {
return this->_blocks.size(); };
1211 void to_(
const int &device) {
1212 for (cytnx_uint64 i = 0; i < this->_blocks.size(); i++) {
1213 this->_blocks[i].to_(device);
1217 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
1218 if (this->device() == device) {
1221 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1227 boost::intrusive_ptr<UniTensor_base> clone()
const {
1228 BlockUniTensor *tmp = this->clone_meta(
true,
true);
1229 tmp->_blocks = vec_clone(this->_blocks);
1230 boost::intrusive_ptr<UniTensor_base> out(tmp);
1234 unsigned int dtype()
const {
1237 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1240 return this->_blocks.size() < 1 ?
Type.Void : this->_blocks[0].dtype();
1242 int device()
const {
1245 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1248 return this->_blocks.size() < 1 ? -404 : this->_blocks[0].device();
1250 std::string dtype_str()
const {
1253 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1256 return this->_blocks.size() < 1 ?
"Void, no valid blocks" : this->_blocks[0].dtype_str();
1258 std::string device_str()
const {
1261 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1264 return this->_blocks.size() < 1 ?
"None, no valid blocks" : this->_blocks[0].device_str();
1267 Tensor get_block(
const cytnx_uint64 &idx = 0)
const {
1268 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1270 return this->_blocks[idx].clone();
1274 Tensor get_block(
const std::vector<cytnx_int64> &indices,
const bool &force_return)
const {
1276 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1277 "Tensor rank (number of legs).%s",
1280 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1284 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1285 if (inds == this->_inner_to_outer_idx[i]) {
1293 return NullRefTensor;
1296 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1297 "force_return=false, so "
1298 "error throws. \n If you want to return an empty block without "
1299 "error when block is "
1300 "not avaliable, set force_return=True.%s",
1304 return this->_blocks[b].clone();
1308 const Tensor &get_block_(
const cytnx_uint64 &idx = 0)
const {
1309 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1311 return this->_blocks[idx];
1314 Tensor &get_block_(
const cytnx_uint64 &idx = 0) {
1315 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1317 return this->_blocks[idx];
1320 const Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
1321 const bool &force_return)
const {
1323 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1324 "Tensor rank (number of legs).%s",
1327 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1331 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1332 if (inds == this->_inner_to_outer_idx[i]) {
1340 return this->NullRefTensor;
1343 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1344 "force_return=false, so "
1345 "error throws. \n If you want to return an empty block without "
1346 "error when block is "
1347 "not avaliable, set force_return=True.%s",
1351 return this->_blocks[b];
1355 Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
const bool &force_return) {
1357 "[ERROR][get_block][BlockUniTensor] len(indices) must be the same as the "
1358 "Tensor rank (number of legs).%s",
1361 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1365 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1366 if (inds == this->_inner_to_outer_idx[i]) {
1374 return this->NullRefTensor;
1377 "[ERROR][get_block][BlockUniTensor] no avaliable block exists, "
1378 "force_return=false, so "
1379 "error throws. \n If you want to return an empty block without "
1380 "error when block is "
1381 "not avaliable, set force_return=True.%s",
1385 return this->_blocks[b];
1389 std::vector<Tensor> get_blocks()
const {
return vec_clone(this->_blocks); }
1390 const std::vector<Tensor> &get_blocks_(
const bool &)
const {
return this->_blocks; }
1391 std::vector<Tensor> &get_blocks_(
const bool &) {
return this->_blocks; }
1393 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
1394 if (rhs->uten_type() !=
UTenType.Block)
return false;
1395 if (rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
1397 for (
int i = 0; i < rhs->get_blocks_(1).size(); i++)
1398 if (this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i]) ==
false)
return false;
1403 void set_rowrank_(
const cytnx_uint64 &new_rowrank) {
1405 "[ERROR][BlockUniTensor] rowrank should be [>=0] and [<=UniTensor.rank].%s",
1407 if (this->is_diag()) {
1409 "[ERROR][BlockUniTensor] rowrank should be [==1] when is_diag =true!.%s",
1412 this->_rowrank = new_rowrank;
1413 this->_is_braket_form = this->_update_braket();
1416 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
1417 BlockUniTensor *tmp = this->clone_meta(
true,
true);
1418 tmp->_blocks = this->_blocks;
1419 tmp->set_rowrank_(new_rowrank);
1420 boost::intrusive_ptr<UniTensor_base> out(tmp);
1424 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
1425 const cytnx_int64 &rowrank = -1);
1426 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
1427 const cytnx_int64 &rowrank = -1);
1429 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1);
1430 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1);
1432 void twist_(
const cytnx_int64 &idx)
override {
1436 void fermion_twists_()
override {
1440 void twist_(
const std::string &label)
override {
1445 boost::intrusive_ptr<UniTensor_base> contiguous_() {
1446 for (
unsigned int b = 0; b < this->_blocks.size(); b++) this->_blocks[b].contiguous_();
1447 return boost::intrusive_ptr<UniTensor_base>(
this);
1449 boost::intrusive_ptr<UniTensor_base> contiguous();
1451 boost::intrusive_ptr<UniTensor_base> apply_() {
1452 return boost::intrusive_ptr<UniTensor_base>(
this);
1454 boost::intrusive_ptr<UniTensor_base> apply() {
1456 boost::intrusive_ptr<UniTensor_base> out(
this);
1460 void print_diagram(
const bool &bond_info =
false)
const;
1461 void print_blocks(
const bool &full_info =
true)
const;
1462 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
1464 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
1465 const bool &mv_elem_self =
false,
1466 const bool &mv_elem_rhs =
false);
1468 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &new_labels);
1469 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
1471 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &old_labels,
1472 const std::vector<std::string> &new_labels);
1473 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
1474 const std::vector<std::string> &new_labels);
1476 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
1477 const std::string &new_label);
1478 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
1479 const std::string &new_label);
1481 std::vector<Symmetry> syms()
const;
1483 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0) {
1484 cytnx_error_msg(
true,
"[ERROR] Cannot reshape a UniTensor with symmetry.%s",
"\n");
1486 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
1487 const cytnx_uint64 &rowrank = 0) {
1488 cytnx_error_msg(
true,
"[ERROR] Cannot reshape a UniTensor with symmetry.%s",
"\n");
1492 boost::intrusive_ptr<UniTensor_base> to_dense();
1495 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
1496 BlockUniTensor *tmp = this->clone_meta(
true,
true);
1497 tmp->_blocks.resize(this->_blocks.size());
1498 for (cytnx_int64 blk = 0; blk < this->_blocks.size(); blk++) {
1499 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
1501 boost::intrusive_ptr<UniTensor_base> out(tmp);
1506 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
1509 "[ERROR][BlockUniTensor][get] Cannot use get on a UniTensor with "
1510 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
1516 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
1519 "[ERROR][BlockUniTensor][get] Cannot use get on a UniTensor with "
1520 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
1524 void put_block(
const Tensor &in,
const cytnx_uint64 &idx = 0) {
1526 "[ERROR][BlockUniTensor][put_block] The input tensor dtype does not match.%s",
1529 "[ERROR][BlockUniTensor][put_block] The input tensor device does not "
1534 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1537 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1538 "of block @ idx=%d\n",
1541 this->_blocks[idx] = in.clone();
1543 void put_block_(Tensor &in,
const cytnx_uint64 &idx = 0) {
1545 "[ERROR][BlockUniTensor][put_block] The input tensor dtype does not match.%s",
1548 "[ERROR][BlockUniTensor][put_block] The input tensor device does not "
1553 cytnx_error_msg(idx >= this->_blocks.size(),
"[ERROR][BlockUniTensor] index out of range%s",
1556 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1557 "of block @ idx=%d\n",
1560 this->_blocks[idx] = in;
1562 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &indices) {
1564 "[ERROR][BlockUniTensor][put_block] The input tensor dtype does not match.%s",
1567 "[ERROR][BlockUniTensor][put_block] The input tensor device does not "
1573 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1574 "Tensor rank (number of legs).%s",
1577 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1581 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1582 if (inds == this->_inner_to_outer_idx[i]) {
1589 cytnx_error_msg(
true,
"[ERROR][put_block][BlockUniTensor] no avaliable block exists.%s",
1593 in.shape() != this->_blocks[b].shape(),
1594 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1595 "of block @ idx=%d\n",
1598 this->_blocks[b] = in.clone();
1601 void put_block_(Tensor &in,
const std::vector<cytnx_int64> &indices) {
1603 "[ERROR][BlockUniTensor][put_block] The input tensor dtype does not match.%s",
1606 "[ERROR][BlockUniTensor][put_block] The input tensor device does not "
1612 "[ERROR][put_block][BlockUniTensor] len(indices) must be the same as the "
1613 "Tensor rank (number of legs).%s",
1616 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
1620 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
1621 if (inds == this->_inner_to_outer_idx[i]) {
1628 cytnx_error_msg(
true,
"[ERROR][put_block][BlockUniTensor] no avaliable block exists.%s",
1632 in.shape() != this->_blocks[b].shape(),
1633 "[ERROR][BlockUniTensor] the shape of input tensor does not match the shape "
1634 "of block @ idx=%d\n",
1636 this->_blocks[b] = in;
1644 boost::intrusive_ptr<UniTensor_base>
Conj() {
1645 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1651 for (
int i = 0; i < this->_blocks.size(); i++) {
1652 this->_blocks[i].Conj_();
1657 boost::intrusive_ptr<UniTensor_base> Transpose() {
1658 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1664 boost::intrusive_ptr<UniTensor_base> normalize() {
1665 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1670 boost::intrusive_ptr<UniTensor_base> Dagger() {
1671 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
1680 void Trace_(
const std::string &a,
const std::string &b);
1681 void Trace_(
const cytnx_int64 &a,
const cytnx_int64 &b);
1683 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
1684 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1686 if (out->rank() == 0) {
1687 DenseUniTensor *tmp =
new DenseUniTensor();
1688 tmp->_block = ((BlockUniTensor *)out.get())->_blocks[0];
1689 out = boost::intrusive_ptr<UniTensor_base>(tmp);
1693 boost::intrusive_ptr<UniTensor_base>
Trace(
const cytnx_int64 &a,
const cytnx_int64 &b) {
1694 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1696 if (out->rank() == 0) {
1697 DenseUniTensor *tmp =
new DenseUniTensor();
1698 tmp->_block = ((BlockUniTensor *)out.get())->_blocks[0];
1699 out = boost::intrusive_ptr<UniTensor_base>(tmp);
1704 Tensor
Norm()
const;
1706 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
1708 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
1709 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1710 const cytnx_complex128 &aux)
const;
1711 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1712 const cytnx_complex64 &aux)
const;
1713 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1714 const cytnx_double &aux)
const;
1715 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1716 const cytnx_float &aux)
const;
1717 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1718 const cytnx_uint64 &aux)
const;
1719 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1720 const cytnx_int64 &aux)
const;
1721 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1722 const cytnx_uint32 &aux)
const;
1723 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1724 const cytnx_int32 &aux)
const;
1725 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1726 const cytnx_uint16 &aux)
const;
1727 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1728 const cytnx_int16 &aux)
const;
1730 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
1731 cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1732 const cytnx_complex128 &aux);
1733 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
1734 const cytnx_complex64 &aux);
1735 cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_double &aux);
1736 cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux);
1737 cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint64 &aux);
1738 cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux);
1739 cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint32 &aux);
1740 cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux);
1741 cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint16 &aux);
1742 cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux);
1744 void _save_dispatch(std::fstream &f)
const;
1745 void _load_dispatch(std::fstream &f);
1748 void truncate_(
const std::string &label,
const cytnx_uint64 &q_index);
1749 void truncate_(
const cytnx_int64 &bond_idx,
const cytnx_uint64 &q_index);
1751 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1752 void Add_(
const Scalar &rhs) {
1755 "[ERROR] Cannot perform elementwise arithmetic '+' between Scalar and BlockUniTensor.\n %s "
1757 "This operation would destroy the block structure. [Suggest] Avoid or use get/put_block(s) "
1758 "to do operation on blocks.");
1761 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1762 void Mul_(
const Scalar &rhs);
1764 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1765 void Sub_(
const Scalar &rhs) {
1768 "[ERROR] Cannot perform elementwise arithmetic '-' between Scalar and BlockUniTensor.\n %s "
1770 "This operation would destroy the block structure. [Suggest] Avoid or use get/put_block(s) "
1771 "to do operation on blocks.");
1773 void lSub_(
const Scalar &lhs) {
1776 "[ERROR] Cannot perform elementwise arithmetic '-' between Scalar and BlockUniTensor.\n %s "
1778 "This operation would destroy the block structure. [Suggest] Avoid or use get/put_block(s) "
1779 "to do operation on blocks.");
1782 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
1783 void Div_(
const Scalar &rhs);
1784 void lDiv_(
const Scalar &lhs) {
1787 "[ERROR] Cannot perform elementwise arithmetic '/' between Scalar and BlockUniTensor.\n %s "
1789 "This operation would cause division by zero on non-block elements. [Suggest] Avoid or use "
1790 "get/put_block(s) to do operation on blocks.");
1792 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
bool force, cytnx_double tol = 0.);
1794 void group_basis_();
1796 void combineBond(
const std::vector<std::string> &indicators,
const bool &force =
false);
1797 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
false);
1798 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
1799 const bool &by_label);
1800 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
false);
1802 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
1804 bidx >= this->Nblocks(),
1805 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1807 return this->_inner_to_outer_idx[bidx];
1809 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
1811 bidx >= this->Nblocks(),
1812 "[ERROR][BlockUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
1814 return this->_inner_to_outer_idx[bidx];
1817 const vec2d<cytnx_uint64> &get_itoi()
const {
return this->_inner_to_outer_idx; }
1818 vec2d<cytnx_uint64> &get_itoi() {
return this->_inner_to_outer_idx; }
1824 class BlockFermionicUniTensor :
public UniTensor_base {
1828 std::vector<std::vector<cytnx_uint64>>
1829 _inner_to_outer_idx;
1830 std::vector<Tensor> _blocks;
1831 Tensor NullRefTensor;
1833 std::vector<cytnx_bool>
1839 void _fx_get_total_fluxs(std::vector<cytnx_uint64> &loc,
const std::vector<Symmetry> &syms,
1840 std::vector<cytnx_int64> &total_qns) {
1842 memset(&total_qns[0], 0,
sizeof(cytnx_int64) * total_qns.size());
1844 for (cytnx_int32 i = 0; i < syms.size(); i++) {
1845 if (this->_bonds[0].type() == BD_BRA)
1846 total_qns[i] = syms[i].reverse_rule(this->_bonds[0]._impl->_qnums[loc[0]][i]);
1848 total_qns[i] = this->_bonds[0]._impl->_qnums[loc[0]][i];
1850 for (
auto j = 1; j < loc.size(); j++) {
1851 if (this->_bonds[j].type() == BD_BRA)
1852 total_qns[i] = syms[i].combine_rule(
1853 total_qns[i], syms[i].reverse_rule(this->_bonds[j]._impl->_qnums[loc[j]][i]));
1856 syms[i].combine_rule(total_qns[i], this->_bonds[j]._impl->_qnums[loc[j]][i]);
1862 void _fx_locate_elem(cytnx_int64 &bidx, std::vector<cytnx_uint64> &loc_in_T,
1863 const std::vector<cytnx_uint64> &locator)
const;
1866 void _fx_group_duplicates(
const std::vector<cytnx_uint64> &dup_bond_idxs,
1867 const std::vector<std::vector<cytnx_uint64>> &idx_mappers);
1869 void set_meta(BlockFermionicUniTensor *tmp,
const bool &inner,
const bool &outer)
const {
1873 tmp->_bonds = vec_clone(this->_bonds);
1874 tmp->_labels = this->_labels;
1875 tmp->_is_braket_form = this->_is_braket_form;
1876 tmp->_rowrank = this->_rowrank;
1877 tmp->_name = this->_name;
1879 tmp->_signflip = this->_signflip;
1882 tmp->_is_diag = this->_is_diag;
1886 tmp->_inner_to_outer_idx = this->_inner_to_outer_idx;
1890 BlockFermionicUniTensor *clone_meta(
const bool &inner,
const bool &outer)
const {
1892 BlockFermionicUniTensor *tmp =
new BlockFermionicUniTensor();
1893 this->set_meta(tmp, inner, outer);
1897 friend class UniTensor;
1898 BlockFermionicUniTensor() {
1900 this->uten_type_id =
UTenType.BlockFermionic;
1901 this->_is_tag =
true;
1904 void Init(
const std::vector<Bond> &bonds,
const std::vector<std::string> &in_labels = {},
1905 const cytnx_int64 &rowrank = -1,
const unsigned int &dtype =
Type.Double,
1906 const int &device =
Device.cpu,
const bool &is_diag =
false,
1907 const bool &no_alloc =
false,
const std::string &name =
"");
1909 void Init_by_Tensor(
const Tensor &in_tensor,
const bool &is_diag =
false,
1910 const cytnx_int64 &rowrank = -1,
const std::string &name =
"") {
1912 "[ERROR][BlockFermionicUniTensor] Cannot use Init_by_tensor() on a "
1913 "BlockFermionicUniTensor.%s",
1917 std::vector<cytnx_uint64> shape()
const {
1919 std::vector<cytnx_uint64> out(this->_bonds.size());
1920 for (cytnx_uint64 i = 0; i < out.size(); i++) {
1921 out[i] = this->_bonds[i].dim();
1926 bool is_blockform()
const {
1931 bool is_contiguous()
const {
1934 for (
int i = 0; i < this->_blocks.size(); i++) {
1935 out &= this->_blocks[i].is_contiguous();
1940 cytnx_uint64 Nblocks()
const {
1942 return this->_blocks.size();
1945 std::vector<bool> signflip()
const override {
return this->_signflip; };
1946 std::vector<bool> &signflip_()
override {
return this->_signflip; };
1948 void to_(
const int &device) {
1950 for (cytnx_uint64 i = 0; i < this->_blocks.size(); i++) {
1951 this->_blocks[i].to_(device);
1955 boost::intrusive_ptr<UniTensor_base> to(
const int &device) {
1957 if (this->device() == device) {
1960 boost::intrusive_ptr<UniTensor_base> out = this->clone();
1966 boost::intrusive_ptr<UniTensor_base> clone()
const {
1969 BlockFermionicUniTensor *tmp = this->clone_meta(
true,
true);
1970 tmp->_blocks = vec_clone(this->_blocks);
1971 boost::intrusive_ptr<UniTensor_base> out(tmp);
1975 unsigned int dtype()
const {
1978 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1981 return this->_blocks.size() < 1 ?
Type.Void : this->_blocks[0].dtype();
1983 int device()
const {
1986 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1989 return this->_blocks.size() < 1 ? -404 : this->_blocks[0].device();
1991 std::string dtype_str()
const {
1994 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
1997 return this->_blocks.size() < 1 ?
"Void, no valid blocks" : this->_blocks[0].dtype_str();
1999 std::string device_str()
const {
2002 cytnx_error_msg(this->_blocks.size() == 0,
"[ERROR][internal] empty blocks for blockform.%s",
2005 return this->_blocks.size() < 1 ?
"None, no valid blocks" : this->_blocks[0].device_str();
2008 Tensor get_block(
const cytnx_uint64 &idx = 0)
const {
2011 "[ERROR][BlockFermionicUniTensor] index out of range%s",
"\n");
2012 return this->_blocks[idx].clone();
2016 Tensor get_block(
const std::vector<cytnx_int64> &indices,
const bool &force_return)
const {
2019 indices.size() != this->rank(),
2020 "[ERROR][get_block][BlockFermionicUniTensor] len(indices) must be the same as the "
2021 "Tensor rank (number of legs).%s",
2024 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
2028 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
2029 if (inds == this->_inner_to_outer_idx[i]) {
2037 return NullRefTensor;
2040 "[ERROR][get_block][BlockFermionicUniTensor] no avaliable block exists, "
2041 "force_return=false, so "
2042 "error throws. \n If you want to return an empty block without "
2043 "error when block is "
2044 "not avaliable, set force_return=True.%s",
2048 return this->_blocks[b].clone();
2052 const Tensor &get_block_(
const cytnx_uint64 &idx = 0)
const {
2055 "[ERROR][BlockFermionicUniTensor] index out of range%s",
"\n");
2056 return this->_blocks[idx];
2059 Tensor &get_block_(
const cytnx_uint64 &idx = 0) {
2062 "[ERROR][BlockFermionicUniTensor] index out of range%s",
"\n");
2063 return this->_blocks[idx];
2066 const Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
2067 const bool &force_return)
const {
2070 indices.size() != this->rank(),
2071 "[ERROR][get_block][BlockFermionicUniTensor] len(indices) must be the same as the "
2072 "Tensor rank (number of legs).%s",
2075 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
2079 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
2080 if (inds == this->_inner_to_outer_idx[i]) {
2088 return this->NullRefTensor;
2091 "[ERROR][get_block][BlockFermionicUniTensor] no avaliable block exists, "
2092 "force_return=false, so "
2093 "error throws. \n If you want to return an empty block without "
2094 "error when block is "
2095 "not avaliable, set force_return=True.%s",
2099 return this->_blocks[b];
2103 Tensor &get_block_(
const std::vector<cytnx_int64> &indices,
const bool &force_return) {
2106 indices.size() != this->rank(),
2107 "[ERROR][get_block][BlockFermionicUniTensor] len(indices) must be the same as the "
2108 "Tensor rank (number of legs).%s",
2111 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
2115 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
2116 if (inds == this->_inner_to_outer_idx[i]) {
2124 return this->NullRefTensor;
2127 "[ERROR][get_block][BlockFermionicUniTensor] no avaliable block exists, "
2128 "force_return=false, so "
2129 "error throws. \n If you want to return an empty block without "
2130 "error when block is "
2131 "not avaliable, set force_return=True.%s",
2135 return this->_blocks[b];
2139 std::vector<Tensor> get_blocks()
const {
2141 return vec_clone(this->_blocks);
2143 const std::vector<Tensor> &get_blocks_(
const bool &)
const {
2145 return this->_blocks;
2147 std::vector<Tensor> &get_blocks_(
const bool &) {
2149 return this->_blocks;
2152 bool same_data(
const boost::intrusive_ptr<UniTensor_base> &rhs)
const {
2154 if (rhs->uten_type() !=
UTenType.BlockFermionic)
return false;
2155 if (rhs->get_blocks_(1).size() != this->get_blocks_(1).size())
return false;
2157 for (
int i = 0; i < rhs->get_blocks_(1).size(); i++)
2158 if (this->get_blocks_(1)[i].same_data(rhs->get_blocks_(1)[i]) ==
false)
return false;
2163 void set_rowrank_(
const cytnx_uint64 &new_rowrank) {
2166 new_rowrank > this->rank(),
2167 "[ERROR][BlockFermionicUniTensor] rowrank should be [>=0] and [<=UniTensor.rank].%s",
"\n");
2168 if (this->is_diag()) {
2171 "[ERROR][BlockFermionicUniTensor] rowrank should be [==1] when is_diag =true!.%s",
"\n");
2173 this->_rowrank = new_rowrank;
2174 this->_is_braket_form = this->_update_braket();
2177 boost::intrusive_ptr<UniTensor_base> set_rowrank(
const cytnx_uint64 &new_rowrank)
const {
2180 BlockFermionicUniTensor *tmp = this->clone_meta(
true,
true);
2181 tmp->_blocks = this->_blocks;
2182 tmp->set_rowrank_(new_rowrank);
2183 boost::intrusive_ptr<UniTensor_base> out(tmp);
2187 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<cytnx_int64> &mapper,
2188 const cytnx_int64 &rowrank = -1);
2189 boost::intrusive_ptr<UniTensor_base> permute(
const std::vector<std::string> &mapper,
2190 const cytnx_int64 &rowrank = -1);
2192 void permute_(
const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1)
override;
2193 void permute_(
const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1)
override;
2195 boost::intrusive_ptr<UniTensor_base> permute_nosignflip(
2196 const std::vector<cytnx_int64> &mapper,
const cytnx_int64 &rowrank = -1)
override;
2197 boost::intrusive_ptr<UniTensor_base> permute_nosignflip(
2198 const std::vector<std::string> &mapper,
const cytnx_int64 &rowrank = -1)
override;
2199 void permute_nosignflip_(
const std::vector<cytnx_int64> &mapper,
2200 const cytnx_int64 &rowrank = -1)
override;
2201 void permute_nosignflip_(
const std::vector<std::string> &mapper,
2202 const cytnx_int64 &rowrank = -1)
override;
2204 void twist_(
const cytnx_int64 &idx)
override;
2205 void twist_(
const std::string &label)
override;
2206 void fermion_twists_()
override;
2209 std::vector<bool> _swapsigns_(
const std::vector<cytnx_int64> &mapper)
const;
2210 std::vector<bool> _lhssigns_(
const std::vector<cytnx_int64> &mapper,
2211 const cytnx_int64 contrno)
const;
2212 std::vector<bool> _swapsigns_(
const std::vector<cytnx_uint64> &mapper)
const;
2213 std::vector<bool> _lhssigns_(
const std::vector<cytnx_uint64> &mapper,
2214 const cytnx_uint64 contrno)
const;
2216 boost::intrusive_ptr<UniTensor_base> contiguous_() {
2218 for (
unsigned int b = 0; b < this->_blocks.size(); b++) this->_blocks[b].contiguous_();
2219 return boost::intrusive_ptr<UniTensor_base>(
this);
2221 boost::intrusive_ptr<UniTensor_base> contiguous();
2223 boost::intrusive_ptr<UniTensor_base> apply_();
2224 boost::intrusive_ptr<UniTensor_base> apply();
2226 void print_diagram(
const bool &bond_info =
false)
const;
2227 void print_blocks(
const bool &full_info =
true)
const;
2228 void print_block(
const cytnx_int64 &idx,
const bool &full_info =
true)
const;
2230 boost::intrusive_ptr<UniTensor_base> contract(
const boost::intrusive_ptr<UniTensor_base> &rhs,
2231 const bool &mv_elem_self =
false,
2232 const bool &mv_elem_rhs =
false);
2234 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &new_labels);
2235 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &new_labels);
2237 boost::intrusive_ptr<UniTensor_base> relabel(
const std::vector<std::string> &old_labels,
2238 const std::vector<std::string> &new_labels);
2239 boost::intrusive_ptr<UniTensor_base> relabels(
const std::vector<std::string> &old_labels,
2240 const std::vector<std::string> &new_labels);
2242 boost::intrusive_ptr<UniTensor_base> relabel(
const std::string &old_label,
2243 const std::string &new_label);
2244 boost::intrusive_ptr<UniTensor_base> relabel(
const cytnx_int64 &inx,
2245 const std::string &new_label);
2246 std::vector<Symmetry> syms()
const;
2248 void reshape_(
const std::vector<cytnx_int64> &new_shape,
const cytnx_uint64 &rowrank = 0) {
2249 cytnx_error_msg(
true,
"[ERROR] Cannot reshape a UniTensor with symmetry.%s",
"\n");
2251 boost::intrusive_ptr<UniTensor_base> reshape(
const std::vector<cytnx_int64> &new_shape,
2252 const cytnx_uint64 &rowrank = 0) {
2253 cytnx_error_msg(
true,
"[ERROR] Cannot reshape a UniTensor with symmetry.%s",
"\n");
2257 boost::intrusive_ptr<UniTensor_base> to_dense();
2260 boost::intrusive_ptr<UniTensor_base> astype(
const unsigned int &dtype)
const {
2262 BlockFermionicUniTensor *tmp = this->clone_meta(
true,
true);
2263 tmp->_blocks.resize(this->_blocks.size());
2264 for (cytnx_int64 blk = 0; blk < this->_blocks.size(); blk++) {
2265 tmp->_blocks[blk] = this->_blocks[blk].astype(dtype);
2267 boost::intrusive_ptr<UniTensor_base> out(tmp);
2272 boost::intrusive_ptr<UniTensor_base> get(
const std::vector<Accessor> &accessors) {
2275 "[ERROR][BlockFermionicUniTensor][get] Cannot use get on a UniTensor with "
2276 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
2282 void set(
const std::vector<Accessor> &accessors,
const Tensor &rhs) {
2286 "[ERROR][BlockFermionicUniTensor][get] Cannot use get on a UniTensor with "
2287 "Symmetry.\n suggestion: try get_block/get_block_/get_blocks/get_blocks_ first.%s",
2291 void put_block(
const Tensor &in,
const cytnx_uint64 &idx = 0) {
2294 in.dtype() != this->dtype(),
2295 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor dtype does not match.%s",
2298 in.device() != this->device(),
2299 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor device does not "
2305 "[ERROR][BlockFermionicUniTensor] index out of range%s",
"\n");
2307 in.shape() != this->_blocks[idx].shape(),
2308 "[ERROR][BlockFermionicUniTensor] the shape of input tensor does not match the shape "
2309 "of block @ idx=%d\n",
2312 this->_blocks[idx] = in.clone();
2314 void put_block_(Tensor &in,
const cytnx_uint64 &idx = 0) {
2317 in.dtype() != this->dtype(),
2318 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor dtype does not match.%s",
2321 in.device() != this->device(),
2322 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor device does not "
2328 "[ERROR][BlockFermionicUniTensor] index out of range%s",
"\n");
2330 in.shape() != this->_blocks[idx].shape(),
2331 "[ERROR][BlockFermionicUniTensor] the shape of input tensor does not match the shape "
2332 "of block @ idx=%d\n",
2335 this->_blocks[idx] = in;
2337 void put_block(
const Tensor &in,
const std::vector<cytnx_int64> &indices) {
2340 in.dtype() != this->dtype(),
2341 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor dtype does not match.%s",
2344 in.device() != this->device(),
2345 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor device does not "
2351 indices.size() != this->rank(),
2352 "[ERROR][put_block][BlockFermionicUniTensor] len(indices) must be the same as the "
2353 "Tensor rank (number of legs).%s",
2356 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
2360 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
2361 if (inds == this->_inner_to_outer_idx[i]) {
2369 true,
"[ERROR][put_block][BlockFermionicUniTensor] no avaliable block exists.%s",
"\n");
2372 in.shape() != this->_blocks[b].shape(),
2373 "[ERROR][BlockFermionicUniTensor] the shape of input tensor does not match the shape "
2374 "of block @ idx=%d\n",
2377 this->_blocks[b] = in.clone();
2380 void put_block_(Tensor &in,
const std::vector<cytnx_int64> &indices) {
2383 in.dtype() != this->dtype(),
2384 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor dtype does not match.%s",
2387 in.device() != this->device(),
2388 "[ERROR][BlockFermionicUniTensor][put_block] The input tensor device does not "
2394 indices.size() != this->rank(),
2395 "[ERROR][put_block][BlockFermionicUniTensor] len(indices) must be the same as the "
2396 "Tensor rank (number of legs).%s",
2399 std::vector<cytnx_uint64> inds(indices.begin(), indices.end());
2403 for (cytnx_uint64 i = 0; i < this->_inner_to_outer_idx.size(); i++) {
2404 if (inds == this->_inner_to_outer_idx[i]) {
2412 true,
"[ERROR][put_block][BlockFermionicUniTensor] no avaliable block exists.%s",
"\n");
2415 in.shape() != this->_blocks[b].shape(),
2416 "[ERROR][BlockFermionicUniTensor] the shape of input tensor does not match the shape "
2417 "of block @ idx=%d\n",
2419 this->_blocks[b] = in;
2427 boost::intrusive_ptr<UniTensor_base>
Conj() {
2429 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2436 for (
int i = 0; i < this->_blocks.size(); i++) {
2437 this->_blocks[i].Conj_();
2444 boost::intrusive_ptr<UniTensor_base> Transpose() {
2446 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2452 boost::intrusive_ptr<UniTensor_base> normalize() {
2454 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2459 boost::intrusive_ptr<UniTensor_base> Dagger() {
2461 boost::intrusive_ptr<UniTensor_base> out = this->
Conj();
2471 void Trace_(
const std::string &a,
const std::string &b);
2472 void Trace_(
const cytnx_int64 &a,
const cytnx_int64 &b);
2474 boost::intrusive_ptr<UniTensor_base>
Trace(
const std::string &a,
const std::string &b) {
2476 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2478 if (out->rank() == 0) {
2479 DenseUniTensor *tmp =
new DenseUniTensor();
2480 tmp->_block = ((BlockFermionicUniTensor *)out.get())->_blocks[0];
2481 out = boost::intrusive_ptr<UniTensor_base>(tmp);
2485 boost::intrusive_ptr<UniTensor_base>
Trace(
const cytnx_int64 &a,
const cytnx_int64 &b) {
2487 boost::intrusive_ptr<UniTensor_base> out = this->clone();
2489 if (out->rank() == 0) {
2490 DenseUniTensor *tmp =
new DenseUniTensor();
2491 tmp->_block = ((BlockFermionicUniTensor *)out.get())->_blocks[0];
2492 out = boost::intrusive_ptr<UniTensor_base>(tmp);
2497 Tensor
Norm()
const;
2499 bool elem_exists(
const std::vector<cytnx_uint64> &locator)
const;
2501 const Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator)
const;
2502 const cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2503 const cytnx_complex128 &aux)
const;
2504 const cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2505 const cytnx_complex64 &aux)
const;
2506 const cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2507 const cytnx_double &aux)
const;
2508 const cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2509 const cytnx_float &aux)
const;
2510 const cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2511 const cytnx_uint64 &aux)
const;
2512 const cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2513 const cytnx_int64 &aux)
const;
2514 const cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2515 const cytnx_uint32 &aux)
const;
2516 const cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2517 const cytnx_int32 &aux)
const;
2518 const cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2519 const cytnx_uint16 &aux)
const;
2520 const cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2521 const cytnx_int16 &aux)
const;
2523 Scalar::Sproxy at_for_sparse(
const std::vector<cytnx_uint64> &locator);
2524 cytnx_complex128 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2525 const cytnx_complex128 &aux);
2526 cytnx_complex64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
2527 const cytnx_complex64 &aux);
2528 cytnx_double &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_double &aux);
2529 cytnx_float &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_float &aux);
2530 cytnx_uint64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint64 &aux);
2531 cytnx_int64 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int64 &aux);
2532 cytnx_uint32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint32 &aux);
2533 cytnx_int32 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int32 &aux);
2534 cytnx_uint16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_uint16 &aux);
2535 cytnx_int16 &at_for_sparse(
const std::vector<cytnx_uint64> &locator,
const cytnx_int16 &aux);
2537 void _save_dispatch(std::fstream &f)
const;
2538 void _load_dispatch(std::fstream &f);
2541 void truncate_(
const std::string &label,
const cytnx_uint64 &q_index);
2542 void truncate_(
const cytnx_int64 &bond_idx,
const cytnx_uint64 &q_index);
2544 void Add_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
2545 void Add_(
const Scalar &rhs) {
2547 "[ERROR] Cannot perform elementwise arithmetic '+' between Scalar and "
2548 "BlockFermionicUniTensor.\n %s "
2550 "This operation would destroy the block structure. [Suggest] Avoid or use "
2551 "get/put_block(s) to do operation on blocks.");
2554 void Mul_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
2555 void Mul_(
const Scalar &rhs);
2557 void Sub_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
2558 void Sub_(
const Scalar &rhs) {
2560 "[ERROR] Cannot perform elementwise arithmetic '-' between Scalar and "
2561 "BlockFermionicUniTensor.\n %s "
2563 "This operation would destroy the block structure. [Suggest] Avoid or use "
2564 "get/put_block(s) to do operation on blocks.");
2566 void lSub_(
const Scalar &lhs) {
2568 "[ERROR] Cannot perform elementwise arithmetic '-' between Scalar and "
2569 "BlockFermionicUniTensor.\n %s "
2571 "This operation would destroy the block structure. [Suggest] Avoid or use "
2572 "get/put_block(s) to do operation on blocks.");
2575 void Div_(
const boost::intrusive_ptr<UniTensor_base> &rhs);
2576 void Div_(
const Scalar &rhs);
2577 void lDiv_(
const Scalar &lhs) {
2579 "[ERROR] Cannot perform elementwise arithmetic '/' between Scalar and "
2580 "BlockFermionicUniTensor.\n %s "
2582 "This operation would cause division by zero on non-block elements. "
2583 "[Suggest] Avoid or use get/put_block(s) to do operation on blocks.");
2585 void from_(
const boost::intrusive_ptr<UniTensor_base> &rhs,
bool force, cytnx_double tol = 0.);
2587 void group_basis_();
2589 void combineBond(
const std::vector<std::string> &indicators,
const bool &force =
false);
2590 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force =
false);
2591 void combineBonds(
const std::vector<cytnx_int64> &indicators,
const bool &force,
2592 const bool &by_label);
2593 void combineBonds(
const std::vector<std::string> &indicators,
const bool &force =
false);
2595 const std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx)
const {
2598 bidx >= this->Nblocks(),
2599 "[ERROR][BlockFermionicUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
2601 return this->_inner_to_outer_idx[bidx];
2603 std::vector<cytnx_uint64> &get_qindices(
const cytnx_uint64 &bidx) {
2606 bidx >= this->Nblocks(),
2607 "[ERROR][BlockFermionicUniTensor] bidx out of bound! only %d blocks in current UTen.\n",
2609 return this->_inner_to_outer_idx[bidx];
2612 const vec2d<cytnx_uint64> &get_itoi()
const {
2614 return this->_inner_to_outer_idx;
2616 vec2d<cytnx_uint64> &get_itoi() {
2618 return this->_inner_to_outer_idx;
2621 void beauty_print_block(std::ostream &os,
const cytnx_uint64 &Nin,
const cytnx_uint64 &Nout,
2622 const std::vector<cytnx_uint64> &qn_indices,
2623 const std::vector<Bond> &bonds,
const Tensor &block)
const;
2630 class UniTensor_options {
2637 UniTensor_options() {
2638 this->_is_diag =
false;
2639 this->_dtype =
Type.Double;
2640 this->_device =
Device.cpu;
2641 this->_rowrank = -1;
2644 UniTensor_options(
const UniTensor_options &rhs) {
2645 this->_is_diag = rhs._is_diag;
2646 this->_dtype = rhs._dtype;
2647 this->_device = rhs._device;
2648 this->_rowrank = rhs._rowrank;
2651 UniTensor_options &operator=(
const UniTensor_options &rhs) {
2652 this->_is_diag = rhs._is_diag;
2653 this->_dtype = rhs._dtype;
2654 this->_device = rhs._device;
2655 this->_rowrank = rhs._rowrank;
2659 UniTensor_options &is_diag(
const bool &in) {
2660 this->_is_diag = in;
2663 UniTensor_options &dtype(
const int &in) {
2667 UniTensor_options &device(
const int &in) {
2671 UniTensor_options &rowrank(
const int &in) {
2672 this->_rowrank = in;
2682 boost::intrusive_ptr<UniTensor_base>
_impl;
2686 this->_impl =
rhs._impl;
2720 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"")
2742 const std::vector<std::string> &
in_labels = {},
const std::string &
name =
"") {
2771 const std::string &
name =
"")
2776 "[DEBUG] message: entry for UniTensor(const std::vector<Bond> &bonds, const "
2777 "std::vector<std::string> &in_labels={}, const cytnx_int64 &rowrank=-1, const unsigned "
2779 "&dtype=Type.Double, const int &device = Device.cpu, const bool &is_diag=false)%s",
2818 const std::string &
name =
"") {
2832 "[ERROR] When initializing a UniTensor with symmetries, all Bonds must "
2833 "be in the same format!%s",
2844 is_sym,
"[ERROR] Cannot have bonds with mixing of symmetry and non-symmetry.%s",
"\n");
2850 cytnx_warning_msg(
true,
"[DEBUG] message: entry dispatch: UniTensor: symmetric%s",
"\n");
2858 "[ERROR] internal error! [legacy Sparse entry] the Bond is symmetry but "
2859 "the version is not properly determined!%s",
2863 "[ERROR] internal error! the Bond is symmetry but the version is not "
2864 "properly determined!%s",
2970 "UniTensor &relabel_(const std::vector<std::string> &new_labels) "
2984 "UniTensor &relabel_(const std::initializer_list<char *> &new_labels) "
2988 std::vector<std::string>
vs(
new_lbls.size());
2990 [](
char *
x) -> std::string { return std::string(x); });
2992 this->_impl->set_labels(
vs);
3016 "[ERROR] Cannot use item on UniTensor with Symmetry.\n suggestion: use "
3017 "get_block()/get_blocks() first.%s",
3021 return tmp->_block.item<
T>();
3026 "[ERROR] Cannot use item on UniTensor with Symmetry.\n suggestion: use "
3027 "get_block()/get_blocks() first.%s",
3031 return tmp->_block.item();
3056 unsigned int dtype()
const {
return this->_impl->dtype(); }
3071 int device()
const {
return this->_impl->device(); }
3077 std::string
name()
const {
return this->_impl->name(); }
3084 std::string
dtype_str()
const {
return this->_impl->dtype_str(); }
3091 std::string
device_str()
const {
return this->_impl->device_str(); }
3111 bool is_diag()
const {
return this->_impl->is_diag(); }
3118 bool is_tag()
const {
return this->_impl->is_tag(); }
3125 std::vector<Symmetry>
syms()
const {
return this->_impl->syms(); }
3139 const std::vector<std::string> &
labels()
const {
return this->_impl->labels(); }
3152 const std::vector<Bond> &
bonds()
const {
return this->_impl->bonds(); }
3157 std::vector<Bond> &
bonds() {
return this->_impl->bonds(); }
3172 std::vector<cytnx_uint64>
shape()
const {
return this->_impl->shape(); }
3180 std::vector<bool>
signflip()
const {
return this->_impl->signflip(); }
3190 std::vector<bool> &
signflip_() {
return this->_impl->signflip_(); }
3255 "UniTensor &relabel_(const std::vector<std::string> &new_labels) "
3285 "UniTensor relabel(const std::vector<std::string> &new_labels) const "
3299 std::vector<std::string>
vs(
new_lbls.size());
3301 [](
char *
x) -> std::string { return std::string(x); });
3314 "UniTensor relabel(const std::initializer_list<char *> &new_labels) const "
3318 std::vector<std::string>
vs(
new_lbls.size());
3320 [](
char *
x) -> std::string { return std::string(x); });
3331 std::vector<std::string>
vs(
new_lbls.size());
3333 [](
char *
x) -> std::string { return std::string(x); });
3335 this->_impl->relabel_(
vs);
3345 "UniTensor &relabel_(const std::initializer_list<char *> &new_labels) "
3349 std::vector<std::string>
vs(
new_lbls.size());
3351 [](
char *
x) -> std::string { return std::string(x); });
3353 this->_impl->relabels_(
vs);
3365 const std::vector<std::string> &
new_labels)
const {
3377 "UniTensor relabel(const std::vector<std::string> &old_labels, const "
3378 "std::vector<std::string> &new_labels) const "
3381 const std::vector<std::string> &
new_labels)
const {
3403 const std::vector<std::string> &
new_labels) {
3414 "UniTensor &relabel_(const std::vector<std::string> &old_labels, const "
3415 "std::vector<std::string> &new_labels) "
3418 const std::vector<std::string> &
new_labels) {
3428 const std::initializer_list<char *> &
new_labels)
const {
3430 std::vector<std::string>
vs(
new_lbls.size());
3432 [](
char *
x) -> std::string { return std::string(x); });
3437 [](
char *
x) -> std::string { return std::string(x); });
3449 "UniTensor relabel(const std::initializer_list<char *> &old_labels, const "
3450 "std::initializer_list<char *> &new_labels) const "
3453 const std::initializer_list<char *> &
new_labels)
const {
3455 std::vector<std::string>
vs(
new_lbls.size());
3457 [](
char *
x) -> std::string { return std::string(x); });
3462 [](
char *
x) -> std::string { return std::string(x); });
3472 const std::initializer_list<char *> &
new_labels) {
3474 std::vector<std::string>
vs(
new_lbls.size());
3476 [](
char *
x) -> std::string { return std::string(x); });
3481 [](
char *
x) -> std::string { return std::string(x); });
3493 "UniTensor &relabel_(const std::initializer_list<char *> &old_labels, const "
3494 "std::initializer_list<char *> &new_labels) "
3497 const std::initializer_list<char *> &
new_labels) {
3499 std::vector<std::string>
vs(
new_lbls.size());
3501 [](
char *
x) -> std::string { return std::string(x); });
3506 [](
char *
x) -> std::string { return std::string(x); });
3585 if (this->
dtype() == dtype) {
3629 std::vector<std::string>
vs(
mprs.size());
3631 [](
char *
x) -> std::string { return std::string(x); });
3705 std::vector<std::string>
vs(
mprs.size());
3707 [](
char *
x) -> std::string { return std::string(x); });
3862 this->_impl = this->_impl->
apply_();
3919 return this->_impl->at_for_sparse(
locator,
aux);
3921 }
else if (this->
uten_type() == UTenType.Sparse) {
3922 if (this->_impl->elem_exists(
locator)) {
3924 return this->_impl->at_for_sparse(
locator,
aux);
3926 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
3947 return this->_impl->at_for_sparse(
locator,
aux);
3949 }
else if (this->
uten_type() == UTenType.Sparse) {
3950 if (this->_impl->elem_exists(
locator)) {
3952 return this->_impl->at_for_sparse(
locator,
aux);
3954 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
3964 const std::vector<cytnx_uint64> &
locator)
const {
3967 "[ERROR][at] length of list should be the same for label and locator.%s",
3971 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
3974 for (
int i = 0;
i <
labels.size();
i++) {
3975 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
3977 "[ERROR] label:%s does not exist in current UniTensor.\n",
3979 new_loc = std::distance(this->_impl->_labels.begin(),
res);
3982 return this->
at<T>(new_locator);
3988 "[ERROR][at] length of list should be the same for label and locator.%s",
3992 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
3995 for (
int i = 0;
i <
labels.size();
i++) {
3996 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
3998 "[ERROR] label:%s does not exist in current UniTensor.\n",
4000 new_loc = std::distance(this->_impl->_labels.begin(),
res);
4003 return this->
at<T>(new_locator);
4013 const Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator)
const {
4015 return this->_impl->at_for_sparse(
locator);
4016 }
else if (this->
uten_type() == UTenType.Sparse) {
4017 if (this->_impl->elem_exists(
locator)) {
4018 return this->_impl->at_for_sparse(
locator);
4020 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
4035 Scalar::Sproxy
at(
const std::vector<cytnx_uint64> &
locator) {
4037 return this->_impl->at_for_sparse(
locator);
4038 }
else if (this->
uten_type() == UTenType.Sparse) {
4039 if (this->_impl->elem_exists(
locator)) {
4040 return this->_impl->at_for_sparse(
locator);
4042 cytnx_error_msg(
true,
"[ERROR][SparseUniTensor] invalid location. break qnum block.%s",
4050 Scalar::Sproxy
at(
const std::vector<std::string> &
labels,
4051 const std::vector<cytnx_uint64> &
locator) {
4054 "[ERROR][at] length of list should be the same for label and locator.%s",
4058 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
4061 for (
int i = 0;
i <
labels.size();
i++) {
4062 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
4064 "[ERROR] label:%s does not exist in current UniTensor.\n",
4066 new_loc = std::distance(this->_impl->_labels.begin(),
res);
4069 return this->
at(new_locator);
4072 const Scalar::Sproxy
at(
const std::vector<std::string> &
labels,
4073 const std::vector<cytnx_uint64> &
locator)
const {
4076 "[ERROR][at] length of list should be the same for label and locator.%s",
4080 "[ERROR][at] length of lists must be the same as UniTensor.rank (# of legs)%s",
"\n");
4083 for (
int i = 0;
i <
labels.size();
i++) {
4084 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
4086 "[ERROR] label:%s does not exist in current UniTensor.\n",
4088 new_loc = std::distance(this->_impl->_labels.begin(),
res);
4091 return this->
at(new_locator);
4118 return this->_impl->get_block(
qidx,
force);
4122 const bool &
force =
false)
const {
4125 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
4127 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
4129 std::vector<cytnx_int64>
loc_id(this->
rank());
4134 for (
int i = 0;
i <
labels.size();
i++) {
4135 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
4137 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
4139 new_loc = std::distance(this->_impl->_labels.begin(),
res);
4153 const bool &
force =
false)
const {
4154 std::vector<cytnx_int64>
tmp =
qnum;
4168 const bool &
force =
false)
const {
4182 return this->_impl->get_block_(
idx);
4203 return this->_impl->get_block_(
qidx,
force);
4225 const bool &
force =
false) {
4228 "[ERROR][get_block] length of lists must be the same for both lables and qnidices%s",
"\n");
4230 "[ERROR][get_block] length of lists must be the rank (# of legs)%s",
"\n");
4232 std::vector<cytnx_int64>
loc_id(this->
rank());
4237 for (
int i = 0;
i <
labels.size();
i++) {
4238 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
labels[
i]);
4240 "[ERROR][get_block] label:%s does not exists in current Tensor.\n",
4242 new_loc = std::distance(this->_impl->_labels.begin(),
res);
4247 if (
out.dtype() !=
Type.Void) {
4257 std::vector<cytnx_int64>
tmp =
qidx;
4270 const bool &
force =
false) {
4281 const bool &
force =
false)
const {
4282 return this->_impl->get_block_(
qidx,
force);
4289 const bool &
force =
false)
const {
4290 std::vector<cytnx_int64>
tmp =
qidx;
4291 return this->_impl->get_block_(
tmp,
force);
4298 const bool &
force =
false)
const {
4316 std::vector<Tensor>
get_blocks()
const {
return this->_impl->get_blocks(); }
4328 return this->_impl->get_blocks_(
silent);
4336 return this->_impl->get_blocks_(
silent);
4360 "UniTensor &put_block(const Tensor &in, const cytnx_uint64 &idx) "
4388 "UniTensor &put_block(const Tensor &in_tens, const std::vector<cytnx_int64> &qidx) "
4404 const std::vector<cytnx_int64> &
qidx) {
4407 "[ERROR][put_block] length of lists must be the same for both lables and qnidices%s",
"\n");
4409 "[ERROR][put_block] length of lists must be the rank (# of legs)%s",
"\n");
4411 std::vector<cytnx_int64>
loc_id(this->
rank());
4417 for (
int i = 0;
i <
lbls.size();
i++) {
4418 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
4420 "[ERROR][put_block] label:%s does not exists in current Tensor.\n",
4422 new_loc = std::distance(this->_impl->_labels.begin(),
res);
4438 "UniTensor &put_block(Tensor &in, const std::vector<std::string> &lbls, const "
4439 "std::vector<cytnx_int64> &qidx) "
4442 const std::vector<cytnx_int64> &
qidx,
const bool &
force) {
4481 "UniTensor &put_block_(Tensor &in, const std::vector<cytnx_int64> &qidx) "
4497 const std::vector<cytnx_int64> &
qidx) {
4500 "[ERROR][put_block_] length of lists must be the same for both lables and qnidices%s",
4503 "[ERROR][put_block_] length of lists must be the rank (# of legs)%s",
"\n");
4505 std::vector<cytnx_int64>
loc_id(this->
rank());
4511 for (
int i = 0;
i <
lbls.size();
i++) {
4512 auto res = std::find(this->_impl->_labels.begin(),
this->_impl->_labels.end(),
lbls[
i]);
4514 "[ERROR][put_block_] label:%s does not exists in current Tensor.\n",
4516 new_loc = std::distance(this->_impl->_labels.begin(),
res);
4534 "UniTensor &put_block_(Tensor &in, const std::vector<std::string> &lbls, const "
4535 "std::vector<cytnx_int64> &qidx) "
4538 const std::vector<cytnx_int64> &
qidx,
const bool &
force) {
4574 return this->
get(acc_in);
4577 std::vector<cytnx::Accessor>
acc_in;
4581 return this->
get(acc_in);
4611 "[ERROR] Cannot set elements from UniTensor with symmetry. Use at() instead.%s",
"\n");
4614 "[ERROR] Cannot set UniTensor. incoming UniTensor is_diag=True.%s",
"\n");
4677 "combineBond(const std::vector<std::string> &indicators, const bool &force) "
4691 "combineBond(const std::vector<std::string> &indicators, const bool &force) "
4704 "combineBond(const std::vector<std::string> &indicators, const bool &force) "
4760 return this->_impl->getTotalQnums(
physical);
4767 return this->_impl->get_blocks_qnums();
4777 if (this->_impl->uten_type() !=
rhs._impl->uten_type())
return false;
4779 return this->_impl->same_data(
rhs._impl);
5257 out._impl = this->_impl->
Conj();
5269 this->_impl->
Conj_();
5370 if (this->
rank() == 0) {
5373 this->_impl = boost::intrusive_ptr<UniTensor_base>(
tmp);
5392 if (this->
rank() == 0) {
5395 this->_impl = boost::intrusive_ptr<UniTensor_base>(
tmp);
5482 return this->_impl->elem_exists(
locator);
5491 [[deprecated(
"Use at() instead.")]]
T get_elem(
const std::vector<cytnx_uint64> &
locator)
const {
5492 return this->
at<T>(locator);
5502 const std::vector<cytnx_uint64> &
locator,
const T2 &
rc) {
5504 this->
at(locator) =
rc;
5608 return this->_impl->get_qindices(
bidx);
5618 return this->_impl->get_qindices(
bidx);
5631 void _Load(std::fstream &
f);
5632 void _Save(std::fstream &
f)
const;
5668 const std::vector<std::string> &
in_labels = {},
5670 const std::string &
name =
"") {
5688 const std::vector<std::string> &
in_labels = {},
5690 const std::string &
name =
"") {
5707 const std::string &
name =
"") {
5725 const std::vector<std::string> &
in_labels = {},
5727 const unsigned int &
dtype =
Type.Double,
5770 const std::vector<std::string> &
in_labels = {},
5772 const std::string &
name =
"") {
5791 const std::vector<std::string> &
in_labels = {},
5792 const std::string &
name =
"") {
5815 const std::vector<std::string> &
in_labels = {},
5817 const std::string &
name =
"") {
5842 const std::vector<std::string> &
in_labels = {},
5843 const unsigned int &
dtype =
Type.Double,
5869 const std::vector<std::string> &
in_labels = {},
5872 const std::string &
name =
"");
5893 const double &
std,
const std::vector<std::string> &
in_labels = {},
5896 const std::string &
name =
"");
5917 const std::vector<std::string> &
in_labels = {},
5919 const unsigned int &
dtype =
Type.Double,
5960 const double &
high,
const std::vector<std::string> &
in_labels = {},
5962 const unsigned int &
dtype =
Type.Double,
5999 std::ostream &operator<<(std::ostream &os,
const UniTensor &in);
6015 const bool &cacheR =
false);
6030 const bool &optimal);
6039 "UniTensor Contract(const std::vector<UniTensor> &TNs, const std::string &order, const bool "
6042 Contracts(
const std::vector<UniTensor> &TNs,
const std::string &order,
const bool &optimal);
6045 void _resolve_CT(std::vector<UniTensor> &TNlist);
6046 template <
class... T>
6047 void _resolve_CT(std::vector<UniTensor> &TNlist,
const UniTensor &in,
const T &...args) {
6048 TNlist.push_back(in);
6049 _resolve_CT(TNlist, args...);
6064 template <
class... T>
6066 const bool &optimal) {
6067 std::vector<UniTensor> TNlist;
6068 _resolve_CT(TNlist, in, args...);
6069 return Contract(TNlist, order, optimal);
6077 template <
class... T>
6080 "UniTensor Contract(const UniTensor &in, const T &...args, const std::string &order, const "
6082 "instead.")]] UniTensor
6084 const bool &optimal) {
6085 std::vector<UniTensor> TNlist;
6086 _resolve_CT(TNlist, in, args...);
6087 return Contracts(TNlist, order, optimal);
constexpr Type_class Type
data type
Definition Type.hpp:426
object that mimic the python slice to access elements in C++ [this is for c++ API only].
Definition Accessor.hpp:17
the object contains auxiliary properties for each Tensor rank (bond)
Definition Bond.hpp:178
Bond clone() const
return a copy of the instance Bond
Definition Bond.hpp:490
an tensor (multi-dimensional array)
Definition Tensor.hpp:41
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at specific location.
Definition Tensor.hpp:922
Tensor Norm() const
the Norm member function. Same as linalg::Norm(const Tensor &Tin), where Tin is the current Tensor.
An Enhanced tensor specifically designed for physical Tensor network simulation.
Definition UniTensor.hpp:2679
UniTensor to(const int &device) const
move the current UniTensor to the assigned device.
Definition UniTensor.hpp:3219
UniTensor & operator*=(const UniTensor &rhs)
The multiplication assignment operator of the UniTensor.
Definition UniTensor.hpp:5131
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:5751
Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:4256
std::vector< Tensor > & get_blocks_(const bool &silent=false)
Definition UniTensor.hpp:4335
Tensor & get_block_(const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:4264
void print_block(const cytnx_int64 &idx, const bool &full_info=true) const
Print out the block of the UniTensor with a given block index number.
Definition UniTensor.hpp:3885
UniTensor & operator/=(const UniTensor &rhs)
The division assignment operator of the UniTensor.
Definition UniTensor.hpp:5111
UniTensor & set_elem(const std::vector< cytnx_uint64 > &locator, const T2 &rc)
Definition UniTensor.hpp:5501
T & item()
Definition UniTensor.hpp:3014
UniTensor & put_block_(Tensor &in, const std::vector< cytnx_int64 > &qidx)
Put the block into the UniTensor with given quantum indices, inplacely.
Definition UniTensor.hpp:4469
bool is_contiguous() const
To tell whether the UniTensor is contiguous.
Definition UniTensor.hpp:3105
T get_elem(const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:5491
UniTensor Div(const UniTensor &rhs) const
The division function of the UniTensor.
UniTensor & convert_from(const UniTensor &rhs, bool force=false, cytnx_double tol=0.)
Copy data from a UniTensor of different type.
Definition UniTensor.hpp:5649
Tensor get_block(const std::vector< std::string > &labels, const std::vector< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:4121
UniTensor & put_block(const Tensor &in, const cytnx_uint64 &idx, const bool &force)
Definition UniTensor.hpp:4362
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:5617
std::vector< bool > signflip() const
Get the sign information of a fermionic UniTensor.
Definition UniTensor.hpp:3180
UniTensor & set_label(const cytnx_int64 &idx, const char *new_label)
Definition UniTensor.hpp:2912
UniTensor & operator+=(const UniTensor &rhs)
The addition assignment operator of the UniTensor.
Definition UniTensor.hpp:5071
UniTensor reshape(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor.
Definition UniTensor.hpp:4627
std::vector< Tensor > get_blocks() const
Get all the blocks of the UniTensor.
Definition UniTensor.hpp:4316
UniTensor permute(const std::initializer_list< char * > &mapper, const cytnx_int64 &rowrank=-1) const
Definition UniTensor.hpp:3626
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:3118
std::string uten_type_str() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor in 'string' form.
Definition UniTensor.hpp:3098
UniTensor permute_nosignflip(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1) const
permute the legs of the UniTensor by labels without sign flips
Definition UniTensor.hpp:3690
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:2768
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:4117
UniTensor & contiguous_()
Make the UniTensor contiguous by coalescing the memory (storage), inplacely.
Definition UniTensor.hpp:3837
UniTensor & tag()
Set the UniTensor as a tagged UniTensor.
Definition UniTensor.hpp:5436
const Bond & bond_(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:3159
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force=false)
Definition UniTensor.hpp:4706
UniTensor & relabel_(const std::string &old_label, const std::string &new_label)
relabel the legs in the UniTensor by a given label.
Definition UniTensor.hpp:3552
const T & at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:3963
UniTensor & relabels_(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:3347
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:2718
Tensor & get_block_(const std::vector< cytnx_int64 > &qidx, const bool &force=false)
Get the shared view of the block for the given quantum indices.
Definition UniTensor.hpp:4202
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 from a cytnx::Tensor.
Definition UniTensor.hpp:2741
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:5687
UniTensor get(const std::vector< Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition UniTensor.hpp:4557
UniTensor & permute_nosignflip_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1)
permute the legs of the UniTensor without fermionic sign flips, inplacely.
Definition UniTensor.hpp:3724
T & at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:3985
UniTensor Conj() const
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:5255
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:2927
UniTensor set_rowrank(const cytnx_uint64 &new_rowrank) const
Definition UniTensor.hpp:3007
UniTensor & set(const std::vector< Accessor > &accessors, const UniTensor &rhs)
Definition UniTensor.hpp:4608
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:5161
cytnx_uint64 rowrank() const
Return the row rank of the UniTensor.
Definition UniTensor.hpp:3049
UniTensor & put_block(const Tensor &in_tens, const std::vector< cytnx_int64 > &qidx)
Put the block into the UniTensor with given quantum number.
Definition UniTensor.hpp:4376
UniTensor & relabels_(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels)
Definition UniTensor.hpp:3417
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:5054
UniTensor Mul(const Scalar &rhs) const
The multiplication function for a given scalar.
UniTensor & twist_(const std::string &label)
Inline version.
Definition UniTensor.hpp:3778
UniTensor twist(const std::string &label) const
Apply a twist (or braids/self-swap) operation to a given bond; No effect for bosonic tensors; for a f...
Definition UniTensor.hpp:3755
UniTensor & set_labels(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:2986
UniTensor & relabel_(const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:3329
UniTensor & Sub_(const Scalar &rhs)
The subtraction function for a given scalar.
Definition UniTensor.hpp:4906
UniTensor & relabel_(const cytnx_int64 &inx, const std::string &new_label)
rebable the legs in the UniTensor by given index.
Definition UniTensor.hpp:3539
UniTensor & operator/=(const Scalar &rhs)
The division assignment operator for a given scalar.
Definition UniTensor.hpp:5176
const bool & is_braket_form() const
Check whether the UniTensor is in braket form.
Definition UniTensor.hpp:3133
UniTensor Add(const Scalar &rhs) const
The addition function for a given scalar.
UniTensor operator[](const std::vector< cytnx::Accessor > &accessors) const
get elements using Accessor (C++ API) / slices (python API)
Definition UniTensor.hpp:4567
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:5840
std::vector< cytnx_uint64 > shape() const
Get the shape of the UniTensor.
Definition UniTensor.hpp:3172
UniTensor to_dense()
Convert the UniTensor to non-diagonal form.
Definition UniTensor.hpp:4655
UniTensor & permute_(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1)
permute the legs of the UniTensor, inplacely.
Definition UniTensor.hpp:3643
Scalar::Sproxy at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator)
Definition UniTensor.hpp:4050
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:4280
UniTensor & set_labels(const std::vector< std::string > &new_labels)
Definition UniTensor.hpp:2972
std::string name() const
Return the name of the UniTensor.
Definition UniTensor.hpp:3077
const Scalar::Sproxy at(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &locator) const
Definition UniTensor.hpp:4072
UniTensor & put_block(Tensor &in, const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx)
Put the block into the UniTensor with given quantum indices, will copy the input tensor.
Definition UniTensor.hpp:4403
UniTensor & Add_(const Scalar &rhs)
The addition function for a given scalar.
Definition UniTensor.hpp:4876
UniTensor & set(const std::vector< Accessor > &accessors, const Tensor &rhs)
set elements using Accessor (C++ API) / slices (python API)
Definition UniTensor.hpp:4604
UniTensor & Trace_(const std::string &a, const std::string &b)
Take the partial trace of the UniTensor, inplacely.
Definition UniTensor.hpp:5366
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:5565
UniTensor & twist_(const cytnx_int64 &idx)
Inline version.
Definition UniTensor.hpp:3787
Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator)
Get an element at a specific location.
Definition UniTensor.hpp:4035
UniTensor Trace(const std::string &a, const std::string &b) const
Take the partial trace of the UniTensor.
Definition UniTensor.hpp:5336
UniTensor & 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:2815
bool same_data(const UniTensor &rhs) const
Check whether the Blocks address are the same.
Definition UniTensor.hpp:4775
UniTensor astype(const unsigned int &dtype) const
Return a new UniTensor whose elements are casted to a different data type.
Definition UniTensor.hpp:3583
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:5769
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:5579
UniTensor Transpose() const
Take the transpose of the UniTensor.
Definition UniTensor.hpp:5286
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="")
Create a rank-1 UniTensor with incremental elements in the range [start,end) with given step-size ste...
Definition UniTensor.hpp:5813
UniTensor operator[](const std::initializer_list< cytnx_int64 > &accessors) const
Definition UniTensor.hpp:4583
UniTensor & set_label(const char *old_label, const std::string &new_label)
Definition UniTensor.hpp:2935
static UniTensor Load(const char *fname)
load a UniTensor from file
UniTensor & Dagger_()
Take the conjugate transpose to the UniTensor, inplacely.
Definition UniTensor.hpp:5423
std::vector< Bond > & bonds()
Definition UniTensor.hpp:3157
T & at(const std::vector< cytnx_uint64 > &locator)
Get an element at a specific location.
Definition UniTensor.hpp:3915
UniTensor & set_rowrank_(const cytnx_uint64 &new_rowrank)
Set the rowrank of the UniTensor.
Definition UniTensor.hpp:3002
UniTensor & 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 & 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 operator[](const std::initializer_list< cytnx::Accessor > &accessors) const
Definition UniTensor.hpp:4572
UniTensor & put_block_(Tensor &in, const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx)
Put the block into the UniTensor with given quantum indices, inplacely.
Definition UniTensor.hpp:4496
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:2904
UniTensor permute_nosignflip(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1) const
permute the legs of the UniTensor without sign flips
Definition UniTensor.hpp:3672
UniTensor & fermion_twists_()
Inline version.
Definition UniTensor.hpp:3816
UniTensor & to_dense_()
Convert the UniTensor to non-diagonal form, inplacely.
Definition UniTensor.hpp:4665
UniTensor contiguous() const
Make the UniTensor contiguous by coalescing the memory (storage).
Definition UniTensor.hpp:3827
UniTensor & put_block_(Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index, inplacely.
Definition UniTensor.hpp:4455
UniTensor & apply_()
Apply fermionic signflips to the UniTensor, inplacely. Subsequently, all elements returned by signfli...
Definition UniTensor.hpp:3861
Tensor get_block(const cytnx_uint64 &idx=0) const
Get the block of the UniTensor for a given block index.
Definition UniTensor.hpp:4103
const T & at(const std::vector< cytnx_uint64 > &locator) const
Get an element at a specific location.
Definition UniTensor.hpp:3943
UniTensor & operator*=(const Scalar &rhs)
The multiplication assignment operator for a given scalar.
Definition UniTensor.hpp:5191
UniTensor relabels(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels) const
Definition UniTensor.hpp:3380
UniTensor normalize() const
normalize the current UniTensor instance with 2-norm.
Definition UniTensor.hpp:5310
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:5705
UniTensor & relabel_(const std::vector< std::string > &new_labels)
Set new labels for all the bonds.
Definition UniTensor.hpp:3244
std::vector< Symmetry > syms() const
Return the symmetry type of the UniTensor.
Definition UniTensor.hpp:3125
UniTensor relabel(const std::vector< std::string > &new_labels) const
relabel all of the labels in UniTensor.
Definition UniTensor.hpp:3273
UniTensor & Mul_(const UniTensor &rhs)
The multiplcation function of the UniTensor.
Definition UniTensor.hpp:4819
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:5667
UniTensor & permute_nosignflip_(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1)
permute the legs of the UniTensor without fermionic sign flips, inplacely.
Definition UniTensor.hpp:3741
void combineBonds(const std::vector< std::string > &indicators, const bool &force=false)
Definition UniTensor.hpp:4693
UniTensor & combineBond(const std::vector< std::string > &indicators, const bool &force=false)
Combine the sevral bonds of the UniTensor.
Definition UniTensor.hpp:4720
UniTensor relabel(const std::string &old_label, const std::string &new_label) const
relabel the legs in the UniTensor by a given label.
Definition UniTensor.hpp:3571
UniTensor & group_basis_()
Group the same quantum number basis together.
Definition UniTensor.hpp:3895
UniTensor & normalize_()
normalize the UniTensor, inplacely.
Definition UniTensor.hpp:5322
UniTensor & Inv_(double clip=-1.)
Element-wise (pseudo-)inverse, inplacely.
bool is_diag() const
To tell whether the UniTensor is in diagonal form.
Definition UniTensor.hpp:3111
int device() const
Return the device of the UniTensor.
Definition UniTensor.hpp:3071
UniTensor & Pow_(const double &p)
Take the power p of all elements, inplacely.
const Tensor & get_block_(const std::vector< cytnx_uint64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:4297
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 the block for the given quantum indices on given labels.
Definition UniTensor.hpp:4224
std::string dtype_str() const
Return the data type of the UniTensor in 'string' form.
Definition UniTensor.hpp:3084
UniTensor & operator+=(const Scalar &rhs)
The addition assignment operator for a given scalar.
Definition UniTensor.hpp:5146
UniTensor & Div_(const UniTensor &rhs)
The division function of the UniTensor.
Definition UniTensor.hpp:4861
UniTensor & Div_(const Scalar &rhs)
The division function for a given scalar.
Definition UniTensor.hpp:4921
UniTensor & put_block_(Tensor &in, const std::vector< cytnx_int64 > &qidx, const bool &force)
Definition UniTensor.hpp:4483
Bond & bond_(const std::string &label)
Definition UniTensor.hpp:3163
cytnx_uint64 rank() const
Return the rank of the UniTensor.
Definition UniTensor.hpp:3043
Bond bond(const std::string &label) const
Definition UniTensor.hpp:3166
std::vector< bool > & signflip_()
Get reference to the sign information of a fermionic UniTensor.
Definition UniTensor.hpp:3190
UniTensor fermion_twists() const
Apply twists to all right bonds (>= rowrank) with bond type BD_KET.
Definition UniTensor.hpp:3806
UniTensor permute_nosignflip(const std::initializer_list< char * > &mapper, const cytnx_int64 &rowrank=-1) const
Definition UniTensor.hpp:3702
UniTensor & Trace_(const cytnx_int64 &a=0, const cytnx_int64 &b=1)
Take the partial trace of the UniTensor, inplacely.
Definition UniTensor.hpp:5388
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:3364
UniTensor & put_block(const Tensor &in, const cytnx_uint64 &idx=0)
Put the block into the UniTensor with given index.
Definition UniTensor.hpp:4348
UniTensor & put_block(const Tensor &in_tens, const std::vector< cytnx_int64 > &qidx, const bool &force)
Definition UniTensor.hpp:4390
UniTensor & set_name(const std::string &in)
Set the name of a UniTensor.
Definition UniTensor.hpp:2889
UniTensor Trace(const cytnx_int64 &a=0, const cytnx_int64 &b=1) const
Take the partial trace of the UniTensor.
Definition UniTensor.hpp:5351
UniTensor & Add_(const UniTensor &rhs)
The addition function of the UniTensor.
Definition UniTensor.hpp:4798
UniTensor permute(const std::vector< cytnx_int64 > &mapper, const cytnx_int64 &rowrank=-1) const
permute the legs of the UniTensor
Definition UniTensor.hpp:3601
UniTensor & set_label(const std::string &old_label, const char *new_label)
Definition UniTensor.hpp:2943
UniTensor permute(const std::vector< std::string > &mapper, const cytnx_int64 &rowrank=-1) const
permute the legs of the UniTensor by labels
Definition UniTensor.hpp:3614
unsigned int dtype() const
Return the data type of the UniTensor.
Definition UniTensor.hpp:3056
UniTensor Pow(const double &p) const
Take the power p of all elements.
UniTensor & Mul_(const Scalar &rhs)
The multiplication function for a given scalar.
Definition UniTensor.hpp:4891
UniTensor & operator-=(const UniTensor &rhs)
The subtraction assignment operator of the UniTensor.
Definition UniTensor.hpp:5091
Tensor get_block_(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &qidx, const bool &force=false)
Definition UniTensor.hpp:4269
void combineBonds(const std::vector< cytnx_int64 > &indicators, const bool &force, const bool &by_label)
Definition UniTensor.hpp:4679
UniTensor & set_label(const char *old_label, const char *new_label)
Definition UniTensor.hpp:2951
static UniTensor arange(const cytnx_int64 &Nelem, const std::vector< std::string > &in_labels={}, const std::string &name="")
Create a rank-1 UniTensor with incremental unsigned integer elements in the range [0,...
Definition UniTensor.hpp:5790
bool is_blockform() const
Check whether the UniTensor is in block form.
Definition UniTensor.hpp:3197
UniTensor group_basis() const
Definition UniTensor.hpp:3900
UniTensor twist(const cytnx_int64 &idx) const
Apply a twist (or braids/self-swap) operation to a given bond; No effect for bosonic tensors; for a f...
Definition UniTensor.hpp:3768
UniTensor apply() const
Apply fermionic signflips to the UniTensor, such that all elements calling signflip() on the output t...
Definition UniTensor.hpp:3850
UniTensor Dagger() const
Take the conjugate transpose to the UniTensor.
Definition UniTensor.hpp:5409
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.
const std::vector< Tensor > & get_blocks_(const bool &silent=false) const
Get all the blocks of the UniTensor, inplacely.
Definition UniTensor.hpp:4327
UniTensor & relabels_(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:3496
const Tensor & get_block_(const std::initializer_list< cytnx_int64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:4288
bool elem_exists(const std::vector< cytnx_uint64 > &locator) const
Given the locator, check if the element exists.
Definition UniTensor.hpp:5481
UniTensor & Sub_(const UniTensor &rhs)
The subtraction function of the UniTensor.
Definition UniTensor.hpp:4840
UniTensor relabels(const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:3316
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:4743
const Tensor & get_block_(const cytnx_uint64 &idx=0) const
Get the shared view of the block for the given block index.
Definition UniTensor.hpp:4181
UniTensor & relabel_(const std::vector< std::string > &old_labels, const std::vector< std::string > &new_labels)
relabel part or all of the labels in UniTensor by given new labels
Definition UniTensor.hpp:3402
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 legs of the UniTensor, inplacely.
Definition UniTensor.hpp:3654
const Bond & bond_(const std::string &label) const
Definition UniTensor.hpp:3162
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 an identity UniTensor with two bonds.
Definition UniTensor.hpp:5724
Bond & bond_(const cytnx_uint64 &idx)
Definition UniTensor.hpp:3160
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 Inv(double clip=-1.) const
Element-wise (pseudo-)inverse.
UniTensor relabel(const cytnx_int64 &inx, const std::string &new_label) const
rebabel the legs in the UniTensor by given index.
Definition UniTensor.hpp:3526
UniTensor Mul(const UniTensor &rhs) const
The multiplication function of the UniTensor.
UniTensor & reshape_(const std::vector< cytnx_int64 > &new_shape, const cytnx_uint64 &rowrank=0)
Reshape the UniTensor, inplacely.
Definition UniTensor.hpp:4639
void print_diagram(const bool &bond_info=false) const
Plot the diagram of the UniTensor.
Definition UniTensor.hpp:3870
UniTensor relabels(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:3452
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:5607
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:3139
UniTensor & relabel_(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels)
Definition UniTensor.hpp:3471
cytnx_int64 get_index(std::string label) const
Get the index of an desired label string.
Definition UniTensor.hpp:3146
UniTensor & to_(const int &device)
move the current UniTensor to the assigned device (inplace).
Definition UniTensor.hpp:3205
const std::vector< Bond > & bonds() const
Get the bonds of the UniTensor.
Definition UniTensor.hpp:3152
Tensor get_block(const std::vector< std::string > &labels, const std::vector< cytnx_uint64 > &qidx, const bool &force=false) const
Definition UniTensor.hpp:4167
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:5594
UniTensor & Transpose_()
Take the transpose of the UniTensor, inplacely.
Definition UniTensor.hpp:5299
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 & put_block(Tensor &in, const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx, const bool &force)
Definition UniTensor.hpp:4441
UniTensor clone() const
Clone (deep copy) the UniTensor.
Definition UniTensor.hpp:3229
vec2d< cytnx_uint64 > & get_itoi()
Definition UniTensor.hpp:5628
void print_blocks(const bool &full_info=true) const
Print all blocks of the UniTensor.
Definition UniTensor.hpp:3878
Scalar::Sproxy item() const
Definition UniTensor.hpp:3024
const vec2d< cytnx_uint64 > & get_itoi() const
get the q-indices on each leg for all the blocks
Definition UniTensor.hpp:5627
std::string device_str() const
Return the device of the UniTensor in 'string' form.
Definition UniTensor.hpp:3091
UniTensor & put_block_(Tensor &in, const std::vector< std::string > &lbls, const std::vector< cytnx_int64 > &qidx, const bool &force)
Definition UniTensor.hpp:4537
UniTensor relabels(const std::vector< std::string > &new_labels) const
Definition UniTensor.hpp:3287
UniTensor relabel(const std::initializer_list< char * > &old_labels, const std::initializer_list< char * > &new_labels) const
Definition UniTensor.hpp:3427
UniTensor Sub(const UniTensor &rhs) const
The subtraction function of the UniTensor.
UniTensor & Conj_()
Apply complex conjugate on each entry of the UniTensor.
Definition UniTensor.hpp:5268
UniTensor operator[](const std::vector< cytnx_int64 > &accessors) const
Definition UniTensor.hpp:4576
UniTensor relabel(const std::initializer_list< char * > &new_labels) const
relables all of the labels in UniTensor.
Definition UniTensor.hpp:3297
cytnx_uint64 Nblocks() const
Return the number of blocks in the UniTensor.
Definition UniTensor.hpp:3037
Tensor get_block(const std::vector< cytnx_uint64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:4162
void Save(const char *fname) const
save a UniTensor to file
Bond bond(const cytnx_uint64 &idx) const
Definition UniTensor.hpp:3165
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:5552
Tensor get_block(const std::initializer_list< cytnx_int64 > &qnum, const bool &force=false) const
Definition UniTensor.hpp:4152
UniTensor & relabels_(const std::vector< std::string > &new_labels)
Definition UniTensor.hpp:3257
const Scalar::Sproxy at(const std::vector< cytnx_uint64 > &locator) const
Get an element at a specific location.
Definition UniTensor.hpp:4013
int uten_type() const
Return the UniTensor type (cytnx::UTenType) of the UniTensor.
Definition UniTensor.hpp:3064
Tensor & get_block_(const cytnx_uint64 &idx=0)
Definition UniTensor.hpp:4189
#define cytnx_warning_msg(is_true, format,...)
Definition cytnx_error.hpp:65
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:27
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)
Perform the trace over two legs of a UniTensor.
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.
@ Void
Definition Symmetry.hpp:32
Tensor arange(const cytnx_int64 &Nelem)
Create a rank-1 Tensor with incremental unsigned integer elements in the range [0,...
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 a rank-1 Tensor with all elements initialized to 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 a rank-1 Tensor with all elements initialized to zero.
Tensor identity(const cytnx_uint64 &Dim, const unsigned int &dtype=Type.Double, const int &device=Device.cpu)
Create a square rank-2 Tensor with the diagonal initialized to one and all other elements set to zero...