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