00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 namespace MathCore
00059 {
00060
00061
00062
00063 template <class T>
00064 Vector<int> Find(Vector<T>& m)
00065 {
00066 std::vector<int> ind;
00067 for(int i=0; i<m.Length(); i++)
00068 {
00069 if(m.ElemNC(i) != 0)
00070 {
00071 ind.push_back(i);
00072 }
00073 }
00074 Vector<int> temp((int)ind.size());
00075 memcpy(temp.Data(), &ind[0], sizeof(int)*ind.size() );
00076
00077
00078
00079
00080
00081
00082
00083 return temp;
00084 }
00085
00086 template <class T>
00087 Vector<int> Find(Matrix<T>& m)
00088 {
00089 std::vector<int> ind;
00090 for(int i=0; i<m.Length(); i++)
00091 {
00092 if(m.ElemNC(i) != 0)
00093 {
00094 ind.push_back(i);
00095 }
00096 }
00097 Vector<int> temp((int)ind.size());
00098 memcpy(temp.Data(), &ind[0], sizeof(int)*ind.size() );
00099 return temp;
00100 }
00101
00102 template <class T>
00103 void Find(Matrix<T>& m, Vector<int>& I, Vector<int>& J)
00104 {
00105 std::vector<int> indI;
00106 std::vector<int> indJ;
00107 for(int j=0; j<m.Columns(); j++)
00108 {
00109 for(int i=0; i<m.Rows(); i++)
00110 {
00111 if(m.ElemNC(i,j) != 0)
00112 {
00113 indI.push_back(i);
00114 indJ.push_back(j);
00115 }
00116 }
00117 }
00118 I = Vector<int>((int)indI.size());
00119 memcpy(I.Data(), &indI[0], sizeof(int)*indI.size() );
00120 J = Vector<int>((int)indJ.size());
00121 memcpy(J.Data(), &indJ[0], sizeof(int)*indJ.size() );
00122 }
00123
00124
00125
00126
00127 template <class T>
00128 Vector<T> Cross(Vector<T>& x, Vector<T>& y)
00129 {
00130 Vector<T> temp(3);
00131 temp[0] = x[1]*y[2]-x[2]*y[1];
00132 temp[1] = x[2]*y[0]-x[0]*y[2];
00133 temp[2] = x[0]*y[1]-x[1]*y[0];
00134
00135 return temp;
00136 }
00137
00138
00139 template <class T>
00140 Matrix<T> Cross(Matrix<T>& x, Matrix<T>& y)
00141 {
00142 if(x.Rows() == 3)
00143 {
00144 return Cross(x,y,1);
00145 }
00146 else if(x.Columns() == 3)
00147 {
00148 return Cross(x,y,2);
00149 }
00150 else
00151 {
00152 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00153 Utility::RunTimeError("One of the dimension of the matrices x and y should be of length 3!");
00154 }
00155 }
00156
00157
00158 template <class T>
00159 Matrix<T> Cross(Matrix<T>& x, Matrix<T>& y, int dimension)
00160 {
00161 if(x.Rows() != y.Rows() || x.Columns() != y.Columns())
00162 {
00163 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00164 Utility::RunTimeError("Matrices are not of the same size!");
00165 }
00166
00167 Matrix<T> temp(x.Rows(), x.Columns());
00168
00169 if(dimension == 1)
00170 {
00171 if(temp.Rows() != 3)
00172 {
00173 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00174 Utility::RunTimeError("Both matrices x and y should be of length 3 along the dimension on which the cross product is taken!");
00175 }
00176 for(int z=0; z<temp.Columns(); z++)
00177 {
00178 temp.ElemNC(0,z) = x.ElemNC(1,z)*y.ElemNC(2,z) - x.ElemNC(2,z)*y.ElemNC(1,z);
00179 temp.ElemNC(1,z) = x.ElemNC(2,z)*y.ElemNC(0,z) - x.ElemNC(0,z)*y.ElemNC(2,z);
00180 temp.ElemNC(2,z) = x.ElemNC(0,z)*y.ElemNC(1,z) - x.ElemNC(1,z)*y.ElemNC(0,z);
00181 }
00182 }
00183 else if(dimension == 2)
00184 {
00185 if(temp.Columns() != 3)
00186 {
00187 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00188 Utility::RunTimeError("Both matrices x and y should be of length 3 along the dimension on which the cross product is taken!");
00189 }
00190 for(int z=0; z<temp.Rows(); z++)
00191 {
00192 temp.ElemNC(z,0) = x.ElemNC(z,1)*y.ElemNC(z,2) - x.ElemNC(z,2)*y.ElemNC(z,1);
00193 temp.ElemNC(z,1) = x.ElemNC(z,2)*y.ElemNC(z,0) - x.ElemNC(z,0)*y.ElemNC(z,2);
00194 temp.ElemNC(z,2) = x.ElemNC(z,0)*y.ElemNC(z,1) - x.ElemNC(z,1)*y.ElemNC(z,0);
00195 }
00196 }
00197 else
00198 {
00199 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00200 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00201 }
00202 return temp;
00203 }
00204
00205
00206
00207 template <class T>
00208 Vector<T> CumSum(Vector<T>& m)
00209 {
00210 Vector<T> temp(m.Length());
00211 temp.ElemNC(0) = m.ElemNC(0);
00212 for(int i=1; i<m.Length(); i++)
00213 {
00214 temp.ElemNC(i) = temp.ElemNC(i-1) + m.ElemNC(i);
00215 }
00216 return temp;
00217 }
00218
00219 template <class T>
00220 Matrix<T> CumSum(Matrix<T>& m)
00221 {
00222 return CumSum(m,1);
00223 }
00224
00225 template <class T>
00226 Matrix<T> CumSum(Matrix<T>& m, int dimension)
00227 {
00228 Matrix<T> temp(m.Rows(), m.Columns());
00229 if(dimension == 1)
00230 {
00231 for(int z=0; z<m.Columns(); z++)
00232 {
00233 temp.ElemNC(0,z) = m.ElemNC(0,z);
00234 for(int i=1; i<m.Rows(); i++)
00235 {
00236 temp.ElemNC(i,z) = temp.ElemNC(i-1,z) + m.ElemNC(i,z);
00237 }
00238 }
00239 }
00240 else if(dimension == 2)
00241 {
00242 for(int z=0; z<m.Rows(); z++)
00243 {
00244 temp.ElemNC(z,0) = m.ElemNC(z,0);
00245 for(int i=1; i<m.Columns(); i++)
00246 {
00247 temp.ElemNC(z,i) = temp.ElemNC(z,i-1) + m.ElemNC(z,i);
00248 }
00249 }
00250 }
00251 else
00252 {
00253 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00254 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00255 }
00256 return temp;
00257 }
00258
00259
00260
00261
00262 template <class T>
00263 Vector<T>& CumSumI(Vector<T>& m)
00264 {
00265 for(int i=1; i<m.Length(); i++)
00266 {
00267 m.ElemNC(i) = m.ElemNC(i-1) + m.ElemNC(i);
00268 }
00269 return m;
00270 }
00271
00272 template <class T>
00273 Matrix<T>& CumSumI(Matrix<T>& m)
00274 {
00275 return CumSum(m,1);
00276 }
00277
00278 template <class T>
00279 Matrix<T>& CumSumI(Matrix<T>& m, int dimension)
00280 {
00281 if(dimension == 1)
00282 {
00283 for(int z=0; z<m.Columns(); z++)
00284 {
00285 for(int i=1; i<m.Rows(); i++)
00286 {
00287 m.ElemNC(i,z) = m.ElemNC(i-1,z) + m.ElemNC(i,z);
00288 }
00289 }
00290 }
00291 else if(dimension == 2)
00292 {
00293 for(int z=0; z<m.Rows(); z++)
00294 {
00295 for(int i=1; i<m.Columns(); i++)
00296 {
00297 m.ElemNC(z,i) = m.ElemNC(z,i-1) + m.ElemNC(z,i);
00298 }
00299 }
00300 }
00301 else
00302 {
00303 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00304 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00305 }
00306 return m;
00307 }
00308
00309
00310
00311 template <class T>
00312 Vector<T> CumProd(Vector<T>& m)
00313 {
00314 Vector<T> temp(m.Length());
00315 temp.ElemNC(0) = m.ElemNC(0);
00316 for(int i=1; i<m.Length(); i++)
00317 {
00318 temp.ElemNC(i) = temp.ElemNC(i-1) * m.ElemNC(i);
00319 }
00320 return temp;
00321 }
00322
00323 template <class T>
00324 Matrix<T> CumProd(Matrix<T>& m)
00325 {
00326 return CumProd(m,1);
00327 }
00328
00329 template <class T>
00330 Matrix<T> CumProd(Matrix<T>& m, int dimension)
00331 {
00332 Matrix<T> temp(m.Rows(), m.Columns());
00333 if(dimension == 1)
00334 {
00335 for(int z=0; z<m.Columns(); z++)
00336 {
00337 temp.ElemNC(0,z) = m.ElemNC(0,z);
00338 for(int i=1; i<m.Rows(); i++)
00339 {
00340 temp.ElemNC(i,z) = temp.ElemNC(i-1,z) * m.ElemNC(i,z);
00341 }
00342 }
00343 }
00344 else if(dimension == 2)
00345 {
00346 for(int z=0; z<m.Rows(); z++)
00347 {
00348 temp.ElemNC(z,0) = m.ElemNC(z,0);
00349 for(int i=1; i<m.Columns(); i++)
00350 {
00351 temp.ElemNC(z,i) = temp.ElemNC(z,i-1) * m.ElemNC(z,i);
00352 }
00353 }
00354 }
00355 else
00356 {
00357 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00358 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00359 }
00360 return temp;
00361 }
00362
00363
00364 template <class T>
00365 Vector<T>& CumProdI(Vector<T>& m)
00366 {
00367 for(int i=1; i<m.Length(); i++)
00368 {
00369 m.ElemNC(i) = m.ElemNC(i-1) * m.ElemNC(i);
00370 }
00371 return m;
00372 }
00373
00374 template <class T>
00375 Matrix<T>& CumProdI(Matrix<T>& m)
00376 {
00377 return CumProd(m,1);
00378 }
00379
00380 template <class T>
00381 Matrix<T>& CumProdI(Matrix<T>& m, int dimension)
00382 {
00383 if(dimension == 1)
00384 {
00385 for(int z=0; z<m.Columns(); z++)
00386 {
00387 for(int i=1; i<m.Rows(); i++)
00388 {
00389 m.ElemNC(i,z) = m.ElemNC(i-1,z) * m.ElemNC(i,z);
00390 }
00391 }
00392 }
00393 else if(dimension == 2)
00394 {
00395 for(int z=0; z<m.Rows(); z++)
00396 {
00397 for(int i=1; i<m.Columns(); i++)
00398 {
00399 m.ElemNC(z,i) = m.ElemNC(z,i-1) * m.ElemNC(z,i);
00400 }
00401 }
00402 }
00403 else
00404 {
00405 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00406 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00407 }
00408 return m;
00409 }
00410
00411
00412 template <class T>
00413 Matrix<T> Diag(Vector<T>& m)
00414 {
00415 return Diag(m,0);
00416 }
00417
00418 template <class T>
00419 Matrix<T> Diag(Vector<T>& m, int k)
00420 {
00421 int absk = abs(k);
00422 int dim = m.Length() + absk;
00423 Matrix<T> temp(dim,dim,0);
00424 if(k>=0)
00425 {
00426 for(int i=0; i<m.Length(); i++)
00427 {
00428 temp.ElemNC(i,i+absk) = m[i];
00429 }
00430 }
00431 else
00432 {
00433 for(int i=0; i<m.Length(); i++)
00434 {
00435 temp.ElemNC(i+absk,i) = m[i];
00436 }
00437 }
00438 return temp;
00439 }
00440
00441
00442 template <class T>
00443 Vector<T> Diag(Matrix<T>& m)
00444 {
00445 return Diag(m,0);
00446 }
00447
00448
00449 template <class T>
00450 Vector<T> Diag(Matrix<T>& m, int k)
00451 {
00452 Vector<T> temp;
00453 int absk = abs(k);
00454 int dim;
00455 if(k>=0)
00456 {
00457 if(absk>=m.Columns())
00458 {
00459 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00460 Utility::RunTimeError("diagonal index k is outside the matrix dimensions!");
00461 }
00462 dim = m.Columns()-absk > m.Rows() ? m.Rows() : m.Columns()-absk;
00463 temp = Vector<T>(dim);
00464 for(int i=0; i<temp.Length(); i++)
00465 {
00466 temp[i] = m.ElemNC(i,i+absk);
00467 }
00468 }
00469 else
00470 {
00471 if(absk>=m.Rows())
00472 {
00473 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00474 Utility::RunTimeError("diagonal index k is outside the matrix dimensions!");
00475 }
00476 dim = m.Rows()-absk > m.Columns() ? m.Columns() : m.Rows()-absk;
00477 temp = Vector<T>(dim);
00478 for(int i=0; i<temp.Length(); i++)
00479 {
00480 temp[i] = m.ElemNC(i+absk,i);
00481 }
00482 }
00483
00484 return temp;
00485 }
00486
00487
00488
00489 template <class T>
00490 Matrix<T> FlipLR(Matrix<T>& m)
00491 {
00492 Matrix<T> temp(m.Rows(), m.Columns());
00493 for(int j=0; j<m.Columns(); j++)
00494 {
00495 for(int i=0; i<m.Rows(); i++)
00496 {
00497 temp.ElemNC(i,m.Columns()-j-1) = m.ElemNC(i,j);
00498 }
00499 }
00500 return temp;
00501 }
00502
00503
00504 template <class T>
00505 Matrix<T>& FlipLRI(Matrix<T>& m)
00506 {
00507 for(int j=0; j<m.Columns()/2; j++)
00508 {
00509 for(int i=0; i<m.Rows(); i++)
00510 {
00511 T dummy = m.ElemNC(i,j);
00512 m.ElemNC(i,j) = m.ElemNC(i,m.Columns()-j-1);
00513 m.ElemNC(i,m.Columns()-j-1) = dummy;
00514 }
00515 }
00516 return m;
00517 }
00518
00519
00520
00521 template <class T>
00522 Matrix<T> FlipUD(Matrix<T>& m)
00523 {
00524 Matrix<T> temp(m.Rows(), m.Columns());
00525 for(int j=0; j<m.Columns(); j++)
00526 {
00527 for(int i=0; i<m.Rows(); i++)
00528 {
00529 temp.ElemNC(m.Rows()-i-1,j) = m.ElemNC(i,j);
00530 }
00531 }
00532 return temp;
00533 }
00534
00535
00536 template <class T>
00537 Matrix<T>& FlipUDI(Matrix<T>& m)
00538 {
00539 for(int j=0; j<m.Columns(); j++)
00540 {
00541 for(int i=0; i<m.Rows()/2; i++)
00542 {
00543 T dummy = m.ElemNC(i,j);
00544 m.ElemNC(i,j) = m.ElemNC(m.Rows()-i-1,j);
00545 m.ElemNC(m.Rows()-i-1,j) = dummy;
00546 }
00547 }
00548 return m;
00549 }
00550
00551
00552
00553 template <class T>
00554 Vector<T> Reverse(Vector<T>& m)
00555 {
00556 Vector<T> temp(m.Length());
00557 for(int i=0; i<m.Length(); i++)
00558 {
00559 temp.ElemNC(m.Length()-i-1) = m.ElemNC(i);
00560 }
00561 return temp;
00562 }
00563
00564
00565 template <class T>
00566 Vector<T>& ReverseI(Vector<T>& m)
00567 {
00568 for(int i=0; i<(m.Length()+1)/2; i++)
00569 {
00570 T dummy = m.ElemNC(i);
00571 m.ElemNC(i) = m.ElemNC(m.Length()-i-1);
00572 m.ElemNC(m.Length()-i-1) = dummy;
00573 }
00574 return m;
00575 }
00576
00577
00578 template <class T>
00579 Matrix<T> Rot90(Matrix<T>& m)
00580 {
00581 return Rot90(m,1);
00582 }
00583
00584
00585 template <class T>
00586 Matrix<T> Rot90(Matrix<T>& m, int k)
00587 {
00588 int rot = k % 4;
00589 if(rot<0)
00590 {
00591 rot += 4;
00592 }
00593
00594 if(rot==0)
00595 {
00596 return m.Clone();
00597 }
00598 else if(rot==1)
00599 {
00600 return FlipUD(~m);
00601 }
00602 else if(rot==2)
00603 {
00604 return FlipLR(FlipUD(m));
00605 }
00606 else if(rot==3)
00607 {
00608 return FlipLR(~m);
00609 }
00610 else
00611 {
00612 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00613 Utility::RunTimeError("Something went wrong when trying to rotate the matrix!");
00614 }
00615 }
00616
00617 template <class T>
00618 Vector<T> Maximum(Matrix<T>& m)
00619 {
00620 Vector<T> maxes(m.Columns());
00621 for(int j=0; j<m.Columns(); j++)
00622 {
00623 maxes[j] = Maximum(m[j]);
00624 }
00625 return maxes;
00626 }
00627
00628 template <class T>
00629 T Maximum(Vector<T>& m)
00630 {
00631 T max = m.ElemNC(0);
00632 for(int i=1; i<m.Length(); i++)
00633 {
00634 max = max >= m.ElemNC(i) ? max : m.ElemNC(i);
00635 }
00636 return max;
00637 }
00638
00639 template <class T>
00640 Vector<T> Minimum(Matrix<T>& m)
00641 {
00642 Vector<T> mins(m.Columns());
00643 for(int j=0; j<m.Columns(); j++)
00644 {
00645 mins[j] = Minimum(m[j]);
00646 }
00647 return mins;
00648 }
00649
00650 template <class T>
00651 T Minimum(Vector<T>& m)
00652 {
00653 T min = m.ElemNC(0);
00654 for(int i=1; i<m.Length(); i++)
00655 {
00656 min = min <= m.ElemNC(i) ? min : m.ElemNC(i);
00657 }
00658 return min;
00659 }
00660
00661
00662 template <class T>
00663 Vector<double> Mean(Matrix<T>& m)
00664 {
00665 Vector<double> means(m.Columns());
00666 for(int j=0; j<m.Columns(); j++)
00667 {
00668 means[j] = Mean(m[j]);
00669 }
00670 return means;
00671 }
00672
00673 template <class T>
00674 double Mean(Vector<T>& m)
00675 {
00676 double mean = 0;
00677 for(int i=0; i<m.Length(); i++)
00678 {
00679 mean += m.ElemNC(i);
00680 }
00681 mean /= m.Length();
00682 return mean;
00683 }
00684
00685 template <class T>
00686 Vector<T> Median(Matrix<T>& m)
00687 {
00688 Vector<T> medians(m.Columns());
00689 for(int j=0; j<m.Columns(); j++)
00690 {
00691 medians[j] = Median(m[j]);
00692 }
00693 return medians;
00694 }
00695
00696 template <class T>
00697 T Median(Vector<T>& m)
00698 {
00699 Vector<T> temp = m.Clone();
00700 T *arr = temp.Data();
00701 int n = temp.Length();
00702 int low, high;
00703 int median;
00704 int middle, ll, hh;
00705
00706 low = 0;
00707 high = m.Length()-1;
00708 median = (low + high)/2;
00709 for(;;)
00710 {
00711 if(high <= low)
00712 {
00713 return arr[median];
00714 }
00715 if(high == low + 1)
00716 {
00717 if(arr[low] > arr[high])
00718 {
00719 Swap(arr[low], arr[high]);
00720 }
00721 return arr[median];
00722 }
00723
00724 middle = (low + high)/2;
00725 if(arr[middle] > arr[high])
00726 {
00727 Swap(arr[middle], arr[high]);
00728 }
00729 if(arr[low] > arr[high])
00730 {
00731 Swap(arr[low], arr[high]);
00732 }
00733 if(arr[middle] > arr[low])
00734 {
00735 Swap(arr[middle], arr[low]);
00736 }
00737
00738 Swap(arr[middle], arr[low+1]) ;
00739
00740 ll = low + 1;
00741 hh = high;
00742 for(;;)
00743 {
00744 do ll++; while(arr[low] > arr[ll]);
00745 do hh--; while(arr[hh] > arr[low]);
00746
00747 if (hh < ll)
00748 {
00749 break;
00750 }
00751
00752 Swap(arr[ll], arr[hh]);
00753 }
00754
00755 Swap(arr[low], arr[hh]);
00756
00757 if (hh <= median)
00758 {
00759 low = ll;
00760 }
00761 if (hh >= median)
00762 {
00763 high = hh - 1;
00764 }
00765 }
00766 }
00767
00768
00769 template <class T>
00770 Vector<double> Var(Matrix<T>& m)
00771 {
00772 return Var(m,true);
00773 }
00774
00775 template <class T>
00776 double Var(Vector<T>& m)
00777 {
00778 return Var(m,true);
00779 }
00780
00781
00782 template <class T>
00783 Vector<double> Var(Matrix<T>& m, bool unbiased)
00784 {
00785 Vector<double> vars(m.Columns());
00786 for(int j=0; j<m.Columns(); j++)
00787 {
00788 vars[j] = Var(m[j], unbiased);
00789 }
00790 return vars;
00791 }
00792
00793 template <class T>
00794 double Var(Vector<T>& m, bool unbiased)
00795 {
00796 double mean = Mean(m);
00797 double var = 0;
00798 for(int i=0; i<m.Length(); i++)
00799 {
00800 var += (m.ElemNC(i)-mean)*(m.ElemNC(i)-mean);
00801 }
00802
00803 if(unbiased)
00804 {
00805 return var/(m.Length()-1);
00806 }
00807 else
00808 {
00809 return var/m.Length();
00810 }
00811 }
00812
00813
00814
00815 template <class T>
00816 Vector<double> Std(Matrix<T>& m)
00817 {
00818 return Std(m,true);
00819 }
00820
00821 template <class T>
00822 double Std(Vector<T>& m)
00823 {
00824 return Std(m,true);
00825 }
00826
00827
00828 template <class T>
00829 Vector<double> Std(Matrix<T>& m, bool unbiased)
00830 {
00831 Vector<double> stds(m.Columns());
00832 for(int j=0; j<m.Columns(); j++)
00833 {
00834 stds[j] = Std(m[j], unbiased);
00835 }
00836 return stds;
00837 }
00838
00839 template <class T>
00840 double Std(Vector<T>& m, bool unbiased)
00841 {
00842 return sqrt(Var(m,unbiased));
00843 }
00844
00845
00846
00847
00848 template <class T>
00849 Vector<T> Sum(Matrix<T>& m)
00850 {
00851 return Sum(m,1);
00852 }
00853
00854
00855 template <class T>
00856 Vector<T> Sum(Matrix<T>& m, int dimension)
00857 {
00858 Vector<T> sums;
00859 if(dimension == 1)
00860 {
00861 sums = Vector<T>(m.Columns());
00862 for(int j=0; j<m.Columns(); j++)
00863 {
00864 sums[j] = Sum(m[j]);
00865 }
00866 }
00867 else if(dimension == 2)
00868 {
00869 sums = Vector<T>(m.Rows());
00870 for(int j=0; j<m.Rows(); j++)
00871 {
00872 T sum = 0;
00873 for(int i=0; i<m.Columns(); i++)
00874 {
00875 sum += m.ElemNC(j,i);
00876 }
00877 sums[j] = sum;
00878 }
00879 }
00880 else
00881 {
00882 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00883 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00884 }
00885 return sums;
00886 }
00887
00888 template <class T>
00889 T Sum(Vector<T>& m)
00890 {
00891 T sum = 0;
00892 for(int i=0; i<m.Length(); i++)
00893 {
00894 sum += m.ElemNC(i);
00895 }
00896 return sum;
00897 }
00898
00899
00900
00901
00902 template <class T>
00903 Vector<T> Prod(Matrix<T>& m)
00904 {
00905 return Prod(m,1);
00906 }
00907
00908
00909 template <class T>
00910 Vector<T> Prod(Matrix<T>& m, int dimension)
00911 {
00912 Vector<T> prods;
00913 if(dimension == 1)
00914 {
00915 prods = Vector<T>(m.Columns());
00916 for(int j=0; j<m.Columns(); j++)
00917 {
00918 prods[j] = Prod(m[j]);
00919 }
00920 }
00921 else if(dimension == 2)
00922 {
00923 prods = Vector<T>(m.Rows());
00924 for(int j=0; j<m.Rows(); j++)
00925 {
00926 T prod = 1;
00927 for(int i=0; i<m.Columns(); i++)
00928 {
00929 prod *= m.ElemNC(j,i);
00930 }
00931 prods[j] = prod;
00932 }
00933 }
00934 else
00935 {
00936 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00937 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00938 }
00939 return prods;
00940 }
00941
00942 template <class T>
00943 T Prod(Vector<T>& m)
00944 {
00945 T prod = 1;
00946 for(int i=0; i<m.Length(); i++)
00947 {
00948 prod *= m.ElemNC(i);
00949 }
00950 return prod;
00951 }
00952
00953
00954 template <class T>
00955 Vector<T> Diff(Vector<T>& m)
00956 {
00957 if(m.Length() == 1)
00958 {
00959 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00960 Utility::RunTimeError("Diff can only be called on vectors of length 2 or more!");
00961 }
00962 Vector<T> temp(m.Length()-1);
00963 for(int i=0;i<temp.Length(); i++)
00964 {
00965 temp.ElemNC(i) = m.ElemNC(i+1) - m.ElemNC(i);
00966 }
00967 return temp;
00968 }
00969
00970 template <class T>
00971 Matrix<T> Diff(Matrix<T>& m)
00972 {
00973 if(m.Rows() == 1)
00974 {
00975 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00976 Utility::RunTimeError("Diff can only be called on matrices with 2 or more rows!");
00977 }
00978 Matrix<T> temp(m.Rows()-1, m.Columns());
00979 for(int j=0; j<temp.Columns(); j++)
00980 {
00981 for(int i=0; i<temp.Rows(); i++)
00982 {
00983
00984 temp.ElemNC(i,j) = m.ElemNC(i+1,j) - m.ElemNC(i,j);
00985 }
00986 }
00987 return temp;
00988 }
00989
00990
00991
00992
00993 template <class T>
00994 Matrix<T> RepMat(Matrix<T>& m, int M, int N)
00995 {
00996 Matrix<T> temp(M*m.Rows(),N*m.Columns());
00997 for(int k=0; k<M; k++)
00998 {
00999 for(int l=0; l<N; l++)
01000 {
01001 int s = k*m.Rows();
01002 int t = l*m.Columns();
01003 for(int i=0; i<m.Rows(); i++)
01004 {
01005 for(int j=0; j<m.Columns(); j++)
01006 {
01007 temp.ElemNC(s+i,t+j) = m.ElemNC(i,j);
01008 }
01009 }
01010 }
01011 }
01012 return temp;
01013 }
01014
01015
01016
01017 template <class T>
01018 Matrix<T> Reshape(Matrix<T>& m, int M, int N)
01019 {
01020 if(m.Length() != M*N)
01021 {
01022 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01023 Utility::RunTimeError("Number of elements should be the same when using Reshape()!");
01024 }
01025 Matrix<T> temp(M,N);
01026 memcpy(temp.Data(), m.Data(), sizeof(T)*m.Length());
01027 return temp;
01028 }
01029
01030 template <class T>
01031 Matrix<T> Reshape(Vector<T>& m, int M, int N)
01032 {
01033 if(m.Length() != M*N)
01034 {
01035 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01036 Utility::RunTimeError("Number of elements should be the same when using Reshape()!");
01037 }
01038 Matrix<T> temp(M,N);
01039 memcpy(temp.Data(), m.Data(), sizeof(T)*m.Length());
01040 return temp;
01041 }
01042
01043 template <class T>
01044 Vector<T>& QuickSort(Vector<T>& m)
01045 {
01046 int M = 7;
01047 int NSTACK = 50;
01048
01049 int i, j, k;
01050 int l=1;
01051 int ir = m.Length();
01052 Vector<int> stack(m.Length());
01053 int *istack = stack.Data()-1;
01054 int jstack = 0;
01055
01056 T a;
01057 T* arr = m.Data()-1;
01058
01059 for (;;)
01060 {
01061 if (ir-l < M)
01062 {
01063 for (j=l+1;j<=ir;j++)
01064 {
01065 a=arr[j];
01066 for (i=j-1;i>=l;i--)
01067 {
01068 if (arr[i] <= a)
01069 {
01070 break;
01071 }
01072 arr[i+1]=arr[i];
01073 }
01074 arr[i+1]=a;
01075 }
01076 if (jstack == 0)
01077 {
01078 break;
01079 }
01080 ir=istack[jstack--];
01081 l=istack[jstack--];
01082 }
01083 else
01084 {
01085 k=(l+ir) >> 1;
01086 Swap(arr[k],arr[l+1]);
01087 if (arr[l] > arr[ir])
01088 {
01089 Swap(arr[l],arr[ir]);
01090 }
01091 if (arr[l+1] > arr[ir])
01092 {
01093 Swap(arr[l+1],arr[ir]);
01094 }
01095 if (arr[l] > arr[l+1])
01096 {
01097 Swap(arr[l],arr[l+1]);
01098 }
01099 i=l+1;
01100 j=ir;
01101 a=arr[l+1];
01102 for (;;)
01103 {
01104 do i++; while (arr[i] < a);
01105 do j--; while (arr[j] > a);
01106 if (j < i)
01107 {
01108 break;
01109 }
01110 Swap(arr[i],arr[j]);
01111 }
01112 arr[l+1]=arr[j];
01113 arr[j]=a;
01114 jstack += 2;
01115 if (jstack > NSTACK)
01116 {
01117 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01118 Utility::RunTimeError("Stack size is too small in quick sort!");
01119 }
01120 if (ir-i+1 >= j-l)
01121 {
01122 istack[jstack]=ir;
01123 istack[jstack-1]=i;
01124 ir=j-1;
01125 }
01126 else
01127 {
01128 istack[jstack]=j-1;
01129 istack[jstack-1]=l;
01130 l=i;
01131 }
01132 }
01133 }
01134 return m;
01135 }
01136
01137
01138 template <class T>
01139 Vector<T> Sort(Vector<T>& m)
01140 {
01141 Vector<T> sorted = m.Clone();
01142 QuickSort(sorted);
01143 return sorted;
01144 }
01145
01146 template <class T>
01147 Matrix<T> Sort(Matrix<T>& m, int dimension)
01148 {
01149 Matrix<T> temp;
01150 if(dimension == 1)
01151 {
01152 temp = m.Clone();
01153 for(int j=0; j<temp.Columns(); j++)
01154 {
01155 QuickSort(temp[j]);
01156 }
01157 }
01158 else if(dimension == 2)
01159 {
01160 temp = Matrix<T>(m.Rows(), m.Columns());
01161 for(int i=0; i<temp.Rows(); i++)
01162 {
01163 Vector<T> dummy(temp.Columns());
01164 for(int j=0; j<temp.Columns(); j++)
01165 {
01166 dummy.ElemNC(j) = m.ElemNC(i,j);
01167 }
01168 QuickSort(dummy);
01169 for(int j=0; j<temp.Columns(); j++)
01170 {
01171 temp.ElemNC(i,j) = dummy.ElemNC(j);
01172 }
01173 }
01174 }
01175 else
01176 {
01177 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01178 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
01179 }
01180 return temp;
01181 }
01182
01183 template <class T>
01184 Matrix<T> Sort(Matrix<T>& m)
01185 {
01186 return Sort(m,1);
01187 }
01188
01189
01190
01191
01192
01193 template <class T>
01194 Vector<T>& SortI(Vector<T>& m)
01195 {
01196 return QuickSort(m);
01197 }
01198
01199 template <class T>
01200 Matrix<T>& SortI(Matrix<T>& m, int dimension)
01201 {
01202 if(dimension == 1)
01203 {
01204 for(int j=0; j<m.Columns(); j++)
01205 {
01206 QuickSort(m[j]);
01207 }
01208 }
01209 else if(dimension == 2)
01210 {
01211 Vector<T> dummy(m.Columns());
01212 for(int i=0; i<m.Rows(); i++)
01213 {
01214 for(int j=0; j<m.Columns(); j++)
01215 {
01216 dummy.ElemNC(j) = m.ElemNC(i,j);
01217 }
01218 QuickSort(dummy);
01219 for(int j=0; j<m.Columns(); j++)
01220 {
01221 m.ElemNC(i,j) = dummy.ElemNC(j);
01222 }
01223 }
01224 }
01225 else
01226 {
01227 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01228 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
01229 }
01230 return m;
01231 }
01232
01233 template <class T>
01234 Matrix<T>& SortI(Matrix<T>& m)
01235 {
01236 return Sort(m,1);
01237 }
01238
01239
01240
01241
01242
01243
01244 template <class T>
01245 void MeshGrid(Vector<T>& x, Vector<T>& y, Matrix<T>& X, Matrix<T>& Y)
01246 {
01247 X = Matrix<T>(y.Length(), x.Length());
01248 Y = Matrix<T>(y.Length(), x.Length());
01249 for(int i=0; i<y.Length(); i++)
01250 {
01251 for(int j=0; j<x.Length(); j++)
01252 {
01253 X.ElemNC(i,j) = x(j);
01254 Y.ElemNC(i,j) = y(i);
01255 }
01256 }
01257 }
01258
01259
01260
01261
01262
01263
01264
01265 template <class T>
01266 Vector<int> Sign(Vector<T>& m)
01267 {
01268 Vector<int> temp(m.Length());
01269 for(int i=0; i<m.Length(); i++)
01270 {
01271 if(m.ElemNC(i) > 0)
01272 {
01273 temp.ElemNC(i) = 1;
01274 }
01275 else if(m.ElemNC(i) < 0)
01276 {
01277 temp.ElemNC(i) = -1;
01278 }
01279 else
01280 {
01281 temp.ElemNC(i) = 0;
01282 }
01283 }
01284 return temp;
01285 }
01286
01287 template <class T>
01288 Matrix<int> Sign(Matrix<T>& m)
01289 {
01290 Matrix<int> temp(m.Rows(), m.Columns());
01291 for(int i=0; i<m.Length(); i++)
01292 {
01293 if(m.ElemNC(i) > 0)
01294 {
01295 temp.ElemNC(i) = 1;
01296 }
01297 else if(m.ElemNC(i) < 0)
01298 {
01299 temp.ElemNC(i) = -1;
01300 }
01301 else
01302 {
01303 temp.ElemNC(i) = 0;
01304 }
01305 }
01306 return temp;
01307 }
01308
01309
01310 template <class T>
01311 Vector<double> Gradient(Vector<T>& m)
01312 {
01313 Vector<double> temp(m.Length());
01314 for(int i=1; i<m.Length()-1; i++)
01315 {
01316 temp.ElemNC(i) = (m.ElemNC(i+1)-m.ElemNC(i-1))/2.0;
01317 }
01318 temp.ElemNC(0) = m.ElemNC(1)-m.ElemNC(0);
01319 temp.ElemNC(m.Length()-1) = m.ElemNC(m.Length()-1)-m.ElemNC(m.Length()-2);
01320 return temp;
01321 }
01322
01323
01324 template <class T>
01325 void Gradient(Matrix<T>& m, Matrix<double>& X, Matrix<double>& Y)
01326 {
01327 Matrix<double> X(m.Rows(), m.Columns());
01328 Matrix<double> Y(m.Rows(), m.Columns());
01329
01330 for(int j=1; j<m.Columns()-1; j++)
01331 {
01332 for(int i=0; i<m.Rows(); i++)
01333 {
01334 X.ElemNC(i,j) = (m.ElemNC(i,j+1)-m.ElemNC(i,j-1))/2.0;
01335 }
01336 }
01337 for(int i=0; i<m.Rows(); i++)
01338 {
01339 X.ElemNC(i,0) = m.ElemNC(i,1)-m.ElemNC(i,0);
01340 X.ElemNC(i,m.Columns()-1) = m.ElemNC(i,Columns()-1)-m.ElemNC(i,Columns()-2);
01341 }
01342
01343 for(int j=0; j<m.Columns(); j++)
01344 {
01345 for(int i=1; i<m.Rows()-1; i++)
01346 {
01347 Y.ElemNC(i,j) = (m.ElemNC(i+1,j)-m.ElemNC(i-1,j))/2.0;
01348 }
01349 }
01350 for(int j=0; j<m.Columns(); j++)
01351 {
01352 Y.ElemNC(0,j) = m.ElemNC(1,j)-m.ElemNC(0,j);
01353 Y.ElemNC(m.Rows()-1,j) = m.ElemNC(m.Rows()-1,j))-m.ElemNC(m.Rows()-2,j));
01354 }
01355 }
01356
01357
01358 template <class T>
01359 Vector<double> Del2(Vector<T>& m)
01360 {
01361 Vector<double> temp(m.Length());
01362 if(m.Length()>3)
01363 {
01364 for(int i=1; i<m.Length()-1; i++)
01365 {
01366 temp.ElemNC(i) = (m.ElemNC(i+1) - 2*m.ElemNC(i) + m.ElemNC(i-1))/4.0;
01367 }
01368 temp.ElemNC(0) = 2*temp.ElemNC(1)-temp.ElemNC(2);
01369 temp.ElemNC(m.Length()-1) = 2*temp.ElemNC(m.Length()-2)-temp.ElemNC(m.Length()-3);
01370 }
01371 else if(m.Length()==3)
01372 {
01373 temp.ElemNC(1) = (m.ElemNC(2) - 2*m.ElemNC(1) + m.ElemNC(0))/4.0;
01374 temp.ElemNC(0) = temp.ElemNC(1);
01375 temp.ElemNC(2) = temp.ElemNC(1);
01376 }
01377 else
01378 {
01379 temp.ElemNC(0) = 0;
01380 temp.ElemNC(m.Length()-1) = 0;
01381 }
01382 return temp;
01383 }
01384
01385
01386 template <class T>
01387 Matrix<double> Del2(Matrix<T>& m)
01388 {
01389 Matrix<double> temp(m.Rows(), m.Columns(),0.0);
01390
01391 Vector<double> temp2(m.Columns());
01392 for(int i=0; i<m.Rows(); i++)
01393 {
01394 if(m.Columns()>3)
01395 {
01396 for(int j=1; j<m.Columns()-1; j++)
01397 {
01398 temp2.ElemNC(j) = (m.ElemNC(i,j+1) - 2*m.ElemNC(i,j) + m.ElemNC(i,j-1))/4.0;
01399 }
01400 temp2.ElemNC(0) = 2*temp2.ElemNC(1)-temp2.ElemNC(2);
01401 temp2.ElemNC(m.Columns()-1) = 2*temp2.ElemNC(m.Columns()-2)-temp2.ElemNC(m.Columns()-3);
01402 for(int j=0; j<m.Columns(); j++)
01403 {
01404 temp.ElemNC(i,j) += temp2.ElemNC(j);
01405 }
01406 }
01407 else if(m.Columns()==3)
01408 {
01409 double dummy = (m.ElemNC(i,2) - 2*m.ElemNC(i,1) + m.ElemNC(i,0))/4.0;
01410 temp.ElemNC(i,0) += dummy;
01411 temp.ElemNC(i,1) += dummy;
01412 temp.ElemNC(i,2) += dummy;
01413 }
01414 }
01415
01416 Vector<double> temp3(m.Rows());
01417 for(int j=0; j<m.Columns(); j++)
01418 {
01419 if(m.Rows()>3)
01420 {
01421 for(int i=1; i<m.Rows()-1; i++)
01422 {
01423 temp3.ElemNC(i) = (m.ElemNC(i+1,j) - 2*m.ElemNC(i,j) + m.ElemNC(i-1,j))/4.0;
01424 }
01425 temp3.ElemNC(0) = 2*temp3.ElemNC(1)-temp3.ElemNC(2);
01426 temp3.ElemNC(m.Rows()-1) = 2*temp3.ElemNC(m.Rows()-2)-temp3.ElemNC(m.Rows()-3);
01427 for(int i=0; i<m.Rows(); i++)
01428 {
01429 temp.ElemNC(i,j) += temp3.ElemNC(i);
01430 }
01431 }
01432 else if(m.Rows()==3)
01433 {
01434 double dummy = (m.ElemNC(2,j) - 2*m.ElemNC(1,j) + m.ElemNC(0,j))/4.0;
01435 temp.ElemNC(0,j) += dummy;
01436 temp.ElemNC(1,j) += dummy;
01437 temp.ElemNC(2,j) += dummy;
01438 }
01439 }
01440
01441 return temp;
01442 }
01443
01444
01445
01446
01447 template <class T>
01448 Vector<T> CircShift(Vector<T>& m, int shift)
01449 {
01450 Vector<T> temp(m.Length());
01451 for(int i=0; i<m.Length(); i++)
01452 {
01453 int ind = (i-shift) % m.Length();
01454 ind = ind >=0 ? ind : ind+m.Length();
01455 temp.ElemNC(i) = m.ElemNC(ind);
01456 }
01457 return temp;
01458 }
01459
01460
01461 template <class T>
01462 Matrix<T> CircShift(Matrix<T>& m, int rshift, int cshift)
01463 {
01464 Matrix<T> temp(m.Rows(), m.Columns());
01465 for(int i=0; i<m.Rows(); i++)
01466 {
01467 int rind = (i-rshift) % m.Rows();
01468 rind = rind >=0 ? rind : rind+m.Rows();
01469 for(int j=0; j<m.Columns(); j++)
01470 {
01471 int cind = (j-cshift) % m.Columns();
01472 cind = cind >=0 ? cind : cind+m.Columns();
01473 temp.ElemNC(i,j) = m.ElemNC(rind,cind);
01474 }
01475 }
01476
01477 return temp;
01478 }
01479
01480
01481
01482 template <class T>
01483 Vector<T> FFTShift(Vector<T>& m)
01484 {
01485 return CircShift(m, m.Length()/2);
01486 }
01487
01488
01489 template <class T>
01490 Matrix<T> FFTShift(Matrix<T>& m)
01491 {
01492 return CircShift(m, -m.Rows()/2, -m.Columns()/2);
01493 }
01494
01495 template <class T>
01496 Vector<T> IFFTShift(Vector<T>& m)
01497 {
01498 return CircShift(m, m.Length()/2);
01499 }
01500
01501
01502 template <class T>
01503 Matrix<T> IFFTShift(Matrix<T>& m)
01504 {
01505 return CircShift(m, -m.Rows()/2, -m.Columns()/2);
01506 }
01507
01508
01509
01510 template <class T>
01511 Vector<int> Floor(Vector<T>& m)
01512 {
01513 Vector<int> temp(m.Length());
01514 for(int i=0; i<m.Length(); i++)
01515 {
01516 temp.ElemNC(i) = (int)floor(m.ElemNC(i));
01517 }
01518 return temp;
01519 }
01520
01521
01522 template <class T>
01523 Matrix<int> Floor(Matrix<T>& m)
01524 {
01525 Matrix<int> temp(m.Length());
01526 for(int i=0; i<m.Length(); i++)
01527 {
01528 temp.ElemNC(i) = (int)floor(m.ElemNC(i));
01529 }
01530 return temp;
01531 }
01532
01533
01534 template <class T>
01535 Vector<int> Ceil(Vector<T>& m)
01536 {
01537 Vector<int> temp(m.Length());
01538 for(int i=0; i<m.Length(); i++)
01539 {
01540 temp.ElemNC(i) = (int)ceil(m.ElemNC(i));
01541 }
01542 return temp;
01543 }
01544
01545
01546 template <class T>
01547 Matrix<int> Ceil(Matrix<T>& m)
01548 {
01549 Matrix<int> temp(m.Length());
01550 for(int i=0; i<m.Length(); i++)
01551 {
01552 temp.ElemNC(i) = (int)ceil(m.ElemNC(i));
01553 }
01554 return temp;
01555 }
01556
01557
01558 template <class T>
01559 Vector<int> Fix(Vector<T>& m)
01560 {
01561 Vector<int> temp(m.Length());
01562 for(int i=0; i<m.Length(); i++)
01563 {
01564 temp.ElemNC(i) = (m.ElemNC(i) >= 0) ? (int)floor(m.ElemNC(i)) : (int)ceil(m.ElemNC(i));
01565 }
01566 return temp;
01567 }
01568
01569
01570 template <class T>
01571 Matrix<int> Fix(Matrix<T>& m)
01572 {
01573 Matrix<int> temp(m.Length());
01574 for(int i=0; i<m.Length(); i++)
01575 {
01576 temp.ElemNC(i) = (m.ElemNC(i) >= 0) ? (int)floor(m.ElemNC(i)) : (int)ceil(m.ElemNC(i));
01577 }
01578 return temp;
01579 }
01580
01581
01582 template <class T>
01583 Vector<int> Round(Vector<T>& m)
01584 {
01585 Vector<int> temp(m.Length());
01586 for(int i=0; i<m.Length(); i++)
01587 {
01588 temp.ElemNC(i) = (int)floor(m.ElemNC(i)+0.5);
01589 }
01590 return temp;
01591 }
01592
01593
01594 template <class T>
01595 Matrix<int> Round(Matrix<T>& m)
01596 {
01597 Matrix<int> temp(m.Length());
01598 for(int i=0; i<m.Length(); i++)
01599 {
01600 temp.ElemNC(i) = (int)floor(m.ElemNC(i)+0.5);
01601 }
01602 return temp;
01603 }
01604
01605
01606
01607
01608
01609
01610 };
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668