openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
SF_sort.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // openCARP is an open cardiac electrophysiology simulator.
3 //
4 // Copyright (C) 2020 openCARP project
5 //
6 // This program is licensed under the openCARP Academic Public License (APL)
7 // v1.0: You can use and redistribute it and/or modify it in non-commercial
8 // academic environments under the terms of APL as published by the openCARP
9 // project v1.0, or (at your option) any later version. Commercial use requires
10 // a commercial license (info@opencarp.org).
11 //
12 // This program is distributed without any warranty; see the openCARP APL for
13 // more details.
14 //
15 // You should have received a copy of the openCARP APL along with this program
16 // and can find it online: http://www.opencarp.org/license
17 // ----------------------------------------------------------------------------
18 
27 #ifndef _SF_SORT_H
28 #define _SF_SORT_H
29 
30 #include "SF_vector.h"
31 #include "hashmap.hpp"
32 
33 
34 namespace SF {
35 
39 template<class T> inline
40 void _binary_sort(T *_P, T *_Q, T s)
41 {
42  T *P = _P, *Q = _Q;
43  T p=0, q=0;
44  while(P != Q)
45  {
46  if(((p = P[0]) & s) != 0) break;
47  P++;
48  }
49  while(P != Q)
50  {
51  if(((q = Q[-1]) & s) == 0) break;
52  Q--;
53  }
54  while(P != Q)
55  {
56  *P++ = q;
57  *--Q = p;
58  while(((p = P[0]) & s) == 0) P++;
59  while(((q = Q[-1]) & s) != 0) Q--;
60  }
61  s >>= 1;
62  if(s)
63  {
64  if(_Q - P > 1) _binary_sort(P, _Q, s);
65  if(Q - _P > 1) _binary_sort(_P, Q, s);
66  }
67 }
68 
72 template<class T, class S> inline
73 void _binary_sort_copy(T *_P, T *_Q, S *_U, S* _V, T s)
74 {
75  T *P = _P, *Q = _Q;
76  S *U = _U, *V = _V;
77  T p=0, q=0;
78  while(P != Q)
79  {
80  if(((p = P[0]) & s) != 0) break;
81  P++;
82  U++;
83  }
84  while(P != Q)
85  {
86  if(((q = Q[-1]) & s) == 0) break;
87  Q--;
88  V--;
89  }
90  while(P != Q)
91  {
92  *P++ = q;
93  *--Q = p;
94  S u, v;
95  u = *U;
96  v = *--V;
97  *U++ = v;
98  *V = u;
99  while(((p = P[0]) & s) == 0) P++, U++;
100  while(((q = Q[-1]) & s) != 0) Q--, V--;
101  }
102  s >>= 1;
103  if(s)
104  {
105  if(_Q - P > 1) _binary_sort_copy(P, _Q, U, _V, s);
106  if(Q - _P > 1) _binary_sort_copy(_P, Q, _U, V, s);
107  }
108 }
109 
113 template<class T, class S, class R> inline
114 void _binary_sort_copy_copy(T *_P, T *_Q, S *_A, S *_B, R *_U, R *_V, T s)
115 {
116  T *P = _P, *Q = _Q;
117  S *A = _A, *B = _B;
118  R *U = _U, *V = _V;
119  T p=0, q=0;
120  while(P != Q)
121  {
122  if(((p = P[0]) & s) != 0) break;
123  P++;
124  A++;
125  U++;
126  }
127  while(P != Q)
128  {
129  if(((q = Q[-1]) & s) == 0) break;
130  Q--;
131  B--;
132  V--;
133  }
134  while(P != Q)
135  {
136  *P++ = q;
137  *--Q = p;
138  S u, v;
139  u = *U;
140  v = *--V;
141  *U++ = v;
142  *V = u;
143  S a, b;
144  a = *A;
145  b = *--B;
146  *A++ = b;
147  *B = a;
148  while(((p = P[0]) & s) == 0) P++, A++, U++;
149  while(((q = Q[-1]) & s) != 0) Q--, B--, V--;
150  }
151  s >>= 1;
152  if(s)
153  {
154  if(_Q - P > 1) _binary_sort_copy_copy(P, _Q, A, _B, U, _V, s);
155  if(Q - _P > 1) _binary_sort_copy_copy(_P, Q, _A, B, _U, V, s);
156  }
157 }
158 
162 template<class T> inline
163 void _binary_sort_sort(T *_P, T *_Q, T *_A, T *_B, T s, T t)
164 {
165  T *P = _P, *Q = _Q, *A = _A, *B = _B;
166  T p=0, q=0;
167  while(P != Q)
168  {
169  if(((p = P[0]) & s) != 0) break;
170  P++;
171  A++;
172  }
173  while(P != Q)
174  {
175  if(((q = Q[-1]) & s) == 0) break;
176  Q--;
177  B--;
178  }
179  while(P != Q)
180  {
181  *P++ = q;
182  *--Q = p;
183  T a, b;
184  a = *A;
185  b = *--B;
186  *A++ = b;
187  *B = a;
188  while(((p = P[0]) & s) == 0) P++, A++;
189  while(((q = Q[-1]) & s) != 0) Q--, B--;
190  }
191  s >>= 1;
192  if(s)
193  {
194  if(_Q - P > 1) _binary_sort_sort(P, _Q, A, _B, s, t);
195  if(Q - _P > 1) _binary_sort_sort(_P, Q, _A, B, s, t);
196  }
197  else if(t)
198  {
199  if(_Q - P > 1) _binary_sort_sort(A, _B, P, _Q, t, s);
200  if(Q - _P > 1) _binary_sort_sort(_A, B, _P, Q, t, s);
201  }
202 }
203 
207 template<class T, class S> inline
208 void _binary_sort_sort_copy(T *_P, T *_Q, T *_A, T *_B, S *_U, S* _V, T s, T t)
209 {
210  T *P = _P, *Q = _Q, *A = _A, *B = _B;
211  S *U = _U, *V = _V;
212  T p=0, q=0;
213  while(P != Q)
214  {
215  if(((p = P[0]) & s) != 0) break;
216  P++;
217  A++;
218  U++;
219  }
220  while(P != Q)
221  {
222  if(((q = Q[-1]) & s) == 0) break;
223  Q--;
224  B--;
225  V--;
226  }
227  while(P != Q)
228  {
229  *P++ = q;
230  *--Q = p;
231  T a, b;
232  a = *A;
233  b = *--B;
234  *A++ = b;
235  *B = a;
236  S u, v;
237  u = *U;
238  v = *--V;
239  *U++ = v;
240  *V = u;
241  while(((p = P[0]) & s) == 0) P++, A++, U++;
242  while(((q = Q[-1]) & s) != 0) Q--, B--, V--;
243  }
244  s >>= 1;
245  if(s)
246  {
247  if(_Q - P > 1) _binary_sort_sort_copy(P, _Q, A, _B, U, _V, s, t);
248  if(Q - _P > 1) _binary_sort_sort_copy(_P, Q, _A, B, _U, V, s, t);
249  }
250  else if(t)
251  {
252  if(_Q - P > 1) _binary_sort_sort_copy(A, _B, P, _Q, U, _V, t, s);
253  if(Q - _P > 1) _binary_sort_sort_copy(_A, B, _P, Q, _U, V, t, s);
254  }
255 }
256 
257 
261 template<class T> inline
262 T _binary_log(const T *P, const T *Q)
263 {
264  T s = 0;
265  while(P != Q)
266  {
267  s |= *P++;
268  }
269  T t = ~0;
270  while(s & t)
271  {
272  s &= t;
273  t <<= 1;
274  }
275  return s;
276 }
277 
278 
283 template<class T> inline
285 {
286  if(_V.size() < 2) return;
287  _binary_sort(&_V[0], &_V[0]+_V.size(), _binary_log(&_V[0], &_V[0]+_V.size()));
288 }
289 
295 template<class T, class S> inline
297 {
298  if(_V.size() < 2) return;
299  _binary_sort_copy(&_V[0], &_V[0]+_V.size(), &_W[0], &_W[0]+_W.size(), _binary_log(&_V[0], &_V[0]+_V.size()));
300 }
301 
308 template<class T, class S, class R> inline
310 {
311  if(_V.size() < 2) return;
312  _binary_sort_copy_copy(&_V[0], &_V[0]+_V.size(), &_W[0], &_W[0]+_W.size(), &_A[0], &_A[0]+_A.size(), _binary_log(&_V[0], &_V[0]+_V.size()));
313 }
314 
320 template<class T> inline
322 {
323  if(_V.size() < 2) return;
324  _binary_sort_sort(&_V[0], &_V[0]+_V.size(), &_W[0], &_W[0]+_W.size(),
325  _binary_log(&_V[0], &_V[0]+_V.size()), _binary_log(&_W[0], &_W[0]+_W.size()));
326 }
327 
334 template<class T, class S> inline
336 {
337  if(_V.size() < 2) return;
338  _binary_sort_sort_copy(&_V[0], &_V[0]+_V.size(), &_W[0], &_W[0]+_W.size(), &_A[0], &_A[0]+_A.size(),
339  _binary_log(&_V[0], &_V[0]+_V.size()), _binary_log(&_W[0], &_W[0]+_W.size()));
340 }
341 
342 
347 template<class T> inline
349 {
350  if(_P.size() < 2) return;
351  T *P = &_P[0], *Q = &_P[0] + _P.size();
352 
353  if(P != Q)
354  {
355  T* R = P;
356  ++P;
357  while(P != Q)
358  {
359  if ((*R != *P))
360  {
361  *++R = *P;
362  }
363  ++P;
364  }
365  ++R;
366  _P.resize(int(R - &_P[0]));
367  }
368 }
369 
375 template<class T> inline
377 {
378  if(_P.size() < 2) return;
379  T *P = &_P[0], *Q = &_P[0] + _P.size();
380  T *U = &_U[0];
381 
382  if(P != Q)
383  {
384  T* R = P;
385  T* W = U;
386  ++P; ++U;
387  while(P != Q)
388  {
389  if ((*R != *P) || (*W != *U))
390  {
391  *++R = *P;
392  *++W = *U;
393  }
394  ++P; ++U;
395  }
396  ++R;
397  ++W;
398  _P.resize(int(R - &_P[0]));
399  _U.resize(int(W - &_U[0]));
400  }
401 }
402 
408 template<class T, class S> inline
410 {
411  if(_P.size() < 2) return;
412  T *P = &_P[0], *Q = &_P[0] + _P.size();
413  S *A = &_A[0];
414 
415  if(P != Q)
416  {
417  T* R = P;
418  S* C = A;
419  ++P; ++A;
420  while(P != Q)
421  {
422  if (*R == *P)
423  {
424  *C += *A;
425  }
426  else
427  {
428  *++R = *P;
429  *++C = *A;
430  }
431  ++P; ++A;
432  }
433  ++R;
434  ++C;
435  _P.resize(int(R - &_P[0]));
436  _A.resize(int(C - &_A[0]));
437  }
438 }
439 
446 template<class T, class S> inline
448 {
449  if(_P.size() < 2) return;
450  T *P = &_P[0], *Q = &_P[0] + _P.size();
451  T *U = &_U[0];
452  S *A = &_A[0];
453 
454  if(P != Q)
455  {
456  T* R = P;
457  T* W = U;
458  S* C = A;
459  ++P; ++U; ++A;
460  while(P != Q)
461  {
462  if ((*R == *P) && (*W == *U))
463  {
464  *C += *A;
465  }
466  else
467  {
468  *++R = *P;
469  *++W = *U;
470  *++C = *A;
471  }
472  ++P; ++U; ++A;
473  }
474  ++R;
475  ++W;
476  ++C;
477  _P.resize(int(R - &_P[0]));
478  _U.resize(int(W - &_U[0]));
479  _A.resize(int(C - &_A[0]));
480  }
481 }
482 
493 template<class T> inline
494 void global_to_local_sorted(const vector<T> & glob, vector<T> & data, bool sortedData, bool doWarn)
495 {
496  size_t dsize = data.size(), gsize = glob.size();
497  vector<T> perm;
498 
499  // sort data if necessary
500  if(!sortedData) {
501  perm.resize(dsize);
502  interval(perm, 0, dsize);
503  binary_sort_copy(data, perm);
504  }
505 
506  size_t cidx, ridx, widx=0;
507  for (ridx=0, cidx=0; ridx<dsize; ridx++)
508  {
509  while (glob[cidx] < data[ridx] && cidx < (gsize-1)) cidx++;
510  if(data[ridx] == glob[cidx]) {
511  data[widx] = cidx;
512  widx++;
513  }
514  }
515 
516  // check if all values could be mapped. if its not the case, then permuting back makes no sense
517  if(widx < ridx) {
518  data.resize(widx);
519  if(doWarn)
520  fprintf(stderr, "global_to_local warning: Not all indices could be mapped!\n");
521  }
522  else {
523  if(!sortedData)
524  binary_sort_copy(perm, data);
525  }
526 }
527 
528 
539 template<class T> inline
540 void global_to_local(const vector<T> & glob, vector<T> & data, bool sortedData, bool doWarn)
541 {
542  size_t dsize = data.size(), gsize = glob.size();
543  vector<T> _glob(glob), perm_glob(glob.size()), perm_data;
544 
545  interval(perm_glob, 0, gsize);
546  binary_sort_copy(_glob, perm_glob);
547 
548  // sort data if necessary
549  if(!sortedData) {
550  perm_data.resize(dsize);
551  interval(perm_data, 0, dsize);
552  binary_sort_copy(data, perm_data);
553  }
554 
555  size_t cidx, ridx, widx=0;
556  for (ridx=0, cidx=0; ridx<dsize; ridx++)
557  {
558  while (_glob[cidx] < data[ridx] && cidx < (gsize-1)) cidx++;
559  if(data[ridx] == _glob[cidx]) {
560  data[widx] = perm_glob[cidx];
561  widx++;
562  }
563  }
564 
565  // check if all values could be mapped. if its not the case, then permuting back makes no sense
566  if(widx < ridx) {
567  data.resize(widx);
568  if(doWarn)
569  fprintf(stderr, "global_to_local warning: Not all indices could be mapped!\n");
570  }
571  else {
572  if(!sortedData)
573  binary_sort_copy(perm_data, data);
574  }
575 }
576 
586 template<class T> inline
587 void global_to_local(const hashmap::unordered_map<T,T> & g2l, vector<T> & data, bool doWarn)
588 {
589  size_t widx = 0;
590  for(size_t i=0; i<data.size(); i++) {
591  auto it = g2l.find(data[i]);
592  if(it != g2l.end()) {
593  data[widx++] = it->second;
594  }
595  }
596 
597  // check if all values could be mapped. if its not the case, then permuting back makes no sense
598  if(widx < data.size()) {
599  data.resize(widx);
600  if(doWarn)
601  fprintf(stderr, "%s warning: Not all indices could be mapped!\n", __func__);
602  }
603 }
604 
605 }
606 #endif
607 
Definition: dense_mat.hpp:34
The vector class and related algorithms.
void _binary_sort_copy_copy(T *_P, T *_Q, S *_A, S *_B, R *_U, R *_V, T s)
Definition: SF_sort.h:114
void interval(vector< T > &vec, size_t start, size_t end)
Create an integer interval between start and end.
Definition: SF_vector.h:350
void global_to_local_sorted(const vector< T > &glob, vector< T > &data, bool sortedData, bool doWarn)
Definition: SF_sort.h:494
void unique_resize(vector< T > &_P)
Definition: SF_sort.h:348
void binary_sort_sort_copy(vector< T > &_V, vector< T > &_W, vector< S > &_A)
Definition: SF_sort.h:335
void _binary_sort(T *_P, T *_Q, T s)
Definition: SF_sort.h:40
void _binary_sort_sort_copy(T *_P, T *_Q, T *_A, T *_B, S *_U, S *_V, T s, T t)
Definition: SF_sort.h:208
void _binary_sort_copy(T *_P, T *_Q, S *_U, S *_V, T s)
Definition: SF_sort.h:73
void binary_sort_copy_copy(vector< T > &_V, vector< S > &_W, vector< R > &_A)
Definition: SF_sort.h:309
void binary_sort_copy(vector< T > &_V, vector< S > &_W)
Definition: SF_sort.h:296
void _binary_sort_sort(T *_P, T *_Q, T *_A, T *_B, T s, T t)
Definition: SF_sort.h:163
void global_to_local(const vector< T > &glob, vector< T > &data, bool sortedData, bool doWarn)
Definition: SF_sort.h:540
T _binary_log(const T *P, const T *Q)
Definition: SF_sort.h:262
size_t size() const
The current size of the vector.
Definition: SF_vector.h:104
void unique_accumulate(vector< T > &_P, vector< S > &_A)
Definition: SF_sort.h:409
A vector storing arbitrary data.
Definition: SF_vector.h:42
iterator find(const K &key)
Search for key. Return iterator.
Definition: hashmap.hpp:593
void binary_sort(vector< T > &_V)
Definition: SF_sort.h:284
void resize(size_t n)
Resize a vector.
Definition: SF_vector.h:209
void binary_sort_sort(vector< T > &_V, vector< T > &_W)
Definition: SF_sort.h:321
Classes similar to unordered_set and unordered_map, but with better performance.