ivf.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* ivf.c
  2. *
  3. * Modified Bessel function of noninteger order
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float v, x, y, ivf();
  10. *
  11. * y = ivf( v, x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns modified Bessel function of order v of the
  18. * argument. If x is negative, v must be integer valued.
  19. *
  20. * The function is defined as Iv(x) = Jv( ix ). It is
  21. * here computed in terms of the confluent hypergeometric
  22. * function, according to the formula
  23. *
  24. * v -x
  25. * Iv(x) = (x/2) e hyperg( v+0.5, 2v+1, 2x ) / gamma(v+1)
  26. *
  27. * If v is a negative integer, then v is replaced by -v.
  28. *
  29. *
  30. * ACCURACY:
  31. *
  32. * Tested at random points (v, x), with v between 0 and
  33. * 30, x between 0 and 28.
  34. * arithmetic domain # trials peak rms
  35. * Relative error:
  36. * IEEE 0,15 3000 4.7e-6 5.4e-7
  37. * Absolute error (relative when function > 1)
  38. * IEEE 0,30 5000 8.5e-6 1.3e-6
  39. *
  40. * Accuracy is diminished if v is near a negative integer.
  41. * The useful domain for relative error is limited by overflow
  42. * of the single precision exponential function.
  43. *
  44. * See also hyperg.c.
  45. *
  46. */
  47. /* iv.c */
  48. /* Modified Bessel function of noninteger order */
  49. /* If x < 0, then v must be an integer. */
  50. /*
  51. Cephes Math Library Release 2.2: June, 1992
  52. Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
  53. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  54. */
  55. #include <math.h>
  56. extern float MAXNUMF;
  57. #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
  58. float hypergf(float, float, float);
  59. float expf(float), gammaf(float), logf(float), floorf(float);
  60. float ivf( float v, float x )
  61. {
  62. int sign;
  63. float t, ax;
  64. /* If v is a negative integer, invoke symmetry */
  65. t = floorf(v);
  66. if( v < 0.0 )
  67. {
  68. if( t == v )
  69. {
  70. v = -v; /* symmetry */
  71. t = -t;
  72. }
  73. }
  74. /* If x is negative, require v to be an integer */
  75. sign = 1;
  76. if( x < 0.0 )
  77. {
  78. if( t != v )
  79. {
  80. mtherr( "ivf", DOMAIN );
  81. return( 0.0 );
  82. }
  83. if( v != 2.0 * floorf(v/2.0) )
  84. sign = -1;
  85. }
  86. /* Avoid logarithm singularity */
  87. if( x == 0.0 )
  88. {
  89. if( v == 0.0 )
  90. return( 1.0 );
  91. if( v < 0.0 )
  92. {
  93. mtherr( "ivf", OVERFLOW );
  94. return( MAXNUMF );
  95. }
  96. else
  97. return( 0.0 );
  98. }
  99. ax = fabsf(x);
  100. t = v * logf( 0.5 * ax ) - x;
  101. t = sign * expf(t) / gammaf( v + 1.0 );
  102. ax = v + 0.5;
  103. return( t * hypergf( ax, 2.0 * ax, 2.0 * x ) );
  104. }