|
STK++ 1.0
|
00001 /*--------------------------------------------------------------------*/ 00002 /* Copyright (C) 2004-2011 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: stkpp::StatistiK::StatDesc 00027 * Purpose: Compute elementary statistics for two variables. 00028 * Author: Serge Iovleff, serge.iovleff@stkpp.org 00029 **/ 00030 00035 #ifndef STK_STAT_BIVARIATEREALREAL_H 00036 #define STK_STAT_BIVARIATEREALREAL_H 00037 00038 #include "STK_Stat_Bivariate.h" 00039 #include "STK_Stat_UnivariateReal.h" 00040 00041 namespace STK 00042 { 00043 namespace Stat 00044 { 00045 00067 template < class TContainer1D > 00068 class Bivariate<Real, Real, TContainer1D> 00069 { 00070 public: 00076 Bivariate( ITContainer1D<Real, TContainer1D> const& X 00077 , ITContainer1D<Real, TContainer1D> const& Y 00078 ) 00079 : X_(X.asLeaf()) 00080 , Y_(Y.asLeaf()) 00081 , W_() 00082 , xStat_(X) 00083 , yStat_(Y) 00084 , cov_(0.) 00085 , ucov_(0.) 00086 , cor_(0.) 00087 , ucor_(0.) 00088 , sumWeights_(0.0) 00089 , sum2Weights_(0.0) 00090 { 00091 compCovariance(); 00092 } 00093 00100 Bivariate( ITContainer1D<Real, TContainer1D> const& X 00101 , ITContainer1D<Real, TContainer1D> const& Y 00102 , TContainer1D const& W 00103 ) 00104 : X_(X.asLeaf()) 00105 , Y_(Y.asLeaf()) 00106 , W_(W) 00107 , xStat_(X, W) 00108 , yStat_(Y, W) 00109 , cov_(0.) 00110 , ucov_(0.) 00111 , cor_(0.) 00112 , ucor_(0.) 00113 , sumWeights_(0.0) 00114 , sum2Weights_(0.0) 00115 { 00116 compWeightedCovariance(); 00117 } 00121 Bivariate( Bivariate<Real, Real, TContainer1D> const& stat) 00122 : xStat_(stat.xStat_) 00123 , yStat_(stat.yStat_) 00124 , cov_(stat.cov_) 00125 , ucov_(stat.ucov_) 00126 , cor_(stat.cor_) 00127 , ucor_(stat.ucor_) 00128 , sumWeights_(stat.nweight_) 00129 , sum2Weights_(stat.nweight2_) 00130 { } 00131 00133 virtual ~Bivariate() { ;} 00134 00139 Bivariate& operator=( Bivariate<Real, Real, TContainer1D> const& stat) 00140 { 00141 xStat_ = stat.xStat_; 00142 yStat_ = stat.yStat_; 00143 W_ = stat.W_; 00144 cov_ = stat.cov_; 00145 ucov_ = stat.ucov_; 00146 cor_ = stat.cor_; 00147 ucor_ = stat.ucor_; 00148 return *this; 00149 } 00150 00155 void setData( ITContainer1D<Real, TContainer1D> const& X 00156 , ITContainer1D<Real, TContainer1D> const& Y 00157 ) 00158 { 00159 X_ = X.asLeaf(); 00160 Y_ = Y.asLeaf(); 00161 W_.clear(); 00162 xStat_.setData(X); 00163 yStat_.setData(Y); 00164 compCovariance(); 00165 } 00166 00172 void setData( ITContainer1D<Real, TContainer1D> const& X 00173 , ITContainer1D<Real, TContainer1D> const& Y 00174 , TContainer1D const& W 00175 ) 00176 { 00177 X_ = X.asLeaf(); 00178 Y_ = Y.asLeaf(); 00179 W_ = W; 00180 xStat_.setData(X, W); 00181 yStat_.setData(Y, W); 00182 compWeightedCovariance(); 00183 } 00184 00188 inline Univariate<Real, TContainer1D> const& xStat() const {return xStat_;} 00192 inline Univariate<Real, TContainer1D> const& yStat() const {return yStat_;} 00196 inline Real const& covariance() const { return cov_;} 00200 inline Real const& correlation() const { return cor_;} 00204 inline Real const& unbiasedCovariance() const { return ucov_;} 00208 inline Real const& unbiasedCorrelation() const { return ucor_;} 00209 00210 protected: 00212 TContainer1D X_; 00214 TContainer1D Y_; 00216 TContainer1D W_; 00218 Univariate<Real, TContainer1D> xStat_; 00220 Univariate<Real, TContainer1D> yStat_; 00222 Real cov_; 00224 Real ucov_; 00226 Real cor_; 00228 Real ucor_; 00230 Real sumWeights_; 00232 Real sum2Weights_; 00233 00235 void compCovariance() 00236 { 00237 // get dimensions 00238 Range com = STK::Range::inf(X_.range(),Y_.range()); 00239 const Integer first = com.first(), last = com.last(); 00240 Integer nobs = com.size(); 00241 // get means 00242 Real xMean = xStat_.mean(), yMean= yStat_.mean(); 00243 // compute covariance 00244 Real xsum = 0.0, ysum = 0.0, xdev, ydev; 00245 cov_ = 0.; 00246 for (Integer i=first; i<=last; i++) 00247 { 00248 if (Arithmetic<Real>::isFinite(X_[i]) && Arithmetic<Real>::isFinite(Y_[i])) 00249 { 00250 xsum += (xdev = X_[i] - xMean); // deviation from the mean 00251 ysum += (ydev = Y_[i] - yMean); // deviation from the mean 00252 cov_ += (xdev*ydev); // squared value 00253 } 00254 else nobs--; 00255 } 00256 if (nobs > 1) 00257 { 00258 ucov_ = (cov_ - (xsum*ysum)/(Real)nobs)/(Real)(nobs -1); 00259 ucor_ = ucov_/(xStat_.unbiasedStd()*yStat_.unbiasedStd()); 00260 cov_ = (cov_ - (xsum*ysum)/(Real)nobs)/(Real)(nobs); 00261 cor_ = cov_/(xStat_.std()*yStat_.std()); 00262 } 00263 else 00264 { 00265 if (nobs == 1) 00266 { 00267 cov_ = 0.; 00268 cor_ = 0.; 00269 ucov_ = Arithmetic<Real>::NA(); 00270 ucor_ = Arithmetic<Real>::NA(); 00271 } 00272 // no observations 00273 cov_ = Arithmetic<Real>::NA(); 00274 cor_ = Arithmetic<Real>::NA(); 00275 ucov_ = Arithmetic<Real>::NA(); 00276 ucor_ = Arithmetic<Real>::NA(); 00277 } 00278 } 00279 00281 void compWeightedCovariance() 00282 { 00283 // get dimensions 00284 Range com = STK::Range::inf(X_.range(),Y_.range()); 00285 Integer first = com.first(), last = com.last(); 00286 // get means 00287 Real xMean = xStat_.mean(), yMean= yStat_.mean(); 00288 // compute covariance 00289 Real xsum = 0.0, ysum = 0.0, xdev, ydev; 00290 sumWeights_ = 0.0; 00291 sum2Weights_ = 0.0; 00292 // sum 00293 cov_ = 0.0; 00294 for (Integer i=first; i<=last; i++) 00295 { 00296 if (Arithmetic<Real>::isFinite(X_[i]) && Arithmetic<Real>::isFinite(Y_[i])) 00297 { 00298 xsum += (xdev = X_[i] - xMean); // deviation from the mean 00299 ysum += (ydev = Y_[i] - yMean); // deviation from the mean 00300 Real Wi = abs((Real)W_[i]); 00301 cov_ += Wi * (xdev*ydev); // cross product 00302 sumWeights_ += Wi; // sum absolute weights 00303 sum2Weights_ += Wi * Wi; // sum squared weights 00304 } 00305 } 00306 // not pathological weights 00307 if (sumWeights_*sumWeights_ > sum2Weights_) 00308 { 00309 ucov_ = (cov_ - xsum*ysum/sumWeights_)/(sumWeights_ - sum2Weights_/sumWeights_); 00310 ucor_ = ucov_/(xStat_.unbiasedStd()*yStat_.unbiasedStd()); 00311 cov_ = (cov_ - xsum*ysum)/(sumWeights_); 00312 cor_ = cov_/(xStat_.std()*yStat_.std()); 00313 } 00314 else 00315 { 00316 if (sumWeights_) // if sum of the weights is not 0 00317 { 00318 cov_ = 0.; 00319 cor_ = 0.; 00320 ucov_ = Arithmetic<Real>::NA(); 00321 ucor_ = Arithmetic<Real>::NA(); 00322 } 00323 // no weigths 00324 cov_ = Arithmetic<Real>::NA(); 00325 cor_ = Arithmetic<Real>::NA(); 00326 ucov_ = Arithmetic<Real>::NA(); 00327 ucor_ = Arithmetic<Real>::NA(); 00328 } 00329 } 00330 }; 00331 00344 template<class TContainer1D> 00345 Real covarianceWithFixedMean( ITContainer1D<Real, TContainer1D> const& X 00346 , ITContainer1D<Real, TContainer1D> const& Y 00347 , Real const& xMean 00348 , Real const& yMean 00349 , bool unbiased = false 00350 ) 00351 { 00352 // get dimensions 00353 Range com = STK::Range::inf(X.range(),Y.range()); 00354 // no samples 00355 if (com.empty()) { return Arithmetic<Real>::NA();} 00356 00357 // get dimensions 00358 const Integer first = com.first(), last = com.last(); 00359 Integer nobs = com.size(); 00360 // compute covariance 00361 Real xsum = 0.0, ysum = 0.0, cov = 0.0, xdev, ydev; 00362 for (Integer i=first; i<=last; i++) 00363 { 00364 if (Arithmetic<Real>::isFinite(X[i]) && Arithmetic<Real>::isFinite(Y[i])) 00365 { 00366 xsum += (xdev = X[i] - xMean); // deviation from the mean 00367 ysum += (ydev = Y[i] - yMean); // deviation from the mean 00368 cov += (xdev*ydev); // squared value 00369 } 00370 else nobs--; 00371 } 00372 // compute the variance 00373 if (unbiased) 00374 { 00375 return (nobs > 1) ? ((cov - (xsum*ysum)/(Real)nobs)/(Real)(nobs -1)) 00376 : Arithmetic<Real>::NA(); 00377 00378 } 00379 return (nobs > 0) ? (cov - (xsum*ysum)/(Real)nobs)/(Real)(nobs) 00380 : Arithmetic<Real>::NA(); 00381 } 00382 00396 template<class TContainer1D> 00397 Real covarianceWithFixedMean( ITContainer1D<Real, TContainer1D> const& X 00398 , ITContainer1D<Real, TContainer1D> const& Y 00399 , ITContainer1D<Real, TContainer1D> const& W 00400 , Real const& xMean 00401 , Real const& yMean 00402 , bool unbiased = false 00403 ) 00404 { 00405 // get dimensions 00406 Range com = STK::Range::inf(X.range(),Y.range()); 00407 // no samples 00408 if (com.empty()) { return Arithmetic<Real>::NA();} 00409 00410 // if the weight are not of the same size, ignore them 00411 if (!com.isIn(W.range())) 00412 return covarianceWithFixedMean(X, Y, xMean, yMean, unbiased); 00413 00414 // get dimensions 00415 Integer first = com.first(), last = com.last(); 00416 // compute covariance 00417 Real xsum = 0.0, ysum = 0.0, xdev, ydev, sumWeights = 0.0, sum2Weights = 0.0, cov = 0.0; 00418 for (Integer i=first; i<=last; i++) 00419 { 00420 if (Arithmetic<Real>::isFinite(X[i]) && Arithmetic<Real>::isFinite(Y[i])) 00421 { 00422 xsum += (xdev = X[i] - xMean); // deviation from the mean 00423 ysum += (ydev = Y[i] - yMean); // deviation from the mean 00424 Real Wi = abs((Real)W[i]); 00425 cov += Wi * (xdev*ydev); // cross product 00426 sumWeights += Wi; // sum absolute weights 00427 sum2Weights += Wi * Wi; // sum squared weights 00428 } 00429 } 00430 // compute the variance 00431 if (unbiased) 00432 { 00433 if (sumWeights*sumWeights > sum2Weights) 00434 { 00435 return (cov - xsum*ysum/sumWeights)/(sumWeights - sum2Weights/sumWeights); 00436 } 00437 else 00438 { 00439 if (sumWeights) return 0.; 00440 } 00441 return Arithmetic<Real>::NA(); 00442 } 00443 return (sumWeights) ? (cov - xsum*ysum)/(sumWeights) : Arithmetic<Real>::NA(); 00444 } 00445 00456 template<class TContainer1D> 00457 Real covariance( ITContainer1D<Real, TContainer1D> const& X 00458 , ITContainer1D<Real, TContainer1D> const& Y 00459 , bool unbiased = false 00460 ) 00461 { 00462 // get dimensions 00463 Range com = STK::Range::inf(X.range(),Y.range()); 00464 // no samples 00465 if (com.empty()) { return Arithmetic<Real>::NA();} 00466 00467 // Compute the mean 00468 Real xMean = mean<TContainer1D>(X), yMean = mean<TContainer1D>(Y); 00469 00470 // get dimensions 00471 const Integer first = com.first(), last = com.last(); 00472 Integer nobs = com.size(); 00473 // compute covariance 00474 Real xsum = 0.0, ysum = 0.0, cov = 0.0, xdev, ydev; 00475 for (Integer i=first; i<=last; i++) 00476 { 00477 if (Arithmetic<Real>::isFinite(X[i]) && Arithmetic<Real>::isFinite(Y[i])) 00478 { 00479 xsum += (xdev = X[i] - xMean); // deviation from the mean 00480 ysum += (ydev = Y[i] - yMean); // deviation from the mean 00481 cov += (xdev*ydev); // squared value 00482 } 00483 else nobs--; 00484 } 00485 // compute the variance 00486 if (unbiased) 00487 { 00488 return (nobs > 1) ? ((cov - (xsum*ysum)/(Real)nobs)/(Real)(nobs -1)) 00489 : Arithmetic<Real>::NA(); 00490 00491 } 00492 return (nobs > 0) ? ((cov - (xsum*ysum)/(Real)nobs)/(Real)(nobs)) 00493 : Arithmetic<Real>::NA(); 00494 } 00495 00511 template<class TContainer1D> 00512 Real covariance( ITContainer1D<Real, TContainer1D> const& X 00513 , ITContainer1D<Real, TContainer1D> const& Y 00514 , ITContainer1D<Real, TContainer1D> const& W 00515 , bool unbiased = false 00516 ) 00517 { 00518 // get dimensions 00519 Range com = STK::Range::inf(X.range(),Y.range()); 00520 // no samples 00521 if (com.empty()) { return Arithmetic<Real>::NA();} 00522 00523 // Compute the mean 00524 Real xMean = mean(X, W), yMean= mean(Y, W); 00525 00526 // if the weight are not of the same size, ignore them 00527 if (!com.isIn(W.range())) 00528 return covarianceWithFixedMean(X, Y, xMean, yMean, unbiased); 00529 00530 // get dimensions 00531 Integer first = com.first(), last = com.last(); 00532 // compute covariance 00533 Real xsum = 0.0, ysum = 0.0, xdev, ydev, sumWeights = 0.0, sum2Weights = 0.0, cov = 0.0; 00534 for (Integer i=first; i<=last; i++) 00535 { 00536 if (Arithmetic<Real>::isFinite(X[i]) && Arithmetic<Real>::isFinite(Y[i])) 00537 { 00538 xsum += (xdev = X[i] - xMean); // deviation from the mean 00539 ysum += (ydev = Y[i] - yMean); // deviation from the mean 00540 Real Wi = abs((Real)W[i]); 00541 cov += Wi * (xdev*ydev); // cross product 00542 sumWeights += Wi; // sum absolute weights 00543 sum2Weights += Wi * Wi; // sum squared weights 00544 } 00545 } 00546 // compute the variance 00547 if (unbiased) 00548 { 00549 if (sumWeights*sumWeights > sum2Weights) 00550 { 00551 return (cov - xsum*ysum/sumWeights)/(sumWeights - sum2Weights/sumWeights); 00552 } 00553 else 00554 { 00555 if (sumWeights) return 0.; 00556 } 00557 return Arithmetic<Real>::NA(); 00558 } 00559 return (sumWeights) ? (cov - xsum*ysum)/(sumWeights) : Arithmetic<Real>::NA(); 00560 } 00561 00562 00563 } // namespace Stat 00564 00565 } // namespace STK 00566 00567 #endif /*STK_STAT_BIVARIATEREALREAL_H*/