Skip to content

Commit 72c50cd

Browse files
committed
add ginibre ensemble integration
1 parent cd02717 commit 72c50cd

6 files changed

Lines changed: 695 additions & 1 deletion

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using IntU
2+
using Symbolics
3+
using LinearAlgebra
4+
using BenchmarkTools
5+
import LinearAlgebra: tr
6+
7+
function benchmark_ginibre(N_vals, powers)
8+
println("=== GinUE Benchmarks (Explicit Matrix) ===")
9+
for N in N_vals
10+
println("N = $N")
11+
G = [Symbolics.variable(:G, i, j, T=Complex{Num}) for i = 1:N, j = 1:N]
12+
meas = dGinUE(G, N)
13+
for p in powers
14+
expr = tr(G * G')^p
15+
println(" <Tr(G G')^$p>")
16+
t = @benchmark integrate($expr, $meas)
17+
display(t)
18+
println()
19+
end
20+
end
21+
22+
println("\n=== GinUE Benchmarks (Symbolic Dimension) ===")
23+
@variables d
24+
Gs = SymbolicMatrix(:G)
25+
meas_s = dGinUE(Gs, d)
26+
for p in powers
27+
# For LazyTrace, it's tr(G G')^p
28+
expr = tr_lazy(Gs * Gs')^p
29+
println(" <Tr(G G')^$p> (Symbolic d)")
30+
t = @benchmark integrate($expr, $meas_s)
31+
display(t)
32+
println()
33+
end
34+
end
35+
36+
println("=== Ginibre Ensembles Benchmark ===")
37+
benchmark_ginibre([2, 4], [1, 2])

examples/20_ginibre_ensembles.jl

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using IntU
2+
using Symbolics
3+
using LinearAlgebra
4+
import LinearAlgebra: tr
5+
6+
println("=== Ginibre Ensembles Integration Examples ===\n")
7+
8+
# --- 1. Complex Ginibre (GinUE) ---
9+
println("1. Complex Ginibre Ensemble (GinUE)")
10+
N = 2
11+
# Specification of T=Complex{Num} is important for GinUE to ensure conj(G) != G
12+
G = [Symbolics.variable(:G, i, j, T=Complex{Num}) for i = 1:N, j = 1:N]
13+
meas_ginue = dGinUE(G, N)
14+
15+
println("--- Basic Moments ---")
16+
# <Tr(G G')> = N^2
17+
res_sq = simplify(integrate(tr(G * G'), meas_ginue))
18+
println("<Tr(G G')> = ", res_sq, " (Expected: $(N^2))")
19+
20+
# <Tr(G G' G G')> = N^4 + N^2 (for GinUE)
21+
# Wait, for GinUE <G_ij conj(G_kl)> = delta_ik delta_jl.
22+
# Tr(G G' G G') = G_ij conj(G_kj) G_kl conj(G_il)
23+
# Contractions:
24+
# 1. (ij, kj) and (kl, il) -> delta_ik delta_jj * delta_ki delta_ll = N * N = N^2? No.
25+
# Actually for GUE <Tr(H^4)> = 2N^3 + N. GinUE is different as it's not Hermitian.
26+
res_fourth = simplify(integrate(tr(G * G' * G * G'), meas_ginue))
27+
println("<Tr(G G' G G')> = ", res_fourth)
28+
29+
# --- 2. Real Ginibre (GinOE) ---
30+
println("\n2. Real Ginibre Ensemble (GinOE)")
31+
# entries are real, so G_ij is Hermitian to itself
32+
G_real = [Symbolics.variable(:G_r, i, j) for i = 1:N, j = 1:N]
33+
meas_ginoe = dGinOE(G_real, N)
34+
35+
# <Tr(G G^T)> = N^2
36+
res_oe_sq = simplify(integrate(tr(G_real * transpose(G_real)), meas_ginoe))
37+
println("<Tr(G G^T)> = ", res_oe_sq, " (Expected: $(N^2))")
38+
39+
# --- 3. Graphical Calculus (Symbolic Dimension) ---
40+
println("\n3. Graphical Calculus and Symbolic Dimension")
41+
@variables d
42+
Gs = SymbolicMatrix(:G)
43+
meas_s = dGinUE(Gs, d)
44+
45+
# <Tr(G G' G G')> with symbolic d
46+
t = tr_lazy(Gs * Gs' * Gs * Gs')
47+
res_s = simplify(integrate(t, meas_s))
48+
println("<Tr(G G' G G')>_GinUE = ", res_s)
49+
50+
# Coordinate-free matrix integration using SymbolicMatrix for A and B
51+
println("\n--- Coordinate-free Symbolic Matrix Integration ---")
52+
As = SymbolicMatrix(:A)
53+
Bs = SymbolicMatrix(:B)
54+
# <Tr(G A G' B)> = Tr(A) * Tr(B)
55+
t2 = tr_lazy(Gs * As * Gs' * Bs)
56+
res_t2 = simplify(integrate(t2, meas_s))
57+
println("<Tr(G A G' B)> = ", res_t2, " (Should be tr(A)*tr(B))")
58+
59+
# Matrix Integration
60+
println("\n4. Matrix Integrals (Numerical A, B)")
61+
A = [1 0; 0 2]
62+
B = [1 1; 1 1]
63+
# < G A G' B > = Tr(A) B
64+
res_mat = integrate(G * A * G' * B, meas_ginue)
65+
println("< G A G' B > = ")
66+
display(map(simplify, res_mat))
67+
68+
# Symbolic A and B using Array Variables (avoids separate entries)
69+
println("\n5. Matrix Integrals with Symbolic Array Variables")
70+
# Use Matrix{Num} to ensure standard indexing works
71+
As = [Symbolics.variable(:A, i, j) for i = 1:N, j = 1:N]
72+
Bs = [Symbolics.variable(:B, i, j) for i = 1:N, j = 1:N]
73+
res_sym = integrate(G * As * G' * Bs, meas_ginue)
74+
println("< G As G' Bs > = ")
75+
display(map(simplify, res_sym))
76+
77+
# Verification
78+
expected_sym = tr(As) * Bs
79+
is_correct = all(i -> IntU._symbolic_isequal(simplify(res_sym[i]), simplify(expected_sym[i])), eachindex(res_sym))
80+
println("\nMatches Tr(A)*B: ", is_correct)
81+
82+
println("\nDone.")

src/IntU.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export integrate,
5252
dGUE,
5353
dGOE,
5454
dGSE,
55+
dGinUE,
56+
dGinOE,
57+
dGinSE,
5558
dDiagUnitary,
5659
dStiefel,
5760
integrate_indices,

0 commit comments

Comments
 (0)