quchip.declarative.expr

Backend-neutral operator algebra for the declarative physics DSL.

PhysicsExpr is the expression tree LocalOps handles compose into; compile_expr() lowers a tree into a backend-native operator once endpoint labels are resolved to concrete Hilbert spaces.

Functions

compile_expr(expr, op_lookup, backend)

Compile a PhysicsExpr into a backend-native operator.

ensure_expr(value)

Coerce a scalar-like value into PhysicsExpr.

Classes

DynamicScalar(source)

A time-dependent scalar payload attached to a PhysicsExpr.

PhysicsExpr(kind[, args, labels, scalar, ...])

Backend-neutral expression tree for local physics operators.

class quchip.declarative.expr.DynamicScalar(source)[source]

Bases: object

A time-dependent scalar payload attached to a PhysicsExpr.

source is the time-dependent object (typically an envelope or a ScalarModulation) that the engine compiles into a DynamicTerm when assembling the Hamiltonian. Multiplying a DynamicScalar by a PhysicsExpr records the source on the resulting expression’s dynamic_sources tuple — the operator structure itself is unchanged.

Parameters:

source (Any)

source: Any
class quchip.declarative.expr.PhysicsExpr(kind, args=(), labels=(), scalar=1.0, dynamic_sources=())[source]

Bases: object

Backend-neutral expression tree for local physics operators.

Built by composing LocalOps operator handles, not constructed directly. Operators on the same endpoint compose with @ (matrix product); operators on different endpoints combine with * (tensor product). Scalars scale via *, and an envelope or modulation multiplied in is recorded as a dynamic source rather than altering the operator structure.

Examples

>>> from quchip.declarative import LocalOps
>>> a, b = LocalOps("q0", 3), LocalOps("q1", 3)
>>> coupling = 0.01 * (a.a * b.adag + a.adag * b.a)
>>> coupling.kind
'add'
>>> coupling.labels
('q0', 'q1')
Parameters:
kind: str
args: tuple[Any, ...] = ()
labels: tuple[str, ...] = ()
scalar: Any = 1.0
dynamic_sources: tuple[DynamicScalar, ...] = ()
without_dynamic_sources()[source]

Return the same operator expression with dynamic sources stripped.

Return type:

PhysicsExpr

has_dynamic_source()[source]

Return whether this expression carries any time-dependent source.

Return type:

bool

quchip.declarative.expr.ensure_expr(value)[source]

Coerce a scalar-like value into PhysicsExpr.

Parameters:

value (Any)

Return type:

PhysicsExpr

quchip.declarative.expr.compile_expr(expr, op_lookup, backend)[source]

Compile a PhysicsExpr into a backend-native operator.

op_lookup maps (label, operator_name) to a backend operator (e.g. a, adag, n, I for each device label). backend is the active default backend; only its tensor() method is used here. Scalar coefficients carried by every node are preserved consistently — including traced (non-concrete) scalars, which are multiplied unconditionally so gradients still flow.

Parameters:
Return type:

Any