karbon

vglobal.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001, The Karbon Developers
3 Copyright (C) 2002, The Karbon Developers
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21
22#include <math.h>
23
24#include "vglobal.h"
25
26
27int
28VGlobal::binomialCoeff( unsigned n, unsigned k )
29{
30 return
31 static_cast<int>(
32 0.5 +
33 exp(
34 factorialLn( n ) -
35 factorialLn( k ) -
36 factorialLn( n - k ) ) );
37}
38
39double
40VGlobal::factorialLn( unsigned n )
41{
42 const unsigned cacheSize = 100;
43
44 // A static array is initalized to zero.
45 static double cache[ cacheSize ];
46
47
48 if( n <= 1 )
49 return 0.0;
50
51 if( n <= cacheSize - 1 )
52 {
53 return cache[ n ]
54 ? cache[ n ]
55 : ( cache[ n ] = gammaLn( n + 1.0 ) );
56 }
57 else
58 {
59 return gammaLn( n + 1.0 );
60 }
61}
62
63double
64VGlobal::gammaLn( double x )
65{
66 static double coeff[ 6 ] =
67 {
68 76.18009172947146,
69 -86.50532032941677,
70 24.01409824083091,
71 -1.231739572450155,
72 0.1208650973866179e-2,
73 -0.5395239384953e-5
74 };
75
76 double y = x;
77
78 double tmp = x + 5.5;
79 tmp -= ( x + 0.5 ) * log( tmp );
80
81 double ser = 1.000000000190015;
82
83 for( int i = 0; i < 5; ++i )
84 {
85 ser += coeff[ i ] / ++y;
86 }
87
88 return -tmp + log( 2.5066282746310005 * ser / x );
89}
90