STK++ 1.0
STK_Stat_BivariateRealReal.h
Go to the documentation of this file.
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*/