Warning: this documentation for the development version is under construction.
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