Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/2.5.0/ALGLIB-2.5.0/psif.cs @ 3932

Last change on this file since 3932 was 3839, checked in by mkommend, 15 years ago

implemented first version of LR (ticket #1012)

File size: 5.4 KB
Line 
1/*************************************************************************
2Cephes Math Library Release 2.8:  June, 2000
3Copyright by Stephen L. Moshier
4
5Contributors:
6    * Sergey Bochkanov (ALGLIB project). Translation from C to
7      pseudocode.
8
9See subroutines comments for additional copyrights.
10
11>>> SOURCE LICENSE >>>
12This program is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation (www.fsf.org); either version 2 of the
15License, or (at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20GNU General Public License for more details.
21
22A copy of the GNU General Public License is available at
23http://www.fsf.org/licensing/licenses
24
25>>> END OF LICENSE >>>
26*************************************************************************/
27
28using System;
29
30namespace alglib
31{
32    public class psif
33    {
34        /*************************************************************************
35        Psi (digamma) function
36
37                     d      -
38          psi(x)  =  -- ln | (x)
39                     dx
40
41        is the logarithmic derivative of the gamma function.
42        For integer x,
43                          n-1
44                           -
45        psi(n) = -EUL  +   >  1/k.
46                           -
47                          k=1
48
49        This formula is used for 0 < n <= 10.  If x is negative, it
50        is transformed to a positive argument by the reflection
51        formula  psi(1-x) = psi(x) + pi cot(pi x).
52        For general positive x, the argument is made greater than 10
53        using the recurrence  psi(x+1) = psi(x) + 1/x.
54        Then the following asymptotic expansion is applied:
55
56                                  inf.   B
57                                   -      2k
58        psi(x) = log(x) - 1/2x -   >   -------
59                                   -        2k
60                                  k=1   2k x
61
62        where the B2k are Bernoulli numbers.
63
64        ACCURACY:
65           Relative error (except absolute when |psi| < 1):
66        arithmetic   domain     # trials      peak         rms
67           IEEE      0,30        30000       1.3e-15     1.4e-16
68           IEEE      -30,0       40000       1.5e-15     2.2e-16
69
70        Cephes Math Library Release 2.8:  June, 2000
71        Copyright 1984, 1987, 1992, 2000 by Stephen L. Moshier
72        *************************************************************************/
73        public static double psi(double x)
74        {
75            double result = 0;
76            double p = 0;
77            double q = 0;
78            double nz = 0;
79            double s = 0;
80            double w = 0;
81            double y = 0;
82            double z = 0;
83            double polv = 0;
84            int i = 0;
85            int n = 0;
86            int negative = 0;
87
88            negative = 0;
89            nz = 0.0;
90            if( (double)(x)<=(double)(0) )
91            {
92                negative = 1;
93                q = x;
94                p = (int)Math.Floor(q);
95                if( (double)(p)==(double)(q) )
96                {
97                    System.Diagnostics.Debug.Assert(false, "Singularity in Psi(x)");
98                    result = AP.Math.MaxRealNumber;
99                    return result;
100                }
101                nz = q-p;
102                if( (double)(nz)!=(double)(0.5) )
103                {
104                    if( (double)(nz)>(double)(0.5) )
105                    {
106                        p = p+1.0;
107                        nz = q-p;
108                    }
109                    nz = Math.PI/Math.Tan(Math.PI*nz);
110                }
111                else
112                {
113                    nz = 0.0;
114                }
115                x = 1.0-x;
116            }
117            if( (double)(x)<=(double)(10.0) & (double)(x)==(double)((int)Math.Floor(x)) )
118            {
119                y = 0.0;
120                n = (int)Math.Floor(x);
121                for(i=1; i<=n-1; i++)
122                {
123                    w = i;
124                    y = y+1.0/w;
125                }
126                y = y-0.57721566490153286061;
127            }
128            else
129            {
130                s = x;
131                w = 0.0;
132                while( (double)(s)<(double)(10.0) )
133                {
134                    w = w+1.0/s;
135                    s = s+1.0;
136                }
137                if( (double)(s)<(double)(1.0E17) )
138                {
139                    z = 1.0/(s*s);
140                    polv = 8.33333333333333333333E-2;
141                    polv = polv*z-2.10927960927960927961E-2;
142                    polv = polv*z+7.57575757575757575758E-3;
143                    polv = polv*z-4.16666666666666666667E-3;
144                    polv = polv*z+3.96825396825396825397E-3;
145                    polv = polv*z-8.33333333333333333333E-3;
146                    polv = polv*z+8.33333333333333333333E-2;
147                    y = z*polv;
148                }
149                else
150                {
151                    y = 0.0;
152                }
153                y = Math.Log(s)-0.5/s-y-w;
154            }
155            if( negative!=0 )
156            {
157                y = y-nz;
158            }
159            result = y;
160            return result;
161        }
162    }
163}
Note: See TracBrowser for help on using the repository browser.