Open
Graph Drawing
Framework

 v.2010.10
 

NMM.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 2027 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2010-09-01 11:55:17 +0200 (Wed, 01 Sep 2010) $ 
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();          //constructor
00079       ~NMM();         //destructor
00080 
00081       //Calculate rep. forces for each node.
00082       void calculate_repulsive_forces(const Graph &G,NodeArray<NodeAttributes>& A,
00083                                       NodeArray<DPoint>& F_rep);
00084 
00085       //Make all initialisations that are needed for New Multipole Method (NMM)
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       //Dynamically allocated memory is freed here.
00092       void deallocate_memory();
00093 
00094       //Import updated information of the drawing area.
00095       void update_boxlength_and_cornercoordinate(double b_l,DPoint d_l_c);
00096         
00097    private:
00098 
00099        int MIN_NODE_NUMBER; //The minimum number of nodes for which the forces are
00100                             //calculated using NMM (for lower values the exact 
00101                             //calculation is used).
00102        bool using_NMM; //Indicates whether the exact method or NMM is used for force
00103                        //calculation (value depends on MIN_NODE_NUMBER)
00104        FruchtermanReingold ExactMethod; //needed in case that using_NMM == false
00105  
00106        int _tree_construction_way;//1 = pathwise;2 = subtreewise
00107        int _find_small_cell;//0 = iterative; 1= Aluru
00108        int _particles_in_leaves;//max. number of particles for leaves of the quadtree
00109        int _precision;  //precision for p-term multipole expansion
00110     
00111        double boxlength;//length of drawing box
00112        DPoint down_left_corner;//down left corner of drawing box
00113 
00114        int* power_of_2;//holds the powers of 2 (for speed reasons to calculate the
00115                        //maximal boxindex (index is from 0 to max_power_of_2_index)
00116        int max_power_of_2_index;//holds max. index for power_of_2 (= 30) 
00117        double ** BK; //holds the binominal coefficients
00118        List<DPoint> rep_forces;   //stores the rep. forces of the last iteration 
00119                                   //(needed for error calculation)
00120 
00121       //private helping functions
00122 
00123       //The array power_of_2 is calculated for values from 0 to max_power_of_2_index
00124       //which is set here to 30.
00125       void init_power_of_2_array(void);
00126 
00127       //The space of power_of_2 is freed.
00128       void free_power_of_2_array();     
00129 
00130       //Returns power_of_2[i] for values <= max_power_of_2_index else it returns 
00131       //pow(2,i).
00132       int power_of_two(int i);  
00133     
00134       //Returns the maximal index of a box in level i.
00135       int maxboxindex (int level);
00136 
00137       //Use NMM for force calculation (useded for large Graphs (|V| > MIN_NODE_NUMBER)).
00138       void  calculate_repulsive_forces_by_NMM(const Graph &G, NodeArray 
00139                   <NodeAttributes>& A ,NodeArray<DPoint>& F_rep);
00140                     
00141       //Use the exact method for force calculation (used for small Graphs (|V| <=
00142       //MIN_NODE_NUMBER) for speed reasons).
00143       void  calculate_repulsive_forces_by_exact_method(const Graph &G, NodeArray 
00144                   <NodeAttributes>& A ,NodeArray<DPoint>& F_rep);
00145 
00146       // *********Functions needed for path by path tree construction***********
00147    
00148       //The reduced quadtree is build up path by path (the Lists LE,ME, the
00149       //centers, D1, D2, M, and quad_tree_leaves are not calculated here.
00150       void  build_up_red_quad_tree_path_by_path(const Graph& G, NodeArray
00151                            <NodeAttributes>& A,QuadTreeNM& T);
00152 
00153       //Makes L_x(y)_copy a copy of L_x(y)_orig and sets p.copy_item for each element in 
00154       //L_x(y)_orig to the ListIterator of the corresponding element in L_x(y)_copy;
00155       //Furthermore, the p.cross_ref_items in L_x(y)_copy are set and p.subList_ptr and
00156       //p.tmp_cross_ref_item is reset to NULL in both lists.
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       //The root node of T is constructed.
00162       void build_up_root_node(const Graph& G,NodeArray<NodeAttributes>& A,QuadTreeNM& T);
00163 
00164       //The sorted and linked Lists L_x and L_y for the root node are created.
00165       void create_sorted_coordinate_Lists(const Graph& G,NodeArray<NodeAttributes>& A, 
00166                    List<ParticleInfo>& L_x,List<ParticleInfo>& L_y);
00167 
00168       //T is extended by a subtree T1 rooted at the T.get_act_node().  
00169       //The boxlength and down_left_corner of the actaul node is reduced if it is
00170       //not the minimal subquad that containes all the particles in the represented area.
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       //The extreme coordinates of the particles conatined in *act_ptr are calculated. 
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       //Returns true if the rectangle defined by x_min,...,y_max lies within the
00180       //left(right)_top(bottom) quad of the small cell of *act_ptr.
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     //The Lists *act_ptr->get_x(y)_List_ptr() are split into two sublists containing
00191     //the particles in the left and right half of the actual quad. The list that is 
00192     //larger is constructed from *act_ptr->get_x(y)_List_ptr() by deleting the other
00193     //elements; The smaller List stays empty at this point, but the corresponding
00194     //elements in L_x(y)_copy contain a pointer to the x(y) List, where they belong to.
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     //The Lists *act_ptr->get_x(y)_List_ptr() are split into two subLists containing
00203     //the particles in the top /bottom half ...
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     //The Lists *L_x(y)_left_ptr are constructed from *act_ptr->get_x(y)_List_ptr()
00213     //by deleting all elements right from last_left_item in *act_ptr->get_x_List_ptr()
00214     //the corresponding values in  *act_ptr->get_y_List_ptr() are deleted as well.
00215     //The corresponding List-elements of the deleted elements in the Lists L_x(y)_copy
00216     //hold the information, that they belong to the Lists *L_x(y)_left_ptr.
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     //Analogue as above.
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     //The Lists *L_x(y)_left_ptr are constructed from *act_ptr->get_x(y)_List_ptr()
00235     //by deleting all elements right from last_left_item in *act_ptr->get_y_List_ptr()
00236     //the ... 
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     //Analogue as above.
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     //The Lists *L_x(y)_b_ptr and *L_x(y)_t_ptr are constructed from the Lists 
00256     // *L_x(y)_ptr.
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       //The Lists *L_x(y)_b(t)_ptr are constructed from the Lists *L_x(y)_ptr by 
00267       //moving all List elements from *L_x(y)_ptr that belong to *L_x(y)_l_ptr 
00268       //to this List. the L_x(y)_right_ptr point  to the reduced Lists L_x(y)_ptr 
00269       //afterwards.      
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       //Same as above but the elements that belong to *&L_x(y)_right_ptr are moved.
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       //The sorted subLists, that can be accesssed by the entries in L_x(y)_copy->
00284       //get_subList_ptr() are constructed.
00285       void build_up_sorted_subLists(List<ParticleInfo>& L_x_copy,List<ParticleInfo>&
00286                     act_y_List_copy);   
00287      
00288       // ************functions needed for subtree by subtree tree construction **********
00289      
00290       //The reduced quadtree is build up subtree by subtree (the lists LE, ME the
00291       //centers, D1, D2, M, quad_tree_leaves are not calculated here.
00292       void  build_up_red_quad_tree_subtree_by_subtree(const Graph& G, NodeArray
00293                               <NodeAttributes>& A,QuadTreeNM& T);
00294      
00295       //The root node ot T is constructed and contained_nodes is set to the list of
00296       //all nodes of G.
00297       void build_up_root_vertex(const Graph&G,QuadTreeNM& T);
00298       
00299       //The reduced subtree of T rooted at *subtree_root_ptr containing all the particles
00300       //of subtree_root_ptr->get_contained_nodes() is constructed; Pointers to leaves 
00301       //of the subtree that contain more than particles_in_leaves() particles in their
00302       //contained_nodes() lists are added to new_subtree_root_List_ptr; The lists 
00303       //contained_nodes() are nonempty only for the (actual) leaves of T.
00304       void construct_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM& T,QuadTreeNodeNM* 
00305                  subtree_root_ptr,List<QuadTreeNodeNM*>& 
00306                  new_subtree_root_List);
00307       
00308       //A complete subtree of T and of depth subtree_depth, rooted at *T.get_act_ptr() is
00309       //constructed. Furthermore leaf_ptr[i][j] points to a leaf node of the suptree
00310       //that represents the quadratic subregion of *T.get_act_ptr() at subtree_depth
00311       //and position [i][j] i,j in 0,...,maxindex;act_depth(x_index,y_index) are
00312       //helping variables for recursive calls.
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       //The particles in subtree_root_ptr->get_contained_nodes() are assigned to 
00319       //the the contained_nodes lists of the leaves of the subtree by using the 
00320       //information of A,leaf_ptr and maxindex. Afterwards contained_nodes of 
00321       // *subtree_root_ptr is empty.
00322       void set_contained_nodes_for_leaves(NodeArray<NodeAttributes>& A,
00323                       QuadTreeNodeNM* subtree_root_ptr,Array2D
00324                       <QuadTreeNodeNM*>& leaf_ptr,int  maxindex);
00325       
00326       //The subtree of T rooted at *T.get_act_ptr() is traversed bottom up, such that
00327       //the subtreeparticlenumber of every node in this subtree is set correctly.
00328       void set_particlenumber_in_subtree_entries(QuadTreeNM& T);
00329       
00330       //The reduced subtree rooted at *T.get_act_ptr() is calculated ; A pointer to 
00331       //every leaf of this subtree that contains more then particles_in_leaves() 
00332       //particles is added to new_subtree_root_List; The lists contained_nodes are 
00333       //empty for all but the leaves.
00334       void construct_reduced_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM& T,List
00335                      <QuadTreeNodeNM*>& new_subtree_root_List);
00336       
00337       //All subtrees of *T.get_act_ptr() that have a child c of *T.get_act_ptr() as root
00338       //and c.get_particlenumber_in_subtree() == 0 are deleted.
00339       void delete_empty_subtrees(QuadTreeNM& T);
00340       
00341       //If *T.get_act_ptr() is a degenerated node (has only one child c) *T.get_act_ptr()
00342       //is deleted from T and the child c is linked with the father of *T.get_act_ptr()
00343       //if *T.get_act_ptr() is the root of T than c is set to the new root of T
00344       //T.get_act_ptr() points to c afterwards; Furthermore true is returned if
00345       // *T.get_act_ptr() has been degenerated, else false is returned.
00346       bool check_and_delete_degenerated_node(QuadTreeNM& T);
00347       
00348       //The subtree rooted at new_leaf_ptr is deleted, *new_leaf_ptr is a leaf 
00349       //of T and new_leaf_ptr->get_contained_nodes() containes all the particles
00350       //contained in the leaves of the deleted subtree; Precondition: T.get_act_ptr() is
00351       //new_leaf_ptr.
00352       void delete_sparse_subtree(QuadTreeNM& T,QuadTreeNodeNM* new_leaf_ptr);
00353       
00354       //new_leaf_ptr->get_contained_nodes() containes all the particles contained in 
00355       //the leaves of its subtree afterwards; Precondition: T.get_act_ptr() is
00356       //new_leaf_ptr
00357       void collect_contained_nodes(QuadTreeNM& T,QuadTreeNodeNM* new_leaf_ptr);
00358       
00359       //If all nodes in T.get_act_ptr()->get_contained_nodes() have the same position
00360       //false is returned. Else true is returned and
00361       //the boxlength, down_left_corner and level of *T.get_act_ptr() is updated
00362       //such that this values are minimal (i.e. the smallest quad that contains all
00363       //the particles of T.get_act_ptr()->get_contained_nodes(); If all this particles
00364       //are placed at a point nothing is done.
00365       bool find_smallest_quad(NodeArray<NodeAttributes>& A,QuadTreeNM& T);
00366       
00367       // *********functions needed for subtree by subtree tree construction(end) ********
00368       
00369       //Finds the small cell of the actual Node of T iteratively,and updates 
00370       //Sm_downleftcorner, Sm_boxlength, and level of *act_ptr. 
00371       void find_small_cell_iteratively(QuadTreeNodeNM* act_ptr,double x_min,double x_max,
00372                        double y_min,double y_max);
00373       
00374       //Finds the small cell of the actual Node of T by Alurus Formula, and updates 
00375       //Sm_downleftcorner, Sm_boxlength, and level of *act_ptr. 
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       //The reduced quad tree is deleted; Furthermore the treenode_number is calculated.
00380       void delete_red_quad_tree_and_count_treenodes(QuadTreeNM& T);
00381       
00382       //The multipole expansion terms ME are calculated for all nodes of T ( centers are
00383       //initialized for each cell and quad_tree_leaves stores pointers to leaves of T).
00384       void form_multipole_expansions(NodeArray<NodeAttributes>& A,QuadTreeNM& T,List
00385                      <QuadTreeNodeNM*>& quad_tree_leaves);
00386       
00387       //The multiplole expansion List ME for the tree rooted at T.get_act_ptr() is 
00388       //recursively calculated. 
00389       void form_multipole_expansion_of_subtree(NodeArray<NodeAttributes>& A,QuadTreeNM& 
00390                            T, List<QuadTreeNodeNM*>& 
00391                            quad_tree_leaves);
00392       
00393       //The Lists ME and LE are both initialized to zero entries for *act_ptr.
00394       void init_expansion_Lists(QuadTreeNodeNM* act_ptr);
00395       
00396       //The center of the box of *act_ptr is initialized.  
00397       void set_center(QuadTreeNodeNM* act_ptr);
00398       
00399       //Calculate List ME for *act_ptr Precondition: *act_ptr is a leaf.
00400       void form_multipole_expansion_of_leaf_node(NodeArray<NodeAttributes>& A,
00401                           QuadTreeNodeNM* act_ptr);
00402       
00403       //Add the shifted ME Lists of *act_ptr to act_ptr->get_father_ptr() ; precondition
00404       // *act_ptr has a father_node.
00405       void add_shifted_expansion_to_father_expansion(QuadTreeNodeNM* act_ptr);
00406       
00407       //According to NMM T is traversed recursively top-down starting from act_node_ptr 
00408       //== T.get_root_ptr() and thereby the lists D1, D2, M and LE are calculated for all
00409       //treenodes. 
00410       void calculate_local_expansions_and_WSPRLS(NodeArray<NodeAttributes>&A,
00411                          QuadTreeNodeNM* act_node_ptr);
00412       
00413       //If the small cell of ptr_1 and ptr_2 are well seperated true is returned (else 
00414       //false).
00415       bool well_seperated(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00416       
00417       //If ptr_1 and ptr_2 are nonequal and bordering true is returned; else false.
00418       bool bordering(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00419       
00420       //The shifted local expansion of the father of node_ptr is added to the local
00421       //expansion of node_ptr;precondition: node_ptr is not the root of T.
00422       void add_shifted_local_exp_of_parent(QuadTreeNodeNM* node_ptr);  
00423       
00424       //The multipole expansion of *ptr_1 is transformed into a local expansion around
00425       //the center of *ptr_2 and added to *ptr_2 s local expansion list.
00426       void add_local_expansion(QuadTreeNodeNM* ptr_1,QuadTreeNodeNM* ptr_2);
00427       
00428       //The multipole expansion for every particle of leaf_ptr->contained_nodes 
00429       //(1,0,...) is transformed into a local expansion around the center of *ptr_2 and 
00430       //added to *ptr_2 s local expansion List;precondition: *leaf_ptr is a leaf.
00431       void add_local_expansion_of_leaf(NodeArray<NodeAttributes>&A,QuadTreeNodeNM*
00432                     leaf_ptr,QuadTreeNodeNM* act_ptr);
00433       
00434       //For each leaf v in quad_tree_leaves the force contribution defined by 
00435       //v.get_local_exp() is calculated and stored in F_local_exp.
00436       void transform_local_exp_to_forces(NodeArray <NodeAttributes>&A, 
00437                      List<QuadTreeNodeNM*>& quad_tree_leaves,
00438                      NodeArray<DPoint>& F_local_exp);
00439       
00440       //For each leaf v in quad_tree_leaves the force contribution defined by all nodes
00441       //in v.get_M() is calculated and stored in F_multipole_exp.
00442       void transform_multipole_exp_to_forces(NodeArray<NodeAttributes>& A,
00443                          List<QuadTreeNodeNM*>& quad_tree_leaves, 
00444                          NodeArray<DPoint>& F_multipole_exp);
00445       
00446       //For each leaf v in quad_tree_leaves the force contributions from all leaves in
00447       //v.get_D1() and v.get_D2() are calculated.
00448       void calculate_neighbourcell_forces(NodeArray<NodeAttributes>& 
00449                       A,List<QuadTreeNodeNM*>& quad_tree_leaves,
00450                       NodeArray<DPoint>& F_direct);
00451       
00452       //Add repulsive force contributions for each node.
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       //Returns the repulsing force_function_value of scalar d. 
00458       double f_rep_scalar (double d);
00459       
00460       //Init BK -matrix for values n, k in 0 to t.
00461       void init_binko(int t);    
00462       
00463       //Free space for BK.
00464       void free_binko();
00465       
00466       //Returns n over k.
00467       double binko(int n, int k);
00468       
00469       //The way to construct the reduced tree (0) = level by level (1) path by path 
00470       //(2) subtree by subtree
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       //(0) means that the smallest quadratic cell that surrounds a node of the 
00476       //quadtree is calculated iteratively in constant time (1) means that it is 
00477       //calculated by the formula of Aluru et al. in constsnt time
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       //Max. number of particles that are contained in a leaf of the red. quadtree.
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       //The precision p for the p-term multipole expansions.
00487       void precision (int p) { _precision  = ((p >= 1 ) ? p : 1);}
00488       int  precision () const {return _precision;}
00489       
00490 };
00491 }//namespace ogdf
00492 #endif
00493 
00494