Skip to content

refactor label handling - #310

Open
jhauschild wants to merge 3 commits into
mainfrom
refactor_labelled_legs
Open

jhauschild wants to merge 3 commits into
mainfrom
refactor_labelled_legs

Conversation

@jhauschild

@jhauschild jhauschild commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Summary

This PR adresses the first part of #254: It renames the LabelledLegs class to LegLabels, and removes the LabelledLegs from the Tensor / TensorPlaceholder MRO, i.e. they are no longer subclasses, but now own a LegLabels labels instance member instead.
This comes with an few changes for the calling interface, as given below (and in docs/cpp_conversion/convert_LegLabels.md). I hope/think that these should make the calls actually more intuitive.

Moreover, I opted to replace the None standing for "no label set" with an empty string, i.e. non-set labels appear/need to be set as empty strings , unifying the type for the label list.

Call-site map (Python)

Old New
LabelledLegs LegLabels
t.labels / t.labels() as a list t.labels (LegLabels); copy via t.labels.as_list()
t.set_labels(x) t.labels.set(x) or t.labels = x
t.set_label(i, x) t.labels[i] = x
t.relabel(m) t.labels.update(m)
t.get_leg_idcs(x)[0] t.labels.index(x)
t.get_leg_idcs([...]) t.labels.indices([...])
t.has_label(...) t.labels.has(...) or 'x' in t.labels
t.labels_are(...) t.labels.are(...)
t.is_fully_labelled t.labels.is_fully_labelled
t._labels / t._labelmap remove (compare t.labels or use as_list())
for x in t.labels / list(t.labels) for x in t.labels.as_list() / t.labels.as_list()
assert t.labels == [a, None, b] assert t.labels == [a, '', b]

Label values

Old New
OptionalLabel / std::optional<std::string> std::string
OptionalLabels std::vector<std::string> (LegLabelList)
std::nullopt / Python None as unset ""
if (lab) / lab.has_value() !lab.empty()

LegLabels supports equality, len, [] get/set (int or str key), and
assignment from a sequence. It does not implement __iter__.

relabel1 / relabel2 kwargs on compose / tdot / outer / etc. are unchanged
(function arguments, not tensor methods).

Chaining note: old t.relabel(m) returned self; t.labels.update(m) returns
the LegLabels member. Split chains:

# old: expect = move_leg(...).relabel({...})
expect = move_leg(...)
expect.labels.update({...})

HDF5

  • Nested "labels" stores a string list; load old None entries as "".
  • Standalone roundtrips: LegLabels::{save_hdf5,from_hdf5}.

Bindings / stubs

  • pybind/tensors/py_labels.cpp: bind LegLabels; sequences of str only.
  • Drop nested labels property and _labelmap from the old holder API.
  • lasyten/_core.pyi: list[str], not list[str | None].

@jhauschild

Copy link
Copy Markdown
Member Author

This is ready for merge, but requires downstream changes, see tenpy/tenpy#715

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant