Skip to content

Commit 5d4e6ea

Browse files
committed
feat(matrices): add wathen
1 parent 702e54f commit 5d4e6ea

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

Diff for: src/matrices/index.jl

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export
4343
Sampling,
4444
Toeplitz,
4545
Triw,
46+
Wathen,
4647
Wilkinson
4748

4849
# include all matrices
@@ -86,6 +87,7 @@ include("rosser.jl")
8687
include("sampling.jl")
8788
include("toeplitz.jl")
8889
include("triw.jl")
90+
include("wathen.jl")
8991
include("wilkinson.jl")
9092

9193
# matrix groups
@@ -134,6 +136,7 @@ MATRIX_GROUPS[GROUP_BUILTIN] = Set([
134136
Sampling,
135137
Toeplitz,
136138
Triw,
139+
Wathen,
137140
Wilkinson
138141
])
139142
MATRIX_GROUPS[GROUP_USER] = Set([])

Diff for: src/matrices/wathen.jl

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using SparseArrays: sparse
2+
3+
"""
4+
Wathen Matrix
5+
=============
6+
Wathen Matrix is a sparse, symmetric positive, random matrix
7+
arose from the finite element method. The generated matrix is
8+
the consistent mass matrix for a regular nx-by-ny grid of
9+
8-nodes.
10+
11+
*Input options:*
12+
13+
+ [type,] nx, ny: the dimension of the matrix is equal to
14+
`3 * nx * ny + 2 * nx * ny + 1`.
15+
16+
+ [type,] n: `nx = ny = n`.
17+
18+
*Groups:* ["symmetric", "posdef", "eigen", "random", "sparse"]
19+
20+
*References:*
21+
22+
**A. J. Wathen**, Realistic eigenvalue bounds for
23+
the Galerkin mass matrix, IMA J. Numer. Anal., 7 (1987),
24+
pp. 449-457.
25+
"""
26+
struct Wathen{T<:Number} <: AbstractMatrix{T}
27+
nx::Integer
28+
ny::Integer
29+
M::AbstractMatrix{T}
30+
31+
function Wathen{T}(nx::Integer, ny::Integer) where {T<:Number}
32+
nx >= 0 || throw(ArgumentError("$nx < 0"))
33+
ny >= 0 || throw(ArgumentError("$ny < 0"))
34+
35+
# create matrix
36+
e1 = T[6 -6 2 -8; -6 32 -6 20; 2 -6 6 -6; -8 20 -6 32]
37+
e2 = T[3 -8 2 -6; -8 16 -8 20; 2 -8 3 -8; -6 20 -8 16]
38+
e3 = [e1 e2; e2' e1] / 45
39+
n = 3 * nx * ny + 2 * nx + 2 * ny + 1
40+
ntriplets = nx * ny * 64
41+
Irow = zeros(Int, ntriplets)
42+
Jrow = zeros(Int, ntriplets)
43+
Xrow = zeros(T, ntriplets)
44+
ntriplets = 0
45+
rho = 100 * rand(nx, ny)
46+
node = zeros(T, 8)
47+
48+
for j = 1:ny
49+
for i = 1:nx
50+
51+
node[1] = 3 * j * nx + 2 * i + 2 * j + 1
52+
node[2] = node[1] - 1
53+
node[3] = node[2] - 1
54+
node[4] = (3 * j - 1) * nx + 2 * j + i - 1
55+
node[5] = (3 * j - 3) * nx + 2 * j + 2 * i - 3
56+
node[6] = node[5] + 1
57+
node[7] = node[5] + 2
58+
node[8] = node[4] + 1
59+
60+
em = convert(T, rho[i, j]) * e3
61+
62+
for krow = 1:8
63+
for kcol = 1:8
64+
ntriplets += 1
65+
Irow[ntriplets] = node[krow]
66+
Jrow[ntriplets] = node[kcol]
67+
Xrow[ntriplets] = em[krow, kcol]
68+
end
69+
end
70+
71+
end
72+
end
73+
M = sparse(Irow, Jrow, Xrow, n, n)
74+
75+
return new{T}(nx, ny, M)
76+
end
77+
end
78+
79+
# constructors
80+
Wathen(n::Integer) = Wathen(n, n)
81+
Wathen(nx::Integer, ny::Integer) = Wathen{Float64}(nx, ny)
82+
Wathen{T}(n::Integer) where {T<:Number} = Wathen{T}(n, n)
83+
84+
# metadata
85+
@properties Wathen [:symmetric, :posdef, :eigen, :sparse, :random]
86+
87+
# properties
88+
size(A::Wathen) = size(A.M)
89+
LinearAlgebra.issymmetric(::Wathen) = true
90+
91+
# functions
92+
@inline Base.@propagate_inbounds function getindex(A::Wathen{T}, i::Integer, j::Integer) where {T}
93+
@boundscheck checkbounds(A, i, j)
94+
return A.M[i, j]
95+
end

0 commit comments

Comments
 (0)