Skip to content

terms

Term-family modules for compiled scalar graphs.

Each compiled ZX scalar is the product of four term families plus a global phase and a floatfactor. This module defines the four families as equinox.Module records, bundles the shared phase tables, and gives each family an evaluate method that turns a batch of binary parameter values into an ExactScalarArray.

Downstream, compile.py builds instances of these classes from pyzx_param scalars, and evaluate.py orchestrates the products.

HalfPiPhases

Bases: Module


              flowchart TD
              tsim.compile.terms.HalfPiPhases[HalfPiPhases]

              

              click tsim.compile.terms.HalfPiPhases href "" "tsim.compile.terms.HalfPiPhases"
            

Sum of exp(i·j·π·⊕params / 2) terms with j ∈ {1, 3}.

Terms sharing a parameter bitstring have been combined to a single stored coefficient j' ∈ {1, 2, 3} (see _compile_halfpi_phases). Coefficients are stored in eighth-turn units — i.e. as 2·j' — so the evaluator can reuse the ω = e^(iπ/4) phase table.

Padded slots use 0 (the additive identity for phase sums), so padded entries contribute nothing to the summed exponent.

Shapes are (num_graphs, max_terms) except params which is (num_graphs, max_terms, n_params).

evaluate

evaluate(param_vals: Array) -> ExactScalarArray

Evaluate ω^(Σ coeffs · parity) per graph, batched over param_vals.

Parameters:

Name Type Description Default
param_vals Array

Binary parameter values, shape (batch, n_params).

required

Returns:

Type Description
ExactScalarArray

ExactScalarArray of shape (batch, num_graphs).

Source code in src/tsim/compile/terms.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def evaluate(self, param_vals: Array) -> ExactScalarArray:
    """Evaluate ω^(Σ coeffs · parity) per graph, batched over param_vals.

    Args:
        param_vals: Binary parameter values, shape ``(batch, n_params)``.

    Returns:
        ``ExactScalarArray`` of shape ``(batch, num_graphs)``.

    """
    rowsum = matmul_gf2(self.params, param_vals)
    phase_idx = (rowsum * self.coeffs) % 8
    total_phase = jnp.sum(phase_idx, axis=-1) % 8
    return ExactScalarArray(UNIT_PHASES[total_phase])

NodePhases

Bases: Module


              flowchart TD
              tsim.compile.terms.NodePhases[NodePhases]

              

              click tsim.compile.terms.NodePhases href "" "tsim.compile.terms.NodePhases"
            

Product of 1 + exp(i·(α + ⊕params)·π) terms, one factor per stored term.

Padded slots use 0 for both phases and params; the evaluator masks padded slots to the multiplicative identity using counts.

Shapes are (num_graphs, max_terms) except params which is (num_graphs, max_terms, n_params).

evaluate

evaluate(param_vals: Array) -> ExactScalarArray

Evaluate Π (1 + ω^(4·parity + phase)) per graph, batched over param_vals.

Parameters:

Name Type Description Default
param_vals Array

Binary parameter values, shape (batch, n_params).

required

Returns:

Type Description
ExactScalarArray

ExactScalarArray of shape (batch, num_graphs).

Source code in src/tsim/compile/terms.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def evaluate(self, param_vals: Array) -> ExactScalarArray:
    """Evaluate Π (1 + ω^(4·parity + phase)) per graph, batched over param_vals.

    Args:
        param_vals: Binary parameter values, shape ``(batch, n_params)``.

    Returns:
        ``ExactScalarArray`` of shape ``(batch, num_graphs)``.

    """
    rowsum = matmul_gf2(self.params, param_vals)
    phase_idx = (4 * rowsum + self.phases) % 8

    term_vals = _ONE_PLUS_PHASES[phase_idx]
    mask = jnp.arange(self.phases.shape[1])[None, :] < self.counts[:, None]
    term_vals = jnp.where(mask[..., None], term_vals, _IDENTITY)

    return ExactScalarArray(term_vals).prod(axis=-1)

PhasePairs

Bases: Module


              flowchart TD
              tsim.compile.terms.PhasePairs[PhasePairs]

              

              click tsim.compile.terms.PhasePairs href "" "tsim.compile.terms.PhasePairs"
            

Product of 1 + e^(iα) + e^(iβ) − e^(i(α+β)) terms.

