Warning: this documentation for the development version is under construction.

/home/vivien/public_html/.src_seldon/vector/Functions_Arrays.cxx

00001 // Copyright (C) 2003-2009 Marc Duruflé
00002 // Copyright (C) 2001-2009 Vivien Mallet
00003 //
00004 // This file is part of the linear-algebra library Seldon,
00005 // http://seldon.sourceforge.net/.
00006 //
00007 // Seldon is free software; you can redistribute it and/or modify it under the
00008 // terms of the GNU Lesser General Public License as published by the Free
00009 // Software Foundation; either version 2.1 of the License, or (at your option)
00010 // any later version.
00011 //
00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00015 // more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public License
00018 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00019 
00020 
00021 #ifndef SELDON_FILE_FUNCTIONS_ARRAYS_CXX
00022 
00023 /*
00024   Functions defined in this file
00025 
00026   QuickSort(m, n, X);
00027   QuickSort(m, n, X, Y);
00028   QuickSort(m, n, X, Y, Z);
00029 
00030   MergeSort(m, n, X);
00031   MergeSort(m, n, X, Y);
00032   MergeSort(m, n, X, Y, Z);
00033 
00034   Sort(m, n, X);
00035   Sort(m, n, X, Y);
00036   Sort(m, n, X, Y, Z);
00037   Sort(m, X);
00038   Sort(m, X, Y);
00039   Sort(m, X, Y, Z);
00040   Sort(X);
00041   Sort(X, Y);
00042   Sort(X, Y, Z);
00043 
00044   Assemble(m, X);
00045   Assemble(m, X, Y);
00046 
00047   RemoveDuplicate(m, X);
00048   RemoveDuplicate(m, X, Y);
00049   RemoveDuplicate(X);
00050   RemoveDuplicate(X, Y);
00051 */
00052 
00053 namespace Seldon
00054 {
00055 
00056 
00058   //  SORT  //
00059 
00060 
00062   template<class T, class Storage, class Allocator>
00063   int PartitionQuickSort(int m, int n,
00064                          Vector<T, Storage, Allocator>& t)
00065   {
00066     T temp, v;
00067     v = t(m);
00068     int i = m - 1;
00069     int j = n + 1;
00070 
00071     while (true)
00072       {
00073         do
00074           {
00075             j--;
00076           }
00077         while (t(j) > v);
00078 
00079         do
00080           {
00081             i++;
00082           }
00083         while (t(i) < v);
00084 
00085         if (i < j)
00086           {
00087             temp = t(i);
00088             t(i) = t(j);
00089             t(j) = temp;
00090           }
00091         else
00092           {
00093             return j;
00094           }
00095       }
00096   }
00097 
00098 
00100 
00103   template<class T, class Storage, class Allocator>
00104   void QuickSort(int m, int n,
00105                  Vector<T, Storage, Allocator>& t)
00106   {
00107     if (m < n)
00108       {
00109         int p = PartitionQuickSort(m, n, t);
00110         QuickSort(m, p, t);
00111         QuickSort(p+1, n, t);
00112       }
00113   }
00114 
00115 
00117   template<class T1, class Storage1, class Allocator1,
00118            class T2, class Storage2, class Allocator2>
00119   int PartitionQuickSort(int m, int n,
00120                          Vector<T1, Storage1, Allocator1>& t1,
00121                          Vector<T2, Storage2, Allocator2>& t2)
00122   {
00123     T1 temp1, v;
00124     T2 temp2;
00125     v = t1(m);
00126     int i = m - 1;
00127     int j = n + 1;
00128 
00129     while (true)
00130       {
00131         do
00132           {
00133             j--;
00134           }
00135         while (t1(j) > v);
00136         do
00137           {
00138             i++;
00139           }
00140         while (t1(i) < v);
00141 
00142         if (i < j)
00143           {
00144             temp1 = t1(i);
00145             t1(i) = t1(j);
00146             t1(j) = temp1;
00147             temp2 = t2(i);
00148             t2(i) = t2(j);
00149             t2(j) = temp2;
00150           }
00151         else
00152           {
00153             return j;
00154           }
00155       }
00156   }
00157 
00158 
00160 
00163   template<class T1, class Storage1, class Allocator1,
00164            class T2, class Storage2, class Allocator2>
00165   void QuickSort(int m, int n,
00166                  Vector<T1, Storage1, Allocator1>& t1,
00167                  Vector<T2, Storage2, Allocator2>& t2)
00168   {
00169     if (m < n)
00170       {
00171         int p = PartitionQuickSort(m, n, t1, t2);
00172         QuickSort(m, p, t1, t2);
00173         QuickSort(p+1, n, t1, t2);
00174       }
00175   }
00176 
00177 
00179   template<class T1, class Storage1, class Allocator1,
00180            class T2, class Storage2, class Allocator2,
00181            class T3, class Storage3, class Allocator3>
00182   int PartitionQuickSort(int m, int n,
00183                          Vector<T1, Storage1, Allocator1>& t1,
00184                          Vector<T2, Storage2, Allocator2>& t2,
00185                          Vector<T3, Storage3, Allocator3>& t3)
00186   {
00187     T1 temp1, v;
00188     T2 temp2;
00189     T3 temp3;
00190     v = t1(m);
00191     int i = m - 1;
00192     int j = n + 1;
00193 
00194     while (true)
00195       {
00196         do
00197           {
00198             j--;
00199           }
00200         while (t1(j) > v);
00201 
00202         do
00203           {
00204             i++;
00205           }
00206         while (t1(i) < v);
00207 
00208         if (i < j)
00209           {
00210             temp1 = t1(i);
00211             t1(i) = t1(j);
00212             t1(j) = temp1;
00213             temp2 = t2(i);
00214             t2(i) = t2(j);
00215             t2(j) = temp2;
00216             temp3 = t3(i);
00217             t3(i) = t3(j);
00218             t3(j) = temp3;
00219           }
00220         else
00221           {
00222             return j;
00223           }
00224       }
00225   }
00226 
00227 
00229 
00232   template<class T1, class Storage1, class Allocator1,
00233            class T2, class Storage2, class Allocator2,
00234            class T3, class Storage3, class Allocator3>
00235   void QuickSort(int m, int n,
00236                  Vector<T1, Storage1, Allocator1>& t1,
00237                  Vector<T2, Storage2, Allocator2>& t2,
00238                  Vector<T3, Storage3, Allocator3>& t3)
00239   {
00240     if (m < n)
00241       {
00242         int p = PartitionQuickSort(m, n, t1, t2, t3);
00243         QuickSort(m, p, t1, t2, t3);
00244         QuickSort(p+1, n, t1, t2, t3);
00245       }
00246   }
00247 
00248 
00250 
00253   template<class T, class Storage, class Allocator>
00254   void MergeSort(int m, int n, Vector<T, Storage, Allocator>& tab1)
00255   {
00256     if (m >= n)
00257       return;
00258 
00259     int inc = 1, ind = 0, current, i, j, sup;
00260     Vector<T, Storage, Allocator> tab1t(n - m + 1);
00261     // Performs a merge sort with a recurrence.
00262     // inc = 1, 2, 4, 8, ...
00263     while (inc < (n - m + 1) )
00264       {
00265         // 'i' is the first index of the sub array of size 2*inc.
00266         // A loop is performed on these sub-arrays.
00267         // Each sub array is divided in two sub-arrays of size 'inc'.
00268         // These two sub-arrays are then merged.
00269         for (i = m; i <= n - inc; i += 2 * inc)
00270           {
00271             ind = i;
00272             current = i + inc; // Index of the second sub-array.
00273             sup = i + 2 * inc; // End of the merged array.
00274             if (sup >= n + 1)
00275               sup = n + 1;
00276 
00277             j = i;
00278             // Loop on values of the first sub-array.
00279             while (j < i + inc)
00280               {
00281                 // If the second sub-array has still unsorted elements.
00282                 if (current < sup)
00283                   {
00284                     // Insert the elements of the second sub-array in the
00285                     // merged array until tab1(j) < tab1(current).
00286                     while (current < sup && tab1(j) > tab1(current))
00287                       {
00288                         tab1t(ind-m) = tab1(current);
00289                         current++;
00290                         ind++;
00291                       }
00292 
00293                     // Inserts the element of the first sub-array now.
00294                     tab1t(ind - m) = tab1(j);
00295                     ind++;
00296                     j++;
00297 
00298                     // If the first sub-array is sorted, all remaining
00299                     // elements of the second sub-array are inserted.
00300                     if (j == i + inc)
00301                       {
00302                         for (j = current; j < sup; j++)
00303                           {
00304                             tab1t(ind - m) = tab1(j);
00305                             ind++;
00306                           }
00307                       }
00308                   }
00309                 else
00310                   {
00311                     // If the second sub-array is sorted, all remaining
00312                     // elements of the first sub-array are inserted.
00313                     for (current = j; current < i + inc; current++)
00314                       {
00315                         tab1t(ind - m) = tab1(current);
00316                         ind++;
00317                       }
00318                     j = current + 1;
00319                   }
00320               }
00321           }
00322 
00323         for (i = m; i < ind; i++)
00324           tab1(i) = tab1t(i - m);
00325 
00326         inc = 2 * inc;
00327       }
00328   }
00329 
00330 
00332 
00335   template<class T1, class Storage1, class Allocator1,
00336            class T2, class Storage2, class Allocator2>
00337   void MergeSort(int m, int n, Vector<T1, Storage1, Allocator1>& tab1,
00338                  Vector<T2, Storage2, Allocator2>& tab2)
00339   {
00340     if (m >= n)
00341       return;
00342 
00343     int inc = 1, ind = 0, current, i, j, sup;
00344     Vector<T1, Storage1, Allocator1> tab1t(n - m + 1);
00345     Vector<T2, Storage2, Allocator2> tab2t(n - m + 1);
00346 
00347     while (inc < n - m + 1)
00348       {
00349         for (i = m; i <= n - inc; i += 2 * inc)
00350           {
00351             ind = i;
00352             current = i + inc;
00353             sup = i + 2 * inc;
00354             if (sup >= n+1)
00355               sup = n+1;
00356 
00357             j = i;
00358             while (j < i + inc)
00359               {
00360                 if (current < sup)
00361                   {
00362                     while (current < sup && tab1(j) > tab1(current))
00363                       {
00364                         tab1t(ind - m) = tab1(current);
00365                         tab2t(ind - m) = tab2(current);
00366                         current++;
00367                         ind++;
00368                       }
00369                     tab1t(ind - m) = tab1(j);
00370                     tab2t(ind - m) = tab2(j);
00371                     ind++;
00372                     j++;
00373                     if (j == i + inc)
00374                       {
00375                         for (j = current; j < sup; j++)
00376                           {
00377                             tab1t(ind - m) = tab1(j);
00378                             tab2t(ind - m) = tab2(j);
00379                             ind++;
00380                           }
00381                       }
00382                   }
00383                 else
00384                   {
00385                     for (current = j; current < i + inc; current++)
00386                       {
00387                         tab1t(ind - m) = tab1(current);
00388                         tab2t(ind - m) = tab2(current);
00389                         ind++;
00390                       }
00391                     j = current + 1;
00392                   }
00393               }
00394           }
00395         for (i = m; i < ind; i++)
00396           {
00397             tab1(i) = tab1t(i - m);
00398             tab2(i) = tab2t(i - m);
00399           }
00400         inc = 2 * inc;
00401       }
00402   }
00403 
00404 
00406 
00409   template<class T1, class Storage1, class Allocator1,
00410            class T2, class Storage2, class Allocator2,
00411            class T3, class Storage3, class Allocator3>
00412   void MergeSort(int m, int n, Vector<T1, Storage1, Allocator1>& tab1,
00413                  Vector<T2, Storage2, Allocator2>& tab2,
00414                  Vector<T3, Storage3, Allocator3>& tab3)
00415   {
00416     if (m >= n)
00417       return;
00418 
00419     int inc = 1, ind = 0, current, i, j, sup;
00420     Vector<T1, Storage1, Allocator1> tab1t(n - m + 1);
00421     Vector<T2, Storage2, Allocator2> tab2t(n - m + 1);
00422     Vector<T3, Storage3, Allocator3> tab3t(n - m + 1);
00423 
00424     while (inc < n - m + 1)
00425       {
00426         for (i = m; i <= n - inc; i += 2 * inc)
00427           {
00428             ind = i;
00429             current = i + inc;
00430             sup = i + 2 * inc;
00431             if (sup >= n+1)
00432               sup = n+1;
00433 
00434             j = i;
00435             while (j < i + inc)
00436               {
00437                 if (current < sup)
00438                   {
00439                     while (current < sup && tab1(j) > tab1(current))
00440                       {
00441                         tab1t(ind - m) = tab1(current);
00442                         tab2t(ind - m) = tab2(current);
00443                         tab3t(ind - m) = tab3(current);
00444                         current++;
00445                         ind++;
00446                       }
00447                     tab1t(ind - m) = tab1(j);
00448                     tab2t(ind - m) = tab2(j);
00449                     tab3t(ind - m) = tab3(j);
00450                     ind++;
00451                     j++;
00452                     if (j == i + inc)
00453                       {
00454                         for (j = current; j < sup; j++)
00455                           {
00456                             tab1t(ind - m) = tab1(j);
00457                             tab2t(ind - m) = tab2(j);
00458                             tab3t(ind - m) = tab3(j);
00459                             ind++;
00460                           }
00461                       }
00462                   }
00463                 else
00464                   {
00465                     for (current = j; current < i + inc; current++)
00466                       {
00467                         tab1t(ind - m) = tab1(current);
00468                         tab2t(ind - m) = tab2(current);
00469                         tab3t(ind - m) = tab3(current);
00470                         ind++;
00471                       }
00472                     j = current+1;
00473                   }
00474               }
00475           }
00476         for (i = m; i < ind; i++)
00477           {
00478             tab1(i) = tab1t(i - m);
00479             tab2(i) = tab2t(i - m);
00480             tab3(i) = tab3t(i - m);
00481           }
00482         inc = 2 * inc;
00483       }
00484   }
00485 
00486 
00488 
00500   template<class Storage1, class Allocator1,
00501            class T2, class Storage2, class Allocator2 >
00502   void Assemble(int& n, Vector<int, Storage1, Allocator1>& Node,
00503                 Vector<T2, Storage2, Allocator2>& Vect)
00504   {
00505     if (n <= 1)
00506       return;
00507 
00508     Sort(n, Node, Vect);
00509     int prec = Node(0);
00510     int nb = 0;
00511     for (int i = 1; i < n; i++)
00512       if (Node(i) == prec)
00513         {
00514           Vect(nb) += Vect(i);
00515         }
00516       else
00517         {
00518           nb++;
00519           Node(nb) = Node(i);
00520           Vect(nb) = Vect(i);
00521           prec = Node(nb);
00522         }
00523     n = nb + 1;
00524   }
00525 
00526 
00528 
00534   template<class T, class Storage1, class Allocator1>
00535   void Assemble(int& n, Vector<T, Storage1, Allocator1>& Node)
00536   {
00537     if (n <= 1)
00538       return;
00539 
00540     Sort(n, Node);
00541     T prec = Node(0);
00542     int nb = 1;
00543     for (int i = 1; i < n; i++)
00544       if (Node(i) != prec)
00545         {
00546           Node(nb) = Node(i);
00547           prec = Node(nb);
00548           nb++;
00549         }
00550     n = nb;
00551   }
00552 
00553 
00555   template<class T, class Storage1, class Allocator1>
00556   void Assemble(Vector<T, Storage1, Allocator1>& Node)
00557   {
00558     int nb = Node.GetM();
00559     Assemble(nb, Node);
00560     Node.Resize(nb);
00561   }
00562 
00563 
00565 
00568   template<class T, class Storage1, class Allocator1,
00569            class T2, class Storage2, class Allocator2>
00570   void RemoveDuplicate(int& n, Vector<T, Storage1, Allocator1>& Node,
00571                        Vector<T2, Storage2, Allocator2>& Node2)
00572   {
00573     if (n <= 1)
00574       return;
00575 
00576     Sort(n, Node, Node2);
00577     T prec = Node(0);
00578     int nb = 1;
00579     for (int i = 1; i < n; i++)
00580       if (Node(i) != prec)
00581         {
00582           Node(nb) = Node(i);
00583           Node2(nb) = Node2(i);
00584           prec = Node(nb);
00585           nb++;
00586         }
00587     n = nb;
00588   }
00589 
00590 
00592   template<class T, class Storage1, class Allocator1>
00593   void RemoveDuplicate(int& n, Vector<T, Storage1, Allocator1>& Node)
00594   {
00595     Assemble(n, Node);
00596   }
00597 
00598 
00600 
00603   template<class T, class Storage1, class Allocator1,
00604            class T2, class Storage2, class Allocator2>
00605   void RemoveDuplicate(Vector<T, Storage1, Allocator1>& Node,
00606                        Vector<T2, Storage2, Allocator2>& Node2)
00607   {
00608     int n = Node.GetM();
00609     if (n <= 1)
00610       return;
00611 
00612     RemoveDuplicate(n, Node, Node2);
00613     Node.Resize(n);
00614     Node2.Resize(n);
00615   }
00616 
00617 
00619   template<class T, class Storage1, class Allocator1>
00620   void RemoveDuplicate(Vector<T, Storage1, Allocator1>& Node)
00621   {
00622     int n = Node.GetM();
00623     if (n <= 1)
00624       return;
00625 
00626     Assemble(n, Node);
00627     Node.Resize(n);
00628   }
00629 
00630 
00632   template<class T, class Storage, class Allocator>
00633   void Sort(int m, int n, Vector<T, Storage, Allocator>& V)
00634   {
00635     MergeSort(m, n, V);
00636   }
00637 
00638 
00640 
00643   template<class T1, class Storage1, class Allocator1,
00644            class T2, class Storage2, class Allocator2>
00645   void Sort(int m, int n, Vector<T1, Storage1, Allocator1>& V,
00646             Vector<T2, Storage2, Allocator2>& V2)
00647   {
00648     MergeSort(m, n, V, V2);
00649   }
00650 
00651 
00653 
00656   template<class T1, class Storage1, class Allocator1,
00657            class T2, class Storage2, class Allocator2,
00658            class T3, class Storage3, class Allocator3>
00659   void Sort(int m, int n, Vector<T1, Storage1, Allocator1>& V,
00660             Vector<T2, Storage2, Allocator2>& V2,
00661             Vector<T3, Storage3, Allocator3>& V3)
00662   {
00663     MergeSort(m, n, V, V2, V3);
00664   }
00665 
00666 
00668   template<class T, class Storage, class Allocator>
00669   void Sort(int n, Vector<T, Storage, Allocator>& V)
00670   {
00671     Sort(0, n - 1, V);
00672   }
00673 
00674 
00676 
00679   template<class T1, class Storage1, class Allocator1,
00680            class T2, class Storage2, class Allocator2>
00681   void Sort(int n, Vector<T1, Storage1, Allocator1>& V,
00682             Vector<T2, Storage2, Allocator2>& V2)
00683   {
00684     Sort(0, n - 1, V, V2);
00685   }
00686 
00687 
00689 
00692   template<class T1, class Storage1, class Allocator1,
00693            class T2, class Storage2, class Allocator2,
00694            class T3, class Storage3, class Allocator3>
00695   void Sort(int n, Vector<T1, Storage1, Allocator1>& V,
00696             Vector<T2, Storage2, Allocator2>& V2,
00697             Vector<T3, Storage3, Allocator3>& V3)
00698   {
00699     Sort(0, n - 1, V, V2, V3);
00700   }
00701 
00702 
00704   template<class T, class Storage, class Allocator>
00705   void Sort(Vector<T, Storage, Allocator>& V)
00706   {
00707     Sort(0, V.GetM() - 1, V);
00708   }
00709 
00710 
00712 
00715   template<class T1, class Storage1, class Allocator1,
00716            class T2, class Storage2, class Allocator2>
00717   void Sort(Vector<T1, Storage1, Allocator1>& V,
00718             Vector<T2, Storage2, Allocator2>& V2)
00719   {
00720     Sort(0, V.GetM() - 1, V, V2);
00721   }
00722 
00723 
00725 
00728   template<class T1, class Storage1, class Allocator1,
00729            class T2, class Storage2, class Allocator2,
00730            class T3, class Storage3, class Allocator3>
00731   void Sort(Vector<T1, Storage1, Allocator1>& V,
00732             Vector<T2, Storage2, Allocator2>& V2,
00733             Vector<T3, Storage3, Allocator3>& V3)
00734   {
00735     Sort(0, V.GetM() - 1, V, V2, V3);
00736   }
00737 
00738 
00739   //  SORT  //
00741 
00742 
00743 } // namespace Seldon
00744 
00745 #define SELDON_FILE_FUNCTIONS_ARRAYS_CXX
00746 #endif