Skip to content

Commit e2781a2

Browse files
committed
Allow vm and vn to be of different types
This is a proof-of-concept that in a problem Ax=b, the vector space of x (vn) can be different from the vector space of b (vm). This PR implements the actual change only for CGLS, but it could easily be extended to other solvers. Fixes #1037
1 parent fa7aef2 commit e2781a2

File tree

1 file changed

+52
-53
lines changed

1 file changed

+52
-53
lines changed

src/krylov_workspaces.jl

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ For rectangular problems (`m ≠ n`), use the second constructor with `vm` and `
3232
Empty vectors `vm_empty` and `vn_empty` reduce storage requirements when features such as warm-start or preconditioners are unused.
3333
These empty vectors will be replaced within a [`KrylovWorkspace`](@ref) only if required, such as when preconditioners are provided.
3434
"""
35-
struct KrylovConstructor{S}
36-
vm::S
37-
vn::S
38-
vm_empty::S
39-
vn_empty::S
35+
struct KrylovConstructor{Sm, Sn}
36+
vm::Sm
37+
vn::Sn
38+
vm_empty::Sm
39+
vn_empty::Sn
4040
end
4141

4242
function KrylovConstructor(vm; vm_empty=vm)
@@ -48,7 +48,7 @@ function KrylovConstructor(vm, vn; vm_empty=vm, vn_empty=vn)
4848
end
4949

5050
"Abstract type for using Krylov solvers in-place."
51-
abstract type KrylovWorkspace{T,FC,S} end
51+
abstract type KrylovWorkspace{T,FC,Sm,Sn} end
5252

5353
"""
5454
Workspace for the in-place method [`minres!`](@ref).
@@ -59,7 +59,7 @@ The following outer constructors can be used to initialize this workspace:
5959
workspace = MinresWorkspace(A, b; window = 5)
6060
workspace = MinresWorkspace(kc::KrylovConstructor; window = 5)
6161
"""
62-
mutable struct MinresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
62+
mutable struct MinresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
6363
m :: Int
6464
n :: Int
6565
Δx :: S
@@ -131,7 +131,7 @@ The following outer constructors can be used to initialize this workspace:
131131
workspace = MinaresWorkspace(A, b)
132132
workspace = MinaresWorkspace(kc::KrylovConstructor)
133133
"""
134-
mutable struct MinaresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
134+
mutable struct MinaresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
135135
m :: Int
136136
n :: Int
137137
Δx :: S
@@ -200,7 +200,7 @@ The following outer constructors can be used to initialize this workspace:
200200
workspace = CgWorkspace(A, b)
201201
workspace = CgWorkspace(kc::KrylovConstructor)
202202
"""
203-
mutable struct CgWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
203+
mutable struct CgWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
204204
m :: Int
205205
n :: Int
206206
Δx :: S
@@ -263,7 +263,7 @@ The following outer constructors can be used to initialize this workspace:
263263
workspace = CrWorkspace(A, b)
264264
workspace = CrWorkspace(kc::KrylovConstructor)
265265
"""
266-
mutable struct CrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
266+
mutable struct CrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
267267
m :: Int
268268
n :: Int
269269
Δx :: S
@@ -329,7 +329,7 @@ The following outer constructors can be used to initialize this workspace:
329329
workspace = CarWorkspace(A, b)
330330
workspace = CarWorkspace(kc::KrylovConstructor)
331331
"""
332-
mutable struct CarWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
332+
mutable struct CarWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
333333
m :: Int
334334
n :: Int
335335
Δx :: S
@@ -398,7 +398,7 @@ The following outer constructors can be used to initialize this workspace:
398398
workspace = SymmlqWorkspace(A, b)
399399
workspace = SymmlqWorkspace(kc::KrylovConstructor)
400400
"""
401-
mutable struct SymmlqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
401+
mutable struct SymmlqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
402402
m :: Int
403403
n :: Int
404404
Δx :: S
@@ -470,7 +470,7 @@ The following outer constructors can be used to initialize this workspace:
470470
workspace = CgLanczosWorkspace(A, b)
471471
workspace = CgLanczosWorkspace(kc::KrylovConstructor)
472472
"""
473-
mutable struct CgLanczosWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
473+
mutable struct CgLanczosWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
474474
m :: Int
475475
n :: Int
476476
Δx :: S
@@ -533,7 +533,7 @@ The following outer constructors can be used to initialize this workspace:
533533
workspace = CgLanczosShiftWorkspace(A, b, nshifts)
534534
workspace = CgLanczosShiftWorkspace(kc::KrylovConstructor, nshifts)
535535
"""
536-
mutable struct CgLanczosShiftWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
536+
mutable struct CgLanczosShiftWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
537537
m :: Int
538538
n :: Int
539539
nshifts :: Int
@@ -616,7 +616,7 @@ The following outer constructors can be used to initialize this workspace:
616616
workspace = MinresQlpWorkspace(A, b)
617617
workspace = MinresQlpWorkspace(kc::KrylovConstructor)
618618
"""
619-
mutable struct MinresQlpWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
619+
mutable struct MinresQlpWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
620620
m :: Int
621621
n :: Int
622622
Δx :: S
@@ -687,7 +687,7 @@ The following outer constructors can be used to initialize this workspace:
687687
688688
`memory` is set to `n` if the value given is larger than `n`.
689689
"""
690-
mutable struct DqgmresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
690+
mutable struct DqgmresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
691691
m :: Int
692692
n :: Int
693693
Δx :: S
@@ -763,7 +763,7 @@ The following outer constructors can be used to initialize this workspace:
763763
764764
`memory` is set to `n` if the value given is larger than `n`.
765765
"""
766-
mutable struct DiomWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
766+
mutable struct DiomWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
767767
m :: Int
768768
n :: Int
769769
Δx :: S
@@ -834,7 +834,7 @@ The following outer constructors can be used to initialize this workspace:
834834
workspace = UsymlqWorkspace(A, b)
835835
workspace = UsymlqWorkspace(kc::KrylovConstructor)
836836
"""
837-
mutable struct UsymlqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
837+
mutable struct UsymlqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
838838
m :: Int
839839
n :: Int
840840
uₖ₋₁ :: S
@@ -903,7 +903,7 @@ The following outer constructors can be used to initialize this workspace:
903903
workspace = UsymqrWorkspace(A, b)
904904
workspace = UsymqrWorkspace(kc::KrylovConstructor)
905905
"""
906-
mutable struct UsymqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
906+
mutable struct UsymqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
907907
m :: Int
908908
n :: Int
909909
vₖ₋₁ :: S
@@ -975,7 +975,7 @@ The following outer constructors can be used to initialize this workspace:
975975
workspace = TricgWorkspace(A, b)
976976
workspace = TricgWorkspace(kc::KrylovConstructor)
977977
"""
978-
mutable struct TricgWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
978+
mutable struct TricgWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
979979
m :: Int
980980
n :: Int
981981
y :: S
@@ -1065,7 +1065,7 @@ The following outer constructors can be used to initialize this workspace:
10651065
workspace = TrimrWorkspace(A, b)
10661066
workspace = TrimrWorkspace(kc::KrylovConstructor)
10671067
"""
1068-
mutable struct TrimrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1068+
mutable struct TrimrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
10691069
m :: Int
10701070
n :: Int
10711071
y :: S
@@ -1167,7 +1167,7 @@ The following outer constructors can be used to initialize this workspace:
11671167
workspace = TrilqrWorkspace(A, b)
11681168
workspace = TrilqrWorkspace(kc::KrylovConstructor)
11691169
"""
1170-
mutable struct TrilqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1170+
mutable struct TrilqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
11711171
m :: Int
11721172
n :: Int
11731173
uₖ₋₁ :: S
@@ -1248,7 +1248,7 @@ The following outer constructors can be used to initialize this workspace:s
12481248
workspace = CgsWorkspace(A, b)
12491249
workspace = CgsWorkspace(kc::KrylovConstructor)
12501250
"""
1251-
mutable struct CgsWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1251+
mutable struct CgsWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
12521252
m :: Int
12531253
n :: Int
12541254
Δx :: S
@@ -1317,7 +1317,7 @@ The following outer constructors can be used to initialize this workspace:
13171317
workspace = BicgstabWorkspace(A, b)
13181318
workspace = BicgstabWorkspace(kc::KrylovConstructor)
13191319
"""
1320-
mutable struct BicgstabWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1320+
mutable struct BicgstabWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
13211321
m :: Int
13221322
n :: Int
13231323
Δx :: S
@@ -1386,7 +1386,7 @@ The following outer constructors can be used to initialize this workspace:
13861386
workspace = BilqWorkspace(A, b)
13871387
workspace = BilqWorkspace(kc::KrylovConstructor)
13881388
"""
1389-
mutable struct BilqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1389+
mutable struct BilqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
13901390
m :: Int
13911391
n :: Int
13921392
uₖ₋₁ :: S
@@ -1461,7 +1461,7 @@ The following outer constructors can be used to initialize this workspace:
14611461
workspace = QmrWorkspace(A, b)
14621462
workspace = QmrWorkspace(kc::KrylovConstructor)
14631463
"""
1464-
mutable struct QmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1464+
mutable struct QmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
14651465
m :: Int
14661466
n :: Int
14671467
uₖ₋₁ :: S
@@ -1539,7 +1539,7 @@ The following outer constructors can be used to initialize this workspace:
15391539
workspace = BilqrWorkspace(A, b)
15401540
workspace = BilqrWorkspace(kc::KrylovConstructor)
15411541
"""
1542-
mutable struct BilqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1542+
mutable struct BilqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
15431543
m :: Int
15441544
n :: Int
15451545
uₖ₋₁ :: S
@@ -1620,21 +1620,20 @@ The following outer constructors can be used to initialize this workspace:
16201620
workspace = CglsWorkspace(A, b)
16211621
workspace = CglsWorkspace(kc::KrylovConstructor)
16221622
"""
1623-
mutable struct CglsWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1623+
mutable struct CglsWorkspace{T,FC,Sm,Sn} <: KrylovWorkspace{T,FC,Sm,Sn}
16241624
m :: Int
16251625
n :: Int
1626-
x :: S
1627-
p :: S
1628-
s :: S
1629-
r :: S
1630-
q :: S
1631-
Mr :: S
1626+
x :: Sn
1627+
p :: Sn
1628+
s :: Sn
1629+
r :: Sm
1630+
q :: Sm
1631+
Mr :: Sm
16321632
stats :: SimpleStats{T}
16331633
end
16341634

1635-
function CglsWorkspace(kc::KrylovConstructor)
1636-
S = typeof(kc.vm)
1637-
FC = eltype(S)
1635+
function CglsWorkspace(kc::KrylovConstructor{Sm,Sn}) where {Sm,Sn}
1636+
FC = promote_type(eltype(Sm), eltype(Sn))
16381637
T = real(FC)
16391638
m = length(kc.vm)
16401639
n = length(kc.vn)
@@ -1645,7 +1644,7 @@ function CglsWorkspace(kc::KrylovConstructor)
16451644
q = similar(kc.vm)
16461645
Mr = similar(kc.vm_empty)
16471646
stats = SimpleStats(0, false, false, false, 0, T[], T[], T[], 0.0, "unknown")
1648-
workspace = CglsWorkspace{T,FC,S}(m, n, x, p, s, r, q, Mr, stats)
1647+
workspace = CglsWorkspace{T,FC,Sm,Sn}(m, n, x, p, s, r, q, Mr, stats)
16491648
return workspace
16501649
end
16511650

@@ -1660,7 +1659,7 @@ function CglsWorkspace(m::Integer, n::Integer, S::Type)
16601659
Mr = S(undef, 0)
16611660
S = isconcretetype(S) ? S : typeof(x)
16621661
stats = SimpleStats(0, false, false, false, 0, T[], T[], T[], 0.0, "unknown")
1663-
workspace = CglsWorkspace{T,FC,S}(m, n, x, p, s, r, q, Mr, stats)
1662+
workspace = CglsWorkspace{T,FC,S,S}(m, n, x, p, s, r, q, Mr, stats)
16641663
return workspace
16651664
end
16661665

@@ -1679,7 +1678,7 @@ The following outer constructors can be used to initialize this workspace::
16791678
workspace = CglsLanczosShiftWorkspace(A, b, nshifts)
16801679
workspace = CglsLanczosShiftWorkspace(kc::KrylovConstructor, nshifts)
16811680
"""
1682-
mutable struct CglsLanczosShiftWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1681+
mutable struct CglsLanczosShiftWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
16831682
m :: Int
16841683
n :: Int
16851684
nshifts :: Int
@@ -1765,7 +1764,7 @@ The following outer constructors can be used to initialize this workspace:
17651764
workspace = CrlsWorkspace(A, b)
17661765
workspace = CrlsWorkspace(kc::KrylovConstructor)
17671766
"""
1768-
mutable struct CrlsWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1767+
mutable struct CrlsWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
17691768
m :: Int
17701769
n :: Int
17711770
x :: S
@@ -1830,7 +1829,7 @@ The following outer constructors can be used to initialize this workspace:
18301829
workspace = CgneWorkspace(A, b)
18311830
workspace = CgneWorkspace(kc::KrylovConstructor)
18321831
"""
1833-
mutable struct CgneWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1832+
mutable struct CgneWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
18341833
m :: Int
18351834
n :: Int
18361835
x :: S
@@ -1892,7 +1891,7 @@ The following outer constructors can be used to initialize this workspace:
18921891
workspace = CrmrWorkspace(A, b)
18931892
workspace = CrmrWorkspace(kc::KrylovConstructor)
18941893
"""
1895-
mutable struct CrmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1894+
mutable struct CrmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
18961895
m :: Int
18971896
n :: Int
18981897
x :: S
@@ -1954,7 +1953,7 @@ The following outer constructors can be used to initialize this workspace:
19541953
workspace = LslqWorkspace(A, b)
19551954
workspace = LslqWorkspace(kc::KrylovConstructor)
19561955
"""
1957-
mutable struct LslqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
1956+
mutable struct LslqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
19581957
m :: Int
19591958
n :: Int
19601959
x :: S
@@ -2022,7 +2021,7 @@ The following outer constructors can be used to initialize this workspace:
20222021
workspace = LsqrWorkspace(A, b)
20232022
workspace = LsqrWorkspace(kc::KrylovConstructor)
20242023
"""
2025-
mutable struct LsqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2024+
mutable struct LsqrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
20262025
m :: Int
20272026
n :: Int
20282027
x :: S
@@ -2090,7 +2089,7 @@ The following outer constructors can be used to initialize this workspace:
20902089
workspace = LsmrWorkspace(A, b)
20912090
workspace = LsmrWorkspace(kc::KrylovConstructor)
20922091
"""
2093-
mutable struct LsmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2092+
mutable struct LsmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
20942093
m :: Int
20952094
n :: Int
20962095
x :: S
@@ -2161,7 +2160,7 @@ The following outer constructors can be used to initialize this workspace:
21612160
workspace = LnlqWorkspace(A, b)
21622161
workspace = LnlqWorkspace(kc::KrylovConstructor)
21632162
"""
2164-
mutable struct LnlqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2163+
mutable struct LnlqWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
21652164
m :: Int
21662165
n :: Int
21672166
x :: S
@@ -2232,7 +2231,7 @@ The following outer constructors can be used to initialize this workspace:
22322231
workspace = CraigWorkspace(A, b)
22332232
workspace = CraigWorkspace(kc::KrylovConstructor)
22342233
"""
2235-
mutable struct CraigWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2234+
mutable struct CraigWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
22362235
m :: Int
22372236
n :: Int
22382237
x :: S
@@ -2303,7 +2302,7 @@ The following outer constructors can be used to initialize this workspace:
23032302
workspace = CraigmrWorkspace(A, b)
23042303
workspace = CraigmrWorkspace(kc::KrylovConstructor)
23052304
"""
2306-
mutable struct CraigmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2305+
mutable struct CraigmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
23072306
m :: Int
23082307
n :: Int
23092308
x :: S
@@ -2382,7 +2381,7 @@ The following outer constructors can be used to initialize this workspace:
23822381
23832382
`memory` is set to `n` if the value given is larger than `n`.
23842383
"""
2385-
mutable struct GmresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2384+
mutable struct GmresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
23862385
m :: Int
23872386
n :: Int
23882387
Δx :: S
@@ -2459,7 +2458,7 @@ The following outer constructors can be used to initialize this workspace:
24592458
24602459
`memory` is set to `n` if the value given is larger than `n`.
24612460
"""
2462-
mutable struct FgmresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2461+
mutable struct FgmresWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
24632462
m :: Int
24642463
n :: Int
24652464
Δx :: S
@@ -2536,7 +2535,7 @@ The following outer constructors can be used to initialize this workspace:
25362535
25372536
`memory` is set to `n` if the value given is larger than `n`.
25382537
"""
2539-
mutable struct FomWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2538+
mutable struct FomWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
25402539
m :: Int
25412540
n :: Int
25422541
Δx :: S
@@ -2609,7 +2608,7 @@ The following outer constructors can be used to initialize this workspace:
26092608
26102609
`memory` is set to `n + m` if the value given is larger than `n + m`.
26112610
"""
2612-
mutable struct GpmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S}
2611+
mutable struct GpmrWorkspace{T,FC,S} <: KrylovWorkspace{T,FC,S,S}
26132612
m :: Int
26142613
n :: Int
26152614
wA :: S

0 commit comments

Comments
 (0)