LifeV
cbessjy.cpp
Go to the documentation of this file.
1 // cbessjy.cpp -- complex Bessel functions.
2 // Algorithms and coefficient values from "Computation of Special
3 // Functions", Zhang and Jin, John Wiley and Sons, 1996.
4 //
5 // (C) 2003, C. Bond. All rights reserved.
6 //
7 
8 #include <lifev/navier_stokes/function/bessel/bessel.hpp>
9 
10 namespace bessel
11 {
12 double gamma (double);
13 
14 static std::complex<double> cii (0.0, 1.0);
15 static std::complex<double> cone (1.0, 0.0);
16 static std::complex<double> czero (0.0, 0.0);
17 
18 int cbessjy01 (std::complex<double> z, std::complex<double>& cj0, std::complex<double>& cj1,
19  std::complex<double>& cy0, std::complex<double>& cy1, std::complex<double>& cj0p,
20  std::complex<double>& cj1p, std::complex<double>& cy0p, std::complex<double>& cy1p)
21 {
22  std::complex<double> z1, z2, cr, cp, cs, cp0, cq0, cp1, cq1, ct1, ct2, cu;
23  double a0, w0, w1;
24  int k, kz;
25 
26  static double a[] =
27  {
28  -7.03125e-2,
29  0.112152099609375,
30  -0.5725014209747314,
31  6.074042001273483,
32  -1.100171402692467e2,
33  3.038090510922384e3,
34  -1.188384262567832e5,
35  6.252951493434797e6,
36  -4.259392165047669e8,
37  3.646840080706556e10,
38  -3.833534661393944e12,
39  4.854014686852901e14,
40  -7.286857349377656e16,
41  1.279721941975975e19
42  };
43  static double b[] =
44  {
45  7.32421875e-2,
46  -0.2271080017089844,
47  1.727727502584457,
48  -2.438052969955606e1,
49  5.513358961220206e2,
50  -1.825775547429318e4,
51  8.328593040162893e5,
52  -5.006958953198893e7,
53  3.836255180230433e9,
54  -3.649010818849833e11,
55  4.218971570284096e13,
56  -5.827244631566907e15,
57  9.476288099260110e17,
58  -1.792162323051699e20
59  };
60  static double a1[] =
61  {
62  0.1171875,
63  -0.1441955566406250,
64  0.6765925884246826,
65  -6.883914268109947,
66  1.215978918765359e2,
67  -3.302272294480852e3,
68  1.276412726461746e5,
69  -6.656367718817688e6,
70  4.502786003050393e8,
71  -3.833857520742790e10,
72  4.011838599133198e12,
73  -5.060568503314727e14,
74  7.572616461117958e16,
75  -1.326257285320556e19
76  };
77  static double b1[] =
78  {
79  -0.1025390625,
80  0.2775764465332031,
81  -1.993531733751297,
82  2.724882731126854e1,
83  -6.038440767050702e2,
84  1.971837591223663e4,
85  -8.902978767070678e5,
86  5.310411010968522e7,
87  -4.043620325107754e9,
88  3.827011346598605e11,
89  -4.406481417852278e13,
90  6.065091351222699e15,
91  -9.833883876590679e17,
92  1.855045211579828e20
93  };
94 
95  a0 = std::abs (z);
96  z2 = z * z;
97  z1 = z;
98  if (a0 == 0.0)
99  {
100  cj0 = cone;
101  cj1 = czero;
102  cy0 = std::complex<double> (-1e308, 0);
103  cy1 = std::complex<double> (-1e308, 0);
104  cj0p = czero;
105  cj1p = std::complex<double> (0.5, 0.0);
106  cy0p = std::complex<double> (1e308, 0);
107  cy1p = std::complex<double> (1e308, 0);
108  return 0;
109  }
110  if (real (z) < 0.0)
111  {
112  z1 = -z;
113  }
114  if (a0 <= 12.0)
115  {
116  cj0 = cone;
117  cr = cone;
118  for (k = 1; k <= 40; k++)
119  {
120  cr *= -0.25 * z2 / (double) (k * k);
121  cj0 += cr;
122  if (std::abs (cr) < std::abs (cj0) *eps)
123  {
124  break;
125  }
126  }
127  cj1 = cone;
128  cr = cone;
129  for (k = 1; k <= 40; k++)
130  {
131  cr *= -0.25 * z2 / (k * (k + 1.0) );
132  cj1 += cr;
133  if (std::abs (cr) < std::abs (cj1) *eps)
134  {
135  break;
136  }
137  }
138  cj1 *= 0.5 * z1;
139  w0 = 0.0;
140  cr = cone;
141  cs = czero;
142  for (k = 1; k <= 40; k++)
143  {
144  w0 += 1.0 / k;
145  cr *= -0.25 * z2 / (double) (k * k);
146  cp = cr * w0;
147  cs += cp;
148  if (std::abs (cp) < std::abs (cs) *eps)
149  {
150  break;
151  }
152  }
153  cy0 = M_2_PI * ( (std::log (0.5 * z1) + el) * cj0 - cs);
154  w1 = 0.0;
155  cr = cone;
156  cs = cone;
157  for (k = 1; k <= 40; k++)
158  {
159  w1 += 1.0 / k;
160  cr *= -0.25 * z2 / (k * (k + 1.0) );
161  cp = cr * (2.0 * w1 + 1.0 / (k + 1.0) );
162  cs += cp;
163  if (std::abs (cp) < std::abs (cs) *eps)
164  {
165  break;
166  }
167  }
168  cy1 = M_2_PI * ( (std::log (0.5 * z1) + el) * cj1 - 1.0 / z1 - 0.25 * z1 * cs);
169  }
170  else
171  {
172  if (a0 >= 50.0)
173  {
174  kz = 8; // can be changed to 10
175  }
176  else if (a0 >= 35.0)
177  {
178  kz = 10; // " " " 12
179  }
180  else
181  {
182  kz = 12; // " " " 14
183  }
184  ct1 = z1 - M_PI_4;
185  cp0 = cone;
186  for (k = 0; k < kz; k++)
187  {
188  cp0 += a[k] * std::pow (z1, -2.0 * k - 2.0);
189  }
190  cq0 = -0.125 / z1;
191  for (k = 0; k < kz; k++)
192  {
193  cq0 += b[k] * std::pow (z1, -2.0 * k - 3.0);
194  }
195  cu = std::sqrt (M_2_PI / z1);
196  cj0 = cu * (cp0 * std::cos (ct1) - cq0 * std::sin (ct1) );
197  cy0 = cu * (cp0 * std::sin (ct1) + cq0 * std::cos (ct1) );
198  ct2 = z1 - 0.75 * M_PI;
199  cp1 = cone;
200  for (k = 0; k < kz; k++)
201  {
202  cp1 += a1[k] * std::pow (z1, -2.0 * k - 2.0);
203  }
204  cq1 = 0.375 / z1;
205  for (k = 0; k < kz; k++)
206  {
207  cq1 += b1[k] * std::pow (z1, -2.0 * k - 3.0);
208  }
209  cj1 = cu * (cp1 * std::cos (ct2) - cq1 * std::sin (ct2) );
210  cy1 = cu * (cp1 * std::sin (ct2) + cq1 * std::cos (ct2) );
211  }
212  if (real (z) < 0.0)
213  {
214  if (imag (z) < 0.0)
215  {
216  cy0 -= 2.0 * cii * cj0;
217  cy1 = - (cy1 - 2.0 * cii * cj1);
218  }
219  else if (imag (z) > 0.0)
220  {
221  cy0 += 2.0 * cii * cj0;
222  cy1 = - (cy1 + 2.0 * cii * cj1);
223  }
224  cj1 = -cj1;
225  }
226  cj0p = -cj1;
227  cj1p = cj0 - cj1 / z;
228  cy0p = -cy1;
229  cy1p = cy0 - cy1 / z;
230  return 0;
231 }
232 
233 int cbessjyna (int n, std::complex<double> z, int& nm, std::complex<double>* cj,
234  std::complex<double>* cy, std::complex<double>* cjp, std::complex<double>* cyp)
235 {
236  std::complex<double> cbj0, cbj1, cby0, cby1, cj0, cjk, cj1, cf, cf1, cf2;
237  std::complex<double> cs, cg0, cg1, cyk, cyl1, cyl2, cylk, cp11, cp12, cp21, cp22;
238  std::complex<double> ch0, ch1, ch2;
239  double a0, yak, ya1, ya0, wa;
240  int m, k, lb, lb0;
241 
242  if (n < 0)
243  {
244  return 1;
245  }
246  a0 = std::abs (z);
247  nm = n;
248  if (a0 < 1.0e-100)
249  {
250  for (k = 0; k <= n; k++)
251  {
252  cj[k] = czero;
253  cy[k] = std::complex<double> (-1e308, 0);
254  cjp[k] = czero;
255  cyp[k] = std::complex<double> (1e308, 0);
256  }
257  cj[0] = cone;
258  cjp[1] = std::complex<double> (0.5, 0.0);
259  return 0;
260  }
261  cbessjy01 (z, cj[0], cj[1], cy[0], cy[1], cjp[0], cjp[1], cyp[0], cyp[1]);
262  cbj0 = cj[0];
263  cbj1 = cj[1];
264  cby0 = cy[0];
265  cby1 = cy[1];
266  if (n <= 1)
267  {
268  return 0;
269  }
270  if (n < (int) 0.25 * a0)
271  {
272  cj0 = cbj0;
273  cj1 = cbj1;
274  for (k = 2; k <= n; k++)
275  {
276  cjk = 2.0 * (k - 1.0) * cj1 / z - cj0;
277  cj[k] = cjk;
278  cj0 = cj1;
279  cj1 = cjk;
280  }
281  }
282  else
283  {
284  m = msta1 (a0, 200);
285  if (m < n)
286  {
287  nm = m;
288  }
289  else
290  {
291  m = msta2 (a0, n, 15);
292  }
293  cf2 = czero;
294  cf1 = std::complex<double> (1.0e-100, 0.0);
295  for (k = m; k >= 0; k--)
296  {
297  cf = 2.0 * (k + 1.0) * cf1 / z - cf2;
298  if (k <= nm)
299  {
300  cj[k] = cf;
301  }
302  cf2 = cf1;
303  cf1 = cf;
304  }
305  if (std::abs (cbj0) > std::abs (cbj1) )
306  {
307  cs = cbj0 / cf;
308  }
309  else
310  {
311  cs = cbj1 / cf2;
312  }
313  for (k = 0; k <= nm; k++)
314  {
315  cj[k] *= cs;
316  }
317  }
318  for (k = 2; k <= nm; k++)
319  {
320  cjp[k] = cj[k - 1] - (double) k * cj[k] / z;
321  }
322  ya0 = std::abs (cby0);
323  lb = 0;
324  cg0 = cby0;
325  cg1 = cby1;
326  for (k = 2; k <= nm; k++)
327  {
328  cyk = 2.0 * (k - 1.0) * cg1 / z - cg0;
329  yak = std::abs (cyk);
330  ya1 = std::abs (cg0);
331  if ( (yak < ya0) && (yak < ya1) )
332  {
333  lb = k;
334  }
335  cy[k] = cyk;
336  cg0 = cg1;
337  cg1 = cyk;
338  }
339  lb0 = 0;
340  if ( (lb > 4) && (imag (z) != 0.0) )
341  {
342  while (lb != lb0)
343  {
344  ch2 = cone;
345  ch1 = czero;
346  lb0 = lb;
347  for (k = lb; k >= 1; k--)
348  {
349  ch0 = 2.0 * k * ch1 / z - ch2;
350  ch2 = ch1;
351  ch1 = ch0;
352  }
353  cp12 = ch0;
354  cp22 = ch2;
355  ch2 = czero;
356  ch1 = cone;
357  for (k = lb; k >= 1; k--)
358  {
359  ch0 = 2.0 * k * ch1 / z - ch2;
360  ch2 = ch1;
361  ch1 = ch0;
362  }
363  cp11 = ch0;
364  cp21 = ch2;
365  if (lb == nm)
366  {
367  cj[lb + 1] = 2.0 * lb * cj[lb] / z - cj[lb - 1];
368  }
369  if (std::abs (cj[0]) > std::abs (cj[1]) )
370  {
371  cy[lb + 1] = (cj[lb + 1] * cby0 - 2.0 * cp11 / (M_PI * z) ) / cj[0];
372  cy[lb] = (cj[lb] * cby0 + 2.0 * cp12 / (M_PI * z) ) / cj[0];
373  }
374  else
375  {
376  cy[lb + 1] = (cj[lb + 1] * cby1 - 2.0 * cp21 / (M_PI * z) ) / cj[1];
377  cy[lb] = (cj[lb] * cby1 + 2.0 * cp22 / (M_PI * z) ) / cj[1];
378  }
379  cyl2 = cy[lb + 1];
380  cyl1 = cy[lb];
381  for (k = lb - 1; k >= 0; k--)
382  {
383  cylk = 2.0 * (k + 1.0) * cyl1 / z - cyl2;
384  cy[k] = cylk;
385  cyl2 = cyl1;
386  cyl1 = cylk;
387  }
388  cyl1 = cy[lb];
389  cyl2 = cy[lb + 1];
390  for (k = lb + 1; k < n; k++)
391  {
392  cylk = 2.0 * k * cyl2 / z - cyl1;
393  cy[k + 1] = cylk;
394  cyl1 = cyl2;
395  cyl2 = cylk;
396  }
397  for (k = 2; k <= nm; k++)
398  {
399  wa = std::abs (cy[k]);
400  if (wa < std::abs (cy[k - 1]) )
401  {
402  lb = k;
403  }
404  }
405  }
406  }
407  for (k = 2; k <= nm; k++)
408  {
409  cyp[k] = cy[k - 1] - (double) k * cy[k] / z;
410  }
411  return 0;
412 }
413 
414 int cbessjynb (int n, std::complex<double> z, int& nm, std::complex<double>* cj,
415  std::complex<double>* cy, std::complex<double>* cjp, std::complex<double>* cyp)
416 {
417  std::complex<double> cf, cf0, cf1, cf2, cbs, csu, csv, cs0, ce;
418  std::complex<double> ct1, cp0, cq0, cp1, cq1, cu, cbj0, cby0, cbj1, cby1;
419  std::complex<double> cyy, cbjk, ct2;
420  double a0, y0;
421  int k, m;
422  static double a[] =
423  {
424  -0.7031250000000000e-1,
425  0.1121520996093750,
426  -0.5725014209747314,
427  6.074042001273483
428  };
429  static double b[] =
430  {
431  0.7324218750000000e-1,
432  -0.2271080017089844,
433  1.727727502584457,
434  -2.438052969955606e1
435  };
436  static double a1[] =
437  {
438  0.1171875,
439  -0.1441955566406250,
440  0.6765925884246826,
441  -6.883914268109947
442  };
443  static double b1[] =
444  {
445  -0.1025390625,
446  0.2775764465332031,
447  -1.993531733751297,
448  2.724882731126854e1
449  };
450 
451  y0 = std::abs (imag (z) );
452  a0 = std::abs (z);
453  nm = n;
454  if (a0 < 1.0e-100)
455  {
456  for (k = 0; k <= n; k++)
457  {
458  cj[k] = czero;
459  cy[k] = std::complex<double> (-1e308, 0);
460  cjp[k] = czero;
461  cyp[k] = std::complex<double> (1e308, 0);
462  }
463  cj[0] = cone;
464  cjp[1] = std::complex<double> (0.5, 0.0);
465  return 0;
466  }
467  if ( (a0 <= 300.0) || (n > (int) (0.25 * a0) ) )
468  {
469  if (n == 0)
470  {
471  nm = 1;
472  }
473  m = msta1 (a0, 200);
474  if (m < nm)
475  {
476  nm = m;
477  }
478  else
479  {
480  m = msta2 (a0, nm, 15);
481  }
482  cbs = czero;
483  csu = czero;
484  csv = czero;
485  cf2 = czero;
486  cf1 = std::complex<double> (1.0e-100, 0.0);
487  for (k = m; k >= 0; k--)
488  {
489  cf = 2.0 * (k + 1.0) * cf1 / z - cf2;
490  if (k <= nm)
491  {
492  cj[k] = cf;
493  }
494  if ( ( (k & 1) == 0) && (k != 0) )
495  {
496  if (y0 <= 1.0)
497  {
498  cbs += 2.0 * cf;
499  }
500  else
501  {
502  cbs += (-1) * ( (k & 2) - 1) * 2.0 * cf;
503  }
504  csu += (double) ( (-1) * ( (k & 2) - 1) ) * cf / (double) k;
505  }
506  else if (k > 1)
507  {
508  csv += (double) ( (-1) * ( (k & 2) - 1) * k) * cf / (double) (k * k - 1.0);
509  }
510  cf2 = cf1;
511  cf1 = cf;
512  }
513  if (y0 <= 1.0)
514  {
515  cs0 = cbs + cf;
516  }
517  else
518  {
519  cs0 = (cbs + cf) / std::cos (z);
520  }
521  for (k = 0; k <= nm; k++)
522  {
523  cj[k] /= cs0;
524  }
525  ce = std::log (0.5 * z) + el;
526  cy[0] = M_2_PI * (ce * cj[0] - 4.0 * csu / cs0);
527  cy[1] = M_2_PI * (-cj[0] / z + (ce - 1.0) * cj[1] - 4.0 * csv / cs0);
528  }
529  else
530  {
531  ct1 = z - M_PI_4;
532  cp0 = cone;
533  for (k = 0; k < 4; k++)
534  {
535  cp0 += a[k] * std::pow (z, -2.0 * k - 2.0);
536  }
537  cq0 = -0.125 / z;
538  for (k = 0; k < 4; k++)
539  {
540  cq0 += b[k] * std::pow (z, -2.0 * k - 3.0);
541  }
542  cu = std::sqrt (M_2_PI / z);
543  cbj0 = cu * (cp0 * std::cos (ct1) - cq0 * std::sin (ct1) );
544  cby0 = cu * (cp0 * std::sin (ct1) + cq0 * std::cos (ct1) );
545  cj[0] = cbj0;
546  cy[0] = cby0;
547  ct2 = z - 0.75 * M_PI;
548  cp1 = cone;
549  for (k = 0; k < 4; k++)
550  {
551  cp1 += a1[k] * std::pow (z, -2.0 * k - 2.0);
552  }
553  cq1 = 0.375 / z;
554  for (k = 0; k < 4; k++)
555  {
556  cq1 += b1[k] * std::pow (z, -2.0 * k - 3.0);
557  }
558  cbj1 = cu * (cp1 * std::cos (ct2) - cq1 * std::sin (ct2) );
559  cby1 = cu * (cp1 * std::sin (ct2) + cq1 * std::cos (ct2) );
560  cj[1] = cbj1;
561  cy[1] = cby1;
562  for (k = 2; k <= n; k++)
563  {
564  cbjk = 2.0 * (k - 1.0) * cbj1 / z - cbj0;
565  cj[k] = cbjk;
566  cbj0 = cbj1;
567  cbj1 = cbjk;
568  }
569  }
570  cjp[0] = -cj[1];
571  for (k = 1; k <= nm; k++)
572  {
573  cjp[k] = cj[k - 1] - (double) k * cj[k] / z;
574  }
575  if (std::abs (cj[0]) > 1.0)
576  {
577  cy[1] = (cj[1] * cy[0] - 2.0 / (M_PI * z) ) / cj[0];
578  }
579  for (k = 2; k <= nm; k++)
580  {
581  if (std::abs (cj[k - 1]) >= std::abs (cj[k - 2]) )
582  {
583  cyy = (cj[k] * cy[k - 1] - 2.0 / (M_PI * z) ) / cj[k - 1];
584  }
585  else
586  {
587  cyy = (cj[k] * cy[k - 2] - 4.0 * (k - 1.0) / (M_PI * z * z) ) / cj[k - 2];
588  }
589  cy[k] = cyy;
590  }
591  cyp[0] = -cy[1];
592  for (k = 1; k <= nm; k++)
593  {
594  cyp[k] = cy[k - 1] - (double) k * cy[k] / z;
595  }
596 
597  return 0;
598 }
599 
600 int cbessjyva (double v, std::complex<double> z, double& vm, std::complex<double>* cjv,
601  std::complex<double>* cyv, std::complex<double>* cjvp, std::complex<double>* cyvp)
602 {
603  std::complex<double> z1, z2, zk, cjvl, cr, ca, cjv0, cjv1, cpz, crp;
604  std::complex<double> cqz, crq, ca0, cck, csk, cyv0, cyv1, cju0, cju1, cb;
605  std::complex<double> cs, cs0, cr0, cs1, cr1, cec, cf, cf0, cf1, cf2;
606  std::complex<double> cfac0, cfac1, cg0, cg1, cyk, cp11, cp12, cp21, cp22;
607  std::complex<double> ch0, ch1, ch2, cyl1, cyl2, cylk;
608 
609  double a0, v0, pv0, pv1, vl, ga, gb, vg, vv, w0, w1, ya0, yak, ya1, wa;
610  int j, n, k, kz, l, lb, lb0, m;
611 
612  a0 = std::abs (z);
613  z1 = z;
614  z2 = z * z;
615  n = (int) v;
616 
617 
618  v0 = v - n;
619 
620  pv0 = M_PI * v0;
621  pv1 = M_PI * (1.0 + v0);
622  if (a0 < 1.0e-100)
623  {
624  for (k = 0; k <= n; k++)
625  {
626  cjv[k] = czero;
627  cyv[k] = std::complex<double> (-1e308, 0);
628  cjvp[k] = czero;
629  cyvp[k] = std::complex<double> (1e308, 0);
630 
631  }
632  if (v0 == 0.0)
633  {
634  cjv[0] = cone;
635  cjvp[1] = std::complex<double> (0.5, 0.0);
636  }
637  else
638  {
639  cjvp[0] = std::complex<double> (1e308, 0);
640  }
641  vm = v;
642  return 0;
643  }
644  if (real (z1) < 0.0)
645  {
646  z1 = -z;
647  }
648  if (a0 <= 12.0)
649  {
650  for (l = 0; l < 2; l++)
651  {
652  vl = v0 + l;
653  cjvl = cone;
654  cr = cone;
655  for (k = 1; k <= 40; k++)
656  {
657  cr *= -0.25 * z2 / (k * (k + vl) );
658  cjvl += cr;
659  if (std::abs (cr) < std::abs (cjvl) *eps)
660  {
661  break;
662  }
663  }
664  vg = 1.0 + vl;
665  ga = gamma (vg);
666  ca = std::pow (0.5 * z1, vl) / ga;
667  if (l == 0)
668  {
669  cjv0 = cjvl * ca;
670  }
671  else
672  {
673  cjv1 = cjvl * ca;
674  }
675  }
676  }
677  else
678  {
679  if (a0 >= 50.0)
680  {
681  kz = 8;
682  }
683  else if (a0 >= 35.0)
684  {
685  kz = 10;
686  }
687  else
688  {
689  kz = 11;
690  }
691  for (j = 0; j < 2; j++)
692  {
693  vv = 4.0 * (j + v0) * (j + v0);
694  cpz = cone;
695  crp = cone;
696  for (k = 1; k <= kz; k++)
697  {
698  crp = -0.78125e-2 * crp * (vv - std::pow (4.0 * k - 3.0, 2.0) ) *
699  (vv - std::pow (4.0 * k - 1.0, 2.0) ) / (k * (2.0 * k - 1.0) * z2);
700  cpz += crp;
701  }
702  cqz = cone;
703  crq = cone;
704  for (k = 1; k <= kz; k++)
705  {
706  crq = -0.78125e-2 * crq * (vv - std::pow (4.0 * k - 1.0, 2.0) ) *
707  (vv - std::pow (4.0 * k + 1.0, 2.0) ) / (k * (2.0 * k + 1.0) * z2);
708  cqz += crq;
709  }
710  cqz *= 0.125 * (vv - 1.0) / z1;
711  zk = z1 - (0.5 * (j + v0) + 0.25) * M_PI;
712  ca0 = std::sqrt (M_2_PI / z1);
713  cck = std::cos (zk);
714  csk = std::sin (zk);
715  if (j == 0)
716  {
717  cjv0 = ca0 * (cpz * cck - cqz * csk);
718  cyv0 = ca0 * (cpz * csk + cqz + cck);
719  }
720  else
721  {
722  cjv1 = ca0 * (cpz * cck - cqz * csk);
723  cyv1 = ca0 * (cpz * csk + cqz * cck);
724  }
725  }
726  }
727  if (a0 <= 12.0)
728  {
729  if (v0 != 0.0)
730  {
731  for (l = 0; l < 2; l++)
732  {
733  vl = v0 + l;
734  cjvl = cone;
735  cr = cone;
736  for (k = 1; k <= 40; k++)
737  {
738  cr *= -0.25 * z2 / (k * (k - vl) );
739  cjvl += cr;
740  if (std::abs (cr) < std::abs (cjvl) *eps)
741  {
742  break;
743  }
744  }
745  vg = 1.0 - vl;
746  gb = gamma (vg);
747  cb = std::pow (2.0 / z1, vl) / gb;
748  if (l == 0)
749  {
750  cju0 = cjvl * cb;
751  }
752  else
753  {
754  cju1 = cjvl * cb;
755  }
756  }
757  cyv0 = (cjv0 * std::cos (pv0) - cju0) / std::sin (pv0);
758  cyv1 = (cjv1 * std::cos (pv1) - cju1) / std::sin (pv1);
759  }
760  else
761  {
762  cec = std::log (0.5 * z1) + el;
763  cs0 = czero;
764  w0 = 0.0;
765  cr0 = cone;
766  for (k = 1; k <= 30; k++)
767  {
768  w0 += 1.0 / k;
769  cr0 *= -0.25 * z2 / (double) (k * k);
770  cs0 += cr0 * w0;
771  }
772  cyv0 = M_2_PI * (cec * cjv0 - cs0);
773  cs1 = cone;
774  w1 = 0.0;
775  cr1 = cone;
776  for (k = 1; k <= 30; k++)
777  {
778  w1 += 1.0 / k;
779  cr1 *= -0.25 * z2 / (k * (k + 1.0) );
780  cs1 += cr1 * (2.0 * w1 + 1.0 / (k + 1.0) );
781  }
782  cyv1 = M_2_PI * (cec * cjv1 - 1.0 / z1 - 0.25 * z1 * cs1);
783  }
784  }
785  if (real (z) < 0.0)
786  {
787  cfac0 = std::exp (pv0 * cii);
788  cfac1 = std::exp (pv1 * cii);
789  if (imag (z) < 0.0)
790  {
791  cyv0 = cfac0 * cyv0 - 2.0 * cii * std::cos (pv0) * cjv0;
792  cyv1 = cfac1 * cyv1 - 2.0 * cii * std::cos (pv1) * cjv1;
793  cjv0 /= cfac0;
794  cjv1 /= cfac1;
795  }
796  else if (imag (z) > 0.0)
797  {
798  cyv0 = cyv0 / cfac0 + 2.0 * cii * std::cos (pv0) * cjv0;
799  cyv1 = cyv1 / cfac1 + 2.0 * cii * std::cos (pv1) * cjv1;
800  cjv0 *= cfac0;
801  cjv1 *= cfac1;
802  }
803  }
804  cjv[0] = cjv0;
805  cjv[1] = cjv1;
806  if ( (n >= 2) && (n <= (int) (0.25 * a0) ) )
807  {
808  cf0 = cjv0;
809  cf1 = cjv1;
810  for (k = 2; k <= n; k++)
811  {
812  cf = 2.0 * (k + v0 - 1.0) * cf1 / z - cf0;
813  cjv[k] = cf;
814  cf0 = cf1;
815  cf1 = cf;
816  }
817  }
818  else if (n >= 2)
819  {
820  m = msta1 (a0, 200);
821  if (m < n)
822  {
823  n = m;
824  }
825  else
826  {
827  m = msta2 (a0, n, 15);
828  }
829  cf2 = czero;
830  cf1 = std::complex<double> (1.0e-100, 0.0);
831  for (k = m; k >= 0; k--)
832  {
833  cf = 2.0 * (v0 + k + 1.0) * cf1 / z - cf2;
834  if (k <= n)
835  {
836  cjv[k] = cf;
837  }
838  cf2 = cf1;
839  cf1 = cf;
840  }
841  if (std::abs (cjv0) > std::abs (cjv1) )
842  {
843  cs = cjv0 / cf;
844  }
845  else
846  {
847  cs = cjv1 / cf2;
848  }
849  for (k = 0; k <= n; k++)
850  {
851  cjv[k] *= cs;
852  }
853  }
854  cjvp[0] = v0 * cjv[0] / z - cjv[1];
855  for (k = 1; k <= n; k++)
856  {
857  cjvp[k] = - (k + v0) * cjv[k] / z + cjv[k - 1];
858  }
859  cyv[0] = cyv0;
860  cyv[1] = cyv1;
861  ya0 = std::abs (cyv0);
862  lb = 0;
863  cg0 = cyv0;
864  cg1 = cyv1;
865  for (k = 2; k <= n; k++)
866  {
867  cyk = 2.0 * (v0 + k - 1.0) * cg1 / z - cg0;
868  yak = std::abs (cyk);
869  ya1 = std::abs (cg0);
870  if ( (yak < ya0) && (yak < ya1) )
871  {
872  lb = k;
873  }
874  cyv[k] = cyk;
875  cg0 = cg1;
876  cg1 = cyk;
877  }
878  lb0 = 0;
879  if ( (lb > 4) && (imag (z) != 0.0) )
880  {
881  while (lb != lb0)
882  {
883  ch2 = cone;
884  ch1 = czero;
885  lb0 = lb;
886  for (k = lb; k >= 1; k--)
887  {
888  ch0 = 2.0 * (k + v0) * ch1 / z - ch2;
889  ch2 = ch1;
890  ch1 = ch0;
891  }
892  cp12 = ch0;
893  cp22 = ch2;
894  ch2 = czero;
895  ch1 = cone;
896  for (k = lb; k >= 1; k--)
897  {
898  ch0 = 2.0 * (k + v0) * ch1 / z - ch2;
899  ch2 = ch1;
900  ch1 = ch0;
901  }
902  cp11 = ch0;
903  cp21 = ch2;
904  if (lb == n)
905  {
906  cjv[lb + 1] = 2.0 * (lb + v0) * cjv[lb] / z - cjv[lb - 1];
907  }
908  if (std::abs (cjv[0]) > std::abs (cjv[1]) )
909  {
910  cyv[lb + 1] = (cjv[lb + 1] * cyv0 - 2.0 * cp11 / (M_PI * z) ) / cjv[0];
911  cyv[lb] = (cjv[lb] * cyv0 + 2.0 * cp12 / (M_PI * z) ) / cjv[0];
912  }
913  else
914  {
915  cyv[lb + 1] = (cjv[lb + 1] * cyv1 - 2.0 * cp21 / (M_PI * z) ) / cjv[1];
916  cyv[lb] = (cjv[lb] * cyv1 + 2.0 * cp22 / (M_PI * z) ) / cjv[1];
917  }
918  cyl2 = cyv[lb + 1];
919  cyl1 = cyv[lb];
920  for (k = lb - 1; k >= 0; k--)
921  {
922  cylk = 2.0 * (k + v0 + 1.0) * cyl1 / z - cyl2;
923  cyv[k] = cylk;
924  cyl2 = cyl1;
925  cyl1 = cylk;
926  }
927  cyl1 = cyv[lb];
928  cyl2 = cyv[lb + 1];
929  for (k = lb + 1; k < n; k++)
930  {
931  cylk = 2.0 * (k + v0) * cyl2 / z - cyl1;
932  cyv[k + 1] = cylk;
933  cyl1 = cyl2;
934  cyl2 = cylk;
935  }
936  for (k = 2; k <= n; k++)
937  {
938  wa = std::abs (cyv[k]);
939  if (wa < std::abs (cyv[k - 1]) )
940  {
941  lb = k;
942  }
943  }
944  }
945  }
946  cyvp[0] = v0 * cyv[0] / z - cyv[1];
947  for (k = 1; k <= n; k++)
948  {
949  cyvp[k] = cyv[k - 1] - (k + v0) * cyv[k] / z;
950  }
951  vm = n + v0;
952  return 0;
953 }
954 }
#define eps
Definition: bessel.hpp:14
int msta1(double x, int mp)
Definition: bessjy.cpp:312
static std::complex< double > cii(0.0, 1.0)
int msta2(double x, int n, int mp)
Definition: bessjy.cpp:337
Definition: bessik.cpp:9
int cbessjyva(double v, std::complex< double > z, double &vm, std::complex< double > *cjv, std::complex< double > *cyv, std::complex< double > *cjvp, std::complex< double > *cyvp)
Definition: cbessjy.cpp:600
#define M_PI
Definition: winmath.h:20
static std::complex< double > czero(0.0, 0.0)
double gamma(double x)
Definition: gamma.cpp:15
int cbessjy01(std::complex< double > z, std::complex< double > &cj0, std::complex< double > &cj1, std::complex< double > &cy0, std::complex< double > &cy1, std::complex< double > &cj0p, std::complex< double > &cj1p, std::complex< double > &cy0p, std::complex< double > &cy1p)
Definition: cbessjy.cpp:18
int cbessjynb(int n, std::complex< double > z, int &nm, std::complex< double > *cj, std::complex< double > *cy, std::complex< double > *cjp, std::complex< double > *cyp)
Definition: cbessjy.cpp:414
int cbessjyna(int n, std::complex< double > z, int &nm, std::complex< double > *cj, std::complex< double > *cy, std::complex< double > *cjp, std::complex< double > *cyp)
Definition: cbessjy.cpp:233
#define el
Definition: bessel.hpp:15
static std::complex< double > cone(1.0, 0.0)