Skip to content

Commit 8f851dd

Browse files
committed
added linear algebra tests and example
1 parent 39eabba commit 8f851dd

File tree

11 files changed

+113
-53
lines changed

11 files changed

+113
-53
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ language: julia
33
os:
44
- osx
55
- linux
6+
- windows
67

78
julia:
89
- 1.0

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ authors = ["Juergen Fuhrmann <juergen.fuhrmann@wias-berlin.de>"]
44
version = "0.1.3"
55

66
[deps]
7+
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
78
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
9+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
810
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
911
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
1012
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ExtendableSparse.jl
22

3-
[![Build Status](https://img.shields.io/travis/j-fu/ExtendableSparse.jl/master.svg?label=Linux+MacOSX)](https://travis-ci.org/j-fu/ExtendableSparse.jl)
3+
[![Build Status](https://img.shields.io/travis/j-fu/ExtendableSparse.jl/master.svg?label=Linux+MacOSX+Windows)](https://travis-ci.org/j-fu/ExtendableSparse.jl)
44
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://j-fu.github.io/ExtendableSparse.jl/stable)
55
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://j-fu.github.io/ExtendableSparse.jl/dev)
66

@@ -12,5 +12,4 @@ Without an intermediate data structure, efficient successive insertion/update of
1212

1313
`ExtendableSparseMatrix` is aimed to work as a drop-in replacement to `SparseMatrixCSC` in finite element and finite volume codes.
1414

15-
Currently it has the methods required for `AbstractSparseMatrix` (`getindex`, `setindex!`,`size`,`nnz`), as well as `lufact` and `mul!`, which is already sufficient for a number of interesting applications.
1615

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ makedocs(sitename="ExtendableSparse.jl",
99
repo="https://github.com/j-fu/ExtendableSparse.jl",
1010
pages=[
1111
"Home"=>"index.md",
12+
"example.md",
1213
"changes.md",
1314
"api.md"
1415
])

docs/src/changes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# Changes
2+
## dev
3+
- more interface methods delegating to csc, in particular mul! and ldiv!
4+
- lazy creation of extendable part: don't create idle memory
5+
- nicer constructors
26

37
## V0.1, July 2019
48

docs/src/example.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Examples
2+
3+
An `ExtendableSparseMatrix` can serve as a drop-in replacement for
4+
`SparseMatrixCSC`, albeit with faster assembly.
5+
6+
The code below provides a small benchmark example.
7+
```julia
8+
using ExtendableSparse
9+
using SparseArrays
10+
11+
function ext_create(n, row_nz)
12+
A=ExtendableSparseMatrix(n,n)
13+
sprand_sdd!(A,row_nz);
14+
end
15+
16+
function csc_create(n, row_nz)
17+
A=spzeros(n,n)
18+
sprand_sdd!(A,row_nz);
19+
end
20+
21+
csc_create(10,2);
22+
ext_create(10,2);
23+
n=65536
24+
row_nz=5
25+
@time Acsc=csc_create(n,row_nz);
26+
nnz(Acsc)
27+
@time Aext=ext_create(n,row_nz);
28+
nnz(Aext)
29+
b=rand(n);
30+
@time Acsc*(Acsc\b)b
31+
@time Aext*(Aext\b)b
32+
```
33+
34+
The function [`sprand_sdd!`](@ref) fills a
35+
sparse matrix with random entries such that it becomes strictly diagonally
36+
dominant and thus invertible and has a fixed number of nonzeros in
37+
its rows. Its bandwidth is bounded by 2*sqrt(n), therefore it
38+
resembles a typical matrix of a 2D piecewise linear FEM discretization.
39+
For filling a matrix a, the method conveniently albeit naively
40+
uses just `a[i,j]=value`. This approach is considerably faster with
41+
the [`ExtendableSparseMatrix`](@ref).
42+
43+

src/ExtendableSparse.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ include("extension.jl")
77
include("extendable.jl")
88
include("sprand.jl")
99

10-
export SparseMatrixExtension,ExtendableSparseMatrix,flush!,nnz,sprand!
10+
export SparseMatrixExtension,ExtendableSparseMatrix,flush!,nnz, sprand!,sprand_sdd!
1111

12-
export xcolptrs,colptrs
12+
export colptrs
1313
end # module

src/extendable.jl

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function ExtendableSparseMatrix(::Type{Tv},::Type{Ti},m::Integer, n::Integer) wh
3939
end
4040

4141
"""
42-
$(TYPEDSIGNATURES)
42+
$(SIGNATURES)
4343
4444
Create empty ExtendablSparseMatrix.
4545
This is a pendant to spzeros.
@@ -48,7 +48,7 @@ ExtendableSparseMatrix(::Type{Tv},m::Integer, n::Integer) where{Tv}=ExtendableSp
4848

4949

5050
"""
51-
$(TYPEDSIGNATURES)
51+
$(SIGNATURES)
5252
5353
Create empty ExtendablSparseMatrix.
5454
This is a pendant to spzeros.
@@ -69,7 +69,7 @@ end
6969

7070

7171
"""
72-
$(TYPEDSIGNATURES)
72+
$(SIGNATURES)
7373
7474
Return index corresponding to entry (i,j) in the array of nonzeros,
7575
if the entry exists, otherwise, return 0.
@@ -132,15 +132,15 @@ function Base.getindex(M::ExtendableSparseMatrix{Tv,Ti},i::Integer, j::Integer)
132132
end
133133

134134
"""
135-
$(TYPEDSIGNATURES)
135+
$(SIGNATURES)
136136
137137
Size of ExtendableSparseMatrix.
138138
"""
139139
Base.size(E::ExtendableSparseMatrix) = (E.cscmatrix.m, E.cscmatrix.n)
140140

141141

142142
"""
143-
$(TYPEDSIGNATURES)
143+
$(SIGNATURES)
144144
145145
Number of nonzeros of ExtendableSparseMatrix.
146146
"""
@@ -165,13 +165,12 @@ end
165165
Base.isless(x::ColEntry{Tv, Ti},y::ColEntry{Tv, Ti}) where {Tv,Ti<:Integer} = (x.i<y.i)
166166

167167

168+
# Create new CSC matrix with sorted entries from CSC matrix S and matrix extension E.
169+
#
170+
# This method assumes that there are no entries with the same
171+
# indices in E and S, therefore it appears too dangerous for general use and
172+
# so we don't export it. Generalizations appear to be possible, though.
168173
function _splice(E::SparseMatrixExtension{Tv,Ti},S::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti<:Integer}
169-
# Create new CSC matrix with sorted entries from CSC matrix S and matrix extension E.
170-
#
171-
# This method assumes that there are no entries with the same
172-
# indices in E and S, therefore it appears too dangerous for general use and
173-
# so we don't export it. Generalizations appear to be possible, though.
174-
175174
@assert(S.m==E.m)
176175
@assert(S.n==E.n)
177176

@@ -191,8 +190,8 @@ function _splice(E::SparseMatrixExtension{Tv,Ti},S::SparseMatrixCSC{Tv,Ti}) wher
191190
end
192191
E_maxcol=max(lcol,E_maxcol)
193192
end
194-
195-
# pre-allocate column
193+
194+
# pre-allocate column data
196195
col=[ColEntry{Tv,Ti}(0,0) for i=1:E_maxcol]
197196

198197

@@ -265,7 +264,7 @@ end
265264

266265

267266
"""
268-
$(TYPEDSIGNATURES)
267+
$(SIGNATURES)
269268
270269
Flush and delegate to cscmatrix.
271270
"""
@@ -276,9 +275,8 @@ end
276275

277276

278277

279-
280278
"""
281-
$(TYPEDSIGNATURES)
279+
$(SIGNATURES)
282280
283281
Flush and delegate to cscmatrix.
284282
"""
@@ -289,29 +287,18 @@ end
289287

290288

291289
"""
292-
$(TYPEDSIGNATURES)
293-
294-
Flush and delegate to cscmatrix.
295-
"""
296-
function xcolptrs(E::ExtendableSparseMatrix)
297-
@inbounds flush!(E)
298-
return E.cscmatrix.colptr
299-
end
300-
301-
302-
"""
303-
$(TYPEDSIGNATURES)
290+
$(SIGNATURES)
304291
305292
Flush and delegate to cscmatrix.
306293
"""
307294
function colptrs(E::ExtendableSparseMatrix)
308-
flush!(E)
295+
@inbounds flush!(E)
309296
return E.cscmatrix.colptr
310297
end
311298

312299

313300
"""
314-
$(TYPEDSIGNATURES)
301+
$(SIGNATURES)
315302
316303
Flush and delegate to cscmatrix.
317304
"""
@@ -322,7 +309,7 @@ end
322309

323310

324311
"""
325-
$(TYPEDSIGNATURES)
312+
$(SIGNATURES)
326313
327314
Delegating LU factorization.
328315
"""
@@ -332,7 +319,7 @@ function LinearAlgebra.lu(E::ExtendableSparseMatrix)
332319
end
333320

334321
"""
335-
$(TYPEDSIGNATURES)
322+
$(SIGNATURES)
336323
337324
Delegating Matrix multiplication
338325
"""
@@ -343,7 +330,7 @@ end
343330

344331

345332
"""
346-
$(TYPEDSIGNATURES)
333+
$(SIGNATURES)
347334
348335
Delegating Matrix ldiv
349336
"""
@@ -353,7 +340,7 @@ function LinearAlgebra.ldiv!(r::AbstractArray{T,1} where T, E::ExtendableSparse
353340
end
354341

355342
"""
356-
$(TYPEDSIGNATURES)
343+
$(SIGNATURES)
357344
358345
Delegating Matrix multiplication
359346
"""
@@ -364,7 +351,7 @@ end
364351

365352

366353
"""
367-
$(TYPEDSIGNATURES)
354+
$(SIGNATURES)
368355
369356
Delegating Matrix ldiv
370357
"""

src/extension.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ end
5858

5959

6060
"""
61-
$(TYPEDSIGNATURES)
61+
$(SIGNATURES)
6262
6363
Constructor of empty extension
6464
"""
@@ -142,23 +142,23 @@ end
142142

143143

144144
"""
145-
$(TYPEDSIGNATURES)
145+
$(SIGNATURES)
146146
147147
Return tuple containing size of the matrix.
148148
"""
149149
Base.size(E::SparseMatrixExtension) = (E.m, E.n)
150150

151151

152152
"""
153-
$(TYPEDSIGNATURES)
153+
$(SIGNATURES)
154154
155155
Return number of nonzero entries.
156156
"""
157157
SparseArrays.nnz(E::SparseMatrixExtension)=E.nnz
158158

159159

160160
"""
161-
$(TYPEDSIGNATURES)
161+
$(SIGNATURES)
162162
163163
Dummy flush! method for Sparse matrix extension. Just
164164
used in thest methods

src/sprand.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,37 @@ function sprand!(A::AbstractSparseMatrix{Tv,Ti},xnnz::Int) where {Tv,Ti}
1313
a=1.0+rand(Tv)
1414
A[i,j]+=a
1515
end
16+
A
17+
end
18+
19+
"""
20+
$(SIGNATURES)
21+
22+
Fill sparse matrix with random entries such that it becomes strictly diagonally
23+
dominant and thus invertible and has a fixed number of nonzeros in
24+
its rows. The matrix bandwidth is bounded by sqrt(n), therefore it
25+
resembles a typical matrix of a 2D piecewise linear FEM discretization
26+
27+
"""
28+
function sprand_sdd!(A::AbstractSparseMatrix{Tv,Ti},nnzrow::Int; dim=2) where {Tv,Ti}
29+
m,n=size(A)
30+
@assert m==n
31+
nnzrow=min(n,nnzrow)
32+
bandwidth=convert(Int,ceil(sqrt(n)))
33+
for i=1:n
34+
aii=0
35+
for k=1:nnzrow
36+
jmin=max(1,i-bandwidth)
37+
jmax=min(n,i+bandwidth)
38+
j=rand((jmin:jmax))
39+
if i!=j
40+
aij=rand()
41+
A[i,j]=aij
42+
aii+=abs(aij)
43+
end
44+
end
45+
A[i,i]=aii+rand() # make it strictly diagonally dominant
46+
end
47+
A
1648
end
1749

0 commit comments

Comments
 (0)