I ran into this issue when some of my unit tests failed on the v0.5 release 
candidate. This example illustrates it:

v0.4:
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.4.6 (2016-06-19 17:16 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-w64-mingw32

julia> a = cov(rand(1000,6));

julia> chol(inv(a))
6x6 UpperTriangular{Float64,Array{Float64,2}}:
 3.58638  -0.0476413  -0.208862   0.0448371  -0.127109    0.163736
 0.0       3.5431     -0.0297272  0.1167     -0.0598619  -0.105655
 0.0       0.0         3.45667    0.0493362   0.0118136  -0.00615045
 0.0       0.0         0.0        3.36366     0.0491131   0.146946
 0.0       0.0         0.0        0.0         3.52767    -0.0148549
 0.0       0.0         0.0        0.0         0.0         3.52757

v0.5:
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.5.0-rc0+0 (2016-07-26 20:22 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-w64-mingw32

julia> a = cov(rand(1000,6));

julia> chol(inv(a))
ERROR: ArgumentError: matrix is not symmetric/Hermitian. This error can be 
avoided by calling chol(Hermitian(A)) which will ignore either the upper or 
lower triangle of the matrix.
 in chol(::Array{Float64,2}) at .\linalg\cholesky.jl:156

julia> b = inv(a);

julia> maximum(b'-b)
1.1102230246251565e-16

I know an example using rand() is not ideal, but the behavior is pretty 
consistent. I tracked the difference down to here 
<https://github.com/JuliaLang/julia/commit/597d945adc083c031806bc7c4510f4cdeb0a23b9#diff-3d858f382dd60c92d7d650dae9243d58>:
 
basically, in v0.5 there is an explicit check for a Hermitian matrix using 
ishermitian(), whereas in v0.4, chol() just uses the `info` output 
parameter from LAPACK.potrf!(). Calling potrf!() on the matrix `b` above 
returns a zero for info, meaning the execution completed successfully. So, 
it seems the ishermtian check for symmetry is stricter than LAPACK's.

This is not necessarily a problem, but I run into this kind of issue 
frequently in my code, and I'm wondering what the best way forward is. I 
could wrap every chol() argument with Hermitian to ensure it's exactly 
symmetric, but then I lose a guard against more sinister bugs, since it 
will force any matrix to be Hermitian. Thoughts? Is the explicit 
ishermitian check necessary?

Reply via email to