|
1 | 1 | # Examples |
2 | 2 |
|
3 | 3 |
|
4 | | -## Usage idea |
| 4 | +## Matrix creation |
5 | 5 | An `ExtendableSparseMatrix` can serve as a drop-in replacement for |
6 | | -`SparseMatrixCSC`, albeit with faster assembly. |
7 | | - |
| 6 | +`SparseMatrixCSC`, albeit with faster assembly during the buildup |
| 7 | +phase when using index based access. That means that code similar |
| 8 | +to the following example should be fast enough to avoid the assembly |
| 9 | +steps using the coordinate format: |
8 | 10 |
|
9 | | -```jldoctest |
10 | | -using ExtendableSparse |
11 | | -function example(n,bandwidth) |
12 | | - A=ExtendableSparseMatrix(n,n); |
13 | | - aii=0.0 |
14 | | - for i=1:n |
15 | | - for j=max(1,i-bandwidth):5:min(n,i+bandwidth) |
16 | | - aij=-rand() |
17 | | - A[i,j]=aij |
18 | | - aii+=abs(aij) |
19 | | - end |
20 | | - A[i,i]=aii+0.1 |
21 | | - end |
22 | | - b=rand(n) |
23 | | - x=A\b |
24 | | - A*x≈ b |
| 11 | +```@example |
| 12 | +using ExtendableSparse # hide |
| 13 | +n=3 |
| 14 | +A=ExtendableSparseMatrix(n,n) |
| 15 | +for i=1:n-1 |
| 16 | + A[i,i+1]=i |
25 | 17 | end |
26 | | -example(1000,100) |
27 | | -# output |
28 | | -true |
| 18 | +A |
29 | 19 | ``` |
30 | 20 |
|
31 | 21 |
|
32 | | -## Benchmark |
33 | | -The code below provides a small benchmark example. |
34 | | -```julia |
35 | | -using ExtendableSparse |
36 | | -using SparseArrays |
| 22 | +### Benchmark |
37 | 23 |
|
38 | | -function ext_create(n) |
39 | | - A=ExtendableSparseMatrix(n,n) |
40 | | - sprand_sdd!(A); |
41 | | -end |
| 24 | +The method [`fdrand`](@ref) creates a matrix similar to the discetization |
| 25 | +matrix of a Poisson equation on a d-dimensional cube. The code uses the index |
| 26 | +access API for the creation of the matrix. |
| 27 | +This approach is considerably faster with |
| 28 | +the [`ExtendableSparseMatrix`](@ref) which uses a linked list based |
| 29 | +structure [`SparseMatrixLNK`](@ref) to grab new entries. |
42 | 30 |
|
43 | | -function csc_create(n) |
44 | | - A=spzeros(n,n) |
45 | | - sprand_sdd!(A); |
46 | | -end |
47 | 31 |
|
48 | | -# Trigger JIT compilation before timing |
49 | | -csc_create(10); |
50 | | -ext_create(10); |
51 | | - |
52 | | -n=90000 |
53 | | -@time Acsc=csc_create(n); |
54 | | -nnz(Acsc) |
55 | | -@time Aext=ext_create(n); |
56 | | -nnz(Aext) |
57 | | -b=rand(n); |
58 | | -@time Acsc*(Acsc\b)≈b |
59 | | -@time Aext*(Aext\b)≈b |
| 32 | +```@example |
| 33 | +using ExtendableSparse # hide |
| 34 | +using SparseArrays # hide |
| 35 | +using BenchmarkTools # hide |
| 36 | +
|
| 37 | +@benchmark fdrand(30,30,30, matrixtype=ExtendableSparseMatrix); |
| 38 | +``` |
| 39 | + |
| 40 | +```@example |
| 41 | +using ExtendableSparse # hide |
| 42 | +using SparseArrays # hide |
| 43 | +using BenchmarkTools # hide |
| 44 | +
|
| 45 | +@benchmark fdrand(30,30,30, matrixtype=SparseMatrixCSC); |
| 46 | +``` |
| 47 | + |
| 48 | + |
| 49 | +## Matrix update |
| 50 | +For repeated calculations on the same sparsity structure (e.g. for time dependent |
| 51 | +problems or Newton iterations) it is convenient to skip all but the first creation steps |
| 52 | +and to just replace the values in the matrix after setting then elements of the `nzval` |
| 53 | +vector to zero. Typically in finite element and finite volume methods this step updates |
| 54 | +matrix entries (most of them several times) by adding values. In this case, the current indexing |
| 55 | +interface of Julia requires to access the matrix twice: |
| 56 | + |
| 57 | +```@example |
| 58 | +using SparseArrays # hide |
| 59 | +A=spzeros(3,3) |
| 60 | +Meta.@lower A[1,2]+=3 |
| 61 | +``` |
| 62 | +For sparse matrices this requires to the index search in the structure twice. |
| 63 | +The packages provides the method [`updateindex!`](@ref) for both `SparseMatrixCSC` and |
| 64 | +for `ExtendableSparse` which allows to update a matrix element with one index search. |
| 65 | + |
| 66 | + |
| 67 | +### Benchmark for `SparseMatrixCSC` |
| 68 | +```@example |
| 69 | +using ExtendableSparse # hide |
| 70 | +using SparseArrays # hide |
| 71 | +using BenchmarkTools # hide |
| 72 | +
|
| 73 | +A=fdrand(30,30,30, matrixtype=SparseMatrixCSC); |
| 74 | +@benchmark fdrand!(A,30,30,30, update=(A,v,i,j)-> A[i,j]+=v); |
| 75 | +``` |
| 76 | +```@example |
| 77 | +using ExtendableSparse # hide |
| 78 | +using SparseArrays # hide |
| 79 | +using BenchmarkTools # hide |
| 80 | +
|
| 81 | +A=fdrand(30,30,30, matrixtype=SparseMatrixCSC); |
| 82 | +@benchmark fdrand!(A,30,30,30, update=(A,v,i,j)-> updateindex!(A,+,v,i,j)); |
| 83 | +``` |
| 84 | + |
| 85 | +### Benchmark for `ExtendableSparseMatrix` |
| 86 | +```@example |
| 87 | +using ExtendableSparse # hide |
| 88 | +using BenchmarkTools # hide |
| 89 | +
|
| 90 | +A=fdrand(30,30,30, matrixtype=ExtendableSparseMatrix); |
| 91 | +@benchmark fdrand!(A,30,30,30, update=(A,v,i,j)-> A[i,j]+=v); |
| 92 | +``` |
| 93 | +```@example |
| 94 | +using ExtendableSparse # hide |
| 95 | +using BenchmarkTools # hide |
| 96 | +
|
| 97 | +A=fdrand(30,30,30, matrixtype=ExtendableSparseMatrix); |
| 98 | +@benchmark fdrand!(A,30,30,30, update=(A,v,i,j)-> updateindex!(A,+,v,i,j)); |
60 | 99 | ``` |
61 | 100 |
|
62 | | -The function [`sprand_sdd!`](@ref) fills a |
63 | | -sparse matrix with random entries such that it becomes strictly diagonally |
64 | | -dominant and thus invertible and has a fixed number of nonzeros in |
65 | | -its rows (similar to the method in the first example). Its bandwidth is bounded by 2*sqrt(n), therefore it |
66 | | -resembles a typical matrix of a 2D piecewise linear FEM discretization. |
67 | | -For filling a matrix a, the method conveniently albeit naively |
68 | | -uses just `a[i,j]=value`. This approach is considerably faster with |
69 | | -the [`ExtendableSparseMatrix`](@ref) which uses a linked list based |
70 | | -structure [`SparseMatrixLNK`](@ref) to grab new entries. |
71 | 101 |
|
| 102 | +Note that the update process for `ExtendableSparse` is slightly slower |
| 103 | +than for `SparseMatrixCSC` due to the overhead which comes from checking |
| 104 | +the presence of new entries. |
72 | 105 |
|
73 | 106 |
|
0 commit comments