1
+ function partialchol (H:: Hankel )
2
+ # Assumes positive definite
3
+ σ= Array (eltype (H),0 )
4
+ n= size (H,1 )
5
+ C= Array (eltype (H),n,n)
6
+ v= [H[:,1 ];vec (H[end ,2 : end ])]
7
+ d= diag (H)
8
+
9
+ @assert length (v) ≥ 2 n- 1
10
+
11
+ tol= 1E-14
12
+ for k= 1 : n
13
+ mx,idx= findmax (d)
14
+ if mx ≤ tol
15
+ break
16
+ end
17
+ push! (σ,1 / mx)
18
+ @simd for p= 1 : n
19
+ @inbounds C[p,k]= v[p+ idx- 1 ] # H[p,idx]
20
+ end
21
+ for j= 1 : k- 1 ,p= 1 : n
22
+ @inbounds C[p,k]-= C[p,j]* C[idx,j]* σ[j]
23
+ end
24
+ @simd for p= 1 : n
25
+ @inbounds d[p]-= C[p,k]^ 2 / mx
26
+ end
27
+ end
28
+ for k= 1 : length (σ),p= 1 : n
29
+ @inbounds C[p,k]*= sqrt (σ[k])
30
+ end
31
+ C[:,1 : length (σ)]
32
+ end
33
+
34
+ function toeplitzcholmult (T,C,v)
35
+ ret= C[:,1 ]. * (T* (C[:,1 ]. * v))
36
+ for j= 2 : size (C,2 )
37
+ ret+= C[:,j]. * (T* (C[:,j]. * v))
38
+ end
39
+ ret
40
+ end
41
+
42
+
43
+ # Plan a multiply by DL*(T.*H)*DR
44
+ immutable ToepltizHankelPlan{T}
45
+ T:: TriangularToeplitz{T}
46
+ C:: Matrix{T} # A cholesky factorization of H: H=CC'
47
+ DL:: Vector{T}
48
+ DR:: Vector{T}
49
+ end
50
+
51
+ ToepltizHankelPlan (T:: TriangularToeplitz ,C:: Matrix )= ToepltizHankelPlan (T,C,ones (size (T,1 )),ones (size (T,2 )))
52
+ ToepltizHankelPlan (T:: TriangularToeplitz ,H:: Hankel ,D... )= ToepltizHankelPlan (T,partialchol (H),D... )
53
+
54
+ * (P:: ToepltizHankelPlan ,v:: Vector )= P. DL.* toeplitzcholmult (P. T,P. C,P. DR.* v)
55
+
56
+
57
+
58
+ # Legendre transforms
59
+
60
+
61
+ Λ {T} (:: Type{T} ,z)= z< 5 ?gamma (z+ one (T)/ 2 )/ gamma (z+ one (T)): exp (lgamma (z+ one (T)/ 2 )- lgamma (z+ one (T)))
62
+
63
+ # use recurrence to construct Λ fast on a range of values
64
+ function Λ {T} (:: Type{T} ,r:: UnitRange )
65
+ n= length (r)
66
+ ret= Array (T,n)
67
+ ret[1 ]= Λ (T,r[1 ])
68
+ for k= 2 : n
69
+ ret[k]= ret[k- 1 ]* (r[k- 1 ]+ one (T)/ 2 )/ r[k]
70
+ end
71
+ ret
72
+ end
73
+
74
+ function Λ {T} (:: Type{T} ,r:: FloatRange )
75
+ @assert step (r)== 0.5
76
+ n= length (r)
77
+ ret= Array (T,n)
78
+ ret[1 ]= Λ (T,r[1 ])
79
+ ret[2 ]= Λ (T,r[2 ])
80
+ for k= 3 : n
81
+ ret[k]= ret[k- 2 ]* (r[k- 2 ]+ one (T)/ 2 )/ r[k]
82
+ end
83
+ ret
84
+ end
85
+
86
+ Λ (z:: Number )= Λ (typeof (z),z)
87
+ Λ (z:: AbstractArray )= Λ (eltype (z),z)
88
+
89
+
90
+ function leg2chebuTH (n)
91
+ λ= Λ (0 : 0.5 : n- 1 )
92
+ t= zeros (n)
93
+ t[1 : 2 : end ]= λ[1 : 2 : n]. / (((1 : 2 : n)- 2 ))
94
+ T= TriangularToeplitz (- 2 / π* t,:U )
95
+ H= Hankel (λ[1 : n]. / ((1 : n)+ 1 ),λ[n: end ]. / ((n: 2 n- 1 )+ 1 ))
96
+ T,H
97
+ end
98
+
99
+ leg2chebuplan (n)= ToepltizHankelPlan (leg2chebuTH (n)... ,1 : n,ones (n))
100
+
101
+ function leg2chebTH {TT} (:: Type{TT} ,n)
102
+ λ= Λ (TT,0 : 0.5 : n- 1 )
103
+ t= zeros (TT,n)
104
+ t[1 : 2 : end ]= λ[1 : 2 : n]
105
+ T= TriangularToeplitz (2 / π* t,:U )
106
+ H= Hankel (λ[1 : n],λ[n: end ])
107
+ DL= ones (TT,n)
108
+ DL[1 ]/= 2
109
+ T,H,DL
110
+ end
111
+
112
+ leg2chebplan {TT} (:: Type{TT} ,n)= ToepltizHankelPlan (leg2chebTH (TT,n)... ,ones (TT,n))
113
+
114
+ function leg2chebTHslow (n)
115
+ λ= map (Λ,0 : 0.5 : n- 1 )
116
+ t= zeros (n)
117
+ t[1 : 2 : end ]= λ[1 : 2 : n]
118
+ T= TriangularToeplitz (2 / π* t,:U )
119
+ H= Hankel (λ[1 : n],λ[n: end ])
120
+ DL= ones (n)
121
+ DL[1 ]*= 0.5
122
+ T,H,DL
123
+ end
124
+
125
+
126
+ leg2cheb (v)= leg2chebplan (eltype (v),length (v))* v
0 commit comments