diff --git a/src/affine.jl b/src/affine.jl index 95b50cb..33b2558 100644 --- a/src/affine.jl +++ b/src/affine.jl @@ -143,6 +143,16 @@ function affine_transform_tensors( b = @. b >> 1 end + # If the carry set is empty, no valid integer mappings exist for this + # transformation. Return zero tensors forming a valid (zero) MPO. + if isempty(carry) + @warn "Affine transformation has no valid integer mappings; returning zero MPO." + for r in 1:R + tensors[r] = zeros(Bool, 1, 1, 1 << M, 1 << N) + end + return tensors, carry + end + if boundary == OpenBoundaryConditions() && maximum(b) > 0 # Extend the tensors to the left until we have no more nonzero bits in b # This is equivalent to a larger domain. @@ -154,6 +164,15 @@ function affine_transform_tensors( carry = new_carry b = @. b >> 1 + isempty(carry) && break + end + + if isempty(carry) + @warn "Affine transformation has no valid integer mappings; returning zero MPO." + for r in 1:R + tensors[r] = zeros(Bool, 1, 1, 1 << M, 1 << N) + end + return tensors, carry end weights = map(c -> carry_weight(c, boundary), carry) diff --git a/test/affine_tests.jl b/test/affine_tests.jl index 7e49df4..3fdac94 100644 --- a/test/affine_tests.jl +++ b/test/affine_tests.jl @@ -158,4 +158,28 @@ end end end + + @testset "degenerate_rational (issue #46)" begin + # This transformation has no valid integer mappings because + # A_int has all even entries while b_int[3] is odd, so + # A_int*x + b_int can never be divisible by the even denominator s=42. + A = [1 0 0; -1//7 6//7 6//7; -10//21 6//7 -1//7] + b = [0, 27 // 7, 61 // 14] + R = 3 + + M, N = size(A) + bc = Quantics.OpenBoundaryConditions() + + # The full matrix should be all zeros (no valid mappings) + T = Quantics.affine_transform_matrix(R, A, b, bc) + @test nnz(T) == 0 + + # The MPO construction should not crash (was DivideError before fix) + # and should emit a warning about no valid mappings. + mpo = @test_warn "no valid integer mappings" Quantics.affine_transform_mpo( + outsite[1:R, 1:M], insite[1:R, 1:N], A, b, bc) + Trec = Quantics.affine_mpo_to_matrix( + outsite[1:R, 1:M], insite[1:R, 1:N], mpo) + @test T == Trec + end end