bpp-core  2.1.0
VectorTools.h
Go to the documentation of this file.
00001 //
00002 // File: VectorTools.h
00003 // Created by: Julien Dutheil
00004 // Created on: Fri Mar 14 14:16:32 2003
00005 //
00006 
00007 /*
00008    Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
00009 
00010    This software is a computer program whose purpose is to provide classes
00011    for numerical calculus.
00012 
00013    This software is governed by the CeCILL  license under French law and
00014    abiding by the rules of distribution of free software.  You can  use,
00015    modify and/ or redistribute the software under the terms of the CeCILL
00016    license as circulated by CEA, CNRS and INRIA at the following URL
00017    "http://www.cecill.info".
00018 
00019    As a counterpart to the access to the source code and  rights to copy,
00020    modify and redistribute granted by the license, users are provided only
00021    with a limited warranty  and the software's author,  the holder of the
00022    economic rights,  and the successive licensors  have only  limited
00023    liability.
00024 
00025    In this respect, the user's attention is drawn to the risks associated
00026    with loading,  using,  modifying and/or developing or reproducing the
00027    software by the user in light of its specific status of free software,
00028    that may mean  that it is complicated to manipulate,  and  that  also
00029    therefore means  that it is reserved for developers  and  experienced
00030    professionals having in-depth computer knowledge. Users are therefore
00031    encouraged to load and test the software's suitability as regards their
00032    requirements in conditions enabling the security of their systems and/or
00033    data to be ensured and,  more generally, to use and operate it in the
00034    same conditions as regards security.
00035 
00036    The fact that you are presently reading this means that you have had
00037    knowledge of the CeCILL license and that you accept its terms.
00038  */
00039 
00040 #ifndef _VECTORTOOLS_H_
00041 #define _VECTORTOOLS_H_
00042 
00043 #include "VectorExceptions.h"
00044 #include "NumTools.h"
00045 #include "AdaptiveKernelDensityEstimation.h"
00046 #include "Matrix/Matrix.h"
00047 #include "../Io/OutputStream.h"
00048 #include "../App/ApplicationTools.h"
00049 
00050 // From the STL:
00051 #include <vector>
00052 #include <map>
00053 #include <cmath>
00054 #include <algorithm>
00055 #include <complex>
00056 
00057 namespace bpp
00058 {
00059 typedef std::vector<std::complex<double> > Vcomplex;
00060 typedef std::vector<Vcomplex> VVcomplex;
00061 typedef std::vector<VVcomplex> VVVcomplex;
00062 
00063 typedef std::vector<std::complex<long double> > Vlcomplex;
00064 typedef std::vector<Vlcomplex> VVlcomplex;
00065 typedef std::vector<VVlcomplex> VVVlcomplex;
00066 
00067 typedef std::vector<double> Vdouble;
00068 typedef std::vector<Vdouble> VVdouble;
00069 typedef std::vector<VVdouble> VVVdouble;
00070 typedef std::vector<VVVdouble> VVVVdouble;
00071 
00072 typedef std::vector<long double> Vldouble;
00073 typedef std::vector<Vldouble> VVldouble;
00074 typedef std::vector<VVldouble> VVVldouble;
00075 typedef std::vector<VVVldouble> VVVVldouble;
00076 
00077 typedef std::vector<int> Vint;
00078 typedef std::vector<Vint> VVint;
00079 typedef std::vector<VVint> VVVint;
00080 typedef std::vector<VVVint> VVVVint;
00081 
00087 template<class T>
00088 std::vector<T>  operator+(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00089 {
00090   size_t size;
00091   if (v1.size() != v2.size())
00092   {
00093     throw DimensionException("VectorTools::operator+", v1.size(), v2.size());
00094   }
00095   else
00096   {
00097     size = v1.size();
00098   }
00099   std::vector<T> result(size);
00100   for (size_t i = 0; i < size; i++)
00101   {
00102     result[i] = v1[i] + v2[i];
00103   }
00104   return result;
00105 }
00106 
00107 template<class T>
00108 std::vector<T> operator-(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00109 {
00110   size_t size;
00111   if (v1.size() != v2.size())
00112   {
00113     throw DimensionException("VectorTools::operator-", v1.size(), v2.size());
00114   }
00115   else
00116   {
00117     size = v1.size();
00118   }
00119   std::vector<T> result(size);
00120   for (size_t i = 0; i < size; i++)
00121   {
00122     result[i] = v1[i] - v2[i];
00123   }
00124   return result;
00125 }
00126 
00127 template<class T>
00128 std::vector<T> operator*(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00129 {
00130   size_t size;
00131   if (v1.size() != v2.size())
00132   {
00133     throw DimensionException("VectorTools::operator*", v1.size(), v2.size());
00134   }
00135   else
00136   {
00137     size = v1.size();
00138   }
00139   std::vector<T> result(size);
00140   for (size_t i = 0; i < size; i++)
00141   {
00142     result[i] = v1[i] * v2[i];
00143   }
00144   return result;
00145 }
00146 
00147 template<class T>
00148 std::vector<T> operator/(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00149 {
00150   size_t size;
00151   if (v1.size() != v2.size())
00152   {
00153     throw DimensionException("VectorTools::operator/", v1.size(), v2.size());
00154   }
00155   else
00156   {
00157     size = v1.size();
00158   }
00159   std::vector<T> result(size);
00160   for (size_t i = 0; i < size; i++)
00161   {
00162     result[i] = v1[i] / v2[i];
00163   }
00164   return result;
00165 }
00166 
00167 
00168 template<class T, class C>
00169 std::vector<T> operator+(const std::vector<T>& v1, const C& c)
00170 {
00171   std::vector<T> result(v1.size());
00172   for (size_t i = 0; i < result.size(); i++)
00173   {
00174     result[i] = v1[i] + c;
00175   }
00176   return result;
00177 }
00178 template<class T, class C>
00179 std::vector<T> operator+(const C& c, const std::vector<T>& v1)
00180 {
00181   std::vector<T> result(v1.size());
00182   for (size_t i = 0; i < result.size(); i++)
00183   {
00184     result[i] = c + v1[i];
00185   }
00186   return result;
00187 }
00188 
00189 template<class T, class C>
00190 std::vector<T> operator-(const std::vector<T>& v1, const C& c)
00191 {
00192   std::vector<T> result(v1.size());
00193   for (size_t i = 0; i < result.size(); i++)
00194   {
00195     result[i] = v1[i] - c;
00196   }
00197   return result;
00198 }
00199 template<class T, class C>
00200 std::vector<T> operator-(const C& c, const std::vector<T>& v1)
00201 {
00202   std::vector<T> result(v1.size());
00203   for (size_t i = 0; i < result.size(); i++)
00204   {
00205     result[i] = c - v1[i];
00206   }
00207   return result;
00208 }
00209 
00210 template<class T, class C>
00211 std::vector<T> operator*(const std::vector<T>& v1, const C& c)
00212 {
00213   std::vector<T> result(v1.size());
00214   for (size_t i = 0; i < result.size(); i++)
00215   {
00216     result[i] = v1[i] * c;
00217   }
00218   return result;
00219 }
00220 template<class T, class C>
00221 std::vector<T> operator*(const C& c, const std::vector<T>& v1)
00222 {
00223   std::vector<T> result(v1.size());
00224   for (size_t i = 0; i < result.size(); i++)
00225   {
00226     result[i] = c * v1[i];
00227   }
00228   return result;
00229 }
00230 
00231 template<class T, class C>
00232 std::vector<T> operator/(const std::vector<T>& v1, const C& c)
00233 {
00234   std::vector<T> result(v1.size());
00235   for (size_t i = 0; i < result.size(); i++)
00236   {
00237     result[i] = v1[i] / c;
00238   }
00239   return result;
00240 }
00241 template<class T, class C>
00242 std::vector<T> operator/(const C& c, const std::vector<T>& v1)
00243 {
00244   std::vector<T> result(v1.size());
00245   for (size_t i = 0; i < result.size(); i++)
00246   {
00247     result[i] = c / v1[i];
00248   }
00249   return result;
00250 }
00251 
00252 
00253 template<class T>
00254 void operator+=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00255 {
00256   for (size_t i = 0; i < v1.size(); i++)
00257   {
00258     v1[i] += v2[i];
00259   }
00260 }
00261 
00262 template<class T>
00263 void operator-=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00264 {
00265   for (size_t i = 0; i < v1.size(); i++)
00266   {
00267     v1[i] -= v2[i];
00268   }
00269 }
00270 
00271 template<class T>
00272 void operator*=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00273 {
00274   for (size_t i = 0; i < v1.size(); i++)
00275   {
00276     v1[i] *= v2[i];
00277   }
00278 }
00279 
00280 template<class T>
00281 void operator/=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00282 {
00283   for (size_t i = 0; i < v1.size(); i++)
00284   {
00285     v1[i] /= v2[i];
00286   }
00287 }
00288 
00289 
00290 template<class T, class C>
00291 void operator+=(std::vector<T>& v1, const C& c)
00292 {
00293   for (size_t i = 0; i < v1.size(); i++)
00294   {
00295     v1[i] += c;
00296   }
00297 }
00298 
00299 template<class T, class C>
00300 void operator-=(std::vector<T>& v1, const C& c)
00301 {
00302   for (size_t i = 0; i < v1.size(); i++)
00303   {
00304     v1[i] -= c;
00305   }
00306 }
00307 
00308 template<class T, class C>
00309 void operator*=(std::vector<T>& v1, const C& c)
00310 {
00311   for (size_t i = 0; i < v1.size(); i++)
00312   {
00313     v1[i] *= c;
00314   }
00315 }
00316 
00317 template<class T, class C>
00318 void operator/=(std::vector<T>& v1, const C& c)
00319 {
00320   for (size_t i = 0; i < v1.size(); i++)
00321   {
00322     v1[i] /= c;
00323   }
00324 }
00327 /******************************************************************************/
00328 
00329 class VectorTools
00330 {
00331 public:
00332   VectorTools() {}
00333   virtual ~VectorTools() {}
00334 
00335 public:
00341   template<class T>
00342   static void resize2(VVdouble& vv, size_t n1, size_t n2)
00343   {
00344     vv.resize(n1);
00345     for (size_t i = 0; i < n1; i++) { vv[i].resize(n2); }
00346   }
00347 
00348   template<class T>
00349   static void resize3(VVVdouble& vvv, size_t n1, size_t n2, size_t n3)
00350   {
00351     vvv.resize(n1);
00352     for (size_t i = 0; i < n1; i++)
00353     {
00354       vvv[i].resize(n2);
00355       for (size_t j = 0; j < n2; j++)
00356       {
00357         vvv[i][j].resize(n3);
00358       }
00359     }
00360   }
00361 
00362   static void resize4(VVVVdouble& vvvv, size_t n1, size_t n2, size_t n3, size_t n4)
00363   {
00364     vvvv.resize(n1);
00365     for (size_t i = 0; i < n1; i++)
00366     {
00367       vvvv[i].resize(n2);
00368       for (size_t j = 0; j < n2; j++)
00369       {
00370         vvvv[i][j].resize(n3);
00371         for (size_t k = 0; k < n3; k++)
00372         {
00373           vvvv[i][j][k].resize(n4);
00374         }
00375       }
00376     }
00377   }
00380   template<class T>
00381   static void fill(std::vector<T>& v, T value)
00382   {
00383     for (typename std::vector<T>::iterator it = v.begin(); it < v.end(); it++)
00384     {
00385       *it = value;
00386     }
00387   }
00388 
00401   template<class T>
00402   static std::vector<T> seq(T from, T to, T by)
00403   {
00404     std::vector<T> v;
00405     if (from < to)
00406     {
00407       // for (T i = from ; i <= to ; i += by) {           // Not good for double, 'to'
00408       for (T i = from; i <= to + (by / 100); i += by)
00409       { // must be a little bit larger
00410         v.push_back(i);
00411       }
00412     }
00413     else
00414     {
00415       for (T i = from; i >= to - (by / 100); i -= by)
00416       {
00417         v.push_back(i);
00418       }
00419     }
00420     return v;
00421   }
00422 
00433   template<class T>
00434   static size_t which(const std::vector<T>& v, const T& which) throw (ElementNotFoundException<T> )
00435   {
00436     for (size_t i = 0; i < v.size(); i++)
00437     {
00438       if (v[i] == which) return i;
00439     }
00440     throw ElementNotFoundException<T>("VectorTools::which.", &v, &which);
00441   }
00442 
00453   template<class T>
00454   static std::vector<size_t> whichAll(const std::vector<T>& v, const T& which) throw (ElementNotFoundException<T> )
00455   {
00456     std::vector<size_t> w;
00457     for (size_t i = 0; i < v.size(); i++)
00458     {
00459       if (v[i] == which) w.push_back(i);
00460     }
00461     if (w.size())
00462       return w;
00463     throw ElementNotFoundException<T>("VectorTools::whichAll.", &v, &which);
00464   }
00465 
00477   template<class T>
00478   static std::vector<T> unique(const std::vector<T>& v)
00479   {
00480     if (v.size() == 0) return v;
00481     std::vector<T> sortedV(v.begin(), v.end());
00482     sort(sortedV.begin(), sortedV.end());
00483     std::vector<T> uniq;
00484     uniq.push_back(sortedV[0]);
00485     for (size_t i = 1; i < sortedV.size(); i++)
00486     {
00487       if (sortedV[i] != sortedV[i - 1]) uniq.push_back(sortedV[i]);
00488     }
00489     return uniq;
00490   }
00491 
00502   template<class T>
00503   static bool isUnique(const std::vector<T>& v)
00504   {
00505     if (v.size() == 0) return true;
00506     std::vector<T> sortedV(v.begin(), v.end());
00507     sort(sortedV.begin(), sortedV.end());
00508     for (size_t i = 1; i < sortedV.size(); i++)
00509     {
00510       if (sortedV[i] == sortedV[i - 1]) return false;
00511     }
00512     return true;
00513   }
00514 
00522   template<class T>
00523   static std::vector<T> extract(const std::vector<T>& v1, const std::vector<int>& v2)
00524   {
00525     std::vector<T> v(v2.size());
00526     for (size_t i = 0; i < v2.size(); i++)
00527     {
00528       v[i] = v1[v2[i]];
00529     }
00530     return v;
00531   }
00532 
00539   template<class T>
00540   static std::map<T, size_t> countValues(const std::vector<T>& v)
00541   {
00542     std::map<T, size_t> c;
00543     for (size_t i = 0; i < v.size(); i++)
00544     {
00545       c[v[i]]++;
00546     }
00547     return c;
00548   }
00549 
00560   static std::vector<double> breaks(const std::vector<double>& v, unsigned int n);
00561 
00572   template<class T>
00573   static size_t nclassScott(const std::vector<T>& v)
00574   {
00575     std::vector<T> r1 = VectorTools::range(v);
00576     T r = r1[1] - r1[0];
00577     double n = v.size();
00578     double h = 3.5 * VectorTools::sd<T, double>(v) * std::pow(n, -1. / 3);
00579     return (size_t) ceil(r / h);
00580   }
00581 
00586   template<class T>
00587   static T prod(const std::vector<T>& v1)
00588   {
00589     T p = 1;
00590     for (size_t i = 0; i < v1.size(); i++) { p *= v1[i]; }
00591     return p;
00592   }
00593 
00599   template<class T>
00600   static std::vector<T> cumProd(const std::vector<T>& v1)
00601   {
00602     std::vector<T> p(v1.size());
00603     if (v1.size() == 0) return p;
00604     p[0] = v1[0];
00605     for (size_t i = 1; i < v1.size(); i++) { p[i] = v1[i] * p[i - 1]; }
00606     return p;
00607   }
00608 
00613   template<class T>
00614   static T sum(const std::vector<T>& v1)
00615   {
00616     T s = 0;
00617     for (size_t i = 0; i < v1.size(); i++) { s += v1[i]; }
00618     return s;
00619   }
00620 
00626   template<class T>
00627   static std::vector<T> cumSum(const std::vector<T>& v1)
00628   {
00629     std::vector<T> s(v1.size());
00630     if (v1.size() == 0) return s;
00631     s[0] = v1[0];
00632     for (size_t i = 1; i < v1.size(); i++) { s[i] = v1[i] + s[i - 1]; }
00633     return s;
00634   }
00635 
00642   template<class T>
00643   static void logNorm(std::vector<T>& v)
00644   {
00645     T M = max(v);
00646     T x = std::exp(v[0] - M);
00647     for (size_t i = 1; i < v.size(); i++)
00648     {
00649       x += std::exp(v[i] - M);
00650     }
00651     v -= M + std::log(x);
00652   }
00653 
00659   template<class T>
00660   static T logSumExp(const std::vector<T>& v1)
00661   {
00662     T M = max(v1);
00663     T x = std::exp(v1[0] - M);
00664     for (size_t i = 1; i < v1.size(); i++)
00665     {
00666       x += std::exp(v1[i] - M);
00667     }
00668     return std::log(x) + M;
00669   }
00670 
00677   template<class T>
00678   static T logSumExp(const std::vector<T>& v1, const std::vector<T>& v2)
00679   {
00680     size_t size;
00681     if (v1.size() != v2.size())
00682       throw DimensionException("VectorTools::logsumexp", v1.size(), v2.size());
00683     else
00684       size = v1.size();
00685 
00686     T M = max(v1);
00687     T x = v2[0] * std::exp(v1[0] - M);
00688     for (size_t i = 1; i < size; i++)
00689     {
00690       x += v2[i] * std::exp(v1[i] - M);
00691     }
00692     return std::log(x) + M;
00693   }
00694 
00700   template<class T>
00701   static T logMeanExp(const std::vector<T>& v1)
00702   {
00703     T M = max(v1);
00704     T x = std::exp(v1[0] - M);
00705     for (size_t i = 1; i < v1.size(); i++)
00706     {
00707       x += std::exp(v1[i] - M);
00708     }
00709     return std::log(x) + M - std::log(v1.size());
00710   }
00711 
00712 
00718   template<class T>
00719   static T sumExp(const std::vector<T>& v1)
00720   {
00721     T M = max(v1);
00722     T x = std::exp(v1[0] - M);
00723     for (size_t i = 1; i < v1.size(); i++)
00724     {
00725       x += std::exp(v1[i] - M);
00726     }
00727     return x * std::exp(M);
00728   }
00729 
00736   template<class T>
00737   static T sumExp(const std::vector<T>& v1, const std::vector<T>& v2)
00738   {
00739     size_t size;
00740     if (v1.size() != v2.size())
00741       throw DimensionException("VectorTools::logsumexp", v1.size(), v2.size());
00742     else
00743       size = v1.size();
00744 
00745     T M = max(v1);
00746     T x = v2[0] * std::exp(v1[0] - M);
00747     for (size_t i = 1; i < size; i++)
00748     {
00749       x += v2[i] * std::exp(v1[i] - M);
00750     }
00751     return x * std::exp(M);
00752   }
00753 
00760   template<class T>
00761   static std::vector<double> log(const std::vector<T>& v1)
00762   {
00763     std::vector<double> v2(v1.size());
00764     for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::log(v1[i]); }
00765     return v2;
00766   }
00767   template<class T>
00768   static std::vector<double> log(const std::vector<T>& v1, double base)
00769   {
00770     std::vector<double> v2(v1.size());
00771     for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::log(v1[i]) / std::log(base); }
00772     return v2;
00773   }
00774 
00775   template<class T>
00776   static std::vector<double> exp(const std::vector<T>& v1)
00777   {
00778     std::vector<double> v2(v1.size());
00779     for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::exp(v1[i]); }
00780     return v2;
00781   }
00782 
00783   template<class T>
00784   static std::vector<double> cos(const std::vector<T>& v1)
00785   {
00786     std::vector<double> v2(v1.size());
00787     for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::cos(v1[i]); }
00788     return v2;
00789   }
00790 
00791   template<class T>
00792   static std::vector<double> sin(const std::vector<T>& v1)
00793   {
00794     std::vector<double> v2(v1.size());
00795     for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::sin(v1[i]); }
00796     return v2;
00797   }
00798 
00799   template<class T>
00800   static std::vector<double> log10(const std::vector<T>& v1)
00801   {
00802     std::vector<double> v2(v1.size());
00803     for (size_t i = 0; i < v1.size(); i++) { v2[i] = std::log10(v1[i]); }
00804     return v2;
00805   }
00806 
00807   template<class T>
00808   static std::vector<T> fact(const std::vector<T>& v1)
00809   {
00810     std::vector<T> v2(v1.size());
00811     for (size_t i = 0; i < v1.size(); i++) { v2[i] = NumTools::fact<T>(v1[i]); }
00812     return v2;
00813   }
00814 
00815   template<class T>
00816   static std::vector<T> sqr(const std::vector<T>& v1)
00817   {
00818     std::vector<T> v2(v1.size());
00819     for (size_t i = 0; i < v1.size(); i++) { v2[i] = NumTools::sqr<T>(v1[i]); }
00820     return v2;
00821   }
00822 
00823   template<class T>
00824   static std::vector<T> pow(const std::vector<T>& v1, T& b)
00825   {
00826     std::vector<T> v2(v1.size());
00827     for (size_t i = 0; i < v1.size(); i++) { v2[i] = std::pow(v1[i], b); }
00828     return v2;
00829   }
00838   template<class T>
00839   static std::string paste(const std::vector<T>& v, const std::string& delim = " ")
00840   {
00841     std::ostringstream out;
00842     for (size_t i = 0; i < v.size(); i++)
00843     {
00844       out << v[i];
00845       if (i < v.size() - 1)
00846         out << delim;
00847     }
00848     return out.str();
00849   }
00850 
00857   template<class T>
00858   static void print(const std::vector<T>& v1, OutputStream& out = * ApplicationTools::message, const std::string& delim = " ")
00859   {
00860     for (size_t i = 0; i < v1.size(); i++)
00861     {
00862       out << v1[i];
00863       if (i < v1.size() - 1)
00864         out << delim;
00865     }
00866     out.endLine();
00867   }
00868 
00875   template<class T>
00876   static void printForR(const std::vector<T>& v1, std::string variableName = "x", std::ostream& out = std::cout)
00877   {
00878     out.precision(12);
00879     out << variableName << "<-c(";
00880     for (size_t i = 0; i < v1.size(); i++)
00881     {
00882       out << v1[i];
00883       if (i < v1.size() - 1)
00884         out << ", ";
00885     }
00886     out << ")" << std::endl;
00887   }
00888 
00895   template<class InputType, class OutputType>
00896   static OutputType scalar(const std::vector<InputType>& v1, const std::vector<InputType>& v2) throw (DimensionException)
00897   {
00898     if (v1.size() != v2.size())
00899     {
00900       throw DimensionException("VectorFunctions::scalar", v1.size(), v2.size());
00901     }
00902     OutputType result = 0;
00903     for (size_t i = 0; i < v1.size(); i++)
00904     {
00905       result += v1[i] * v2[i];
00906     }
00907     return result;
00908   }
00925   template<class InputType, class OutputType>
00926   static OutputType scalar(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w) throw (DimensionException)
00927   {
00928     if (v1.size() != w.size())
00929     {
00930       throw DimensionException("VectorFunctions::scalar", v1.size(), w.size());
00931     }
00932     if (v2.size() != w.size())
00933     {
00934       throw DimensionException("VectorFunctions::scalar", v2.size(), w.size());
00935     }
00936     OutputType result = 0;
00937     for (size_t i = 0; i < v1.size(); i++)
00938     {
00939       result += v1[i] * v2[i] * w[i];
00940     }
00941     return result;
00942   }
00943 
00950   template<class T>
00951   static std::vector<T> kroneckerMult(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
00952   {
00953     size_t n1 = v1.size();
00954     size_t n2 = v2.size();
00955     std::vector<T> v3(n1 * n2);
00956     for (size_t i = 0; i < n1; i++)
00957     {
00958       T v1i = v1[i];
00959       for (size_t j = 0; j < n2; j++)
00960       {
00961         v3[i * n2 + j] = v1i * v2[j];
00962       }
00963     }
00964     return v3;
00965   }
00966 
00971   template<class InputType, class OutputType>
00972   static OutputType norm(const std::vector<InputType>& v1)
00973   {
00974     OutputType result = 0;
00975     for (size_t i = 0; i < v1.size(); i++)
00976     {
00977       result += v1[i] * v1[i];
00978     }
00979     return sqrt(result);
00980   }
00981 
00989   template<class InputType, class OutputType>
00990   static OutputType norm(const std::vector<InputType>& v1, const std::vector<InputType>& w) throw (DimensionException)
00991   {
00992     if (v1.size() != w.size())
00993     {
00994       throw DimensionException("VectorFunctions::norm", v1.size(), w.size());
00995     }
00996     OutputType result = 0;
00997     for (size_t i = 0; i < v1.size(); i++)
00998     {
00999       result += v1[i] * v1[i] * w[i];
01000     }
01001     return sqrt(result);
01002   }
01003 
01010   template<class InputType, class OutputType>
01011   static OutputType cos(const std::vector<InputType>& v1, const std::vector<InputType>& v2) throw (DimensionException)
01012   {
01013     return scalar<InputType, OutputType>(v1, v2)
01014            / (norm<InputType, OutputType>(v1) * norm<InputType, OutputType>(v2));
01015   }
01016 
01024   template<class InputType, class OutputType>
01025   static OutputType cos(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w) throw (DimensionException)
01026   {
01027     return scalar<InputType, OutputType>(v1, v2, w)
01028            / (norm<InputType, OutputType>(v1, w) * norm<InputType, OutputType>(v2, w));
01029   }
01030 
01046   template<class T>
01047   static T min(const std::vector<T>& v) throw (EmptyVectorException<T> )
01048   {
01049     if (v.size() == 0) throw EmptyVectorException<T>("VectorFunctions::min()", &v);
01050     T mini = v[0];
01051     for (size_t i = 1; i < v.size(); i++)
01052     {
01053       if (v[i] < mini) mini = v[i];
01054     }
01055     return mini;
01056   }
01057 
01067   template<class T>
01068   static T max(const std::vector<T>& v) throw (EmptyVectorException<T> )
01069   {
01070     if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::max()", &v);
01071     T maxi = v[0];
01072     for (size_t i = 1; i < v.size(); i++)
01073     {
01074       if (v[i] > maxi) maxi = v[i];
01075     }
01076     return maxi;
01077   }
01078 
01089   template<class T>
01090   static size_t whichMax(const std::vector<T>& v) throw (EmptyVectorException<T> )
01091   {
01092     if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::whichMax()", &v);
01093     T maxi = v[0];
01094     size_t pos = 0;
01095     for (size_t i = 1; i < v.size(); i++)
01096     {
01097       if (v[i] > maxi)
01098       {
01099         maxi = v[i];
01100         pos = i;
01101       }
01102     }
01103     return pos;
01104   }
01105 
01116   template<class T>
01117   static size_t whichMin(const std::vector<T>& v) throw (EmptyVectorException<T> )
01118   {
01119     if (v.size() == 0) throw EmptyVectorException<T>("VectorFunctions::whichMin()", &v);
01120     T mini = v[0];
01121     size_t pos = 0;
01122     for (size_t i = 1; i < v.size(); i++)
01123     {
01124       if (v[i] < mini)
01125       {
01126         mini = v[i];
01127         pos = i;
01128       }
01129     }
01130     return pos;
01131   }
01132 
01143   template<class T>
01144   static std::vector<size_t> whichMaxAll(const std::vector<T>& v) throw (EmptyVectorException<T> )
01145   {
01146     if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::whichMaxAll()", &v);
01147     T maxi = max(v);
01148     std::vector<size_t> pos;
01149     for (size_t i = 0; i < v.size(); i++)
01150     {
01151       if (v[i] == maxi)
01152       {
01153         pos.push_back(i);
01154       }
01155     }
01156     return pos;
01157   }
01158 
01169   template<class T>
01170   static std::vector<size_t> whichMinAll(const std::vector<T>& v) throw (EmptyVectorException<T> )
01171   {
01172     if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::whichMinAll()", &v);
01173     T mini = min(v);
01174     std::vector<size_t> pos;
01175     for (size_t i = 0; i < v.size(); i++)
01176     {
01177       if (v[i] == mini)
01178       {
01179         pos.push_back(i);
01180       }
01181     }
01182     return pos;
01183   }
01184 
01185 
01195   template<class T>
01196   static std::vector<T> range(const std::vector<T>& v) throw (EmptyVectorException<T> )
01197   {
01198     if (v.size() == 0)
01199       throw EmptyVectorException<T>("VectorTools::range()", &v);
01200     std::vector<T> r(2);
01201     r[0] = r[1] = v[0];
01202     for (size_t i = 1; i < v.size(); i++)
01203     {
01204       if (v[i] < r[0]) r[0] = v[i];
01205       if (v[i] > r[1]) r[1] = v[i];
01206     }
01207     return r;
01208   }
01209 
01210 private:
01211   template<class T> class order_Cmp_
01212   {
01213     const std::vector<T>& values_;
01214 
01215 public:
01216     order_Cmp_(const std::vector<T>& v) : values_(v) {}
01217     bool operator()(size_t a, size_t b) { return values_[a] < values_[b]; }
01218   };
01219 
01220 public:
01230   template<class T>
01231   static std::vector<size_t> order(const std::vector<T>& v) throw (EmptyVectorException<T> )
01232   {
01233     if (v.size() == 0)
01234       throw EmptyVectorException<T>("VectorTools::sort()", &v);
01235     // Private inner class:
01236     std::vector<size_t> index(v.size());
01237     for (size_t i = 0; i < index.size(); ++i)
01238     {
01239       index[i] = i;
01240     }
01241     sort(index.begin(), index.end(), order_Cmp_<T>(v));
01242     return index;
01243   }
01244 
01254   template<class T>
01255   static std::vector<T> abs(const std::vector<T>& v) throw (EmptyVectorException<T> )
01256   {
01257     std::vector<T> vabs(v.size());
01258     for (size_t i = 1; i < v.size(); i++)
01259     {
01260       vabs[i] = std::abs(v[i]);
01261     }
01262     return vabs;
01263   }
01264 
01269   template<class InputType, class OutputType>
01270   static OutputType mean(const std::vector<InputType>& v1)
01271   {
01272     return (OutputType)sum<InputType>(v1) / (OutputType)v1.size();
01273   }
01280   template<class InputType, class OutputType>
01281   static OutputType mean(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool normalizeWeights = true)
01282   {
01283     if (normalizeWeights)
01284     {
01285       std::vector<InputType> wn = w / sum(w);
01286       return scalar<InputType, OutputType>(v1, wn);
01287     }
01288     else
01289     {
01290       return scalar<InputType, OutputType>(v1, w);
01291     }
01292   }
01293 
01298   template<class InputType>
01299   static InputType median(std::vector<InputType>& v1)
01300   {
01301     InputType med = 0;
01302     if (v1.size() == 0) return med;
01303     if (v1.size() == 1) return v1[0];
01304     sort(v1.begin(), v1.end());
01305     size_t i = v1.size() / 2;
01306     if (v1.size() % 2 == 0)
01307     {
01308       // Vector size is pair
01309       med = double((v1[i - 1] + v1[i]) / 2);
01310     }
01311     else
01312     {
01313       // Vector size is impair
01314       med = v1[i];
01315     }
01316     return med;
01317   }
01318 
01325   template<class InputType, class OutputType>
01326   static std::vector<OutputType> center(const std::vector<InputType>& v1)
01327   {
01328     OutputType m = mean<InputType, OutputType>(v1);
01329     std::vector<OutputType> v(v1.size());
01330     for (size_t i = 0; i < v1.size(); i++)
01331     {
01332       v[i] = (OutputType)v1[i] - m;
01333     }
01334     return v;
01335   }
01344   template<class InputType, class OutputType>
01345   static std::vector<OutputType> center(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool normalizeWeights = true)
01346   {
01347     OutputType m = mean<InputType, OutputType>(v1, w, normalizeWeights);
01348     std::vector<OutputType> v(v1.size());
01349     for (size_t i = 0; i < v1.size(); i++)
01350     {
01351       v[i] = (OutputType)v1[i] - m;
01352     }
01353     return v;
01354   }
01355 
01363   template<class InputType, class OutputType>
01364   static OutputType cov(const std::vector<InputType>& v1, const std::vector<InputType>& v2, bool unbiased = true) throw (DimensionException)
01365   {
01366     OutputType n = (OutputType)v1.size();
01367     OutputType x =  scalar<InputType, OutputType>(
01368       center<InputType, OutputType>(v1),
01369       center<InputType, OutputType>(v2)
01370       ) / n;
01371     if (unbiased) x = x * n / (n - 1);
01372     return x;
01373   }
01374 
01385   template<class InputType, class OutputType>
01386   static OutputType cov(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w, bool unbiased = true, bool normalizeWeights = true) throw (DimensionException)
01387   {
01388     if (normalizeWeights)
01389     {
01390       std::vector<InputType> wn = w / sum(w);
01391       OutputType x = scalar<InputType, OutputType>(
01392         center<InputType, OutputType>(v1, wn, false),
01393         center<InputType, OutputType>(v2, wn, false),
01394         wn
01395         );
01396       if (unbiased)
01397       {
01398         x = x / (1 - sum(sqr<double>(wn)));
01399       }
01400       return x;
01401     }
01402     else
01403     {
01404       OutputType x = scalar<InputType, OutputType>(
01405         center<InputType, OutputType>(v1, w, false),
01406         center<InputType, OutputType>(v2, w, false),
01407         w
01408         );
01409       if (unbiased)
01410       {
01411         x = x / (1 - sum(sqr(w)));
01412       }
01413       return x;
01414     }
01415   }
01421   template<class InputType, class OutputType>
01422   static OutputType var(const std::vector<InputType>& v1, bool unbiased = true)
01423   {
01424     return cov<InputType, OutputType>(v1, v1, unbiased);
01425   }
01434   template<class InputType, class OutputType>
01435   static OutputType var(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool unbiased = true, bool normalizeWeights = true) throw (DimensionException)
01436   {
01437     return cov<InputType, OutputType>(v1, v1, w, unbiased, normalizeWeights);
01438   }
01439 
01445   template<class InputType, class OutputType>
01446   static OutputType sd(const std::vector<InputType>& v1, bool unbiased = true)
01447   {
01448     return sqrt(var<InputType, OutputType>(v1, unbiased));
01449   }
01450 
01459   template<class InputType, class OutputType>
01460   static OutputType sd(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool unbiased = true, bool normalizeWeights = true) throw (DimensionException)
01461   {
01462     return sqrt(var<InputType, OutputType>(v1, w, unbiased, normalizeWeights));
01463   }
01464 
01471   template<class InputType, class OutputType>
01472   static OutputType cor(const std::vector<InputType>& v1, const std::vector<InputType>& v2) throw (DimensionException)
01473   {
01474     return cov<InputType, OutputType>(v1, v2)
01475            / ( sd<InputType, OutputType>(v1) * sd<InputType, OutputType>(v2) );
01476   }
01477 
01486   template<class InputType, class OutputType>
01487   static OutputType cor(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w, bool normalizeWeights = true) throw (DimensionException)
01488   {
01489     if (normalizeWeights)
01490     {
01491       std::vector<InputType> wn = w / sum(w);
01492       return cov<InputType, OutputType>(v1, v2, wn, false, false)
01493              / ( sd<InputType, OutputType>(v1, wn, false, false) * sd<InputType, OutputType>(v2, wn, false, false) );
01494     }
01495     else
01496     {
01497       return cov<InputType, OutputType>(v1, v2, w, false, false)
01498              / ( sd<InputType, OutputType>(v1, w, false, false) * sd<InputType, OutputType>(v2, w, false, false) );
01499     }
01500   }
01501 
01516   template<class InputType, class OutputType>
01517   static OutputType shannon(const std::vector<InputType>& v, double base = 2.7182818)
01518   {
01519     OutputType s = 0;
01520     for (size_t i = 0; i < v.size(); i++)
01521     {
01522       if (v[i] > 0) s += static_cast<OutputType>(v[i] * std::log(v[i]) / std::log(base));
01523     }
01524     return -s;
01525   }
01526 
01541   template<class InputType, class OutputType>
01542   static OutputType shannonDiscrete(const std::vector<InputType>& v, double base = 2.7182818)
01543   {
01544     std::map<InputType, double> counts;
01545     for (size_t i = 0; i < v.size(); i++)
01546     {
01547       counts[v[i]]++;
01548     }
01549     OutputType s = 0;
01550     double n = static_cast<double>(v.size());
01551     for (typename std::map<InputType, double>::iterator it = counts.begin(); it != counts.end(); it++)
01552     {
01553       s += static_cast<OutputType>((it->second / n) * std::log(it->second / n) / std::log(base));
01554     }
01555     return -s;
01556   }
01557 
01573   template<class InputType, class OutputType>
01574   static OutputType miDiscrete(const std::vector<InputType>& v1, const std::vector<InputType>& v2, double base = 2.7182818) throw (DimensionException)
01575   {
01576     if (v1.size() != v2.size())
01577       throw DimensionException("VectorTools::miDiscrete. The two samples must have the same length.", v2.size(), v1.size());
01578     std::map<InputType, double> counts1;
01579     std::map<InputType, double> counts2;
01580     std::map<InputType, std::map<InputType, double> > counts12;
01581     for (size_t i = 0; i < v1.size(); i++)
01582     {
01583       counts1[v1[i]]++;
01584       counts2[v2[i]]++;
01585       counts12[v1[i]][v2[i]]++;
01586     }
01587     OutputType s = 0;
01588     double n = static_cast<double>(v1.size());
01589     for (typename std::map<InputType, std::map<InputType, double> >::iterator it1 = counts12.begin(); it1 != counts12.end(); it1++)
01590     {
01591       for (typename std::map<InputType, double>::iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
01592       {
01593         s += static_cast<OutputType>((it2->second / n) * std::log(it2->second * n / (counts1[it1->first] * counts2[it2->first])) / std::log(base));
01594       }
01595     }
01596     return s;
01597   }
01598 
01614   template<class InputType, class OutputType>
01615   static OutputType shannonContinuous(const std::vector<InputType>& v, double base = 2.7182818)
01616   {
01617     LinearMatrix<InputType> m(1, v.size());
01618     for (size_t i = 0; i < v.size(); i++)
01619     {
01620       m(0, i) = v[i];
01621     }
01622     AdaptiveKernelDensityEstimation kd(m);
01623     OutputType s = 0;
01624     std::vector<double> x(1);
01625     for (size_t i = 0; i < v.size(); i++)
01626     {
01627       x[0] = static_cast<double>(v[i]);
01628       s += static_cast<OutputType>(std::log(kd.kDensity(x)) / std::log(base));
01629     }
01630     return -s / static_cast<double>(v.size());
01631   }
01632 
01652   template<class InputType, class OutputType>
01653   static OutputType miContinuous(const std::vector<InputType>& v1, const std::vector<InputType>& v2, double base = 2.7182818) throw (DimensionException)
01654   {
01655     if (v1.size() != v2.size())
01656       throw DimensionException("VectorTools::miContinuous. The two samples must have the same length.", v2.size(), v1.size());
01657     LinearMatrix<InputType> m1(1, v1.size());
01658     LinearMatrix<InputType> m2(1, v2.size());
01659     LinearMatrix<InputType> m12(2, v1.size());
01660     for (size_t i = 0; i < v1.size(); i++)
01661     {
01662       m1(0, i) = m12(0, i) = v1[i];
01663       m2(0, i) = m12(1, i) = v2[i];
01664     }
01665     AdaptiveKernelDensityEstimation kd1(m1);
01666     AdaptiveKernelDensityEstimation kd2(m2);
01667     AdaptiveKernelDensityEstimation kd12(m12);
01668     OutputType s = 0;
01669     std::vector<double> x1(1);
01670     std::vector<double> x2(1);
01671     std::vector<double> x12(2);
01672     for (size_t i = 0; i < v1.size(); i++)
01673     {
01674       x1[0] = x12[0] = static_cast<double>(v1[i]);
01675       x2[0] = x12[1] = static_cast<double>(v2[i]);
01676       s += static_cast<OutputType>(std::log(kd12.kDensity(x12) / (kd1.kDensity(x1) * kd2.kDensity(x2))) / std::log(base));
01677     }
01678     return s / static_cast<double>(v1.size());
01679   }
01680 
01686   template<class T>
01687   static bool haveSameElements(const std::vector<T>& v1, const std::vector<T>& v2)
01688   {
01689     std::vector<T> u1(v1);
01690     std::vector<T> u2(v2);
01691     if (u1.size() != u2.size()) return false;
01692     std::sort(u1.begin(), u1.end());
01693     std::sort(u2.begin(), u2.end());
01694     return u1 == u2;
01695   }
01696 
01705   template<class T>
01706   static bool haveSameElements(std::vector<T>& v1, std::vector<T>& v2)
01707   {
01708     if (v1.size() != v2.size()) return false;
01709     std::sort(v1.begin(), v1.end());
01710     std::sort(v2.begin(), v2.end());
01711     return v1 == v2;
01712   }
01713 
01719   template<class T>
01720   static bool contains(const std::vector<T>& vec, T el)
01721   {
01722     for (size_t i = 0; i < vec.size(); i++)
01723     {
01724       if (vec[i] == el) return true;
01725     }
01726     return false;
01727   }
01728 
01737   template<class T>
01738   static bool containsAll(std::vector<T>& v1, std::vector<T>& v2)
01739   {
01740     std::sort(v1.begin(), v1.end());
01741     std::sort(v2.begin(), v2.end());
01742     size_t j = 0;
01743     for (size_t i = 0; i < v2.size(); i++)
01744     {
01745       if (i > 0 && v2[i] == v2[i - 1]) continue;
01746       while (j < v1.size() - 1 && v1[j] < v2[i]) j++;
01747       if (v1[j] != v2[i]) return false;
01748     }
01749     return true;
01750   }
01751 
01758   template<class T>
01759   static std::vector<T> vectorUnion(const std::vector<T>& vec1, const std::vector<T>& vec2)
01760   {
01761     std::vector<T> unionEl = vec1;
01762     for (size_t j = 0; j < vec2.size(); j++)
01763     {
01764       if (!contains(unionEl, vec2[j]))
01765         unionEl.push_back(vec2[j]);
01766     }
01767     return unionEl;
01768   }
01769 
01775   template<class T>
01776   static std::vector<T> vectorUnion(const std::vector< std::vector<T> >& vecElementL)
01777   {
01778     std::vector<T> unionEl;
01779     for (size_t i = 0; i < vecElementL.size(); i++)
01780     {
01781       for (size_t j = 0; j < vecElementL[i].size(); j++)
01782       {
01783         if (!contains(unionEl, vecElementL[i][j]))
01784           unionEl.push_back(vecElementL[i][j]);
01785       }
01786     }
01787     return unionEl;
01788   }
01789 
01795   template<class T>
01796   static std::vector<T> vectorIntersection(const std::vector<T>& vec1, const std::vector<T>& vec2)
01797   {
01798     std::vector<T> interEl;
01799     for (size_t i = 0; i < vec1.size(); i++)
01800     {
01801       if (contains(vec2, vec1[i])) interEl.push_back(vec1[i]);
01802     }
01803     return interEl;
01804   }
01805 
01810   template<class T>
01811   static std::vector<T> vectorIntersection(const std::vector< std::vector<T> >& vecElementL)
01812   {
01813     if (vecElementL.size() == 1) return vecElementL[0];
01814     std::vector<T> interEl;
01815     if (vecElementL.size() == 0) return interEl;
01816     for (size_t i = 0; i < vecElementL[0].size(); i++)
01817     {
01818       bool test = true;
01819       for (size_t j = 1; test && j < vecElementL.size(); j++)
01820       {
01821         if (!contains(vecElementL[j], vecElementL[0][i])) test = false;
01822       }
01823       if (test) interEl.push_back(vecElementL[0][i]);
01824     }
01825     return interEl;
01826   }
01827 
01833   template<class T>
01834   static void append(std::vector<T>& vec1, const std::vector<T>& vec2)
01835   {
01836     vec1.insert(vec1.end(), vec2.begin(), vec2.end());
01837     // for(size_t i = 0; i < vec2.size(); i++)
01838     // {
01839     //  vec1.push_back(vec2[i]);
01840     // }
01841   }
01842 
01848   template<class T>
01849   static void prepend(std::vector<T>& vec1, const std::vector<T>& vec2)
01850   {
01851     vec1.insert(vec1.begin(), vec2.begin(), vec2.end());
01852   }
01853 
01854 
01859   template<class T>
01860   static std::vector<T> append(const std::vector< std::vector<T> >& vecElementL)
01861   {
01862     if (vecElementL.size() == 1) return vecElementL[0];
01863     std::vector<T> v;
01864     if (vecElementL.size() == 0) return v;
01865     for (size_t i = 0; i < vecElementL[0].size(); i++)
01866     {
01867       v.push_back(vecElementL[0][i]);
01868     }
01869     return v;
01870   }
01871 
01877   template<class T>
01878   static void extend(std::vector<T>& vec1, const std::vector<T>& vec2)
01879   {
01880     for (size_t i = 0; i < vec2.size(); i++)
01881     {
01882       if (!contains(vec1, vec2[i]))
01883         vec1.push_back(vec2[i]);
01884     }
01885   }
01886 
01892   template<class T>
01893   static std::vector<T> rep(const std::vector<T>& vec, size_t n)
01894   {
01895     if (n == 1) return vec;
01896     std::vector<T> v;
01897     if (n == 0) return v;
01898     v.resize(vec.size() * n);
01899     for (size_t i = 0; i < v.size(); i++)
01900     {
01901       v[i] = vec[i % vec.size()];
01902     }
01903     return v;
01904   }
01905 
01915   template<class T>
01916   static void diff(std::vector<T>& v1, std::vector<T>& v2, std::vector<T>& v3)
01917   {
01918     if (v2.size() == 0) append(v3, v1);
01919     std::sort(v1.begin(), v1.end());
01920     std::sort(v2.begin(), v2.end());
01921     size_t j = 0;
01922     for (size_t i = 0; i < v1.size(); i++)
01923     {
01924       if (i > 0 && v1[i] == v1[i - 1]) continue;
01925       while (j < v2.size() - 1 && v2[j] < v1[i]) j++;
01926       if (v2[j] != v1[i]) v3.push_back(v1[i]);
01927     }
01928   }
01929 
01934   static bool test();
01935 };
01936 } // end of namespace bpp.
01937 
01938 #endif  // _VECTORTOOLS_H_
01939 
 All Classes Namespaces Files Functions Variables Typedefs Friends