Skip to content

Commit c7498e9

Browse files
committed
Fixes up symbolic integration, leaves only coefficient calculation
1 parent bc8599e commit c7498e9

File tree

1 file changed

+49
-61
lines changed

1 file changed

+49
-61
lines changed

src/Haar.jl

Lines changed: 49 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,25 @@ function cycle_structure(P::Ptr{gsl_permutation})
3838
end
3939

4040
#Returns a vector of indices (starting from 1 in the Julia convention)
41-
data(P::Ptr{gsl_permutation}) = [convert(Int64, x)+1 for x in pointer_to_array(permutation_data(P), (convert(Int64, permutation_size(P)) ,))]
41+
data(P::Ptr{gsl_permutation}) = [convert(Int64, x)+1 for x in
42+
pointer_to_array(permutation_data(P), (convert(Int64, permutation_size(P)) ,))]
4243

4344

4445
# In random matrix theory one often encounters expressions of the form
4546
#
46-
#X = trace(Q * A * Q' * B)
47+
#X = Q * A * Q' * B
4748
#
48-
#where A and B are deterministic matrices with fixed numerical matrix entries and Q is a random matrix that does not have explicitly defined matrix elements. Instead, one takes an expectation over of expressions of this form and this "integrates out" the Qs to produce a numeric result.
49+
#where A and B are deterministic matrices with fixed numerical matrix entries
50+
#and Q is a random matrix that does not have explicitly defined matrix
51+
#elements. Instead, one takes an expectation over of expressions of this form
52+
#and this "integrates out" the Qs to produce a numeric result.
4953
#
5054
#expectation(X) #= some number
5155
#
52-
#I'm curious how far one can implement, in Julia, a data type for Q and expectation() method for which expressions of this form can be written natively as code. This probably strays into the larger question of how much symbolic algebra can be written and handled in Julia, but I think this would be have real payoffs for making possible extremely elegant manipulations of random matrices that doesn't exist in any known computer language.
53-
#
54-
#Any thoughts on how feasible this is? Perhaps to begin with, it would be nice to have an expectation() that would work on arbitrary strings of products of matrices. Probably this would involve taking an input expression argument Would like to hear some stuff on t would be nice to start with just how one can write arbitrary products of matrices My initial thoughts are to declare Q::MyRandomMatrix with the type MyRandomMatrix<:AbstractMatrix and to write an expectation(Ex::Expr) function that at first blush traverses the expression Ex, finds a * that takes at least one MyRandomMatrix in its arguments and applies the appropriate substitution.
55-
#
56-
#So... 1) How feasible is this and 2) How do I traverse the expression in the way described in the previous paragraph? The "Metaprogramming" manual is somewhat sparse on this other than saying .args[], but that doesn't quite help
57-
56+
#Here is a function that symbolically calculates the expectation of a product
57+
#of matrices over the symmetric group that Q is uniform Haar over.
58+
#It takes an expression consisting of a product of matrices and replaces it
59+
#with an evaluated symbolic expression which is the expectation.
5860
function Expectation(X::Expr)
5961
if X.head != :call
6062
error(string("Unexpected type of expression: ", X.head))
@@ -75,20 +77,18 @@ function Expectation(X::Expr)
7577
MyQ=None
7678
for i=1:n
7779
thingy=X.args[i+1]
78-
if typeof(thingy)==Symbol
79-
matrixtype = typeof(eval(thingy))
80-
if matrixtype == HaarMatrix
80+
if isa(thingy, Symbol)
81+
if isa(eval(thingy), HaarMatrix)
8182
if MyQ==None MyQ=thingy end
8283
if MyQ == thingy
8384
Qidx=[Qidx; i]
8485
else
85-
println(string("only one instance of HaarMatrix supported, skipping the other guy ", thingy))
86-
end
86+
warning("only one instance of HaarMatrix supported, skipping the other guy ", thingy) end
8787
else
8888
Others = [Others; (thingy, i, i+1)]
8989
end
9090
println(i, ' ', thingy, "::", typeof(eval(thingy)))
91-
elseif typeof(thingy)==Expr
91+
elseif isa(thingy, Expr)
9292
println(i, ' ', thingy, "::Expr")
9393
if thingy.head==symbol('\'') && length(thingy.args)>=1 #Maybe this is a Q'
9494
if typeof(thingy.args[1])==Symbol && typeof(eval(thingy.args[1]))==HaarMatrix
@@ -100,7 +100,6 @@ function Expectation(X::Expr)
100100
error(string("Unexpected token ", thingy ," of type ", typeof(thingy)))
101101
end
102102
end
103-
104103
if length(Qidx) == length(Qpidx) == 0 return eval(X) end #nothing to do Haar-wise
105104
println(MyQ, " is in places ", Qidx)
106105
println(MyQ, "' is in places ", Qpidx)
@@ -112,9 +111,7 @@ function Expectation(X::Expr)
112111
##################################
113112
# Step 2. Enumerate permutations #
114113
##################################
115-
AllTerms = :(+(A*B))
116-
delete!(AllTerms.args, 2)
117-
println("BEGINS WITH ", AllTerms)
114+
AllTerms = {}
118115
for sigma in @task permutations_in_Sn(n)
119116
for tau in @task permutations_in_Sn(n)
120117
sigma_inv=permutation_inverse(sigma)
@@ -129,8 +126,8 @@ function Expectation(X::Expr)
129126
#Consolidate deltas
130127
Deltas=Dict()
131128
for i=1:n
132-
Deltas[Qr[i]] = Qpr[i]
133-
Deltas[Qidx[i]] = Qpidx[data(sigma)[i]]
129+
Deltas[Qr[i]] = Qpidx[data(sigma)[i]]
130+
Deltas[Qidx[i]] = Qpr[data(tau)[i]]
134131
end
135132
#Print deltas
136133
print("V(", cyclestruct, ") ")
@@ -142,7 +139,7 @@ function Expectation(X::Expr)
142139
end
143140
println()
144141
print("= V(", cyclestruct, ") ")
145-
#Substitute
142+
#Evaluate deltas over the indices of the other matrices
146143
ReindexedSymbols = []
147144
for (Symb, col_idx, row_idx) in Others
148145
new_col, new_row = col_idx, row_idx
@@ -152,13 +149,13 @@ function Expectation(X::Expr)
152149
ReindexedSymbols = [ReindexedSymbols; (Symb, new_col, new_row)]
153150
end
154151
println()
155-
println(ReindexedSymbols)
156-
println()
152+
#TODO Parse coefficient
153+
Coefficient = 1.0
157154
#Reconstruct expression
158155
println("START PARSING")
159-
Symb, left_idx, right_idx = delete!(ReindexedSymbols, length(ReindexedSymbols))
156+
println("The term is =", ReindexedSymbols[end])
157+
Symb, left_idx, right_idx = pop!(ReindexedSymbols)#, length(ReindexedSymbols))
160158
Expression={{{Symb}, left_idx, right_idx}}
161-
println("E =", Expression)
162159
while length(ReindexedSymbols) > 0
163160
pop_idx = expr_idx = do_transpose = is_left = nothing
164161
for expr_iter in enumerate(Expression)
@@ -197,55 +194,47 @@ function Expectation(X::Expr)
197194
end
198195
println("Terms left = ", ReindexedSymbols)
199196
if pop_idx == nothing #Found nothing, start new expression blob
200-
println("NEW EXPRBLOB: The term is =", ReindexedSymbols[1])
197+
println("New word: The term is ", ReindexedSymbols[1])
201198
Symb, left_idx, right_idx = delete!(ReindexedSymbols, 1)
202-
insert!(Expression, length(Expression)+1, {{Symb}, left_idx, right_idx})
199+
push!(Expression, {{Symb}, left_idx, right_idx})
203200
else #Found something
204-
println("The term is =", ReindexedSymbols[pop_idx])
201+
println("The term is =", ReindexedSymbols[pop_idx])
205202
Symb, col_idx, row_idx = delete!(ReindexedSymbols, pop_idx)
206203
Term = do_transpose ? Expr(symbol("'"), Symb) : Symb
207-
println(Expression[expr_idx])
208-
println(Expression[expr_idx][1])
209204
if is_left
210-
println("insert left")
211205
insert!(Expression[expr_idx][1], 1, Term)
212206
Expression[expr_idx][2] = do_transpose ? row_idx : col_idx
213207
else
214-
println("insert right")
215-
insert!(Expression[expr_idx][1],
216-
length(Expression[expr_idx][1])+1, Term)
208+
push!(Expression[expr_idx][1], Term)
217209
Expression[expr_idx][3] = do_transpose ? col_idx : row_idx
218210
end
219211
end
220-
println("E=",Expression)
221212
end
222213
println("DONE PARSING TREE")
223214

