1
- #= Aren't tested yet
1
+ function besseljy (nu:: Real , x:: T ) where T
2
+ isinteger (nu) && return besseljy (Int (nu), x)
3
+ abs_nu = abs (nu)
4
+ abs_x = abs (x)
5
+
6
+ Ynu = bessely_positive_args (abs_nu, abs_x)
7
+ Jnu = bessely_positive_args (abs_nu, abs_x)
8
+
9
+ if nu >= zero (T)
10
+ if x >= zero (T)
11
+ return Jnu, Ynu
12
+ else
13
+ return throw (DomainError (x, " Complex result returned for real arguments. Complex arguments are currently not supported" ))
14
+ # return Ynu * cispi(-nu) + 2im * besselj_positive_args(abs_nu, abs_x) * cospi(abs_nu)
15
+ end
16
+ else
17
+ spi, cpi = sincospi (abs_nu)
18
+ out = Jnu * cpi - Ynu * spi
19
+ if x >= zero (T)
20
+ return out, Ynu * cpi + Jnu * spi
21
+ else
22
+ return throw (DomainError (x, " Complex result returned for real arguments. Complex arguments are currently not supported" ))
23
+ # return cpi * (Ynu * cispi(nu) + 2im * Jnu * cpi) + Jnu * spi * cispi(abs_nu)
24
+ end
25
+ end
26
+ end
27
+
28
+ function besseljy (nu:: Integer , x:: T ) where T
29
+ abs_nu = abs (nu)
30
+ abs_x = abs (x)
31
+ sg = iseven (abs_nu) ? 1 : - 1
32
+
33
+ Jnu = besselj_positive_args (abs_nu, abs_x)
34
+ Ynu = bessely_positive_args (abs_nu, abs_x)
35
+ if nu >= zero (T)
36
+ if x >= zero (T)
37
+ return Jnu, Ynu
38
+ else
39
+ return throw (DomainError (x, " Complex result returned for real arguments. Complex arguments are currently not supported" ))
40
+ # return Jnu * sg, Ynu * sg + 2im * sg * besselj_positive_args(abs_nu, abs_x)
41
+ end
42
+ else
43
+ if x >= zero (T)
44
+ return Jnu * sg, Ynu * sg
45
+ else
46
+ spi, cpi = sincospi (abs_nu)
47
+ return throw (DomainError (x, " Complex result returned for real arguments. Complex arguments are currently not supported" ))
48
+ # return (cpi*Jnu - spi*Ynu) * sg, Ynu + 2im * besselj_positive_args(abs_nu, abs_x)
49
+ end
50
+ end
51
+ end
52
+
53
+ function besseljy_positive_args (nu:: Real , x:: T ) where T
54
+ nu == 0 && return (besselj0 (x), bessely0 (x))
55
+ nu == 1 && return (besselj1 (x), bessely1 (x))
56
+ iszero (x) && return (besselj_positive_args (nu, x), bessely_positive_args (nu, x))
57
+
58
+ # x < ~nu branch see src/U_polynomials.jl
59
+ besseljy_debye_cutoff (nu, x) && return besseljy_debye (nu, x)
60
+
61
+ # large argument branch see src/asymptotics.jl
62
+ besseljy_large_argument_cutoff (nu, x) && return besseljy_large_argument (nu, x)
63
+
64
+ # x > ~nu branch see src/U_polynomials.jl on computing Hankel function
65
+ if hankel_debye_cutoff (nu, x)
66
+ H = hankel_debye (nu, x)
67
+ return real (H), imag (H)
68
+ end
69
+
70
+ # use forward recurrence if nu is an integer up until the continued fraction becomes inefficient
71
+ if isinteger (nu) && nu < 150
72
+ Y0 = bessely0 (x)
73
+ Y1 = bessely1 (x)
74
+ Ynm1, Yn = besselj_up_recurrence (x, bessely1 (x), bessely0 (x), 1 , nu- 1 )
75
+
76
+ ratio_Jv_Jvm1 = besselj_ratio_jnu_jnum1 (nu, x)
77
+ Jn = 2 / (π* x * (Ynm1 - Yn / ratio_Jv_Jvm1))
78
+ return Jn, Yn
79
+ end
80
+
81
+ # use power series for small x and for when nu > x
82
+ if bessely_series_cutoff (nu, x) && besselj_series_cutoff (nu, x)
83
+ Yn, Jn = bessely_power_series (nu, x)
84
+ return Jn, Yn
85
+ end
86
+
87
+ # for x ∈ (6, 19) we use Chebyshev approximation and forward recurrence
88
+ if besseljy_chebyshev_cutoff (nu, x)
89
+ Yn, Ynp1 = bessely_chebyshev (nu, x)
90
+ ratio_Jvp1_Jv = besselj_ratio_jnu_jnum1 (nu+ 1 , x)
91
+ Jnp1 = 2 / (π* x * (Yn - Ynp1 / ratio_Jvp1_Jv))
92
+ return Jnp1 / ratio_Jvp1_Jv, Yn
93
+ end
94
+
95
+ # at this point x > 19.0 (for Float64) and fairly close to nu
96
+ # shift nu down and use the debye expansion for Hankel function (valid x > nu) then use forward recurrence
97
+ nu_shift = floor (nu) - ceil (Int, - 1.5 + x + Base. Math. _approx_cbrt (- 411 * x))
98
+ v2 = maximum ((nu - nu_shift, modf (nu)[1 ] + 1 ))
99
+
100
+ Hnu = hankel_debye (v2, x)
101
+ Hnum1 = hankel_debye (v2 - 1 , x)
102
+ # forward recurrence is stable for Hankel when x >= nu
103
+ if x >= nu
104
+ H = besselj_up_recurrence (x, Hnu, Hnum1, v2, nu)[1 ]
105
+ return real (H), imag (H)
106
+ else
107
+ Yn, Ynp1 = besselj_up_recurrence (x, imag (Hnu), imag (Hnum1), v2, nu)
108
+ ratio_Jvp1_Jv = besselj_ratio_jnu_jnum1 (nu+ 1 , x)
109
+ Jnp1 = 2 / (π* x * (Yn - Ynp1 / ratio_Jvp1_Jv))
110
+ return Jnp1 / ratio_Jvp1_Jv, Yn
111
+ end
112
+ end
113
+
114
+ function besselj_ratio_jnu_jnum1 (n, x:: T ) where T
115
+ MaxIter = 5000
116
+ xinv = inv (x)
117
+ xinv2 = 2 * xinv
118
+ d = x / (n + n)
119
+ a = d
120
+ h = a
121
+ b = muladd (2 , n, 2 ) * xinv
122
+ for _ in 1 : MaxIter
123
+ d = inv (b - d)
124
+ a *= muladd (b, d, - 1 )
125
+ h = h + a
126
+ b = b + xinv2
127
+ abs (a / h) <= eps (T) && break
128
+ end
129
+ return h
130
+ end
131
+
2
132
function besselh (nu:: Float64 , k:: Integer , x:: AbstractFloat )
3
133
if k == 1
4
134
return complex (besselj (nu, x), bessely (nu, x))
11
141
12
142
hankelh1 (nu, z) = besselh (nu, 1 , z)
13
143
hankelh2 (nu, z) = besselh (nu, 2 , z)
14
- =#
0 commit comments