Solving A*x=b in Nemo

Let A = [1 0 0; 0 1 1; 0 3 0; 0 0 1]

a matrix of type 4×3 Matrix{QQFieldElem}:
and Q=[2 ,-3 , 1, 1] of type 4-element Vector{QQFieldElem}:
My goal is to compute A \setminus Q but I got error

MethodError: no method matching abs2(::QQFieldElem)

I try to convert 4×3 Matrix{QQFieldElem}: into 4×3 Matrix{Int64}: so I can use LinearAlgebra package but no success.
Any ideal how to compute this.

You’re trying to find a length-3 vector X such that A * X == Q. In this case, you can check by hand that no solution exists, because the system is over-determined. If you were doing this over floating-point numbers, it makes sense to talk about a “closest” solution, but this is not a natural thing for rational numbers or integers. If you really need to do this, convert the matrix and vector to Float64.

You’re assuming @blociss wants the closest solution, however what they want is not at all clear.

@blociss if you’re looking for an exact solution, as opposed to the closest one, look here:

What I want is to convert QQFieldElem into Int64 element.
I got closed solution when the matrix and vector are of type Int64.

Edit: As pointed out by @thofma, the method below is brittle and should not be used. See this post for the correct way.

julia> function conv2int(A::Array{QQFieldElem})
           all(x -> x.den == 1, A) || error("A not an integer-valued matrix")
           return map(x -> x.num, A)
       end
conv2int (generic function with 1 method)

julia> A = QQFieldElem[1 0 0; 0 1 1; 0 3 0; 0 0 1]
4×3 Matrix{QQFieldElem}:
 1  0  0
 0  1  1
 0  3  0
 0  0  1

julia> Aint = conv2int(A)
4×3 Matrix{Int64}:
 1  0  0
 0  1  1
 0  3  0
 0  0  1
1 Like

The functions for solving or checking solvability are can_solve and can_solve_with_solution. Only works with matrices though, so your example would look like:

julia> A = QQ[1 0 0; 0 1 1; 0 3 0; 0 0 1]
[1   0   0]
[0   1   1]
[0   3   0]
[0   0   1]

julia> Q =  [2 ,-3 , 1, 1]
4-element Vector{Int64}:
  2
 -3
  1
  1

julia> B = matrix(QQ, 4, 1, Q)
[ 2]
[-3]
[ 1]
[ 1]

julia> can_solve(A, B)
false

See also the docstring of can_solve.

(Here is how it would look like to compute a solution in case one exists:

julia> B = matrix(QQ, 4, 1, [1, 0, 0, 0])
[1]
[0]
[0]
[0]

julia> can_solve_with_solution(A, B)
(true, [1; 0; 0])

)

3 Likes

So this doesn’t work if A and B are of type Matrix{QQFieldElem}?

Yes. By the way, if you want to convert to Matrix{Int}, the correct way would be

julia> A = QQFieldElem[1 0 0; 0 1 1; 0 3 0; 0 0 1]
4×3 Matrix{QQFieldElem}:
 1  0  0
 0  1  1
 0  3  0
 0  0  1

julia> map(x -> Int(ZZ(x)), A)
4×3 Matrix{Int64}:
 1  0  0
 0  1  1
 0  3  0
 0  0  1

The version with x.num will give (silently) wrong results:

julia> A = QQFieldElem[1 0 0; 0 1 1; 0 3 0; 0 0 18446744073709551615]
4×3 Matrix{QQFieldElem}:
 1  0  0
 0  1  1
 0  3  0
 0  0  18446744073709551615

julia> Aint = conv2int(A)
4×3 Matrix{Int64}:
 1  0                    0
 0  1                    1
 0  3                    0
 0  0  4611686018537972628
2 Likes