00001
00002
00003
00004
00005
00006
00007
00008
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046
00047 #ifndef OGDF_NMM_H
00048 #define OGDF_NMM_H
00049
00050 #include <ogdf/basic/Graph.h>
00051 #include <ogdf/basic/List.h>
00052 #include <ogdf/basic/Array2D.h>
00053 #include <ogdf/basic/geometry.h>
00054 #include <ogdf/internal/energybased/NodeAttributes.h>
00055 #include <ogdf/internal/energybased/EdgeAttributes.h>
00056 #include <ogdf/internal/energybased/QuadTreeNM.h>
00057 #include <ogdf/internal/energybased/ParticleInfo.h>
00058 #include <ogdf/internal/energybased/FruchtermanReingold.h>
00059 #include <complex>
00060
00061 namespace ogdf {
00062
00063 class OGDF_EXPORT NMM
00064 {
00065
00066
00067 public:
00068 NMM();
00069 ~NMM();
00070
00071
00072 void calculate_repulsive_forces(const Graph &G,NodeArray<NodeAttributes>& A,
00073 NodeArray<DPoint>& F_rep);
00074
00075
00076 void make_initialisations (const Graph &G, double boxlength,
00077 DPoint down_left_corner,int particles_in_leaves,
00078 int precision,int tree_construction_way,
00079 int find_small_cell);
00080
00081
00082 void deallocate_memory();
00083
00084
00085 void update_boxlength_and_cornercoordinate(double b_l,DPoint d_l_c);
00086
00087 private:
00088
00089 int MIN_NODE_NUMBER;
00090
00091
00092 bool using_NMM;
00093
00094 FruchtermanReingold ExactMethod;
00095
00096 int _tree_construction_way;
00097 int _find_small_cell;
00098 int _particles_in_leaves;
00099 int _precision;
00100
00101 double boxlength;
00102 DPoint down_left_corner;
00103
00104 int* power_of_2;
00105
00106 int max_power_of_2_index;
00107 double ** BK;
00108 List<DPoint> rep_forces;
00109
00110
00111
00112
00113
00114
00115 void init_power_of_2_array(void);
00116
00117
00118 void free_power_of_2_array();
00119
00120
00121
00122 int power_of_two(int i);
00123
00124
00125 int maxboxindex (int level);
00126
00127
00128 void calculate_repulsive_forces_by_NMM(const Graph &G, NodeArray
00129 <NodeAttributes>& A ,NodeArray<DPoint>& F_rep);
00130
00131
00132
00133 void calculate_repulsive_forces_by_exact_method(const Graph &G, NodeArray
00134 <NodeAttributes>& A ,NodeArray<DPoint>& F_rep);
00135
00136
00137
00138
00139
00140 void build_up_red_quad_tree_path_by_path(const Graph& G, NodeArray
00141 <NodeAttributes>& A,QuadTreeNM& T);
00142
00143
00144
00145
00146
00147 void make_copy_and_init_Lists(List<ParticleInfo>& L_x_orig,List<ParticleInfo>&
00148 L_x_copy,List<ParticleInfo>& L_y_orig,List
00149 <ParticleInfo>& L_y_copy);
00150
00151
00152 void build_up_root_node(const Graph& G,NodeArray<NodeAttributes>& A,QuadTreeNM& T);
00153
00154
00155 void create_sorted_coordinate_Lists(const Graph& G,NodeArray<NodeAttributes>& A,
00156 List<ParticleInfo>& L_x,List<ParticleInfo>& L_y);
00157
00158
00159
00160
00161 void decompose_subtreenode(QuadTreeNM& T,List<ParticleInfo>& act_x_List_copy,
00162 List<ParticleInfo>& act_y_List_copy,List<QuadTreeNodeNM*>&
00163 new_leaf_List);
00164
00165
00166 void calculate_boundaries_of_act_node(QuadTreeNodeNM* act_ptr,double& x_min,
00167 double& x_max,double& y_min,double& y_max);
00168
00169
00170
00171 bool in_lt_quad(QuadTreeNodeNM* act_ptr,double x_min,double x_max, double y_min,
00172 double y_max);
00173 bool in_rt_quad(QuadTreeNodeNM* act_ptr,double x_min,double x_max, double y_min,
00174 double y_max);
00175 bool in_lb_quad(QuadTreeNodeNM* act_ptr,double x_min,double x_max, double y_min,
00176 double y_max);
00177 bool in_rb_quad(QuadTreeNodeNM* act_ptr,double x_min,double x_max, double y_min,
00178 double y_max);
00179
00180
00181
00182
00183
00184
00185 void split_in_x_direction(
00186 QuadTreeNodeNM* act_ptr,
00187 List<ParticleInfo>*& L_x_left_ptr,
00188 List<ParticleInfo>*& L_y_left_ptr,
00189 List<ParticleInfo>*& L_x_right_ptr,
00190 List <ParticleInfo>*& L_y_right_ptr);
00191
00192
00193
00194 void split_in_y_direction(
00195 QuadTreeNodeNM* act_ptr,
00196 List<ParticleInfo>*& L_x_bottom_ptr,
00197 List<ParticleInfo>*& L_y_bottom_ptr,
00198 List<ParticleInfo>*& L_x_top_ptr,
00199 List<ParticleInfo>*& L_y_top_ptr);
00200
00201
00202
00203
00204
00205
00206
00207 void x_delete_right_subLists(
00208 QuadTreeNodeNM* act_ptr,
00209 List<ParticleInfo>*& L_x_left_ptr,
00210 List <ParticleInfo>*& L_y_left_ptr,
00211 List<ParticleInfo>*& L_x_right_ptr,
00212 List <ParticleInfo>*& L_y_right_ptr,
00213 ListIterator<ParticleInfo> last_left_item);
00214
00215
00216 void x_delete_left_subLists(
00217 QuadTreeNodeNM* act_ptr,
00218 List<ParticleInfo>*& L_x_left_ptr,
00219 List <ParticleInfo>*& L_y_left_ptr,
00220 List<ParticleInfo>*& L_x_right_ptr,
00221 List <ParticleInfo>*& L_y_right_ptr,
00222 ListIterator<ParticleInfo> last_left_item);
00223
00224
00225
00226
00227 void y_delete_right_subLists(
00228 QuadTreeNodeNM* act_ptr,
00229 List<ParticleInfo>*& L_x_left_ptr,
00230 List<ParticleInfo>*& L_y_left_ptr,
00231 List<ParticleInfo>*& L_x_right_ptr,
00232 List <ParticleInfo>*& L_y_right_ptr,
00233 ListIterator<ParticleInfo> last_left_item);
00234
00235
00236 void y_delete_left_subLists(
00237 QuadTreeNodeNM* act_ptr,
00238 List<ParticleInfo>*& L_x_left_ptr,
00239 List<ParticleInfo>*& L_y_left_ptr,
00240 List<ParticleInfo>*& L_x_right_ptr,
00241 List <ParticleInfo>*& L_y_right_ptr,
00242 ListIterator<ParticleInfo> last_left_item);
00243
00244
00245
00246
00247 void split_in_y_direction(
00248 QuadTreeNodeNM* act_ptr,
00249 List<ParticleInfo>*& L_x_ptr,
00250 List<ParticleInfo>*& L_x_b_ptr,
00251 List<ParticleInfo>*& L_x_t_ptr,
00252 List<ParticleInfo>*& L_y_ptr,
00253 List<ParticleInfo>*& L_y_b_ptr,
00254 List<ParticleInfo>*& L_y_t_ptr);
00255
00256
00257
00258
00259
00260 void y_move_left_subLists(List<ParticleInfo>*& L_x_ptr,List<ParticleInfo>*&
00261 L_x_b_ptr,List<ParticleInfo>*& L_x_t_ptr,List
00262 <ParticleInfo>*& L_y_ptr,List <ParticleInfo>*&
00263 L_y_b_ptr,List<ParticleInfo>*&
00264 L_y_t_ptr,ListIterator<ParticleInfo> last_left_item);
00265
00266
00267 void y_move_right_subLists(List<ParticleInfo>*& L_x_ptr,List<ParticleInfo>*&
00268 L_x_b_ptr,List<ParticleInfo>*& L_x_t_ptr,List
00269 <ParticleInfo>*&L_y_ptr,List <ParticleInfo>*&
00270 L_y_b_ptr,List<ParticleInfo>*&
00271 L_y_t_ptr,ListIterator<ParticleInfo> last_left_item);
00272
00273
00274
00275 void build_up_sorted_subLists(List<ParticleInfo>& L_x_copy,List<ParticleInfo>&
00276 act_y_List_copy);
00277
00278
00279
00280
00281
00282 void build_up_red_quad_tree_subtree_by_subtree(const Graph& G, NodeArray
00283 <NodeAttributes>& A,QuadTreeNM& T);
00284
00285
00286
00287 void build_up_root_vertex(const Graph&G,QuadTreeNM& T);
00288
00289
00290
00291
00292
00293
00294 void construct_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM& T,QuadTreeNodeNM*
00295 subtree_root_ptr,List<QuadTreeNodeNM*>&
00296 new_subtree_root_List);
00297
00298
00299
00300
00301
00302
00303 void construct_complete_subtree(QuadTreeNM& T,int subtree_depth,
00304 Array2D<QuadTreeNodeNM*>& leaf_ptr,
00305 int act_depth,int
00306 act_x_index,int act_y_index);
00307
00308
00309
00310
00311
00312 void set_contained_nodes_for_leaves(NodeArray<NodeAttributes>& A,
00313 QuadTreeNodeNM* subtree_root_ptr,Array2D
00314 <QuadTreeNodeNM*>& leaf_ptr,int maxindex);
00315
00316
00317
00318 void set_particlenumber_in_subtree_entries(QuadTreeNM& T);
00319
00320
00321
00322
00323
00324 void construct_reduced_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM& T,List
00325 <QuadTreeNodeNM*>& new_subtree_root_List);
00326
00327
00328
00329 void delete_empty_subtrees(QuadTreeNM& T);
00330
00331
00332
00333
00334
00335
00336 bool check_and_delete_degenerated_node(QuadTreeNM& T);
00337
00338
00339
00340
00341
00342 void delete_sparse_subtree(QuadTreeNM& T,QuadTreeNodeNM* new_leaf_ptr);
00343
00344
00345
00346
00347 void collect_contained_nodes(QuadTreeNM& T,QuadTreeNodeNM* new_leaf_ptr);
00348
00349
00350
00351
00352
00353
00354
00355 bool find_smallest_quad(NodeArray<NodeAttributes>& A,QuadTreeNM& T);
00356
00357
00358
00359
00360
00361 void find_small_cell_iteratively(QuadTreeNodeNM* act_ptr,double x_min,double x_max,
00362 double y_min,double y_max);
00363
00364
00365
00366 void find_small_cell_by_formula(QuadTreeNodeNM* act_ptr,double x_min,double x_max,
00367 double y_min,double y_max);
00368
00369
00370 void delete_red_quad_tree_and_count_treenodes(QuadTreeNM& T);
00371
00372
00373
00374 void form_multipole_expansions(NodeArray<NodeAttributes>& A,QuadTreeNM& T,List
00375 <QuadTreeNodeNM*>& quad_tree_leaves);
00376
00377
00378
00379 void form_multipole_expansion_of_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM&
00380 T, List<QuadTreeNodeNM*>&
00381 quad_tree_leaves);
00382
00383
00384 void init_expansion_Lists(QuadTreeNodeNM* act_ptr);
00385
00386
00387 void set_center(QuadTreeNodeNM* act_ptr);
00388
00389
00390 void form_multipole_expansion_of_leaf_node(NodeArray<NodeAttributes>& A,
00391 QuadTreeNodeNM* act_ptr);
00392
00393
00394
00395 void add_shifted_expansion_to_father_expansion(QuadTreeNodeNM* act_ptr);
00396
00397
00398
00399
00400 void calculate_local_expansions_and_WSPRLS(NodeArray<NodeAttributes>&A,
00401 QuadTreeNodeNM* act_node_ptr);
00402
00403
00404
00405 bool well_separated(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00406
00407
00408 bool bordering(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00409
00410
00411
00412 void add_shifted_local_exp_of_parent(QuadTreeNodeNM* node_ptr);
00413
00414
00415
00416 void add_local_expansion(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00417
00418
00419
00420
00421 void add_local_expansion_of_leaf(NodeArray<NodeAttributes>&A,QuadTreeNodeNM*
00422 leaf_ptr,QuadTreeNodeNM* act_ptr);
00423
00424
00425
00426 void transform_local_exp_to_forces(NodeArray <NodeAttributes>&A,
00427 List<QuadTreeNodeNM*>& quad_tree_leaves,
00428 NodeArray<DPoint>& F_local_exp);
00429
00430
00431
00432 void transform_multipole_exp_to_forces(NodeArray<NodeAttributes>& A,
00433 List<QuadTreeNodeNM*>& quad_tree_leaves,
00434 NodeArray<DPoint>& F_multipole_exp);
00435
00436
00437
00438 void calculate_neighbourcell_forces(NodeArray<NodeAttributes>&
00439 A,List<QuadTreeNodeNM*>& quad_tree_leaves,
00440 NodeArray<DPoint>& F_direct);
00441
00442
00443 void add_rep_forces(const Graph& G,NodeArray<DPoint>& F_direct,NodeArray<DPoint>&
00444 F_multipole_exp,NodeArray<DPoint>& F_local_exp,
00445 NodeArray<DPoint>& F_rep);
00446
00447
00448 double f_rep_scalar (double d);
00449
00450
00451 void init_binko(int t);
00452
00453
00454 void free_binko();
00455
00456
00457 double binko(int n, int k);
00458
00459
00460
00461 int tree_construction_way() const {return _tree_construction_way;}
00462 void tree_construction_way(int a) { _tree_construction_way=
00463 (((0<=a)&&(a<=2)) ? a : 0);}
00464
00465
00466
00467
00468 int find_sm_cell() const {return _find_small_cell;}
00469 void find_sm_cell(int a) { _find_small_cell =
00470 (((0<=a)&&(a<=1)) ? a : 0);}
00471
00472
00473 void particles_in_leaves (int b) { _particles_in_leaves = ((b>= 1)? b : 1);}
00474 int particles_in_leaves () const { return _particles_in_leaves;}
00475
00476
00477 void precision (int p) { _precision = ((p >= 1 ) ? p : 1);}
00478 int precision () const {return _precision;}
00479
00480 };
00481 }
00482 #endif
00483
00484