Each of α and β combines a constant phase with a parameter parity. Padded slots use 0 and are masked to the multiplicative identity using counts.

Shapes are (num_graphs, max_terms) except *_params which are (num_graphs, max_terms, n_params).

evaluate

evaluate(param_vals: Array) -> ExactScalarArray

Evaluate Π (1 + ω^α + ω^β - ω^(α+β)) per graph, batched.

Parameters:

Name Type Description Default
param_vals Array

Binary parameter values, shape (batch, n_params).

required

Returns:

Type Description
ExactScalarArray

ExactScalarArray of shape (batch, num_graphs).

Source code in src/tsim/compile/terms.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
def evaluate(self, param_vals: Array) -> ExactScalarArray:
    """Evaluate Π (1 + ω^α + ω^β - ω^(α+β)) per graph, batched.

    Args:
        param_vals: Binary parameter values, shape ``(batch, n_params)``.

    Returns:
        ``ExactScalarArray`` of shape ``(batch, num_graphs)``.

    """
    rowsum_a = matmul_gf2(self.alpha_params, param_vals)
    rowsum_b = matmul_gf2(self.beta_params, param_vals)

    alpha = (self.alpha + rowsum_a * 4) % 8
    beta = (self.beta + rowsum_b * 4) % 8
    gamma = (alpha + beta) % 8

    term_vals = (
        _IDENTITY + UNIT_PHASES[alpha] + UNIT_PHASES[beta] - UNIT_PHASES[gamma]
    )
    mask = jnp.arange(self.alpha.shape[1])[None, :] < self.counts[:, None]
    term_vals = jnp.where(mask[..., None], term_vals, _IDENTITY)

    return ExactScalarArray(term_vals).prod(axis=-1)

PiProducts

Bases: Module


              flowchart TD
              tsim.compile.terms.PiProducts[PiProducts]

              

              click tsim.compile.terms.PiProducts href "" "tsim.compile.terms.PiProducts"
            

Product of (-1)^(ψ · φ) terms, with ψ and φ each a parity expression.

Each side is encoded as a constant bit plus a parameter bitmask. Padded slots use 0 everywhere; a padded term contributes (-1)^0 = 1 to the product.

Shapes are (num_graphs, max_terms) except *_params which are (num_graphs, max_terms, n_params).

evaluate

evaluate(param_vals: Array) -> ExactScalarArray

Evaluate Π (-1)^(ψ·φ) per graph as a real ±1 exact scalar.

Parameters:

Name Type Description Default
param_vals Array

Binary parameter values, shape (batch, n_params).

required

Returns:

Type Description
ExactScalarArray

ExactScalarArray of shape (batch, num_graphs), with values

ExactScalarArray

in {+1, -1} represented exactly.

Source code in src/tsim/compile/terms.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def evaluate(self, param_vals: Array) -> ExactScalarArray:
    """Evaluate Π (-1)^(ψ·φ) per graph as a real ±1 exact scalar.

    Args:
        param_vals: Binary parameter values, shape ``(batch, n_params)``.

    Returns:
        ``ExactScalarArray`` of shape ``(batch, num_graphs)``, with values
        in {+1, -1} represented exactly.

    """
    psi = (self.psi_const + matmul_gf2(self.psi_params, param_vals)) % 2
    phi = (self.phi_const + matmul_gf2(self.phi_params, param_vals)) % 2

    exponent = (psi * phi) % 2
    sum_exponents = jnp.sum(exponent, axis=-1) % 2

    # (1 - 2·bit) ∈ {+1, -1}; promote to the 4-coefficient ExactScalar basis.
    summands_exact = (1 - 2 * sum_exponents)[..., None] * _IDENTITY
    return ExactScalarArray(summands_exact)

ScalarPrefactor

Bases: Module


              flowchart TD
              tsim.compile.terms.ScalarPrefactor[ScalarPrefactor]

              

              click tsim.compile.terms.ScalarPrefactor href "" "tsim.compile.terms.ScalarPrefactor"
            

Per-graph static scalar prefactor — independent of parameter values.

Each graph's amplitude is the product of the four term families times the prefactor ω^phase_index · floatfactor · 2^power2, with an additional complex approximate_floatfactor multiplied in when any graph's phase had a denominator outside {1, 2, 4} and was folded into float form.

This class is pure data; the final fold-in with the term-family product (which requires branching on has_approximate_floatfactors) lives in evaluate.py.