Skip to content

Commit 6e6491b

Browse files
committed
minor change
1 parent bdf5318 commit 6e6491b

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

test/grid.jl

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
function fine_ωGrid_test::Float, degree, ratio::Float) where {Float}
2+
############## use composite grid #############################################
3+
N = Int(floor(log(Λ) / log(ratio) + 1))
4+
5+
grid = CompositeGrid.LogDensedGrid(
6+
:cheb,# The top layer grid is :gauss, optimized for integration. For interpolation use :cheb
7+
[0.0, Λ],# The grid is defined on [0.0, β]
8+
[0.0,],# and is densed at 0.0 and β, as given by 2nd and 3rd parameter.
9+
N,# N of log grid
10+
Λ / ratio^(N - 1), # minimum interval length of log grid
11+
degree, # N of bottom layer
12+
Float
13+
)
14+
15+
return grid
16+
#return vcat(-grid[end:-1:1], grid)
17+
end
18+
19+
function fine_τGrid_test::Float,degree,ratio::Float) where {Float}
20+
############## use composite grid #############################################
21+
# Generating a log densed composite grid with LogDensedGrid()
22+
npo = Int(ceil(log(Λ) / log(ratio))) - 2 # subintervals on [0,1/2] in tau space (# subintervals on [0,1] is 2*npt)
23+
grid = CompositeGrid.LogDensedGrid(
24+
:gauss,# The top layer grid is :gauss, optimized for integration. For interpolation use :cheb
25+
[0.0, 1.0],# The grid is defined on [0.0, β]
26+
[0.0, 1.0],# and is densed at 0.0 and β, as given by 2nd and 3rd parameter.
27+
npo,# N of log grid
28+
0.5 / ratio^(npo-1), # minimum interval length of log grid
29+
degree, # N of bottom layer
30+
Float
31+
)
32+
#print(grid[1:length(grid)÷2+1])
33+
#print(grid+reverse(grid))
34+
# println("Composite expoential grid size: $(length(grid))")
35+
println("fine grid size: $(length(grid)) within [$(grid[1]), $(grid[end])]")
36+
return grid
37+
38+
end
39+
40+
@inline function A1(L::T) where {T}
41+
42+
return T(2 * expinti(-L) - 2 * expinti(-2 * L) - exp(-2 * L) * (exp(L) - 1)^2 / L)
43+
44+
end
45+
46+
@inline function A2(a::T, beta::T, L::T) where {T}
47+
48+
return T(expinti(-a * L) - expinti(-(a + beta) * L))
49+
#return T(-shi(a * L) + shi((a + 1) * L))
50+
end
51+
52+
"""
53+
``F(x, y) = (1-exp(x+y))/(x+y)``
54+
"""
55+
@inline function A3(a::T, b::T, L::T) where {T}
56+
lamb = (a + b) * L
57+
if abs(lamb) > Tiny
58+
return (1 - exp(-lamb)) / (a + b)
59+
else
60+
return T(L * (1 - lamb / 2.0 + lamb^2 / 6.0 - lamb^3 / 24.0))
61+
end
62+
end
63+
64+
function uni_ngrid( isFermi, Λ::Float) where {Float}
65+
ngrid = Float[]
66+
n = 0
67+
while (2n+1)*π<Λ
68+
append!(ngrid, n)
69+
n += 1
70+
end
71+
if isFermi
72+
return vcat(-ngrid[end:-1:1] .-1, ngrid)
73+
else
74+
return vcat(-ngrid[end:-1:2], ngrid)
75+
end
76+
end
77+
78+
function find_closest_indices(a, b)
79+
closest_indices = []
80+
for i in 1:length(b)
81+
min_diff = Inf
82+
closest_idx = 0
83+
for j in 1:length(a)
84+
diff = abs(a[j] - b[i])
85+
if diff < min_diff
86+
min_diff = diff
87+
closest_idx = j
88+
end
89+
end
90+
push!(closest_indices, closest_idx)
91+
end
92+
return closest_indices
93+
end
94+
95+
function Freq2Index(isFermi, ωnList)
96+
if isFermi
97+
# ωn=(2n+1)π
98+
return [Int(round((ωn / π - 1) / 2)) for ωn in ωnList]
99+
else
100+
# ωn=2nπ
101+
return [Int(round(ωn / π / 2)) for ωn in ωnList]
102+
end
103+
end
104+
function nGrid_test(isFermi, Λ::Float, degree, ratio::Float) where {Float}
105+
# generate n grid from a logarithmic fine grid
106+
np = Int(round(log(10*10 *10*Λ) / log(ratio)))
107+
xc = [(i - 1) / degree for i = 1:degree]
108+
panel = [ratio^(i - 1) - 1 for i = 1:(np+1)]
109+
nGrid = zeros(Int, np * degree)
110+
for i = 1:np
111+
a, b = panel[i], panel[i+1]
112+
nGrid[(i-1)*degree+1:i*degree] = Freq2Index(isFermi, a .+ (b - a) .* xc)
113+
end
114+
unique!(nGrid)
115+
#return nGrid
116+
if isFermi
117+
return vcat(-nGrid[end:-1:1] .-1, nGrid)
118+
else
119+
return vcat(-nGrid[end:-1:2], nGrid)
120+
end
121+
end
122+
123+
function find_indices_optimized(a, b)
124+
indices = []
125+
for i in 1:length(b)
126+
for j in 1:length(a)
127+
if abs(b[i] - a[j])<1e-16
128+
push!(indices, j)
129+
break
130+
end
131+
end
132+
end
133+
return indices
134+
end
135+
136+
function ωQR(kernel, rtol, print::Bool = true)
137+
# print && println(τ.grid[end], ", ", τ.panel[end])
138+
# print && println(ω.grid[end], ", ", ω.panel[end])
139+
################# find the rank ##############################
140+
"""
141+
For a given index k, decompose R=[R11, R12; 0, R22] where R11 is a k×k matrix.
142+
If R11 is well-conditioned, then
143+
σᵢ(R11) ≤ σᵢ(kernel) for 1≤i≤k, and
144+
σⱼ(kernel) ≤ σⱼ₋ₖ(R22) for k+1≤j≤N
145+
See Page 487 of the book: Golub, G.H. and Van Loan, C.F., 2013. Matrix computations. 4th. Johns Hopkins.
146+
Thus, the effective rank is defined as the minimal k that satisfy rtol≤ σ₁(R22)/σ₁(kernel)
147+
"""
148+
Nτ, Nω = size(kernel)
149+
150+
u, σ, v = svd(kernel)
151+
rank, err = 1, 0.0
152+
for (si, s) in enumerate(σ)
153+
# println(si, " => ", s / σ[1])
154+
if s / σ[1] < rtol
155+
rank = si - 1
156+
err = s[1] / σ[1]
157+
break
158+
end
159+
end
160+
print && println("Kernel ϵ-rank = ", rank, ", rtol ≈ ", err)
161+
162+
Q, R, p = qr(kernel, Val(true)) # julia qr has a strange design, Val(true) will do a pivot QR
163+
# size(R) == (Nτ, Nω) if Nω>Nτ
164+
# or size(R) == (Nω, Nω) if Nω<Nτ
165+
166+
for idx = rank:min(Nτ, Nω)
167+
if>
168+
R22 = R[idx:Nτ, idx:Nω]
169+
else
170+
R22 = R[idx:Nω, idx:Nω]
171+
end
172+
u2, s2, v2 = svd(R22)
173+
# println(idx, " => ", s2[1] / σ[1])
174+
if s2[1] / σ[1] < rtol
175+
rank = idx
176+
err = s2[1] / σ[1]
177+
break
178+
end
179+
end
180+
print && println("DLR rank = ", rank, ", rtol ≈ ", err)
181+
182+
# @assert err ≈ 4.58983288255442e-13
183+
184+
return p[1:rank]
185+
end

0 commit comments

Comments
 (0)