00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if !defined(_ARRAY_HH)
00021 #define _ARRAY_HH
00022
00023 #include <set>
00024 #include <stdexcept>
00025 #include <iostream>
00026 #include <iomanip>
00027 #include <cmath>
00028 #include <cstdlib>
00029
00030 namespace QuadProgPP{
00031
00032 enum MType { DIAG };
00033
00034 template <typename T>
00035 class Vector
00036 {
00037 public:
00038 Vector();
00039 Vector(const unsigned int n);
00040 Vector(const T& a, const unsigned int n);
00041 Vector(const T* a, const unsigned int n);
00042 Vector(const Vector &rhs);
00043 ~Vector();
00044
00045 inline void set(const T* a, const unsigned int n);
00046 Vector<T> extract(const std::set<unsigned int>& indexes) const;
00047 inline T& operator[](const unsigned int& i);
00048 inline const T& operator[](const unsigned int& i) const;
00049
00050 inline unsigned int size() const;
00051 inline void resize(const unsigned int n);
00052 inline void resize(const T& a, const unsigned int n);
00053
00054 Vector<T>& operator=(const Vector<T>& rhs);
00055 Vector<T>& operator=(const T& a);
00056 inline Vector<T>& operator+=(const Vector<T>& rhs);
00057 inline Vector<T>& operator-=(const Vector<T>& rhs);
00058 inline Vector<T>& operator*=(const Vector<T>& rhs);
00059 inline Vector<T>& operator/=(const Vector<T>& rhs);
00060 inline Vector<T>& operator^=(const Vector<T>& rhs);
00061 inline Vector<T>& operator+=(const T& a);
00062 inline Vector<T>& operator-=(const T& a);
00063 inline Vector<T>& operator*=(const T& a);
00064 inline Vector<T>& operator/=(const T& a);
00065 inline Vector<T>& operator^=(const T& a);
00066
00067 private:
00068 T* v;
00069 unsigned int n;
00070 };
00071
00072 template <typename T>
00073 Vector<T>::Vector()
00074 : v(0), n(0)
00075 {}
00076
00077 template <typename T>
00078 Vector<T>::Vector(const unsigned int n)
00079 : v(new T[n])
00080 {
00081 this->n = n;
00082 }
00083
00084 template <typename T>
00085 Vector<T>::Vector(const T& a, const unsigned int n)
00086 : v(new T[n])
00087 {
00088 this->n = n;
00089 for (unsigned int i = 0; i < n; i++)
00090 v[i] = a;
00091 }
00092
00093 template <typename T>
00094 Vector<T>::Vector(const T* a, const unsigned int n)
00095 : v(new T[n])
00096 {
00097 this->n = n;
00098 for (unsigned int i = 0; i < n; i++)
00099 v[i] = *a++;
00100 }
00101
00102 template <typename T>
00103 Vector<T>::Vector(const Vector<T>& rhs)
00104 : v(new T[rhs.n])
00105 {
00106 this->n = rhs.n;
00107 for (unsigned int i = 0; i < n; i++)
00108 v[i] = rhs[i];
00109 }
00110
00111 template <typename T>
00112 Vector<T>::~Vector()
00113 {
00114 if (v != 0)
00115 delete[] (v);
00116 }
00117
00118 template <typename T>
00119 void Vector<T>::resize(const unsigned int n)
00120 {
00121 if (n == this->n)
00122 return;
00123 if (v != 0)
00124 delete[] (v);
00125 v = new T[n];
00126 this->n = n;
00127 }
00128
00129 template <typename T>
00130 void Vector<T>::resize(const T& a, const unsigned int n)
00131 {
00132 resize(n);
00133 for (unsigned int i = 0; i < n; i++)
00134 v[i] = a;
00135 }
00136
00137
00138 template <typename T>
00139 inline Vector<T>& Vector<T>::operator=(const Vector<T>& rhs)
00140
00141
00142
00143 {
00144 if (this != &rhs)
00145 {
00146 resize(rhs.n);
00147 for (unsigned int i = 0; i < n; i++)
00148 v[i] = rhs[i];
00149 }
00150 return *this;
00151 }
00152
00153 template <typename T>
00154 inline Vector<T> & Vector<T>::operator=(const T& a)
00155 {
00156 for (unsigned int i = 0; i < n; i++)
00157 v[i] = a;
00158 return *this;
00159 }
00160
00161 template <typename T>
00162 inline T & Vector<T>::operator[](const unsigned int& i)
00163 {
00164 return v[i];
00165 }
00166
00167 template <typename T>
00168 inline const T& Vector<T>::operator[](const unsigned int& i) const
00169 {
00170 return v[i];
00171 }
00172
00173 template <typename T>
00174 inline unsigned int Vector<T>::size() const
00175 {
00176 return n;
00177 }
00178
00179 template <typename T>
00180 inline void Vector<T>::set(const T* a, unsigned int n)
00181 {
00182 resize(n);
00183 for (unsigned int i = 0; i < n; i++)
00184 v[i] = a[i];
00185 }
00186
00187 template <typename T>
00188 inline Vector<T> Vector<T>::extract(const std::set<unsigned int>& indexes) const
00189 {
00190 Vector<T> tmp(indexes.size());
00191 unsigned int i = 0;
00192
00193 for (std::set<unsigned int>::const_iterator el = indexes.begin(); el != indexes.end(); el++)
00194 {
00195 if (*el >= n)
00196 throw std::logic_error("Error extracting subvector: the indexes are out of vector bounds");
00197 tmp[i++] = v[*el];
00198 }
00199
00200 return tmp;
00201 }
00202
00203 template <typename T>
00204 inline Vector<T>& Vector<T>::operator+=(const Vector<T>& rhs)
00205 {
00206 if (this->size() != rhs.size())
00207 throw std::logic_error("Operator+=: vectors have different sizes");
00208 for (unsigned int i = 0; i < n; i++)
00209 v[i] += rhs[i];
00210
00211 return *this;
00212 }
00213
00214
00215 template <typename T>
00216 inline Vector<T>& Vector<T>::operator+=(const T& a)
00217 {
00218 for (unsigned int i = 0; i < n; i++)
00219 v[i] += a;
00220
00221 return *this;
00222 }
00223
00224 template <typename T>
00225 inline Vector<T> operator+(const Vector<T>& rhs)
00226 {
00227 return rhs;
00228 }
00229
00230 template <typename T>
00231 inline Vector<T> operator+(const Vector<T>& lhs, const Vector<T>& rhs)
00232 {
00233 if (lhs.size() != rhs.size())
00234 throw std::logic_error("Operator+: vectors have different sizes");
00235 Vector<T> tmp(lhs.size());
00236 for (unsigned int i = 0; i < lhs.size(); i++)
00237 tmp[i] = lhs[i] + rhs[i];
00238
00239 return tmp;
00240 }
00241
00242 template <typename T>
00243 inline Vector<T> operator+(const Vector<T>& lhs, const T& a)
00244 {
00245 Vector<T> tmp(lhs.size());
00246 for (unsigned int i = 0; i < lhs.size(); i++)
00247 tmp[i] = lhs[i] + a;
00248
00249 return tmp;
00250 }
00251
00252 template <typename T>
00253 inline Vector<T> operator+(const T& a, const Vector<T>& rhs)
00254 {
00255 Vector<T> tmp(rhs.size());
00256 for (unsigned int i = 0; i < rhs.size(); i++)
00257 tmp[i] = a + rhs[i];
00258
00259 return tmp;
00260 }
00261
00262 template <typename T>
00263 inline Vector<T>& Vector<T>::operator-=(const Vector<T>& rhs)
00264 {
00265 if (this->size() != rhs.size())
00266 throw std::logic_error("Operator-=: vectors have different sizes");
00267 for (unsigned int i = 0; i < n; i++)
00268 v[i] -= rhs[i];
00269
00270 return *this;
00271 }
00272
00273
00274 template <typename T>
00275 inline Vector<T>& Vector<T>::operator-=(const T& a)
00276 {
00277 for (unsigned int i = 0; i < n; i++)
00278 v[i] -= a;
00279
00280 return *this;
00281 }
00282
00283 template <typename T>
00284 inline Vector<T> operator-(const Vector<T>& rhs)
00285 {
00286 return (T)(-1) * rhs;
00287 }
00288
00289 template <typename T>
00290 inline Vector<T> operator-(const Vector<T>& lhs, const Vector<T>& rhs)
00291 {
00292 if (lhs.size() != rhs.size())
00293 throw std::logic_error("Operator-: vectors have different sizes");
00294 Vector<T> tmp(lhs.size());
00295 for (unsigned int i = 0; i < lhs.size(); i++)
00296 tmp[i] = lhs[i] - rhs[i];
00297
00298 return tmp;
00299 }
00300
00301 template <typename T>
00302 inline Vector<T> operator-(const Vector<T>& lhs, const T& a)
00303 {
00304 Vector<T> tmp(lhs.size());
00305 for (unsigned int i = 0; i < lhs.size(); i++)
00306 tmp[i] = lhs[i] - a;
00307
00308 return tmp;
00309 }
00310
00311 template <typename T>
00312 inline Vector<T> operator-(const T& a, const Vector<T>& rhs)
00313 {
00314 Vector<T> tmp(rhs.size());
00315 for (unsigned int i = 0; i < rhs.size(); i++)
00316 tmp[i] = a - rhs[i];
00317
00318 return tmp;
00319 }
00320
00321 template <typename T>
00322 inline Vector<T>& Vector<T>::operator*=(const Vector<T>& rhs)
00323 {
00324 if (this->size() != rhs.size())
00325 throw std::logic_error("Operator*=: vectors have different sizes");
00326 for (unsigned int i = 0; i < n; i++)
00327 v[i] *= rhs[i];
00328
00329 return *this;
00330 }
00331
00332
00333 template <typename T>
00334 inline Vector<T>& Vector<T>::operator*=(const T& a)
00335 {
00336 for (unsigned int i = 0; i < n; i++)
00337 v[i] *= a;
00338
00339 return *this;
00340 }
00341
00342 template <typename T>
00343 inline Vector<T> operator*(const Vector<T>& lhs, const Vector<T>& rhs)
00344 {
00345 if (lhs.size() != rhs.size())
00346 throw std::logic_error("Operator*: vectors have different sizes");
00347 Vector<T> tmp(lhs.size());
00348 for (unsigned int i = 0; i < lhs.size(); i++)
00349 tmp[i] = lhs[i] * rhs[i];
00350
00351 return tmp;
00352 }
00353
00354 template <typename T>
00355 inline Vector<T> operator*(const Vector<T>& lhs, const T& a)
00356 {
00357 Vector<T> tmp(lhs.size());
00358 for (unsigned int i = 0; i < lhs.size(); i++)
00359 tmp[i] = lhs[i] * a;
00360
00361 return tmp;
00362 }
00363
00364 template <typename T>
00365 inline Vector<T> operator*(const T& a, const Vector<T>& rhs)
00366 {
00367 Vector<T> tmp(rhs.size());
00368 for (unsigned int i = 0; i < rhs.size(); i++)
00369 tmp[i] = a * rhs[i];
00370
00371 return tmp;
00372 }
00373
00374 template <typename T>
00375 inline Vector<T>& Vector<T>::operator/=(const Vector<T>& rhs)
00376 {
00377 if (this->size() != rhs.size())
00378 throw std::logic_error("Operator/=: vectors have different sizes");
00379 for (unsigned int i = 0; i < n; i++)
00380 v[i] /= rhs[i];
00381
00382 return *this;
00383 }
00384
00385
00386 template <typename T>
00387 inline Vector<T>& Vector<T>::operator/=(const T& a)
00388 {
00389 for (unsigned int i = 0; i < n; i++)
00390 v[i] /= a;
00391
00392 return *this;
00393 }
00394
00395 template <typename T>
00396 inline Vector<T> operator/(const Vector<T>& lhs, const Vector<T>& rhs)
00397 {
00398 if (lhs.size() != rhs.size())
00399 throw std::logic_error("Operator/: vectors have different sizes");
00400 Vector<T> tmp(lhs.size());
00401 for (unsigned int i = 0; i < lhs.size(); i++)
00402 tmp[i] = lhs[i] / rhs[i];
00403
00404 return tmp;
00405 }
00406
00407 template <typename T>
00408 inline Vector<T> operator/(const Vector<T>& lhs, const T& a)
00409 {
00410 Vector<T> tmp(lhs.size());
00411 for (unsigned int i = 0; i < lhs.size(); i++)
00412 tmp[i] = lhs[i] / a;
00413
00414 return tmp;
00415 }
00416
00417 template <typename T>
00418 inline Vector<T> operator/(const T& a, const Vector<T>& rhs)
00419 {
00420 Vector<T> tmp(rhs.size());
00421 for (unsigned int i = 0; i < rhs.size(); i++)
00422 tmp[i] = a / rhs[i];
00423
00424 return tmp;
00425 }
00426
00427 template <typename T>
00428 inline Vector<T> operator^(const Vector<T>& lhs, const Vector<T>& rhs)
00429 {
00430 if (lhs.size() != rhs.size())
00431 throw std::logic_error("Operator^: vectors have different sizes");
00432 Vector<T> tmp(lhs.size());
00433 for (unsigned int i = 0; i < lhs.size(); i++)
00434 tmp[i] = pow(lhs[i], rhs[i]);
00435
00436 return tmp;
00437 }
00438
00439 template <typename T>
00440 inline Vector<T> operator^(const Vector<T>& lhs, const T& a)
00441 {
00442 Vector<T> tmp(lhs.size());
00443 for (unsigned int i = 0; i < lhs.size(); i++)
00444 tmp[i] = pow(lhs[i], a);
00445
00446 return tmp;
00447 }
00448
00449 template <typename T>
00450 inline Vector<T> operator^(const T& a, const Vector<T>& rhs)
00451 {
00452 Vector<T> tmp(rhs.size());
00453 for (unsigned int i = 0; i < rhs.size(); i++)
00454 tmp[i] = pow(a, rhs[i]);
00455
00456 return tmp;
00457 }
00458
00459 template <typename T>
00460 inline Vector<T>& Vector<T>::operator^=(const Vector<T>& rhs)
00461 {
00462 if (this->size() != rhs.size())
00463 throw std::logic_error("Operator^=: vectors have different sizes");
00464 for (unsigned int i = 0; i < n; i++)
00465 v[i] = pow(v[i], rhs[i]);
00466
00467 return *this;
00468 }
00469
00470 template <typename T>
00471 inline Vector<T>& Vector<T>::operator^=(const T& a)
00472 {
00473 for (unsigned int i = 0; i < n; i++)
00474 v[i] = pow(v[i], a);
00475
00476 return *this;
00477 }
00478
00479 template <typename T>
00480 inline bool operator==(const Vector<T>& v, const Vector<T>& w)
00481 {
00482 if (v.size() != w.size())
00483 throw std::logic_error("Vectors of different size are not confrontable");
00484 for (unsigned i = 0; i < v.size(); i++)
00485 if (v[i] != w[i])
00486 return false;
00487 return true;
00488 }
00489
00490 template <typename T>
00491 inline bool operator!=(const Vector<T>& v, const Vector<T>& w)
00492 {
00493 if (v.size() != w.size())
00494 throw std::logic_error("Vectors of different size are not confrontable");
00495 for (unsigned i = 0; i < v.size(); i++)
00496 if (v[i] != w[i])
00497 return true;
00498 return false;
00499 }
00500
00501 template <typename T>
00502 inline bool operator<(const Vector<T>& v, const Vector<T>& w)
00503 {
00504 if (v.size() != w.size())
00505 throw std::logic_error("Vectors of different size are not confrontable");
00506 for (unsigned i = 0; i < v.size(); i++)
00507 if (v[i] >= w[i])
00508 return false;
00509 return true;
00510 }
00511
00512 template <typename T>
00513 inline bool operator<=(const Vector<T>& v, const Vector<T>& w)
00514 {
00515 if (v.size() != w.size())
00516 throw std::logic_error("Vectors of different size are not confrontable");
00517 for (unsigned i = 0; i < v.size(); i++)
00518 if (v[i] > w[i])
00519 return false;
00520 return true;
00521 }
00522
00523 template <typename T>
00524 inline bool operator>(const Vector<T>& v, const Vector<T>& w)
00525 {
00526 if (v.size() != w.size())
00527 throw std::logic_error("Vectors of different size are not confrontable");
00528 for (unsigned i = 0; i < v.size(); i++)
00529 if (v[i] <= w[i])
00530 return false;
00531 return true;
00532 }
00533
00534 template <typename T>
00535 inline bool operator>=(const Vector<T>& v, const Vector<T>& w)
00536 {
00537 if (v.size() != w.size())
00538 throw std::logic_error("Vectors of different size are not confrontable");
00539 for (unsigned i = 0; i < v.size(); i++)
00540 if (v[i] < w[i])
00541 return false;
00542 return true;
00543 }
00544
00548 template <typename T>
00549 inline std::ostream& operator<<(std::ostream& os, const Vector<T>& v)
00550 {
00551 os << std::endl << v.size() << std::endl;
00552 for (unsigned int i = 0; i < v.size() - 1; i++)
00553 os << std::setw(20) << std::setprecision(16) << v[i] << ", ";
00554 os << std::setw(20) << std::setprecision(16) << v[v.size() - 1] << std::endl;
00555
00556 return os;
00557 }
00558
00559 template <typename T>
00560 std::istream& operator>>(std::istream& is, Vector<T>& v)
00561 {
00562 int elements;
00563 char comma;
00564 is >> elements;
00565 v.resize(elements);
00566 for (unsigned int i = 0; i < elements; i++)
00567 is >> v[i] >> comma;
00568
00569 return is;
00570 }
00571
00576 std::set<unsigned int> seq(unsigned int s, unsigned int e);
00577
00578 std::set<unsigned int> singleton(unsigned int i);
00579
00580 template <typename T>
00581 class CanonicalBaseVector : public Vector<T>
00582 {
00583 public:
00584 CanonicalBaseVector(unsigned int i, unsigned int n);
00585 inline void reset(unsigned int i);
00586 private:
00587 unsigned int e;
00588 };
00589
00590 template <typename T>
00591 CanonicalBaseVector<T>::CanonicalBaseVector(unsigned int i, unsigned int n)
00592 : Vector<T>((T)0, n), e(i)
00593 { (*this)[e] = (T)1; }
00594
00595 template <typename T>
00596 inline void CanonicalBaseVector<T>::reset(unsigned int i)
00597 {
00598 (*this)[e] = (T)0;
00599 e = i;
00600 (*this)[e] = (T)1;
00601 }
00602
00603 #include <stdexcept>
00604
00605 template <typename T>
00606 inline T sum(const Vector<T>& v)
00607 {
00608 T tmp = (T)0;
00609 for (unsigned int i = 0; i < v.size(); i++)
00610 tmp += v[i];
00611
00612 return tmp;
00613 }
00614
00615 template <typename T>
00616 inline T prod(const Vector<T>& v)
00617 {
00618 T tmp = (T)1;
00619 for (unsigned int i = 0; i < v.size(); i++)
00620 tmp *= v[i];
00621
00622 return tmp;
00623 }
00624
00625 template <typename T>
00626 inline T mean(const Vector<T>& v)
00627 {
00628 T sum = (T)0;
00629 for (unsigned int i = 0; i < v.size(); i++)
00630 sum += v[i];
00631 return sum / v.size();
00632 }
00633
00634 template <typename T>
00635 inline T median(const Vector<T>& v)
00636 {
00637 Vector<T> tmp = sort(v);
00638 if (v.size() % 2 == 1)
00639 return tmp[v.size() / 2];
00640 else
00641 return 0.5 * (tmp[v.size() / 2 - 1] + tmp[v.size() / 2]);
00642 }
00643
00644 template <typename T>
00645 inline T stdev(const Vector<T>& v, bool sample_correction = false)
00646 {
00647 return sqrt(var(v, sample_correction));
00648 }
00649
00650 template <typename T>
00651 inline T var(const Vector<T>& v, bool sample_correction = false)
00652 {
00653 T sum = (T)0, ssum = (T)0;
00654 unsigned int n = v.size();
00655 for (unsigned int i = 0; i < n; i++)
00656 {
00657 sum += v[i];
00658 ssum += (v[i] * v[i]);
00659 }
00660 if (!sample_correction)
00661 return (ssum / n) - (sum / n) * (sum / n);
00662 else
00663 return n * ((ssum / n) - (sum / n) * (sum / n)) / (n - 1);
00664 }
00665
00666 template <typename T>
00667 inline T max(const Vector<T>& v)
00668 {
00669 T value = v[0];
00670 for (unsigned int i = 1; i < v.size(); i++)
00671 value = std::max(v[i], value);
00672
00673 return value;
00674 }
00675
00676 template <typename T>
00677 inline T min(const Vector<T>& v)
00678 {
00679 T value = v[0];
00680 for (unsigned int i = 1; i < v.size(); i++)
00681 value = std::min(v[i], value);
00682
00683 return value;
00684 }
00685
00686 template <typename T>
00687 inline unsigned int index_max(const Vector<T>& v)
00688 {
00689 unsigned int max = 0;
00690 for (unsigned int i = 1; i < v.size(); i++)
00691 if (v[i] > v[max])
00692 max = i;
00693
00694 return max;
00695 }
00696
00697 template <typename T>
00698 inline unsigned int index_min(const Vector<T>& v)
00699 {
00700 unsigned int min = 0;
00701 for (unsigned int i = 1; i < v.size(); i++)
00702 if (v[i] < v[min])
00703 min = i;
00704
00705 return min;
00706 }
00707
00708
00709 template <typename T>
00710 inline T dot_prod(const Vector<T>& a, const Vector<T>& b)
00711 {
00712 T sum = (T)0;
00713 if (a.size() != b.size())
00714 throw std::logic_error("Dotprod error: the vectors are not the same size");
00715 for (unsigned int i = 0; i < a.size(); i++)
00716 sum += a[i] * b[i];
00717
00718 return sum;
00719 }
00720
00725 template <typename T>
00726 inline Vector<T> exp(const Vector<T>& v)
00727 {
00728 Vector<T> tmp(v.size());
00729 for (unsigned int i = 0; i < v.size(); i++)
00730 tmp[i] = exp(v[i]);
00731
00732 return tmp;
00733 }
00734
00735 template <typename T>
00736 inline Vector<T> log(const Vector<T>& v)
00737 {
00738 Vector<T> tmp(v.size());
00739 for (unsigned int i = 0; i < v.size(); i++)
00740 tmp[i] = log(v[i]);
00741
00742 return tmp;
00743 }
00744
00745 template <typename T>
00746 inline Vector<T> sqrt(const Vector<T>& v)
00747 {
00748 Vector<T> tmp(v.size());
00749 for (unsigned int i = 0; i < v.size(); i++)
00750 tmp[i] = sqrt(v[i]);
00751
00752 return tmp;
00753 }
00754
00755 template <typename T>
00756 inline Vector<T> pow(const Vector<T>& v, double a)
00757 {
00758 Vector<T> tmp(v.size());
00759 for (unsigned int i = 0; i < v.size(); i++)
00760 tmp[i] = pow(v[i], a);
00761
00762 return tmp;
00763 }
00764
00765 template <typename T>
00766 inline Vector<T> abs(const Vector<T>& v)
00767 {
00768 Vector<T> tmp(v.size());
00769 for (unsigned int i = 0; i < v.size(); i++)
00770 tmp[i] = (T)fabs(v[i]);
00771
00772 return tmp;
00773 }
00774
00775 template <typename T>
00776 inline Vector<T> sign(const Vector<T>& v)
00777 {
00778 Vector<T> tmp(v.size());
00779 for (unsigned int i = 0; i < v.size(); i++)
00780 tmp[i] = v[i] > 0 ? +1 : v[i] == 0 ? 0 : -1;
00781
00782 return tmp;
00783 }
00784
00785 template <typename T>
00786 inline unsigned int partition(Vector<T>& v, unsigned int begin, unsigned int end)
00787 {
00788 unsigned int i = begin + 1, j = begin + 1;
00789 T pivot = v[begin];
00790 while (j <= end)
00791 {
00792 if (v[j] < pivot) {
00793 std::swap(v[i], v[j]);
00794 i++;
00795 }
00796 j++;
00797 }
00798 v[begin] = v[i - 1];
00799 v[i - 1] = pivot;
00800 return i - 2;
00801 }
00802
00803
00804 template <typename T>
00805 inline void quicksort(Vector<T>& v, unsigned int begin, unsigned int end)
00806 {
00807 if (end > begin)
00808 {
00809 unsigned int index = partition(v, begin, end);
00810 quicksort(v, begin, index);
00811 quicksort(v, index + 2, end);
00812 }
00813 }
00814
00815 template <typename T>
00816 inline Vector<T> sort(const Vector<T>& v)
00817 {
00818 Vector<T> tmp(v);
00819
00820 quicksort<T>(tmp, 0, tmp.size() - 1);
00821
00822 return tmp;
00823 }
00824
00825 template <typename T>
00826 inline Vector<double> rank(const Vector<T>& v)
00827 {
00828 Vector<T> tmp(v);
00829 Vector<double> tmp_rank(0.0, v.size());
00830
00831 for (unsigned int i = 0; i < tmp.size(); i++)
00832 {
00833 unsigned int smaller = 0, equal = 0;
00834 for (unsigned int j = 0; j < tmp.size(); j++)
00835 if (i == j)
00836 continue;
00837 else
00838 if (tmp[j] < tmp[i])
00839 smaller++;
00840 else if (tmp[j] == tmp[i])
00841 equal++;
00842 tmp_rank[i] = smaller + 1;
00843 if (equal > 0)
00844 {
00845 for (unsigned int j = 1; j <= equal; j++)
00846 tmp_rank[i] += smaller + 1 + j;
00847 tmp_rank[i] /= (double)(equal + 1);
00848 }
00849 }
00850
00851 return tmp_rank;
00852 }
00853
00854
00855
00856 template <typename T>
00857 class Matrix
00858 {
00859 public:
00860 Matrix();
00861 Matrix(const unsigned int n, const unsigned int m);
00862 Matrix(const T& a, const unsigned int n, const unsigned int m);
00863 Matrix(MType t, const T& a, const T& o, const unsigned int n, const unsigned int m);
00864 Matrix(MType t, const Vector<T>& v, const T& o, const unsigned int n, const unsigned int m);
00865 Matrix(const T* a, const unsigned int n, const unsigned int m);
00866 Matrix(const Matrix<T>& rhs);
00867 ~Matrix();
00868
00869 inline T* operator[](const unsigned int& i) { return v[i]; }
00870 inline const T* operator[](const unsigned int& i) const { return v[i]; };
00871
00872 inline void resize(const unsigned int n, const unsigned int m);
00873 inline void resize(const T& a, const unsigned int n, const unsigned int m);
00874
00875
00876 inline Vector<T> extractRow(const unsigned int i) const;
00877 inline Vector<T> extractColumn(const unsigned int j) const;
00878 inline Vector<T> extractDiag() const;
00879 inline Matrix<T> extractRows(const std::set<unsigned int>& indexes) const;
00880 inline Matrix<T> extractColumns(const std::set<unsigned int>& indexes) const;
00881 inline Matrix<T> extract(const std::set<unsigned int>& r_indexes, const std::set<unsigned int>& c_indexes) const;
00882
00883 inline void set(const T* a, unsigned int n, unsigned int m);
00884 inline void set(const std::set<unsigned int>& r_indexes, const std::set<unsigned int>& c_indexes, const Matrix<T>& m);
00885 inline void setRow(const unsigned int index, const Vector<T>& v);
00886 inline void setRow(const unsigned int index, const Matrix<T>& v);
00887 inline void setRows(const std::set<unsigned int>& indexes, const Matrix<T>& m);
00888 inline void setColumn(const unsigned int index, const Vector<T>& v);
00889 inline void setColumn(const unsigned int index, const Matrix<T>& v);
00890 inline void setColumns(const std::set<unsigned int>& indexes, const Matrix<T>& m);
00891
00892
00893 inline unsigned int nrows() const { return n; }
00894 inline unsigned int ncols() const { return m; }
00895
00896 inline Matrix<T>& operator=(const Matrix<T>& rhs);
00897 inline Matrix<T>& operator=(const T& a);
00898 inline Matrix<T>& operator+=(const Matrix<T>& rhs);
00899 inline Matrix<T>& operator-=(const Matrix<T>& rhs);
00900 inline Matrix<T>& operator*=(const Matrix<T>& rhs);
00901 inline Matrix<T>& operator/=(const Matrix<T>& rhs);
00902 inline Matrix<T>& operator^=(const Matrix<T>& rhs);
00903 inline Matrix<T>& operator+=(const T& a);
00904 inline Matrix<T>& operator-=(const T& a);
00905 inline Matrix<T>& operator*=(const T& a);
00906 inline Matrix<T>& operator/=(const T& a);
00907 inline Matrix<T>& operator^=(const T& a);
00908 inline operator Vector<T>();
00909 private:
00910 unsigned int n;
00911 unsigned int m;
00912 T **v;
00913 };
00914
00915 template <typename T>
00916 Matrix<T>::Matrix()
00917 : n(0), m(0), v(0)
00918 {}
00919
00920 template <typename T>
00921 Matrix<T>::Matrix(unsigned int n, unsigned int m)
00922 : v(new T*[n])
00923 {
00924 unsigned int i;
00925 this->n = n; this->m = m;
00926 v[0] = new T[m * n];
00927 for (i = 1; i < n; i++)
00928 v[i] = v[i - 1] + m;
00929 }
00930
00931 template <typename T>
00932 Matrix<T>::Matrix(const T& a, unsigned int n, unsigned int m)
00933 : v(new T*[n])
00934 {
00935 unsigned int i, j;
00936 this->n = n; this->m = m;
00937 v[0] = new T[m * n];
00938 for (i = 1; i < n; i++)
00939 v[i] = v[i - 1] + m;
00940 for (i = 0; i < n; i++)
00941 for (j = 0; j < m; j++)
00942 v[i][j] = a;
00943 }
00944
00945 template <class T>
00946 Matrix<T>::Matrix(const T* a, unsigned int n, unsigned int m)
00947 : v(new T*[n])
00948 {
00949 unsigned int i, j;
00950 this->n = n; this->m = m;
00951 v[0] = new T[m * n];
00952 for (i = 1; i < n; i++)
00953 v[i] = v[i - 1] + m;
00954 for (i = 0; i < n; i++)
00955 for (j = 0; j < m; j++)
00956 v[i][j] = *a++;
00957 }
00958
00959 template <class T>
00960 Matrix<T>::Matrix(MType t, const T& a, const T& o, unsigned int n, unsigned int m)
00961 : v(new T*[n])
00962 {
00963 unsigned int i, j;
00964 this->n = n; this->m = m;
00965 v[0] = new T[m * n];
00966 for (i = 1; i < n; i++)
00967 v[i] = v[i - 1] + m;
00968 switch (t)
00969 {
00970 case DIAG:
00971 for (i = 0; i < n; i++)
00972 for (j = 0; j < m; j++)
00973 if (i != j)
00974 v[i][j] = o;
00975 else
00976 v[i][j] = a;
00977 break;
00978 default:
00979 throw std::logic_error("Matrix type not supported");
00980 }
00981 }
00982
00983 template <class T>
00984 Matrix<T>::Matrix(MType t, const Vector<T>& a, const T& o, unsigned int n, unsigned int m)
00985 : v(new T*[n])
00986 {
00987 unsigned int i, j;
00988 this->n = n; this->m = m;
00989 v[0] = new T[m * n];
00990 for (i = 1; i < n; i++)
00991 v[i] = v[i - 1] + m;
00992 switch (t)
00993 {
00994 case DIAG:
00995 for (i = 0; i < n; i++)
00996 for (j = 0; j < m; j++)
00997 if (i != j)
00998 v[i][j] = o;
00999 else
01000 v[i][j] = a[i];
01001 break;
01002 default:
01003 throw std::logic_error("Matrix type not supported");
01004 }
01005 }
01006
01007 template <typename T>
01008 Matrix<T>::Matrix(const Matrix<T>& rhs)
01009 : v(new T*[rhs.n])
01010 {
01011 unsigned int i, j;
01012 n = rhs.n; m = rhs.m;
01013 v[0] = new T[m * n];
01014 for (i = 1; i < n; i++)
01015 v[i] = v[i - 1] + m;
01016 for (i = 0; i < n; i++)
01017 for (j = 0; j < m; j++)
01018 v[i][j] = rhs[i][j];
01019 }
01020
01021 template <typename T>
01022 Matrix<T>::~Matrix()
01023 {
01024 if (v != 0) {
01025 delete[] (v[0]);
01026 delete[] (v);
01027 }
01028 }
01029
01030 template <typename T>
01031 inline Matrix<T>& Matrix<T>::operator=(const Matrix<T> &rhs)
01032
01033
01034
01035 {
01036 unsigned int i, j;
01037 if (this != &rhs)
01038 {
01039 resize(rhs.n, rhs.m);
01040 for (i = 0; i < n; i++)
01041 for (j = 0; j < m; j++)
01042 v[i][j] = rhs[i][j];
01043 }
01044 return *this;
01045 }
01046
01047 template <typename T>
01048 inline Matrix<T>& Matrix<T>::operator=(const T& a)
01049 {
01050 unsigned int i, j;
01051 for (i = 0; i < n; i++)
01052 for (j = 0; j < m; j++)
01053 v[i][j] = a;
01054 return *this;
01055 }
01056
01057
01058 template <typename T>
01059 inline void Matrix<T>::resize(const unsigned int n, const unsigned int m)
01060 {
01061 unsigned int i;
01062 if (n == this->n && m == this->m)
01063 return;
01064 if (v != 0)
01065 {
01066 delete[] (v[0]);
01067 delete[] (v);
01068 }
01069 this->n = n; this->m = m;
01070 v = new T*[n];
01071 v[0] = new T[m * n];
01072 for (i = 1; i < n; i++)
01073 v[i] = v[i - 1] + m;
01074 }
01075
01076 template <typename T>
01077 inline void Matrix<T>::resize(const T& a, const unsigned int n, const unsigned int m)
01078 {
01079 unsigned int i, j;
01080 resize(n, m);
01081 for (i = 0; i < n; i++)
01082 for (j = 0; j < m; j++)
01083 v[i][j] = a;
01084 }
01085
01086
01087
01088 template <typename T>
01089 inline Vector<T> Matrix<T>::extractRow(const unsigned int i) const
01090 {
01091 if (i >= n)
01092 throw std::logic_error("Error in extractRow: trying to extract a row out of matrix bounds");
01093 Vector<T> tmp(v[i], m);
01094
01095 return tmp;
01096 }
01097
01098 template <typename T>
01099 inline Vector<T> Matrix<T>::extractColumn(const unsigned int j) const
01100 {
01101 unsigned int i;
01102 if (j >= m)
01103 throw std::logic_error("Error in extractRow: trying to extract a row out of matrix bounds");
01104 Vector<T> tmp(n);
01105
01106 for (i = 0; i < n; i++)
01107 tmp[i] = v[i][j];
01108
01109 return tmp;
01110 }
01111
01112 template <typename T>
01113 inline Vector<T> Matrix<T>::extractDiag() const
01114 {
01115 unsigned int d = std::min(n, m), i;
01116
01117 Vector<T> tmp(d);
01118
01119 for (i = 0; i < d; i++)
01120 tmp[i] = v[i][i];
01121
01122 return tmp;
01123
01124 }
01125
01126 template <typename T>
01127 inline Matrix<T> Matrix<T>::extractRows(const std::set<unsigned int>& indexes) const
01128 {
01129 Matrix<T> tmp(indexes.size(), m);
01130 unsigned int i = 0, j;
01131
01132 for (std::set<unsigned int>::const_iterator el = indexes.begin(); el != indexes.end(); el++)
01133 {
01134 for (j = 0; j < m; j++)
01135 {
01136 if (*el >= n)
01137 throw std::logic_error("Error extracting rows: the indexes are out of matrix bounds");
01138 tmp[i][j] = v[*el][j];
01139 }
01140 i++;
01141 }
01142
01143 return tmp;
01144 }
01145
01146 template <typename T>
01147 inline Matrix<T> Matrix<T>::extractColumns(const std::set<unsigned int>& indexes) const
01148 {
01149 Matrix<T> tmp(n, indexes.size());
01150 unsigned int i, j = 0;
01151
01152 for (std::set<unsigned int>::const_iterator el = indexes.begin(); el != indexes.end(); el++)
01153 {
01154 for (i = 0; i < n; i++)
01155 {
01156 if (*el >= m)
01157 throw std::logic_error("Error extracting columns: the indexes are out of matrix bounds");
01158 tmp[i][j] = v[i][*el];
01159 }
01160 j++;
01161 }
01162
01163 return tmp;
01164 }
01165
01166 template <typename T>
01167 inline Matrix<T> Matrix<T>::extract(const std::set<unsigned int>& r_indexes, const std::set<unsigned int>& c_indexes) const
01168 {
01169 Matrix<T> tmp(r_indexes.size(), c_indexes.size());
01170 unsigned int i = 0, j;
01171
01172 for (std::set<unsigned int>::const_iterator r_el = r_indexes.begin(); r_el != r_indexes.end(); r_el++)
01173 {
01174 if (*r_el >= n)
01175 throw std::logic_error("Error extracting submatrix: the indexes are out of matrix bounds");
01176 j = 0;
01177 for (std::set<unsigned int>::const_iterator c_el = c_indexes.begin(); c_el != c_indexes.end(); c_el++)
01178 {
01179 if (*c_el >= m)
01180 throw std::logic_error("Error extracting rows: the indexes are out of matrix bounds");
01181 tmp[i][j] = v[*r_el][*c_el];
01182 j++;
01183 }
01184 i++;
01185 }
01186
01187 return tmp;
01188 }
01189
01190 template <typename T>
01191 inline void Matrix<T>::setRow(unsigned int i, const Vector<T>& a)
01192 {
01193 if (i >= n)
01194 throw std::logic_error("Error in setRow: trying to set a row out of matrix bounds");
01195 if (this->m != a.size())
01196 throw std::logic_error("Error setting matrix row: ranges are not compatible");
01197 for (unsigned int j = 0; j < ncols(); j++)
01198 v[i][j] = a[j];
01199 }
01200
01201 template <typename T>
01202 inline void Matrix<T>::setRow(unsigned int i, const Matrix<T>& a)
01203 {
01204 if (i >= n)
01205 throw std::logic_error("Error in setRow: trying to set a row out of matrix bounds");
01206 if (this->m != a.ncols())
01207 throw std::logic_error("Error setting matrix column: ranges are not compatible");
01208 if (a.nrows() != 1)
01209 throw std::logic_error("Error setting matrix column with a non-row matrix");
01210 for (unsigned int j = 0; j < ncols(); j++)
01211 v[i][j] = a[0][j];
01212 }
01213
01214 template <typename T>
01215 inline void Matrix<T>::setRows(const std::set<unsigned int>& indexes, const Matrix<T>& m)
01216 {
01217 unsigned int i = 0;
01218
01219 if (indexes.size() != m.nrows() || this->m != m.ncols())
01220 throw std::logic_error("Error setting matrix rows: ranges are not compatible");
01221 for (std::set<unsigned int>::const_iterator el = indexes.begin(); el != indexes.end(); el++)
01222 {
01223 for (unsigned int j = 0; j < ncols(); j++)
01224 {
01225 if (*el >= n)
01226 throw std::logic_error("Error in setRows: trying to set a row out of matrix bounds");
01227 v[*el][j] = m[i][j];
01228 }
01229 i++;
01230 }
01231 }
01232
01233 template <typename T>
01234 inline void Matrix<T>::setColumn(unsigned int j, const Vector<T>& a)
01235 {
01236 if (j >= m)
01237 throw std::logic_error("Error in setColumn: trying to set a column out of matrix bounds");
01238 if (this->n != a.size())
01239 throw std::logic_error("Error setting matrix column: ranges are not compatible");
01240 for (unsigned int i = 0; i < nrows(); i++)
01241 v[i][j] = a[i];
01242 }
01243
01244 template <typename T>
01245 inline void Matrix<T>::setColumn(unsigned int j, const Matrix<T>& a)
01246 {
01247 if (j >= m)
01248 throw std::logic_error("Error in setColumn: trying to set a column out of matrix bounds");
01249 if (this->n != a.nrows())
01250 throw std::logic_error("Error setting matrix column: ranges are not compatible");
01251 if (a.ncols() != 1)
01252 throw std::logic_error("Error setting matrix column with a non-column matrix");
01253 for (unsigned int i = 0; i < nrows(); i++)
01254 v[i][j] = a[i][0];
01255 }
01256
01257
01258 template <typename T>
01259 inline void Matrix<T>::setColumns(const std::set<unsigned int>& indexes, const Matrix<T>& a)
01260 {
01261 unsigned int j = 0;
01262
01263 if (indexes.size() != a.ncols() || this->n != a.nrows())
01264 throw std::logic_error("Error setting matrix columns: ranges are not compatible");
01265 for (std::set<unsigned int>::const_iterator el = indexes.begin(); el != indexes.end(); el++)
01266 {
01267 for (unsigned int i = 0; i < nrows(); i++)
01268 {
01269 if (*el >= m)
01270 throw std::logic_error("Error in setColumns: trying to set a column out of matrix bounds");
01271 v[i][*el] = a[i][j];
01272 }
01273 j++;
01274 }
01275 }
01276
01277 template <typename T>
01278 inline void Matrix<T>::set(const std::set<unsigned int>& r_indexes, const std::set<unsigned int>& c_indexes, const Matrix<T>& a)
01279 {
01280 unsigned int i = 0, j;
01281 if (c_indexes.size() != a.ncols() || r_indexes.size() != a.nrows())
01282 throw std::logic_error("Error setting matrix elements: ranges are not compatible");
01283
01284 for (std::set<unsigned int>::const_iterator r_el = r_indexes.begin(); r_el != r_indexes.end(); r_el++)
01285 {
01286 if (*r_el >= n)
01287 throw std::logic_error("Error in set: trying to set a row out of matrix bounds");
01288 j = 0;
01289 for (std::set<unsigned int>::const_iterator c_el = c_indexes.begin(); c_el != c_indexes.end(); c_el++)
01290 {
01291 if (*c_el >= m)
01292 throw std::logic_error("Error in set: trying to set a column out of matrix bounds");
01293 v[*r_el][*c_el] = a[i][j];
01294 j++;
01295 }
01296 i++;
01297 }
01298 }
01299
01300 template <typename T>
01301 inline void Matrix<T>::set(const T* a, unsigned int n, unsigned int m)
01302 {
01303 if (this->n != n || this->m != m)
01304 resize(n, m);
01305 unsigned int k = 0;
01306 for (unsigned int i = 0; i < n; i++)
01307 for (unsigned int j = 0; j < m; j++)
01308 v[i][j] = a[k++];
01309 }
01310
01311
01312 template <typename T>
01313 Matrix<T> operator+(const Matrix<T>& rhs)
01314 {
01315 return rhs;
01316 }
01317
01318 template <typename T>
01319 Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs)
01320 {
01321 if (lhs.ncols() != rhs.ncols() || lhs.nrows() != rhs.nrows())
01322 throw std::logic_error("Operator+: matrices have different sizes");
01323 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01324 for (unsigned int i = 0; i < lhs.nrows(); i++)
01325 for (unsigned int j = 0; j < lhs.ncols(); j++)
01326 tmp[i][j] = lhs[i][j] + rhs[i][j];
01327
01328 return tmp;
01329 }
01330
01331 template <typename T>
01332 Matrix<T> operator+(const Matrix<T>& lhs, const T& a)
01333 {
01334 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01335 for (unsigned int i = 0; i < lhs.nrows(); i++)
01336 for (unsigned int j = 0; j < lhs.ncols(); j++)
01337 tmp[i][j] = lhs[i][j] + a;
01338
01339 return tmp;
01340 }
01341
01342 template <typename T>
01343 Matrix<T> operator+(const T& a, const Matrix<T>& rhs)
01344 {
01345 Matrix<T> tmp(rhs.nrows(), rhs.ncols());
01346 for (unsigned int i = 0; i < rhs.nrows(); i++)
01347 for (unsigned int j = 0; j < rhs.ncols(); j++)
01348 tmp[i][j] = a + rhs[i][j];
01349
01350 return tmp;
01351 }
01352
01353 template <typename T>
01354 inline Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& rhs)
01355 {
01356 if (m != rhs.ncols() || n != rhs.nrows())
01357 throw std::logic_error("Operator+=: matrices have different sizes");
01358 for (unsigned int i = 0; i < n; i++)
01359 for (unsigned int j = 0; j < m; j++)
01360 v[i][j] += rhs[i][j];
01361
01362 return *this;
01363 }
01364
01365 template <typename T>
01366 inline Matrix<T>& Matrix<T>::operator+=(const T& a)
01367 {
01368 for (unsigned int i = 0; i < n; i++)
01369 for (unsigned int j = 0; j < m; j++)
01370 v[i][j] += a;
01371
01372 return *this;
01373 }
01374
01375 template <typename T>
01376 Matrix<T> operator-(const Matrix<T>& rhs)
01377 {
01378 return (T)(-1) * rhs;
01379 }
01380
01381 template <typename T>
01382 Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs)
01383 {
01384 if (lhs.ncols() != rhs.ncols() || lhs.nrows() != rhs.nrows())
01385 throw std::logic_error("Operator-: matrices have different sizes");
01386 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01387 for (unsigned int i = 0; i < lhs.nrows(); i++)
01388 for (unsigned int j = 0; j < lhs.ncols(); j++)
01389 tmp[i][j] = lhs[i][j] - rhs[i][j];
01390
01391 return tmp;
01392 }
01393
01394 template <typename T>
01395 Matrix<T> operator-(const Matrix<T>& lhs, const T& a)
01396 {
01397 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01398 for (unsigned int i = 0; i < lhs.nrows(); i++)
01399 for (unsigned int j = 0; j < lhs.ncols(); j++)
01400 tmp[i][j] = lhs[i][j] - a;
01401
01402 return tmp;
01403 }
01404
01405 template <typename T>
01406 Matrix<T> operator-(const T& a, const Matrix<T>& rhs)
01407 {
01408 Matrix<T> tmp(rhs.nrows(), rhs.ncols());
01409 for (unsigned int i = 0; i < rhs.nrows(); i++)
01410 for (unsigned int j = 0; j < rhs.ncols(); j++)
01411 tmp[i][j] = a - rhs[i][j];
01412
01413 return tmp;
01414 }
01415
01416 template <typename T>
01417 inline Matrix<T>& Matrix<T>::operator-=(const Matrix<T>& rhs)
01418 {
01419 if (m != rhs.ncols() || n != rhs.nrows())
01420 throw std::logic_error("Operator-=: matrices have different sizes");
01421 for (unsigned int i = 0; i < n; i++)
01422 for (unsigned int j = 0; j < m; j++)
01423 v[i][j] -= rhs[i][j];
01424
01425 return *this;
01426 }
01427
01428 template <typename T>
01429 inline Matrix<T>& Matrix<T>::operator-=(const T& a)
01430 {
01431 for (unsigned int i = 0; i < n; i++)
01432 for (unsigned int j = 0; j < m; j++)
01433 v[i][j] -= a;
01434
01435 return *this;
01436 }
01437
01438 template <typename T>
01439 Matrix<T> operator*(const Matrix<T>& lhs, const Matrix<T>& rhs)
01440 {
01441 if (lhs.ncols() != rhs.ncols() || lhs.nrows() != rhs.nrows())
01442 throw std::logic_error("Operator*: matrices have different sizes");
01443 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01444 for (unsigned int i = 0; i < lhs.nrows(); i++)
01445 for (unsigned int j = 0; j < lhs.ncols(); j++)
01446 tmp[i][j] = lhs[i][j] * rhs[i][j];
01447
01448 return tmp;
01449 }
01450
01451 template <typename T>
01452 Matrix<T> operator*(const Matrix<T>& lhs, const T& a)
01453 {
01454 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01455 for (unsigned int i = 0; i < lhs.nrows(); i++)
01456 for (unsigned int j = 0; j < lhs.ncols(); j++)
01457 tmp[i][j] = lhs[i][j] * a;
01458
01459 return tmp;
01460 }
01461
01462 template <typename T>
01463 Matrix<T> operator*(const T& a, const Matrix<T>& rhs)
01464 {
01465 Matrix<T> tmp(rhs.nrows(), rhs.ncols());
01466 for (unsigned int i = 0; i < rhs.nrows(); i++)
01467 for (unsigned int j = 0; j < rhs.ncols(); j++)
01468 tmp[i][j] = a * rhs[i][j];
01469
01470 return tmp;
01471 }
01472
01473 template <typename T>
01474 inline Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& rhs)
01475 {
01476 if (m != rhs.ncols() || n != rhs.nrows())
01477 throw std::logic_error("Operator*=: matrices have different sizes");
01478 for (unsigned int i = 0; i < n; i++)
01479 for (unsigned int j = 0; j < m; j++)
01480 v[i][j] *= rhs[i][j];
01481
01482 return *this;
01483 }
01484
01485 template <typename T>
01486 inline Matrix<T>& Matrix<T>::operator*=(const T& a)
01487 {
01488 for (unsigned int i = 0; i < n; i++)
01489 for (unsigned int j = 0; j < m; j++)
01490 v[i][j] *= a;
01491
01492 return *this;
01493 }
01494
01495 template <typename T>
01496 Matrix<T> operator/(const Matrix<T>& lhs, const Matrix<T>& rhs)
01497 {
01498 if (lhs.ncols() != rhs.ncols() || lhs.nrows() != rhs.nrows())
01499 throw std::logic_error("Operator+: matrices have different sizes");
01500 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01501 for (unsigned int i = 0; i < lhs.nrows(); i++)
01502 for (unsigned int j = 0; j < lhs.ncols(); j++)
01503 tmp[i][j] = lhs[i][j] / rhs[i][j];
01504
01505 return tmp;
01506 }
01507
01508 template <typename T>
01509 Matrix<T> operator/(const Matrix<T>& lhs, const T& a)
01510 {
01511 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01512 for (unsigned int i = 0; i < lhs.nrows(); i++)
01513 for (unsigned int j = 0; j < lhs.ncols(); j++)
01514 tmp[i][j] = lhs[i][j] / a;
01515
01516 return tmp;
01517 }
01518
01519 template <typename T>
01520 Matrix<T> operator/(const T& a, const Matrix<T>& rhs)
01521 {
01522 Matrix<T> tmp(rhs.nrows(), rhs.ncols());
01523 for (unsigned int i = 0; i < rhs.nrows(); i++)
01524 for (unsigned int j = 0; j < rhs.ncols(); j++)
01525 tmp[i][j] = a / rhs[i][j];
01526
01527 return tmp;
01528 }
01529
01530 template <typename T>
01531 inline Matrix<T>& Matrix<T>::operator/=(const Matrix<T>& rhs)
01532 {
01533 if (m != rhs.ncols() || n != rhs.nrows())
01534 throw std::logic_error("Operator+=: matrices have different sizes");
01535 for (unsigned int i = 0; i < n; i++)
01536 for (unsigned int j = 0; j < m; j++)
01537 v[i][j] /= rhs[i][j];
01538
01539 return *this;
01540 }
01541
01542 template <typename T>
01543 inline Matrix<T>& Matrix<T>::operator/=(const T& a)
01544 {
01545 for (unsigned int i = 0; i < n; i++)
01546 for (unsigned int j = 0; j < m; j++)
01547 v[i][j] /= a;
01548
01549 return *this;
01550 }
01551
01552 template <typename T>
01553 Matrix<T> operator^(const Matrix<T>& lhs, const T& a)
01554 {
01555 Matrix<T> tmp(lhs.nrows(), lhs.ncols());
01556 for (unsigned int i = 0; i < lhs.nrows(); i++)
01557 for (unsigned int j = 0; j < lhs.ncols(); j++)
01558 tmp[i][j] = pow(lhs[i][j], a);
01559
01560 return tmp;
01561 }
01562
01563 template <typename T>
01564 inline Matrix<T>& Matrix<T>::operator^=(const Matrix<T>& rhs)
01565 {
01566 if (m != rhs.ncols() || n != rhs.nrows())
01567 throw std::logic_error("Operator^=: matrices have different sizes");
01568 for (unsigned int i = 0; i < n; i++)
01569 for (unsigned int j = 0; j < m; j++)
01570 v[i][j] = pow(v[i][j], rhs[i][j]);
01571
01572 return *this;
01573 }
01574
01575
01576 template <typename T>
01577 inline Matrix<T>& Matrix<T>::operator^=(const T& a)
01578 {
01579 for (unsigned int i = 0; i < n; i++)
01580 for (unsigned int j = 0; j < m; j++)
01581 v[i][j] = pow(v[i][j], a);
01582
01583 return *this;
01584 }
01585
01586 template <typename T>
01587 inline Matrix<T>::operator Vector<T>()
01588 {
01589 if (n > 1 && m > 1)
01590 throw std::logic_error("Error matrix cast to vector: trying to cast a multi-dimensional matrix");
01591 if (n == 1)
01592 return extractRow(0);
01593 else
01594 return extractColumn(0);
01595 }
01596
01597 template <typename T>
01598 inline bool operator==(const Matrix<T>& a, const Matrix<T>& b)
01599 {
01600 if (a.nrows() != b.nrows() || a.ncols() != b.ncols())
01601 throw std::logic_error("Matrices of different size are not confrontable");
01602 for (unsigned i = 0; i < a.nrows(); i++)
01603 for (unsigned j = 0; j < a.ncols(); j++)
01604 if (a[i][j] != b[i][j])
01605 return false;
01606 return true;
01607 }
01608
01609 template <typename T>
01610 inline bool operator!=(const Matrix<T>& a, const Matrix<T>& b)
01611 {
01612 if (a.nrows() != b.nrows() || a.ncols() != b.ncols())
01613 throw std::logic_error("Matrices of different size are not confrontable");
01614 for (unsigned i = 0; i < a.nrows(); i++)
01615 for (unsigned j = 0; j < a.ncols(); j++)
01616 if (a[i][j] != b[i][j])
01617 return true;
01618 return false;
01619 }
01620
01621
01622
01626 template <typename T>
01627 std::ostream& operator<<(std::ostream& os, const Matrix<T>& m)
01628 {
01629 os << std::endl << m.nrows() << " " << m.ncols() << std::endl;
01630 for (unsigned int i = 0; i < m.nrows(); i++)
01631 {
01632 for (unsigned int j = 0; j < m.ncols() - 1; j++)
01633 os << std::setw(20) << std::setprecision(16) << m[i][j] << ", ";
01634 os << std::setw(20) << std::setprecision(16) << m[i][m.ncols() - 1] << std::endl;
01635 }
01636
01637 return os;
01638 }
01639
01640 template <typename T>
01641 std::istream& operator>>(std::istream& is, Matrix<T>& m)
01642 {
01643 int rows, cols;
01644 char comma;
01645 is >> rows >> cols;
01646 m.resize(rows, cols);
01647 for (unsigned int i = 0; i < rows; i++)
01648 for (unsigned int j = 0; j < cols; j++)
01649 is >> m[i][j] >> comma;
01650
01651 return is;
01652 }
01653
01654 template <typename T>
01655 T sign(const T& v)
01656 {
01657 if (v >= (T)0.0)
01658 return (T)1.0;
01659 else
01660 return (T)-1.0;
01661 }
01662
01663 template <typename T>
01664 T dist(const T& a, const T& b)
01665 {
01666 T abs_a = (T)fabs(a), abs_b = (T)fabs(b);
01667 if (abs_a > abs_b)
01668 return abs_a * sqrt((T)1.0 + (abs_b / abs_a) * (abs_b / abs_a));
01669 else
01670 return (abs_b == (T)0.0 ? (T)0.0 : abs_b * sqrt((T)1.0 + (abs_a / abs_b) * (abs_a / abs_b)));
01671 }
01672
01673 template <typename T>
01674 void svd(const Matrix<T>& A, Matrix<T>& U, Vector<T>& W, Matrix<T>& V)
01675 {
01676 int m = A.nrows(), n = A.ncols(), i, j, k, l, jj, nm;
01677 const unsigned int max_its = 30;
01678 bool flag;
01679 Vector<T> rv1(n);
01680 U = A;
01681 W.resize(n);
01682 V.resize(n, n);
01683 T anorm, c, f, g, h, s, scale, x, y, z;
01684 g = scale = anorm = (T)0.0;
01685
01686
01687 for (i = 0; i < n; i++)
01688 {
01689 l = i + 1;
01690 rv1[i] = scale * g;
01691 g = s = scale = (T)0.0;
01692 if (i < m)
01693 {
01694 for (k = i; k < m; k++)
01695 scale += fabs(U[k][i]);
01696 if (scale != (T)0.0)
01697 {
01698 for (k = i; k < m; k++)
01699 {
01700 U[k][i] /= scale;
01701 s += U[k][i] * U[k][i];
01702 }
01703 f = U[i][i];
01704 g = -sign(f) * sqrt(s);
01705 h = f * g - s;
01706 U[i][i] = f - g;
01707 for (j = l; j < n; j++)
01708 {
01709 s = (T)0.0;
01710 for (k = i; k < m; k++)
01711 s += U[k][i] * U[k][j];
01712 f = s / h;
01713 for (k = i; k < m; k++)
01714 U[k][j] += f * U[k][i];
01715 }
01716 for (k = i; k < m; k++)
01717 U[k][i] *= scale;
01718 }
01719 }
01720 W[i] = scale * g;
01721 g = s = scale = (T)0.0;
01722 if (i < m && i != n - 1)
01723 {
01724 for (k = l; k < n; k++)
01725 scale += fabs(U[i][k]);
01726 if (scale != (T)0.0)
01727 {
01728 for (k = l; k < n; k++)
01729 {
01730 U[i][k] /= scale;
01731 s += U[i][k] * U[i][k];
01732 }
01733 f = U[i][l];
01734 g = -sign(f) * sqrt(s);
01735 h = f * g - s;
01736 U[i][l] = f - g;
01737 for (k = l; k <n; k++)
01738 rv1[k] = U[i][k] / h;
01739 for (j = l; j < m; j++)
01740 {
01741 s = (T)0.0;
01742 for (k = l; k < n; k++)
01743 s += U[j][k] * U[i][k];
01744 for (k = l; k < n; k++)
01745 U[j][k] += s * rv1[k];
01746 }
01747 for (k = l; k < n; k++)
01748 U[i][k] *= scale;
01749 }
01750 }
01751 anorm = std::max(anorm, fabs(W[i]) + fabs(rv1[i]));
01752 }
01753
01754 for (i = n - 1; i >= 0; i--)
01755 {
01756 if (i < n - 1)
01757 {
01758 if (g != (T)0.0)
01759 {
01760 for (j = l; j < n; j++)
01761 V[j][i] = (U[i][j] / U[i][l]) / g;
01762 for (j = l; j < n; j++)
01763 {
01764 s = (T)0.0;
01765 for (k = l; k < n; k++)
01766 s += U[i][k] * V[k][j];
01767 for (k = l; k < n; k++)
01768 V[k][j] += s * V[k][i];
01769 }
01770 }
01771 for (j = l; j < n; j++)
01772 V[i][j] = V[j][i] = (T)0.0;
01773 }
01774 V[i][i] = (T)1.0;
01775 g = rv1[i];
01776 l = i;
01777 }
01778
01779 for (i = std::min(m, n) - 1; i >= 0; i--)
01780 {
01781 l = i + 1;
01782 g = W[i];
01783 for (j = l; j < n; j++)
01784 U[i][j] = (T)0.0;
01785 if (g != (T)0.0)
01786 {
01787 g = (T)1.0 / g;
01788 for (j = l; j < n; j++)
01789 {
01790 s = (T)0.0;
01791 for (k = l; k < m; k++)
01792 s += U[k][i] * U[k][j];
01793 f = (s / U[i][i]) * g;
01794 for (k = i; k < m; k++)
01795 U[k][j] += f * U[k][i];
01796 }
01797 for (j = i; j < m; j++)
01798 U[j][i] *= g;
01799 }
01800 else
01801 for (j = i; j < m; j++)
01802 U[j][i] = (T)0.0;
01803 U[i][i]++;
01804 }
01805
01806 for (k = n - 1; k >= 0; k--)
01807 {
01808 for (unsigned int its = 0; its < max_its; its++)
01809 {
01810 flag = true;
01811 for (l = k; l >= 0; l--)
01812 {
01813 nm = l - 1;
01814 if ((T)(fabs(rv1[l]) + anorm) == anorm)
01815 {
01816 flag = false;
01817 break;
01818 }
01819 if ((T)(fabs(W[nm]) + anorm) == anorm)
01820 break;
01821 }
01822 if (flag)
01823 {
01824
01825 c = (T)0.0;
01826 s = (T)1.0;
01827 for (i = l; i <= k; i++)
01828 {
01829 f = s * rv1[i];
01830 rv1[i] *= c;
01831 if ((T)(fabs(f) + anorm) == anorm)
01832 break;
01833 g = W[i];
01834 h = dist(f, g);
01835 W[i] = h;
01836 h = (T)1.0 / h;
01837 c = g * h;
01838 s = -f * h;
01839 for (j = 0; j < m; j++)
01840 {
01841 y = U[j][nm];
01842 z = U[j][i];
01843 U[j][nm] = y * c + z * s;
01844 U[j][i] = z * c - y * s;
01845 }
01846 }
01847 }
01848 z = W[k];
01849 if (l == k)
01850 {
01851 if (z < (T)0.0)
01852 {
01853 W[k] = -z;
01854 for (j = 0; j < n; j++)
01855 V[j][k] = -V[j][k];
01856 }
01857 break;
01858 }
01859 if (its == max_its)
01860 throw std::logic_error("Error svd: no convergence in the maximum number of iterations");
01861 x = W[l];
01862 nm = k - 1;
01863 y = W[nm];
01864 g = rv1[nm];
01865 h = rv1[k];
01866 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
01867 g = dist(f, (T)1.0);
01868 f = ((x - z) * (x + z) + h * ((y / (f + sign(f)*fabs(g))) - h)) / x;
01869 c = s = (T)1.0;
01870 for (j = l; j <= nm; j++)
01871 {
01872 i = j + 1;
01873 g = rv1[i];
01874 y = W[i];
01875 h = s * g;
01876 g *= c;
01877 z = dist(f, h);
01878 rv1[j] = z;
01879 c = f / z;
01880 s = h / z;
01881 f = x * c + g * s;
01882 g = g * c - x * s;
01883 h = y * s;
01884 y *= c;
01885 for (jj = 0; jj < n; jj++)
01886 {
01887 x = V[jj][j];
01888 z = V[jj][i];
01889 V[jj][j] = x * c + z * s;
01890 V[jj][i] = z * c - x * s;
01891 }
01892 z = dist(f, h);
01893 W[j] = z;
01894 if (z != 0)
01895 {
01896 z = (T)1.0 / z;
01897 c = f * z;
01898 s = h * z;
01899 }
01900 f = c * g + s * y;
01901 x = c * y - s * g;
01902 for (jj = 0; jj < m; jj++)
01903 {
01904 y = U[jj][j];
01905 z = U[jj][i];
01906 U[jj][j] = y * c + z * s;
01907 U[jj][i] = z * c - y * s;
01908 }
01909 }
01910 rv1[l] = (T)0.0;
01911 rv1[k] = f;
01912 W[k] = x;
01913 }
01914 }
01915 }
01916
01917 template <typename T>
01918 Matrix<T> pinv(const Matrix<T>& A)
01919 {
01920 Matrix<T> U, V, x, tmp(A.ncols(), A.nrows());
01921 Vector<T> W;
01922 CanonicalBaseVector<T> e(0, A.nrows());
01923 svd(A, U, W, V);
01924 for (unsigned int i = 0; i < A.nrows(); i++)
01925 {
01926 e.reset(i);
01927 tmp.setColumn(i, dot_prod(dot_prod(dot_prod(V, Matrix<double>(DIAG, 1.0 / W, 0.0, W.size(), W.size())), t(U)), e));
01928 }
01929
01930 return tmp;
01931 }
01932
01933 template <typename T>
01934 int lu(const Matrix<T>& A, Matrix<T>& LU, Vector<unsigned int>& index)
01935 {
01936 if (A.ncols() != A.nrows())
01937 throw std::logic_error("Error in LU decomposition: matrix must be squared");
01938 int i, p, j, k, n = A.ncols(), ex;
01939 T val, tmp;
01940 Vector<T> d(n);
01941 LU = A;
01942 index.resize(n);
01943
01944 ex = 1;
01945 for (i = 0; i < n; i++)
01946 {
01947 index[i] = i;
01948 val = (T)0.0;
01949 for (j = 0; j < n; j++)
01950 val = std::max(val, (T)fabs(LU[i][j]));
01951 if (val == (T)0.0)
01952 std::logic_error("Error in LU decomposition: matrix was singular");
01953 d[i] = val;
01954 }
01955
01956 for (k = 0; k < n - 1; k++)
01957 {
01958 p = k;
01959 val = fabs(LU[k][k]) / d[k];
01960 for (i = k + 1; i < n; i++)
01961 {
01962 tmp = fabs(LU[i][k]) / d[i];
01963 if (tmp > val)
01964 {
01965 val = tmp;
01966 p = i;
01967 }
01968 }
01969 if (val == (T)0.0)
01970 std::logic_error("Error in LU decomposition: matrix was singular");
01971 if (p > k)
01972 {
01973 ex = -ex;
01974 std::swap(index[k], index[p]);
01975 std::swap(d[k], d[p]);
01976 for (j = 0; j < n; j++)
01977 std::swap(LU[k][j], LU[p][j]);
01978 }
01979
01980 for (i = k + 1; i < n; i++)
01981 {
01982 LU[i][k] /= LU[k][k];
01983 for (j = k + 1; j < n; j++)
01984 LU[i][j] -= LU[i][k] * LU[k][j];
01985 }
01986 }
01987 if (LU[n - 1][n - 1] == (T)0.0)
01988 std::logic_error("Error in LU decomposition: matrix was singular");
01989
01990 return ex;
01991 }
01992
01993 template <typename T>
01994 Vector<T> lu_solve(const Matrix<T>& LU, const Vector<T>& b, Vector<unsigned int>& index)
01995 {
01996 if (LU.ncols() != LU.nrows())
01997 throw std::logic_error("Error in LU solve: LU matrix should be squared");
01998 unsigned int n = LU.ncols();
01999 if (b.size() != n)
02000 throw std::logic_error("Error in LU solve: b vector must be of the same dimensions of LU matrix");
02001 Vector<T> x((T)0.0, n);
02002 int i, j, p;
02003 T sum;
02004
02005 p = index[0];
02006 x[0] = b[p];
02007
02008 for (i = 1; i < n; i++)
02009 {
02010 sum = (T)0.0;
02011 for (j = 0; j < i; j++)
02012 sum += LU[i][j] * x[j];
02013 p = index[i];
02014 x[i] = b[p] - sum;
02015 }
02016 x[n - 1] /= LU[n - 1][n - 1];
02017 for (i = n - 2; i >= 0; i--)
02018 {
02019 sum = (T)0.0;
02020 for (j = i + 1; j < n; j++)
02021 sum += LU[i][j] * x[j];
02022 x[i] = (x[i] - sum) / LU[i][i];
02023 }
02024 return x;
02025 }
02026
02027 template <typename T>
02028 void lu_solve(const Matrix<T>& LU, Vector<T>& x, const Vector<T>& b, Vector<unsigned int>& index)
02029 {
02030 x = lu_solve(LU, b, index);
02031 }
02032
02033 template <typename T>
02034 Matrix<T> lu_inverse(const Matrix<T>& A)
02035 {
02036 if (A.ncols() != A.nrows())
02037 throw std::logic_error("Error in LU invert: matrix must be squared");
02038 unsigned int n = A.ncols();
02039 Matrix<T> A1(n, n), LU;
02040 Vector<unsigned int> index;
02041
02042 lu(A, LU, index);
02043 CanonicalBaseVector<T> e(0, n);
02044 for (unsigned i = 0; i < n; i++)
02045 {
02046 e.reset(i);
02047 A1.setColumn(i, lu_solve(LU, e, index));
02048 }
02049
02050 return A1;
02051 }
02052
02053 template <typename T>
02054 T lu_det(const Matrix<T>& A)
02055 {
02056 if (A.ncols() != A.nrows())
02057 throw std::logic_error("Error in LU determinant: matrix must be squared");
02058 unsigned int d;
02059 Matrix<T> LU;
02060 Vector<unsigned int> index;
02061
02062 d = lu(A, LU, index);
02063
02064 return d * prod(LU.extractDiag());
02065 }
02066
02067 template <typename T>
02068 void cholesky(const Matrix<T> A, Matrix<T>& LL)
02069 {
02070 if (A.ncols() != A.nrows())
02071 throw std::logic_error("Error in Cholesky decomposition: matrix must be squared");
02072 int i, j, k, n = A.ncols();
02073 double sum;
02074 LL = A;
02075
02076 for (i = 0; i < n; i++)
02077 {
02078 for (j = i; j < n; j++)
02079 {
02080 sum = LL[i][j];
02081 for (k = i - 1; k >= 0; k--)
02082 sum -= LL[i][k] * LL[j][k];
02083 if (i == j)
02084 {
02085 if (sum <= 0.0)
02086 throw std::logic_error("Error in Cholesky decomposition: matrix is not postive definite");
02087 LL[i][i] = ::std::sqrt(sum);
02088 }
02089 else
02090 LL[j][i] = sum / LL[i][i];
02091 }
02092 for (k = i + 1; k < n; k++)
02093 LL[i][k] = LL[k][i];
02094 }
02095 }
02096
02097 template <typename T>
02098 Matrix<T> cholesky(const Matrix<T> A)
02099 {
02100 Matrix<T> LL;
02101 cholesky(A, LL);
02102
02103 return LL;
02104 }
02105
02106 template <typename T>
02107 Vector<T> cholesky_solve(const Matrix<T>& LL, const Vector<T>& b)
02108 {
02109 if (LL.ncols() != LL.nrows())
02110 throw std::logic_error("Error in Cholesky solve: matrix must be squared");
02111 unsigned int n = LL.ncols();
02112 if (b.size() != n)
02113 throw std::logic_error("Error in Cholesky decomposition: b vector must be of the same dimensions of LU matrix");
02114 Vector<T> x, y;
02115
02116
02117 forward_elimination(LL, y, b);
02118
02119 backward_elimination(LL, x, y);
02120
02121 return x;
02122 }
02123
02124 template <typename T>
02125 void cholesky_solve(const Matrix<T>& LL, Vector<T>& x, const Vector<T>& b)
02126 {
02127 x = cholesky_solve(LL, b);
02128 }
02129
02130 template <typename T>
02131 void forward_elimination(const Matrix<T>& L, Vector<T>& y, const Vector<T> b)
02132 {
02133 if (L.ncols() != L.nrows())
02134 throw std::logic_error("Error in Forward elimination: matrix must be squared (lower triangular)");
02135 if (b.size() != L.nrows())
02136 throw std::logic_error("Error in Forward elimination: b vector must be of the same dimensions of L matrix");
02137 int i, j, n = b.size();
02138 y.resize(n);
02139
02140 y[0] = b[0] / L[0][0];
02141 for (i = 1; i < n; i++)
02142 {
02143 y[i] = b[i];
02144 for (j = 0; j < i; j++)
02145 y[i] -= L[i][j] * y[j];
02146 y[i] = y[i] / L[i][i];
02147 }
02148 }
02149
02150 template <typename T>
02151 Vector<T> forward_elimination(const Matrix<T>& L, const Vector<T> b)
02152 {
02153 Vector<T> y;
02154 forward_elimination(L, y, b);
02155
02156 return y;
02157 }
02158
02159 template <typename T>
02160 void backward_elimination(const Matrix<T>& U, Vector<T>& x, const Vector<T>& y)
02161 {
02162 if (U.ncols() != U.nrows())
02163 throw std::logic_error("Error in Backward elimination: matrix must be squared (upper triangular)");
02164 if (y.size() != U.nrows())
02165 throw std::logic_error("Error in Backward elimination: b vector must be of the same dimensions of U matrix");
02166 int i, j, n = y.size();
02167 x.resize(n);
02168
02169 x[n - 1] = y[n - 1] / U[n - 1][n - 1];
02170 for (i = n - 2; i >= 0; i--)
02171 {
02172 x[i] = y[i];
02173 for (j = i + 1; j < n; j++)
02174 x[i] -= U[i][j] * x[j];
02175 x[i] = x[i] / U[i][i];
02176 }
02177 }
02178
02179 template <typename T>
02180 Vector<T> backward_elimination(const Matrix<T>& U, const Vector<T> y)
02181 {
02182 Vector<T> x;
02183 forward_elimination(U, x, y);
02184
02185 return x;
02186 }
02187
02188
02189
02190 #define det lu_det
02191 #define inverse lu_inverse
02192 #define solve lu_solve
02193
02194
02195
02196 template <typename T>
02197 void random(Matrix<T>& m)
02198 {
02199 for (unsigned int i = 0; i < m.nrows(); i++)
02200 for (unsigned int j = 0; j < m.ncols(); j++)
02201 m[i][j] = (T)(rand() / double(RAND_MAX));
02202 }
02203
02208 template <typename T>
02209 Vector<T> sum(const Matrix<T>& m)
02210 {
02211 Vector<T> tmp((T)0, m.ncols());
02212 for (unsigned int j = 0; j < m.ncols(); j++)
02213 for (unsigned int i = 0; i < m.nrows(); i++)
02214 tmp[j] += m[i][j];
02215 return tmp;
02216 }
02217
02218 template <typename T>
02219 Vector<T> r_sum(const Matrix<T>& m)
02220 {
02221 Vector<T> tmp((T)0, m.nrows());
02222 for (unsigned int i = 0; i < m.nrows(); i++)
02223 for (unsigned int j = 0; j < m.ncols(); j++)
02224 tmp[i] += m[i][j];
02225 return tmp;
02226 }
02227
02228 template <typename T>
02229 T all_sum(const Matrix<T>& m)
02230 {
02231 T tmp = (T)0;
02232 for (unsigned int i = 0; i < m.nrows(); i++)
02233 for (unsigned int j = 0; j < m.ncols(); j++)
02234 tmp += m[i][j];
02235 return tmp;
02236 }
02237
02238 template <typename T>
02239 Vector<T> prod(const Matrix<T>& m)
02240 {
02241 Vector<T> tmp((T)1, m.ncols());
02242 for (unsigned int j = 0; j < m.ncols(); j++)
02243 for (unsigned int i = 0; i < m.nrows(); i++)
02244 tmp[j] *= m[i][j];
02245 return tmp;
02246 }
02247
02248 template <typename T>
02249 Vector<T> r_prod(const Matrix<T>& m)
02250 {
02251 Vector<T> tmp((T)1, m.nrows());
02252 for (unsigned int i = 0; i < m.nrows(); i++)
02253 for (unsigned int j = 0; j < m.ncols(); j++)
02254 tmp[i] *= m[i][j];
02255 return tmp;
02256 }
02257
02258 template <typename T>
02259 T all_prod(const Matrix<T>& m)
02260 {
02261 T tmp = (T)1;
02262 for (unsigned int i = 0; i < m.nrows(); i++)
02263 for (unsigned int j = 0; j < m.ncols(); j++)
02264 tmp *= m[i][j];
02265 return tmp;
02266 }
02267
02268 template <typename T>
02269 Vector<T> mean(const Matrix<T>& m)
02270 {
02271 Vector<T> res((T)0, m.ncols());
02272 for (unsigned int j = 0; j < m.ncols(); j++)
02273 {
02274 for (unsigned int i = 0; i < m.nrows(); i++)
02275 res[j] += m[i][j];
02276 res[j] /= m.nrows();
02277 }
02278
02279 return res;
02280 }
02281
02282 template <typename T>
02283 Vector<T> r_mean(const Matrix<T>& m)
02284 {
02285 Vector<T> res((T)0, m.rows());
02286 for (unsigned int i = 0; i < m.nrows(); i++)
02287 {
02288 for (unsigned int j = 0; j < m.ncols(); j++)
02289 res[i] += m[i][j];
02290 res[i] /= m.nrows();
02291 }
02292
02293 return res;
02294 }
02295
02296 template <typename T>
02297 T all_mean(const Matrix<T>& m)
02298 {
02299 T tmp = (T)0;
02300 for (unsigned int i = 0; i < m.nrows(); i++)
02301 for (unsigned int j = 0; j < m.ncols(); j++)
02302 tmp += m[i][j];
02303 return tmp / (m.nrows() * m.ncols());
02304 }
02305
02306 template <typename T>
02307 Vector<T> var(const Matrix<T>& m, bool sample_correction = false)
02308 {
02309 Vector<T> res((T)0, m.ncols());
02310 unsigned int n = m.nrows();
02311 double sum, ssum;
02312 for (unsigned int j = 0; j < m.ncols(); j++)
02313 {
02314 sum = (T)0.0; ssum = (T)0.0;
02315 for (unsigned int i = 0; i < m.nrows(); i++)
02316 {
02317 sum += m[i][j];
02318 ssum += (m[i][j] * m[i][j]);
02319 }
02320 if (!sample_correction)
02321 res[j] = (ssum / n) - (sum / n) * (sum / n);
02322 else
02323 res[j] = n * ((ssum / n) - (sum / n) * (sum / n)) / (n - 1);
02324 }
02325
02326 return res;
02327 }
02328
02329 template <typename T>
02330 Vector<T> stdev(const Matrix<T>& m, bool sample_correction = false)
02331 {
02332 return sqrt(var(m, sample_correction));
02333 }
02334
02335 template <typename T>
02336 Vector<T> r_var(const Matrix<T>& m, bool sample_correction = false)
02337 {
02338 Vector<T> res((T)0, m.nrows());
02339 double sum, ssum;
02340 unsigned int n = m.ncols();
02341 for (unsigned int i = 0; i < m.nrows(); i++)
02342 {
02343 sum = 0.0; ssum = 0.0;
02344 for (unsigned int j = 0; j < m.ncols(); j++)
02345 {
02346 sum += m[i][j];
02347 ssum += (m[i][j] * m[i][j]);
02348 }
02349 if (!sample_correction)
02350 res[i] = (ssum / n) - (sum / n) * (sum / n);
02351 else
02352 res[i] = n * ((ssum / n) - (sum / n) * (sum / n)) / (n - 1);
02353 }
02354
02355 return res;
02356 }
02357
02358 template <typename T>
02359 Vector<T> r_stdev(const Matrix<T>& m, bool sample_correction = false)
02360 {
02361 return sqrt(r_var(m, sample_correction));
02362 }
02363
02364 template <typename T>
02365 Vector<T> max(const Matrix<T>& m)
02366 {
02367 Vector<T> res(m.ncols());
02368 double value;
02369 for (unsigned int j = 0; j < m.ncols(); j++)
02370 {
02371 value = m[0][j];
02372 for (unsigned int i = 1; i < m.nrows(); i++)
02373 value = std::max(m[i][j], value);
02374 res[j] = value;
02375 }
02376
02377 return res;
02378 }
02379
02380 template <typename T>
02381 Vector<T> r_max(const Matrix<T>& m)
02382 {
02383 Vector<T> res(m.nrows());
02384 double value;
02385 for (unsigned int i = 0; i < m.nrows(); i++)
02386 {
02387 value = m[i][0];
02388 for (unsigned int j = 1; j < m.ncols(); j++)
02389 value = std::max(m[i][j], value);
02390 res[i] = value;
02391 }
02392
02393 return res;
02394 }
02395
02396 template <typename T>
02397 Vector<T> min(const Matrix<T>& m)
02398 {
02399 Vector<T> res(m.ncols());
02400 double value;
02401 for (unsigned int j = 0; j < m.ncols(); j++)
02402 {
02403 value = m[0][j];
02404 for (unsigned int i = 1; i < m.nrows(); i++)
02405 value = std::min(m[i][j], value);
02406 res[j] = value;
02407 }
02408
02409 return res;
02410 }
02411
02412 template <typename T>
02413 Vector<T> r_min(const Matrix<T>& m)
02414 {
02415 Vector<T> res(m.nrows());
02416 double value;
02417 for (unsigned int i = 0; i < m.nrows(); i++)
02418 {
02419 value = m[i][0];
02420 for (unsigned int j = 1; j < m.ncols(); j++)
02421 value = std::min(m[i][j], value);
02422 res[i] = value;
02423 }
02424
02425 return res;
02426 }
02427
02428
02429
02434 template <typename T>
02435 Matrix<T> exp(const Matrix<T>&m)
02436 {
02437 Matrix<T> tmp(m.nrows(), m.ncols());
02438
02439 for (unsigned int i = 0; i < m.nrows(); i++)
02440 for (unsigned int j = 0; j < m.ncols(); j++)
02441 tmp[i][j] = exp(m[i][j]);
02442
02443 return tmp;
02444 }
02445
02446 template <typename T>
02447 Matrix<T> sqrt(const Matrix<T>&m)
02448 {
02449 Matrix<T> tmp(m.nrows(), m.ncols());
02450
02451 for (unsigned int i = 0; i < m.nrows(); i++)
02452 for (unsigned int j = 0; j < m.ncols(); j++)
02453 tmp[i][j] = sqrt(m[i][j]);
02454
02455 return tmp;
02456 }
02457
02462 template <typename T>
02463 Matrix<T> kron(const Vector<T>& b, const Vector<T>& a)
02464 {
02465 Matrix<T> tmp(b.size(), a.size());
02466 for (unsigned int i = 0; i < b.size(); i++)
02467 for (unsigned int j = 0; j < a.size(); j++)
02468 tmp[i][j] = a[j] * b[i];
02469
02470 return tmp;
02471 }
02472
02473 template <typename T>
02474 Matrix<T> t(const Matrix<T>& a)
02475 {
02476 Matrix<T> tmp(a.ncols(), a.nrows());
02477 for (unsigned int i = 0; i < a.nrows(); i++)
02478 for (unsigned int j = 0; j < a.ncols(); j++)
02479 tmp[j][i] = a[i][j];
02480
02481 return tmp;
02482 }
02483
02484 template <typename T>
02485 Matrix<T> dot_prod(const Matrix<T>& a, const Matrix<T>& b)
02486 {
02487 if (a.ncols() != b.nrows())
02488 throw std::logic_error("Error matrix dot product: dimensions of the matrices are not compatible");
02489 Matrix<T> tmp(a.nrows(), b.ncols());
02490 for (unsigned int i = 0; i < tmp.nrows(); i++)
02491 for (unsigned int j = 0; j < tmp.ncols(); j++)
02492 {
02493 tmp[i][j] = (T)0;
02494 for (unsigned int k = 0; k < a.ncols(); k++)
02495 tmp[i][j] += a[i][k] * b[k][j];
02496 }
02497
02498 return tmp;
02499 }
02500
02501 template <typename T>
02502 Matrix<T> dot_prod(const Matrix<T>& a, const Vector<T>& b)
02503 {
02504 if (a.ncols() != b.size())
02505 throw std::logic_error("Error matrix dot product: dimensions of the matrix and the vector are not compatible");
02506 Matrix<T> tmp(a.nrows(), 1);
02507 for (unsigned int i = 0; i < tmp.nrows(); i++)
02508 {
02509 tmp[i][0] = (T)0;
02510 for (unsigned int k = 0; k < a.ncols(); k++)
02511 tmp[i][0] += a[i][k] * b[k];
02512 }
02513
02514 return tmp;
02515 }
02516
02517 template <typename T>
02518 Matrix<T> dot_prod(const Vector<T>& a, const Matrix<T>& b)
02519 {
02520 if (a.size() != b.ncols())
02521 throw std::logic_error("Error matrix dot product: dimensions of the vector and matrix are not compatible");
02522 Matrix<T> tmp(1, b.ncols());
02523 for (unsigned int j = 0; j < tmp.ncols(); j++)
02524 {
02525 tmp[0][j] = (T)0;
02526 for (unsigned int k = 0; k < a.size(); k++)
02527 tmp[0][j] += a[k] * b[k][j];
02528 }
02529
02530 return tmp;
02531 }
02532
02533 template <typename T>
02534 inline Matrix<double> rank(const Matrix<T> m)
02535 {
02536 Matrix<double> tmp(m.nrows(), m.ncols());
02537 for (unsigned int j = 0; j < m.ncols(); j++)
02538 tmp.setColumn(j, rank<T>(m.extractColumn(j)));
02539
02540 return tmp;
02541 }
02542
02543 template <typename T>
02544 inline Matrix<double> r_rank(const Matrix<T> m)
02545 {
02546 Matrix<double> tmp(m.nrows(), m.ncols());
02547 for (unsigned int i = 0; i < m.nrows(); i++)
02548 tmp.setRow(i, rank<T>(m.extractRow(i)));
02549
02550 return tmp;
02551 }
02552
02553 }
02554
02555 #endif // define _ARRAY_HH_