From a2407065eb7ac44a5eec22143511a4b6f6b691fa Mon Sep 17 00:00:00 2001 From: Samuel Badr Date: Fri, 13 Feb 2026 17:04:33 +0100 Subject: [PATCH] Accept untyped indextable containers in grid constructors --- src/grid.jl | 33 +++++++++++++++++++++++++++++- src/grid_discretized.jl | 3 ++- test/discretizedgrid_misc_tests.jl | 18 ++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/grid.jl b/src/grid.jl index 58a8b71..976c645 100644 --- a/src/grid.jl +++ b/src/grid.jl @@ -61,6 +61,36 @@ _to_tuple(::Val{d}, x) where {d} = ntuple(i -> x, d) _all_base_two(base::NTuple{D,Int}) where {D} = all(==(2), base) +function _normalize_indextable(indextable) + normalized = Vector{Vector{Tuple{Symbol,Int}}}(undef, length(indextable)) + for (site_idx, site) in pairs(indextable) + if !(site isa AbstractVector) + throw(ArgumentError(lazy"Index table entry at site $site_idx must be an AbstractVector, got $(typeof(site)).")) + end + + normalized_site = Vector{Tuple{Symbol,Int}}(undef, length(site)) + for (position, qindex) in pairs(site) + if !(qindex isa Tuple) || length(qindex) != 2 + throw(ArgumentError(lazy"Index table entry at site $site_idx position $position must be a tuple (Symbol, Int).")) + end + + variablename, bitnumber = qindex + if !(variablename isa Symbol) + throw(ArgumentError(lazy"Index table entry at site $site_idx position $position has invalid variablename $(variablename). Expected Symbol.")) + end + if !(bitnumber isa Integer) + throw(ArgumentError(lazy"Index table entry at site $site_idx position $position has invalid bitnumber $(bitnumber). Expected Integer.")) + end + + normalized_site[position] = (variablename, Int(bitnumber)) + end + + normalized[site_idx] = normalized_site + end + + return normalized +end + function _base_as_scalar_if_uniform(base::NTuple{D,Int}) where {D} if D == 0 return base @@ -291,11 +321,12 @@ end function InherentDiscreteGrid( variablenames::NTuple{D,Symbol}, - indextable::Vector{Vector{Tuple{Symbol,Int}}}; + indextable::AbstractVector; origin=default_origin(Val(D)), step=default_step(Val(D)), base=2 ) where D + indextable = _normalize_indextable(indextable) base = _to_tuple(Val(D), base) Rs = map(variablenames) do variablename count(index -> first(index) == variablename, Iterators.flatten(indextable)) diff --git a/src/grid_discretized.jl b/src/grid_discretized.jl index 9fbea66..50c1ef0 100644 --- a/src/grid_discretized.jl +++ b/src/grid_discretized.jl @@ -211,12 +211,13 @@ end function DiscretizedGrid( variablenames::NTuple{D,Symbol}, - indextable::Vector{Vector{Tuple{Symbol,Int}}}; + indextable::AbstractVector; lower_bound=default_lower_bound(Val(D)), upper_bound=default_upper_bound(Val(D)), base=2, includeendpoint=false ) where D + indextable = _normalize_indextable(indextable) Rs = map(variablenames) do variablename count(index -> first(index) == variablename, Iterators.flatten(indextable)) end diff --git a/test/discretizedgrid_misc_tests.jl b/test/discretizedgrid_misc_tests.jl index e7c1986..0bf008d 100644 --- a/test/discretizedgrid_misc_tests.jl +++ b/test/discretizedgrid_misc_tests.jl @@ -47,6 +47,24 @@ end @test g.discretegrid.lookup_table == g´.discretegrid.lookup_table == g´´.discretegrid.lookup_table end +@testitem "DiscretizedGrid accepts untyped indextable container" begin + R = 10 + N = 2^R + lower_bound = (0.0, 0.0) + upper_bound = (2.0, N - 1.0) + + indextable = [] + for l in 1:R + push!(indextable, [(:w, l)]) + push!(indextable, [(:n, R - l + 1)]) + end + + g = DiscretizedGrid((:w, :n), indextable; lower_bound, upper_bound, includeendpoint=(false, true)) + @test QuanticsGrids.grid_variablenames(g) == (:w, :n) + @test length(QuanticsGrids.grid_indextable(g)) == 2R + @test QuanticsGrids.grid_max(g)[2] ≈ N - 1 +end + @testitem "DiscretizedGrid dimension mismatch for bounds" begin @test_throws ArgumentError DiscretizedGrid{2}(3, (0.0,), (1.0, 2.0)) @test_throws ArgumentError DiscretizedGrid{2}(3, (0.0, 1.0), (1.0,))