Wed, 22 Dec 2021 11:13:38 +0200
Planar finite elements, simple linear solvers for fixed dimensions
37
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
1 | """ |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
2 | Linear solvers for small problems. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
3 | """ |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
4 | module LinSolve |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
5 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
6 | using ..Metaprogramming |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
7 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
8 | export linsolve, |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
9 | TupleMatrix |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
10 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
11 | const TupleMatrix{M,N} = NTuple{M, NTuple{N, Float64}} |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
12 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
13 | """ |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
14 | `linsolve(AB :: TupleMatrix{M,N}, :: Type{TupleMatrix{M, K}}) :: TupleMatrix{M, K}` |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
15 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
16 | where |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
17 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
18 | `TupleMatrix{M, N} = NTuple{M, NTuple{N, Float64}}` |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
19 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
20 | “Immutable” Gaussian elimination on tuples: solve AX=B for X, |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
21 | Both A and B are stored in AB. The second type parameter indicates the size of B. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
22 | """ |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
23 | @polly function linsolve₀(AB :: TupleMatrix{M,N}, :: Val{K}) :: TupleMatrix{M, K} where {N,M,K} |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
24 | @assert(M == N - K) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
25 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
26 | k = 0 |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
27 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
28 | # Convert to row-echelon form |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
29 | for h = 1:(M-1) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
30 | # Find pivotable column (has some non-zero entries in rows ≥ h) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
31 | v = 0.0 |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
32 | î = h |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
33 | while k ≤ N-1 && v == 0 |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
34 | k = k + 1 |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
35 | v = abs(AB[h][k]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
36 | # Find row ≥ h of maximum absolute value in this column |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
37 | for i=(h+1):M |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
38 | local v′ = abs(AB[i][k]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
39 | if v′ > v |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
40 | î = i |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
41 | v = v′ |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
42 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
43 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
44 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
45 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
46 | if v > 0 |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
47 | AB = ( |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
48 | AB[1:(h-1)]..., |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
49 | AB[î], |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
50 | (let ĩ = (i==î ? h : i), h̃ = î, f = AB[ĩ][k] / AB[h̃][k] |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
51 | ((0.0 for _ = 1:k)..., (AB[ĩ][j]-AB[h̃][j]*f for j = (k+1):N)...,) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
52 | end for i = (h+1):M)... |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
53 | ) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
54 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
55 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
56 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
57 | # Solve UAX=UB for X where UA with U presenting the transformations above an |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
58 | # upper triangular matrix. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
59 | X = () |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
60 | for i=M:-1:1 |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
61 | r = .+(AB[i][M+1:end], (-AB[i][j].*X[j-i] for j=i+1:M)...)./AB[i][i] |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
62 | X = (r, X...) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
63 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
64 | return X |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
65 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
66 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
67 | @inline function linsolve₀(AB :: TupleMatrix{M,N}) :: NTuple{M,Float64} where {N,M} |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
68 | X = linsolve₀(AB, Val(1)) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
69 | return ((x for (x,) ∈ X)...,) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
70 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
71 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
72 | #@generated function linsolve₁(AB :: TupleMatrix{M,N}, :: Type{TupleMatrix{M, K}}) :: TupleMatrix{M, K} where {N,M,K} |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
73 | function generate_linsolve(AB :: Symbol, M :: Int, N :: Int, K :: Int) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
74 | @assert(M == N - K) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
75 | # The variables of ABN collect the stepwise stages of the transformed matrix. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
76 | # Initial i-1 entries of ABN[i] are never used, as the previous steps have already |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
77 | # finalised the corresponding rows, but are included as “missing” (at compile time) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
78 | # for the sake of indexing clarity. The M-1:th row-wise step finalises the row-echelon |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
79 | # form, so ABN has M-1 rows itself. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
80 | step_ABN(step) = ((missing for i=1:step-1)..., |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
81 | (gensym("ABN_$(step)_$(i)") for i ∈ step:M)...,) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
82 | ABN = ((step_ABN(step) for step=1:M-1)...,) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
83 | # UAB “diagonally” refers to ABN to collate the final rows of the transformed matrix UAB. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
84 | # Since the M-1:th row-wise step finalises the row-echelon form, the last row comes already |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
85 | # from the M-1:th step. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
86 | UAB = ((ABN[i][i] for i=1:M-1)..., ABN[M-1][M]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
87 | # The variables of X collect the rows of the solution to AX=B. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
88 | X = ((gensym("X_$(i)") for i ∈ 1:M)...,) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
89 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
90 | # Convert to row-echelon form. On each step we strip leading zeroes from ABN. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
91 | # In the end UAB should be upper-triangular. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
92 | convert_row(ABNout, h, ABNin) = quote |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
93 | # Find pivotable column (has some non-zero entries in rows ≥ h) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
94 | $(ABNout[h]) = $(ABNin[h]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
95 | local v = abs($(ABNout[h])[1]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
96 | # Find row ≥ h of maximum absolute value in this column |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
97 | $(sequence_exprs(:( |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
98 | let v′ = abs($(ABNin[i])[1]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
99 | if v′ > v |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
100 | $(ABNout[h]), $(ABNin[i]) = $(ABNin[i]), $(ABNout[h]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
101 | v = v′ |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
102 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
103 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
104 | ) for i=(h+1):M)) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
105 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
106 | $(lift_exprs(ABNout[h+1:M])) = v > 0 ? ( $(lift_exprs( :( |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
107 | # Transform |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
108 | $(ABNin[i])[2:$N-$h+1] .- $(ABNout[h])[2:$N-$h+1].*( $(ABNin[i])[1] / $(ABNout[h])[1]) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
109 | ) for i=h+1:M)) ) : ( $(lift_exprs( :( |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
110 | # Strip leading zeroes |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
111 | $(ABNin[i])[2:$N-$h+1] |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
112 | ) for i=h+1:M)) ) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
113 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
114 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
115 | # Solve UAX=UB for X where UA with U presenting the transformations above an |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
116 | # upper triangular matrix. |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
117 | solve_row(UAB, i) = :( |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
118 | $(X[i]) = $(lift_exprs( :( |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
119 | +($(UAB[i])[$M-$i+1+$k], $(( :( -$(UAB[i])[$j-$i+1]*$(X[j])[$k] ) for j=i+1:M)...)) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
120 | ) for k=1:K )) ./ $(UAB[i])[1] |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
121 | ) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
122 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
123 | return X, quote |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
124 | $(lift_exprs(ABN[1][i] for i=1:M)) = $(lift_exprs( :( $AB[$i] ) for i=1:M)) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
125 | $(convert_row(ABN[1], 1, ABN[1])) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
126 | $((convert_row(ABN[h], h, ABN[h-1]) for h = 2:(M-1))...) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
127 | $((solve_row(UAB, i) for i=M:-1:1)...) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
128 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
129 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
130 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
131 | @inline @generated function linsolve₁(AB :: TupleMatrix{M,N}, :: Val{K}) :: TupleMatrix{M, K} where {N,M,K} |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
132 | X, solver = generate_linsolve(:AB, M, N, K) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
133 | return quote |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
134 | $solver |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
135 | return $(lift_exprs( X[i] for i=1:M )) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
136 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
137 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
138 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
139 | @inline @generated function linsolve₁(AB :: TupleMatrix{M,N}) :: NTuple{M,Float64} where {N,M} |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
140 | X, solver = generate_linsolve(:AB, M, N, 1) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
141 | return quote |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
142 | $solver |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
143 | return $(lift_exprs( :( $(X[i])[1] ) for i=1:M )) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
144 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
145 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
146 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
147 | const linsolve = linsolve₁ |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
148 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
149 | function tuplify(M, N, A, b) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
150 | ((((A[i][j] for j=1:N)..., b[j]) for i=1:M)...,) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
151 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
152 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
153 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
154 | function compare(; dim=5, n_matrices=10000, n_testvectors=100) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
155 | testmatrices=[] |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
156 | testvectors=[] |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
157 | while length(testmatrices)<n_matrices |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
158 | A=randn(dim, dim) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
159 | push!(testmatrices, A) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
160 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
161 | test_vectors=[randn(dim) for _ = 1:n_testvectors] |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
162 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
163 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
164 | function evaluate(fn) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
165 | for A ∈ testmatrices |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
166 | for b ∈ testvectors |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
167 | fn(A, b) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
168 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
169 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
170 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
171 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
172 | function evaluate_and_report(fn, name) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
173 | printstyled("Evaluating $name…\n", color=:cyan) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
174 | @time evaluate(fn) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
175 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
176 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
177 | evaluate_and_report("tuple-linsolve, ungenerated") do A, b |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
178 | linsolve₀(tuplify(A, b)) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
179 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
180 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
181 | evaluate_and_report("tuple-linsolve, generated") do A, b |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
182 | linsolve₁(tuplify(A, b)) |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
183 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
184 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
185 | evaluate_and_report("backslash") do A, b |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
186 | A \ b |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
187 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
188 | end |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
189 | |
f8be66557e0f
Planar finite elements, simple linear solvers for fixed dimensions
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
190 | end # module |