|
STK++ 1.0
|
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