Skip to content

Promote a plain tensor to a trivial operator - #235

Merged
mtfishman merged 1 commit into
mainfrom
mf/operator-promotion
Jul 28, 2026
Merged

Promote a plain tensor to a trivial operator#235
mtfishman merged 1 commit into
mainfrom
mf/operator-promotion

Conversation

@mtfishman

Copy link
Copy Markdown
Member

Summary

Makes a NamedTensorOperator the promotion of a plain NamedTensor by defining convert and promote_rule. A plain tensor is a trivial operator with an empty output/input pairing, so convert wraps it via operator(a, (), ()) and promote_rule picks the operator as the common type. As a result promote(state, operator) returns two operators, and a mixed collection like [state, operator] builds a homogeneous Vector{<:NamedTensorOperator} instead of falling back to the abstract typejoin.

This is what lets a downstream network mixing operators and plain tensors promote to a single concrete operand type before contraction.

Defines convert and promote_rule so a NamedTensorOperator is the promotion
of a plain NamedTensor. A mixed collection like [state, operator] now builds
a homogeneous Vector{<:NamedTensorOperator} instead of falling back to the
abstract typejoin.
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.79%. Comparing base (f867b1a) to head (fb98a03).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #235      +/-   ##
==========================================
+ Coverage   77.74%   77.79%   +0.04%     
==========================================
  Files          30       30              
  Lines        1788     1792       +4     
==========================================
+ Hits         1390     1394       +4     
  Misses        398      398              
Flag Coverage Δ
docs 26.52% <0.00%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mtfishman
mtfishman merged commit eb6bb3c into main Jul 28, 2026
18 checks passed
@mtfishman
mtfishman deleted the mf/operator-promotion branch July 28, 2026 20:05
mtfishman added a commit that referenced this pull request Jul 29, 2026
## Summary

Extends the operator promotion added in
#235 to lazy tensors, and
makes `operator` re-partition an existing operator instead of nesting.

A `LazyNamedTensor` now promotes with another lazy tensor, or with an
eager tensor, to the lazy tensor whose leaf (parent) type is the
promotion of the leaves, reusing the eager `NamedTensor` /
`NamedTensorOperator` promotion at the leaves. So a lazy plain tensor
and an operator promote to a lazy operator, and `convert` rebuilds the
lazy product with each leaf converted. This lets `contract_network`
homogenize a network that mixes lazy and eager, plain and operator
operands without materializing anything. The motivating case is a
norm-network vertex, a lazy `ket * conj(bra)` product, contracted
against operator-valued belief-propagation messages, which the
eager-only promotion could not reach. An all-eager or all-plain network
is unaffected (the promotion stays at the eager or plain type).

`operator(a, output, input)` on an existing `NamedTensorOperator` now
reassigns the pairing over the same state rather than wrapping another
operator around it, since an operator's output/input pairing is a view
over its state.

Together these let ITensorNetworksNext drop the interim `state`-unwrap
workarounds in belief propagation.
mtfishman added a commit to ITensor/ITensorNetworksNext.jl that referenced this pull request Jul 29, 2026
## Summary

`contract_network` now handles a network that mixes operator-valued
(`NamedTensorOperator`) and plain tensors, which previously threw a
`convert` `MethodError`. It promotes the operands to their common type
with `promote_type` and `convert` before lowering to the lazy
expression, so every operand shares one concrete type and the
contraction folds with `*`, routing operators through `operator_product`
and preserving the output and input pairing. Without that, a mixed
network widens the symbolic `Mul` container to a `UnionAll` that cannot
be constructed. An all-plain network is unaffected (the promotion is a
no-op).

The promotion lives in ITensorBase: eager operands via
ITensor/ITensorBase.jl#235 and lazy operands via
ITensor/ITensorBase.jl#236. With the lazy case
handled, this drops the interim `state`-unwrap workarounds in belief
propagation: `vertex_scalar` and `updated_message` contract operator
messages directly, and the `NormNetwork` `message_update!` re-partitions
the result with `operator` (the vertex factor is a lazy `ket *
conj(bra)` product, so its surviving bond legs come out unpaired and the
message's ket/bra pairing is assigned by the norm-network convention).

Also switches the `NormNetwork` tests to the package's
`contract_network` rather than a local helper of the same name that
shadowed it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant