Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

node.h

Go to the documentation of this file.
00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00011 
00013 
00014 //  version 1:  Dec 1992   Piet Hut, Steve McMillan, Jun Makino
00015 //  version 2:
00016 //
00017 //  This file includes:
00018 //  1) definition of class node
00019 
00020 
00021 #ifndef  STARLAB_NODE_H
00022 #  define  STARLAB_NODE_H
00023 
00024 #include  "starlab_vector.h"
00025 #include  "story.h"
00026 #include  "hydrobase.h"
00027 #include  "starbase.h"
00028 
00029 #define __VALID_NODE__          123456789
00030 #define __INVALID_NODE__        -1
00031 
00033 
00039 
00040 class node
00041     {
00042     protected:             // not private, since other classes, such as dyn
00043                            // and hdyn should have access to these data.
00044 
00045         // Global variable!
00046 
00047         static node* root;        
00048 
00049 
00050         long int node_flag;       
00051                                   // Experimental attempt to check for
00052                                   // and avoid deleted nodes (Steve, 8/98)
00053                                   //  - set only in node constructor
00054                                   //  - reset only in node destructor
00055 
00056         int  index;               
00057         char * name;              
00058 
00059         real  mass;               
00060 
00061         node * parent;            // oya       | As you can see, Japanese is
00062         node * oldest_daughter;   // choujo    | a more natural language for
00063         node * elder_sister;      // oneesan   | building a tree structure;
00064         node * younger_sister;    // imouto    | the names are so much simpler!
00065 
00067                           
00068         hydrobase * hbase;        // This is the only hydro class provided 
00069                                   // here, in order to allow separate
00070                                   // recompilation of the inherited classes
00071                                   // based on hydro without necessitating
00072                                   // compilation of the dynamics part.
00073 
00075                           
00076         starbase * sbase;         // This is the only star class provided 
00077                                   // here, in order to allow separate
00078                                   // recompilation of the inherited classes
00079                                   // based on star without necessitating
00080                                   // compilation of the dynamics part.
00081 
00082         // The log story is a generalized scratchpad for notes and log entries.
00083 
00084         story * log_story;
00085 
00086         // The dyn story is a placeholder for unrecognized dynamical data.
00087                                   
00088         story * dyn_story;        // allows information to be preserved
00089                                   // and passed down a pipe
00090 
00091     public:
00092 
00093         inline void clear_node() {
00094             if (name) delete [] name;
00095             parent = oldest_daughter = elder_sister = younger_sister = NULL;
00096         }
00097 
00098         inline void node_init() {
00099             node_flag = __VALID_NODE__;
00100             index = -1;     // < 0 to show that no number has yet been assigned
00101             mass = 1;       // to allow star and hydro to rescale this value
00102             name = NULL;
00103             clear_node();
00104         }
00105 
00106         inline void node_set_stories(bool use_stories) {
00107 
00108             // Potentially very dangerous to set any of the following NULL!
00109 
00110             if (use_stories) {
00111                 log_story = mk_story_chapter(LOG_ID);
00112                 dyn_story = mk_story_chapter(DYNAMICS_ID);
00113             } else {
00114                 log_story = NULL;
00115                 dyn_story = NULL;
00116             }
00117         }
00118 
00119         inline void node_set_hbase(hbpfp the_hbpfp) {
00120             if (the_hbpfp)
00121                 hbase = (*the_hbpfp)();
00122             else
00123                 hbase = NULL;
00124         }
00125 
00126         inline void node_set_sbase(sbpfp the_sbpfp) {
00127             if (the_sbpfp) {
00128                 sbase = (*the_sbpfp)();
00129                 sbase->set_node(this);
00130             } else
00131                 sbase = NULL;
00132         }
00133 
00135 
00136         node(hbpfp the_hbpfp = new_hydrobase,
00137              sbpfp the_sbpfp = new_starbase,
00138              bool use_stories = true) {
00139             node_init();
00140             node_set_stories(use_stories);
00141             node_set_hbase(the_hbpfp);
00142             node_set_sbase(the_sbpfp);
00143         }
00144 
00146 
00147         inline void rmstory() {
00148             if (log_story) {
00149                 delete log_story;
00150                 log_story = NULL;
00151             }
00152             if (dyn_story) {
00153                 delete dyn_story;
00154                 dyn_story = NULL;
00155             }
00156         }
00157 
00159 
00160         inline void rmstarbase() {
00161             if (sbase) {
00162                 delete sbase;
00163                 sbase = NULL;
00164             }
00165         }
00166 
00168 
00169         inline void rmhydrobase() {
00170             if (hbase) {
00171                 delete hbase;
00172                 hbase = NULL;
00173             }
00174         }
00175 
00176         virtual ~node() {
00177             node_flag = __INVALID_NODE__;
00178             if (name) delete [] name;
00179             rmstory();
00180             rmhydrobase();
00181             rmstarbase();
00182             if (this == root) root = NULL;
00183         }
00184 
00186 
00187         inline bool is_valid() const
00188             {return (node_flag == __VALID_NODE__);}
00189 
00191 
00192         inline void set_invalid()
00193             {node_flag = __INVALID_NODE__;}
00194 
00196 
00197         void  set_label(int number)             // to set the index to a number
00198             {index = number;}
00199 
00201 
00202         void  set_label(char * a_string)        // to set the name to a string
00203             {
00204             if(name != NULL)
00205                 delete [] name;
00206             name = new char[strlen(a_string)+1];
00207             strcpy(name, a_string);
00208             }
00209 
00211 
00212         void  set_index(int number)             // to set the index to a number
00213             {index = number;}
00214 
00216 
00217         void  set_name(char * a_string)        // to set the name to a string
00218         {
00219             if (name)
00220                 delete [] name;
00221             if (!a_string)
00222                 name = NULL;
00223             else {
00224                 name = new char[strlen(a_string)+1];
00225                 strcpy(name, a_string);
00226             }
00227         }
00228 
00230 
00231         void clear_name()                   {set_name(NULL);}
00232 
00234 
00235         void clear_label()                  {clear_name();}
00236 
00238 
00239         void  set_mass(const real new_mass) {mass = new_mass;}
00240 
00242 
00243         void  set_parent(node * b)          {parent = b;}
00244 
00246 
00247         void  set_oldest_daughter(node * b) {oldest_daughter = b;}
00248 
00250 
00251         void  set_elder_sister(node * b)    {elder_sister = b;}
00252 
00254 
00255         void  set_younger_sister(node * b)  {younger_sister = b;}
00256 
00257 #if 0
00258         void  set_log_story(story * s)      {log_story = s;}    
00259 #else
00260         // note that some functions (e.g. node::scan_log_story)
00261         // simply set the story, and don't bother deleting
00262         // the old one, which is normally made with new_dyn()
00263 
00264         void  set_log_story(story * s) {
00265             if (log_story != NULL) delete log_story;
00266             log_story = s;
00267         }       
00268 #endif
00269         void  set_dyn_story(story * s)      {dyn_story = s;}
00270 
00272 
00273         void  log_comment(char *);
00274 
00276 
00277         void  log_history(int, char **);
00278 
00280 
00281         void  inc_mass(const real d_mass)          {mass += d_mass;}
00282 
00284 
00285         void  scale_mass(const real scale_factor)  {mass *= scale_factor;}
00286 
00287         int  get_index()                     const {return index;}
00288         char * get_name()                    const {return name;}
00289 
00290         inline real  get_mass()              const {return mass;}
00291 
00292         inline node * get_parent()           const {return parent;}
00293         inline node * get_oldest_daughter()  const {return oldest_daughter;}
00294         inline node * get_younger_sister()   const {return younger_sister;}
00295         inline node * get_elder_sister()     const {return elder_sister;}
00296 
00298 
00299         inline node* get_top_level_node() const {
00300 
00301             if (parent == NULL) return NULL;    // root node
00302 
00303             node* n = const_cast<node*>(this);
00304             node* g = parent->get_parent();
00305 
00306             while (g) {
00307                 n = n->get_parent();
00308                 g = g->get_parent();
00309             }
00310             return n;
00311         }
00312 
00314 
00315         inline void set_root(node * b = NULL) {
00316             if (b)
00317                 root = b;
00318             else {
00319                 if (parent == NULL)
00320                     root = this;
00321                 else
00322                     root = get_top_level_node()->get_parent();
00323             }
00324         }
00325 
00326         // As of 4/05, get_root() *never* sets the root node pointer.
00327         // We assume that set_root() has always been called first.
00328         // All functions that create or read data from a file should
00329         // call set_root() once the system has been created.  If for
00330         // some reason root is not set, this function reverts to the
00331         // original (slow) option of searching for the root node.
00332 
00334 
00335         inline node* get_root() const
00336         {
00337             if (root) return root;
00338 
00339             if (parent == NULL)
00340                 return const_cast<node*>(this);
00341             else
00342                 return get_top_level_node()->get_parent();
00343         }
00344 
00346 
00347         node * get_binary_sister();
00348 
00349         void set_hydrobase(hydrobase * hb) {hbase = hb;}
00350         void set_starbase(starbase * sb)   {sbase = sb;}
00351 
00352         hydrobase * get_hydrobase()     const {return hbase;}
00353         starbase  * get_starbase()      const {return sbase;}
00354 
00355         story * get_log_story()         const {return log_story;}
00356         story * get_dyn_story()         const {return dyn_story;}
00357         story * get_hydro_story()       const {return hbase->get_hydro_story();}
00358         story * get_star_story()        const {return sbase->get_star_story();}
00359 
00361 
00362         virtual void null_pointers();
00363 
00365 
00366         virtual void print_static(ostream &s = cerr);
00367 
00369 
00370         istream& scan_log_story(istream&, char *);
00371 
00373 
00374         istream& scan_hydro_story(istream&);
00375 
00377 
00378         virtual istream& scan_star_story(istream&, int level = 0);
00379 
00381 
00382         virtual istream& scan_dyn_story(istream&);
00383 
00385 
00386         virtual bool check_and_correct_node(bool verbose = false);
00387 
00389 
00390         ostream& print_log_story(ostream &s = cout);
00391 
00393 
00394         ostream& print_hydro_story(ostream &s = cout);
00395 
00397 
00398         ostream& print_star_story(ostream &s = cout,
00399                                   int short_output = 0);
00400 
00402 
00403         virtual ostream& print_dyn_story(ostream &s = cout,
00404                                          bool print_xreal = true,
00405                                          int short_output = 0);
00406 
00408 
00409         inline bool is_isolated() const
00410             {return (parent == NULL && oldest_daughter==NULL);}
00411 
00413 
00414         inline bool is_root() const
00415             {return (parent == NULL);}
00416 
00418 
00419         inline bool is_leaf() const
00420             {return (parent != NULL && oldest_daughter==NULL);}
00421 
00423 
00424         inline bool is_top_level_node() const {
00425             return (parent == get_root());
00426         }
00427 
00429 
00430         inline bool is_top_level_leaf() const {
00431             if (parent != get_root()) return false;
00432             return (oldest_daughter == NULL);
00433         }
00434 
00436 
00437         inline bool is_low_level_node() const {
00438             return (parent != get_root());
00439         }
00440 
00442 
00443         inline bool is_low_level_leaf() const {
00444             if (parent == get_root()) return false;
00445             return (oldest_daughter == NULL);
00446         }
00447 
00449 
00450         inline bool is_parent() const
00451             {return oldest_daughter != NULL;}
00452 
00454 
00455         bool is_grandparent() const;
00456 
00458 
00459         node* next_node(node*);
00460         node* orig_next_node(node*);
00461 
00463 
00464         bool name_is(char*) const;
00465 
00467 
00468         char* format_label() const;
00469 
00471 
00472         void print_label(ostream&) const;
00473 
00475 
00476         void pretty_print_node(ostream& s = cerr) const;
00477 
00479 
00480         void pretty_print_tree(ostream& s = cerr, int level = 0);
00481 
00483 
00484         int  n_leaves() const;
00485 
00487 
00488         int  n_daughters() const;
00489 
00490         // SeBa counter access functions.
00491         //seba_counters* get_seba_counters() {
00492         //     return starbase->get_seba_counters();}
00493         //void set_seba_counters(seba_counters *sb) {
00494         //     starbase->set_seba_counters(sb);}
00495 
00496 };
00497 
00498 typedef  node *(*npfp)(hbpfp, sbpfp, bool);
00499 
00500 typedef node * nodeptr;  // to enable dynamic array declarations such as
00501                          //    node** node_ptr_array = new nodeptr[n];
00502                          // (note that the following expression is illegal:
00503                          //    node** node_ptr_array = new (node *)[n];)
00504 
00506 
00507 inline  node * new_node(hbpfp the_hbpfp,
00508                         sbpfp the_sbpfp ,
00509                         bool use_stories)
00510     {return  new node(the_hbpfp, the_sbpfp, use_stories);}
00511 
00513 
00514 node * mk_flat_tree(int, npfp, hbpfp, sbpfp, bool use_stories = true);
00515 
00517 
00518 inline node * mknode(int n, hbpfp the_hbpfp = new_hydrobase,
00519                             sbpfp the_sbpfp = new_starbase,
00520                             bool use_stories = true)
00521     {return  mk_flat_tree(n, new_node, the_hbpfp, the_sbpfp, use_stories);}
00522 
00523 // Modified first argument (default) 5/03 (Steve):
00524 
00526 
00527 node * get_node(istream &s = cin,
00528                 npfp the_npfp = new_node,
00529                 hbpfp the_hbpfp = new_hydrobase,
00530                 sbpfp the_sbpfp = new_starbase,
00531                 bool use_stories = true);
00532 
00533 // Modified arguments 5/03 (Steve):
00534 //
00535 //  void put_node(ostream &s, node &b,
00536 //            bool print_xreal = true,
00537 //            int short_output = 0);
00538 //  void put_single_node(ostream &s, node &b,
00539 //                   bool print_xreal = true,
00540 //                   int short_output = 0);
00541 
00543 
00544 void put_node(node *b,
00545               ostream &s = cout,
00546               bool print_xreal = true,
00547               int short_output = 0);
00548 
00550 
00551 void put_single_node(node *b,
00552                      ostream &s = cout,
00553                      bool print_xreal = true,
00554                      int short_output = 0);
00555 
00556 bool forget_node(istream &s = cin);
00557 
00559 
00560 bool node_contains(node * b, int i);
00561 
00563 
00564 bool node_contains(node * b, char* s);
00565 
00567 
00568 bool clump_contains(node * b, int i);
00569 
00571 
00572 bool clump_contains(node * b, char *s);
00573 
00575 
00576 void pp(const node *, ostream & s = cerr);
00577 
00579 
00580 void pp2(const node *, ostream & s = cerr, int level = 0);
00581 
00582 #define  for_all_daughters(dyntype, mother_node, daughter_name)               \
00583          for (dyntype* daughter_name = mother_node->get_oldest_daughter();    \
00584               daughter_name != NULL;                                          \
00585               daughter_name = daughter_name->get_younger_sister())
00586 
00587 // Note: for_all_nodes and for_all_leaves INCLUDE the base node.
00588 
00589 #define  for_all_nodes(dyntype, base, node_name)                              \
00590          for (dyntype* node_name = base;                                      \
00591               node_name != NULL;                                              \
00592               node_name = (dyntype*) node_name->next_node(base))
00593 
00594 #define  for_all_leaves(dyntype, base, node_name)                             \
00595          for (dyntype* node_name = base;                                      \
00596               node_name != NULL;                                              \
00597               node_name = (dyntype*) node_name->next_node(base))              \
00598               if (node_name->get_oldest_daughter() == NULL)
00599 
00600 node * mknode_mass(int n, real m = 1.0);
00601 
00602 // Declaration of functions defined in node_tt.C
00603 
00605 
00606 real total_mass(node *n);
00607 
00609 
00610 void rmtree(node *b, bool delete_b = true);
00611 
00612 void detach_node_from_general_tree(node *n);
00613 
00615 
00616 void remove_node_with_one_daughter(node *n);
00617 void detach_node_from_binary_tree(node *n);
00618 
00620 
00621 void extend_tree(node *old, node *n);
00622 
00624 
00625 void add_node(node *n, node *parent);
00626 
00628 
00629 void add_node_before(node *n, node *m);
00630 
00632 
00633 void insert_node_into_binary_tree(node *n, node *m, node *new_node);
00634 
00636 
00637 int is_descendent_of(node *a, node *b, int mode);
00638 
00640 
00641 node * common_ancestor(node *a, node *b);
00642 
00644 
00645 node * node_with_index(int i, node * top = NULL);
00646 
00648 
00649 node * node_with_name(char* s, node * top = NULL);
00650 
00652 
00653 int depth_of_node(node *n);
00654 
00656 
00657 char * construct_binary_label(node * ni, node * nj);
00658 
00660 
00661 void label_binary_node(node*);
00662 
00664 
00665 void label_merger_node(node*);
00666 
00667 void print_normal_form(node*, ostream&);
00668 char* get_normal_form(node*);
00669 
00670 // From node/util:
00671 
00672 void renumber(node* b, int istart, bool mass_order, bool name_nodes = false,
00673               bool single_number = false);
00674 void construct_node_name(node* b);
00675 
00676 #endif
00677 
00678 //=======================================================================//
00679 //  +---------------+        _\|/_        +------------------------------\\ ~
00680 //  |  the end of:  |         /|\         |  inc/node.h
00681 //  +---------------+                     +------------------------------//
00682 //========================= STARLAB =====================================\\ ~

Generated on Wed Jul 20 12:43:35 2005 for Starlab by  doxygen 1.4.3