Advertisement
homer512

Kahan C

Jul 26th, 2014
311
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.90 KB | None | 0 0
  1. #include <stdio.h>
  2. /* using printf */
  3.  
  4.  
  5. #define KAHAN_ACCUMULATE(type, sum, compensation, added) \
  6.   do {                           \
  7.   type _y = (added) - compensation;          \
  8.   type _t = sum + _y;                    \
  9.   compensation = (_t - sum) - _y;            \
  10.   sum = _t;                      \
  11.   } while(0);
  12.  
  13. struct Accumulator
  14. {
  15.   double sum, compensation;
  16. };
  17.  
  18. void accumulator_init(struct Accumulator* self)
  19. {
  20.   self->sum = self->compensation = 0.;
  21. }
  22.  
  23. double accumulator_add(struct Accumulator* self, double added)
  24. {
  25.   KAHAN_ACCUMULATE(double, self->sum, self->compensation, added);
  26.   return self->sum;
  27. }
  28.  
  29. double accumulator_sum(const struct Accumulator* self)
  30. {
  31.   return self->sum;
  32. }
  33.  
  34. struct AccumulatorF
  35. {
  36.   float sum, compensation;
  37. };
  38.  
  39. void accumulatorf_init(struct AccumulatorF* self)
  40. {
  41.   self->sum = self->compensation = 0.f;
  42. }
  43.  
  44. float accumulatorf_add(struct AccumulatorF* self, float added)
  45. {
  46.   KAHAN_ACCUMULATE(float, self->sum, self->compensation, added);
  47.   return self->sum;
  48. }
  49.  
  50. float accumulatorf_sum(const struct AccumulatorF* self)
  51. {
  52.   return self->sum;
  53. }
  54.  
  55. double test_accumulation(long start, long end, long step)
  56. {
  57.   long i;
  58.   struct Accumulator adder;
  59.   accumulator_init(&adder);
  60.   for(i = start; i != end; i += step)
  61.     accumulator_add(&adder, 1. / (((double) i) * i));
  62.   return accumulator_sum(&adder);
  63. }
  64.  
  65. float test_accumulationf(long start, long end, long step)
  66. {
  67.   long i;
  68.   struct AccumulatorF adder;
  69.   accumulatorf_init(&adder);
  70.   for(i = start; i != end; i += step)
  71.     accumulatorf_add(&adder, 1.f / (((float) i) * i));
  72.   return accumulatorf_sum(&adder);
  73. }
  74.  
  75. /*
  76.  * Demonstration of the Kahan summation algorithm
  77.  */
  78. int main()
  79. {
  80.   printf("%.8f\n", (double) test_accumulationf(1, 100000001, 1));
  81.   printf("%.8f\n", (double) test_accumulationf(100000000, 0, -1));
  82.   printf("%.8f\n", test_accumulation(1, 100000001, 1));
  83.   printf("%.8f\n", test_accumulation(100000000, 0, -1));
  84.   return 0;
  85. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement