Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/cpp/tensors/labels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ labels.h

Declared in ``include/lasyten/tensors/labels.h``.

lasyten::LabelledLegs
-------------------
lasyten::LegLabels
----------------

.. doxygenclass:: lasyten::LabelledLegs
.. doxygenclass:: lasyten::LegLabels
:project: lasyten
:members:
:undoc-members:
Expand Down
5 changes: 5 additions & 0 deletions docs/cpp_conversion/convert_LabelledLegs.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Conversion of LabelledLegs (+ label helpers)

> **Rename:** `LabelledLegs` was refactored into composed `LegLabels`
> (`Tensor.labels`). For the mechanical call-site / type replacement summary used
> by open PRs, see [convert_LegLabels.md](convert_LegLabels.md). This file keeps
> the historical batch-1–2 conversion notes.

## metadata

- original python name: `LabelledLegs` (+ helpers in same batch)
Expand Down
65 changes: 65 additions & 0 deletions docs/cpp_conversion/convert_LegLabels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Conversion note: `LabelledLegs` → `LegLabels` (composition)

Mechanical replacement summary for open tenpy / lasyten branches and PRs that still
touch the old label API. Prefer this file over
[convert_LabelledLegs.md](convert_LabelledLegs.md) (historical batch notes).

## Type / MRO

- Rename class `LabelledLegs` → `LegLabels`.
- `Tensor` / `TensorPlaceholder` **compose** a `LegLabels labels` member; they no
longer inherit `LabelledLegs`.
- Keep `tensor.num_legs` on `Tensor` (synced with `labels.size()`).

## 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()` |

## 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]` |

`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:

```python
# 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]`.
21 changes: 12 additions & 9 deletions docs/intro/from_np_conserved.rst
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,15 @@ Differences:
- Dual labels use a trailing ``*``, same as TeNPy ``Array.conj()``. Combined
pipes still use ``(a.b)``. Avoid ``( ) . ? ! *`` inside a *single* (not
combined/dual) label; see :func:`~lasyten.tensors.is_valid_leg_label`.
- Set labels with :meth:`~lasyten.tensors.LabelledLegs.set_labels` /
:meth:`~lasyten.tensors.LabelledLegs.set_label` /
:meth:`~lasyten.tensors.LabelledLegs.relabel` (in-place). There is no
``iset_leg_labels``.
- Read them from :attr:`~lasyten.tensors.LabelledLegs.labels`,
:attr:`~lasyten.tensors.Tensor.codomain_labels`,
- Unset labels are empty strings (``""``), not ``None``.
- Each tensor owns a :class:`~lasyten.tensors.LegLabels` member
``t.labels``. Assign a full list with ``t.labels = [...]`` or
``t.labels.set([...])``, rename with ``t.labels.update({...})``, and set
one entry with ``t.labels[i] = ...`` or ``t.labels['old'] = 'new'``. There
is no ``iset_leg_labels`` / ``set_labels`` / ``relabel``.
- Compare or index via ``t.labels``; use ``t.labels.as_list()`` when a real
Python list is required (``LegLabels`` is not iterable). Read slices with
:attr:`~lasyten.tensors.Tensor.codomain_labels` /
:attr:`~lasyten.tensors.Tensor.domain_labels`. There is no
``get_leg_labels()``.
- Duplicate labels after a contraction are dropped (as in TeNPy). Optional
Expand All @@ -285,9 +288,9 @@ Differences:

.. code-block:: python

A.set_labels(['p', 'vL', 'vR']) # TeNPy: A.iset_leg_labels(...)
A.relabel({'vL': 'vR', 'vR': 'vL'})
A.set_label(0, 'p0')
A.labels = ['p', 'vL', 'vR'] # TeNPy: A.iset_leg_labels(...)
A.labels.update({'vL': 'vR', 'vR': 'vL'})
A.labels[0] = 'p0'


Contractions
Expand Down
6 changes: 3 additions & 3 deletions docs/python/lasyten.tensors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ Classes and functions imported from the pybind11 module :mod:`lasyten._core`.

.. lasyten-inheritance-diagram::

lasyten.tensors.LabelledLegs
--------------------------
lasyten.tensors.LegLabels
-----------------------

.. autoclass:: lasyten.tensors.LabelledLegs
.. autoclass:: lasyten.tensors.LegLabels
:members:
:undoc-members:
:show-inheritance:
Expand Down
25 changes: 12 additions & 13 deletions include/lasyten/symmetries/spaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,8 @@ class ElementarySpace

