Core.inl

Go to the documentation of this file.
00001 //Copyright (c) 2004-2005, Baris Sumengen
00002 //All rights reserved.
00003 //
00004 // CIMPL Matrix Performance Library
00005 //
00006 //Redistribution and use in source and binary
00007 //forms, with or without modification, are
00008 //permitted provided that the following
00009 //conditions are met:
00010 //
00011 //    * No commercial use is allowed. 
00012 //    This software can only be used
00013 //    for non-commercial purposes. This 
00014 //    distribution is mainly intended for
00015 //    academic research and teaching.
00016 //    * Redistributions of source code must
00017 //    retain the above copyright notice, this
00018 //    list of conditions and the following
00019 //    disclaimer.
00020 //    * Redistributions of binary form must
00021 //    mention the above copyright notice, this
00022 //    list of conditions and the following
00023 //    disclaimer in a clearly visible part 
00024 //    in associated product manual, 
00025 //    readme, and web site of the redistributed 
00026 //    software.
00027 //    * Redistributions in binary form must
00028 //    reproduce the above copyright notice,
00029 //    this list of conditions and the
00030 //    following disclaimer in the
00031 //    documentation and/or other materials
00032 //    provided with the distribution.
00033 //    * The name of Baris Sumengen may not be
00034 //    used to endorse or promote products
00035 //    derived from this software without
00036 //    specific prior written permission.
00037 //
00038 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
00039 //HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00040 //EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
00041 //NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00042 //MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00043 //PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00044 //CONTRIBUTORS BE LIABLE FOR ANY
00045 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00046 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00047 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00048 //OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00049 //DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00050 //HOWEVER CAUSED AND ON ANY THEORY OF
00051 //LIABILITY, WHETHER IN CONTRACT, STRICT
00052 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00053 //OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00054 //OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00055 //POSSIBILITY OF SUCH DAMAGE.
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                 //std::vector<int>::const_iterator constIterator;
00077                 //int j = 0;
00078                 //for(constIterator = ind.begin(); constIterator != ind.end(); constIterator++)
00079                 //{
00080                 //      temp[j] = *constIterator;
00081                 //      j++;
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         // Vectors need to be of length 3
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 

Generated on Thu Jan 20 08:43:41 2005 for CIMPL by  doxygen 1.3.9.1