00001
00002
00003
00004
00005
00006
00007
00008
00051 #ifdef _MSC_VER
00052 #pragma once
00053 #endif
00054
00055 #ifndef NMM_H
00056 #define NMM_H
00057
00058 #include <complex>
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
00070 namespace ogdf {
00071
00072 class NMM
00073 {
00074
00075
00076 public:
00077 NMM();
00078 ~NMM();
00079
00080
00081 void calculate_repulsive_forces(const Graph &G,NodeArray<NodeAttributes>& A,
00082 NodeArray<DPoint>& F_rep);
00083
00084
00085 void make_initialisations (const Graph &G,NodeArray<NodeAttributes>& A,
00086 NodeArray<DPoint>& F_rep, 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(QuadTreeNodeNM* act_ptr,List<ParticleInfo>& L_x_copy,
00196 List<ParticleInfo>& L_y_copy,List<ParticleInfo>*&
00197 L_x_left_ptr,List <ParticleInfo>*& L_y_left_ptr,List
00198 <ParticleInfo>*& L_x_right_ptr,List <ParticleInfo>*&
00199 L_y_right_ptr);
00200
00201
00202
00203 void split_in_y_direction(QuadTreeNodeNM* act_ptr,List<ParticleInfo>& L_x_copy,
00204 List<ParticleInfo>&L_y_copy,List<ParticleInfo>*&
00205 L_x_bottom_ptr,List <ParticleInfo>*& L_y_bottom_ptr,List
00206 <ParticleInfo>*& L_x_top_ptr,List <ParticleInfo>*&
00207 L_y_top_ptr);
00208
00209
00210
00211
00212
00213
00214
00215 void x_delete_right_subLists(QuadTreeNodeNM* act_ptr,List<ParticleInfo>& L_x_copy,
00216 List<ParticleInfo>&L_y_copy,List<ParticleInfo>*&
00217 L_x_left_ptr,List <ParticleInfo>*& L_y_left_ptr,List
00218 <ParticleInfo>*& L_x_right_ptr,List <ParticleInfo>*&
00219 L_y_right_ptr,ListIterator<ParticleInfo>
00220 last_left_item);
00221
00222
00223 void x_delete_left_subLists(QuadTreeNodeNM* act_ptr,List<ParticleInfo>& L_x_copy,
00224 List<ParticleInfo>&L_y_copy,List<ParticleInfo>*&
00225 L_x_left_ptr,List <ParticleInfo>*& L_y_left_ptr,List
00226 <ParticleInfo>*& L_x_right_ptr,List <ParticleInfo>*&
00227 L_y_right_ptr,ListIterator<ParticleInfo>
00228 last_left_item);
00229
00230
00231
00232
00233 void y_delete_right_subLists(QuadTreeNodeNM* act_ptr,List<ParticleInfo>& L_x_copy,
00234 List<ParticleInfo>&L_y_copy,List<ParticleInfo>*&
00235 L_x_left_ptr,List <ParticleInfo>*& L_y_left_ptr,List
00236 <ParticleInfo>*& L_x_right_ptr,List <ParticleInfo>*&
00237 L_y_right_ptr,ListIterator<ParticleInfo>
00238 last_left_item);
00239
00240
00241 void y_delete_left_subLists(QuadTreeNodeNM* act_ptr,List<ParticleInfo>& L_x_copy,
00242 List<ParticleInfo>&L_y_copy,List<ParticleInfo>*&
00243 L_x_left_ptr,List <ParticleInfo>*& L_y_left_ptr,List
00244 <ParticleInfo>*& L_x_right_ptr,List <ParticleInfo>*&
00245 L_y_right_ptr,ListIterator<ParticleInfo>
00246 last_left_item);
00247
00248
00249
00250
00251 void split_in_y_direction(QuadTreeNodeNM* act_ptr,List<ParticleInfo>*& L_x_ptr,
00252 List <ParticleInfo>*& L_x_b_ptr,List<ParticleInfo>*&
00253 L_x_t_ptr,List<ParticleInfo>*& L_y_ptr,List
00254 <ParticleInfo>*& L_y_b_ptr,List<ParticleInfo>*&
00255 L_y_t_ptr);
00256
00257
00258
00259
00260
00261 void y_move_left_subLists(List<ParticleInfo>*& L_x_ptr,List<ParticleInfo>*&
00262 L_x_b_ptr,List<ParticleInfo>*& L_x_t_ptr,List
00263 <ParticleInfo>*& L_y_ptr,List <ParticleInfo>*&
00264 L_y_b_ptr,List<ParticleInfo>*&
00265 L_y_t_ptr,ListIterator<ParticleInfo> last_left_item);
00266
00267
00268 void y_move_right_subLists(List<ParticleInfo>*& L_x_ptr,List<ParticleInfo>*&
00269 L_x_b_ptr,List<ParticleInfo>*& L_x_t_ptr,List
00270 <ParticleInfo>*&L_y_ptr,List <ParticleInfo>*&
00271 L_y_b_ptr,List<ParticleInfo>*&
00272 L_y_t_ptr,ListIterator<ParticleInfo> last_left_item);
00273
00274
00275
00276 void build_up_sorted_subLists(List<ParticleInfo>& L_x_copy,List<ParticleInfo>&
00277 act_y_List_copy);
00278
00279
00280
00281
00282
00283 void build_up_red_quad_tree_subtree_by_subtree(const Graph& G, NodeArray
00284 <NodeAttributes>& A,QuadTreeNM& T);
00285
00286
00287
00288 void build_up_root_vertex(const Graph&G,QuadTreeNM& T);
00289
00290
00291
00292
00293
00294
00295 void construct_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM& T,QuadTreeNodeNM*
00296 subtree_root_ptr,List<QuadTreeNodeNM*>&
00297 new_subtree_root_List);
00298
00299
00300
00301
00302
00303
00304 void construct_complete_subtree(QuadTreeNM& T,int subtree_depth,
00305 Array2D<QuadTreeNodeNM*>& leaf_ptr,
00306 int act_depth,int
00307 act_x_index,int act_y_index);
00308
00309
00310
00311
00312
00313 void set_contained_nodes_for_leaves(NodeArray<NodeAttributes>& A,QuadTreeNM& T,
00314 QuadTreeNodeNM* subtree_root_ptr,Array2D
00315 <QuadTreeNodeNM*>& leaf_ptr,int maxindex);
00316
00317
00318
00319 void set_particlenumber_in_subtree_entries(QuadTreeNM& T);
00320
00321
00322
00323
00324
00325 void construct_reduced_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM& T,List
00326 <QuadTreeNodeNM*>& new_subtree_root_List);
00327
00328
00329
00330 void delete_empty_subtrees(QuadTreeNM& T);
00331
00332
00333
00334
00335
00336
00337 bool check_and_delete_degenerated_node(QuadTreeNM& T);
00338
00339
00340
00341
00342
00343 void delete_sparse_subtree(QuadTreeNM& T,QuadTreeNodeNM* new_leaf_ptr);
00344
00345
00346
00347
00348 void collect_contained_nodes(QuadTreeNM& T,QuadTreeNodeNM* new_leaf_ptr);
00349
00350
00351
00352
00353
00354
00355
00356 bool find_smallest_quad(NodeArray<NodeAttributes>& A,QuadTreeNM& T);
00357
00358
00359
00360
00361
00362 void find_small_cell_iteratively(QuadTreeNodeNM* act_ptr,double x_min,double x_max,
00363 double y_min,double y_max);
00364
00365
00366
00367 void find_small_cell_by_formula(QuadTreeNodeNM* act_ptr,double x_min,double x_max,
00368 double y_min,double y_max);
00369
00370
00371 void delete_red_quad_tree_and_count_treenodes(QuadTreeNM& T);
00372
00373
00374
00375 void form_multipole_expansions(NodeArray<NodeAttributes>& A,QuadTreeNM& T,List
00376 <QuadTreeNodeNM*>& quad_tree_leaves);
00377
00378
00379
00380 void form_multipole_expansion_of_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM&
00381 T, List<QuadTreeNodeNM*>&
00382 quad_tree_leaves);
00383
00384
00385 void init_expansion_Lists(QuadTreeNodeNM* act_ptr);
00386
00387
00388 void set_center(NodeArray<NodeAttributes>& A,QuadTreeNodeNM* act_ptr);
00389
00390
00391 void form_multipole_expansion_of_leaf_node(NodeArray<NodeAttributes>& A,
00392 QuadTreeNodeNM* act_ptr);
00393
00394
00395
00396 void add_shifted_expansion_to_father_expansion(QuadTreeNodeNM* act_ptr);
00397
00398
00399
00400
00401 void calculate_local_expansions_and_WSPRLS(NodeArray<NodeAttributes>&A,
00402 QuadTreeNodeNM* act_node_ptr);
00403
00404
00405
00406 bool well_seperated(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00407
00408
00409 bool bordering(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00410
00411
00412
00413 void add_shifted_local_exp_of_parent(QuadTreeNodeNM* node_ptr);
00414
00415
00416
00417 void add_local_expansion(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00418
00419
00420
00421
00422 void add_local_expansion_of_leaf(NodeArray<NodeAttributes>&A,QuadTreeNodeNM*
00423 leaf_ptr,QuadTreeNodeNM* act_ptr);
00424
00425
00426
00427 void transform_local_exp_to_forces(NodeArray <NodeAttributes>&A,
00428 List<QuadTreeNodeNM*>& quad_tree_leaves,
00429 NodeArray<DPoint>& F_local_exp);
00430
00431
00432
00433 void transform_multipole_exp_to_forces(NodeArray<NodeAttributes>& A,
00434 List<QuadTreeNodeNM*>& quad_tree_leaves,
00435 NodeArray<DPoint>& F_multipole_exp);
00436
00437
00438
00439 void calculate_neighbourcell_forces(const Graph& G, NodeArray<NodeAttributes>&
00440 A,List<QuadTreeNodeNM*>& quad_tree_leaves,
00441 NodeArray<DPoint>& F_direct);
00442
00443
00444 void add_rep_forces(const Graph& G,NodeArray<DPoint>& F_direct,NodeArray<DPoint>&
00445 F_multipole_exp,NodeArray<DPoint>& F_local_exp,
00446 NodeArray<DPoint>& F_rep);
00447
00448
00449 double f_rep_scalar (double d);
00450
00451
00452 void init_binko(int t);
00453
00454
00455 void free_binko();
00456
00457
00458 double binko(int n, int k);
00459
00460
00461
00462 int tree_construction_way() const {return _tree_construction_way;}
00463 void tree_construction_way(int a) { _tree_construction_way=
00464 (((0<=a)&&(a<=2)) ? a : 0);}
00465
00466
00467
00468
00469 int find_sm_cell() const {return _find_small_cell;}
00470 void find_sm_cell(int a) { _find_small_cell =
00471 (((0<=a)&&(a<=1)) ? a : 0);}
00472
00473
00474 void particles_in_leaves (int b) { _particles_in_leaves = ((b>= 1)? b : 1);}
00475 int particles_in_leaves () const { return _particles_in_leaves;}
00476
00477
00478 void precision (int p) { _precision = ((p >= 1 ) ? p : 1);}
00479 int precision () const {return _precision;}
00480
00481 };
00482 }
00483 #endif
00484
00485