/// Direct sum with `others`, always wrapped as a `DirectSumSpace` (even if `others`
/// is empty and no `summand_labels` are given).
[[nodiscard]] Ptr direct_sum(
std::vector<Ptr> const& others,
std::optional<OptionalLabels> summand_labels = std::nullopt) const;
[[nodiscard]] Ptr direct_sum(std::vector<Ptr> const& others,
std::optional<LegLabelList> summand_labels = std::nullopt) const;

Space::Ptr drop_symmetry(std::optional<std::vector<int64>> which = std::nullopt) override;

Expand Down Expand Up @@ -473,11 +472,11 @@ class DirectSumSpace : public ElementarySpace
std::vector<ElementarySpace::Ptr> spaces;

/// Optional label per summand (parallel to `spaces`; `nullopt` entries are unlabeled).
OptionalLabels summand_labels;
LegLabelList summand_labels;

explicit DirectSumSpace(std::vector<ElementarySpace::Ptr> spaces,
bool is_dual = false,
std::optional<OptionalLabels> summand_labels = std::nullopt);
std::optional<LegLabelList> summand_labels = std::nullopt);
~DirectSumSpace() override = default;

void test_sanity() const override;
Expand All @@ -491,7 +490,7 @@ class DirectSumSpace : public ElementarySpace
[[nodiscard]] static Ptr from_spaces(
std::vector<ElementarySpace::Ptr> spaces,
bool is_dual = false,
std::optional<OptionalLabels> summand_labels = std::nullopt);
std::optional<LegLabelList> summand_labels = std::nullopt);

/// Resolve a summand reference (index or label) to a normalized, non-negative index.
[[nodiscard]] int64 get_summand_idx(SummandRef which) const;
Expand Down Expand Up @@ -558,7 +557,7 @@ class DirectSumSpace : public ElementarySpace
std::optional<std::vector<SummandRef>> keep_indices = std::nullopt,
std::optional<std::vector<SummandRef>> discard_indices = std::nullopt,
std::shared_ptr<TensorBackend> backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<std::string> device = std::nullopt) const;

/// Inclusion Mask onto the union of selected summands (dagger of the projection).
Expand All @@ -573,7 +572,7 @@ class DirectSumSpace : public ElementarySpace
std::optional<std::vector<SummandRef>> keep_indices = std::nullopt,
std::optional<std::vector<SummandRef>> discard_indices = std::nullopt,
std::shared_ptr<TensorBackend> backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<std::string> device = std::nullopt) const;

/// Projection Mask onto summand ``which`` (index or label).
Expand All @@ -586,7 +585,7 @@ class DirectSumSpace : public ElementarySpace
[[nodiscard]] MaskPtr projection_onto_summand(
SummandRef which,
std::shared_ptr<TensorBackend> backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<std::string> device = std::nullopt) const;

/// Inclusion Mask of summand ``which`` (index or label; dagger of the projection).
Expand All @@ -596,7 +595,7 @@ class DirectSumSpace : public ElementarySpace
[[nodiscard]] MaskPtr inclusion_of_summand(
SummandRef which,
std::shared_ptr<TensorBackend> backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<std::string> device = std::nullopt) const;

/// Unit vector selecting summand ``i``.
Expand All @@ -608,7 +607,7 @@ class DirectSumSpace : public ElementarySpace
[[nodiscard]] SymmetricTensorPtr unit_vector_of_summand(
int64 i,
std::shared_ptr<TensorBackend> backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<Dtype> dtype = std::nullopt,
std::optional<std::string> device = std::nullopt) const;

Expand Down Expand Up @@ -644,12 +643,12 @@ class DirectSumSpace : public ElementarySpace
SectorArray defining_sectors;
std::vector<int64> multiplicities;
std::optional<std::vector<int64>> basis_perm;
OptionalLabels summand_labels;
LegLabelList summand_labels;
};

static Prepared prepare(std::vector<ElementarySpace::Ptr> spaces,
bool is_dual,
std::optional<OptionalLabels> summand_labels);
std::optional<LegLabelList> summand_labels);

DirectSumSpace(Prepared prepared, bool is_dual);

Expand Down
15 changes: 5 additions & 10 deletions include/lasyten/tensors/charged_tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class ChargedTensor : public Tensor
std::variant<ElementarySpace::Ptr, Sector> charge);

