17 INTEGER,
PARAMETER :: nao = 5, nocc = 3, rank = 2
18 REAL(kind=
dp),
PARAMETER :: tolerance = 2.0e-14_dp
19 INTEGER :: i, selected_rank
20 REAL(kind=
dp) :: angle, common_shift, energy_gap, mu, window
21 REAL(kind=
dp),
DIMENSION(7) :: full_eigenvalues
22 REAL(kind=
dp),
DIMENSION(rank) :: eigenvalues
23 REAL(kind=
dp),
DIMENSION(nao, nao) :: complement_operator, &
24 complement_operator_rotated, hamiltonian, &
25 identity, overlap_inverse, projector, &
27 REAL(kind=
dp),
DIMENSION(nao, 2) :: occupied, occupied_rotated, vectors
28 REAL(kind=
dp),
DIMENSION(nao, nocc) :: gradient, gradient_rotated, result, &
30 REAL(kind=
dp),
DIMENSION(nocc, nocc) :: rotation
31 REAL(kind=
dp),
DIMENSION(2, 2) :: occupied_rotation
35 identity(i, i) = 1.0_dp
38 overlap_inverse = identity
39 overlap_inverse(1, 1) = 1.4_dp
40 overlap_inverse(2, 2) = 0.8_dp
41 overlap_inverse(1, 2) = 0.1_dp
42 overlap_inverse(2, 1) = 0.1_dp
45 vectors(3, 1) = 1.0_dp
46 vectors(4, 2) = 0.8_dp
47 vectors(5, 2) = 0.6_dp
48 eigenvalues = [0.35_dp, 0.8_dp]
53 gradient = reshape([0.2_dp, -0.1_dp, 0.4_dp, 0.3_dp, -0.2_dp, &
54 0.6_dp, 0.5_dp, -0.3_dp, 0.1_dp, 0.7_dp, &
55 -0.4_dp, 0.8_dp, 0.2_dp, -0.5_dp, 0.9_dp], [nao, nocc])
58 rotation(1, 1) = cos(angle)
59 rotation(1, 2) = -sin(angle)
60 rotation(2, 1) = sin(angle)
61 rotation(2, 2) = cos(angle)
62 rotation(3, 3) = 1.0_dp
63 gradient_rotated = matmul(gradient, rotation)
68 gradient_rotated, result_rotated)
69 IF (maxval(abs(result_rotated - matmul(result, rotation))) > tolerance)
THEN
70 error stop
"Low-rank preconditioner is not right-covariant under occupied rotations"
79 occupied_rotation = reshape([cos(angle), sin(angle), -sin(angle), cos(angle)], [2, 2])
80 occupied_rotated = matmul(occupied, occupied_rotation)
82 hamiltonian = reshape([1.0_dp, 0.2_dp, 0.1_dp, 0.0_dp, 0.3_dp, &
83 0.2_dp, 1.4_dp, 0.0_dp, 0.2_dp, 0.1_dp, &
84 0.1_dp, 0.0_dp, 2.0_dp, 0.4_dp, 0.2_dp, &
85 0.0_dp, 0.2_dp, 0.4_dp, 2.3_dp, 0.1_dp, &
86 0.3_dp, 0.1_dp, 0.2_dp, 0.1_dp, 3.0_dp], [nao, nao])
87 projector = identity - matmul(occupied, transpose(occupied))
88 projector_rotated = identity - matmul(occupied_rotated, transpose(occupied_rotated))
89 common_shift = -10.2_dp
90 complement_operator = matmul(transpose(projector), matmul(hamiltonian, projector)) + &
91 common_shift*matmul(occupied, transpose(occupied))
92 complement_operator_rotated = &
93 matmul(transpose(projector_rotated), matmul(hamiltonian, projector_rotated)) + &
94 common_shift*matmul(occupied_rotated, transpose(occupied_rotated))
95 IF (maxval(abs(complement_operator_rotated - complement_operator)) > tolerance)
THEN
96 error stop
"Complementary-state construction depends on the occupied orbital gauge"
99 full_eigenvalues = [-0.8_dp, -0.2_dp, 0.2_dp, 0.4_dp, 0.7_dp, 0.7_dp, 1.4_dp]
101 IF (selected_rank /= 2) error stop
"Rank cap split a degenerate complementary manifold"
103 IF (selected_rank /= 5) error stop
"Full complementary space did not retain its rank"
105 error stop
"Common-reference inverse weight differs from the spectral model"
program low_rank_preconditioner_unittest
Defines the basic variable types.
integer, parameter, public dp
Small algebraic helpers for the rotationally covariant low-rank OT preconditioner.
pure elemental real(kind=dp) function, public low_rank_inverse_weight(eigenvalue, reference, energy_gap)
Spectral inverse weight relative to a common occupied reference level.
pure subroutine, public apply_low_rank_dense(overlap_inverse, vectors, eigenvalues, reference, energy_gap, spectral_window, matrix_in, matrix_out)
Dense reference application used to verify right covariance under orbital rotations.
pure integer function, public low_rank_select_rank(eigenvalues, nocc, max_rank, degeneracy_tolerance)
Select a bounded spectral rank without cutting a degenerate boundary manifold.
Definition of mathematical constants and functions.
real(kind=dp), parameter, public sqrthalf