ningshuxia
2022-10-31 2967027410e4131e18c13daf9a80782c3351da4d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
using System;
using System.Numerics;
 
namespace IStation.Numerics
{
    /// <summary>
    /// This partial implementation of the SpecialFunctions class contains all methods related to the modified Bessel function.
    /// </summary>
    public static partial class SpecialFunctions
    {
        /// <summary>
        /// Returns the Kelvin function of the first kind.
        /// <para>KelvinBe(nu, x) is given by BesselJ(0, j * sqrt(j) * x) where j = sqrt(-1).</para>
        /// <para>KelvinBer(nu, x) and KelvinBei(nu, x) are the real and imaginary parts of the KelvinBe(nu, x)</para>
        /// </summary>
        /// <param name="nu">the order of the the Kelvin function.</param>
        /// <param name="x">The value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function of the first kind.</returns>
        public static Complex KelvinBe(double nu, double x)
        {
            Complex ISqrtI = new Complex(-Constants.Sqrt1Over2, Constants.Sqrt1Over2); // j * sqrt(j) = (-1)^(3/4) = (-1 + j)/sqrt(2)
            return BesselJ(nu, ISqrtI * x);
        }
 
        /// <summary>
        /// Returns the Kelvin function ber.
        /// <para>KelvinBer(nu, x) is given by the real part of BesselJ(nu, j * sqrt(j) * x) where j = sqrt(-1).</para>
        /// </summary>
        /// <param name="nu">the order of the the Kelvin function.</param>
        /// <param name="x">The value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function ber.</returns>
        public static double KelvinBer(double nu, double x)
        {
            return KelvinBe(nu, x).Real;
        }
 
        /// <summary>
        /// Returns the Kelvin function ber.
        /// <para>KelvinBer(x) is given by the real part of BesselJ(0, j * sqrt(j) * x) where j = sqrt(-1).</para>
        /// <para>KelvinBer(x) is equivalent to KelvinBer(0, x).</para>
        /// </summary>
        /// <param name="x">The value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function ber.</returns>
        public static double KelvinBer(double x)
        {
            return KelvinBe(0, x).Real;
        }
 
        /// <summary>
        /// Returns the Kelvin function bei.
        /// <para>KelvinBei(nu, x) is given by the imaginary part of BesselJ(nu, j * sqrt(j) * x) where j = sqrt(-1).</para>
        /// </summary>
        /// <param name="nu">the order of the the Kelvin function.</param>
        /// <param name="x">The value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function bei.</returns>
        public static double KelvinBei(double nu, double x)
        {
            return KelvinBe(nu, x).Imaginary;
        }
 
