spencef.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* spencef.c
  2. *
  3. * Dilogarithm
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float x, y, spencef();
  10. *
  11. * y = spencef( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Computes the integral
  18. *
  19. * x
  20. * -
  21. * | | log t
  22. * spence(x) = - | ----- dt
  23. * | | t - 1
  24. * -
  25. * 1
  26. *
  27. * for x >= 0. A rational approximation gives the integral in
  28. * the interval (0.5, 1.5). Transformation formulas for 1/x
  29. * and 1-x are employed outside the basic expansion range.
  30. *
  31. *
  32. *
  33. * ACCURACY:
  34. *
  35. * Relative error:
  36. * arithmetic domain # trials peak rms
  37. * IEEE 0,4 30000 4.4e-7 6.3e-8
  38. *
  39. *
  40. */
  41. /* spence.c */
  42. /*
  43. Cephes Math Library Release 2.1: January, 1989
  44. Copyright 1985, 1987, 1989 by Stephen L. Moshier
  45. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  46. */
  47. #include <math.h>
  48. static float A[8] = {
  49. 4.65128586073990045278E-5,
  50. 7.31589045238094711071E-3,
  51. 1.33847639578309018650E-1,
  52. 8.79691311754530315341E-1,
  53. 2.71149851196553469920E0,
  54. 4.25697156008121755724E0,
  55. 3.29771340985225106936E0,
  56. 1.00000000000000000126E0,
  57. };
  58. static float B[8] = {
  59. 6.90990488912553276999E-4,
  60. 2.54043763932544379113E-2,
  61. 2.82974860602568089943E-1,
  62. 1.41172597751831069617E0,
  63. 3.63800533345137075418E0,
  64. 5.03278880143316990390E0,
  65. 3.54771340985225096217E0,
  66. 9.99999999999999998740E-1,
  67. };
  68. extern float PIF, MACHEPF;
  69. /* pi * pi / 6 */
  70. #define PIFS 1.64493406684822643647
  71. float logf(float), polevlf(float, float *, int);
  72. float spencef(float xx)
  73. {
  74. float x, w, y, z;
  75. int flag;
  76. x = xx;
  77. if( x < 0.0 )
  78. {
  79. mtherr( "spencef", DOMAIN );
  80. return(0.0);
  81. }
  82. if( x == 1.0 )
  83. return( 0.0 );
  84. if( x == 0.0 )
  85. return( PIFS );
  86. flag = 0;
  87. if( x > 2.0 )
  88. {
  89. x = 1.0/x;
  90. flag |= 2;
  91. }
  92. if( x > 1.5 )
  93. {
  94. w = (1.0/x) - 1.0;
  95. flag |= 2;
  96. }
  97. else if( x < 0.5 )
  98. {
  99. w = -x;
  100. flag |= 1;
  101. }
  102. else
  103. w = x - 1.0;
  104. y = -w * polevlf( w, A, 7) / polevlf( w, B, 7 );
  105. if( flag & 1 )
  106. y = PIFS - logf(x) * logf(1.0-x) - y;
  107. if( flag & 2 )
  108. {
  109. z = logf(x);
  110. y = -0.5 * z * z - y;
  111. }
  112. return( y );
  113. }