Skip to content

Optimization with any finite domain - #109

Merged
iagoleal merged 3 commits into
mainfrom
feat/integer-domains
Jul 20, 2026
Merged

iagoleal merged 3 commits into
mainfrom
feat/integer-domains

Conversation

@iagoleal

@iagoleal iagoleal commented Jul 20, 2026 •

Copy link
Copy Markdown
Collaborator

Remove the Ising restriction added in #107.
Now DMRG optimization accepts any finite domain.

Note: While the optimization itself supports non-integer domains,
the constraint support is still feeble: SumConstraint requires nonnegative integers, while other constraints are compared with exact equality.

  • Implement domain
  • Rewrite docs
  • Tests with non-uniform domains.

Close #108.

@iagoleal
iagoleal force-pushed the feat/integer-domains branch from fd91c23 to 361c499 Compare July 20, 2026 20:27
@iagoleal iagoleal changed the title Optimization with any integer domain Optimization with any finite domain Jul 20, 2026
@iagoleal
iagoleal force-pushed the feat/integer-domains branch from d5256a2 to 4e78d6c Compare July 20, 2026 20:40
@iagoleal
iagoleal merged commit 2a7a600 into main Jul 20, 2026
23 of 29 checks passed
@iagoleal
iagoleal deleted the feat/integer-domains branch July 20, 2026 22:15

@bernalde bernalde left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer review — any finite domain (Closes #108)

Clean, well-scoped generalization: it drops the [0,1]/[-1,1] whitelist from validate_solve_domain so DMRG accepts any finite, real, unique domain, and tightens the SumConstraint guard to reject non-nonnegative-integer domains with a clear error — matching the PR's honest note that constraint support stays limited. Minimal surface (no new keyword), good layering. No blocking code issues. One design Question and one nonblocking test gap below; also an environmental CI note.

What I verified

  • Widened range holds against the framework contract. Physical domain values live only in the D operator diagonal (diagm(domain)) and Solution.domain; ITensors still sees a Qudit of dim d with integer state labels 0:(d-1), so arbitrary real domains don't violate its contract. Confirmed a non-integer solve end to end: minimize(zeros(2,2), [-2,3]; domain=[0.0,0.5,1.0]) → E=-2.0, x=[1.0,0.0] (correct).
  • The tightened guard fails fast, not silently. Confirmed SumConstraint over domain=[-1,1] and over the non-integer nonneg domain=[0.0,1.5] both throw ArgumentError: SumConstraint only supports nonnegative integer domains. — the second case previously slipped past the old minimum(alphabet) < 0 guard into the integer partial-sum automaton, so this is a real hardening.
  • Tests cover the extremes, not one interior example: sparse non-contiguous [-2,0,3] (hand-checked E=-18), reversed [1,-1] (normalization to [-1.0,1.0]), singleton [0] (the d=1 edge), empty and non-real domains (validation errors), all cross-checked against brute_force(…; domain=…). No stale domain_dim references remain; docs add a doctested sparse-domain example.

Findings

Question — the accepted domain surface is wider than what's documented or tested. validate_solve_domain (src/backends/dmrg.jl:47) admits any Real domain, and non-integer domains genuinely work for the objective (verified above) — but every test uses integer domains, and the docs scope the domain to ⊆ ℤ, while the PR body claims non-integer support. That's three sources disagreeing on the contract. Please pick one: either make non-integer support real (a doctest/regression over a fractional domain + a doc line), or, if integer domains are the intended surface for now, tighten the validator to integers so the accepted input matches the documented and tested contract rather than silently accepting more than the PR stands behind.

Nonblocking — no test for the changed SumConstraint guard. The guard's condition and message changed (and it now catches the previously-silent non-integer-nonneg case), but nothing exercises the error path. Add a one-line @test_throws ArgumentError for a SumConstraint under a signed and/or fractional domain to lock the fail-fast behavior in.

Tests / CI

Full Pkg.test() passes locally (0 failures). On the PR head, build, documenter/deploy, and every ubuntu/macOS job across lts/1/pre are green. Julia 1 - windows-latest failed — but at ITensors-dependency precompile (ArgumentError: Package Accessors … is required but does not seem to be installed, cascading through Transducers → NDTensors → ITensors), before any TenSolver test runs. This PR changes no Project.toml dependency; main's latest run is green on all three Windows jobs, and this PR's own pre-windows job passed — so it's a transient Windows dependency-materialization flake, not a code defect.

Merge-readiness

No blocking code issues; approving on the merits. Two things before merge, both outside the code: get a green Windows run (re-run the flaked job — the current UNSTABLE state is that failure), and settle the domain-surface Question above (it can be a one-line doc/validator tweak or a follow-up, your call). main is not branch-protected, so no formal approval gate is reported.

Comment thread src/backends/dmrg.jl
elseif !all(value -> value isa Real, domain)
throw(ArgumentError("`domain` values must be real numbers"))
throw(ArgumentError("`domain` must contain at least one value."))
elseif !all(u -> u isa Real, domain)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: this accepts any Real domain, and non-integer domains do work for the objective — I verified minimize(zeros(2,2), [-2,3]; domain=[0.0,0.5,1.0]) returns the correct E=-2.0. But no test uses a non-integer domain and the docs scope the domain to ⊆ ℤ, while the PR description claims non-integer support. The accepted surface should match the documented and tested one: either add a fractional-domain doctest/test (and a doc line) to stand behind the claim, or tighten this check to integers so unsupported inputs fail fast instead of silently doing more than the PR verifies.

Comment thread src/projection_mpo.jl
function constraint_to_dfa(constraint::SumConstraint{S}, nsites::Integer, alphabet) where {S}
if minimum(alphabet) < 0
throw(ArgumentError("SumConstraint only supports nonnegative domains."))
if !all(a -> isinteger(a) && a >= 0, alphabet)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonblocking: this guard's condition and message changed here, and it now also catches non-integer nonnegative domains that the previous minimum(alphabet) < 0 check let slip into the integer partial-sum automaton (I confirmed SumConstraint over domain=[0.0,1.5] now errors cleanly, where before it would not). Worth a one-line @test_throws ArgumentError — a SumConstraint under a signed and/or fractional domain — so this fail-fast behavior can't silently regress.

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.

General (variable-uniform) Integer domains

2 participants