224215
# Evaluate closed cycles
225-
NewExpression=:(+(A*B))
226-
delete!(NewExpression.args, 2)
227-
println("HIHIHI", NewExpression.args)
228-
for ExprBlob in Expression
229-
if ExprBlob[2]==ExprBlob[3] #Have a cycle; this is a trace
230-
println(ExprBlob[1])
231-
ex=:(trace(A*B))
232-
println(ex.args[2].args)
233-
ex.args[2].args={:*; ExprBlob[1]...}
234-
println(ex)
235-
println(ex.args)
236-
insert!(NewExpression.args, length(NewExpression.args)+1, ex)
216+
NewExpression={}
217+
for ExprChunk in Expression
218+
ExprBlob, start_idx, end_idx = ExprChunk
219+
print(ExprChunk, " => ")
220+
if start_idx == end_idx #Have a cycle; this is a trace
221+
ex= length(ExprBlob)==1 ? :(trace($(ExprBlob[1]))) :
222+
Expr(:call, :trace, Expr(:call, :*, ExprBlob...))
237223
else #Not a cycle, regular chain of multiplications
238-
ex=:(A*B)
239-
ex.args={:*; ExprBlob[1]...}
240-
insert!(NewExpression.args, length(NewExpression.args)+1, ex)
224+
ex= length(ExprBlob)==1 ? ExprBlob[1] :
225+
Expr(:call, :*, ExprBlob...)
241226
end
227+
push!(NewExpression, ex)
228+
println(ex)
242229
end
243-
println("Final expression is ", NewExpression)
244-
insert!(AllTerms.args, length(AllTerms.args)+1, NewExpression)
230+
ex = Expr(:call, :*, Coefficient, NewExpression...)
231+
println("Final expression is: ", ex)
232+
push!(AllTerms, ex)
245233
end
246234
end
247-
println("THE ANSWER IS ", AllTerms)
248-
eval(AllTerms)
235+
X = length(AllTerms)==1 ? AllTerms[1] : Expr(:call, :+, AllTerms...)
236+
println("THE ANSWER IS ", X)
237+
eval(X)
249238
end
250239

