Skip to content

Commit 40752c1

Browse files
authored
Update jacobi.jl (#145)
1 parent bca2161 commit 40752c1

File tree

1 file changed

+59
-20
lines changed

1 file changed

+59
-20
lines changed

src/classical/jacobi.jl

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -255,29 +255,68 @@ end
255255
\(A::Legendre, B::Jacobi) = Jacobi(A)\B
256256
\(A::Legendre, B::Weighted{<:Any,<:Jacobi}) = Jacobi(A)\B
257257

258-
function \(A::Jacobi, B::Jacobi)
259-
T = promote_type(eltype(A), eltype(B))
260-
a,b = B.a,B.b
261-
if A.a a && A.b b
262-
Eye{T}(∞)
263-
elseif isone(-a-b) && A.a == a && A.b == b+1
264-
Bidiagonal(Vcat(1, ((2:∞) .+ (a+b)) ./ ((3:2:∞) .+ (a+b))), ((1:∞) .+ a) ./ ((3:2:∞) .+ (a+b)), :U)
265-
elseif isone(-a-b) && A.a == a+1 && A.b == b
258+
function _jacobi_convert_a(a, b) # Jacobi(a+1, b) \ Jacobi(a, b)
259+
if isone(-a-b)
266260
Bidiagonal(Vcat(1, ((2:∞) .+ (a+b)) ./ ((3:2:∞) .+ (a+b))), -((1:∞) .+ b) ./ ((3:2:∞) .+ (a+b)), :U)
267-
elseif A.a == a && A.b == b+1
268-
Bidiagonal(((1:∞) .+ (a+b))./((1:2:∞) .+ (a+b)), ((1:∞) .+ a)./((3:2:∞) .+ (a+b)), :U)
269-
elseif A.a == a+1 && A.b == b
261+
else
270262
Bidiagonal(((1:∞) .+ (a+b))./((1:2:∞) .+ (a+b)), -((1:∞) .+ b)./((3:2:∞) .+ (a+b)), :U)
271-
elseif A.a a+1
272-
J = Jacobi(a+1,b)
273-
(A \ J) * (J \ B)
274-
elseif A.b b+1
275-
J = Jacobi(a,b+1)
276-
(A \ J) * (J \ B)
277-
elseif isinteger(A.a-a) && isinteger(A.b-b)
278-
inv(B \ A)
263+
end
264+
end
265+
function _jacobi_convert_b(a, b) # Jacobi(a, b+1) \ Jacobi(a, b)
266+
if isone(-a-b)
267+
Bidiagonal(Vcat(1, ((2:∞) .+ (a+b)) ./ ((3:2:∞) .+ (a+b))), ((1:∞) .+ a) ./ ((3:2:∞) .+ (a+b)), :U)
268+
else
269+
Bidiagonal(((1:∞) .+ (a+b))./((1:2:∞) .+ (a+b)), ((1:∞) .+ a)./((3:2:∞) .+ (a+b)), :U)
270+
end
271+
end
272+
273+
# TODO: implement ApplyArray(*, A) in LazyArrays.jl, then these can be simplified
274+
# the type specification is also because LazyArrays.jl is slow otherwise
275+
# getindex and print could be very slow. This needs to be fixed by LazyArrays.jl
276+
function _jacobi_convert_a(a, b, k, T) # Jacobi(a+k, b) \ Jacobi(a, b)
277+
if iszero(k)
278+
Eye{T}(∞)
279+
elseif isone(k)
280+
_jacobi_convert_a(a, b)
281+
else
282+
list = tuple([_jacobi_convert_a(a+j, b) for j in k-1:-1:0]...)
283+
ApplyArray{T,2,typeof(*),typeof(list)}(*, list)
284+
end
285+
end
286+
function _jacobi_convert_b(a, b, k, T) # Jacobi(a, b+k) \ Jacobi(a, b)
287+
if iszero(k)
288+
Eye{T}(∞)
289+
elseif isone(k)
290+
_jacobi_convert_b(a, b)
279291
else
280-
error("not implemented for $A and $B")
292+
list = tuple([_jacobi_convert_b(a, b+j) for j in k-1:-1:0]...)
293+
ApplyArray{T,2,typeof(*),typeof(list)}(*, list)
294+
end
295+
end
296+
297+
function \(A::Jacobi, B::Jacobi)
298+
T = promote_type(eltype(A), eltype(B))
299+
aa, ab = A.a, A.b
300+
ba, bb = B.a, B.b
301+
ka = Integer(aa-ba)
302+
kb = Integer(ab-bb)
303+
if ka >= 0
304+
C1 = _jacobi_convert_a(ba, ab, ka, T)
305+
if kb >= 0
306+
C2 = _jacobi_convert_b(ba, bb, kb, T)
307+
else
308+
C2 = inv(_jacobi_convert_b(ba, ab, -kb, T))
309+
end
310+
if iszero(ka)
311+
C2
312+
elseif iszero(kb)
313+
C1
314+
else
315+
list = (C1, C2)
316+
ApplyArray{T,2,typeof(*),typeof(list)}(*, list)
317+
end
318+
else
319+
inv(B \ A)
281320
end
282321
end
283322

0 commit comments

Comments
 (0)