From ff4c0cdb30ac816d1cfed763fe99869de68fadba Mon Sep 17 00:00:00 2001 From: Oskar Henriksson Date: Sun, 2 Aug 2026 16:35:09 +0200 Subject: [PATCH] fix: allow rand_subspace of full and zero dimension --- src/linear_subspaces.jl | 8 ++++---- src/numerical_irreducible_decomposition.jl | 4 +--- test/linear_test.jl | 18 ++++++++++++++++++ test/witness_set_test.jl | 12 +++++++++++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/linear_subspaces.jl b/src/linear_subspaces.jl index 798af6f2b..a6b58de24 100644 --- a/src/linear_subspaces.jl +++ b/src/linear_subspaces.jl @@ -467,10 +467,10 @@ function rand_subspace( throw(ArgumentError("Neither `dim` nor `codim` specified.")) if !isnothing(dim) - 0 < dim < n || throw(ArgumentError("`dim` has to be between 0 and `n`.")) + 0 ≤ dim ≤ n || throw(ArgumentError("`dim` has to be between 0 and `n`.")) k = dim else - 0 < codim < n || throw(ArgumentError("`codim` has to be between 0 and `n`.")) + 0 ≤ codim ≤ n || throw(ArgumentError("`codim` has to be between 0 and `n`.")) k = n - codim end T = real ? Float64 : ComplexF64 @@ -491,10 +491,10 @@ function rand_subspace( throw(ArgumentError("Neither `dim` nor `codim` specified.")) if !isnothing(dim) - 0 < dim < n || throw(ArgumentError("`dim` has to be between 0 and `n`.")) + 0 ≤ dim ≤ n || throw(ArgumentError("`dim` has to be between 0 and `n`.")) k = dim else - 0 < codim < n || throw(ArgumentError("`codim` has to be between 0 and `n`.")) + 0 ≤ codim ≤ n || throw(ArgumentError("`codim` has to be between 0 and `n`.")) k = n - codim end A = zeros(eltype(x), n - k, n) diff --git a/src/numerical_irreducible_decomposition.jl b/src/numerical_irreducible_decomposition.jl index e1da59eff..6bb064776 100644 --- a/src/numerical_irreducible_decomposition.jl +++ b/src/numerical_irreducible_decomposition.jl @@ -627,9 +627,7 @@ end function initialize_witness_sets(codim, n; affine::Bool = true) # we need an initial slice from which the u-regeneration flag is derived dim = affine ? 1 : 2 - L₀ = - dim == n ? LinearSubspace(zeros(ComplexF64, 0, n)) : - rand_subspace(n; dim = dim, affine = affine) + L₀ = rand_subspace(n; dim = dim, affine = affine) flag = get_flag(1:codim, L₀) map(flag) do F diff --git a/test/linear_test.jl b/test/linear_test.jl index c0d763fc1..a8c7ab1e7 100644 --- a/test/linear_test.jl +++ b/test/linear_test.jl @@ -50,6 +50,24 @@ L2 = rand_subspace(x; dim = 2, affine = false) @test is_linear(L2) @test norm(L2(x)) ≈ 0 atol = 1e-8 + + # Test dimension 0 and codimension 0 case + L3 = rand_subspace(3; dim = 0) + @test dim(L3) == 0 + @test codim(L3) == 3 + + L4 = rand_subspace(3; dim = 3) + @test dim(L4) == 3 + @test codim(L4) == 0 + @test is_linear(L4) + + L5 = rand_subspace(3; codim = 3) + @test codim(L5) == 3 + @test dim(L5) == 0 + + L6 = rand_subspace(x; codim = 0) + @test codim(L6) == 0 + @test dim(L6) == length(x) end @testset "Intersect subspaces" begin diff --git a/test/witness_set_test.jl b/test/witness_set_test.jl index 44c5b4092..64b6f2ad2 100644 --- a/test/witness_set_test.jl +++ b/test/witness_set_test.jl @@ -22,7 +22,6 @@ @test trace_test(W) < 1e-8 end - @testset "projective" begin @var x y z @@ -84,6 +83,17 @@ @test degree(witness_set(f; compile = false)) == 16 end + @testset "dimension zero" begin + @var x y + + F = System([x^2 - 1, y - x], [x, y]) + W = witness_set(F; dim = 0, compile = false) + + @test dim(W) == 0 + @test codim(W) == 2 + @test degree(W) == 2 + end + @var x, y, z p = (x * y - x^2) + 1 - z q = x^4 + x^2 - y - 1