|
STK++ 1.0
|
00001 /*--------------------------------------------------------------------*/ 00002 /* Copyright (C) 2004-2008 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 * Project: STatistiK 00027 * Purpose: Implementation of the Cauchy Distribution 00028 * Author: Serge Iovleff, serge.iovleff@stkpp.org 00029 **/ 00030 00035 #include "../include/STK_Law_Cauchy.h" 00036 00037 namespace STK 00038 { 00039 00040 namespace Law 00041 { 00042 00043 /* constructor */ 00044 Cauchy::Cauchy( Real const& location, Real const& scale) 00045 : ITUnivariate<Real>(String(_T("Cauchy"))) 00046 , location_(location) 00047 , scale_(scale) 00048 { 00049 // check parameters 00050 if ( !Arithmetic<Real>::isFinite(location) 00051 || !Arithmetic<Real>::isFinite(scale) 00052 || scale <= 0 00053 ) 00054 throw domain_error("Cauchy::Cauchy(location, scale) " 00055 "argument error"); 00056 } 00057 00058 /* destructor */ 00059 Cauchy::~Cauchy() 00060 { ;} 00061 00062 /* Generate a pseudo Cauchy random variate. */ 00063 Real Cauchy::rand() const 00064 { 00065 return location_ + scale_ * tan((double)(Const::_PI_ * generator.randUnif())); 00066 } 00067 00068 /* 00069 * Generate a pseudo Cauchy random variate with the specified parameters. 00070 * (static) 00071 */ 00072 Real Cauchy::rand( Real const& location, Real const& scale) 00073 { 00074 // check parameters 00075 if ( !Arithmetic<Real>::isFinite(location) 00076 || !Arithmetic<Real>::isFinite(scale) 00077 || scale <= 0 00078 ) 00079 throw domain_error("Cauchy::Cauchy(location, scale) " 00080 "argument error"); 00081 return location + scale * tan(Const::_PI_ * generator.randUnif()); 00082 } 00083 00084 /* Give the value of the pdf at x.*/ 00085 Real Cauchy::pdf( Real const& x) const 00086 { 00087 // check NA value 00088 if (Arithmetic<Real>::isNA(x)) return Arithmetic<Real>::NA(); 00089 00090 // trivial case 00091 if (Arithmetic<Real>::isInfinite(x)) return 0.0; 00092 00093 // general case 00094 Real y = (x - location_) / scale_; 00095 return 1. / (Const::_PI_ * scale_ * (1. + y * y)); 00096 } 00097 00098 /* Give the value of the log-pdf at x. */ 00099 Real Cauchy::lpdf( Real const& x) const 00100 { 00101 // check NA value 00102 if (Arithmetic<Real>::isNA(x)) return Arithmetic<Real>::NA(); 00103 00104 // trivial case 00105 if (Arithmetic<Real>::isInfinite(x)) 00106 return -Arithmetic<Real>::infinity(); 00107 00108 // general case 00109 Real y = (x - location_) / scale_; 00110 return - log(Const::_PI_ * scale_ * (1. + y * y)); 00111 } 00112 00113 /* The cumulative distribution function at t. 00114 */ 00115 Real Cauchy::cdf( Real const& t) const 00116 { 00117 // check NA value 00118 if (Arithmetic<Real>::isNA(t)) return Arithmetic<Real>::NA(); 00119 00120 // check parameter 00121 if (Arithmetic<Real>::isInfinite(t)) 00122 return (t < 0.) ? 0.0 : 1.0; 00123 00124 /* http://www.faqs.org/faqs/fr/maths/maths-faq-3/ 00125 * arctan on [0, 1[: 00126 * if x<0 atan(x)= -atan(-x) 00127 * elseif x>1 atan(x)= Pi/2-atan(1/x). 00128 */ 00129 if (abs(t) > 1) 00130 { 00131 double y = atan(1/t) / Const::_PI_; 00132 return (t > 0) ? (1 - y) : (-y); 00133 } 00134 else 00135 return 0.5 + atan(t) / Const::_PI_; 00136 } 00137 00138 /* 00139 * The inverse cumulative distribution function at p. 00140 */ 00141 Real Cauchy::icdf( Real const& p) const 00142 { 00143 // check NA value 00144 if (Arithmetic<Real>::isNA(p)) return Arithmetic<Real>::NA(); 00145 00146 // check parameter 00147 if ((p > 1.) || (p < 0.)) 00148 throw domain_error("Cauchy::icdf(p) " 00149 "argument error"); 00150 // trivial cases 00151 if (p == 0.) return -Arithmetic<Real>::infinity(); 00152 if (p == 1.) return Arithmetic<Real>::infinity(); 00153 00154 // general case 00155 // tan(pi * (p - 1/2)) = -cot(pi * p) = -1/tan(pi * p) 00156 return location_ - scale_ / tan(Const::_PI_ * p); 00157 } 00158 00159 } // namespace Law 00160 00161 } // namespace STK