        /// <summary>
        /// Returns the Kelvin function bei.
        /// <para>KelvinBei(x) is given by the imaginary part of BesselJ(0, j * sqrt(j) * x) where j = sqrt(-1).</para>
        /// <para>KelvinBei(x) is equivalent to KelvinBei(0, x).</para>
        /// </summary>
        /// <param name="x">The value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function bei.</returns>
        public static double KelvinBei(double x)
        {
            return KelvinBe(0, x).Imaginary;
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function ber.
        /// </summary>
        /// <param name="nu">The order of the Kelvin function.</param>
        /// <param name="x">The value to compute the derivative of the Kelvin function of.</param>
        /// <returns>the derivative of the Kelvin function ber</returns>
        public static double KelvinBerPrime(double nu, double x)
        {
            const double inv2Sqrt2 = 0.35355339059327376220042218105242451964241796884424; // 1/(2 * sqrt(2))
            return inv2Sqrt2 * (-KelvinBer(nu - 1, x) + KelvinBer(nu + 1, x) - KelvinBei(nu - 1, x) + KelvinBei(nu + 1, x));
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function ber.
        /// </summary>
        /// <param name="x">The value to compute the derivative of the Kelvin function of.</param>
        /// <returns>The derivative of the Kelvin function ber.</returns>
        public static double KelvinBerPrime(double x)
        {
            return KelvinBerPrime(0, x);
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function bei.
        /// </summary>
        /// <param name="nu">The order of the Kelvin function.</param>
        /// <param name="x">The value to compute the derivative of the Kelvin function of.</param>
        /// <returns>the derivative of the Kelvin function bei.</returns>
        public static double KelvinBeiPrime(double nu, double x)
        {
            const double inv2Sqrt2 = 0.35355339059327376220042218105242451964241796884424; // 1/(2 * sqrt(2))
            return inv2Sqrt2 * (KelvinBer(nu - 1, x) - KelvinBer(nu + 1, x) - KelvinBei(nu - 1, x) + KelvinBei(nu + 1, x));
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function bei.
        /// </summary>
        /// <param name="x">The value to compute the derivative of the Kelvin function of.</param>
        /// <returns>The derivative of the Kelvin function bei.</returns>
        public static double KelvinBeiPrime(double x)
        {
            return KelvinBeiPrime(0, x);
        }
 
        /// <summary>
        /// Returns the Kelvin function of the second kind
        /// <para>KelvinKe(nu, x) is given by Exp(-nu * pi * j / 2) * BesselK(nu, x * sqrt(j)) where j = sqrt(-1).</para>
        /// <para>KelvinKer(nu, x) and KelvinKei(nu, x) are the real and imaginary parts of the KelvinBe(nu, x)</para>
        /// </summary>
        /// <param name="nu">The order of the Kelvin function.</param>
        /// <param name="x">The value to calculate the kelvin function of,</param>
        /// <returns></returns>
        public static Complex KelvinKe(double nu, double x)
        {
            Complex PiIOver2 = new Complex(0.0, Constants.PiOver2); // pi * I / 2
            Complex SqrtI = new Complex(Constants.Sqrt1Over2, Constants.Sqrt1Over2); // sqrt(j) = (-1)^(1/4) = (1 + j)/sqrt(2)
            return Complex.Exp(-nu * PiIOver2) * BesselK(nu, SqrtI * x);
        }
 
        /// <summary>
        /// Returns the Kelvin function ker.
        /// <para>KelvinKer(nu, x) is given by the real part of Exp(-nu * pi * j / 2) * BesselK(nu, sqrt(j) * x) where j = sqrt(-1).</para>
        /// </summary>
        /// <param name="nu">the order of the the Kelvin function.</param>
        /// <param name="x">The non-negative real value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function ker.</returns>
        public static double KelvinKer(double nu, double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            return KelvinKe(nu, x).Real;
        }
 
        /// <summary>
        /// Returns the Kelvin function ker.
        /// <para>KelvinKer(x) is given by the real part of Exp(-nu * pi * j / 2) * BesselK(0, sqrt(j) * x) where j = sqrt(-1).</para>
        /// <para>KelvinKer(x) is equivalent to KelvinKer(0, x).</para>
        /// </summary>
        /// <param name="x">The non-negative real value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function ker.</returns>
        public static double KelvinKer(double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            return KelvinKe(0, x).Real;
        }
 
        /// <summary>
        /// Returns the Kelvin function kei.
        /// <para>KelvinKei(nu, x) is given by the imaginary part of Exp(-nu * pi * j / 2) * BesselK(nu, sqrt(j) * x) where j = sqrt(-1).</para>
        /// </summary>
        /// <param name="nu">the order of the the Kelvin function.</param>
        /// <param name="x">The non-negative real value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function kei.</returns>
        public static double KelvinKei(double nu, double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            return KelvinKe(nu, x).Imaginary;
        }
 
        /// <summary>
        /// Returns the Kelvin function kei.
        /// <para>KelvinKei(x) is given by the imaginary part of Exp(-nu * pi * j / 2) * BesselK(0, sqrt(j) * x) where j = sqrt(-1).</para>
        /// <para>KelvinKei(x) is equivalent to KelvinKei(0, x).</para>
        /// </summary>
        /// <param name="x">The non-negative real value to compute the Kelvin function of.</param>
        /// <returns>The Kelvin function kei.</returns>
        public static double KelvinKei(double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            return KelvinKe(0, x).Imaginary;
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function ker.
        /// </summary>
        /// <param name="nu">The order of the Kelvin function.</param>
        /// <param name="x">The non-negative real value to compute the derivative of the Kelvin function of.</param>
        /// <returns>The derivative of the Kelvin function ker.</returns>
        public static double KelvinKerPrime(double nu, double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            const double inv2Sqrt2 = 0.35355339059327376220042218105242451964241796884424; // 1/(2 * sqrt(2))
            return inv2Sqrt2 * (-KelvinKer(nu - 1, x) + KelvinKer(nu + 1, x) - KelvinKei(nu - 1, x) + KelvinKei(nu + 1, x));
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function ker.
        /// </summary>
        /// <param name="x">The value to compute the derivative of the Kelvin function of.</param>
        /// <returns>The derivative of the Kelvin function ker.</returns>
        public static double KelvinKerPrime(double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            return KelvinKerPrime(0, x);
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function kei.
        /// </summary>
        /// <param name="nu">The order of the Kelvin function.</param>
        /// <param name="x">The value to compute the derivative of the Kelvin function of.</param>
        /// <returns>The derivative of the Kelvin function kei.</returns>
        public static double KelvinKeiPrime(double nu, double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            const double inv2Sqrt2 = 0.35355339059327376220042218105242451964241796884424; // 1/(2 * sqrt(2))
            return inv2Sqrt2 * (KelvinKer(nu - 1, x) - KelvinKer(nu + 1, x) - KelvinKei(nu - 1, x) + KelvinKei(nu + 1, x));
        }
 
        /// <summary>
        /// Returns the derivative of the Kelvin function kei.
        /// </summary>
        /// <param name="x">The value to compute the derivative of the Kelvin function of.</param>
        /// <returns>The derivative of the Kelvin function kei.</returns>
        public static double KelvinKeiPrime(double x)
        {
            if (x <= 0.0)
            {
                throw new ArithmeticException();
            }
 
            return KelvinKeiPrime(0, x);
        }
    }
}