STK++ 1.0
STK_Funct_erf_raw.cpp
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------*/
00002 /*  Copyright (C) 2004-2007  Serge Iovleff
00003     
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU Lesser General Public License as
00006     published by the Free Software Foundation; either version 2 of the
00007     License, or (at your option) any later version.
00008     
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU Lesser General Public License for more details.
00013     
00014     You should have received a copy of the GNU Lesser General Public
00015     License along with this program; if not, write to the
00016     Free Software Foundation, Inc.,
00017     59 Temple Place,
00018     Suite 330,
00019     Boston, MA 02111-1307
00020     USA
00021     
00022     Contact : Serge.Iovleff@stkpp.org
00023 */
00024 
00025 /*
00026  Cephes Math Library Release 2.2:  June, 1992
00027  Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
00028  Direct inquiries to 30 Frost Street, Cambridge, MA 02140
00029  */
00030 
00031 /*
00032  * Project:  Analysis
00033  * Purpose:  Implementation of the erf and erfc functions
00034  * Author:   Serge Iovleff, serge.iovleff@stkpp.org
00035  *
00036  **/
00037 
00043 #include <cmath>
00044 
00045 // for Integer and Real
00046 #include "../../STKernel/include/STK_Integer.h"
00047 #include "../../STKernel/include/STK_Real.h"
00048 #include "../../STKernel/include/STK_Misc.h"
00049 
00050 #include "../include/STK_Const_Math.h"
00051 
00052 #include "../include/STK_Funct_raw.h"
00053 
00054 namespace STK
00055 {
00056 namespace Funct
00057 {
00058 
00059 static Real P[9] =
00060 { 2.46196981473530512524E-10,
00061   5.64189564831068821977E-1,
00062   7.46321056442269912687E0,
00063   4.86371970985681366614E1,
00064   1.96520832956077098242E2,
00065   5.26445194995477358631E2,
00066   9.34528527171957607540E2,
00067   1.02755188689515710272E3,
00068   5.57535335369399327526E2
00069 };
00070 
00071 static Real Q[8] =
00072 {
00073   /* 1.00000000000000000000E0,*/
00074   1.32281951154744992508E1,
00075   8.67072140885989742329E1,
00076   3.54937778887819891062E2,
00077   9.75708501743205489753E2,
00078   1.82390916687909736289E3,
00079   2.24633760818710981792E3,
00080   1.65666309194161350182E3,
00081   5.57535340817727675546E2
00082 };
00083 
00084 static Real R[6] =
00085 { 5.64189583547755073984E-1,
00086   1.27536670759978104416E0,
00087   5.01905042251180477414E0,
00088   6.16021097993053585195E0,
00089   7.40974269950448939160E0,
00090   2.97886665372100240670E0
00091 };
00092 
00093 static Real S[6] =
00094 {
00095   /* 1.00000000000000000000E0,*/
00096   2.26052863220117276590E0,
00097   9.39603524938001434673E0,
00098   1.20489539808096656605E1,
00099   1.70814450747565897222E1,
00100   9.60896809063285878198E0,
00101   3.36907645100081516050E0
00102 };
00103 
00104 static Real T[5] =
00105 { 9.60497373987051638749E0,
00106   9.00260197203842689217E1,
00107   2.23200534594684319226E3,
00108   7.00332514112805075473E3,
00109   5.55923013010394962768E4
00110 };
00111 
00112 static Real U[5] =
00113 {
00114   /* 1.00000000000000000000E0,*/
00115   3.35617141647503099647E1,
00116   5.21357949780152679795E2,
00117   4.59432382970980127987E3,
00118   2.26290000613890934246E4,
00119   4.92673942608635921086E4
00120 };
00121 
00122 /* inlined poly eval functions */
00123 static inline Real polevl(Real const& x, Real coef[], Integer const& N)
00124 {
00125   Real *p = coef;
00126 
00127   Integer i = N;
00128   Real sum = *p++;
00129   do
00130     sum = sum * x + *p++;
00131   while ( --i);
00132 
00133   return ( sum );
00134 }
00135 
00136 static inline Real p1evl(Real const& x, Real coef[], Integer const& N)
00137 {
00138   Real *p = coef;
00139 
00140   Integer i = N-1;
00141   Real sum = x + *p++;
00142   do
00143     sum = sum * x + *p++;
00144   while ( --i);
00145   
00146   return ( sum );
00147 }
00148 
00157 Real erfc_raw(Real const& a)
00158 {
00159   Real p, q, y;
00160 
00161   Real x = abs(a);
00162   if ( x < 1.0)  return ( 1.0 - erf_raw(a) );
00163 
00164   Real z = exp(-a * a);
00165 
00166   if ( x < 8.0)
00167   {
00168     p = polevl( x, P, 8);
00169     q = p1evl( x, Q, 8);
00170   }
00171   else
00172   {
00173     p = polevl( x, R, 5);
00174     q = p1evl( x, S, 6);
00175   }
00176   y = (z * p)/q;
00177 
00178   if ( a < 0)  y = 2.0 - y;
00179   // result
00180   return (y);
00181 }
00182 
00192 Real erf_raw(Real const& a)
00193 {
00194   if ( abs(a)> 1.0) return ( 1.0 - erfc(a) );
00195   Real z = a * a;
00196   // result
00197   return ( a * polevl( z, T, 4)/ p1evl( z, U, 5 ));
00198 }
00199 
00200 } // namespace Funct
00201   
00202 } // namespace STK