[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-nvidia-cuequivariance":3,"mdc-52u7t7-key":34,"related-repo-nvidia-cuequivariance":3590,"related-org-nvidia-cuequivariance":3627},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":32,"mdContent":33},"cuequivariance","build equivariant tensor products with cuEquivariance","Define custom groups (Irrep subclasses), build segmented tensor products with CG coefficients, create equivariant polynomials and IrDictPolynomials, and use built-in descriptors (linear, tensor products, spherical harmonics). Use when working with cuequivariance group theory, irreps, or segmented polynomials.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"nvidia","NVIDIA","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fnvidia.png",[12,16,19,20],{"name":13,"slug":14,"type":15},"Deep Learning","deep-learning","tag",{"name":17,"slug":18,"type":15},"Mathematics","mathematics",{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},"Engineering","engineering",409,"https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FcuEquivariance","2026-07-14T05:31:46.310103",null,36,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":31},[],"cuEquivariance is a math library that is a collective of low-level primitives and tensor ops to accelerate widely-used models, like DiffDock, MACE, Allegro and NEQUIP, based on equivariant neural networks. Also includes kernels for accelerated structure prediction.","https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FcuEquivariance\u002Ftree\u002FHEAD\u002Fcuequivariance\u002Fcuequivariance","---\nname: cuequivariance\ndescription: Define custom groups (Irrep subclasses), build segmented tensor products with CG coefficients, create equivariant polynomials and IrDictPolynomials, and use built-in descriptors (linear, tensor products, spherical harmonics). Use when working with cuequivariance group theory, irreps, or segmented polynomials.\n---\n\n# cuequivariance: Groups, Irreps, and Segmented Polynomials\n\n## Overview\n\n`cuequivariance` (imported as `cue`) provides two core abstractions:\n\n1. **Group theory**: `Irrep` subclasses define irreducible representations of Lie groups (SO3, O3, SU2, or custom). `Irreps` manages collections with multiplicities.\n2. **Segmented polynomials**: `SegmentedTensorProduct` describes tensor contractions over segments of varying shape, linked by `Path` objects carrying Clebsch-Gordan coefficients. `SegmentedPolynomial` wraps multiple STPs into a polynomial with named inputs\u002Foutputs. Two higher-level wrappers attach group representations:\n   - `EquivariantPolynomial` — dense operands with `IrrepsAndLayout` metadata\n   - `IrDictPolynomial` — operands already split by irrep, with per-group `Irreps` metadata for the `dict[Irrep, Array]` workflow\n\n## Defining a custom group\n\nSubclass `cue.Irrep` (a frozen dataclass) and implement:\n\n```python\nfrom __future__ import annotations\nimport dataclasses\nimport re\nfrom typing import Iterator\nimport numpy as np\nimport cuequivariance as cue\n\n@dataclasses.dataclass(frozen=True)\nclass Z2(cue.Irrep):\n    odd: bool  # dataclass field -- required for correct __eq__ and __hash__\n\n    # No __init__ needed -- @dataclass(frozen=True) generates it: Z2(odd=True)\n\n    @classmethod\n    def regexp_pattern(cls) -> re.Pattern:\n        # Pattern whose first group is passed to from_string\n        return re.compile(r\"(odd|even)\")\n\n    @classmethod\n    def from_string(cls, string: str) -> Z2:\n        return cls(odd=string == \"odd\")\n\n    def __repr__(rep: Z2) -> str:\n        return \"odd\" if rep.odd else \"even\"\n\n    def __mul__(rep1: Z2, rep2: Z2) -> Iterator[Z2]:\n        # Selection rule: which irreps appear in the tensor product rep1 x rep2\n        return [Z2(odd=rep1.odd ^ rep2.odd)]\n\n    @classmethod\n    def clebsch_gordan(cls, rep1: Z2, rep2: Z2, rep3: Z2) -> np.ndarray:\n        # Shape: (num_paths, rep1.dim, rep2.dim, rep3.dim)\n        if rep3 in rep1 * rep2:\n            return np.array([[[[1]]]])\n        else:\n            return np.zeros((0, 1, 1, 1))\n\n    @property\n    def dim(rep: Z2) -> int:\n        return 1\n\n    def __lt__(rep1: Z2, rep2: Z2) -> bool:\n        # Ordering for sorting; dimension is compared first by the base class\n        return rep1.odd \u003C rep2.odd\n\n    @classmethod\n    def iterator(cls) -> Iterator[Z2]:\n        # Must yield trivial irrep first\n        for odd in [False, True]:\n            yield Z2(odd=odd)\n\n    def discrete_generators(rep: Z2) -> np.ndarray:\n        # Shape: (num_generators, dim, dim)\n        if rep.odd:\n            return -np.ones((1, 1, 1))\n        else:\n            return np.ones((1, 1, 1))\n\n    def continuous_generators(rep: Z2) -> np.ndarray:\n        # Shape: (lie_dim, dim, dim) -- Z2 is discrete, so lie_dim=0\n        return np.zeros((0, rep.dim, rep.dim))\n\n    def algebra(self) -> np.ndarray:\n        # Shape: (lie_dim, lie_dim, lie_dim) -- structure constants [X_i, X_j] = A_ijk X_k\n        return np.zeros((0, 0, 0))\n\n\n# Usage:\nirreps = cue.Irreps(Z2, \"3x odd + 2x even\")  # dim=5\n```\n\n### Required methods summary\n\n| Method | Returns | Purpose |\n|--------|---------|---------|\n| `regexp_pattern()` | `re.Pattern` | Parse string like `\"1\"`, `\"0e\"`, `\"odd\"` |\n| `from_string(s)` | `Irrep` | Construct from matched string |\n| `__repr__` | `str` | Canonical string form |\n| `__mul__(a, b)` | `Iterator[Irrep]` | Selection rule for tensor product |\n| `clebsch_gordan(a, b, c)` | `ndarray (n, d1, d2, d3)` | CG coefficients |\n| `dim` (property) | `int` | Dimension of representation |\n| `__lt__(a, b)` | `bool` | Ordering (dimension first, then custom) |\n| `iterator()` | `Iterator[Irrep]` | All irreps, trivial first |\n| `continuous_generators()` | `ndarray (lie_dim, dim, dim)` | Lie algebra generators |\n| `discrete_generators()` | `ndarray (n, dim, dim)` | Finite symmetry generators |\n| `algebra()` | `ndarray (lie_dim, lie_dim, lie_dim)` | Structure constants |\n\n### Built-in groups\n\n- **`cue.SO3(l)`**: 3D rotations. `l` is a non-negative integer. `dim = 2l+1`. String: `\"0\"`, `\"1\"`, `\"2\"`.\n- **`cue.O3(l, p)`**: 3D rotations + parity. `p=+1` (even) or `p=-1` (odd). String: `\"0e\"`, `\"1o\"`, `\"2e\"`.\n- **`cue.SU2(j)`**: Spin group. `j` is a non-negative half-integer. String: `\"0\"`, `\"1\u002F2\"`, `\"1\"`.\n\n## Irreps and layout\n\n```python\nirreps = cue.Irreps(\"SO3\", \"16x0 + 4x1 + 2x2\")  # 16 scalars, 4 vectors, 2 rank-2\nirreps.dim   # 16*1 + 4*3 + 2*5 = 38\n\nfor mul, ir in irreps:\n    print(mul, ir, ir.dim)  # 16 0 1, then 4 1 3, then 2 2 5\n```\n\n`IrrepsLayout` controls memory order within each `(mul, ir)` block:\n\n- `cue.ir_mul`: data ordered as `(ir.dim, mul)` — **used by all descriptors and ir_dict internally**\n- `cue.mul_ir`: data ordered as `(mul, ir.dim)` — **used by nnx `dict[Irrep, Array]` and PyTorch**\n\n`IrrepsAndLayout` combines irreps with a layout into a `Rep`:\n\n```python\nrep = cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x0 + 2x1\"), cue.ir_mul)\nrep.dim  # 10\n```\n\n## Building a SegmentedTensorProduct from scratch\n\nThe subscripts string uses Einstein notation. Operands are comma-separated, coefficient modes follow `+`.\n\n```python\n# Matrix-vector multiply: y_i = sum_j M_ij * x_j\nd = cue.SegmentedTensorProduct.from_subscripts(\"ij,j,i\")\nd.add_segment(0, (3, 4))  # operand 0: matrix segment of shape (3, 4)\nd.add_segment(1, (4,))     # operand 1: vector of size 4\nd.add_segment(2, (3,))     # operand 2: output vector of size 3\nd.add_path(0, 0, 0, c=1.0) # link segments 0,0,0 with coefficient=1.0\n\npoly = cue.SegmentedPolynomial.eval_last_operand(d)  # last operand becomes output\n[y] = poly(M_flat, x)  # numpy evaluation\n```\n\n### Multi-segment STP (how descriptors work internally)\n\nDescriptors build STPs with multiple segments per operand. Each segment corresponds to an irrep block:\n\n```python\n# Linear equivariant map: output[iv] = sum_u weight[uv] * input[iu]\nd = cue.SegmentedTensorProduct.from_subscripts(\"uv,iu,iv\")\n\n# Segment for l=1: ir_dim=3, mul_in=2, mul_out=5\ns_in_0 = d.add_segment(1, (3, 2))    # input block\ns_out_0 = d.add_segment(2, (3, 5))   # output block\nd.add_path((2, 5), s_in_0, s_out_0, c=1.0)\n\n# Segment for l=0: ir_dim=1, mul_in=4, mul_out=3\ns_in_1 = d.add_segment(1, (1, 4))\ns_out_1 = d.add_segment(2, (1, 3))\nd.add_path((4, 3), s_in_1, s_out_1, c=1.0)\n```\n\n### Weights operand\n\nFor weighted tensor products (subscript starting with `uvw` or `uv`), the first operand is always weights. The weight segment shape is `(mul_1, mul_2, ...)` matching the multiplicity modes. The weights operand gets `new_scalars()` irreps since weights are invariant.\n\n### CG coefficients as path coefficients\n\n```python\nd = cue.SegmentedTensorProduct.from_subscripts(\"uvw,iu,jv,kw+ijk\")\n# For each pair of input irreps and each output irrep in the selection rule:\nfor cg in cue.clebsch_gordan(ir1, ir2, ir3):\n    # cg has shape (ir1.dim, ir2.dim, ir3.dim)\n    d.add_path((mul1, mul2, mul3), seg_in1, seg_in2, seg_out, c=cg)\n```\n\n## Descriptors\n\nAll descriptors come in two variants:\n\n- **Original** — returns `EquivariantPolynomial` with dense operands\n- **`_ir_dict`** — returns `IrDictPolynomial` with operands already split by irrep\n\n### EquivariantPolynomial descriptors\n\n```python\n# Fully connected tensor product (all input-output irrep combinations)\ne = cue.descriptors.fully_connected_tensor_product(\n    16 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n    16 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n    16 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n)\n\n# Channelwise tensor product (same-channel only, sparse)\ne = cue.descriptors.channelwise_tensor_product(\n    64 * cue.Irreps(\"SO3\", \"0 + 1\"), cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"), simplify_irreps3=True,\n)\n\n# Full (weightless) tensor product\ne = cue.descriptors.full_tensor_product(\n    cue.Irreps(\"SO3\", \"2x0 + 1x1\"), cue.Irreps(\"SO3\", \"0 + 1\"),\n)\n\n# Elementwise tensor product (paired channels)\ne = cue.descriptors.elementwise_tensor_product(\n    cue.Irreps(\"SO3\", \"4x0 + 4x1\"), cue.Irreps(\"SO3\", \"4x0 + 4x1\"),\n)\n\n# Linear equivariant map (weight x input)\ne = cue.descriptors.linear(\n    cue.Irreps(\"SO3\", \"4x0 + 2x1\"),\n    cue.Irreps(\"SO3\", \"3x0 + 5x1\"),\n)\n\n# Spherical harmonics\ne = cue.descriptors.spherical_harmonics(cue.SO3(1), [0, 1, 2, 3])\n\n# Symmetric contraction (MACE-style)\ne = cue.descriptors.symmetric_contraction(\n    64 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n    64 * cue.Irreps(\"SO3\", \"0 + 1\"),\n    (1, 2, 3),\n)\n```\n\n### IrDictPolynomial descriptors\n\nEach `_ir_dict` variant returns an `IrDictPolynomial` whose polynomial is already split by irrep. The `input_irreps` and `output_irreps` tuples describe the operand groups.\n\n```python\n# Channelwise tensor product\ndesc = cue.descriptors.channelwise_tensor_product_ir_dict(\n    64 * cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n)\n# desc.polynomial       — SegmentedPolynomial, already split by irrep\n# desc.input_irreps     — (weight_irreps, irreps1, irreps2)\n# desc.output_irreps    — (irreps_out,)\n\n# Fully connected tensor product\ndesc = cue.descriptors.fully_connected_tensor_product_ir_dict(irreps1, irreps2, irreps3)\n\n# Full (weightless) tensor product\ndesc = cue.descriptors.full_tensor_product_ir_dict(irreps1, irreps2)\n\n# Elementwise tensor product\ndesc = cue.descriptors.elementwise_tensor_product_ir_dict(irreps1, irreps2)\n\n# Linear\ndesc = cue.descriptors.linear_ir_dict(irreps_in, irreps_out)\n\n# Spherical harmonics\ndesc = cue.descriptors.spherical_harmonics_ir_dict(cue.O3(1, -1), [0, 1, 2, 3])\n\n# Symmetric contraction\ndesc = cue.descriptors.symmetric_contraction_ir_dict(irreps_in, irreps_out, (1, 2, 3))\n```\n\n### IrDictPolynomial\n\n`IrDictPolynomial` pairs a `SegmentedPolynomial` (already split by irrep) with the `Irreps` that describe each operand group.\n\n```python\ndesc = cue.descriptors.channelwise_tensor_product_ir_dict(\n    32 * cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n)\n\ndesc.polynomial       # SegmentedPolynomial — each operand is one (mul, ir) block\ndesc.input_irreps     # (weight_irreps, irreps1, irreps2)\ndesc.output_irreps    # (irreps_out,)\n\n# Scale coefficients\nscaled_poly = desc.polynomial * 0.5\n\n# Access individual operand info\nfor i, op in enumerate(desc.polynomial.inputs):\n    print(f\"Input {i}: size={op.size}, num_segments={op.num_segments}\")\n```\n\nContract: for each `(mul, ir)` block in `input_irreps` \u002F `output_irreps`, the corresponding polynomial operand has size `mul * ir.dim`.\n\n### split_polynomial_by_irreps\n\nThe low-level function underlying `_ir_dict` descriptors. Splits one polynomial operand at irrep boundaries:\n\n```python\npoly = e.polynomial  # from an EquivariantPolynomial\npoly = cue.split_polynomial_by_irreps(poly, 2, irreps_sh)   # split input 2\npoly = cue.split_polynomial_by_irreps(poly, 1, irreps_in)   # split input 1\npoly = cue.split_polynomial_by_irreps(poly, -1, irreps_out) # split output\n```\n\n### EquivariantPolynomial key methods\n\n```python\ne.inputs     # tuple of Rep (group representations for each input)\ne.outputs    # tuple of Rep\ne.polynomial # the underlying SegmentedPolynomial\n\n# Numpy evaluation\n[out] = e(weights, input1, input2)\n\n# Preparing for uniform_1d execution (see cuequivariance_jax SKILL.md)\ne_ready = e.squeeze_modes().flatten_coefficient_modes()\n\n# Split an operand into per-irrep pieces (for ir_dict interface)\ne_split = e.split_operand_by_irrep(1).split_operand_by_irrep(-1)\n\n# Scale all coefficients\ne_scaled = e * 0.5\n\n# Fuse compatible STPs\ne_fused = e.fuse_stps()\n```\n\n### normalize_paths_for_operand\n\nCalled internally by descriptors. Normalizes path coefficients so that a random input produces unit-variance output for the specified operand. Critical for numerical stability.\n\n## SegmentedPolynomial structure\n\n```python\npoly = e.polynomial\npoly.num_inputs    # number of input operands\npoly.num_outputs   # number of output operands\npoly.inputs        # tuple of SegmentedOperand\npoly.outputs       # tuple of SegmentedOperand\npoly.operations    # tuple of (Operation, SegmentedTensorProduct)\n\n# Each operation maps buffers to STP operands\nfor op, stp in poly.operations:\n    print(op.buffers)  # e.g., (0, 1, 2) means inputs[0], inputs[1] -> outputs[0]\n    print(stp.subscripts)\n```\n\n### SegmentedOperand\n\n```python\noperand = poly.inputs[0]\noperand.num_segments     # how many segments\noperand.segments         # tuple of shape tuples, e.g., ((3, 4), (1, 2))\noperand.size             # total flattened size (sum of products of segment shapes)\noperand.ndim             # number of dimensions per segment\noperand.all_same_segment_shape()  # True if all segments have identical shape\noperand.segment_shape    # the common shape (only if all_same_segment_shape)\n```\n\n## Custom equivariant polynomial from scratch\n\n```python\nimport numpy as np\nimport cuequivariance as cue\n\n# Build a fully-connected SO3(1)xSO3(1)->SO3(0) tensor product manually\ncg = cue.clebsch_gordan(cue.SO3(1), cue.SO3(1), cue.SO3(0))  # shape (1, 3, 3, 1)\n\nd = cue.SegmentedTensorProduct.from_subscripts(\"uvw,iu,jv,kw+ijk\")\nd.add_segment(1, (3, 4))   # input1: 4x SO3(1), shape=(ir_dim, mul)\nd.add_segment(2, (3, 4))   # input2: 4x SO3(1)\nd.add_segment(3, (1, 16))  # output: 16x SO3(0) (4*4 fully connected)\n\nfor c in cg:\n    d.add_path((4, 4, 16), 0, 0, 0, c=c)\n\nd = d.normalize_paths_for_operand(-1)\n\npoly = cue.SegmentedPolynomial.eval_last_operand(d)\nep = cue.EquivariantPolynomial(\n    [\n        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\").new_scalars(d.operands[0].size), cue.ir_mul),\n        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\"), cue.ir_mul),\n        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\"), cue.ir_mul),\n    ],\n    [cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"16x0\"), cue.ir_mul)],\n    poly,\n)\n\n# Numpy evaluation\nw = np.random.randn(ep.inputs[0].dim)\nx = np.random.randn(ep.inputs[1].dim)\ny = np.random.randn(ep.inputs[2].dim)\n[out] = ep(w, x, y)\n```\n\n## Key file locations\n\n| Component | Path |\n|-----------|------|\n| `Irrep` base class | `cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep.py` |\n| `Rep` base class | `cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Frep.py` |\n| `SO3` | `cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep_so3.py` |\n| `O3` | `cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep_o3.py` |\n| `SU2` | `cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep_su2.py` |\n| `Irreps` | `cuequivariance\u002Fgroup_theory\u002Firreps_array\u002Firreps.py` |\n| `IrrepsLayout` | `cuequivariance\u002Fgroup_theory\u002Firreps_array\u002Firreps_layout.py` |\n| `IrrepsAndLayout` | `cuequivariance\u002Fgroup_theory\u002Firreps_array\u002Firreps_and_layout.py` |\n| `SegmentedTensorProduct` | `cuequivariance\u002Fsegmented_polynomials\u002Fsegmented_tensor_product.py` |\n| `SegmentedPolynomial` | `cuequivariance\u002Fsegmented_polynomials\u002Fsegmented_polynomial.py` |\n| `EquivariantPolynomial` | `cuequivariance\u002Fgroup_theory\u002Fequivariant_polynomial.py` |\n| `IrDictPolynomial` | `cuequivariance\u002Fgroup_theory\u002Fir_dict_polynomial.py` |\n| Descriptors | `cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002F` |\n| Tensor product descriptors | `cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002Firreps_tp.py` |\n| `spherical_harmonics` | `cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002Fspherical_harmonics_.py` |\n| `symmetric_contraction` | `cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002Fsymmetric_contractions.py` |\n",{"data":35,"body":36},{"name":4,"description":6},{"type":37,"children":38},"root",[39,48,55,75,189,195,208,824,831,1171,1177,1322,1328,1374,1393,1449,1467,1490,1496,1508,1586,1592,1597,1698,1704,1741,1747,1794,1800,1805,1845,1851,2149,2155,2190,2402,2407,2431,2559,2592,2597,2609,2648,2654,2800,2805,2810,2816,2910,2916,2979,2985,3236,3242,3584],{"type":40,"tag":41,"props":42,"children":44},"element","h1",{"id":43},"cuequivariance-groups-irreps-and-segmented-polynomials",[45],{"type":46,"value":47},"text","cuequivariance: Groups, Irreps, and Segmented Polynomials",{"type":40,"tag":49,"props":50,"children":52},"h2",{"id":51},"overview",[53],{"type":46,"value":54},"Overview",{"type":40,"tag":56,"props":57,"children":58},"p",{},[59,65,67,73],{"type":40,"tag":60,"props":61,"children":63},"code",{"className":62},[],[64],{"type":46,"value":4},{"type":46,"value":66}," (imported as ",{"type":40,"tag":60,"props":68,"children":70},{"className":69},[],[71],{"type":46,"value":72},"cue",{"type":46,"value":74},") provides two core abstractions:",{"type":40,"tag":76,"props":77,"children":78},"ol",{},[79,107],{"type":40,"tag":80,"props":81,"children":82},"li",{},[83,89,91,97,99,105],{"type":40,"tag":84,"props":85,"children":86},"strong",{},[87],{"type":46,"value":88},"Group theory",{"type":46,"value":90},": ",{"type":40,"tag":60,"props":92,"children":94},{"className":93},[],[95],{"type":46,"value":96},"Irrep",{"type":46,"value":98}," subclasses define irreducible representations of Lie groups (SO3, O3, SU2, or custom). ",{"type":40,"tag":60,"props":100,"children":102},{"className":101},[],[103],{"type":46,"value":104},"Irreps",{"type":46,"value":106}," manages collections with multiplicities.",{"type":40,"tag":80,"props":108,"children":109},{},[110,115,116,122,124,130,132,138,140],{"type":40,"tag":84,"props":111,"children":112},{},[113],{"type":46,"value":114},"Segmented polynomials",{"type":46,"value":90},{"type":40,"tag":60,"props":117,"children":119},{"className":118},[],[120],{"type":46,"value":121},"SegmentedTensorProduct",{"type":46,"value":123}," describes tensor contractions over segments of varying shape, linked by ",{"type":40,"tag":60,"props":125,"children":127},{"className":126},[],[128],{"type":46,"value":129},"Path",{"type":46,"value":131}," objects carrying Clebsch-Gordan coefficients. ",{"type":40,"tag":60,"props":133,"children":135},{"className":134},[],[136],{"type":46,"value":137},"SegmentedPolynomial",{"type":46,"value":139}," wraps multiple STPs into a polynomial with named inputs\u002Foutputs. Two higher-level wrappers attach group representations:\n",{"type":40,"tag":141,"props":142,"children":143},"ul",{},[144,163],{"type":40,"tag":80,"props":145,"children":146},{},[147,153,155,161],{"type":40,"tag":60,"props":148,"children":150},{"className":149},[],[151],{"type":46,"value":152},"EquivariantPolynomial",{"type":46,"value":154}," — dense operands with ",{"type":40,"tag":60,"props":156,"children":158},{"className":157},[],[159],{"type":46,"value":160},"IrrepsAndLayout",{"type":46,"value":162}," metadata",{"type":40,"tag":80,"props":164,"children":165},{},[166,172,174,179,181,187],{"type":40,"tag":60,"props":167,"children":169},{"className":168},[],[170],{"type":46,"value":171},"IrDictPolynomial",{"type":46,"value":173}," — operands already split by irrep, with per-group ",{"type":40,"tag":60,"props":175,"children":177},{"className":176},[],[178],{"type":46,"value":104},{"type":46,"value":180}," metadata for the ",{"type":40,"tag":60,"props":182,"children":184},{"className":183},[],[185],{"type":46,"value":186},"dict[Irrep, Array]",{"type":46,"value":188}," workflow",{"type":40,"tag":49,"props":190,"children":192},{"id":191},"defining-a-custom-group",[193],{"type":46,"value":194},"Defining a custom group",{"type":40,"tag":56,"props":196,"children":197},{},[198,200,206],{"type":46,"value":199},"Subclass ",{"type":40,"tag":60,"props":201,"children":203},{"className":202},[],[204],{"type":46,"value":205},"cue.Irrep",{"type":46,"value":207}," (a frozen dataclass) and implement:",{"type":40,"tag":209,"props":210,"children":215},"pre",{"className":211,"code":212,"language":213,"meta":214,"style":214},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","from __future__ import annotations\nimport dataclasses\nimport re\nfrom typing import Iterator\nimport numpy as np\nimport cuequivariance as cue\n\n@dataclasses.dataclass(frozen=True)\nclass Z2(cue.Irrep):\n    odd: bool  # dataclass field -- required for correct __eq__ and __hash__\n\n    # No __init__ needed -- @dataclass(frozen=True) generates it: Z2(odd=True)\n\n    @classmethod\n    def regexp_pattern(cls) -> re.Pattern:\n        # Pattern whose first group is passed to from_string\n        return re.compile(r\"(odd|even)\")\n\n    @classmethod\n    def from_string(cls, string: str) -> Z2:\n        return cls(odd=string == \"odd\")\n\n    def __repr__(rep: Z2) -> str:\n        return \"odd\" if rep.odd else \"even\"\n\n    def __mul__(rep1: Z2, rep2: Z2) -> Iterator[Z2]:\n        # Selection rule: which irreps appear in the tensor product rep1 x rep2\n        return [Z2(odd=rep1.odd ^ rep2.odd)]\n\n    @classmethod\n    def clebsch_gordan(cls, rep1: Z2, rep2: Z2, rep3: Z2) -> np.ndarray:\n        # Shape: (num_paths, rep1.dim, rep2.dim, rep3.dim)\n        if rep3 in rep1 * rep2:\n            return np.array([[[[1]]]])\n        else:\n            return np.zeros((0, 1, 1, 1))\n\n    @property\n    def dim(rep: Z2) -> int:\n        return 1\n\n    def __lt__(rep1: Z2, rep2: Z2) -> bool:\n        # Ordering for sorting; dimension is compared first by the base class\n        return rep1.odd \u003C rep2.odd\n\n    @classmethod\n    def iterator(cls) -> Iterator[Z2]:\n        # Must yield trivial irrep first\n        for odd in [False, True]:\n            yield Z2(odd=odd)\n\n    def discrete_generators(rep: Z2) -> np.ndarray:\n        # Shape: (num_generators, dim, dim)\n        if rep.odd:\n            return -np.ones((1, 1, 1))\n        else:\n            return np.ones((1, 1, 1))\n\n    def continuous_generators(rep: Z2) -> np.ndarray:\n        # Shape: (lie_dim, dim, dim) -- Z2 is discrete, so lie_dim=0\n        return np.zeros((0, rep.dim, rep.dim))\n\n    def algebra(self) -> np.ndarray:\n        # Shape: (lie_dim, lie_dim, lie_dim) -- structure constants [X_i, X_j] = A_ijk X_k\n        return np.zeros((0, 0, 0))\n\n\n# Usage:\nirreps = cue.Irreps(Z2, \"3x odd + 2x even\")  # dim=5\n","python","",[216],{"type":40,"tag":60,"props":217,"children":218},{"__ignoreMap":214},[219,230,239,248,257,266,275,285,294,303,312,320,329,337,346,355,364,373,381,389,398,407,415,424,433,441,450,459,468,476,484,493,502,511,520,529,537,545,554,563,572,580,589,598,607,615,623,632,641,650,659,667,676,685,694,703,711,720,728,737,746,755,763,772,781,790,798,806,815],{"type":40,"tag":220,"props":221,"children":224},"span",{"class":222,"line":223},"line",1,[225],{"type":40,"tag":220,"props":226,"children":227},{},[228],{"type":46,"value":229},"from __future__ import annotations\n",{"type":40,"tag":220,"props":231,"children":233},{"class":222,"line":232},2,[234],{"type":40,"tag":220,"props":235,"children":236},{},[237],{"type":46,"value":238},"import dataclasses\n",{"type":40,"tag":220,"props":240,"children":242},{"class":222,"line":241},3,[243],{"type":40,"tag":220,"props":244,"children":245},{},[246],{"type":46,"value":247},"import re\n",{"type":40,"tag":220,"props":249,"children":251},{"class":222,"line":250},4,[252],{"type":40,"tag":220,"props":253,"children":254},{},[255],{"type":46,"value":256},"from typing import Iterator\n",{"type":40,"tag":220,"props":258,"children":260},{"class":222,"line":259},5,[261],{"type":40,"tag":220,"props":262,"children":263},{},[264],{"type":46,"value":265},"import numpy as np\n",{"type":40,"tag":220,"props":267,"children":269},{"class":222,"line":268},6,[270],{"type":40,"tag":220,"props":271,"children":272},{},[273],{"type":46,"value":274},"import cuequivariance as cue\n",{"type":40,"tag":220,"props":276,"children":278},{"class":222,"line":277},7,[279],{"type":40,"tag":220,"props":280,"children":282},{"emptyLinePlaceholder":281},true,[283],{"type":46,"value":284},"\n",{"type":40,"tag":220,"props":286,"children":288},{"class":222,"line":287},8,[289],{"type":40,"tag":220,"props":290,"children":291},{},[292],{"type":46,"value":293},"@dataclasses.dataclass(frozen=True)\n",{"type":40,"tag":220,"props":295,"children":297},{"class":222,"line":296},9,[298],{"type":40,"tag":220,"props":299,"children":300},{},[301],{"type":46,"value":302},"class Z2(cue.Irrep):\n",{"type":40,"tag":220,"props":304,"children":306},{"class":222,"line":305},10,[307],{"type":40,"tag":220,"props":308,"children":309},{},[310],{"type":46,"value":311},"    odd: bool  # dataclass field -- required for correct __eq__ and __hash__\n",{"type":40,"tag":220,"props":313,"children":315},{"class":222,"line":314},11,[316],{"type":40,"tag":220,"props":317,"children":318},{"emptyLinePlaceholder":281},[319],{"type":46,"value":284},{"type":40,"tag":220,"props":321,"children":323},{"class":222,"line":322},12,[324],{"type":40,"tag":220,"props":325,"children":326},{},[327],{"type":46,"value":328},"    # No __init__ needed -- @dataclass(frozen=True) generates it: Z2(odd=True)\n",{"type":40,"tag":220,"props":330,"children":332},{"class":222,"line":331},13,[333],{"type":40,"tag":220,"props":334,"children":335},{"emptyLinePlaceholder":281},[336],{"type":46,"value":284},{"type":40,"tag":220,"props":338,"children":340},{"class":222,"line":339},14,[341],{"type":40,"tag":220,"props":342,"children":343},{},[344],{"type":46,"value":345},"    @classmethod\n",{"type":40,"tag":220,"props":347,"children":349},{"class":222,"line":348},15,[350],{"type":40,"tag":220,"props":351,"children":352},{},[353],{"type":46,"value":354},"    def regexp_pattern(cls) -> re.Pattern:\n",{"type":40,"tag":220,"props":356,"children":358},{"class":222,"line":357},16,[359],{"type":40,"tag":220,"props":360,"children":361},{},[362],{"type":46,"value":363},"        # Pattern whose first group is passed to from_string\n",{"type":40,"tag":220,"props":365,"children":367},{"class":222,"line":366},17,[368],{"type":40,"tag":220,"props":369,"children":370},{},[371],{"type":46,"value":372},"        return re.compile(r\"(odd|even)\")\n",{"type":40,"tag":220,"props":374,"children":376},{"class":222,"line":375},18,[377],{"type":40,"tag":220,"props":378,"children":379},{"emptyLinePlaceholder":281},[380],{"type":46,"value":284},{"type":40,"tag":220,"props":382,"children":384},{"class":222,"line":383},19,[385],{"type":40,"tag":220,"props":386,"children":387},{},[388],{"type":46,"value":345},{"type":40,"tag":220,"props":390,"children":392},{"class":222,"line":391},20,[393],{"type":40,"tag":220,"props":394,"children":395},{},[396],{"type":46,"value":397},"    def from_string(cls, string: str) -> Z2:\n",{"type":40,"tag":220,"props":399,"children":401},{"class":222,"line":400},21,[402],{"type":40,"tag":220,"props":403,"children":404},{},[405],{"type":46,"value":406},"        return cls(odd=string == \"odd\")\n",{"type":40,"tag":220,"props":408,"children":410},{"class":222,"line":409},22,[411],{"type":40,"tag":220,"props":412,"children":413},{"emptyLinePlaceholder":281},[414],{"type":46,"value":284},{"type":40,"tag":220,"props":416,"children":418},{"class":222,"line":417},23,[419],{"type":40,"tag":220,"props":420,"children":421},{},[422],{"type":46,"value":423},"    def __repr__(rep: Z2) -> str:\n",{"type":40,"tag":220,"props":425,"children":427},{"class":222,"line":426},24,[428],{"type":40,"tag":220,"props":429,"children":430},{},[431],{"type":46,"value":432},"        return \"odd\" if rep.odd else \"even\"\n",{"type":40,"tag":220,"props":434,"children":436},{"class":222,"line":435},25,[437],{"type":40,"tag":220,"props":438,"children":439},{"emptyLinePlaceholder":281},[440],{"type":46,"value":284},{"type":40,"tag":220,"props":442,"children":444},{"class":222,"line":443},26,[445],{"type":40,"tag":220,"props":446,"children":447},{},[448],{"type":46,"value":449},"    def __mul__(rep1: Z2, rep2: Z2) -> Iterator[Z2]:\n",{"type":40,"tag":220,"props":451,"children":453},{"class":222,"line":452},27,[454],{"type":40,"tag":220,"props":455,"children":456},{},[457],{"type":46,"value":458},"        # Selection rule: which irreps appear in the tensor product rep1 x rep2\n",{"type":40,"tag":220,"props":460,"children":462},{"class":222,"line":461},28,[463],{"type":40,"tag":220,"props":464,"children":465},{},[466],{"type":46,"value":467},"        return [Z2(odd=rep1.odd ^ rep2.odd)]\n",{"type":40,"tag":220,"props":469,"children":471},{"class":222,"line":470},29,[472],{"type":40,"tag":220,"props":473,"children":474},{"emptyLinePlaceholder":281},[475],{"type":46,"value":284},{"type":40,"tag":220,"props":477,"children":479},{"class":222,"line":478},30,[480],{"type":40,"tag":220,"props":481,"children":482},{},[483],{"type":46,"value":345},{"type":40,"tag":220,"props":485,"children":487},{"class":222,"line":486},31,[488],{"type":40,"tag":220,"props":489,"children":490},{},[491],{"type":46,"value":492},"    def clebsch_gordan(cls, rep1: Z2, rep2: Z2, rep3: Z2) -> np.ndarray:\n",{"type":40,"tag":220,"props":494,"children":496},{"class":222,"line":495},32,[497],{"type":40,"tag":220,"props":498,"children":499},{},[500],{"type":46,"value":501},"        # Shape: (num_paths, rep1.dim, rep2.dim, rep3.dim)\n",{"type":40,"tag":220,"props":503,"children":505},{"class":222,"line":504},33,[506],{"type":40,"tag":220,"props":507,"children":508},{},[509],{"type":46,"value":510},"        if rep3 in rep1 * rep2:\n",{"type":40,"tag":220,"props":512,"children":514},{"class":222,"line":513},34,[515],{"type":40,"tag":220,"props":516,"children":517},{},[518],{"type":46,"value":519},"            return np.array([[[[1]]]])\n",{"type":40,"tag":220,"props":521,"children":523},{"class":222,"line":522},35,[524],{"type":40,"tag":220,"props":525,"children":526},{},[527],{"type":46,"value":528},"        else:\n",{"type":40,"tag":220,"props":530,"children":531},{"class":222,"line":27},[532],{"type":40,"tag":220,"props":533,"children":534},{},[535],{"type":46,"value":536},"            return np.zeros((0, 1, 1, 1))\n",{"type":40,"tag":220,"props":538,"children":540},{"class":222,"line":539},37,[541],{"type":40,"tag":220,"props":542,"children":543},{"emptyLinePlaceholder":281},[544],{"type":46,"value":284},{"type":40,"tag":220,"props":546,"children":548},{"class":222,"line":547},38,[549],{"type":40,"tag":220,"props":550,"children":551},{},[552],{"type":46,"value":553},"    @property\n",{"type":40,"tag":220,"props":555,"children":557},{"class":222,"line":556},39,[558],{"type":40,"tag":220,"props":559,"children":560},{},[561],{"type":46,"value":562},"    def dim(rep: Z2) -> int:\n",{"type":40,"tag":220,"props":564,"children":566},{"class":222,"line":565},40,[567],{"type":40,"tag":220,"props":568,"children":569},{},[570],{"type":46,"value":571},"        return 1\n",{"type":40,"tag":220,"props":573,"children":575},{"class":222,"line":574},41,[576],{"type":40,"tag":220,"props":577,"children":578},{"emptyLinePlaceholder":281},[579],{"type":46,"value":284},{"type":40,"tag":220,"props":581,"children":583},{"class":222,"line":582},42,[584],{"type":40,"tag":220,"props":585,"children":586},{},[587],{"type":46,"value":588},"    def __lt__(rep1: Z2, rep2: Z2) -> bool:\n",{"type":40,"tag":220,"props":590,"children":592},{"class":222,"line":591},43,[593],{"type":40,"tag":220,"props":594,"children":595},{},[596],{"type":46,"value":597},"        # Ordering for sorting; dimension is compared first by the base class\n",{"type":40,"tag":220,"props":599,"children":601},{"class":222,"line":600},44,[602],{"type":40,"tag":220,"props":603,"children":604},{},[605],{"type":46,"value":606},"        return rep1.odd \u003C rep2.odd\n",{"type":40,"tag":220,"props":608,"children":610},{"class":222,"line":609},45,[611],{"type":40,"tag":220,"props":612,"children":613},{"emptyLinePlaceholder":281},[614],{"type":46,"value":284},{"type":40,"tag":220,"props":616,"children":618},{"class":222,"line":617},46,[619],{"type":40,"tag":220,"props":620,"children":621},{},[622],{"type":46,"value":345},{"type":40,"tag":220,"props":624,"children":626},{"class":222,"line":625},47,[627],{"type":40,"tag":220,"props":628,"children":629},{},[630],{"type":46,"value":631},"    def iterator(cls) -> Iterator[Z2]:\n",{"type":40,"tag":220,"props":633,"children":635},{"class":222,"line":634},48,[636],{"type":40,"tag":220,"props":637,"children":638},{},[639],{"type":46,"value":640},"        # Must yield trivial irrep first\n",{"type":40,"tag":220,"props":642,"children":644},{"class":222,"line":643},49,[645],{"type":40,"tag":220,"props":646,"children":647},{},[648],{"type":46,"value":649},"        for odd in [False, True]:\n",{"type":40,"tag":220,"props":651,"children":653},{"class":222,"line":652},50,[654],{"type":40,"tag":220,"props":655,"children":656},{},[657],{"type":46,"value":658},"            yield Z2(odd=odd)\n",{"type":40,"tag":220,"props":660,"children":662},{"class":222,"line":661},51,[663],{"type":40,"tag":220,"props":664,"children":665},{"emptyLinePlaceholder":281},[666],{"type":46,"value":284},{"type":40,"tag":220,"props":668,"children":670},{"class":222,"line":669},52,[671],{"type":40,"tag":220,"props":672,"children":673},{},[674],{"type":46,"value":675},"    def discrete_generators(rep: Z2) -> np.ndarray:\n",{"type":40,"tag":220,"props":677,"children":679},{"class":222,"line":678},53,[680],{"type":40,"tag":220,"props":681,"children":682},{},[683],{"type":46,"value":684},"        # Shape: (num_generators, dim, dim)\n",{"type":40,"tag":220,"props":686,"children":688},{"class":222,"line":687},54,[689],{"type":40,"tag":220,"props":690,"children":691},{},[692],{"type":46,"value":693},"        if rep.odd:\n",{"type":40,"tag":220,"props":695,"children":697},{"class":222,"line":696},55,[698],{"type":40,"tag":220,"props":699,"children":700},{},[701],{"type":46,"value":702},"            return -np.ones((1, 1, 1))\n",{"type":40,"tag":220,"props":704,"children":706},{"class":222,"line":705},56,[707],{"type":40,"tag":220,"props":708,"children":709},{},[710],{"type":46,"value":528},{"type":40,"tag":220,"props":712,"children":714},{"class":222,"line":713},57,[715],{"type":40,"tag":220,"props":716,"children":717},{},[718],{"type":46,"value":719},"            return np.ones((1, 1, 1))\n",{"type":40,"tag":220,"props":721,"children":723},{"class":222,"line":722},58,[724],{"type":40,"tag":220,"props":725,"children":726},{"emptyLinePlaceholder":281},[727],{"type":46,"value":284},{"type":40,"tag":220,"props":729,"children":731},{"class":222,"line":730},59,[732],{"type":40,"tag":220,"props":733,"children":734},{},[735],{"type":46,"value":736},"    def continuous_generators(rep: Z2) -> np.ndarray:\n",{"type":40,"tag":220,"props":738,"children":740},{"class":222,"line":739},60,[741],{"type":40,"tag":220,"props":742,"children":743},{},[744],{"type":46,"value":745},"        # Shape: (lie_dim, dim, dim) -- Z2 is discrete, so lie_dim=0\n",{"type":40,"tag":220,"props":747,"children":749},{"class":222,"line":748},61,[750],{"type":40,"tag":220,"props":751,"children":752},{},[753],{"type":46,"value":754},"        return np.zeros((0, rep.dim, rep.dim))\n",{"type":40,"tag":220,"props":756,"children":758},{"class":222,"line":757},62,[759],{"type":40,"tag":220,"props":760,"children":761},{"emptyLinePlaceholder":281},[762],{"type":46,"value":284},{"type":40,"tag":220,"props":764,"children":766},{"class":222,"line":765},63,[767],{"type":40,"tag":220,"props":768,"children":769},{},[770],{"type":46,"value":771},"    def algebra(self) -> np.ndarray:\n",{"type":40,"tag":220,"props":773,"children":775},{"class":222,"line":774},64,[776],{"type":40,"tag":220,"props":777,"children":778},{},[779],{"type":46,"value":780},"        # Shape: (lie_dim, lie_dim, lie_dim) -- structure constants [X_i, X_j] = A_ijk X_k\n",{"type":40,"tag":220,"props":782,"children":784},{"class":222,"line":783},65,[785],{"type":40,"tag":220,"props":786,"children":787},{},[788],{"type":46,"value":789},"        return np.zeros((0, 0, 0))\n",{"type":40,"tag":220,"props":791,"children":793},{"class":222,"line":792},66,[794],{"type":40,"tag":220,"props":795,"children":796},{"emptyLinePlaceholder":281},[797],{"type":46,"value":284},{"type":40,"tag":220,"props":799,"children":801},{"class":222,"line":800},67,[802],{"type":40,"tag":220,"props":803,"children":804},{"emptyLinePlaceholder":281},[805],{"type":46,"value":284},{"type":40,"tag":220,"props":807,"children":809},{"class":222,"line":808},68,[810],{"type":40,"tag":220,"props":811,"children":812},{},[813],{"type":46,"value":814},"# Usage:\n",{"type":40,"tag":220,"props":816,"children":818},{"class":222,"line":817},69,[819],{"type":40,"tag":220,"props":820,"children":821},{},[822],{"type":46,"value":823},"irreps = cue.Irreps(Z2, \"3x odd + 2x even\")  # dim=5\n",{"type":40,"tag":825,"props":826,"children":828},"h3",{"id":827},"required-methods-summary",[829],{"type":46,"value":830},"Required methods summary",{"type":40,"tag":832,"props":833,"children":834},"table",{},[835,859],{"type":40,"tag":836,"props":837,"children":838},"thead",{},[839],{"type":40,"tag":840,"props":841,"children":842},"tr",{},[843,849,854],{"type":40,"tag":844,"props":845,"children":846},"th",{},[847],{"type":46,"value":848},"Method",{"type":40,"tag":844,"props":850,"children":851},{},[852],{"type":46,"value":853},"Returns",{"type":40,"tag":844,"props":855,"children":856},{},[857],{"type":46,"value":858},"Purpose",{"type":40,"tag":860,"props":861,"children":862},"tbody",{},[863,911,936,962,988,1014,1042,1068,1093,1119,1145],{"type":40,"tag":840,"props":864,"children":865},{},[866,876,885],{"type":40,"tag":867,"props":868,"children":869},"td",{},[870],{"type":40,"tag":60,"props":871,"children":873},{"className":872},[],[874],{"type":46,"value":875},"regexp_pattern()",{"type":40,"tag":867,"props":877,"children":878},{},[879],{"type":40,"tag":60,"props":880,"children":882},{"className":881},[],[883],{"type":46,"value":884},"re.Pattern",{"type":40,"tag":867,"props":886,"children":887},{},[888,890,896,898,904,905],{"type":46,"value":889},"Parse string like ",{"type":40,"tag":60,"props":891,"children":893},{"className":892},[],[894],{"type":46,"value":895},"\"1\"",{"type":46,"value":897},", ",{"type":40,"tag":60,"props":899,"children":901},{"className":900},[],[902],{"type":46,"value":903},"\"0e\"",{"type":46,"value":897},{"type":40,"tag":60,"props":906,"children":908},{"className":907},[],[909],{"type":46,"value":910},"\"odd\"",{"type":40,"tag":840,"props":912,"children":913},{},[914,923,931],{"type":40,"tag":867,"props":915,"children":916},{},[917],{"type":40,"tag":60,"props":918,"children":920},{"className":919},[],[921],{"type":46,"value":922},"from_string(s)",{"type":40,"tag":867,"props":924,"children":925},{},[926],{"type":40,"tag":60,"props":927,"children":929},{"className":928},[],[930],{"type":46,"value":96},{"type":40,"tag":867,"props":932,"children":933},{},[934],{"type":46,"value":935},"Construct from matched string",{"type":40,"tag":840,"props":937,"children":938},{},[939,948,957],{"type":40,"tag":867,"props":940,"children":941},{},[942],{"type":40,"tag":60,"props":943,"children":945},{"className":944},[],[946],{"type":46,"value":947},"__repr__",{"type":40,"tag":867,"props":949,"children":950},{},[951],{"type":40,"tag":60,"props":952,"children":954},{"className":953},[],[955],{"type":46,"value":956},"str",{"type":40,"tag":867,"props":958,"children":959},{},[960],{"type":46,"value":961},"Canonical string form",{"type":40,"tag":840,"props":963,"children":964},{},[965,974,983],{"type":40,"tag":867,"props":966,"children":967},{},[968],{"type":40,"tag":60,"props":969,"children":971},{"className":970},[],[972],{"type":46,"value":973},"__mul__(a, b)",{"type":40,"tag":867,"props":975,"children":976},{},[977],{"type":40,"tag":60,"props":978,"children":980},{"className":979},[],[981],{"type":46,"value":982},"Iterator[Irrep]",{"type":40,"tag":867,"props":984,"children":985},{},[986],{"type":46,"value":987},"Selection rule for tensor product",{"type":40,"tag":840,"props":989,"children":990},{},[991,1000,1009],{"type":40,"tag":867,"props":992,"children":993},{},[994],{"type":40,"tag":60,"props":995,"children":997},{"className":996},[],[998],{"type":46,"value":999},"clebsch_gordan(a, b, c)",{"type":40,"tag":867,"props":1001,"children":1002},{},[1003],{"type":40,"tag":60,"props":1004,"children":1006},{"className":1005},[],[1007],{"type":46,"value":1008},"ndarray (n, d1, d2, d3)",{"type":40,"tag":867,"props":1010,"children":1011},{},[1012],{"type":46,"value":1013},"CG coefficients",{"type":40,"tag":840,"props":1015,"children":1016},{},[1017,1028,1037],{"type":40,"tag":867,"props":1018,"children":1019},{},[1020,1026],{"type":40,"tag":60,"props":1021,"children":1023},{"className":1022},[],[1024],{"type":46,"value":1025},"dim",{"type":46,"value":1027}," (property)",{"type":40,"tag":867,"props":1029,"children":1030},{},[1031],{"type":40,"tag":60,"props":1032,"children":1034},{"className":1033},[],[1035],{"type":46,"value":1036},"int",{"type":40,"tag":867,"props":1038,"children":1039},{},[1040],{"type":46,"value":1041},"Dimension of representation",{"type":40,"tag":840,"props":1043,"children":1044},{},[1045,1054,1063],{"type":40,"tag":867,"props":1046,"children":1047},{},[1048],{"type":40,"tag":60,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":46,"value":1053},"__lt__(a, b)",{"type":40,"tag":867,"props":1055,"children":1056},{},[1057],{"type":40,"tag":60,"props":1058,"children":1060},{"className":1059},[],[1061],{"type":46,"value":1062},"bool",{"type":40,"tag":867,"props":1064,"children":1065},{},[1066],{"type":46,"value":1067},"Ordering (dimension first, then custom)",{"type":40,"tag":840,"props":1069,"children":1070},{},[1071,1080,1088],{"type":40,"tag":867,"props":1072,"children":1073},{},[1074],{"type":40,"tag":60,"props":1075,"children":1077},{"className":1076},[],[1078],{"type":46,"value":1079},"iterator()",{"type":40,"tag":867,"props":1081,"children":1082},{},[1083],{"type":40,"tag":60,"props":1084,"children":1086},{"className":1085},[],[1087],{"type":46,"value":982},{"type":40,"tag":867,"props":1089,"children":1090},{},[1091],{"type":46,"value":1092},"All irreps, trivial first",{"type":40,"tag":840,"props":1094,"children":1095},{},[1096,1105,1114],{"type":40,"tag":867,"props":1097,"children":1098},{},[1099],{"type":40,"tag":60,"props":1100,"children":1102},{"className":1101},[],[1103],{"type":46,"value":1104},"continuous_generators()",{"type":40,"tag":867,"props":1106,"children":1107},{},[1108],{"type":40,"tag":60,"props":1109,"children":1111},{"className":1110},[],[1112],{"type":46,"value":1113},"ndarray (lie_dim, dim, dim)",{"type":40,"tag":867,"props":1115,"children":1116},{},[1117],{"type":46,"value":1118},"Lie algebra generators",{"type":40,"tag":840,"props":1120,"children":1121},{},[1122,1131,1140],{"type":40,"tag":867,"props":1123,"children":1124},{},[1125],{"type":40,"tag":60,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":46,"value":1130},"discrete_generators()",{"type":40,"tag":867,"props":1132,"children":1133},{},[1134],{"type":40,"tag":60,"props":1135,"children":1137},{"className":1136},[],[1138],{"type":46,"value":1139},"ndarray (n, dim, dim)",{"type":40,"tag":867,"props":1141,"children":1142},{},[1143],{"type":46,"value":1144},"Finite symmetry generators",{"type":40,"tag":840,"props":1146,"children":1147},{},[1148,1157,1166],{"type":40,"tag":867,"props":1149,"children":1150},{},[1151],{"type":40,"tag":60,"props":1152,"children":1154},{"className":1153},[],[1155],{"type":46,"value":1156},"algebra()",{"type":40,"tag":867,"props":1158,"children":1159},{},[1160],{"type":40,"tag":60,"props":1161,"children":1163},{"className":1162},[],[1164],{"type":46,"value":1165},"ndarray (lie_dim, lie_dim, lie_dim)",{"type":40,"tag":867,"props":1167,"children":1168},{},[1169],{"type":46,"value":1170},"Structure constants",{"type":40,"tag":825,"props":1172,"children":1174},{"id":1173},"built-in-groups",[1175],{"type":46,"value":1176},"Built-in groups",{"type":40,"tag":141,"props":1178,"children":1179},{},[1180,1231,1281],{"type":40,"tag":80,"props":1181,"children":1182},{},[1183,1192,1194,1200,1202,1208,1210,1216,1217,1222,1223,1229],{"type":40,"tag":84,"props":1184,"children":1185},{},[1186],{"type":40,"tag":60,"props":1187,"children":1189},{"className":1188},[],[1190],{"type":46,"value":1191},"cue.SO3(l)",{"type":46,"value":1193},": 3D rotations. ",{"type":40,"tag":60,"props":1195,"children":1197},{"className":1196},[],[1198],{"type":46,"value":1199},"l",{"type":46,"value":1201}," is a non-negative integer. ",{"type":40,"tag":60,"props":1203,"children":1205},{"className":1204},[],[1206],{"type":46,"value":1207},"dim = 2l+1",{"type":46,"value":1209},". String: ",{"type":40,"tag":60,"props":1211,"children":1213},{"className":1212},[],[1214],{"type":46,"value":1215},"\"0\"",{"type":46,"value":897},{"type":40,"tag":60,"props":1218,"children":1220},{"className":1219},[],[1221],{"type":46,"value":895},{"type":46,"value":897},{"type":40,"tag":60,"props":1224,"children":1226},{"className":1225},[],[1227],{"type":46,"value":1228},"\"2\"",{"type":46,"value":1230},".",{"type":40,"tag":80,"props":1232,"children":1233},{},[1234,1243,1245,1251,1253,1259,1261,1266,1267,1273,1274,1280],{"type":40,"tag":84,"props":1235,"children":1236},{},[1237],{"type":40,"tag":60,"props":1238,"children":1240},{"className":1239},[],[1241],{"type":46,"value":1242},"cue.O3(l, p)",{"type":46,"value":1244},": 3D rotations + parity. ",{"type":40,"tag":60,"props":1246,"children":1248},{"className":1247},[],[1249],{"type":46,"value":1250},"p=+1",{"type":46,"value":1252}," (even) or ",{"type":40,"tag":60,"props":1254,"children":1256},{"className":1255},[],[1257],{"type":46,"value":1258},"p=-1",{"type":46,"value":1260}," (odd). String: ",{"type":40,"tag":60,"props":1262,"children":1264},{"className":1263},[],[1265],{"type":46,"value":903},{"type":46,"value":897},{"type":40,"tag":60,"props":1268,"children":1270},{"className":1269},[],[1271],{"type":46,"value":1272},"\"1o\"",{"type":46,"value":897},{"type":40,"tag":60,"props":1275,"children":1277},{"className":1276},[],[1278],{"type":46,"value":1279},"\"2e\"",{"type":46,"value":1230},{"type":40,"tag":80,"props":1282,"children":1283},{},[1284,1293,1295,1301,1303,1308,1309,1315,1316,1321],{"type":40,"tag":84,"props":1285,"children":1286},{},[1287],{"type":40,"tag":60,"props":1288,"children":1290},{"className":1289},[],[1291],{"type":46,"value":1292},"cue.SU2(j)",{"type":46,"value":1294},": Spin group. ",{"type":40,"tag":60,"props":1296,"children":1298},{"className":1297},[],[1299],{"type":46,"value":1300},"j",{"type":46,"value":1302}," is a non-negative half-integer. String: ",{"type":40,"tag":60,"props":1304,"children":1306},{"className":1305},[],[1307],{"type":46,"value":1215},{"type":46,"value":897},{"type":40,"tag":60,"props":1310,"children":1312},{"className":1311},[],[1313],{"type":46,"value":1314},"\"1\u002F2\"",{"type":46,"value":897},{"type":40,"tag":60,"props":1317,"children":1319},{"className":1318},[],[1320],{"type":46,"value":895},{"type":46,"value":1230},{"type":40,"tag":49,"props":1323,"children":1325},{"id":1324},"irreps-and-layout",[1326],{"type":46,"value":1327},"Irreps and layout",{"type":40,"tag":209,"props":1329,"children":1331},{"className":211,"code":1330,"language":213,"meta":214,"style":214},"irreps = cue.Irreps(\"SO3\", \"16x0 + 4x1 + 2x2\")  # 16 scalars, 4 vectors, 2 rank-2\nirreps.dim   # 16*1 + 4*3 + 2*5 = 38\n\nfor mul, ir in irreps:\n    print(mul, ir, ir.dim)  # 16 0 1, then 4 1 3, then 2 2 5\n",[1332],{"type":40,"tag":60,"props":1333,"children":1334},{"__ignoreMap":214},[1335,1343,1351,1358,1366],{"type":40,"tag":220,"props":1336,"children":1337},{"class":222,"line":223},[1338],{"type":40,"tag":220,"props":1339,"children":1340},{},[1341],{"type":46,"value":1342},"irreps = cue.Irreps(\"SO3\", \"16x0 + 4x1 + 2x2\")  # 16 scalars, 4 vectors, 2 rank-2\n",{"type":40,"tag":220,"props":1344,"children":1345},{"class":222,"line":232},[1346],{"type":40,"tag":220,"props":1347,"children":1348},{},[1349],{"type":46,"value":1350},"irreps.dim   # 16*1 + 4*3 + 2*5 = 38\n",{"type":40,"tag":220,"props":1352,"children":1353},{"class":222,"line":241},[1354],{"type":40,"tag":220,"props":1355,"children":1356},{"emptyLinePlaceholder":281},[1357],{"type":46,"value":284},{"type":40,"tag":220,"props":1359,"children":1360},{"class":222,"line":250},[1361],{"type":40,"tag":220,"props":1362,"children":1363},{},[1364],{"type":46,"value":1365},"for mul, ir in irreps:\n",{"type":40,"tag":220,"props":1367,"children":1368},{"class":222,"line":259},[1369],{"type":40,"tag":220,"props":1370,"children":1371},{},[1372],{"type":46,"value":1373},"    print(mul, ir, ir.dim)  # 16 0 1, then 4 1 3, then 2 2 5\n",{"type":40,"tag":56,"props":1375,"children":1376},{},[1377,1383,1385,1391],{"type":40,"tag":60,"props":1378,"children":1380},{"className":1379},[],[1381],{"type":46,"value":1382},"IrrepsLayout",{"type":46,"value":1384}," controls memory order within each ",{"type":40,"tag":60,"props":1386,"children":1388},{"className":1387},[],[1389],{"type":46,"value":1390},"(mul, ir)",{"type":46,"value":1392}," block:",{"type":40,"tag":141,"props":1394,"children":1395},{},[1396,1420],{"type":40,"tag":80,"props":1397,"children":1398},{},[1399,1405,1407,1413,1415],{"type":40,"tag":60,"props":1400,"children":1402},{"className":1401},[],[1403],{"type":46,"value":1404},"cue.ir_mul",{"type":46,"value":1406},": data ordered as ",{"type":40,"tag":60,"props":1408,"children":1410},{"className":1409},[],[1411],{"type":46,"value":1412},"(ir.dim, mul)",{"type":46,"value":1414}," — ",{"type":40,"tag":84,"props":1416,"children":1417},{},[1418],{"type":46,"value":1419},"used by all descriptors and ir_dict internally",{"type":40,"tag":80,"props":1421,"children":1422},{},[1423,1429,1430,1436,1437],{"type":40,"tag":60,"props":1424,"children":1426},{"className":1425},[],[1427],{"type":46,"value":1428},"cue.mul_ir",{"type":46,"value":1406},{"type":40,"tag":60,"props":1431,"children":1433},{"className":1432},[],[1434],{"type":46,"value":1435},"(mul, ir.dim)",{"type":46,"value":1414},{"type":40,"tag":84,"props":1438,"children":1439},{},[1440,1442,1447],{"type":46,"value":1441},"used by nnx ",{"type":40,"tag":60,"props":1443,"children":1445},{"className":1444},[],[1446],{"type":46,"value":186},{"type":46,"value":1448}," and PyTorch",{"type":40,"tag":56,"props":1450,"children":1451},{},[1452,1457,1459,1465],{"type":40,"tag":60,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":46,"value":160},{"type":46,"value":1458}," combines irreps with a layout into a ",{"type":40,"tag":60,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":46,"value":1464},"Rep",{"type":46,"value":1466},":",{"type":40,"tag":209,"props":1468,"children":1470},{"className":211,"code":1469,"language":213,"meta":214,"style":214},"rep = cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x0 + 2x1\"), cue.ir_mul)\nrep.dim  # 10\n",[1471],{"type":40,"tag":60,"props":1472,"children":1473},{"__ignoreMap":214},[1474,1482],{"type":40,"tag":220,"props":1475,"children":1476},{"class":222,"line":223},[1477],{"type":40,"tag":220,"props":1478,"children":1479},{},[1480],{"type":46,"value":1481},"rep = cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x0 + 2x1\"), cue.ir_mul)\n",{"type":40,"tag":220,"props":1483,"children":1484},{"class":222,"line":232},[1485],{"type":40,"tag":220,"props":1486,"children":1487},{},[1488],{"type":46,"value":1489},"rep.dim  # 10\n",{"type":40,"tag":49,"props":1491,"children":1493},{"id":1492},"building-a-segmentedtensorproduct-from-scratch",[1494],{"type":46,"value":1495},"Building a SegmentedTensorProduct from scratch",{"type":40,"tag":56,"props":1497,"children":1498},{},[1499,1501,1507],{"type":46,"value":1500},"The subscripts string uses Einstein notation. Operands are comma-separated, coefficient modes follow ",{"type":40,"tag":60,"props":1502,"children":1504},{"className":1503},[],[1505],{"type":46,"value":1506},"+",{"type":46,"value":1230},{"type":40,"tag":209,"props":1509,"children":1511},{"className":211,"code":1510,"language":213,"meta":214,"style":214},"# Matrix-vector multiply: y_i = sum_j M_ij * x_j\nd = cue.SegmentedTensorProduct.from_subscripts(\"ij,j,i\")\nd.add_segment(0, (3, 4))  # operand 0: matrix segment of shape (3, 4)\nd.add_segment(1, (4,))     # operand 1: vector of size 4\nd.add_segment(2, (3,))     # operand 2: output vector of size 3\nd.add_path(0, 0, 0, c=1.0) # link segments 0,0,0 with coefficient=1.0\n\npoly = cue.SegmentedPolynomial.eval_last_operand(d)  # last operand becomes output\n[y] = poly(M_flat, x)  # numpy evaluation\n",[1512],{"type":40,"tag":60,"props":1513,"children":1514},{"__ignoreMap":214},[1515,1523,1531,1539,1547,1555,1563,1570,1578],{"type":40,"tag":220,"props":1516,"children":1517},{"class":222,"line":223},[1518],{"type":40,"tag":220,"props":1519,"children":1520},{},[1521],{"type":46,"value":1522},"# Matrix-vector multiply: y_i = sum_j M_ij * x_j\n",{"type":40,"tag":220,"props":1524,"children":1525},{"class":222,"line":232},[1526],{"type":40,"tag":220,"props":1527,"children":1528},{},[1529],{"type":46,"value":1530},"d = cue.SegmentedTensorProduct.from_subscripts(\"ij,j,i\")\n",{"type":40,"tag":220,"props":1532,"children":1533},{"class":222,"line":241},[1534],{"type":40,"tag":220,"props":1535,"children":1536},{},[1537],{"type":46,"value":1538},"d.add_segment(0, (3, 4))  # operand 0: matrix segment of shape (3, 4)\n",{"type":40,"tag":220,"props":1540,"children":1541},{"class":222,"line":250},[1542],{"type":40,"tag":220,"props":1543,"children":1544},{},[1545],{"type":46,"value":1546},"d.add_segment(1, (4,))     # operand 1: vector of size 4\n",{"type":40,"tag":220,"props":1548,"children":1549},{"class":222,"line":259},[1550],{"type":40,"tag":220,"props":1551,"children":1552},{},[1553],{"type":46,"value":1554},"d.add_segment(2, (3,))     # operand 2: output vector of size 3\n",{"type":40,"tag":220,"props":1556,"children":1557},{"class":222,"line":268},[1558],{"type":40,"tag":220,"props":1559,"children":1560},{},[1561],{"type":46,"value":1562},"d.add_path(0, 0, 0, c=1.0) # link segments 0,0,0 with coefficient=1.0\n",{"type":40,"tag":220,"props":1564,"children":1565},{"class":222,"line":277},[1566],{"type":40,"tag":220,"props":1567,"children":1568},{"emptyLinePlaceholder":281},[1569],{"type":46,"value":284},{"type":40,"tag":220,"props":1571,"children":1572},{"class":222,"line":287},[1573],{"type":40,"tag":220,"props":1574,"children":1575},{},[1576],{"type":46,"value":1577},"poly = cue.SegmentedPolynomial.eval_last_operand(d)  # last operand becomes output\n",{"type":40,"tag":220,"props":1579,"children":1580},{"class":222,"line":296},[1581],{"type":40,"tag":220,"props":1582,"children":1583},{},[1584],{"type":46,"value":1585},"[y] = poly(M_flat, x)  # numpy evaluation\n",{"type":40,"tag":825,"props":1587,"children":1589},{"id":1588},"multi-segment-stp-how-descriptors-work-internally",[1590],{"type":46,"value":1591},"Multi-segment STP (how descriptors work internally)",{"type":40,"tag":56,"props":1593,"children":1594},{},[1595],{"type":46,"value":1596},"Descriptors build STPs with multiple segments per operand. Each segment corresponds to an irrep block:",{"type":40,"tag":209,"props":1598,"children":1600},{"className":211,"code":1599,"language":213,"meta":214,"style":214},"# Linear equivariant map: output[iv] = sum_u weight[uv] * input[iu]\nd = cue.SegmentedTensorProduct.from_subscripts(\"uv,iu,iv\")\n\n# Segment for l=1: ir_dim=3, mul_in=2, mul_out=5\ns_in_0 = d.add_segment(1, (3, 2))    # input block\ns_out_0 = d.add_segment(2, (3, 5))   # output block\nd.add_path((2, 5), s_in_0, s_out_0, c=1.0)\n\n# Segment for l=0: ir_dim=1, mul_in=4, mul_out=3\ns_in_1 = d.add_segment(1, (1, 4))\ns_out_1 = d.add_segment(2, (1, 3))\nd.add_path((4, 3), s_in_1, s_out_1, c=1.0)\n",[1601],{"type":40,"tag":60,"props":1602,"children":1603},{"__ignoreMap":214},[1604,1612,1620,1627,1635,1643,1651,1659,1666,1674,1682,1690],{"type":40,"tag":220,"props":1605,"children":1606},{"class":222,"line":223},[1607],{"type":40,"tag":220,"props":1608,"children":1609},{},[1610],{"type":46,"value":1611},"# Linear equivariant map: output[iv] = sum_u weight[uv] * input[iu]\n",{"type":40,"tag":220,"props":1613,"children":1614},{"class":222,"line":232},[1615],{"type":40,"tag":220,"props":1616,"children":1617},{},[1618],{"type":46,"value":1619},"d = cue.SegmentedTensorProduct.from_subscripts(\"uv,iu,iv\")\n",{"type":40,"tag":220,"props":1621,"children":1622},{"class":222,"line":241},[1623],{"type":40,"tag":220,"props":1624,"children":1625},{"emptyLinePlaceholder":281},[1626],{"type":46,"value":284},{"type":40,"tag":220,"props":1628,"children":1629},{"class":222,"line":250},[1630],{"type":40,"tag":220,"props":1631,"children":1632},{},[1633],{"type":46,"value":1634},"# Segment for l=1: ir_dim=3, mul_in=2, mul_out=5\n",{"type":40,"tag":220,"props":1636,"children":1637},{"class":222,"line":259},[1638],{"type":40,"tag":220,"props":1639,"children":1640},{},[1641],{"type":46,"value":1642},"s_in_0 = d.add_segment(1, (3, 2))    # input block\n",{"type":40,"tag":220,"props":1644,"children":1645},{"class":222,"line":268},[1646],{"type":40,"tag":220,"props":1647,"children":1648},{},[1649],{"type":46,"value":1650},"s_out_0 = d.add_segment(2, (3, 5))   # output block\n",{"type":40,"tag":220,"props":1652,"children":1653},{"class":222,"line":277},[1654],{"type":40,"tag":220,"props":1655,"children":1656},{},[1657],{"type":46,"value":1658},"d.add_path((2, 5), s_in_0, s_out_0, c=1.0)\n",{"type":40,"tag":220,"props":1660,"children":1661},{"class":222,"line":287},[1662],{"type":40,"tag":220,"props":1663,"children":1664},{"emptyLinePlaceholder":281},[1665],{"type":46,"value":284},{"type":40,"tag":220,"props":1667,"children":1668},{"class":222,"line":296},[1669],{"type":40,"tag":220,"props":1670,"children":1671},{},[1672],{"type":46,"value":1673},"# Segment for l=0: ir_dim=1, mul_in=4, mul_out=3\n",{"type":40,"tag":220,"props":1675,"children":1676},{"class":222,"line":305},[1677],{"type":40,"tag":220,"props":1678,"children":1679},{},[1680],{"type":46,"value":1681},"s_in_1 = d.add_segment(1, (1, 4))\n",{"type":40,"tag":220,"props":1683,"children":1684},{"class":222,"line":314},[1685],{"type":40,"tag":220,"props":1686,"children":1687},{},[1688],{"type":46,"value":1689},"s_out_1 = d.add_segment(2, (1, 3))\n",{"type":40,"tag":220,"props":1691,"children":1692},{"class":222,"line":322},[1693],{"type":40,"tag":220,"props":1694,"children":1695},{},[1696],{"type":46,"value":1697},"d.add_path((4, 3), s_in_1, s_out_1, c=1.0)\n",{"type":40,"tag":825,"props":1699,"children":1701},{"id":1700},"weights-operand",[1702],{"type":46,"value":1703},"Weights operand",{"type":40,"tag":56,"props":1705,"children":1706},{},[1707,1709,1715,1717,1723,1725,1731,1733,1739],{"type":46,"value":1708},"For weighted tensor products (subscript starting with ",{"type":40,"tag":60,"props":1710,"children":1712},{"className":1711},[],[1713],{"type":46,"value":1714},"uvw",{"type":46,"value":1716}," or ",{"type":40,"tag":60,"props":1718,"children":1720},{"className":1719},[],[1721],{"type":46,"value":1722},"uv",{"type":46,"value":1724},"), the first operand is always weights. The weight segment shape is ",{"type":40,"tag":60,"props":1726,"children":1728},{"className":1727},[],[1729],{"type":46,"value":1730},"(mul_1, mul_2, ...)",{"type":46,"value":1732}," matching the multiplicity modes. The weights operand gets ",{"type":40,"tag":60,"props":1734,"children":1736},{"className":1735},[],[1737],{"type":46,"value":1738},"new_scalars()",{"type":46,"value":1740}," irreps since weights are invariant.",{"type":40,"tag":825,"props":1742,"children":1744},{"id":1743},"cg-coefficients-as-path-coefficients",[1745],{"type":46,"value":1746},"CG coefficients as path coefficients",{"type":40,"tag":209,"props":1748,"children":1750},{"className":211,"code":1749,"language":213,"meta":214,"style":214},"d = cue.SegmentedTensorProduct.from_subscripts(\"uvw,iu,jv,kw+ijk\")\n# For each pair of input irreps and each output irrep in the selection rule:\nfor cg in cue.clebsch_gordan(ir1, ir2, ir3):\n    # cg has shape (ir1.dim, ir2.dim, ir3.dim)\n    d.add_path((mul1, mul2, mul3), seg_in1, seg_in2, seg_out, c=cg)\n",[1751],{"type":40,"tag":60,"props":1752,"children":1753},{"__ignoreMap":214},[1754,1762,1770,1778,1786],{"type":40,"tag":220,"props":1755,"children":1756},{"class":222,"line":223},[1757],{"type":40,"tag":220,"props":1758,"children":1759},{},[1760],{"type":46,"value":1761},"d = cue.SegmentedTensorProduct.from_subscripts(\"uvw,iu,jv,kw+ijk\")\n",{"type":40,"tag":220,"props":1763,"children":1764},{"class":222,"line":232},[1765],{"type":40,"tag":220,"props":1766,"children":1767},{},[1768],{"type":46,"value":1769},"# For each pair of input irreps and each output irrep in the selection rule:\n",{"type":40,"tag":220,"props":1771,"children":1772},{"class":222,"line":241},[1773],{"type":40,"tag":220,"props":1774,"children":1775},{},[1776],{"type":46,"value":1777},"for cg in cue.clebsch_gordan(ir1, ir2, ir3):\n",{"type":40,"tag":220,"props":1779,"children":1780},{"class":222,"line":250},[1781],{"type":40,"tag":220,"props":1782,"children":1783},{},[1784],{"type":46,"value":1785},"    # cg has shape (ir1.dim, ir2.dim, ir3.dim)\n",{"type":40,"tag":220,"props":1787,"children":1788},{"class":222,"line":259},[1789],{"type":40,"tag":220,"props":1790,"children":1791},{},[1792],{"type":46,"value":1793},"    d.add_path((mul1, mul2, mul3), seg_in1, seg_in2, seg_out, c=cg)\n",{"type":40,"tag":49,"props":1795,"children":1797},{"id":1796},"descriptors",[1798],{"type":46,"value":1799},"Descriptors",{"type":40,"tag":56,"props":1801,"children":1802},{},[1803],{"type":46,"value":1804},"All descriptors come in two variants:",{"type":40,"tag":141,"props":1806,"children":1807},{},[1808,1825],{"type":40,"tag":80,"props":1809,"children":1810},{},[1811,1816,1818,1823],{"type":40,"tag":84,"props":1812,"children":1813},{},[1814],{"type":46,"value":1815},"Original",{"type":46,"value":1817}," — returns ",{"type":40,"tag":60,"props":1819,"children":1821},{"className":1820},[],[1822],{"type":46,"value":152},{"type":46,"value":1824}," with dense operands",{"type":40,"tag":80,"props":1826,"children":1827},{},[1828,1837,1838,1843],{"type":40,"tag":84,"props":1829,"children":1830},{},[1831],{"type":40,"tag":60,"props":1832,"children":1834},{"className":1833},[],[1835],{"type":46,"value":1836},"_ir_dict",{"type":46,"value":1817},{"type":40,"tag":60,"props":1839,"children":1841},{"className":1840},[],[1842],{"type":46,"value":171},{"type":46,"value":1844}," with operands already split by irrep",{"type":40,"tag":825,"props":1846,"children":1848},{"id":1847},"equivariantpolynomial-descriptors",[1849],{"type":46,"value":1850},"EquivariantPolynomial descriptors",{"type":40,"tag":209,"props":1852,"children":1854},{"className":211,"code":1853,"language":213,"meta":214,"style":214},"# Fully connected tensor product (all input-output irrep combinations)\ne = cue.descriptors.fully_connected_tensor_product(\n    16 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n    16 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n    16 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n)\n\n# Channelwise tensor product (same-channel only, sparse)\ne = cue.descriptors.channelwise_tensor_product(\n    64 * cue.Irreps(\"SO3\", \"0 + 1\"), cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"), simplify_irreps3=True,\n)\n\n# Full (weightless) tensor product\ne = cue.descriptors.full_tensor_product(\n    cue.Irreps(\"SO3\", \"2x0 + 1x1\"), cue.Irreps(\"SO3\", \"0 + 1\"),\n)\n\n# Elementwise tensor product (paired channels)\ne = cue.descriptors.elementwise_tensor_product(\n    cue.Irreps(\"SO3\", \"4x0 + 4x1\"), cue.Irreps(\"SO3\", \"4x0 + 4x1\"),\n)\n\n# Linear equivariant map (weight x input)\ne = cue.descriptors.linear(\n    cue.Irreps(\"SO3\", \"4x0 + 2x1\"),\n    cue.Irreps(\"SO3\", \"3x0 + 5x1\"),\n)\n\n# Spherical harmonics\ne = cue.descriptors.spherical_harmonics(cue.SO3(1), [0, 1, 2, 3])\n\n# Symmetric contraction (MACE-style)\ne = cue.descriptors.symmetric_contraction(\n    64 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n    64 * cue.Irreps(\"SO3\", \"0 + 1\"),\n    (1, 2, 3),\n)\n",[1855],{"type":40,"tag":60,"props":1856,"children":1857},{"__ignoreMap":214},[1858,1866,1874,1882,1889,1896,1904,1911,1919,1927,1935,1943,1950,1957,1965,1973,1981,1988,1995,2003,2011,2019,2026,2033,2041,2049,2057,2065,2072,2079,2087,2095,2102,2110,2118,2126,2134,2142],{"type":40,"tag":220,"props":1859,"children":1860},{"class":222,"line":223},[1861],{"type":40,"tag":220,"props":1862,"children":1863},{},[1864],{"type":46,"value":1865},"# Fully connected tensor product (all input-output irrep combinations)\n",{"type":40,"tag":220,"props":1867,"children":1868},{"class":222,"line":232},[1869],{"type":40,"tag":220,"props":1870,"children":1871},{},[1872],{"type":46,"value":1873},"e = cue.descriptors.fully_connected_tensor_product(\n",{"type":40,"tag":220,"props":1875,"children":1876},{"class":222,"line":241},[1877],{"type":40,"tag":220,"props":1878,"children":1879},{},[1880],{"type":46,"value":1881},"    16 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n",{"type":40,"tag":220,"props":1883,"children":1884},{"class":222,"line":250},[1885],{"type":40,"tag":220,"props":1886,"children":1887},{},[1888],{"type":46,"value":1881},{"type":40,"tag":220,"props":1890,"children":1891},{"class":222,"line":259},[1892],{"type":40,"tag":220,"props":1893,"children":1894},{},[1895],{"type":46,"value":1881},{"type":40,"tag":220,"props":1897,"children":1898},{"class":222,"line":268},[1899],{"type":40,"tag":220,"props":1900,"children":1901},{},[1902],{"type":46,"value":1903},")\n",{"type":40,"tag":220,"props":1905,"children":1906},{"class":222,"line":277},[1907],{"type":40,"tag":220,"props":1908,"children":1909},{"emptyLinePlaceholder":281},[1910],{"type":46,"value":284},{"type":40,"tag":220,"props":1912,"children":1913},{"class":222,"line":287},[1914],{"type":40,"tag":220,"props":1915,"children":1916},{},[1917],{"type":46,"value":1918},"# Channelwise tensor product (same-channel only, sparse)\n",{"type":40,"tag":220,"props":1920,"children":1921},{"class":222,"line":296},[1922],{"type":40,"tag":220,"props":1923,"children":1924},{},[1925],{"type":46,"value":1926},"e = cue.descriptors.channelwise_tensor_product(\n",{"type":40,"tag":220,"props":1928,"children":1929},{"class":222,"line":305},[1930],{"type":40,"tag":220,"props":1931,"children":1932},{},[1933],{"type":46,"value":1934},"    64 * cue.Irreps(\"SO3\", \"0 + 1\"), cue.Irreps(\"SO3\", \"0 + 1\"),\n",{"type":40,"tag":220,"props":1936,"children":1937},{"class":222,"line":314},[1938],{"type":40,"tag":220,"props":1939,"children":1940},{},[1941],{"type":46,"value":1942},"    cue.Irreps(\"SO3\", \"0 + 1\"), simplify_irreps3=True,\n",{"type":40,"tag":220,"props":1944,"children":1945},{"class":222,"line":322},[1946],{"type":40,"tag":220,"props":1947,"children":1948},{},[1949],{"type":46,"value":1903},{"type":40,"tag":220,"props":1951,"children":1952},{"class":222,"line":331},[1953],{"type":40,"tag":220,"props":1954,"children":1955},{"emptyLinePlaceholder":281},[1956],{"type":46,"value":284},{"type":40,"tag":220,"props":1958,"children":1959},{"class":222,"line":339},[1960],{"type":40,"tag":220,"props":1961,"children":1962},{},[1963],{"type":46,"value":1964},"# Full (weightless) tensor product\n",{"type":40,"tag":220,"props":1966,"children":1967},{"class":222,"line":348},[1968],{"type":40,"tag":220,"props":1969,"children":1970},{},[1971],{"type":46,"value":1972},"e = cue.descriptors.full_tensor_product(\n",{"type":40,"tag":220,"props":1974,"children":1975},{"class":222,"line":357},[1976],{"type":40,"tag":220,"props":1977,"children":1978},{},[1979],{"type":46,"value":1980},"    cue.Irreps(\"SO3\", \"2x0 + 1x1\"), cue.Irreps(\"SO3\", \"0 + 1\"),\n",{"type":40,"tag":220,"props":1982,"children":1983},{"class":222,"line":366},[1984],{"type":40,"tag":220,"props":1985,"children":1986},{},[1987],{"type":46,"value":1903},{"type":40,"tag":220,"props":1989,"children":1990},{"class":222,"line":375},[1991],{"type":40,"tag":220,"props":1992,"children":1993},{"emptyLinePlaceholder":281},[1994],{"type":46,"value":284},{"type":40,"tag":220,"props":1996,"children":1997},{"class":222,"line":383},[1998],{"type":40,"tag":220,"props":1999,"children":2000},{},[2001],{"type":46,"value":2002},"# Elementwise tensor product (paired channels)\n",{"type":40,"tag":220,"props":2004,"children":2005},{"class":222,"line":391},[2006],{"type":40,"tag":220,"props":2007,"children":2008},{},[2009],{"type":46,"value":2010},"e = cue.descriptors.elementwise_tensor_product(\n",{"type":40,"tag":220,"props":2012,"children":2013},{"class":222,"line":400},[2014],{"type":40,"tag":220,"props":2015,"children":2016},{},[2017],{"type":46,"value":2018},"    cue.Irreps(\"SO3\", \"4x0 + 4x1\"), cue.Irreps(\"SO3\", \"4x0 + 4x1\"),\n",{"type":40,"tag":220,"props":2020,"children":2021},{"class":222,"line":409},[2022],{"type":40,"tag":220,"props":2023,"children":2024},{},[2025],{"type":46,"value":1903},{"type":40,"tag":220,"props":2027,"children":2028},{"class":222,"line":417},[2029],{"type":40,"tag":220,"props":2030,"children":2031},{"emptyLinePlaceholder":281},[2032],{"type":46,"value":284},{"type":40,"tag":220,"props":2034,"children":2035},{"class":222,"line":426},[2036],{"type":40,"tag":220,"props":2037,"children":2038},{},[2039],{"type":46,"value":2040},"# Linear equivariant map (weight x input)\n",{"type":40,"tag":220,"props":2042,"children":2043},{"class":222,"line":435},[2044],{"type":40,"tag":220,"props":2045,"children":2046},{},[2047],{"type":46,"value":2048},"e = cue.descriptors.linear(\n",{"type":40,"tag":220,"props":2050,"children":2051},{"class":222,"line":443},[2052],{"type":40,"tag":220,"props":2053,"children":2054},{},[2055],{"type":46,"value":2056},"    cue.Irreps(\"SO3\", \"4x0 + 2x1\"),\n",{"type":40,"tag":220,"props":2058,"children":2059},{"class":222,"line":452},[2060],{"type":40,"tag":220,"props":2061,"children":2062},{},[2063],{"type":46,"value":2064},"    cue.Irreps(\"SO3\", \"3x0 + 5x1\"),\n",{"type":40,"tag":220,"props":2066,"children":2067},{"class":222,"line":461},[2068],{"type":40,"tag":220,"props":2069,"children":2070},{},[2071],{"type":46,"value":1903},{"type":40,"tag":220,"props":2073,"children":2074},{"class":222,"line":470},[2075],{"type":40,"tag":220,"props":2076,"children":2077},{"emptyLinePlaceholder":281},[2078],{"type":46,"value":284},{"type":40,"tag":220,"props":2080,"children":2081},{"class":222,"line":478},[2082],{"type":40,"tag":220,"props":2083,"children":2084},{},[2085],{"type":46,"value":2086},"# Spherical harmonics\n",{"type":40,"tag":220,"props":2088,"children":2089},{"class":222,"line":486},[2090],{"type":40,"tag":220,"props":2091,"children":2092},{},[2093],{"type":46,"value":2094},"e = cue.descriptors.spherical_harmonics(cue.SO3(1), [0, 1, 2, 3])\n",{"type":40,"tag":220,"props":2096,"children":2097},{"class":222,"line":495},[2098],{"type":40,"tag":220,"props":2099,"children":2100},{"emptyLinePlaceholder":281},[2101],{"type":46,"value":284},{"type":40,"tag":220,"props":2103,"children":2104},{"class":222,"line":504},[2105],{"type":40,"tag":220,"props":2106,"children":2107},{},[2108],{"type":46,"value":2109},"# Symmetric contraction (MACE-style)\n",{"type":40,"tag":220,"props":2111,"children":2112},{"class":222,"line":513},[2113],{"type":40,"tag":220,"props":2114,"children":2115},{},[2116],{"type":46,"value":2117},"e = cue.descriptors.symmetric_contraction(\n",{"type":40,"tag":220,"props":2119,"children":2120},{"class":222,"line":522},[2121],{"type":40,"tag":220,"props":2122,"children":2123},{},[2124],{"type":46,"value":2125},"    64 * cue.Irreps(\"SO3\", \"0 + 1 + 2\"),\n",{"type":40,"tag":220,"props":2127,"children":2128},{"class":222,"line":27},[2129],{"type":40,"tag":220,"props":2130,"children":2131},{},[2132],{"type":46,"value":2133},"    64 * cue.Irreps(\"SO3\", \"0 + 1\"),\n",{"type":40,"tag":220,"props":2135,"children":2136},{"class":222,"line":539},[2137],{"type":40,"tag":220,"props":2138,"children":2139},{},[2140],{"type":46,"value":2141},"    (1, 2, 3),\n",{"type":40,"tag":220,"props":2143,"children":2144},{"class":222,"line":547},[2145],{"type":40,"tag":220,"props":2146,"children":2147},{},[2148],{"type":46,"value":1903},{"type":40,"tag":825,"props":2150,"children":2152},{"id":2151},"irdictpolynomial-descriptors",[2153],{"type":46,"value":2154},"IrDictPolynomial descriptors",{"type":40,"tag":56,"props":2156,"children":2157},{},[2158,2160,2165,2167,2172,2174,2180,2182,2188],{"type":46,"value":2159},"Each ",{"type":40,"tag":60,"props":2161,"children":2163},{"className":2162},[],[2164],{"type":46,"value":1836},{"type":46,"value":2166}," variant returns an ",{"type":40,"tag":60,"props":2168,"children":2170},{"className":2169},[],[2171],{"type":46,"value":171},{"type":46,"value":2173}," whose polynomial is already split by irrep. The ",{"type":40,"tag":60,"props":2175,"children":2177},{"className":2176},[],[2178],{"type":46,"value":2179},"input_irreps",{"type":46,"value":2181}," and ",{"type":40,"tag":60,"props":2183,"children":2185},{"className":2184},[],[2186],{"type":46,"value":2187},"output_irreps",{"type":46,"value":2189}," tuples describe the operand groups.",{"type":40,"tag":209,"props":2191,"children":2193},{"className":211,"code":2192,"language":213,"meta":214,"style":214},"# Channelwise tensor product\ndesc = cue.descriptors.channelwise_tensor_product_ir_dict(\n    64 * cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n)\n# desc.polynomial       — SegmentedPolynomial, already split by irrep\n# desc.input_irreps     — (weight_irreps, irreps1, irreps2)\n# desc.output_irreps    — (irreps_out,)\n\n# Fully connected tensor product\ndesc = cue.descriptors.fully_connected_tensor_product_ir_dict(irreps1, irreps2, irreps3)\n\n# Full (weightless) tensor product\ndesc = cue.descriptors.full_tensor_product_ir_dict(irreps1, irreps2)\n\n# Elementwise tensor product\ndesc = cue.descriptors.elementwise_tensor_product_ir_dict(irreps1, irreps2)\n\n# Linear\ndesc = cue.descriptors.linear_ir_dict(irreps_in, irreps_out)\n\n# Spherical harmonics\ndesc = cue.descriptors.spherical_harmonics_ir_dict(cue.O3(1, -1), [0, 1, 2, 3])\n\n# Symmetric contraction\ndesc = cue.descriptors.symmetric_contraction_ir_dict(irreps_in, irreps_out, (1, 2, 3))\n",[2194],{"type":40,"tag":60,"props":2195,"children":2196},{"__ignoreMap":214},[2197,2205,2213,2220,2228,2235,2242,2250,2258,2266,2273,2281,2289,2296,2303,2311,2318,2326,2334,2341,2349,2357,2364,2371,2379,2386,2394],{"type":40,"tag":220,"props":2198,"children":2199},{"class":222,"line":223},[2200],{"type":40,"tag":220,"props":2201,"children":2202},{},[2203],{"type":46,"value":2204},"# Channelwise tensor product\n",{"type":40,"tag":220,"props":2206,"children":2207},{"class":222,"line":232},[2208],{"type":40,"tag":220,"props":2209,"children":2210},{},[2211],{"type":46,"value":2212},"desc = cue.descriptors.channelwise_tensor_product_ir_dict(\n",{"type":40,"tag":220,"props":2214,"children":2215},{"class":222,"line":241},[2216],{"type":40,"tag":220,"props":2217,"children":2218},{},[2219],{"type":46,"value":2133},{"type":40,"tag":220,"props":2221,"children":2222},{"class":222,"line":250},[2223],{"type":40,"tag":220,"props":2224,"children":2225},{},[2226],{"type":46,"value":2227},"    cue.Irreps(\"SO3\", \"0 + 1\"),\n",{"type":40,"tag":220,"props":2229,"children":2230},{"class":222,"line":259},[2231],{"type":40,"tag":220,"props":2232,"children":2233},{},[2234],{"type":46,"value":2227},{"type":40,"tag":220,"props":2236,"children":2237},{"class":222,"line":268},[2238],{"type":40,"tag":220,"props":2239,"children":2240},{},[2241],{"type":46,"value":1903},{"type":40,"tag":220,"props":2243,"children":2244},{"class":222,"line":277},[2245],{"type":40,"tag":220,"props":2246,"children":2247},{},[2248],{"type":46,"value":2249},"# desc.polynomial       — SegmentedPolynomial, already split by irrep\n",{"type":40,"tag":220,"props":2251,"children":2252},{"class":222,"line":287},[2253],{"type":40,"tag":220,"props":2254,"children":2255},{},[2256],{"type":46,"value":2257},"# desc.input_irreps     — (weight_irreps, irreps1, irreps2)\n",{"type":40,"tag":220,"props":2259,"children":2260},{"class":222,"line":296},[2261],{"type":40,"tag":220,"props":2262,"children":2263},{},[2264],{"type":46,"value":2265},"# desc.output_irreps    — (irreps_out,)\n",{"type":40,"tag":220,"props":2267,"children":2268},{"class":222,"line":305},[2269],{"type":40,"tag":220,"props":2270,"children":2271},{"emptyLinePlaceholder":281},[2272],{"type":46,"value":284},{"type":40,"tag":220,"props":2274,"children":2275},{"class":222,"line":314},[2276],{"type":40,"tag":220,"props":2277,"children":2278},{},[2279],{"type":46,"value":2280},"# Fully connected tensor product\n",{"type":40,"tag":220,"props":2282,"children":2283},{"class":222,"line":322},[2284],{"type":40,"tag":220,"props":2285,"children":2286},{},[2287],{"type":46,"value":2288},"desc = cue.descriptors.fully_connected_tensor_product_ir_dict(irreps1, irreps2, irreps3)\n",{"type":40,"tag":220,"props":2290,"children":2291},{"class":222,"line":331},[2292],{"type":40,"tag":220,"props":2293,"children":2294},{"emptyLinePlaceholder":281},[2295],{"type":46,"value":284},{"type":40,"tag":220,"props":2297,"children":2298},{"class":222,"line":339},[2299],{"type":40,"tag":220,"props":2300,"children":2301},{},[2302],{"type":46,"value":1964},{"type":40,"tag":220,"props":2304,"children":2305},{"class":222,"line":348},[2306],{"type":40,"tag":220,"props":2307,"children":2308},{},[2309],{"type":46,"value":2310},"desc = cue.descriptors.full_tensor_product_ir_dict(irreps1, irreps2)\n",{"type":40,"tag":220,"props":2312,"children":2313},{"class":222,"line":357},[2314],{"type":40,"tag":220,"props":2315,"children":2316},{"emptyLinePlaceholder":281},[2317],{"type":46,"value":284},{"type":40,"tag":220,"props":2319,"children":2320},{"class":222,"line":366},[2321],{"type":40,"tag":220,"props":2322,"children":2323},{},[2324],{"type":46,"value":2325},"# Elementwise tensor product\n",{"type":40,"tag":220,"props":2327,"children":2328},{"class":222,"line":375},[2329],{"type":40,"tag":220,"props":2330,"children":2331},{},[2332],{"type":46,"value":2333},"desc = cue.descriptors.elementwise_tensor_product_ir_dict(irreps1, irreps2)\n",{"type":40,"tag":220,"props":2335,"children":2336},{"class":222,"line":383},[2337],{"type":40,"tag":220,"props":2338,"children":2339},{"emptyLinePlaceholder":281},[2340],{"type":46,"value":284},{"type":40,"tag":220,"props":2342,"children":2343},{"class":222,"line":391},[2344],{"type":40,"tag":220,"props":2345,"children":2346},{},[2347],{"type":46,"value":2348},"# Linear\n",{"type":40,"tag":220,"props":2350,"children":2351},{"class":222,"line":400},[2352],{"type":40,"tag":220,"props":2353,"children":2354},{},[2355],{"type":46,"value":2356},"desc = cue.descriptors.linear_ir_dict(irreps_in, irreps_out)\n",{"type":40,"tag":220,"props":2358,"children":2359},{"class":222,"line":409},[2360],{"type":40,"tag":220,"props":2361,"children":2362},{"emptyLinePlaceholder":281},[2363],{"type":46,"value":284},{"type":40,"tag":220,"props":2365,"children":2366},{"class":222,"line":417},[2367],{"type":40,"tag":220,"props":2368,"children":2369},{},[2370],{"type":46,"value":2086},{"type":40,"tag":220,"props":2372,"children":2373},{"class":222,"line":426},[2374],{"type":40,"tag":220,"props":2375,"children":2376},{},[2377],{"type":46,"value":2378},"desc = cue.descriptors.spherical_harmonics_ir_dict(cue.O3(1, -1), [0, 1, 2, 3])\n",{"type":40,"tag":220,"props":2380,"children":2381},{"class":222,"line":435},[2382],{"type":40,"tag":220,"props":2383,"children":2384},{"emptyLinePlaceholder":281},[2385],{"type":46,"value":284},{"type":40,"tag":220,"props":2387,"children":2388},{"class":222,"line":443},[2389],{"type":40,"tag":220,"props":2390,"children":2391},{},[2392],{"type":46,"value":2393},"# Symmetric contraction\n",{"type":40,"tag":220,"props":2395,"children":2396},{"class":222,"line":452},[2397],{"type":40,"tag":220,"props":2398,"children":2399},{},[2400],{"type":46,"value":2401},"desc = cue.descriptors.symmetric_contraction_ir_dict(irreps_in, irreps_out, (1, 2, 3))\n",{"type":40,"tag":825,"props":2403,"children":2405},{"id":2404},"irdictpolynomial",[2406],{"type":46,"value":171},{"type":40,"tag":56,"props":2408,"children":2409},{},[2410,2415,2417,2422,2424,2429],{"type":40,"tag":60,"props":2411,"children":2413},{"className":2412},[],[2414],{"type":46,"value":171},{"type":46,"value":2416}," pairs a ",{"type":40,"tag":60,"props":2418,"children":2420},{"className":2419},[],[2421],{"type":46,"value":137},{"type":46,"value":2423}," (already split by irrep) with the ",{"type":40,"tag":60,"props":2425,"children":2427},{"className":2426},[],[2428],{"type":46,"value":104},{"type":46,"value":2430}," that describe each operand group.",{"type":40,"tag":209,"props":2432,"children":2434},{"className":211,"code":2433,"language":213,"meta":214,"style":214},"desc = cue.descriptors.channelwise_tensor_product_ir_dict(\n    32 * cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n    cue.Irreps(\"SO3\", \"0 + 1\"),\n)\n\ndesc.polynomial       # SegmentedPolynomial — each operand is one (mul, ir) block\ndesc.input_irreps     # (weight_irreps, irreps1, irreps2)\ndesc.output_irreps    # (irreps_out,)\n\n# Scale coefficients\nscaled_poly = desc.polynomial * 0.5\n\n# Access individual operand info\nfor i, op in enumerate(desc.polynomial.inputs):\n    print(f\"Input {i}: size={op.size}, num_segments={op.num_segments}\")\n",[2435],{"type":40,"tag":60,"props":2436,"children":2437},{"__ignoreMap":214},[2438,2445,2453,2460,2467,2474,2481,2489,2497,2505,2512,2520,2528,2535,2543,2551],{"type":40,"tag":220,"props":2439,"children":2440},{"class":222,"line":223},[2441],{"type":40,"tag":220,"props":2442,"children":2443},{},[2444],{"type":46,"value":2212},{"type":40,"tag":220,"props":2446,"children":2447},{"class":222,"line":232},[2448],{"type":40,"tag":220,"props":2449,"children":2450},{},[2451],{"type":46,"value":2452},"    32 * cue.Irreps(\"SO3\", \"0 + 1\"),\n",{"type":40,"tag":220,"props":2454,"children":2455},{"class":222,"line":241},[2456],{"type":40,"tag":220,"props":2457,"children":2458},{},[2459],{"type":46,"value":2227},{"type":40,"tag":220,"props":2461,"children":2462},{"class":222,"line":250},[2463],{"type":40,"tag":220,"props":2464,"children":2465},{},[2466],{"type":46,"value":2227},{"type":40,"tag":220,"props":2468,"children":2469},{"class":222,"line":259},[2470],{"type":40,"tag":220,"props":2471,"children":2472},{},[2473],{"type":46,"value":1903},{"type":40,"tag":220,"props":2475,"children":2476},{"class":222,"line":268},[2477],{"type":40,"tag":220,"props":2478,"children":2479},{"emptyLinePlaceholder":281},[2480],{"type":46,"value":284},{"type":40,"tag":220,"props":2482,"children":2483},{"class":222,"line":277},[2484],{"type":40,"tag":220,"props":2485,"children":2486},{},[2487],{"type":46,"value":2488},"desc.polynomial       # SegmentedPolynomial — each operand is one (mul, ir) block\n",{"type":40,"tag":220,"props":2490,"children":2491},{"class":222,"line":287},[2492],{"type":40,"tag":220,"props":2493,"children":2494},{},[2495],{"type":46,"value":2496},"desc.input_irreps     # (weight_irreps, irreps1, irreps2)\n",{"type":40,"tag":220,"props":2498,"children":2499},{"class":222,"line":296},[2500],{"type":40,"tag":220,"props":2501,"children":2502},{},[2503],{"type":46,"value":2504},"desc.output_irreps    # (irreps_out,)\n",{"type":40,"tag":220,"props":2506,"children":2507},{"class":222,"line":305},[2508],{"type":40,"tag":220,"props":2509,"children":2510},{"emptyLinePlaceholder":281},[2511],{"type":46,"value":284},{"type":40,"tag":220,"props":2513,"children":2514},{"class":222,"line":314},[2515],{"type":40,"tag":220,"props":2516,"children":2517},{},[2518],{"type":46,"value":2519},"# Scale coefficients\n",{"type":40,"tag":220,"props":2521,"children":2522},{"class":222,"line":322},[2523],{"type":40,"tag":220,"props":2524,"children":2525},{},[2526],{"type":46,"value":2527},"scaled_poly = desc.polynomial * 0.5\n",{"type":40,"tag":220,"props":2529,"children":2530},{"class":222,"line":331},[2531],{"type":40,"tag":220,"props":2532,"children":2533},{"emptyLinePlaceholder":281},[2534],{"type":46,"value":284},{"type":40,"tag":220,"props":2536,"children":2537},{"class":222,"line":339},[2538],{"type":40,"tag":220,"props":2539,"children":2540},{},[2541],{"type":46,"value":2542},"# Access individual operand info\n",{"type":40,"tag":220,"props":2544,"children":2545},{"class":222,"line":348},[2546],{"type":40,"tag":220,"props":2547,"children":2548},{},[2549],{"type":46,"value":2550},"for i, op in enumerate(desc.polynomial.inputs):\n",{"type":40,"tag":220,"props":2552,"children":2553},{"class":222,"line":357},[2554],{"type":40,"tag":220,"props":2555,"children":2556},{},[2557],{"type":46,"value":2558},"    print(f\"Input {i}: size={op.size}, num_segments={op.num_segments}\")\n",{"type":40,"tag":56,"props":2560,"children":2561},{},[2562,2564,2569,2571,2576,2578,2583,2585,2591],{"type":46,"value":2563},"Contract: for each ",{"type":40,"tag":60,"props":2565,"children":2567},{"className":2566},[],[2568],{"type":46,"value":1390},{"type":46,"value":2570}," block in ",{"type":40,"tag":60,"props":2572,"children":2574},{"className":2573},[],[2575],{"type":46,"value":2179},{"type":46,"value":2577}," \u002F ",{"type":40,"tag":60,"props":2579,"children":2581},{"className":2580},[],[2582],{"type":46,"value":2187},{"type":46,"value":2584},", the corresponding polynomial operand has size ",{"type":40,"tag":60,"props":2586,"children":2588},{"className":2587},[],[2589],{"type":46,"value":2590},"mul * ir.dim",{"type":46,"value":1230},{"type":40,"tag":825,"props":2593,"children":2595},{"id":2594},"split_polynomial_by_irreps",[2596],{"type":46,"value":2594},{"type":40,"tag":56,"props":2598,"children":2599},{},[2600,2602,2607],{"type":46,"value":2601},"The low-level function underlying ",{"type":40,"tag":60,"props":2603,"children":2605},{"className":2604},[],[2606],{"type":46,"value":1836},{"type":46,"value":2608}," descriptors. Splits one polynomial operand at irrep boundaries:",{"type":40,"tag":209,"props":2610,"children":2612},{"className":211,"code":2611,"language":213,"meta":214,"style":214},"poly = e.polynomial  # from an EquivariantPolynomial\npoly = cue.split_polynomial_by_irreps(poly, 2, irreps_sh)   # split input 2\npoly = cue.split_polynomial_by_irreps(poly, 1, irreps_in)   # split input 1\npoly = cue.split_polynomial_by_irreps(poly, -1, irreps_out) # split output\n",[2613],{"type":40,"tag":60,"props":2614,"children":2615},{"__ignoreMap":214},[2616,2624,2632,2640],{"type":40,"tag":220,"props":2617,"children":2618},{"class":222,"line":223},[2619],{"type":40,"tag":220,"props":2620,"children":2621},{},[2622],{"type":46,"value":2623},"poly = e.polynomial  # from an EquivariantPolynomial\n",{"type":40,"tag":220,"props":2625,"children":2626},{"class":222,"line":232},[2627],{"type":40,"tag":220,"props":2628,"children":2629},{},[2630],{"type":46,"value":2631},"poly = cue.split_polynomial_by_irreps(poly, 2, irreps_sh)   # split input 2\n",{"type":40,"tag":220,"props":2633,"children":2634},{"class":222,"line":241},[2635],{"type":40,"tag":220,"props":2636,"children":2637},{},[2638],{"type":46,"value":2639},"poly = cue.split_polynomial_by_irreps(poly, 1, irreps_in)   # split input 1\n",{"type":40,"tag":220,"props":2641,"children":2642},{"class":222,"line":250},[2643],{"type":40,"tag":220,"props":2644,"children":2645},{},[2646],{"type":46,"value":2647},"poly = cue.split_polynomial_by_irreps(poly, -1, irreps_out) # split output\n",{"type":40,"tag":825,"props":2649,"children":2651},{"id":2650},"equivariantpolynomial-key-methods",[2652],{"type":46,"value":2653},"EquivariantPolynomial key methods",{"type":40,"tag":209,"props":2655,"children":2657},{"className":211,"code":2656,"language":213,"meta":214,"style":214},"e.inputs     # tuple of Rep (group representations for each input)\ne.outputs    # tuple of Rep\ne.polynomial # the underlying SegmentedPolynomial\n\n# Numpy evaluation\n[out] = e(weights, input1, input2)\n\n# Preparing for uniform_1d execution (see cuequivariance_jax SKILL.md)\ne_ready = e.squeeze_modes().flatten_coefficient_modes()\n\n# Split an operand into per-irrep pieces (for ir_dict interface)\ne_split = e.split_operand_by_irrep(1).split_operand_by_irrep(-1)\n\n# Scale all coefficients\ne_scaled = e * 0.5\n\n# Fuse compatible STPs\ne_fused = e.fuse_stps()\n",[2658],{"type":40,"tag":60,"props":2659,"children":2660},{"__ignoreMap":214},[2661,2669,2677,2685,2692,2700,2708,2715,2723,2731,2738,2746,2754,2761,2769,2777,2784,2792],{"type":40,"tag":220,"props":2662,"children":2663},{"class":222,"line":223},[2664],{"type":40,"tag":220,"props":2665,"children":2666},{},[2667],{"type":46,"value":2668},"e.inputs     # tuple of Rep (group representations for each input)\n",{"type":40,"tag":220,"props":2670,"children":2671},{"class":222,"line":232},[2672],{"type":40,"tag":220,"props":2673,"children":2674},{},[2675],{"type":46,"value":2676},"e.outputs    # tuple of Rep\n",{"type":40,"tag":220,"props":2678,"children":2679},{"class":222,"line":241},[2680],{"type":40,"tag":220,"props":2681,"children":2682},{},[2683],{"type":46,"value":2684},"e.polynomial # the underlying SegmentedPolynomial\n",{"type":40,"tag":220,"props":2686,"children":2687},{"class":222,"line":250},[2688],{"type":40,"tag":220,"props":2689,"children":2690},{"emptyLinePlaceholder":281},[2691],{"type":46,"value":284},{"type":40,"tag":220,"props":2693,"children":2694},{"class":222,"line":259},[2695],{"type":40,"tag":220,"props":2696,"children":2697},{},[2698],{"type":46,"value":2699},"# Numpy evaluation\n",{"type":40,"tag":220,"props":2701,"children":2702},{"class":222,"line":268},[2703],{"type":40,"tag":220,"props":2704,"children":2705},{},[2706],{"type":46,"value":2707},"[out] = e(weights, input1, input2)\n",{"type":40,"tag":220,"props":2709,"children":2710},{"class":222,"line":277},[2711],{"type":40,"tag":220,"props":2712,"children":2713},{"emptyLinePlaceholder":281},[2714],{"type":46,"value":284},{"type":40,"tag":220,"props":2716,"children":2717},{"class":222,"line":287},[2718],{"type":40,"tag":220,"props":2719,"children":2720},{},[2721],{"type":46,"value":2722},"# Preparing for uniform_1d execution (see cuequivariance_jax SKILL.md)\n",{"type":40,"tag":220,"props":2724,"children":2725},{"class":222,"line":296},[2726],{"type":40,"tag":220,"props":2727,"children":2728},{},[2729],{"type":46,"value":2730},"e_ready = e.squeeze_modes().flatten_coefficient_modes()\n",{"type":40,"tag":220,"props":2732,"children":2733},{"class":222,"line":305},[2734],{"type":40,"tag":220,"props":2735,"children":2736},{"emptyLinePlaceholder":281},[2737],{"type":46,"value":284},{"type":40,"tag":220,"props":2739,"children":2740},{"class":222,"line":314},[2741],{"type":40,"tag":220,"props":2742,"children":2743},{},[2744],{"type":46,"value":2745},"# Split an operand into per-irrep pieces (for ir_dict interface)\n",{"type":40,"tag":220,"props":2747,"children":2748},{"class":222,"line":322},[2749],{"type":40,"tag":220,"props":2750,"children":2751},{},[2752],{"type":46,"value":2753},"e_split = e.split_operand_by_irrep(1).split_operand_by_irrep(-1)\n",{"type":40,"tag":220,"props":2755,"children":2756},{"class":222,"line":331},[2757],{"type":40,"tag":220,"props":2758,"children":2759},{"emptyLinePlaceholder":281},[2760],{"type":46,"value":284},{"type":40,"tag":220,"props":2762,"children":2763},{"class":222,"line":339},[2764],{"type":40,"tag":220,"props":2765,"children":2766},{},[2767],{"type":46,"value":2768},"# Scale all coefficients\n",{"type":40,"tag":220,"props":2770,"children":2771},{"class":222,"line":348},[2772],{"type":40,"tag":220,"props":2773,"children":2774},{},[2775],{"type":46,"value":2776},"e_scaled = e * 0.5\n",{"type":40,"tag":220,"props":2778,"children":2779},{"class":222,"line":357},[2780],{"type":40,"tag":220,"props":2781,"children":2782},{"emptyLinePlaceholder":281},[2783],{"type":46,"value":284},{"type":40,"tag":220,"props":2785,"children":2786},{"class":222,"line":366},[2787],{"type":40,"tag":220,"props":2788,"children":2789},{},[2790],{"type":46,"value":2791},"# Fuse compatible STPs\n",{"type":40,"tag":220,"props":2793,"children":2794},{"class":222,"line":375},[2795],{"type":40,"tag":220,"props":2796,"children":2797},{},[2798],{"type":46,"value":2799},"e_fused = e.fuse_stps()\n",{"type":40,"tag":825,"props":2801,"children":2803},{"id":2802},"normalize_paths_for_operand",[2804],{"type":46,"value":2802},{"type":40,"tag":56,"props":2806,"children":2807},{},[2808],{"type":46,"value":2809},"Called internally by descriptors. Normalizes path coefficients so that a random input produces unit-variance output for the specified operand. Critical for numerical stability.",{"type":40,"tag":49,"props":2811,"children":2813},{"id":2812},"segmentedpolynomial-structure",[2814],{"type":46,"value":2815},"SegmentedPolynomial structure",{"type":40,"tag":209,"props":2817,"children":2819},{"className":211,"code":2818,"language":213,"meta":214,"style":214},"poly = e.polynomial\npoly.num_inputs    # number of input operands\npoly.num_outputs   # number of output operands\npoly.inputs        # tuple of SegmentedOperand\npoly.outputs       # tuple of SegmentedOperand\npoly.operations    # tuple of (Operation, SegmentedTensorProduct)\n\n# Each operation maps buffers to STP operands\nfor op, stp in poly.operations:\n    print(op.buffers)  # e.g., (0, 1, 2) means inputs[0], inputs[1] -> outputs[0]\n    print(stp.subscripts)\n",[2820],{"type":40,"tag":60,"props":2821,"children":2822},{"__ignoreMap":214},[2823,2831,2839,2847,2855,2863,2871,2878,2886,2894,2902],{"type":40,"tag":220,"props":2824,"children":2825},{"class":222,"line":223},[2826],{"type":40,"tag":220,"props":2827,"children":2828},{},[2829],{"type":46,"value":2830},"poly = e.polynomial\n",{"type":40,"tag":220,"props":2832,"children":2833},{"class":222,"line":232},[2834],{"type":40,"tag":220,"props":2835,"children":2836},{},[2837],{"type":46,"value":2838},"poly.num_inputs    # number of input operands\n",{"type":40,"tag":220,"props":2840,"children":2841},{"class":222,"line":241},[2842],{"type":40,"tag":220,"props":2843,"children":2844},{},[2845],{"type":46,"value":2846},"poly.num_outputs   # number of output operands\n",{"type":40,"tag":220,"props":2848,"children":2849},{"class":222,"line":250},[2850],{"type":40,"tag":220,"props":2851,"children":2852},{},[2853],{"type":46,"value":2854},"poly.inputs        # tuple of SegmentedOperand\n",{"type":40,"tag":220,"props":2856,"children":2857},{"class":222,"line":259},[2858],{"type":40,"tag":220,"props":2859,"children":2860},{},[2861],{"type":46,"value":2862},"poly.outputs       # tuple of SegmentedOperand\n",{"type":40,"tag":220,"props":2864,"children":2865},{"class":222,"line":268},[2866],{"type":40,"tag":220,"props":2867,"children":2868},{},[2869],{"type":46,"value":2870},"poly.operations    # tuple of (Operation, SegmentedTensorProduct)\n",{"type":40,"tag":220,"props":2872,"children":2873},{"class":222,"line":277},[2874],{"type":40,"tag":220,"props":2875,"children":2876},{"emptyLinePlaceholder":281},[2877],{"type":46,"value":284},{"type":40,"tag":220,"props":2879,"children":2880},{"class":222,"line":287},[2881],{"type":40,"tag":220,"props":2882,"children":2883},{},[2884],{"type":46,"value":2885},"# Each operation maps buffers to STP operands\n",{"type":40,"tag":220,"props":2887,"children":2888},{"class":222,"line":296},[2889],{"type":40,"tag":220,"props":2890,"children":2891},{},[2892],{"type":46,"value":2893},"for op, stp in poly.operations:\n",{"type":40,"tag":220,"props":2895,"children":2896},{"class":222,"line":305},[2897],{"type":40,"tag":220,"props":2898,"children":2899},{},[2900],{"type":46,"value":2901},"    print(op.buffers)  # e.g., (0, 1, 2) means inputs[0], inputs[1] -> outputs[0]\n",{"type":40,"tag":220,"props":2903,"children":2904},{"class":222,"line":314},[2905],{"type":40,"tag":220,"props":2906,"children":2907},{},[2908],{"type":46,"value":2909},"    print(stp.subscripts)\n",{"type":40,"tag":825,"props":2911,"children":2913},{"id":2912},"segmentedoperand",[2914],{"type":46,"value":2915},"SegmentedOperand",{"type":40,"tag":209,"props":2917,"children":2919},{"className":211,"code":2918,"language":213,"meta":214,"style":214},"operand = poly.inputs[0]\noperand.num_segments     # how many segments\noperand.segments         # tuple of shape tuples, e.g., ((3, 4), (1, 2))\noperand.size             # total flattened size (sum of products of segment shapes)\noperand.ndim             # number of dimensions per segment\noperand.all_same_segment_shape()  # True if all segments have identical shape\noperand.segment_shape    # the common shape (only if all_same_segment_shape)\n",[2920],{"type":40,"tag":60,"props":2921,"children":2922},{"__ignoreMap":214},[2923,2931,2939,2947,2955,2963,2971],{"type":40,"tag":220,"props":2924,"children":2925},{"class":222,"line":223},[2926],{"type":40,"tag":220,"props":2927,"children":2928},{},[2929],{"type":46,"value":2930},"operand = poly.inputs[0]\n",{"type":40,"tag":220,"props":2932,"children":2933},{"class":222,"line":232},[2934],{"type":40,"tag":220,"props":2935,"children":2936},{},[2937],{"type":46,"value":2938},"operand.num_segments     # how many segments\n",{"type":40,"tag":220,"props":2940,"children":2941},{"class":222,"line":241},[2942],{"type":40,"tag":220,"props":2943,"children":2944},{},[2945],{"type":46,"value":2946},"operand.segments         # tuple of shape tuples, e.g., ((3, 4), (1, 2))\n",{"type":40,"tag":220,"props":2948,"children":2949},{"class":222,"line":250},[2950],{"type":40,"tag":220,"props":2951,"children":2952},{},[2953],{"type":46,"value":2954},"operand.size             # total flattened size (sum of products of segment shapes)\n",{"type":40,"tag":220,"props":2956,"children":2957},{"class":222,"line":259},[2958],{"type":40,"tag":220,"props":2959,"children":2960},{},[2961],{"type":46,"value":2962},"operand.ndim             # number of dimensions per segment\n",{"type":40,"tag":220,"props":2964,"children":2965},{"class":222,"line":268},[2966],{"type":40,"tag":220,"props":2967,"children":2968},{},[2969],{"type":46,"value":2970},"operand.all_same_segment_shape()  # True if all segments have identical shape\n",{"type":40,"tag":220,"props":2972,"children":2973},{"class":222,"line":277},[2974],{"type":40,"tag":220,"props":2975,"children":2976},{},[2977],{"type":46,"value":2978},"operand.segment_shape    # the common shape (only if all_same_segment_shape)\n",{"type":40,"tag":49,"props":2980,"children":2982},{"id":2981},"custom-equivariant-polynomial-from-scratch",[2983],{"type":46,"value":2984},"Custom equivariant polynomial from scratch",{"type":40,"tag":209,"props":2986,"children":2988},{"className":211,"code":2987,"language":213,"meta":214,"style":214},"import numpy as np\nimport cuequivariance as cue\n\n# Build a fully-connected SO3(1)xSO3(1)->SO3(0) tensor product manually\ncg = cue.clebsch_gordan(cue.SO3(1), cue.SO3(1), cue.SO3(0))  # shape (1, 3, 3, 1)\n\nd = cue.SegmentedTensorProduct.from_subscripts(\"uvw,iu,jv,kw+ijk\")\nd.add_segment(1, (3, 4))   # input1: 4x SO3(1), shape=(ir_dim, mul)\nd.add_segment(2, (3, 4))   # input2: 4x SO3(1)\nd.add_segment(3, (1, 16))  # output: 16x SO3(0) (4*4 fully connected)\n\nfor c in cg:\n    d.add_path((4, 4, 16), 0, 0, 0, c=c)\n\nd = d.normalize_paths_for_operand(-1)\n\npoly = cue.SegmentedPolynomial.eval_last_operand(d)\nep = cue.EquivariantPolynomial(\n    [\n        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\").new_scalars(d.operands[0].size), cue.ir_mul),\n        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\"), cue.ir_mul),\n        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\"), cue.ir_mul),\n    ],\n    [cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"16x0\"), cue.ir_mul)],\n    poly,\n)\n\n# Numpy evaluation\nw = np.random.randn(ep.inputs[0].dim)\nx = np.random.randn(ep.inputs[1].dim)\ny = np.random.randn(ep.inputs[2].dim)\n[out] = ep(w, x, y)\n",[2989],{"type":40,"tag":60,"props":2990,"children":2991},{"__ignoreMap":214},[2992,2999,3006,3013,3021,3029,3036,3043,3051,3059,3067,3074,3082,3090,3097,3105,3112,3120,3128,3136,3144,3152,3159,3167,3175,3183,3190,3197,3204,3212,3220,3228],{"type":40,"tag":220,"props":2993,"children":2994},{"class":222,"line":223},[2995],{"type":40,"tag":220,"props":2996,"children":2997},{},[2998],{"type":46,"value":265},{"type":40,"tag":220,"props":3000,"children":3001},{"class":222,"line":232},[3002],{"type":40,"tag":220,"props":3003,"children":3004},{},[3005],{"type":46,"value":274},{"type":40,"tag":220,"props":3007,"children":3008},{"class":222,"line":241},[3009],{"type":40,"tag":220,"props":3010,"children":3011},{"emptyLinePlaceholder":281},[3012],{"type":46,"value":284},{"type":40,"tag":220,"props":3014,"children":3015},{"class":222,"line":250},[3016],{"type":40,"tag":220,"props":3017,"children":3018},{},[3019],{"type":46,"value":3020},"# Build a fully-connected SO3(1)xSO3(1)->SO3(0) tensor product manually\n",{"type":40,"tag":220,"props":3022,"children":3023},{"class":222,"line":259},[3024],{"type":40,"tag":220,"props":3025,"children":3026},{},[3027],{"type":46,"value":3028},"cg = cue.clebsch_gordan(cue.SO3(1), cue.SO3(1), cue.SO3(0))  # shape (1, 3, 3, 1)\n",{"type":40,"tag":220,"props":3030,"children":3031},{"class":222,"line":268},[3032],{"type":40,"tag":220,"props":3033,"children":3034},{"emptyLinePlaceholder":281},[3035],{"type":46,"value":284},{"type":40,"tag":220,"props":3037,"children":3038},{"class":222,"line":277},[3039],{"type":40,"tag":220,"props":3040,"children":3041},{},[3042],{"type":46,"value":1761},{"type":40,"tag":220,"props":3044,"children":3045},{"class":222,"line":287},[3046],{"type":40,"tag":220,"props":3047,"children":3048},{},[3049],{"type":46,"value":3050},"d.add_segment(1, (3, 4))   # input1: 4x SO3(1), shape=(ir_dim, mul)\n",{"type":40,"tag":220,"props":3052,"children":3053},{"class":222,"line":296},[3054],{"type":40,"tag":220,"props":3055,"children":3056},{},[3057],{"type":46,"value":3058},"d.add_segment(2, (3, 4))   # input2: 4x SO3(1)\n",{"type":40,"tag":220,"props":3060,"children":3061},{"class":222,"line":305},[3062],{"type":40,"tag":220,"props":3063,"children":3064},{},[3065],{"type":46,"value":3066},"d.add_segment(3, (1, 16))  # output: 16x SO3(0) (4*4 fully connected)\n",{"type":40,"tag":220,"props":3068,"children":3069},{"class":222,"line":314},[3070],{"type":40,"tag":220,"props":3071,"children":3072},{"emptyLinePlaceholder":281},[3073],{"type":46,"value":284},{"type":40,"tag":220,"props":3075,"children":3076},{"class":222,"line":322},[3077],{"type":40,"tag":220,"props":3078,"children":3079},{},[3080],{"type":46,"value":3081},"for c in cg:\n",{"type":40,"tag":220,"props":3083,"children":3084},{"class":222,"line":331},[3085],{"type":40,"tag":220,"props":3086,"children":3087},{},[3088],{"type":46,"value":3089},"    d.add_path((4, 4, 16), 0, 0, 0, c=c)\n",{"type":40,"tag":220,"props":3091,"children":3092},{"class":222,"line":339},[3093],{"type":40,"tag":220,"props":3094,"children":3095},{"emptyLinePlaceholder":281},[3096],{"type":46,"value":284},{"type":40,"tag":220,"props":3098,"children":3099},{"class":222,"line":348},[3100],{"type":40,"tag":220,"props":3101,"children":3102},{},[3103],{"type":46,"value":3104},"d = d.normalize_paths_for_operand(-1)\n",{"type":40,"tag":220,"props":3106,"children":3107},{"class":222,"line":357},[3108],{"type":40,"tag":220,"props":3109,"children":3110},{"emptyLinePlaceholder":281},[3111],{"type":46,"value":284},{"type":40,"tag":220,"props":3113,"children":3114},{"class":222,"line":366},[3115],{"type":40,"tag":220,"props":3116,"children":3117},{},[3118],{"type":46,"value":3119},"poly = cue.SegmentedPolynomial.eval_last_operand(d)\n",{"type":40,"tag":220,"props":3121,"children":3122},{"class":222,"line":375},[3123],{"type":40,"tag":220,"props":3124,"children":3125},{},[3126],{"type":46,"value":3127},"ep = cue.EquivariantPolynomial(\n",{"type":40,"tag":220,"props":3129,"children":3130},{"class":222,"line":383},[3131],{"type":40,"tag":220,"props":3132,"children":3133},{},[3134],{"type":46,"value":3135},"    [\n",{"type":40,"tag":220,"props":3137,"children":3138},{"class":222,"line":391},[3139],{"type":40,"tag":220,"props":3140,"children":3141},{},[3142],{"type":46,"value":3143},"        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\").new_scalars(d.operands[0].size), cue.ir_mul),\n",{"type":40,"tag":220,"props":3145,"children":3146},{"class":222,"line":400},[3147],{"type":40,"tag":220,"props":3148,"children":3149},{},[3150],{"type":46,"value":3151},"        cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"4x1\"), cue.ir_mul),\n",{"type":40,"tag":220,"props":3153,"children":3154},{"class":222,"line":409},[3155],{"type":40,"tag":220,"props":3156,"children":3157},{},[3158],{"type":46,"value":3151},{"type":40,"tag":220,"props":3160,"children":3161},{"class":222,"line":417},[3162],{"type":40,"tag":220,"props":3163,"children":3164},{},[3165],{"type":46,"value":3166},"    ],\n",{"type":40,"tag":220,"props":3168,"children":3169},{"class":222,"line":426},[3170],{"type":40,"tag":220,"props":3171,"children":3172},{},[3173],{"type":46,"value":3174},"    [cue.IrrepsAndLayout(cue.Irreps(\"SO3\", \"16x0\"), cue.ir_mul)],\n",{"type":40,"tag":220,"props":3176,"children":3177},{"class":222,"line":435},[3178],{"type":40,"tag":220,"props":3179,"children":3180},{},[3181],{"type":46,"value":3182},"    poly,\n",{"type":40,"tag":220,"props":3184,"children":3185},{"class":222,"line":443},[3186],{"type":40,"tag":220,"props":3187,"children":3188},{},[3189],{"type":46,"value":1903},{"type":40,"tag":220,"props":3191,"children":3192},{"class":222,"line":452},[3193],{"type":40,"tag":220,"props":3194,"children":3195},{"emptyLinePlaceholder":281},[3196],{"type":46,"value":284},{"type":40,"tag":220,"props":3198,"children":3199},{"class":222,"line":461},[3200],{"type":40,"tag":220,"props":3201,"children":3202},{},[3203],{"type":46,"value":2699},{"type":40,"tag":220,"props":3205,"children":3206},{"class":222,"line":470},[3207],{"type":40,"tag":220,"props":3208,"children":3209},{},[3210],{"type":46,"value":3211},"w = np.random.randn(ep.inputs[0].dim)\n",{"type":40,"tag":220,"props":3213,"children":3214},{"class":222,"line":478},[3215],{"type":40,"tag":220,"props":3216,"children":3217},{},[3218],{"type":46,"value":3219},"x = np.random.randn(ep.inputs[1].dim)\n",{"type":40,"tag":220,"props":3221,"children":3222},{"class":222,"line":486},[3223],{"type":40,"tag":220,"props":3224,"children":3225},{},[3226],{"type":46,"value":3227},"y = np.random.randn(ep.inputs[2].dim)\n",{"type":40,"tag":220,"props":3229,"children":3230},{"class":222,"line":495},[3231],{"type":40,"tag":220,"props":3232,"children":3233},{},[3234],{"type":46,"value":3235},"[out] = ep(w, x, y)\n",{"type":40,"tag":49,"props":3237,"children":3239},{"id":3238},"key-file-locations",[3240],{"type":46,"value":3241},"Key file locations",{"type":40,"tag":832,"props":3243,"children":3244},{},[3245,3260],{"type":40,"tag":836,"props":3246,"children":3247},{},[3248],{"type":40,"tag":840,"props":3249,"children":3250},{},[3251,3256],{"type":40,"tag":844,"props":3252,"children":3253},{},[3254],{"type":46,"value":3255},"Component",{"type":40,"tag":844,"props":3257,"children":3258},{},[3259],{"type":46,"value":129},{"type":40,"tag":860,"props":3261,"children":3262},{},[3263,3285,3306,3327,3348,3369,3389,3409,3429,3449,3469,3489,3509,3525,3542,3563],{"type":40,"tag":840,"props":3264,"children":3265},{},[3266,3276],{"type":40,"tag":867,"props":3267,"children":3268},{},[3269,3274],{"type":40,"tag":60,"props":3270,"children":3272},{"className":3271},[],[3273],{"type":46,"value":96},{"type":46,"value":3275}," base class",{"type":40,"tag":867,"props":3277,"children":3278},{},[3279],{"type":40,"tag":60,"props":3280,"children":3282},{"className":3281},[],[3283],{"type":46,"value":3284},"cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep.py",{"type":40,"tag":840,"props":3286,"children":3287},{},[3288,3297],{"type":40,"tag":867,"props":3289,"children":3290},{},[3291,3296],{"type":40,"tag":60,"props":3292,"children":3294},{"className":3293},[],[3295],{"type":46,"value":1464},{"type":46,"value":3275},{"type":40,"tag":867,"props":3298,"children":3299},{},[3300],{"type":40,"tag":60,"props":3301,"children":3303},{"className":3302},[],[3304],{"type":46,"value":3305},"cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Frep.py",{"type":40,"tag":840,"props":3307,"children":3308},{},[3309,3318],{"type":40,"tag":867,"props":3310,"children":3311},{},[3312],{"type":40,"tag":60,"props":3313,"children":3315},{"className":3314},[],[3316],{"type":46,"value":3317},"SO3",{"type":40,"tag":867,"props":3319,"children":3320},{},[3321],{"type":40,"tag":60,"props":3322,"children":3324},{"className":3323},[],[3325],{"type":46,"value":3326},"cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep_so3.py",{"type":40,"tag":840,"props":3328,"children":3329},{},[3330,3339],{"type":40,"tag":867,"props":3331,"children":3332},{},[3333],{"type":40,"tag":60,"props":3334,"children":3336},{"className":3335},[],[3337],{"type":46,"value":3338},"O3",{"type":40,"tag":867,"props":3340,"children":3341},{},[3342],{"type":40,"tag":60,"props":3343,"children":3345},{"className":3344},[],[3346],{"type":46,"value":3347},"cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep_o3.py",{"type":40,"tag":840,"props":3349,"children":3350},{},[3351,3360],{"type":40,"tag":867,"props":3352,"children":3353},{},[3354],{"type":40,"tag":60,"props":3355,"children":3357},{"className":3356},[],[3358],{"type":46,"value":3359},"SU2",{"type":40,"tag":867,"props":3361,"children":3362},{},[3363],{"type":40,"tag":60,"props":3364,"children":3366},{"className":3365},[],[3367],{"type":46,"value":3368},"cuequivariance\u002Fgroup_theory\u002Frepresentations\u002Firrep_su2.py",{"type":40,"tag":840,"props":3370,"children":3371},{},[3372,3380],{"type":40,"tag":867,"props":3373,"children":3374},{},[3375],{"type":40,"tag":60,"props":3376,"children":3378},{"className":3377},[],[3379],{"type":46,"value":104},{"type":40,"tag":867,"props":3381,"children":3382},{},[3383],{"type":40,"tag":60,"props":3384,"children":3386},{"className":3385},[],[3387],{"type":46,"value":3388},"cuequivariance\u002Fgroup_theory\u002Firreps_array\u002Firreps.py",{"type":40,"tag":840,"props":3390,"children":3391},{},[3392,3400],{"type":40,"tag":867,"props":3393,"children":3394},{},[3395],{"type":40,"tag":60,"props":3396,"children":3398},{"className":3397},[],[3399],{"type":46,"value":1382},{"type":40,"tag":867,"props":3401,"children":3402},{},[3403],{"type":40,"tag":60,"props":3404,"children":3406},{"className":3405},[],[3407],{"type":46,"value":3408},"cuequivariance\u002Fgroup_theory\u002Firreps_array\u002Firreps_layout.py",{"type":40,"tag":840,"props":3410,"children":3411},{},[3412,3420],{"type":40,"tag":867,"props":3413,"children":3414},{},[3415],{"type":40,"tag":60,"props":3416,"children":3418},{"className":3417},[],[3419],{"type":46,"value":160},{"type":40,"tag":867,"props":3421,"children":3422},{},[3423],{"type":40,"tag":60,"props":3424,"children":3426},{"className":3425},[],[3427],{"type":46,"value":3428},"cuequivariance\u002Fgroup_theory\u002Firreps_array\u002Firreps_and_layout.py",{"type":40,"tag":840,"props":3430,"children":3431},{},[3432,3440],{"type":40,"tag":867,"props":3433,"children":3434},{},[3435],{"type":40,"tag":60,"props":3436,"children":3438},{"className":3437},[],[3439],{"type":46,"value":121},{"type":40,"tag":867,"props":3441,"children":3442},{},[3443],{"type":40,"tag":60,"props":3444,"children":3446},{"className":3445},[],[3447],{"type":46,"value":3448},"cuequivariance\u002Fsegmented_polynomials\u002Fsegmented_tensor_product.py",{"type":40,"tag":840,"props":3450,"children":3451},{},[3452,3460],{"type":40,"tag":867,"props":3453,"children":3454},{},[3455],{"type":40,"tag":60,"props":3456,"children":3458},{"className":3457},[],[3459],{"type":46,"value":137},{"type":40,"tag":867,"props":3461,"children":3462},{},[3463],{"type":40,"tag":60,"props":3464,"children":3466},{"className":3465},[],[3467],{"type":46,"value":3468},"cuequivariance\u002Fsegmented_polynomials\u002Fsegmented_polynomial.py",{"type":40,"tag":840,"props":3470,"children":3471},{},[3472,3480],{"type":40,"tag":867,"props":3473,"children":3474},{},[3475],{"type":40,"tag":60,"props":3476,"children":3478},{"className":3477},[],[3479],{"type":46,"value":152},{"type":40,"tag":867,"props":3481,"children":3482},{},[3483],{"type":40,"tag":60,"props":3484,"children":3486},{"className":3485},[],[3487],{"type":46,"value":3488},"cuequivariance\u002Fgroup_theory\u002Fequivariant_polynomial.py",{"type":40,"tag":840,"props":3490,"children":3491},{},[3492,3500],{"type":40,"tag":867,"props":3493,"children":3494},{},[3495],{"type":40,"tag":60,"props":3496,"children":3498},{"className":3497},[],[3499],{"type":46,"value":171},{"type":40,"tag":867,"props":3501,"children":3502},{},[3503],{"type":40,"tag":60,"props":3504,"children":3506},{"className":3505},[],[3507],{"type":46,"value":3508},"cuequivariance\u002Fgroup_theory\u002Fir_dict_polynomial.py",{"type":40,"tag":840,"props":3510,"children":3511},{},[3512,3516],{"type":40,"tag":867,"props":3513,"children":3514},{},[3515],{"type":46,"value":1799},{"type":40,"tag":867,"props":3517,"children":3518},{},[3519],{"type":40,"tag":60,"props":3520,"children":3522},{"className":3521},[],[3523],{"type":46,"value":3524},"cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002F",{"type":40,"tag":840,"props":3526,"children":3527},{},[3528,3533],{"type":40,"tag":867,"props":3529,"children":3530},{},[3531],{"type":46,"value":3532},"Tensor product descriptors",{"type":40,"tag":867,"props":3534,"children":3535},{},[3536],{"type":40,"tag":60,"props":3537,"children":3539},{"className":3538},[],[3540],{"type":46,"value":3541},"cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002Firreps_tp.py",{"type":40,"tag":840,"props":3543,"children":3544},{},[3545,3554],{"type":40,"tag":867,"props":3546,"children":3547},{},[3548],{"type":40,"tag":60,"props":3549,"children":3551},{"className":3550},[],[3552],{"type":46,"value":3553},"spherical_harmonics",{"type":40,"tag":867,"props":3555,"children":3556},{},[3557],{"type":40,"tag":60,"props":3558,"children":3560},{"className":3559},[],[3561],{"type":46,"value":3562},"cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002Fspherical_harmonics_.py",{"type":40,"tag":840,"props":3564,"children":3565},{},[3566,3575],{"type":40,"tag":867,"props":3567,"children":3568},{},[3569],{"type":40,"tag":60,"props":3570,"children":3572},{"className":3571},[],[3573],{"type":46,"value":3574},"symmetric_contraction",{"type":40,"tag":867,"props":3576,"children":3577},{},[3578],{"type":40,"tag":60,"props":3579,"children":3581},{"className":3580},[],[3582],{"type":46,"value":3583},"cuequivariance\u002Fgroup_theory\u002Fdescriptors\u002Fsymmetric_contractions.py",{"type":40,"tag":3585,"props":3586,"children":3587},"style",{},[3588],{"type":46,"value":3589},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3591,"total":241},[3592,3599,3611],{"slug":4,"name":4,"fn":5,"description":6,"org":3593,"tags":3594,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3595,3596,3597,3598],{"name":13,"slug":14,"type":15},{"name":21,"slug":22,"type":15},{"name":17,"slug":18,"type":15},{"name":9,"slug":8,"type":15},{"slug":3600,"name":3600,"fn":3601,"description":3602,"org":3603,"tags":3604,"stars":23,"repoUrl":24,"updatedAt":3610},"cuequivariance-jax","execute equivariant polynomials in JAX","Execute equivariant polynomials in JAX using segmented_polynomial (naive\u002Funiform_1d), the ir_dict workflow with IrDictPolynomial and dict[Irrep, Array], and Flax NNX layers (IrrepsLinear, SphericalHarmonics, IrrepsIndexedLinear). Use when writing JAX code with cuequivariance.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3605,3606,3607,3608],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":9,"slug":8,"type":15},{"name":3609,"slug":213,"type":15},"Python","2026-07-14T05:34:29.712307",{"slug":3612,"name":3612,"fn":3613,"description":3614,"org":3615,"tags":3616,"stars":23,"repoUrl":24,"updatedAt":3626},"cuequivariance-torch","execute equivariant tensor products in PyTorch","Execute equivariant tensor products in PyTorch using SegmentedPolynomial (naive\u002Funiform_1d\u002Ffused_tp\u002Findexed_linear), high-level operations (ChannelWiseTensorProduct, FullyConnectedTensorProduct, Linear, SymmetricContraction, SphericalHarmonics, Rotation), and layers (BatchNorm, FullyConnectedTensorProductConv). Use when writing PyTorch code with cuequivariance.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3617,3618,3619,3620,3623],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":9,"slug":8,"type":15},{"name":3621,"slug":3622,"type":15},"Physics","physics",{"name":3624,"slug":3625,"type":15},"PyTorch","pytorch","2026-07-23T05:43:52.496117",{"items":3628,"total":3785},[3629,3647,3663,3674,3686,3700,3713,3727,3740,3751,3765,3774],{"slug":3630,"name":3630,"fn":3631,"description":3632,"org":3633,"tags":3634,"stars":3644,"repoUrl":3645,"updatedAt":3646},"nemoclaw-user-guide","retrieve NemoClaw documentation and configuration","Guides human users' AI agents to the NemoClaw docs MCP server and canonical Fern documentation in Markdown form. Use when users ask how to install, configure, operate, troubleshoot, secure, or learn NemoClaw with an AI coding assistant. Trigger keywords - nemoclaw docs, use nemoclaw with ai agent, nemoclaw mcp docs, nemoclaw install help, nemoclaw quickstart, nemoclaw markdown docs, llms.txt, agent skills.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3635,3638,3641],{"name":3636,"slug":3637,"type":15},"Documentation","documentation",{"name":3639,"slug":3640,"type":15},"MCP","mcp",{"name":3642,"slug":3643,"type":15},"Search","search",21777,"https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FNemoClaw","2026-07-20T06:00:01.461044",{"slug":3648,"name":3648,"fn":3649,"description":3650,"org":3651,"tags":3652,"stars":3660,"repoUrl":3661,"updatedAt":3662},"mcore-build-and-dependency","manage Megatron-LM development environments","Container-based dev environment setup and dependency management for Megatron-LM. Covers acquiring and launching the CI container, uv package management, and updating uv.lock.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3653,3656,3659],{"name":3654,"slug":3655,"type":15},"Containers","containers",{"name":3657,"slug":3658,"type":15},"Deployment","deployment",{"name":3609,"slug":213,"type":15},17049,"https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FMegatron-LM","2026-07-27T06:06:11.249662",{"slug":3664,"name":3664,"fn":3665,"description":3666,"org":3667,"tags":3668,"stars":3660,"repoUrl":3661,"updatedAt":3673},"mcore-bump-base-image","update NVIDIA PyTorch base images","Bump the NVIDIA PyTorch base image (`nvcr.io\u002Fnvidia\u002Fpytorch:YY.MM-py3`) used by Megatron-LM CI. Covers the two pin sites (GitHub CI in `docker\u002F.ngc_version.dev` and GitLab CI in `.gitlab\u002Fstages\u002F01.build.yml`), the post-bump CI loop (re-run functional tests, refresh golden values, mark broken tests), and the gotchas that bit PRs",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3669,3672],{"name":3670,"slug":3671,"type":15},"CI\u002FCD","ci-cd",{"name":3657,"slug":3658,"type":15},"2026-07-14T05:25:59.97109",{"slug":3675,"name":3675,"fn":3676,"description":3677,"org":3678,"tags":3679,"stars":3660,"repoUrl":3661,"updatedAt":3685},"mcore-cicd","manage CI\u002FCD pipelines for Megatron-LM","CI\u002FCD reference for Megatron-LM. Covers CI pipeline structure, PR scope labels, triggering internal GitLab CI (which force-pushes the current branch to a pull-request\u002FBRANCH ref — always dry-run and verify the destination first; never run against shared or protected branches), and CI failure investigation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3680,3681,3682],{"name":3670,"slug":3671,"type":15},{"name":3657,"slug":3658,"type":15},{"name":3683,"slug":3684,"type":15},"GitHub","github","2026-07-27T06:06:12.278222",{"slug":3687,"name":3687,"fn":3688,"description":3689,"org":3690,"tags":3691,"stars":3660,"repoUrl":3661,"updatedAt":3699},"mcore-create-issue","investigate CI failures and create issues","Investigate a failing GitHub Actions run or job and create a GitHub issue for the failure.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3692,3695,3696],{"name":3693,"slug":3694,"type":15},"Debugging","debugging",{"name":3683,"slug":3684,"type":15},{"name":3697,"slug":3698,"type":15},"Triage","triage","2026-07-14T05:25:57.442089",{"slug":3701,"name":3701,"fn":3702,"description":3703,"org":3704,"tags":3705,"stars":3660,"repoUrl":3661,"updatedAt":3712},"mcore-linting-and-formatting","lint and format Megatron-LM code","Linting and formatting for Megatron-LM. Covers running autoformat.sh, tools (ruff, black, isort, pylint, mypy), and code style rules.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3706,3709],{"name":3707,"slug":3708,"type":15},"Best Practices","best-practices",{"name":3710,"slug":3711,"type":15},"Code Analysis","code-analysis","2026-07-14T05:25:56.18433",{"slug":3714,"name":3714,"fn":3715,"description":3716,"org":3717,"tags":3718,"stars":3660,"repoUrl":3661,"updatedAt":3726},"mcore-migrate-gpt-to-hybrid","migrate Megatron-LM models to HybridModel","Migration guide for moving Megatron Core GPTModel checkpoints, model providers, training commands, and layer mappings to HybridModel.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3719,3722,3725],{"name":3720,"slug":3721,"type":15},"Machine Learning","machine-learning",{"name":3723,"slug":3724,"type":15},"Migration","migration",{"name":9,"slug":8,"type":15},"2026-07-17T06:07:11.777011",{"slug":3728,"name":3728,"fn":3729,"description":3730,"org":3731,"tags":3732,"stars":3660,"repoUrl":3661,"updatedAt":3739},"mcore-onboard-gb200-1node-tests","onboard functional tests for GB200","Onboard 1-node GitHub MR functional tests for GB200 from existing mr-scoped 2-node tests.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3733,3736],{"name":3734,"slug":3735,"type":15},"QA","qa",{"name":3737,"slug":3738,"type":15},"Testing","testing","2026-07-14T05:25:53.673039",{"slug":3741,"name":3741,"fn":3742,"description":3743,"org":3744,"tags":3745,"stars":3660,"repoUrl":3661,"updatedAt":3750},"mcore-run-on-slurm","launch distributed training jobs on SLURM","How to launch distributed Megatron-LM training jobs on a SLURM cluster. Covers a minimal sbatch skeleton, environment-variable setup for torch.distributed.run, CUDA_DEVICE_MAX_CONNECTIONS rules across hardware and parallelism modes, container conventions, monitoring, and per-rank failure diagnosis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3746,3747],{"name":3657,"slug":3658,"type":15},{"name":3748,"slug":3749,"type":15},"Infrastructure","infrastructure","2026-07-14T05:25:49.362534",{"slug":3752,"name":3752,"fn":3753,"description":3754,"org":3755,"tags":3756,"stars":3660,"repoUrl":3661,"updatedAt":3764},"mcore-split-pr","split pull requests to reduce review load","Split a PR into multiple PRs to reduce the number of required CODEOWNERS reviewer groups.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3757,3760,3761],{"name":3758,"slug":3759,"type":15},"Code Review","code-review",{"name":3683,"slug":3684,"type":15},{"name":3762,"slug":3763,"type":15},"Pull Requests","pull-requests","2026-07-14T05:26:01.226578",{"slug":3766,"name":3766,"fn":3767,"description":3768,"org":3769,"tags":3770,"stars":3660,"repoUrl":3661,"updatedAt":3773},"mcore-testing","run and manage Megatron-LM tests","Test system for Megatron-LM. Covers test layout, recipe YAML structure, adding and running unit and functional tests, golden values, marker filters, and CI parity.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3771,3772],{"name":3734,"slug":3735,"type":15},{"name":3737,"slug":3738,"type":15},"2026-07-14T05:25:54.928983",{"slug":3775,"name":3775,"fn":3776,"description":3777,"org":3778,"tags":3779,"stars":3660,"repoUrl":3661,"updatedAt":3784},"nightly-sync","manage nightly main-to-dev sync workflows","Domain knowledge for the nightly main-to-dev sync workflow. Covers merge strategy, CI architecture, failure investigation, and known issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3780,3783],{"name":3781,"slug":3782,"type":15},"Automation","automation",{"name":3670,"slug":3671,"type":15},"2026-07-30T05:29:03.275638",496]