|
Open Graph Drawing Framework |
v. 2023.09 (Elderberry)
|
|
|
Go to the documentation of this file.
47 namespace fast_multipole_embedder {
71 #define OGDF_FME_KERNEL_USE_OLD
73 #define OGDF_FME_KERNEL_COMPUTE_FORCE_PROTECTION_FACTOR 0.25f
75 #define OGDF_FME_KERNEL_MM_COMPUTE_FORCE(dx, dy, s) \
77 _mm_max_ps(_mm_mul_ps((s), _mm_set1_ps(OGDF_FME_KERNEL_COMPUTE_FORCE_PROTECTION_FACTOR)), \
78 _mm_add_ps(_mm_mul_ps((dx), (dx)), _mm_mul_ps((dy), (dy)))))
79 #define OGDF_FME_KERNEL_COMPUTE_FORCE(dx, dy, s) \
80 (s / (max<float>(s * OGDF_FME_KERNEL_COMPUTE_FORCE_PROTECTION_FACTOR, (dx) * (dx) + (dy) * (dy))))
83 const float* fx,
const float* fy,
const float t) {
85 for (uint32_t i =
begin; i <=
end; i++) {
86 double dsq = fx[i] * fx[i] + fy[i] * fy[i];
99 for (uint32_t i =
begin; i <=
end; i++) {
100 const auto& e_info = graph.
edgeInfo(i);
101 const uint32_t a = e_info.
a;
102 const uint32_t b = e_info.b;
103 const auto& a_info = graph.
nodeInfo(a);
104 const auto& b_info = graph.
nodeInfo(b);
106 float dx = x[a] - x[b];
107 float dy = y[a] - y[b];
108 float dsq = dx * dx + dy * dy;
109 float f = dsq == 0 ? 0 : (logf(dsq) * 0.5f - logf(e[i])) * 0.25f;
110 float fa = (float)(f / ((
float)a_info.degree));
111 float fb = (float)(f / ((
float)b_info.degree));
120 inline void eval_direct(
float* x,
float* y,
float* s,
float* fx,
float* fy,
size_t n) {
121 for (uint32_t i = 0; i < n; i++) {
122 for (uint32_t j = i + 1; j < n; j++) {
123 float dx = x[i] - x[j];
124 float dy = y[i] - y[j];
125 #ifdef OGDF_FME_KERNEL_USE_OLD
126 float s_sum = s[i] + s[j];
128 float s_sum = s[i] * s[j];
140 inline void eval_direct(
float* x1,
float* y1,
float* s1,
float* fx1,
float* fy1,
size_t n1,
141 float* x2,
float* y2,
float* s2,
float* fx2,
float* fy2,
size_t n2) {
142 for (uint32_t i = 0; i < n1; i++) {
143 for (uint32_t j = 0; j < n2; j++) {
144 float dx = x1[i] - x2[j];
145 float dy = y1[i] - y2[j];
146 #ifdef OGDF_FME_KERNEL_USE_OLD
147 float s_sum = s1[i] + s2[j];
149 float s_sum = s1[i] * s2[j];
161 #ifndef OGDF_FME_KERNEL_USE_SSE_DIRECT
162 inline void eval_direct_fast(
float* x,
float* y,
float* s,
float* fx,
float* fy,
size_t n) {
168 inline void eval_direct_fast(
float* x1,
float* y1,
float* s1,
float* fx1,
float* fy1,
size_t n1,
169 float* x2,
float* y2,
float* s2,
float* fx2,
float* fy2,
size_t n2) {
170 eval_direct(x1, y1, s1, fx1, fy1, n1, x2, y2, s2, fx2, fy2, n2);
174 void eval_direct_fast(
float* x,
float* y,
float* s,
float* fx,
float* fy,
size_t n);
177 void eval_direct_fast(
float* x1,
float* y1,
float* s1,
float* fx1,
float* fy1,
size_t n1,
float* x2,
178 float* y2,
float* s2,
float* fx2,
float* fy2,
size_t n2);
182 void fast_multipole_l2p(
double* localCoeffiecients, uint32_t numCoeffiecients,
double centerX,
183 double centerY,
float x,
float y,
float q,
float& fx,
float& fy);
185 void fast_multipole_p2m(
double* mulitCoeffiecients, uint32_t numCoeffiecients,
double centerX,
186 double centerY,
float x,
float y,
float q);
207 return moveNodes(graph, fx, fy, timeStep);
212 return moveNodes(graph, fx, fy, timeStep);
216 uint32_t maxIt, uint32_t preProcIt,
double threshold) {
217 bool earlyExit =
false;
221 for (uint32_t i = 0; i < preProcIt; i++) {
222 for (uint32_t j = 0; j < graph.
numNodes(); j++) {
228 for (uint32_t i = 0; i < maxIt && !earlyExit; i++) {
229 for (uint32_t j = 0; j < graph.
numNodes(); j++) {
234 if (dsq < threshold && i > (minIt)) {
The namespace for all OGDF objects.
void eval_edges(const ArrayGraph &graph, const uint32_t begin, const uint32_t end, float *fx, float *fy)
#define OGDF_FREE_16(ptr)
16-byte aligned memory deallocation macro
void fast_multipole_l2p(double *localCoeffiecients, uint32_t numCoeffiecients, double centerX, double centerY, float x, float y, float q, float &fx, float &fy)
kernel function to evalute a local expansion at point x,y result is added to fx, fy
The fast multipole embedder work thread class.
void simpleForceDirected(ArrayGraph &graph, float timeStep, uint32_t minIt, uint32_t maxIt, uint32_t preProcIt, double threshold)
bool isMainThread() const
returns true if this is the main thread ( the main thread is always the first thread )
HypergraphRegistry< HypernodeElement >::iterator begin(const HypergraphRegistry< HypernodeElement > &self)
uint32_t a
First node of the pair.
uint32_t numNodes() const
Returns the number of nodes.
float * nodeXPos()
Returns the x coord array for all nodes.
double simpleEdgeIteration(ArrayGraph &graph, float *fx, float *fy, float timeStep)
Declaration of class ArrayGraph.
#define OGDF_MALLOC_16(s)
16-byte aligned memory allocation macro
Definition of utility functions for FME layout.
NodeAdjInfo & nodeInfo(uint32_t i)
Returns the adjacency information for the node at index i in m_nodeAdj.
void repForces(ArrayGraph &graph, float *fx, float *fy)
double simpleIteration(ArrayGraph &graph, float *fx, float *fy, float timeStep)
uint32_t numThreads() const
returns the total number of threads in the pool
void eval_direct(float *x, float *y, float *s, float *fx, float *fy, size_t n)
kernel function to evaluate forces between n points with coords x, y directly. result is stored in fx...
float * desiredEdgeLength()
Returns the edge length array for all edges.
Datastructures for edge chains itself and the edge chains of nodes.
double move_nodes(float *x, float *y, const uint32_t begin, const uint32_t end, const float *fx, const float *fy, const float t)
float * nodeSize()
Returns the node size array for all nodes.
void sync()
thread sync call
float * nodeYPos()
Returns the y coord array for all nodes.
void updateMax(T &max, const T &newValue)
Stores the maximum of max and newValue in max.
bool isSingleThreaded() const
returns true if this run only uses one thread )
Basic declarations, included by all source files.
HypergraphRegistry< HypernodeElement >::iterator end(const HypergraphRegistry< HypernodeElement > &self)
uint32_t numEdges() const
Returns the number of edges.
uint32_t threadNr() const
returns the index of the thread ( 0.. numThreads()-1 )
uint32_t numThreads() const
returns the total number of threads in the pool
bool isMainThread() const
returns true if this is the main thread ( the main thread is always the first thread )
FMEKernel(FMEThread *pThread)
void operator()(ArrayGraph &graph, float timeStep, uint32_t minIt, uint32_t maxIt, double threshold)
double moveNodes(ArrayGraph &graph, float *fx, float *fy, float timeStep)
void edgeForces(const ArrayGraph &graph, float *fx, float *fy)
uint32_t threadNr() const
returns the index of the thread ( 0.. numThreads()-1 )
void fast_multipole_p2m(double *mulitCoeffiecients, uint32_t numCoeffiecients, double centerX, double centerY, float x, float y, float q)
EdgeAdjInfo & edgeInfo(uint32_t i)
Returns the adjacency information for the edge at index i in m_edgeAdj.
#define OGDF_FME_KERNEL_COMPUTE_FORCE(dx, dy, s)
Declaration of class FMEThread.
void eval_direct_fast(float *x, float *y, float *s, float *fx, float *fy, size_t n)
kernel function to evaluate forces between n points with coords x, y directly. result is stored in fx...