From 0124e2f8680d78a3361d379e18fbd96158b182e0 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 5 Jun 2026 13:26:45 +0200 Subject: [PATCH] Add high-level cone construction API Allow Cone to build directly from Julia matrix input and convert generic cone_property results back to Julia-native matrix, vector, integer, and rational types. Keep typed property getters as the low-level API while adding coverage for dictionary and keyword construction. Co-authored-by: Codex --- src/Normaliz.jl | 33 ++++++++++++++++++++++++++++----- test/runtests.jl | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/Normaliz.jl b/src/Normaliz.jl index 65174d3..d6ed8da 100644 --- a/src/Normaliz.jl +++ b/src/Normaliz.jl @@ -57,18 +57,28 @@ computed_cone_properties(cone::Cone) = _string_vector(_computed_cone_properties( is_computed(cone::Cone, property::AbstractString) = _is_computed(cone, property) is_computed(cone::Cone, property::Symbol) = is_computed(cone, String(property)) +_julia_cone_property(x) = x +_julia_cone_property(x::NmzInteger) = convert(BigInt, x) +_julia_cone_property(x::NmzRational) = convert(Rational{BigInt}, x) +_julia_cone_property(x::NmzMatrix{NmzInteger}) = Matrix{BigInt}(x) +_julia_cone_property(x::NmzMatrix{NmzRational}) = Matrix{Rational{BigInt}}(x) +_julia_cone_property(x::CxxWrap.StdLib.StdVector{NmzInteger}) = + convert.(BigInt, collect(x)) +_julia_cone_property(x::CxxWrap.StdLib.StdVector{NmzRational}) = + convert.(Rational{BigInt}, collect(x)) + function cone_property(cone::Cone, property::AbstractString) output_type = _cone_property_output_type(property) if output_type == "Matrix" - return get_matrix_cone_property(cone, property) + return _julia_cone_property(get_matrix_cone_property(cone, property)) elseif output_type == "Vector" - return get_vector_cone_property(cone, property) + return _julia_cone_property(get_vector_cone_property(cone, property)) elseif output_type == "Integer" - return get_integer_cone_property(cone, property) + return _julia_cone_property(get_integer_cone_property(cone, property)) elseif output_type == "GMPInteger" - return get_gmp_integer_cone_property(cone, property) + return _julia_cone_property(get_gmp_integer_cone_property(cone, property)) elseif output_type == "Rational" - return get_rational_cone_property(cone, property) + return _julia_cone_property(get_rational_cone_property(cone, property)) elseif output_type == "Float" return get_float_cone_property(cone, property) elseif output_type == "MachineInteger" @@ -161,6 +171,19 @@ function LongLongCone(input::AbstractDict) return _LongLongCone(input_keys, input_matrices) end +function Cone(input::AbstractDict; type::Symbol = :gmp) + if type in (:gmp, :bigint, :NmzInteger) + return GMPCone(input) + elseif type in (:longlong, :long_long, :int64, :Int64) + return LongLongCone(input) + end + throw(ArgumentError("unsupported Normaliz cone type: $type")) +end + +function Cone(; type::Symbol = :gmp, kwargs...) + return Cone(Dict{Symbol,Any}(kwargs); type) +end + Cone{NmzInteger}(args...) = GMPCone(args...) Cone{BigInt}(args...) = GMPCone(args...) Cone{Int64}(args...) = LongLongCone(args...) diff --git a/test/runtests.jl b/test/runtests.jl index 91cb84b..39e2031 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -142,6 +142,29 @@ end Normaliz.get_matrix_cone_property( yy, "SupportHyperplanes" ) end +@testset "high-level cone API" begin + yy = Normaliz.Cone(Dict(:cone => [1 2 ; 3 5], :grading => [1 1])) + @test yy isa Normaliz.Cone + + hilbert_basis = Normaliz.cone_property(yy, :HilbertBasis) + @test hilbert_basis isa Matrix{BigInt} + @test hilbert_basis == BigInt[1 2 ; 3 5] + + grading = Normaliz.cone_property(yy, :Grading) + @test grading isa Vector{BigInt} + @test grading == BigInt[1, 1] + + @test Normaliz.cone_property(yy, :ExternalIndex) == big(1) + @test Normaliz.cone_property(yy, :Multiplicity) isa Rational{BigInt} + @test Normaliz.cone_property(yy, :EuclideanVolume) isa Float64 + @test Normaliz.cone_property(yy, :EmbeddingDim) isa Int + @test Normaliz.cone_property(yy, :IsPointed) isa Bool + + yy = Normaliz.Cone(; cone = [1 2 ; 3 5], grading = [1 1], type = :longlong) + @test yy isa Normaliz.Cone + @test Normaliz.cone_property(yy, :HilbertBasis) == BigInt[1 2 ; 3 5] +end + @testset "cone property queries" begin known_properties = Normaliz.known_cone_properties() @test known_properties isa Vector{String} @@ -197,17 +220,12 @@ end matrix_from_generic = Normaliz.cone_property(yy, :HilbertBasis) matrix_from_typed = Normaliz.get_matrix_cone_property(yy, "HilbertBasis") - @test size(matrix_from_generic) == size(matrix_from_typed) - @test string(matrix_from_generic[1, 1]) == string(matrix_from_typed[1, 1]) + @test matrix_from_generic == Matrix{BigInt}(matrix_from_typed) - @test typeof(Normaliz.cone_property(yy, :Grading)) == - typeof(Normaliz.get_vector_cone_property(yy, "Grading")) - @test Normaliz.cone_property(yy, :TriangulationDetSum) == - Normaliz.get_integer_cone_property(yy, "TriangulationDetSum") - @test string(Normaliz.cone_property(yy, :ExternalIndex)) == - string(Normaliz.get_gmp_integer_cone_property(yy, "ExternalIndex")) - @test string(Normaliz.cone_property(yy, :Multiplicity)) == - string(Normaliz.get_rational_cone_property(yy, "Multiplicity")) + @test eltype(Normaliz.cone_property(yy, :Grading)) <: Integer + @test Normaliz.cone_property(yy, :TriangulationDetSum) isa Integer + @test Normaliz.cone_property(yy, :ExternalIndex) isa BigInt + @test Normaliz.cone_property(yy, :Multiplicity) isa Rational{BigInt} @test Normaliz.cone_property(yy, :EuclideanVolume) == Normaliz.get_float_cone_property(yy, "EuclideanVolume") @test Normaliz.cone_property(yy, "EmbeddingDim") ==