|
| 1 | +#### |
| 2 | +# Support for Fractional derivatives |
| 3 | +# |
| 4 | +# defined as |
| 5 | +#### |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +# export LeftIntegral,LeftDerivative, RightDerivative, RightIntegral |
| 10 | + |
| 11 | +@calculus_operator LeftIntegral |
| 12 | +@calculus_operator LeftDerivative |
| 13 | + |
| 14 | +@calculus_operator RightIntegral |
| 15 | +@calculus_operator RightDerivative |
| 16 | + |
| 17 | +# DLMF18.17.9 with μ=0.5 and α=β=0 |
| 18 | + |
| 19 | +function LeftIntegral(S::Jacobi,k) |
| 20 | + if S.b==0 |
| 21 | + ConcreteLeftIntegral(S,k) |
| 22 | + else |
| 23 | + J=Jacobi(zero(S.a),S.a,domain(S)) |
| 24 | + CLI = ConcreteLeftIntegral(J,k) |
| 25 | + LeftIntegralWrapper(CLI*Conversion(S,J),k,S,rangespace(CLI)) |
| 26 | + end |
| 27 | +end |
| 28 | + |
| 29 | +function LeftIntegral(S::Ultraspherical,k) |
| 30 | + J = Jacobi(S) |
| 31 | + LI = LeftIntegral(J,k) |
| 32 | + LeftIntegralWrapper(LI*ConcreteConversion(S,J),0.5,S,rangespace(LI)) |
| 33 | +end |
| 34 | + |
| 35 | +function LeftIntegral(S::Chebyshev,k) |
| 36 | + SU = Ultraspherical(Legendre(domain(S))) |
| 37 | + LI = LeftIntegral(SU,k) |
| 38 | + LeftIntegralWrapper(LI*ConcreteConversion(S,SU),0.5,S,rangespace(LI)) |
| 39 | +end |
| 40 | + |
| 41 | + |
| 42 | +function rangespace(Q::ConcreteLeftIntegral{<:Jacobi{<:IntervalOrSegment}}) |
| 43 | + μ=Q.order |
| 44 | + S=domainspace(Q) |
| 45 | + |
| 46 | + JacobiWeight(S.b+μ,zero(S.b),Jacobi(S.b+μ,S.a-μ,domain(S))) |
| 47 | +end |
| 48 | + |
| 49 | +function RightIntegral(S::Jacobi,k) |
| 50 | + if S.a==0 |
| 51 | + ConcreteRightIntegral(S,k) |
| 52 | + else |
| 53 | + J=Jacobi(S.b,zero(S.b),domain(S)) |
| 54 | + CRI = ConcreteRightIntegral(J,k) |
| 55 | + RightIntegralWrapper(CRI*Conversion(S,J),k,S,rangespace(CRI)) |
| 56 | + end |
| 57 | +end |
| 58 | + |
| 59 | +function rangespace(Q::ConcreteRightIntegral{<:Jacobi{<:IntervalOrSegment}}) |
| 60 | + μ=Q.order |
| 61 | + S=domainspace(Q) |
| 62 | + @assert S.a==0 |
| 63 | + |
| 64 | + JacobiWeight(zero(S.a),S.a+μ,Jacobi(S.b-μ,S.a+μ,domain(S))) |
| 65 | +end |
| 66 | + |
| 67 | +for TYP in (:ConcreteLeftIntegral,:ConcreteRightIntegral) |
| 68 | + @eval begin |
| 69 | + bandwidths(Q::$TYP{<:Jacobi{<:IntervalOrSegment}}) = (0,0) |
| 70 | + getindex(Q::$TYP{<:Jacobi{<:IntervalOrSegment},<:Any,T},k::Integer,j::Integer) where {T} = |
| 71 | + convert(T, jacobi_frac_getindex(domain(Q),zero(T),Q.order,k,j))::T |
| 72 | + end |
| 73 | +end |
| 74 | + |
| 75 | + |
| 76 | +jacobi_frac_getindex(d::IntervalOrSegment,α,μ,k::Integer,j::Integer) = |
| 77 | + jacobi_frac_getindex((arclength(d)/2)^μ,α,μ,k,j) |
| 78 | + |
| 79 | +jacobi_frac_getindex(c::Number,α,μ,k::Integer,j::Integer) = |
| 80 | + k==j ? c*exp(loggamma(α+k)-loggamma(α+μ+k)) : zero(promote_type(typeof(c),typeof(α),typeof(μ))) |
| 81 | + |
| 82 | + |
| 83 | +# jacobi_frac_addentries!(d::IntervalOrSegment,α,μ,A,kr::UnitRange)= |
| 84 | +# jacobi_frac_addentries!((arclength(d)/2)^μ,α,μ,A,kr) |
| 85 | +# function jacobi_frac_addentries!(c::Number,α,μ,A,kr::UnitRange) |
| 86 | +# γ=c*gamma(α+1)/gamma(α+1+μ) |
| 87 | +# for k=1:first(kr)-1 |
| 88 | +# γ*=(α+k)/(α+μ+k) |
| 89 | +# end |
| 90 | +# for k=kr |
| 91 | +# A[k,k]+=γ |
| 92 | +# γ*=(α+k)/(α+μ+k) |
| 93 | +# #should be gamma(S.α+k)/gamma(S.α+μ+k)= |
| 94 | +# #(S.α+k-1)/(S.α+μ+k-1)*gamma(S.α+k-1)/gamma(S.α+μ+k-1) |
| 95 | +# end |
| 96 | +# A |
| 97 | +# end |
| 98 | + |
| 99 | + |
| 100 | +function LeftIntegral(S::JacobiWeight{<:Jacobi}, k) |
| 101 | + J=S.space |
| 102 | + @assert S.α ≈ 0 |
| 103 | + @assert S.β ≈ J.b |
| 104 | + ConcreteLeftIntegral(S,k) |
| 105 | +end |
| 106 | + |
| 107 | +function RightIntegral(S::JacobiWeight{<:Jacobi}, k) |
| 108 | + J=S.space |
| 109 | + @assert S.α ≈ J.a |
| 110 | + @assert S.β ≈ 0 |
| 111 | + ConcreteRightIntegral(S,k) |
| 112 | +end |
| 113 | + |
| 114 | + |
| 115 | + |
| 116 | +function LeftIntegral(S::JacobiWeight{<:Chebyshev},k) |
| 117 | + # convert to Jacobi |
| 118 | + Q=LeftIntegral(JacobiWeight(S.β,S.α,Jacobi(S.space)),k) |
| 119 | + LeftIntegralWrapper(Q*Conversion(S,domainspace(Q)),k,S,rangespace(Q)) |
| 120 | +end |
| 121 | + |
| 122 | +function RightIntegral(S::JacobiWeight{<:Chebyshev},k) |
| 123 | + # convert to Jacobi |
| 124 | + Q=RightIntegral(JacobiWeight(S.β,S.α,Jacobi(S.space)),k) |
| 125 | + RightIntegralWrapper(Q*Conversion(S,domainspace(Q)),k,S,rangespace(Q)) |
| 126 | +end |
| 127 | + |
| 128 | +for (TYP,WRAP) in ((:LeftIntegral,:LeftIntegralWrapper), |
| 129 | + (:RightIntegral,:RightIntegralWrapper)) |
| 130 | + |
| 131 | + @eval function $TYP(S::JacobiWeight{<:PolynomialSpace}, k) |
| 132 | + JS = JacobiWeight(S.β,S.α,Jacobi(S.space)) |
| 133 | + IOP = $TYP(JS,k) |
| 134 | + $WRAP(IOP*Conversion(S,JS),k,S,rangespace(IOP)) |
| 135 | + end |
| 136 | +end |
| 137 | + |
| 138 | + |
| 139 | +#DLMF18.17.9 |
| 140 | +function rangespace(Q::ConcreteLeftIntegral{<:JacobiWeight{<:Jacobi{DD,RR},DD,RR}}) where {DD<:IntervalOrSegment,RR} |
| 141 | + μ=Q.order |
| 142 | + S=domainspace(Q) |
| 143 | + J=S.space |
| 144 | + if isapprox(S.β,-μ) |
| 145 | + Jacobi(J.b+μ,J.a-μ,domain(J)) |
| 146 | + else |
| 147 | + JacobiWeight(S.β+μ,zero(S.β),Jacobi(J.b+μ,J.a-μ,domain(J))) |
| 148 | + end |
| 149 | +end |
| 150 | + |
| 151 | +function rangespace(Q::ConcreteRightIntegral{<:JacobiWeight{<:Jacobi{DD,RR},DD,RR}}) where {DD<:IntervalOrSegment,RR} |
| 152 | + μ=Q.order |
| 153 | + S=domainspace(Q) |
| 154 | + J=S.space |
| 155 | + @assert S.α==J.a |
| 156 | + @assert S.β==0 |
| 157 | + if isapprox(S.β,-μ) |
| 158 | + Jacobi(J.b-μ,J.a+μ,domain(J)) |
| 159 | + else |
| 160 | + JacobiWeight(zero(S.α),S.α+μ,Jacobi(J.b-μ,J.a+μ,domain(J))) |
| 161 | + end |
| 162 | +end |
| 163 | + |
| 164 | +for TYP in (:ConcreteLeftIntegral,:ConcreteRightIntegral) |
| 165 | + @eval bandwidths(Q::$TYP{<:JacobiWeight{<:Jacobi{DD,RR},DD,RR}}) where {DD<:IntervalOrSegment,RR} = (0,0) |
| 166 | +end |
| 167 | + |
| 168 | +getindex(Q::ConcreteLeftIntegral{<:JacobiWeight{<:Jacobi{DD,RR},DD,RR},<:Any,T},k::Integer,j::Integer) where {DD<:IntervalOrSegment,RR,T} = |
| 169 | + convert(T,jacobi_frac_getindex(domain(Q),domainspace(Q).β,Q.order,k,j))::T |
| 170 | + |
| 171 | +getindex(Q::ConcreteRightIntegral{<:JacobiWeight{<:Jacobi{DD,RR},DD,RR},<:Any,T},k::Integer,j::Integer) where {DD<:IntervalOrSegment,RR,T} = |
| 172 | + convert(T,jacobi_frac_getindex(domain(Q),domainspace(Q).α,Q.order,k,j))::T |
| 173 | + |
| 174 | +function choosedomainspace(Q::LeftIntegral{UnsetSpace}, sp::JacobiWeight) |
| 175 | + @assert sp.β>0 && isapproxinteger(sp.α) |
| 176 | + |
| 177 | + if isapprox(Q.order,sp.β) |
| 178 | + Legendre(domain(sp)) |
| 179 | + else |
| 180 | + JacobiWeight(sp.β-Q.order,0.,Jacobi(sp.β-Q.order,0.,domain(sp))) |
| 181 | + end |
| 182 | +end |
| 183 | + |
| 184 | +choosedomainspace(Q::LeftIntegral{UnsetSpace,T}, sp::PolynomialSpace) where {T} = |
| 185 | + JacobiWeight(-Q.order,zero(T),Jacobi(-Q.order,-Q.order,domain(sp))) |
| 186 | + |
| 187 | + |
| 188 | + |
| 189 | +function choosedomainspace(Q::RightIntegral{UnsetSpace,T},sp::JacobiWeight) where T |
| 190 | + @assert sp.α>0 && isapproxinteger(sp.β) |
| 191 | + |
| 192 | + if isapprox(Q.order,sp.α) |
| 193 | + Legendre(domain(sp)) |
| 194 | + else |
| 195 | + JacobiWeight(zero(T),sp.α-Q.order,Jacobi(0.,sp.α-Q.order)) |
| 196 | + end |
| 197 | +end |
| 198 | +choosedomainspace(Q::RightIntegral{UnsetSpace,T},sp::PolynomialSpace) where {T}= |
| 199 | + JacobiWeight(zero(T),-Q.order,Jacobi(-Q.order,-Q.order,domain(sp))) |
| 200 | + |
| 201 | + |
| 202 | + |
| 203 | + |
| 204 | +# Define Left/RightDerivative |
| 205 | +for (DTYP,QTYP,DWRAP,QWRAP) in ((:LeftDerivative,:LeftIntegral,:LeftDerivativeWrapper,:LeftIntegralWrapper), |
| 206 | + (:RightDerivative,:RightIntegral,:RightDerivativeWrapper,:RightIntegralWrapper)) |
| 207 | + @eval begin |
| 208 | + function $DTYP(S::Space,k::Real) |
| 209 | + i=ceil(Int,k) |
| 210 | + r=i-k |
| 211 | + $DWRAP(i<0 ? $QTYP(S,-k) : Derivative(i)*$QTYP(S,r),k,S) |
| 212 | + end |
| 213 | + function $QTYP(S::SumSpace,k) |
| 214 | + t = map(s->$QTYP(s,k),components(S)) |
| 215 | + IOP = InterlaceOperator_Diagonal(t,S) |
| 216 | + $QWRAP(IOP,k) |
| 217 | + end |
| 218 | + end |
| 219 | +end |
0 commit comments