Correctly check if item was checked
[TortoiseGit.git] / ext / OGDF / src / energybased / FastUtils.h
blobff188b8e6b814ec50a0b44c2818f13cef7ac0e16
1 /*
2 * $Revision: 2559 $
4 * last checkin:
5 * $Author: gutwenger $
6 * $Date: 2012-07-06 15:04:28 +0200 (Fr, 06. Jul 2012) $
7 ***************************************************************/
9 /** \file
10 * \brief Definition of utility functions for FME layout.
12 * \author Martin Gronemann
14 * \par License:
15 * This file is part of the Open Graph Drawing Framework (OGDF).
17 * \par
18 * Copyright (C)<br>
19 * See README.txt in the root directory of the OGDF installation for details.
21 * \par
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
26 * for details.
28 * \par
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
34 * \par
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
43 #ifndef OGDF_FAST_UTILS_H
44 #define OGDF_FAST_UTILS_H
46 #include <ogdf/basic/GraphAttributes.h>
47 #include <iostream>
49 namespace ogdf {
51 // use SSE for Multipole computations
52 //#define OGDF_FME_KERNEL_USE_SSE
54 // use special thread affinity (works only for unix and scatters the threads)
55 //#define OGDF_FME_THREAD_AFFINITY
57 // simple parallel quadtree sort
58 //#define OGDF_FME_PARALLEL_QUADTREE_SORT
60 // use SSE for direct interaction (this is slower than the normal direct computation)
61 //#define OGDF_FME_KERNEL_USE_SSE_DIRECT
63 inline void OGDF_FME_Print_Config()
65 #ifdef OGDF_FME_KERNEL_USE_SSE
66 std::cout << "OGDF_FME_KERNEL_USE_SSE" << std::endl;
67 #endif
68 #ifdef OGDF_FME_THREAD_AFFINITY
69 std::cout << "OGDF_FME_THREAD_AFFINITY" << std::endl;
70 #endif
71 #ifdef OGDF_FME_PARALLEL_QUADTREE_SORT
72 std::cout << "OGDF_FME_PARALLEL_QUADTREE_SORT" << std::endl;
73 #endif
74 #ifdef OGDF_FME_KERNEL_USE_SSE_DIRECT
75 std::cout << "OGDF_FME_KERNEL_USE_SSE_DIRECT" << std::endl;
76 #endif
79 #ifdef OGDF_FME_KERNEL_USE_SSE
80 #include <emmintrin.h>
81 #include <pmmintrin.h>
82 #endif
84 typedef __uint64 MortonNR;
85 typedef __uint32 CoordInt;
87 template<typename T>
88 inline bool is_align_16(T* ptr)
90 return !(((size_t)(void*)ptr) & 0x0F);
93 template<typename T>
94 inline T* align_16_prev_ptr(T* t)
96 return (T*)(((size_t)((void*)t))&~ 0x0F);
99 template<typename T>
100 inline T* align_16_next_ptr(T* t)
102 return (T*)((((size_t)((void*)t)) + 15)&~ 0x0F);
105 #ifdef OGDF_SYSTEM_UNIX
106 #include <sys/time.h>
107 inline timeval GetDiffTime(timeval _then, double& dtime)
109 timeval then = (timeval) _then;
110 timeval now;
111 gettimeofday(&now, NULL);
112 timeval diff;
114 diff.tv_sec = now.tv_sec - then.tv_sec;
115 diff.tv_usec = now.tv_usec - then.tv_usec;
116 while(diff.tv_usec < 0)
118 diff.tv_sec--;
119 diff.tv_usec = 1000000 + now.tv_usec - then.tv_usec;
122 dtime = diff.tv_sec;
123 dtime += (double) diff.tv_usec / 1e6;
125 return (timeval) now;
127 #endif
129 inline void printProfiledTime(double t, const char* text) { std::cout << t <<"s\t" << text << std::endl; };
130 inline void printProfiledTime(double t, double sum, const char* text) { std::cout << t <<"s\t" << text << "\t" << (t / sum)*100.0 <<"%"<< std::endl; };
131 //! Profile Macro to measure time with OGDF
132 #ifdef OGDF_SYSTEM_WINDOWS
133 #define FME_PROFILE(STATEMENT, TEXT) if(true) { double t=0.0;t=usedTime(t);STATEMENT;t=usedTime(t);std::cout << t <<"s\t" << TEXT << std::endl;};
134 #else
135 #define FME_PROFILE(STATEMENT, TEXT) if(true) { double t=0.0;timeval start_time,end_time;gettimeofday(&start_time,0);STATEMENT;end_time=GetDiffTime(start_time,t);if (isMainThread()) std::cout << t <<"s\t" << TEXT << std::endl;};
136 #endif
138 //! 16-byte aligned memory allocation macro
139 #define MALLOC_16(s) System::alignedMemoryAlloc16((s))
141 //! 16-byte aligned memory deallocation macro
142 #define FREE_16(ptr) System::alignedMemoryFree((ptr))
144 //! square root of two
145 #define SQRT_OF_TWO 1.4142135623730950488016887242097
147 //! common template for bit-interleaving to compute the morton number assumes sizeOf(MNR_T) = 2*sizeOf(C_T)
148 template<typename MNR_T, typename C_T>
149 inline MNR_T mortonNumber(C_T ix, C_T iy)
151 MNR_T x = (MNR_T)ix;
152 MNR_T y = (MNR_T)iy;
153 // bit length of the result
154 const unsigned int BIT_LENGTH = sizeof(MNR_T) << 3;
155 // set all bits
156 MNR_T mask = 0x0;
157 mask = ~mask;
159 for (unsigned int i = (BIT_LENGTH >> 1);i>0; i = i >> 1)
161 // increase frequency
162 mask = mask ^ (mask << i);
163 x = (x | (x << i)) & mask;
164 y = (y | (y << i)) & mask;
166 return x | (y << 1);
170 //! common template for extracting the coordinates from a morton number assumes sizeOf(MNR_T) = 2*sizeOf(C_T)
171 template<typename MNR_T, typename C_T>
172 inline void mortonNumberInv(MNR_T mnr, C_T& x, C_T& y)
174 // bit length of the coordinates
175 unsigned int BIT_LENGTH = sizeof(C_T) << 3;
176 // set least significant bit
177 MNR_T mask = 0x1;
178 // set coords to zero
179 x = y = 0;
180 for (unsigned int i=0; i < BIT_LENGTH; i++)
182 x = (C_T)(x | (mnr & mask));
183 mnr = mnr >> 1;
184 y = (C_T)(y | (mnr & mask));
185 mask = mask << 1;
189 //! returns the index of the most signficant bit set. 0 = most signif, bitlength-1 = least signif
190 template<typename T>
191 inline __uint32 mostSignificantBit(T n)
193 __uint32 BIT_LENGTH = sizeof(T) << 3;
194 T mask = 0x1;
195 mask = mask << (BIT_LENGTH - 1);
196 for (__uint32 i = 0; i < BIT_LENGTH; i++)
198 if (mask & n)
199 return i;
200 mask = mask >> 1;
202 return BIT_LENGTH;
205 //! returns the prev power of two
206 inline __uint32 prevPowerOfTwo(__uint32 n)
208 __uint32 msb = 32 - mostSignificantBit(n);
209 return 0x1 << (msb - 1);
212 //! utility class to select multiple nodes randomly
213 class RandomNodeSet
215 public:
216 //! init the random node set with the given graph. takes O(n)
217 RandomNodeSet(const Graph& G) : m_graph(G) { allocate(); }
219 //! destructor
220 ~RandomNodeSet() { deallocate(); }
222 //! chooses a node from the available nodes in O(1)
223 node chooseNode() const
225 int i = m_numNodesChoosen + ogdf::randomNumber(0,nodesLeft()-1);//(int)((double)nodesLeft()*rand()/(RAND_MAX+1.0));
226 return m_array[i];
229 //! removes a node from available nodes (assumes v is available) in O(1)
230 void removeNode(node v)
232 int i = m_nodeIndex[v];
233 int j = m_numNodesChoosen;
234 node w = m_array[j];
235 swap(m_array[i], m_array[j]);
236 m_nodeIndex[w] = i;
237 m_nodeIndex[v] = j;
238 m_numNodesChoosen++;
241 bool isAvailable(node v) const { return (m_nodeIndex[v]>=m_numNodesChoosen); }
243 //! number of nodes available;
244 int nodesLeft() const { return m_numNodes - m_numNodesChoosen; }
246 private:
247 void allocate()
249 m_array = new node[m_graph.numberOfNodes()];
250 m_nodeIndex.init(m_graph);
251 m_numNodes = m_graph.numberOfNodes();
252 m_numNodesChoosen = 0;
253 node v;
254 int i = 0;
255 forall_nodes(v, m_graph)
257 m_array[i] = v;
258 m_nodeIndex[v] = i;
259 i++;
263 void deallocate()
265 delete[] m_array;
268 //! the graph
269 const Graph& m_graph;
271 //! the set of all nodes (at the end the available nodes)
272 node* m_array;
274 //! the index in the array of the nodes
275 NodeArray<int> m_nodeIndex;
277 //! total num nodes
278 int m_numNodes;
280 //! num available nodes
281 int m_numNodesChoosen;
284 inline void gridGraph(Graph& G, int n, int m)
286 G.clear();
287 node v;
288 node* topRow = new node[m];
289 topRow[0] = G.newNode();;
290 for (int j=1; j<m; j++)
292 topRow[j] = G.newNode();
293 G.newEdge(topRow[j-1], topRow[j]);
295 for (int i=1; i<n; i++)
297 v = G.newNode();
298 G.newEdge(topRow[0], v);
299 topRow[0] = v;
300 for (int j=1; j<m; j++)
302 v = G.newNode();
303 G.newEdge(topRow[j-1], v);
304 G.newEdge(topRow[j], v);
305 topRow[j] = v;
308 delete[] topRow;
311 inline void randomGridGraph(Graph& G, int n, int m, double missinNodesPercentage = 0.03)
313 gridGraph(G, n, m);
314 int numberOfNodesToDelete = (int)((double)G.numberOfNodes() * missinNodesPercentage);
316 RandomNodeSet rndSet(G);
317 for(int i=0; i<numberOfNodesToDelete;i++)
319 node v = rndSet.chooseNode();
320 rndSet.removeNode(v);
321 G.delNode(v);
325 //! binomial coeffs from Hachuls FMMM
326 template<class TYP>
327 class BinCoeff
329 public:
330 BinCoeff(unsigned int n) : m_max_n(n) { init_array(); }
332 ~BinCoeff() { free_array(); }
334 //! Init BK -matrix for values n, k in 0 to t.
335 void init_array()
337 typedef TYP* ptr;
338 unsigned int i,j;
339 m_binCoeffs = new ptr[m_max_n+1];
340 for(i = 0;i<= m_max_n ;i++)
342 m_binCoeffs[i]= new TYP[i+1];
345 //Pascalsches Dreieck
346 for (i = 0; i <= m_max_n;i++)
348 m_binCoeffs[i][0] = m_binCoeffs[i][i] = 1;
351 for (i = 2; i <= m_max_n; i ++)
353 for (j = 1; j < i; j++)
355 m_binCoeffs[i][j] = m_binCoeffs[i-1][j-1]+m_binCoeffs[i-1][j];
360 //! Free space for BK.
361 void free_array()
363 unsigned int i;
364 for(i = 0;i<= m_max_n;i++)
366 delete[] m_binCoeffs[i];
368 delete[] m_binCoeffs;
371 //Returns n over k.
372 inline TYP value(unsigned int n, unsigned int k) const
374 return m_binCoeffs[n][k];
377 private:
378 unsigned int m_max_n;
380 //! holds the binominal coefficients
381 TYP** m_binCoeffs;
385 // nothing
386 struct EmptyArgType {};
388 // Function Invoker for 8 args
390 template<typename FunctionType, typename ArgType1 = EmptyArgType, typename ArgType2 = EmptyArgType, typename ArgType3 = EmptyArgType, typename ArgType4 = EmptyArgType, typename ArgType5 = EmptyArgType, typename ArgType6 = EmptyArgType, typename ArgType7 = EmptyArgType, typename ArgType8 = EmptyArgType>
391 struct FuncInvoker
393 FuncInvoker(FunctionType f, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5, ArgType6 _arg6, ArgType7 _arg7, ArgType8 _arg8) :
394 function(f), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5), arg6(_arg6), arg7(_arg7), arg8(_arg8) { }
396 inline void operator()() { function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }
398 FunctionType function;
399 ArgType1 arg1;
400 ArgType2 arg2;
401 ArgType3 arg3;
402 ArgType4 arg4;
403 ArgType5 arg5;
404 ArgType6 arg6;
405 ArgType7 arg7;
406 ArgType8 arg8;
411 // Function Invoker for 7 args
413 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5, typename ArgType6, typename ArgType7>
414 struct FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, EmptyArgType>
416 FuncInvoker(FunctionType f, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5, ArgType6 _arg6, ArgType7 _arg7) :
417 function(f), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5), arg6(_arg6), arg7(_arg7) { }
419 inline void operator()() { function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); }
421 FunctionType function;
422 ArgType1 arg1;
423 ArgType2 arg2;
424 ArgType3 arg3;
425 ArgType4 arg4;
426 ArgType5 arg5;
427 ArgType6 arg6;
428 ArgType7 arg7;
432 // Function Invoker for 6 args
434 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5, typename ArgType6>
435 struct FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, EmptyArgType, EmptyArgType>
437 FuncInvoker(FunctionType f, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5, ArgType6 _arg6) :
438 function(f), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5), arg6(_arg6) { }
440 inline void operator()() { function(arg1, arg2, arg3, arg4, arg5, arg6); }
442 FunctionType function;
443 ArgType1 arg1;
444 ArgType2 arg2;
445 ArgType3 arg3;
446 ArgType4 arg4;
447 ArgType5 arg5;
448 ArgType6 arg6;
452 // Function Invoker for 5 args
454 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5>
455 struct FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, EmptyArgType, EmptyArgType, EmptyArgType>
457 FuncInvoker(FunctionType f, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5) :
458 function(f), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5) { }
460 inline void operator()() { function(arg1, arg2, arg3, arg4, arg5); }
462 FunctionType function;
463 ArgType1 arg1;
464 ArgType2 arg2;
465 ArgType3 arg3;
466 ArgType4 arg4;
467 ArgType5 arg5;
471 // Function Invoker for 4 args
473 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4>
474 struct FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType>
476 FuncInvoker(FunctionType f, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4) :
477 function(f), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4) { }
479 inline void operator()() { function(arg1, arg2, arg3, arg4); }
481 FunctionType function;
482 ArgType1 arg1;
483 ArgType2 arg2;
484 ArgType3 arg3;
485 ArgType4 arg4;
489 // Function Invoker for 3 args
491 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3>
492 struct FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType>
494 FuncInvoker(FunctionType f, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3) :
495 function(f), arg1(_arg1), arg2(_arg2), arg3(_arg3) { }
497 inline void operator()() { function(arg1, arg2, arg3); }
499 FunctionType function;
500 ArgType1 arg1;
501 ArgType2 arg2;
502 ArgType3 arg3;
506 // Function Invoker for 2 args
508 template<typename FunctionType, typename ArgType1, typename ArgType2>
509 struct FuncInvoker<FunctionType, ArgType1, ArgType2, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType>
511 FuncInvoker(FunctionType f, ArgType1 _arg1, ArgType2 _arg2) :
512 function(f), arg1(_arg1), arg2(_arg2) { }
514 inline void operator()() { function(arg1, arg2); }
516 FunctionType function;
517 ArgType1 arg1;
518 ArgType2 arg2;
522 // Function Invoker for 1 args
524 template<typename FunctionType, typename ArgType1>
525 struct FuncInvoker<FunctionType, ArgType1, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType>
527 FuncInvoker(FunctionType f, ArgType1 _arg1) :
528 function(f), arg1(_arg1) { }
530 inline void operator()() { function(arg1); }
532 FunctionType function;
533 ArgType1 arg1;
537 // Function Invoker for 0 args
539 template<typename FunctionType>
540 struct FuncInvoker<FunctionType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType, EmptyArgType>
542 FuncInvoker(FunctionType f) :
543 function(f) { }
545 inline void operator()() { function(); }
547 FunctionType function;
551 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5, typename ArgType6, typename ArgType7, typename ArgType8>
552 FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8>
553 createFuncInvoker(FunctionType func, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5, ArgType6 _arg6, ArgType7 _arg7, ArgType8 _arg8)
555 return FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8>(func, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8);
558 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5, typename ArgType6, typename ArgType7, typename ArgType8>
559 FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, ArgType8>
560 createFuncInvoker(FunctionType func, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5, ArgType6 _arg6, ArgType7 _arg7)
562 return FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6, ArgType7, EmptyArgType>(func, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7);
565 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5, typename ArgType6>
566 FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6>
567 createFuncInvoker(FunctionType func, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5, ArgType6 _arg6)
569 return FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5, ArgType6>(func, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6);
572 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4, typename ArgType5>
573 FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5>
574 createFuncInvoker(FunctionType func, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4, ArgType5 _arg5)
576 return FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4, ArgType5>(func, _arg1, _arg2, _arg3, _arg4, _arg5);
579 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3, typename ArgType4>
580 FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4>
581 createFuncInvoker(FunctionType func, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3, ArgType4 _arg4)
583 return FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3, ArgType4>(func, _arg1, _arg2, _arg3, _arg4);
586 template<typename FunctionType, typename ArgType1, typename ArgType2, typename ArgType3>
587 FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3>
588 createFuncInvoker(FunctionType func, ArgType1 _arg1, ArgType2 _arg2, ArgType3 _arg3)
590 return FuncInvoker<FunctionType, ArgType1, ArgType2, ArgType3>(func, _arg1, _arg2, _arg3);
593 template<typename FunctionType, typename ArgType1, typename ArgType2>
594 FuncInvoker<FunctionType, ArgType1, ArgType2>
595 createFuncInvoker(FunctionType func, ArgType1 _arg1, ArgType2 _arg2)
597 return FuncInvoker<FunctionType, ArgType1, ArgType2>(func, _arg1, _arg2);
600 template<typename FunctionType, typename ArgType1>
601 FuncInvoker<FunctionType, ArgType1>
602 createFuncInvoker(FunctionType func, ArgType1 _arg1)
604 return FuncInvoker<FunctionType, ArgType1>(func, _arg1);
607 template<typename FunctionType>
608 FuncInvoker<FunctionType>
609 createFuncInvoker(FunctionType func)
611 return FuncInvoker<FunctionType>(func);
616 #endif // fast utils h