Skip to content

Commit ff970f4

Browse files
authored
Add support for LinearSolve (#24)
* Add set_A and LinearProblem methods if LinearSolve is loaded. * format all files * format & update docs
1 parent 5aeae73 commit ff970f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1691
-1835
lines changed

.JuliaFormatter.toml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
style = "sciml"
2+
always_for_in = false
3+
separate_kwargs_with_semicolon = true
4+
format_markdown = true

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
QUARRY
2-
.project.jl
32
docs/build
43
*~
54
Manifest.toml
6-
.repl_history.jl
5+
.repl_history
6+
quarry
77

Project.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ExtendableSparse"
22
uuid = "95c220a8-a1cf-11e9-0c77-dbfce5f500b3"
33
authors = ["Juergen Fuhrmann <[email protected]>"]
4-
version = "0.9.5"
4+
version = "0.9.6"
55

66
[deps]
77
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
@@ -16,9 +16,9 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1616

1717
[compat]
1818
DocStringExtensions = "0.8, 0.9"
19-
ILUZero= "0.2"
19+
ILUZero = "0.2"
2020
Requires = "1.1.3"
21-
Sparspak = "0.3.3"
21+
Sparspak = "0.3.6"
2222
julia = "1.6"
2323

2424
[extras]

README.md

+53-15
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,48 @@
77

88
Sparse matrix class with efficient successive insertion of entries and entry update, supporting general number types.
99

10+
## Summary
11+
12+
The package allows for efficient assembly of a sparse matrix without
13+
the need to handle intermediate arrays:
14+
15+
```
16+
using ExtendableSparse
17+
A=ExtendableSparseMatrix(10,10)
18+
A[1,1]=1
19+
for i = 1:9
20+
A[i + 1, i] += -1
21+
A[i, i + 1] += -1
22+
A[i, i] += 1
23+
A[i + 1, i + 1] += 1
24+
end
25+
b=ones(10)
26+
x=A\b
27+
```
28+
29+
While one could replace here `ExtendableSparseMatrix(10,10)` by `spzeros(10,10)`, the later is inefficient for large problems. Without this package, the general advise is to [construct a sparse matrix via the COO format](https://docs.julialang.org/en/v1/stdlib/SparseArrays/#Sparse-Vector-and-Matrix-Constructors).
30+
31+
Instead of `\`, the methods from [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) can be used:
32+
33+
```
34+
using LinearSolve
35+
p=LinearProblem(A,b)
36+
LinearSolve.solve(p)
37+
```
38+
39+
With the help of [Sparspak.jl](https://github.com/PetrKryslUCSD/Sparspak.jl), these examples work for general number types.
40+
41+
`sparse(A)` creates a standard `SparseMatrixCSC` from a filled `ExtendableSparseMatrix` which can be used e.g. to create preconditioners. So one can instead perform e.g.
42+
43+
```
44+
LinearSolve.solve(p, KrylovJL_CG(); Pl = ILUZero.ilu0(sparse(A)))
45+
```
46+
1047
## Rationale
48+
1149
Without an intermediate data structure, efficient successive insertion/update of possibly duplicate entries in random order into a standard compressed column storage structure appears to be not possible. The package introduces `ExtendableSparseMatrix`, a delegating wrapper containing a Julia standard `SparseMatrixCSC` struct for performing linear algebra operations and a `SparseMatrixLNK` struct realising a linked list based (but realised in vectors) format collecting new entries.
1250

13-
The later is modeled after the linked list sparse matrix format described in the [whitepaper](https://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps) by Y. Saad. See also exercise P.3-16 in his [book](https://www-users.cs.umn.edu/~saad/IterMethBook_2ndEd.pdf).
51+
The later is modeled after the linked list sparse matrix format described in the [whitepaper](https://www-users.cs.umn.edu/%7Esaad/software/SPARSKIT/paper.ps) by Y. Saad. See also exercise P.3-16 in his [book](https://www-users.cs.umn.edu/%7Esaad/IterMethBook_2ndEd.pdf).
1452

1553
Any linear algebra method on `ExtendableSparseMatrix` starts with a `flush!` method which adds the LNK entries and the existing CSC entries into a new CSC struct and resets the LNK struct.
1654

@@ -25,10 +63,10 @@ number types not supported by Julia's standard implementation. Notably, this i
2563
This package assumes that a $m \times n$ matrix is sparse if *each* row and *each* column have less than $C$ entries with
2664
$C << n$ and $C << m$ . Adding a full matrix row will be a performance hit.
2765

28-
2966
## Working with ForwardDiff
3067

3168
In particular, it cooperates with [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) when it comes to the assembly of a sparse jacobian. For a function 'f!(y,x)' returning it's result in a vector `y`, one can use e.g.
69+
3270
````
3371
x=...
3472
y=zeros(n)
@@ -38,46 +76,46 @@ jac=DiffResults.jacobian(dresult)
3876
h=jac\x
3977
````
4078

41-
However, without a priori information on sparsity, ForwardDiff calls element insertion for the full range of n^2 indices,
79+
However, without a priori information on sparsity, ForwardDiff calls element insertion for the full range of n^2 indices,
4280
leading to a O(n^2) scaling behavior due to the nevertheless necessary search operations, see this [discourse thread](https://discourse.julialang.org/t/non-sorted-sparsematrixcsc/37133).
4381

4482
## updateindex!
45-
In addition, the package provides a method `updateindex!(A,op,v,i,j)` for both `SparseMatrixCSC` and for `ExtendableSparse` which allows to update a matrix element with one index search instead of two. It allows to replace e.g. `A[i,j]+=v` by `updateindex!(A,+,v,i,j)`. The former operation is lowered to
83+
84+
In addition, the package provides a method `updateindex!(A,op,v,i,j)` for both `SparseMatrixCSC` and for `ExtendableSparse` which allows to update a matrix element with one index search instead of two. It allows to replace e.g. `A[i,j]+=v` by `updateindex!(A,+,v,i,j)`. The former operation is lowered to
85+
4686
````
4787
%1 = Base.getindex(A, 1, 2)
4888
%2 = %1 + 3
4989
Base.setindex!(A, %2, 1, 2)
5090
````
91+
5192
triggering two index searches, one for `getindex!` and another one for `setindex!`.
5293

5394
See [Julia issue #15630](https://github.com/JuliaLang/julia/issues/15630) for a discussion on this.
5495

55-
56-
5796
## Factorizations and Preconditioners
97+
5898
The package provides a common API for factorizations and preconditioners supporting
5999
series of solutions of similar problem as they occur during nonlinear and transient solves.
60100
For details, see the [corresponding documentation](https://j-fu.github.io/ExtendableSparse.jl/stable/iter/).
61101

102+
With the advent of LinearSolve.jl, this functionality probably will be reduced to some core cases.
62103

63104
### Interfaces to other packages
64105

65-
Compatibility with [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) is under development.
66-
67-
The package provides interfaces to other sparse matrix solvers and preconditioners. Dependencies on these
106+
The package directly provides interfaces to other sparse matrix solvers and preconditioners. Dependencies on these
68107
packages are handeled via [Requires.jl](https://github.com/JuliaPackaging/Requires.jl).
69108
Currently, support includes:
70109

71-
- [Pardiso.jl](https://github.com/JuliaSparse/Pardiso.jl) (both ["project Pardiso"](https://pardiso-project.org)
72-
and [MKL Pardiso](https://software.intel.com/content/www/us/en/develop/documentation/onemkl-developer-reference-fortran/top/sparse-solver-routines/onemkl-pardiso-parallel-direct-sparse-solver-interface.html))
73-
- [IncompleteLU.jl](https://github.com/haampie/IncompleteLU.jl)
74-
- [AlgebraicMultigrid.jl](https://github.com/JuliaLinearAlgebra/AlgebraicMultigrid.jl) (Ruge-Stüben AMG)
110+
- [Pardiso.jl](https://github.com/JuliaSparse/Pardiso.jl) (both ["project Pardiso"](https://pardiso-project.org)
111+
and [MKL Pardiso](https://software.intel.com/content/www/us/en/develop/documentation/onemkl-developer-reference-fortran/top/sparse-solver-routines/onemkl-pardiso-parallel-direct-sparse-solver-interface.html))
112+
- [IncompleteLU.jl](https://github.com/haampie/IncompleteLU.jl)
113+
- [AlgebraicMultigrid.jl](https://github.com/JuliaLinearAlgebra/AlgebraicMultigrid.jl) (Ruge-Stüben AMG)
75114

76115
For a similar approach, see [Preconditioners.jl](https://github.com/mohamed82008/Preconditioners.jl)
77116

78117
## Alternatives
79118

80119
You may also evaluate alternatives to this package:
81120

82-
- [DynamicSparseArrays.jl](https://github.com/atoptima/DynamicSparseArrays.jl)
83-
121+
- [DynamicSparseArrays.jl](https://github.com/atoptima/DynamicSparseArrays.jl)

docs/Project.toml

+2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
55
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
66
DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8"
77
ExtendableSparse = "95c220a8-a1cf-11e9-0c77-dbfce5f500b3"
8+
ILUZero = "88f59080-6952-5380-9ea5-54057fb9a43f"
89
IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895"
910
IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
11+
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
1012
Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2"
1113
Sparspak = "e56a9233-b9d6-4f03-8d0f-1825330902ac"
1214

docs/make.jl

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
push!(LOAD_PATH,"../src/")
2-
using Documenter, ExtendableSparse,Pardiso,AlgebraicMultigrid,IncompleteLU,Sparspak
1+
push!(LOAD_PATH, "../src/")
2+
using Documenter, ExtendableSparse, Pardiso, AlgebraicMultigrid, IncompleteLU, Sparspak
33

44
function mkdocs()
5-
makedocs(sitename="ExtendableSparse.jl",
5+
makedocs(; sitename = "ExtendableSparse.jl",
66
modules = [ExtendableSparse],
77
doctest = true,
88
clean = false,
99
authors = "J. Fuhrmann",
10-
repo="https://github.com/j-fu/ExtendableSparse.jl",
11-
pages=[
12-
"Home"=>"index.md",
10+
repo = "https://github.com/j-fu/ExtendableSparse.jl",
11+
pages = [
12+
"Home" => "index.md",
1313
"example.md",
14+
"linearsolve.md",
1415
"extsparse.md",
1516
"iter.md",
16-
# "linearsolve.md",
1717
"internal.md",
1818
"changes.md",
1919
])
2020
end
2121

2222
mkdocs()
2323

24-
deploydocs(repo = "github.com/j-fu/ExtendableSparse.jl.git")
24+
deploydocs(; repo = "github.com/j-fu/ExtendableSparse.jl.git")

docs/src/changes.md

+75-41
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,101 @@
11
# Changes
2+
3+
## v0.9.6, Jan 22, 2023
4+
5+
- support for LinearSolve.jl
6+
7+
## v0.9.1 ... v0.9.5, Jan 5, 2023
8+
9+
- update interface with Sparspak
10+
- Addition, multiplication etc. for ExtendableSparse
11+
- ILUZero.jl as dependency for ILUZeroPreconditioner
12+
- fix ILU0Preconditioner backsubstitution for unsymmetric matrices
13+
- Add LinearAlgebra.lu etc. for ExtendableSparse
14+
215
## v0.9, Sept 28, 2022
3-
- `\` support for general number types and non-GPL system images based on Sparspak.jl 0.3.0
16+
17+
- `\` support for general number types and non-GPL system images based on Sparspak.jl 0.3.0
18+
419
## v0.8, Sept 1, 2022
5-
- Remove LinearSolve compatibility in favor of (future) interfacing via AbstractSparseMatrixCSC
6-
- Add Sparspak LU factorization
7-
- Add handling of GPL free sysimage build
20+
21+
- Remove LinearSolve compatibility in favor of (future) interfacing via AbstractSparseMatrixCSC
22+
- Add Sparspak LU factorization
23+
- Add handling of GPL free sysimage build
24+
825
## v0.7, August 19, 2022
9-
- Require Julia 1.6
10-
- first steps to compatibility with LinearSolve.jl
26+
27+
- Require Julia 1.6
28+
- first steps to compatibility with LinearSolve.jl
29+
1130
## v0.6, April 20, 2021
12-
- use type parameters to describe factorizations
31+
32+
- use type parameters to describe factorizations
33+
1334
## v0.5, April 10, 2021
14-
- Introduce lu/lu! , factorize/factorize!, unifying LU factorizations and preconditioners
15-
- Interface packages: Pardiso, AlgebraicMultigrid, IncompleteLU via Requires.jl
35+
36+
- Introduce lu/lu! , factorize/factorize!, unifying LU factorizations and preconditioners
37+
- Interface packages: Pardiso, AlgebraicMultigrid, IncompleteLU via Requires.jl
38+
1639
## v0.4, March 2021
17-
- Fix handling of Symmetrix matrices
18-
- `rawupdateindex` does not check for entering zeros
19-
- Compare with `COO` method
20-
- Benchmarks in documentation
40+
41+
- Fix handling of Symmetrix matrices
42+
- `rawupdateindex` does not check for entering zeros
43+
- Compare with `COO` method
44+
- Benchmarks in documentation
45+
2146
## v0.3.7, March 20, 2021
22-
- Added parallel jacobi preconditioner (thanks, @jkr)
23-
- Fixes ldiv
24-
- Added simple iterative solver
25-
- Documentation update
26-
- Tests for precondioners, fdrand
47+
48+
- Added parallel jacobi preconditioner (thanks, @jkr)
49+
- Fixes ldiv
50+
- Added simple iterative solver
51+
- Documentation update
52+
- Tests for precondioners, fdrand
2753

2854
## v0.3.0, April 10, 2020
29-
- Don't create new entry if the value to be assigned is zero, making things consistent with SparseMatrixCSC and ForwardDiff
30-
as suggested by @MaximilianJHuber
55+
56+
- Don't create new entry if the value to be assigned is zero, making things consistent with SparseMatrixCSC and ForwardDiff
57+
as suggested by @MaximilianJHuber
3158

3259
## v0.2.5, Jan 26, 2020
33-
- fixed allocations in Base.+
34-
- added updateindex! method
35-
- provide fdrand and fdrand! matrix constructors
36-
- automatic benchmarks in examples
60+
61+
- fixed allocations in Base.+
62+
- added updateindex! method
63+
- provide fdrand and fdrand! matrix constructors
64+
- automatic benchmarks in examples
3765

3866
## v0.2.4, Jan 19, 2020
39-
- Allow preconditioner creation directly from CSC Matrix
40-
- Rename AbstractPreconditioner to AbstractExtendablePreconditioner
67+
68+
- Allow preconditioner creation directly from CSC Matrix
69+
- Rename AbstractPreconditioner to AbstractExtendablePreconditioner
4170

4271
## v0.2.3, Jan 15, 2020
43-
- Started to introduce preconditioners (undocumented)
72+
73+
- Started to introduce preconditioners (undocumented)
4474

4575
## v0.2.3, Jan 8, 2020
46-
- added norm, cond, opnorm methods
47-
- resize! instead of push! when adding entries should trigger less allocation operations
76+
77+
- added norm, cond, opnorm methods
78+
- resize! instead of push! when adding entries should trigger less allocation operations
4879

4980
## v0.2.2. Dec 23, 2019
50-
- What used to be `_splice` is now `+` and allows now real addition (resulting in a CSC matrix)
51-
- Added constructors of LNK matrix from CSC matrix and vice versa
52-
- reorganized tests
81+
82+
- What used to be `_splice` is now `+` and allows now real addition (resulting in a CSC matrix)
83+
- Added constructors of LNK matrix from CSC matrix and vice versa
84+
- reorganized tests
5385

5486
## v0.2.1 Dec 22, 2019
55-
- Tried to track down the source from which I learned the linked list based struct in order
56-
to document this. Ended up with SPARSEKIT of Y.Saad, however I believe this
57-
already was in SPARSEPAK by Chu,George,Liu.
58-
- Internal rename of SparseMatrixExtension to SparseMatrixLNK.
87+
88+
- Tried to track down the source from which I learned the linked list based struct in order
89+
to document this. Ended up with SPARSEKIT of Y.Saad, however I believe this
90+
already was in SPARSEPAK by Chu,George,Liu.
91+
- Internal rename of SparseMatrixExtension to SparseMatrixLNK.
5992

6093
## v0.2 Dec 21, 2019
61-
- more interface methods delegating to csc, in particular mul! and ldiv!
62-
- lazy creation of extendable part: don't create idle memory
63-
- nicer constructors
64-
94+
95+
- more interface methods delegating to csc, in particular mul! and ldiv!
96+
- lazy creation of extendable part: don't create idle memory
97+
- nicer constructors
98+
6599
## V0.1, July 2019
66-
- Initial release
67100

101+
- Initial release

0 commit comments

Comments
 (0)