|
bpp-core
2.1.0
|
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