Our inv uses the LU factorization and if the matrix is singular this can
give an inverse with very large errors instead of a singular exception.
MATLAB gives the same result but with a warning that the result might be
inaccurate. We have considered also giving a warning, but haven't made a
decision yet.
Note that you have the option of doing the calculation in rational instead
of floating point arithmetic, i.e.
julia> Ar = A//1
3x3 Array{Rational{Int64},2}:
2//1 1//1 -1//1
1//1 -2//1 -3//1
-3//1 -1//1 2//1
julia> inv(Ar)
ERROR: SingularException(3)
in naivesub! at linalg/triangular.jl:257
in A_ldiv_B! at linalg/bidiag.jl:143
in inv at linalg/factorization.jl:812
in inv at linalg/dense.jl:328
which will detect the singularity.
2014-12-29 4:52 GMT+01:00 Tomas Lycken <[email protected]>:
> That probably confirms my hypothesis: when you move down to Float32, the
> rounding errors from the arithmetic are truncated away, so that the
> singularity of the matrix is preserved.
>
> // T
>
>
> On Monday, December 29, 2014 4:42:01 AM UTC+1, Ben Zeckel wrote:
>>
>> Interesting. if I move down to Float32 (not the default on my 64-bit
>> version), I a better result.
>>
>> julia> versioninfo()
>> Julia Version 0.3.4
>> Commit 3392026* (2014-12-26 10:42 UTC)
>> Platform Info:
>> System: Windows (x86_64-w64-mingw32)
>> CPU: Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz
>> WORD_SIZE: 64
>> BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
>> LAPACK: libopenblas
>> LIBM: libopenlibm
>> LLVM: libLLVM-3.3
>>
>> julia> A = [2 1 -1; 1 -2 -3; -3 -1 2];
>>
>> julia> A
>> 3x3 Array{Float64,2}:
>> 2.0 1.0 -1.0
>> 1.0 -2.0 -3.0
>> -3.0 -1.0 2.0
>>
>> julia> det(A)
>> 1.5543122344752192e-15
>>
>> julia> eps(Float64)
>> 2.220446049250313e-16
>>
>> julia> nextfloat(0.0)
>> 5.0e-324
>>
>> julia> A = float32(A)
>> 3x3 Array{Float32,2}:
>> 2.0 1.0 -1.0
>> 1.0 -2.0 -3.0
>> -3.0 -1.0 2.0
>>
>> julia> det(A)
>> 0.0f0
>>
>> julia> inv(A)
>> ERROR: SingularException(3)
>> in inv at linalg/lu.jl:149
>> in inv at linalg/dense.jl:328
>>
>> julia>
>>
>> On Sunday, December 28, 2014 10:05:15 PM UTC-5, Tomas Lycken wrote:
>>>
>>> The determinant of your failing A is nonzero:
>>>
>>> julia> det(A)
>>> 1.5543122344752192e-15
>>>
>>> Of course, given its magnitude, that's probably just floating-point
>>> error noise - but it makes me guess that the matrix inversion fails (i.e.
>>> doesn't fail) for the same reason; somewhere along the calculations, enough
>>> floating point error is accumulated to make the matrix non-singular (albeit
>>> still very ill-conditioned, as seen by the monstrously large numbers in the
>>> inverse...). I'm not confident enough to definitely rule out a bug
>>> somewhere, but I'd consider it pretty likely that floating point arithmetic
>>> is the root cause in this instance =)
>>>
>>> // Tomas
>>>
>>> On Monday, December 29, 2014 3:17:06 AM UTC+1, Ben Zeckel wrote:
>>>>
>>>>
>>>> I am attempting to learn Julia and am experimenting with the matrix
>>>> function inv to calculate the inverse of some matrices. Some are singular
>>>> and some are nonsingular.
>>>> One case (below) gives me the wrong result but it is a simple example
>>>> so I must be misusing Julia (I found a similar issue with large numbers in
>>>> the basic factorial function in the documentation returning 0 which came
>>>> down to me not realizing the overflow behavior immediately)
>>>>
>>>> These attempts works as expected
>>>>
>>>> julia> A = [1 2 3; 0 2 2; 1 2 3]; inv(A)
>>>> ERROR: SingularException(3)
>>>> in inv at linalg/lu.jl:149
>>>> in inv at linalg/dense.jl:328
>>>>
>>>> julia> A = [1 1 1; 0 2 3; 5 5 1]; inv(A)
>>>> 3x3 Array{Float64,2}:
>>>> 1.625 -0.5 -0.125
>>>> -1.875 0.5 0.375
>>>> 1.25 0.0 -0.25
>>>>
>>>> julia> inv(A) * A
>>>> 3x3 Array{Float64,2}:
>>>> 1.0 0.0 0.0
>>>> 0.0 1.0 0.0
>>>> 0.0 0.0 1.0
>>>>
>>>>
>>>> This does not
>>>>
>>>> jjulia> A = [2 1 -1; 1 -2 -3; -3 -1 2]; inv(A)
>>>> 3x3 Array{Float64,2}:
>>>> -4.5036e15 -6.43371e14 -3.21686e15
>>>> 4.5036e15 6.43371e14 3.21686e15
>>>> -4.5036e15 -6.43371e14 -3.21686e15
>>>>
>>>> julia> A * inv(A)
>>>> 3x3 Array{Float64,2}:
>>>> 0.0 -0.125 -0.5
>>>> 0.0 0.75 0.0
>>>> 0.0 0.0 0.0
>>>>
>>>> Double checking manually, in julia with rref, and with wolframalpha.com
>>>> shows the expected results on this singular matrix
>>>>
>>>> julia> A = [2 1 -1; 1 -2 -3; -3 -1 2]; rref([A eye(3)])
>>>> 3x6 Array{Float64,2}:
>>>> 1.0 0.0 -1.0 0.0 0.142857 -0.285714
>>>> 0.0 1.0 1.0 0.0 -0.428571 -0.142857
>>>> * 0.0 0.0 0.0 * 1.0 0.142857 0.714286
>>>>
>>>> inv {{2,1,-1}, {1,-2,-3}, {-3,-1,2}}
>>>> http://www.wolframalpha.com/input/?i=inv+%7B%7B2%2C1%2C-1%
>>>> 7D%2C+%7B1%2C-2%2C-3%7D%2C+%7B-3%2C-1%2C2%7D%7D
>>>>
>>>> Thanks for any help,
>>>>
>>>> Ben
>>>>
>>>>