|
1 | 1 | import AlgorithmsInterface as AI |
2 | 2 | import .AlgorithmsInterfaceExtensions as AIE |
3 | 3 |
|
4 | | -maybe_fill(value, len::Int) = fill(value, len) |
5 | | -function maybe_fill(v::AbstractVector, len::Int) |
6 | | - @assert length(v) == len |
7 | | - return v |
8 | | -end |
| 4 | +#= |
| 5 | + EigenProblem(operator) |
9 | 6 |
|
10 | | -function dmrg_sweep(operator, algorithm, state) |
11 | | - problem = select_problem(dmrg_sweep, operator, algorithm, state) |
12 | | - return AI.solve(problem, algorithm; iterate = state).iterate |
| 7 | +Represents the problem we are trying to solve and minimal algorithm-independent |
| 8 | +information, so for an eigenproblem it is the operator we want the eigenvector of. |
| 9 | +=# |
| 10 | +struct EigenProblem{Operator} <: AIE.Problem |
| 11 | + operator::Operator |
13 | 12 | end |
14 | | -function dmrg_sweep(operator, state; kwargs...) |
15 | | - algorithm = select_algorithm(dmrg_sweep, operator, state; kwargs...) |
16 | | - return dmrg_sweep(operator, algorithm, state) |
| 13 | + |
| 14 | +struct EigsolveRegion{R, Kwargs <: NamedTuple} <: AIE.NonIterativeAlgorithm |
| 15 | + region::R |
| 16 | + kwargs::Kwargs |
17 | 17 | end |
| 18 | +EigsolveRegion(region; kwargs...) = EigsolveRegion(region, (; kwargs...)) |
18 | 19 |
|
19 | | -function select_problem(::typeof(dmrg_sweep), operator, algorithm, state) |
20 | | - return EigenProblem(operator) |
| 20 | +function AI.solve!( |
| 21 | + problem::EigenProblem, algorithm::EigsolveRegion, state::AIE.State; kwargs... |
| 22 | + ) |
| 23 | + return error("EigsolveRegion step for EigenProblem not implemented yet.") |
21 | 24 | end |
22 | | -function select_algorithm(::typeof(dmrg_sweep), operator, state; regions, region_kwargs) |
23 | | - region_kwargs′ = maybe_fill(region_kwargs, length(regions)) |
24 | | - return Sweep(length(regions)) do i |
25 | | - return Returns(Region(regions[i]; region_kwargs′[i]...)) |
26 | | - end |
| 25 | + |
| 26 | +maybe_fill(value, len::Int) = fill(value, len) |
| 27 | +function maybe_fill(v::AbstractVector, len::Int) |
| 28 | + @assert length(v) == len |
| 29 | + return v |
27 | 30 | end |
28 | 31 |
|
29 | 32 | function dmrg(operator, algorithm, state) |
30 | | - problem = select_problem(dmrg, operator, algorithm, state) |
| 33 | + problem = EigenProblem(operator) |
31 | 34 | return AI.solve(problem, algorithm; iterate = state).iterate |
32 | 35 | end |
33 | 36 | function dmrg(operator, state; kwargs...) |
| 37 | + problem = EigenProblem(operator) |
34 | 38 | algorithm = select_algorithm(dmrg, operator, state; kwargs...) |
35 | | - return dmrg(operator, algorithm, state) |
| 39 | + return AI.solve(problem, algorithm; iterate = state).iterate |
36 | 40 | end |
37 | 41 |
|
38 | | -function select_problem(::typeof(dmrg), operator, algorithm, state) |
39 | | - return EigenProblem(operator) |
| 42 | +function repeat_last(v::AbstractVector, len::Int) |
| 43 | + length(v) ≥ len && return v |
| 44 | + return [v; fill(v[end], len - length(v))] |
40 | 45 | end |
41 | | -function select_algorithm(::typeof(dmrg), operator, state; nsweeps, regions, region_kwargs) |
42 | | - region_kwargs′ = maybe_fill(region_kwargs, nsweeps) |
43 | | - return Sweeping(nsweeps) do i |
44 | | - return select_algorithm( |
45 | | - dmrg_sweep, operator, state; |
46 | | - regions, region_kwargs = region_kwargs′[i], |
47 | | - ) |
48 | | - end |
| 46 | +repeat_last(v, len::Int) = fill(v, len) |
| 47 | +function extend_columns(nt::NamedTuple, len::Int) |
| 48 | + return NamedTuple{keys(nt)}(map(v -> repeat_last(v, len), values(nt))) |
49 | 49 | end |
50 | | - |
51 | | -#= |
52 | | - EigenProblem(operator) |
53 | | -
|
54 | | -Represents the problem we are trying to solve and minimal algorithm-independent |
55 | | -information, so for an eigenproblem it is the operator we want the eigenvector of. |
56 | | -=# |
57 | | -struct EigenProblem{Operator} <: AIE.Problem |
58 | | - operator::Operator |
| 50 | +function eachrow(nt::NamedTuple, len::Int) |
| 51 | + return [NamedTuple{keys(nt)}(map(v -> v[i], values(nt))) for i in 1:len] |
59 | 52 | end |
60 | 53 |
|
61 | | -function AI.step!(problem::EigenProblem, algorithm::Region, state::AIE.State; kwargs...) |
62 | | - return error("Region step for EigenProblem not implemented.") |
| 54 | +function select_algorithm(::typeof(dmrg), operator, state; nsweeps, regions, kwargs...) |
| 55 | + extended_kwargs = extend_columns((; kwargs...), nsweeps) |
| 56 | + region_kwargs = eachrow(extended_kwargs, nsweeps) |
| 57 | + return AIE.nested_algorithm(nsweeps) do i |
| 58 | + return AIE.nested_algorithm(length(regions)) do j |
| 59 | + return EigsolveRegion(regions[j]; region_kwargs[i]...) |
| 60 | + end |
| 61 | + end |
63 | 62 | end |
0 commit comments