@@ -418,6 +418,13 @@ function copy_dense{Tv<:VTypes}(A::Dense{Tv})
418
418
d
419
419
end
420
420
421
+ function sort! {Tv<:VTypes} (S:: Sparse{Tv} )
422
+ @isok ccall ((:cholmod_l_sort , :libcholmod ), SuiteSparse_long,
423
+ (Ptr{C_Sparse{Tv}}, Ptr{UInt8}),
424
+ get (S. p), common ())
425
+ return S
426
+ end
427
+
421
428
# ## cholmod_matrixops.h ###
422
429
function norm_dense {Tv<:VTypes} (D:: Dense{Tv} , p:: Integer )
423
430
s = unsafe_load (get (D. p))
851
858
function (:: Type{Sparse} ){Tv<: VTypes }(m:: Integer , n:: Integer , colptr:: Vector{SuiteSparse_long} , rowval:: Vector{SuiteSparse_long} , nzval:: Vector{Tv} )
852
859
o = Sparse (m, n, colptr, rowval, nzval, 0 )
853
860
861
+ # sort indices
862
+ sort! (o)
863
+
854
864
# check if array is symmetric and change stype if it is
855
865
if ishermitian (o)
856
866
change_stype! (o, - 1 )
@@ -993,21 +1003,51 @@ function convert{Tv}(::Type{SparseMatrixCSC{Tv,SuiteSparse_long}}, A::Sparse{Tv}
993
1003
if s. stype != 0
994
1004
throw (ArgumentError (" matrix has stype != 0. Convert to matrix with stype == 0 before converting to SparseMatrixCSC" ))
995
1005
end
996
- return SparseMatrixCSC (s. nrow, s. ncol, increment (unsafe_wrap (Array, s. p, (s. ncol + 1 ,), false )), increment (unsafe_wrap (Array, s. i, (s. nzmax,), false )), copy (unsafe_wrap (Array, s. x, (s. nzmax,), false )))
1006
+
1007
+ B = SparseMatrixCSC (s. nrow, s. ncol,
1008
+ increment (unsafe_wrap (Array, s. p, (s. ncol + 1 ,), false )),
1009
+ increment (unsafe_wrap (Array, s. i, (s. nzmax,), false )),
1010
+ copy (unsafe_wrap (Array, s. x, (s. nzmax,), false )))
1011
+
1012
+ if s. sorted == 0
1013
+ return SparseArrays. sortSparseMatrixCSC! (B)
1014
+ else
1015
+ return B
1016
+ end
997
1017
end
998
1018
function convert (:: Type{Symmetric{Float64,SparseMatrixCSC{Float64,SuiteSparse_long}}} , A:: Sparse{Float64} )
999
1019
s = unsafe_load (A. p)
1000
1020
if ! issymmetric (A)
1001
1021
throw (ArgumentError (" matrix is not symmetric" ))
1002
1022
end
1003
- return Symmetric (SparseMatrixCSC (s. nrow, s. ncol, increment (unsafe_wrap (Array, s. p, (s. ncol + 1 ,), false )), increment (unsafe_wrap (Array, s. i, (s. nzmax,), false )), copy (unsafe_wrap (Array, s. x, (s. nzmax,), false ))), s. stype > 0 ? :U : :L )
1023
+
1024
+ B = Symmetric (SparseMatrixCSC (s. nrow, s. ncol,
1025
+ increment (unsafe_wrap (Array, s. p, (s. ncol + 1 ,), false )),
1026
+ increment (unsafe_wrap (Array, s. i, (s. nzmax,), false )),
1027
+ copy (unsafe_wrap (Array, s. x, (s. nzmax,), false ))), s. stype > 0 ? :U : :L )
1028
+
1029
+ if s. sorted == 0
1030
+ return SparseArrays. sortSparseMatrixCSC! (B. data)
1031
+ else
1032
+ return B
1033
+ end
1004
1034
end
1005
1035
function convert {Tv<:VTypes} (:: Type{Hermitian{Tv,SparseMatrixCSC{Tv,SuiteSparse_long}}} , A:: Sparse{Tv} )
1006
1036
s = unsafe_load (A. p)
1007
1037
if ! ishermitian (A)
1008
1038
throw (ArgumentError (" matrix is not Hermitian" ))
1009
1039
end
1010
- return Hermitian (SparseMatrixCSC (s. nrow, s. ncol, increment (unsafe_wrap (Array, s. p, (s. ncol + 1 ,), false )), increment (unsafe_wrap (Array, s. i, (s. nzmax,), false )), copy (unsafe_wrap (Array, s. x, (s. nzmax,), false ))), s. stype > 0 ? :U : :L )
1040
+
1041
+ B = Hermitian (SparseMatrixCSC (s. nrow, s. ncol,
1042
+ increment (unsafe_wrap (Array, s. p, (s. ncol + 1 ,), false )),
1043
+ increment (unsafe_wrap (Array, s. i, (s. nzmax,), false )),
1044
+ copy (unsafe_wrap (Array, s. x, (s. nzmax,), false ))), s. stype > 0 ? :U : :L )
1045
+
1046
+ if s. sorted == 0
1047
+ return SparseArrays. sortSparseMatrixCSC! (B. data)
1048
+ else
1049
+ return B
1050
+ end
1011
1051
end
1012
1052
function sparse (A:: Sparse{Float64} ) # Notice! Cannot be type stable because of stype
1013
1053
s = unsafe_load (A. p)
@@ -1571,21 +1611,16 @@ function isposdef{Tv<:VTypes}(A::SparseMatrixCSC{Tv,SuiteSparse_long})
1571
1611
true
1572
1612
end
1573
1613
1574
- function issymmetric (A:: Sparse )
1575
- s = unsafe_load (A. p)
1576
- if s. stype != 0
1577
- return isreal (A)
1578
- end
1579
- i = symmetry (A, 1 )[1 ]
1580
- return i == MM_SYMMETRIC || i == MM_SYMMETRIC_POSDIAG
1581
- end
1582
-
1583
1614
function ishermitian (A:: Sparse{Float64} )
1584
1615
s = unsafe_load (A. p)
1585
1616
if s. stype != 0
1586
1617
return true
1587
1618
else
1588
1619
i = symmetry (A, 1 )[1 ]
1620
+ if i < 0
1621
+ throw (CHOLMODException (" negative value returned from CHOLMOD's symmetry function. This
1622
+ is either because the indices are not sorted or because of a memory error" ))
1623
+ end
1589
1624
return i == MM_SYMMETRIC || i == MM_SYMMETRIC_POSDIAG
1590
1625
end
1591
1626
end
@@ -1595,6 +1630,10 @@ function ishermitian(A::Sparse{Complex{Float64}})
1595
1630
return true
1596
1631
else
1597
1632
i = symmetry (A, 1 )[1 ]
1633
+ if i < 0
1634
+ throw (CHOLMODException (" negative value returned from CHOLMOD's symmetry function. This
1635
+ is either because the indices are not sorted or because of a memory error" ))
1636
+ end
1598
1637
return i == MM_HERMITIAN || i == MM_HERMITIAN_POSDIAG
1599
1638
end
1600
1639
end
0 commit comments