/// Utility like `_init_parse_labels`, but also returns invariant part labels.
[[nodiscard]] static std::tuple<OptionalLabels, OptionalLabels> _parse_inv_labels(
std::optional<OptionalLabels> labels,
[[nodiscard]] static std::tuple<LegLabelList, LegLabelList> _parse_inv_labels(
std::optional<LegLabelList> labels,
TensorProduct::Ptr const& codomain,
TensorProduct::Ptr const& domain);

Expand All @@ -83,7 +83,7 @@ class ChargedTensor : public Tensor
TensorProduct::Ptr domain = nullptr,
BlockBackend::BlockPtr charged_state = nullptr,
TensorBackend::Ptr backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<Dtype> dtype = std::nullopt,
std::optional<std::string> device = std::nullopt);

Expand All @@ -94,7 +94,7 @@ class ChargedTensor : public Tensor
TensorProduct::Ptr domain = nullptr,
std::optional<std::variant<ElementarySpace::Ptr, Sector>> charge = std::nullopt,
TensorBackend::Ptr backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<Dtype> dtype = std::nullopt,
std::optional<std::string> device = std::nullopt,
float64 tol = 1e-6,
Expand Down Expand Up @@ -128,7 +128,7 @@ class ChargedTensor : public Tensor
std::variant<ElementarySpace::Ptr, Sector> charge,
BlockBackend::BlockPtr charged_state = nullptr,
TensorBackend::Ptr backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
Dtype dtype = Dtype::Complex128,
std::optional<std::string> device = std::nullopt);

Expand Down Expand Up @@ -206,11 +206,6 @@ class ChargedTensor : public Tensor
std::string const& indent,
bool use_symm_str = false) const override;

/// Set a single label at given position, in-place. Return the modified instance.
LabelledLegs& set_label(int64 pos, OptionalLabel label) override;
/// Set the given labels, in-place. Return the modified instance.
Tensor& set_labels(OptionalLabels labels) override;

/// Convert to a tensor with a different backend.
///
/// @param backend The backend of the result.
Expand Down
14 changes: 7 additions & 7 deletions include/lasyten/tensors/constructors.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace lasyten {
/// @param diagonal If true, return a diagonal identity.
[[nodiscard]] TensorPtr eye(Space::Ptr leg,
TensorBackend::Ptr backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
Dtype dtype = Dtype::Float64,
std::optional<std::string> device = std::nullopt,
bool diagonal = true);
Expand All @@ -43,7 +43,7 @@ namespace lasyten {
TensorProduct::Ptr codomain,
TensorProduct::Ptr domain = nullptr,
TensorBackend::Ptr backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<Dtype> dtype = std::nullopt,
std::optional<std::string> device = std::nullopt);

Expand All @@ -60,7 +60,7 @@ namespace lasyten {
TensorProduct::Ptr codomain,
TensorProduct::Ptr domain = nullptr,
TensorBackend::Ptr backend = nullptr,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<Dtype> dtype = std::nullopt,
std::optional<std::string> device = std::nullopt,
bool understood_braiding = false);
Expand Down Expand Up @@ -92,7 +92,7 @@ namespace lasyten {
std::optional<int64> legs_pos = std::nullopt,
std::optional<int64> codomain_pos = std::nullopt,
std::optional<int64> domain_pos = std::nullopt,
OptionalLabel label = std::nullopt,
std::string label = "",
bool is_dual = false);

/// Return a zero tensor with the same type, dtype, legs, backend and labels.
Expand Down Expand Up @@ -151,10 +151,10 @@ namespace lasyten {
/// that column.
[[nodiscard]] TensorPtr tensor_from_grid(
std::vector<std::vector<TensorPtr>> grid,
std::optional<OptionalLabels> labels = std::nullopt,
std::optional<LegLabelList> labels = std::nullopt,
std::optional<Dtype> dtype = std::nullopt,
std::optional<OptionalLabels> row_labels = std::nullopt,
std::optional<OptionalLabels> col_labels = std::nullopt,
std::optional<LegLabelList> row_labels = std::nullopt,
std::optional<LegLabelList> col_labels = std::nullopt,
std::optional<std::vector<ElementarySpace::Ptr>> row_summands = std::nullopt,
std::optional<std::vector<ElementarySpace::Ptr>> col_summands = std::nullopt);

Expand Down
Loading
Loading