251240

@@ -266,7 +255,6 @@ function part(n::Integer)
266255
end
267256

268257

269-
270258
###############
271259
# SANDBOX
272260
N=5
@@ -277,17 +265,17 @@ type HaarMatrix
277265
end
278266
Q = HaarMatrix(2)
279267

280-
281268
println("Case 1")
282269
println("E(A*B) = ", Expectation(:(A*B)))
283270
println("A*B/N = ", A*B)
284271

285272
println("Case 2")
286273
println("tr(A)*tr(B)/N = ", trace(A)*trace(B)/N)
287-
#println("E(A*Q*B*Q') = ", Expectation(:(A*Q*B*Q')))
274+
println(trace(B)*A)
275+
println("E(A*Q*B*Q') = ", Expectation(:(A*Q*B*Q')))
288276
println("E.tr(A*Q*B*Q') = ", trace(Expectation(:(A*Q*B*Q'))))
289277

290-
#println("Case 3")
291-
#println(Expectation(:(A*B)) == A*B)
292-
#println("E(A*Q*B*Q'*A*Q*B*Q') = ", Expectation(:(A*Q*B*Q'*A*Q*B*Q')))
278+
println("Case 3")
279+
println(Expectation(:(A*B)) == A*B)
280+
println("E(A*Q*B*Q'*A*Q*B*Q') = ", Expectation(:(A*Q*B*Q'*A*Q*B*Q')))
293281

0 commit comments

Comments
 (0)