00001 
00002 
00003        
00004       
00005      
00006     
00007    
00008   
00009  
00010 
00011 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 #include "worldline.h"
00064 #include "inline.h"
00065 #include <ctype.h>
00066 
00067 #define NEW 0
00068 
00069 #ifndef TOOLBOX
00070 
00071 
00072 
00073 #ifndef NEW_UNIQUE_ID_T
00074 
00075     
00076 
00077     
00078     
00079 
00080 #   define ID_FAC 0.000001                      // easier to read
00081 
00082     
00083     
00084 
00085 #else
00086 
00087 
00088 
00089 #   define ID_SHIFT 20
00090 
00091 #endif
00092 
00093 
00094 
00095 unique_id_t unique_id(int index)
00096 {
00097 #ifndef NEW_UNIQUE_ID_T
00098     return (unique_id_t)(1 + ID_FAC*index);
00099 #else
00100     return (unique_id_t)((1<<ID_SHIFT) + index);
00101 #endif
00102 }
00103 
00104 unique_id_t unique_id(char *name)
00105 {
00106     
00107     
00108     
00109     
00110     
00111     
00112     
00113     
00114     
00115 
00116     
00117 
00118     int index = atoi(name);
00119     if (index > 0) return unique_id(index);
00120 
00121     
00122     
00123 
00124     
00125 
00126     unique_id_t id = 0;
00127     int n = 0;
00128 
00129 #if 0
00130 
00131     
00132     
00133     
00134     
00135     
00136     
00137 
00138     char tname[1024];
00139     strcpy(tname, name);        
00140     int l = strlen(tname);
00141 
00142     real fac = 1;
00143     int num = 0;
00144 
00145     for (int i = 0; i < l; i++) {
00146         if (tname[i] >= '0' && tname[i] <= '9') {
00147             if (num == 0) {
00148                 fac *= ID_FAC;
00149                 num = i+1;
00150             }
00151         } else {
00152             if (num > 0) {
00153                 tname[i] = '\0';
00154                 id += fac*atoi(tname+num-1);
00155                 n++;
00156                 num = 0;
00157             }
00158         }
00159     }
00160 
00161 #else
00162 
00163     
00164     
00165     
00166     
00167     
00168     
00169     
00170 
00171     char *c = name, *end;
00172     bool num = false;
00173 
00174     while (1) {
00175 
00176         
00177 
00178         while (*c && !isdigit(*c)) c++;
00179 
00180         if (*c) {
00181 
00182             
00183             
00184             
00185 
00186             long int i = strtol(c, &end, 10);
00187             n++;
00188 
00189             if (n == 1) {
00190 
00191 #ifndef NEW_UNIQUE_ID_T
00192                 id = (unique_id_t)(ID_FAC*i);   
00193 #else
00194                 id = (unique_id_t)(i);          
00195 #endif
00196             }
00197 
00198             c = end;            
00199 
00200         } else
00201             break;
00202     }
00203 
00204 #endif
00205 
00206     
00207     
00208 
00209 #ifndef NEW_UNIQUE_ID_T
00210     id += n;
00211 #else
00212     id += (n<<ID_SHIFT);                                
00213 #endif
00214 
00215     return id;
00216 }
00217 
00218 unique_id_t unique_id(node *b)
00219 {
00220     
00221     
00222     
00223     
00224 
00225     
00226     
00227 
00228     if (b->get_index() > 0)
00229         return unique_id(b->get_index());
00230 
00231     else if (b->get_name())
00232         return unique_id(b->format_label());
00233 
00234     else
00235         return -1;
00236 }
00237 
00238 void print_id(void *id, char *s = NULL, int offset = 0)
00239 {
00240     real *r = (real *)id;
00241     unsigned long long *u = (unsigned long long *)id;
00242 
00243     real rr = *r;
00244     unsigned long long uu = *u;
00245 
00246     if (offset > 0) PRI(offset);
00247     if (s)
00248         cerr << s << ": ";
00249     else
00250         cerr << "    ";
00251 
00252     fprintf(stderr, "%.16lf = %qu = %qx\n", rr, uu, uu);
00253 }
00254 
00255 void worldline::dump(int offset,        
00256                      real t1,           
00257                      real t2)           
00258 {
00259     
00260 
00261     PRI(offset+4); PRC(start_esc_flag); PRC(end_esc_flag); PRL(t_esc);
00262 
00263     segment *s = get_first_segment();
00264     int is = 0;
00265     while (s) {
00266         real t_start = s->get_t_start();
00267         real t_end = s->get_t_end();
00268         if (t_start <= t2 && t_end >= t1) { 
00269             PRI(offset+4); cerr << "segment " << is << " (" << s << "): ";
00270             PRC(t_start); PRL(t_end);
00271             print_id(&id, "id", offset+8);
00272         }
00273         tdyn *b = s->get_first_event();
00274         int ie = 0;
00275         while (b) {
00276             real t = b->get_time();
00277             if (t >= t1 && t <= t2) {
00278                 PRI(offset+8);
00279                 cerr << "event " << ie << ": name = "
00280                      << b->format_label() << ", ";
00281                 PRL(t);
00282             }
00283             b = b->get_next();
00284             ie++;
00285         }
00286         if (t_start <= t2 && t_end >= t1) { 
00287             if (ie == 1) {
00288                 PRI(offset+8); cerr << "*** single event ***" << endl;
00289             }
00290         }
00291         s = s->get_next();
00292         is++;
00293     }
00294 }
00295 
00296 local void check_print_worldline_header(bool& print, int i)
00297 {
00298     cerr << "worldline " << i << ":" << endl;
00299     print = false;
00300 }
00301 
00302 void worldline::check(int i)    
00303 {
00304     
00305 
00306     bool print = true;
00307 
00308     segment *s = get_first_segment();
00309     int is = 0;
00310     while (s) {
00311         tdyn *b0 = s->get_first_event();
00312         tdyn *b = b0;
00313         int ie = 0;
00314         while (b) {
00315             real t = b->get_time();
00316             if (b != b0) {
00317                 tdyn *p = b->get_prev();
00318                 if (!p) {
00319                     if (print) check_print_worldline_header(print, i);
00320                     cerr << "    segment " << is << ", event "
00321                          << ie << " has prev = NULL" << endl;
00322                 } else if (p->get_next() != b) {
00323                     if (print) check_print_worldline_header(print, i);
00324                     cerr << "    segment " << is << ", event "
00325                          << ie << " has prev->next != this" << endl;
00326                 }
00327             }
00328             b = b->get_next();
00329             ie++;
00330         }
00331         if (ie == 1) {
00332             if (print) check_print_worldline_header(print, i);
00333             cerr << "    *** single event in segment " << is << " ***" << endl;
00334         }
00335 
00336         s = s->get_next();
00337         is++;
00338     }
00339 }
00340 
00341 void segment::print(char *label)
00342 {
00343     if (label == NULL) label = "    ";
00344     cerr << label << "name " << first_event->format_label()
00345          << ", id = " << id
00346          << ", t_start = " << t_start
00347          << ", t_end = " << t_end
00348          << endl;
00349 }
00350 
00351 
00352 
00353 local int wlcompare(const void *a, const void *b)       
00354                                                         
00355 {
00356     worldlineptr wa = *((worldlineptr*)a);              
00357     worldlineptr wb = *((worldlineptr*)b);
00358 
00359     int result = 0;
00360 
00361 
00362     if (wa->get_id() < wb->get_id())
00363         result = -1;
00364     else if (wa->get_id() > wb->get_id())
00365         result = 1;
00366 
00367 
00368     return result;
00369 }
00370 
00371 worldbundle::worldbundle(tdyn *b)
00372 {
00373     
00374 
00375     nw_max = 0;
00376     for_all_nodes(tdyn, b, bb) nw_max++;
00377 
00378     nw_max *= 2;                                
00379 
00380     bundle = new worldlineptr[nw_max];
00381     nw = 0;
00382 
00383     t_min = VERY_LARGE_NUMBER;
00384     t_max = -VERY_LARGE_NUMBER;
00385 
00386     t_int = -VERY_LARGE_NUMBER;
00387     root = NULL;
00388 
00389     
00390 
00391     for_all_nodes(tdyn, b, bb) {
00392 
00393         
00394 
00395         bb->clear_jerk();
00396 
00397         real t = bb->get_time();
00398         worldline *w = new worldline(bb);
00399 
00400         bundle[nw++] = w;
00401 
00402         t_min = min(t_min, t);
00403         t_max = max(t_max, t);
00404     }
00405 
00406     
00407 
00408     qsort((void*)bundle, (size_t)nw, sizeof(worldlineptr), wlcompare);
00409 
00410 
00411 
00412 
00413 
00414 
00415 }
00416 
00417 void worldbundle::print()
00418 {
00419     
00420 
00421     for (int i = 0; i < nw; i++) {
00422 
00423         worldline *w = bundle[i];
00424         segment *s = w->get_first_segment();
00425         int segnum = 0;
00426 
00427         cerr << i << " (" << s->get_first_event()->format_label();
00428         int p = cerr.precision(HIGH_PRECISION);
00429         cerr << ", id = " << w->get_id() << ")";
00430         cerr.precision(p);
00431         cerr << "  t_start = " << w->get_t_start()
00432              << ", t_end = " << w->get_t_end()
00433              << endl;
00434 
00435         while (s) {
00436 
00437             segnum++;
00438             int nn = 1;
00439 
00440             tdyn *b = s->get_first_event();
00441             while (b->get_next()) {
00442                 b = b->get_next();
00443                 nn++;
00444             }
00445 
00446             cerr << "        segment " << segnum << ":  "
00447                  << s->get_t_start() << " (" << nn << ") " << s->get_t_end()
00448                  << endl;
00449 
00450             s = s->get_next();
00451         }
00452     }
00453 }
00454 
00455 void worldbundle::dump(int offset)      
00456 {
00457     for (int i = 0; i < get_nw(); i++) {
00458         PRI(offset); cerr << "worldline " << i << ":" << endl;
00459         get_worldline(i)->dump(offset);
00460     }
00461 }
00462 
00463 void worldbundle::check()
00464 {
00465     cerr << "checking worldbundle " << this << endl;
00466     for (int i = 0; i < get_nw(); i++)
00467         get_worldline(i)->check(i);
00468 }
00469 
00470 
00471 
00472 int worldbundle::find_index(unique_id_t id)
00473 {
00474     
00475 
00476     
00477     
00478     
00479     
00480     
00481     
00482 
00483     
00484 
00485     int loc;
00486 
00487     if (nw <= 0 || id < bundle[0]->get_id()) {
00488         PRC(id); PRL(bundle[0]->get_id());
00489         loc = -1;
00490     }
00491 
00492     else if (id > bundle[nw-1]->get_id())
00493         loc = -nw-1;
00494 
00495     else {
00496 
00497         int low = 0, high = nw-1;
00498         loc = (low+high)/2;
00499 
00500         if (bundle[low]->get_id() == id)
00501             loc = low;
00502 
00503         else if (bundle[high]->get_id() == id)
00504             loc = high;
00505 
00506         else if (bundle[loc]->get_id() != id) {
00507 
00508             bool found = false;
00509 
00510             while (low < high-1) {
00511 
00512                 if (bundle[loc]->get_id() < id)
00513                     low = loc;
00514                 else if (bundle[loc]->get_id() > id)
00515                     high = loc;
00516                 else {
00517                     found = true;
00518                     break;
00519                 }
00520 
00521                 loc = (low+high)/2;
00522             }
00523 
00524             if (!found) loc = -high - 1;
00525         }
00526     }
00527 
00528     return loc;
00529 }
00530 
00531 int worldbundle::find_index(char *name) {return find_index(unique_id(name));}
00532 int worldbundle::find_index(_pdyn_ *b)  {return find_index(unique_id(b));}
00533 
00534 worldline *worldbundle::find_worldline(unique_id_t id)
00535 {
00536     int i = find_index(id);
00537     if (i >= 0 && i < nw)
00538         return bundle[i];
00539     else
00540         return NULL;
00541 }
00542 
00543 worldline *worldbundle::find_worldline(char *name)
00544 {return find_worldline(unique_id(name));}
00545 
00546 worldline *worldbundle::find_worldline(_pdyn_ *b)
00547 {return find_worldline(unique_id(b));}
00548 
00549 
00550 
00551 
00552 
00553 void worldbundle::attach(tdyn *bn,
00554                          int verbose)           
00555 {
00556     
00557 
00558     if (bn) {
00559 
00560         for_all_nodes(tdyn, bn, b) {
00561 
00562             
00563 
00564             b->clear_jerk();
00565 
00566             
00567             
00568             
00569             
00570             
00571             
00572             
00573             
00574             
00575             
00576             
00577             
00578             
00579             
00580             
00581             
00582 
00583             
00584             
00585 
00586             unique_id_t id = unique_id(b);
00587 
00588             if (id >= 0) {
00589 
00590                 real t = b->get_time();
00591                 int loc = find_index(id);
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603                 if (loc >= 0) {
00604 
00605                     
00606 
00607                     worldline *w = bundle[loc];
00608                     segment *s = w->get_last_segment(); 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616                     
00617 
00618                     if (s->get_last_event()->is_defunct()) {
00619 
00620                         if (verbose)
00621                             cerr << "starting new segment for "
00622                                  << b->format_label()
00623                                  << " (id = " << id
00624                                  << ") at t = " << t
00625                                  << endl;
00626 
00627                         
00628 
00629                         s = new segment(b);
00630                         w->add_segment(s, true);  
00631                                                   
00632 
00633                         if (verbose)
00634                             cerr << "new segment = " << s << endl;
00635 
00636                     } else {
00637 
00638                         
00639 
00640                         s->add_event(b, true);    
00641 
00642                         
00643                         
00644                         
00645                         
00646                         
00647                         
00648                         
00649                         
00650                         
00651                         
00652                         
00653                         
00654                         
00655                         
00656                     }
00657 
00658                     
00659 
00660                     w->set_t_end(t);
00661 
00662                 } else {
00663 
00664                     
00665                     
00666                     
00667 
00668                     if (nw >= nw_max) {
00669 
00670                         
00671                         
00672 
00673                         nw_max *= 5;
00674                         nw_max /= 4;
00675 
00676                         cerr << "extending bundle array for worldbundle "
00677                              << this << ":  nw_max = "
00678                              << nw_max << endl;
00679 
00680                         worldlineptr *tmp = new worldlineptr[nw_max];
00681                         for (int i = 0; i < nw; i++)
00682                             tmp[i] = bundle[i];
00683                         delete [] bundle;
00684                         bundle = tmp;
00685                     }
00686 
00687                     
00688 
00689                     loc = -loc - 1;
00690 
00691                     for (int i = nw-1; i >= loc; i--)
00692                         bundle[i+1] = bundle[i];
00693 
00694                     bundle[loc] = new worldline(b);
00695                     nw++;
00696 
00697                     if (verbose)
00698                         cerr << "adding " << b->format_label()
00699                              << " (id = " << id
00700                              << ") at t = " << b->get_time()
00701                              << endl;
00702                 }
00703 
00704                 t_max = max(t_max, t);
00705             }
00706         }
00707     }
00708 }
00709 
00710 
00711 
00712 static real physical_mass = 0;
00713 
00714 real mass_scale_factor()
00715 {
00716     return physical_mass;
00717 }
00718 
00719 local void check_final_escapers(worldbundle *wb, tdyn *b)
00720 {
00721     for_all_nodes(tdyn, b, bb) {
00722         worldline *w = NULL;
00723         if (bb->get_prev()) {                   
00724             bb->set_prev(NULL);
00725             w = wb->find_worldline(bb);
00726             if (w) w->set_end_esc_flag(1);
00727         }
00728         if (bb->get_next()) {                   
00729             real *t_esc = (real*)bb->get_next();
00730             bb->set_next(NULL);
00731             if (!w) w = wb->find_worldline(bb);
00732             if (w) w->set_t_esc(*t_esc);
00733             delete t_esc;
00734         }
00735     }
00736 }
00737 
00738 
00739 
00740 
00741 
00742 
00743 
00744 worldbundle *read_bundle(istream &s,
00745                          int verbose)                   
00746 {
00747     
00748 
00749     
00750     
00751 
00752     tdyn *b = get_tdyn(s, NULL, NULL, false);           
00753     if (!b || !streq(b->format_label(), "root")) return NULL;
00754 
00755     
00756     
00757     
00758     
00759 
00760     if (b->get_log_story())
00761         physical_mass = getrq(b->get_log_story(), "physical_initial_mass");
00762 
00763     
00764     
00765     
00766     
00767 
00768     worldbundle *wb = new worldbundle(b);
00769 
00770     if (verbose)
00771         cerr << endl
00772              << "new worldbundle: created initial list, nw = "
00773              << wb->get_nw() << endl;
00774 
00775     
00776     
00777 
00778     while (b = get_tdyn(s, NULL, NULL, false)) {        
00779 
00780         
00781         
00782         
00783 
00784         
00785         
00786         
00787 
00788         bool stop = (b->get_oldest_daughter()
00789                      && streq(b->format_label(), "root"));
00790         if (stop)
00791             check_final_escapers(wb, b);
00792 
00793         
00794 
00795         wb->attach(b, verbose);
00796 
00797         
00798 
00799         if (stop) {
00800             if (verbose)
00801                 cerr << "break at t = " << b->get_time() << endl;
00802             break;
00803         }
00804     }
00805 
00806     if (verbose) {
00807 
00808         cerr << "after last input:  nw = " << wb->get_nw()
00809              << endl;
00810 
00811         
00812 
00813         for (int i = 0; i < wb->get_nw(); i++) {
00814             worldline *w = wb->get_bundle()[i];
00815 
00816             
00817 
00818             int seg = 0, nseg = 0;
00819             segment *s = w->get_first_segment();
00820             tdyn *b = s->get_first_event();
00821             real t = s->get_t_start();
00822 
00823             while (s) {
00824                 nseg++;
00825                 s = s->get_next();
00826             }
00827 
00828             s = w->get_first_segment();
00829             int n_jump = 0;
00830 
00831             while (s) {
00832 
00833                 if (s->get_t_start() >= s->get_t_end()) {
00834                     int p = cerr.precision(HIGH_PRECISION);
00835                     cerr << "worldline " << i << " (" << b->format_label()
00836                          << "), id = " << w->get_id() << endl;
00837                     cerr.precision(p);
00838                     PRI(10); cerr << "zero-length segment at t = "
00839                                   << s->get_t_start()
00840                                   << ";  segment " << seg << " of " << nseg
00841                                   << endl;
00842                 }
00843 
00844                 if (s->get_t_start() > t) {
00845                     n_jump++;
00846                     if (verbose > 1) {
00847                         int p = cerr.precision(HIGH_PRECISION);
00848                         cerr << "worldline " << i << " (" << b->format_label()
00849                             << "), id = " << w->get_id() << endl;
00850                         cerr.precision(p);
00851                         PRI(10); cerr << "jump from " << t
00852                                       << " to " << s->get_t_start()
00853                                       << " after segment " << seg
00854                                       << " of " << nseg
00855                                       << endl;
00856                     }
00857                 }
00858 
00859                 t = s->get_t_end();
00860                 seg++;
00861                 s = s->get_next();
00862             }
00863 
00864             if (verbose == 1 && n_jump > 0) {
00865                 cerr << "worldline " << i << " (" << b->format_label()
00866                      << "), id = " << w->get_id()
00867                      << " has " << n_jump << " jump";
00868                 if (n_jump > 1) cerr << "s";
00869                 cerr << endl;
00870             }
00871 
00872             
00873 
00874             seg = 0;
00875             s = w->get_first_segment();
00876             while (s) {
00877 
00878                 b = s->get_first_event();
00879 
00880                 if (b->get_time() != s->get_t_start()) {
00881                     int p = cerr.precision(HIGH_PRECISION);
00882                     cerr << "worldline " << i << " (" << b->format_label()
00883                          << "), id = " << w->get_id() << endl;
00884                     cerr.precision(p);
00885                     PRI(10); cerr << "t_start =  " << s->get_t_start()
00886                                   << ", t = "
00887                                   << b->get_time() << " in segment " << seg
00888                                   << " of " << nseg << endl;
00889                 }
00890 
00891                 while (b && b->get_next()) b = b->get_next();
00892 
00893                 if (b->get_time() != s->get_t_end()) {
00894                     int p = cerr.precision(HIGH_PRECISION);
00895                     cerr << "worldline " << i << " (" << b->format_label()
00896                          << "), id = " << w->get_id() << endl;
00897                     cerr.precision(p);
00898                     PRI(10); cerr << "t_end =  " << s->get_t_end() << ", t = "
00899                                   << b->get_time() << " in segment " << seg
00900                                   << " of " << nseg << endl;
00901                 }
00902 
00903                 seg++;
00904                 s = s->get_next();
00905             }
00906         }
00907     }
00908 
00909     return wb;
00910 }
00911 
00912 int count_segments(worldbundle *wb)
00913 {
00914     int ns = 0;
00915     for (int i = 0; i < wb->get_nw(); i++) {
00916         worldline *w = wb->get_worldline(i);
00917         segment *s = w->get_first_segment();
00918         while (s) {
00919             ns++;
00920             s = s->get_next();
00921         }
00922     }
00923     return ns;
00924 }
00925 
00926 int count_events(worldbundle *wb)
00927 {
00928     int ne = 0;
00929     for (int i = 0; i < wb->get_nw(); i++) {
00930         worldline *w = wb->get_worldline(i);
00931         segment *s = w->get_first_segment();
00932         while (s) {
00933             tdyn *b = s->get_first_event();
00934             while (b) {
00935                 ne++;
00936                 b = b->get_next();
00937             }
00938             s = s->get_next();
00939         }
00940     }
00941     return ne;
00942 }
00943 
00944 
00945 
00946 
00947 
00948 tdyn *find_event(worldline *w, tdyn *bn, real t)
00949 {
00950     
00951     
00952     
00953     
00954     
00955     
00956 
00957     
00958     
00959 
00960     tdyn *b = bn;
00961 
00962     if (w) {
00963 
00964         tdyn *curr = w->get_current_event();
00965 
00966         if (curr) {
00967 
00968             real t_curr = curr->get_time();
00969             real t_bn = bn->get_time();         
00970                                                 
00971                                                 
00972 
00973             if (t_curr > t) {
00974 
00975                 if (t > 0.5*(t_bn + t_curr)) {
00976 
00977                     
00978 
00979                     b = curr;
00980 #if 0
00981                     if (b != bn && !b->get_prev()) {
00982                         cerr << endl << "prev = NULL for node " << b << endl;
00983                         PRC(b); PRL(bn);
00984                         cerr << "worldline dump:" << endl;
00985                         w->dump();
00986                         cerr << "checking worldline..." << endl;
00987                         w->check(-1);
00988                     }
00989 #endif
00990 
00991                     tdyn *p;
00992                     while (b && (p = b->get_prev()) && b->get_time() > t)
00993                         b = p;
00994 
00995                     return b;
00996                 }
00997 
00998             } else {
00999 
01000                 
01001                 
01002                 
01003 
01004                 tdyn *n = curr->get_next();
01005                 if (!n || n->get_time() >= t) return curr;
01006 
01007                 
01008 
01009                 b = n;
01010 
01011             }
01012         }
01013     }
01014 
01015     
01016     
01017 
01018     tdyn *n;
01019     while (b && (n = b->get_next()) && n->get_time() < t)
01020         b = n;
01021 
01022     
01023 
01024     return b;
01025 }
01026 
01027 void print_event(worldline *w, tdyn *bn, real t)
01028 {
01029     
01030     
01031 
01032     tdyn *b = find_event(w, bn, t);
01033 
01034     if (b) {
01035         PRC(t); PRC(b->get_time()); PRL(b->get_next());
01036         if (b->get_next()) PRL(b->get_next()->get_time());
01037     }
01038 }
01039 
01040 
01041 #include "print_local.C"        
01042 
01043 
01044 local inline bool check_and_initialize(tdyn *p,
01045                                        real tp,
01046                                        real t,
01047                                        vector& pos,
01048                                        bool inc,
01049                                        tdyn *bn)
01050 {
01051     if (tp < t) {
01052 
01053         tdyn *n = p->get_next();
01054 
01055         if (!n) {
01056 
01057             cerr << "interpolate_pos: error 2: next node not found: ";
01058             PRC(p->format_label()); PRL(t);
01059             int pr = cerr.precision(HIGH_PRECISION);
01060             PRL(unique_id(p)); cerr.precision(pr);
01061             PRI(26); PRC(bn); PRL(bn->get_time());
01062             PRI(26); PRC(p); PRL(p->get_time());
01063             PRI(26); PRL(p->get_time()-t);
01064             if (bn) {
01065                 PRI(26); PRL(bn->format_label());
01066                 pr = cerr.precision(HIGH_PRECISION);
01067                 PRL(unique_id(bn)); cerr.precision(pr);
01068             }
01069             
01070 
01071             if (inc)
01072                 pos += p->get_pos();
01073             else
01074                 pos = p->get_pos();
01075             return false;
01076 
01077         } else if (n->get_time() < t) {
01078 
01079             cerr << "interpolate_pos: error 3: specified time above range: ";
01080             PRC(p->format_label()); PRC(t); PRL(p->get_time());
01081             
01082 
01083             if (inc)
01084                 pos += p->get_pos();
01085             else
01086                 pos = p->get_pos();
01087             return false;
01088         }
01089 
01090         
01091         
01092         
01093 
01094         if (p->get_jerk()[0] == 0) {
01095 
01096             
01097 
01098             
01099             
01100 
01101             
01102             
01103 
01104             
01105 
01106             real dt = n->get_time() - tp;
01107             real dti = 1/dt;
01108 
01109             if (streq(p->get_name(), "root")) {         
01110 
01111                 
01112                 
01113 
01114                 p->set_vel(dti*(n->get_pos() - p->get_pos()));
01115                 p->set_acc(0);
01116                 p->set_jerk(vector(VERY_SMALL_NUMBER, 0, 0));
01117 
01118             } else {
01119 
01120                 
01121 
01122                 p->set_acc((3*(n->get_pos()-p->get_pos())
01123                             - dt*(2*p->get_vel()+n->get_vel()))*dti*dti);
01124                 p->set_jerk((p->get_vel()+n->get_vel()
01125                              - 2*dti*(n->get_pos()-p->get_pos()))*dti*dti);
01126             }
01127         }
01128         return true;
01129 
01130     } else if (tp > t) {
01131 
01132         cerr << "interpolate_pos: error 1: specified time below range: ";
01133         PRC(p->format_label()); PRC(t); PRL(p->get_time());
01134         
01135     }
01136 
01137     
01138 
01139     if (inc)
01140         pos += p->get_pos();
01141     else
01142         pos = p->get_pos();
01143 
01144     return false;
01145 }
01146 
01147 
01148 
01149 
01150 
01151 
01152 
01153 
01154 
01155 
01156 
01157 
01158 
01159 vector interpolate_pos(tdyn *p, real t,
01160                        tdyn *bn)                
01161                                                 
01162 {
01163     
01164     
01165 
01166     
01167 
01168     if (p->get_time() > t) {
01169         cerr << "interpolate_pos: error 1: specified time below range: ";
01170         PRC(p->format_label()); PRC(t); PRL(p->get_time());
01171         
01172 
01173         return p->get_pos();
01174     }
01175 
01176     
01177 
01178     if (p->get_time() == t) return p->get_pos();
01179 
01180     tdyn *n = p->get_next();
01181 
01182     if (!n) {
01183         cerr << "interpolate_pos: error 2: next node not found: ";
01184         PRC(p->format_label()); PRL(t);
01185         int pr = cerr.precision(HIGH_PRECISION);
01186         PRL(unique_id(p)); cerr.precision(pr);
01187         PRI(26); PRC(bn); PRL(bn->get_time());
01188         PRI(26); PRC(p); PRL(p->get_time());
01189         PRI(26); PRL(p->get_time()-t);
01190         if (bn) {
01191             PRI(26); PRL(bn->format_label());
01192             pr = cerr.precision(HIGH_PRECISION);
01193             PRL(unique_id(bn)); cerr.precision(pr);
01194         }
01195         
01196 
01197         return p->get_pos();
01198     }
01199 
01200     if (n->get_time() < t) {
01201         cerr << "interpolate_pos: error 3: specified time above range: ";
01202         PRC(p->format_label()); PRC(t); PRL(p->get_time());
01203         
01204 
01205         return p->get_pos();
01206     }
01207 
01208     
01209 
01210     
01211     
01212     
01213 
01214     real tp = p->get_time();
01215     real dt = n->get_time() - tp;
01216 
01217     if (dt > 0) {
01218 
01219         
01220 
01221         
01222         
01223 
01224         if (p->get_jerk()[0] == 0) {
01225 
01226             
01227 
01228             real dti = 1/dt;
01229 
01230             if (streq(p->get_name(), "root")) {         
01231 
01232                 
01233                 
01234 
01235                 p->set_vel(dti*(n->get_pos() - p->get_pos()));
01236                 p->set_acc(0);
01237                 p->set_jerk(vector(VERY_SMALL_NUMBER, 0, 0));
01238 
01239             } else {
01240 
01241                 
01242 
01243                 p->set_acc((3*(n->get_pos()-p->get_pos())
01244                             - dt*(2*p->get_vel()+n->get_vel()))*dti*dti);
01245                 p->set_jerk((p->get_vel()+n->get_vel()
01246                              - 2*dti*(n->get_pos()-p->get_pos()))*dti*dti);
01247             }
01248         }
01249 
01250         dt = t - tp;
01251 
01252         return p->get_pos() + dt * (p->get_vel()
01253                                     + dt * (p->get_acc()
01254                                             + dt * p->get_jerk()));
01255     } else
01256 
01257         return p->get_pos();
01258 }
01259 
01260 
01261 
01262 void interpolate_pos(tdyn *p,
01263                      real t,
01264                      vector& pos,
01265                      bool inc,                  
01266                      tdyn *bn)                  
01267                                                 
01268 {
01269     
01270     
01271 
01272     real tp = p->get_time();
01273 
01274     if (check_and_initialize(p, tp, t, pos, inc, bn)) {
01275 
01276         real dt = t - tp;
01277 
01278         if (inc)
01279             pos += p->get_pos() + dt * (p->get_vel()
01280                                            + dt * (p->get_acc()
01281                                                       + dt * p->get_jerk()));
01282         else
01283             pos = p->get_pos() + dt * (p->get_vel()
01284                                           + dt * (p->get_acc()
01285                                                      + dt * p->get_jerk()));
01286     }
01287 }
01288 
01289 
01290 
01291 void set_interpolated_pos(tdyn *p,
01292                           real t,
01293                           vector& pos,
01294                           tdyn *bn)             
01295                                                 
01296 {
01297     
01298     
01299 
01300     real tp = p->get_time();
01301 
01302     if (check_and_initialize(p, tp, t, pos, false, bn)) {
01303 
01304         real dt = t - tp;
01305         pos = p->get_pos() + dt * (p->get_vel()
01306                                       + dt * (p->get_acc()
01307                                                  + dt * p->get_jerk()));
01308     }
01309 }
01310 
01311 
01312 
01313 void set_interpolated_pos(tdyn *p,
01314                           real t,
01315                           pdyn *curr,
01316                           tdyn *bn)             
01317                                                 
01318 {
01319     
01320     
01321 
01322     real tp = p->get_time();
01323     vector pos;
01324 
01325     if (check_and_initialize(p, tp, t, pos, false, bn)) {
01326 
01327         real dt = t - tp;
01328         curr->set_pos(p->get_pos() + dt * (p->get_vel()
01329                                             + dt * (p->get_acc()
01330                                                      + dt * p->get_jerk())));
01331     } else
01332 
01333         curr->set_pos(pos);
01334 }
01335 
01336 void inc_interpolated_pos(tdyn *p,
01337                           real t,
01338                           vector& pos,
01339                           tdyn *bn)             
01340                                                 
01341 {
01342     
01343     
01344 
01345     real tp = p->get_time();
01346 
01347     if (check_and_initialize(p, tp, t, pos, true, bn)) {
01348 
01349         real dt = t - tp;
01350         pos += p->get_pos() + dt * (p->get_vel()
01351                                        + dt * (p->get_acc()
01352                                                   + dt * p->get_jerk()));
01353     }
01354 }
01355 
01356 vector interpolate_vel(tdyn *p, real t,
01357                        tdyn *bn)                
01358                                                 
01359 {
01360     
01361 
01362     
01363     
01364 
01365     
01366 
01367     if (p->get_time() == t) return p->get_vel();
01368 
01369     tdyn *n = p->get_next();
01370     real tp = p->get_time();
01371     real dt = n->get_time() - tp;
01372 
01373     if (dt > 0) {
01374 
01375         dt = t - tp;
01376         return p->get_vel() + dt * (2*p->get_acc()
01377                                     + dt * 3*p->get_jerk());
01378     } else
01379 
01380         return p->get_vel();
01381 }
01382 
01383 
01384 
01385 
01386 local vector get_pos(worldline *w,
01387                      tdyn *b, tdyn *bn,
01388                      real t = VERY_LARGE_NUMBER)
01389 {
01390     
01391     
01392 
01393     
01394     
01395 
01396     if (t == -VERY_LARGE_NUMBER) t = b->get_time();
01397 
01398     vector pos;
01399     set_interpolated_pos(b, t, pos, bn);
01400 
01401     
01402     
01403     
01404 
01405     
01406     
01407     
01408     
01409 
01410     tdyn *bp = bn->get_parent();
01411 
01412     while (bp) {
01413 
01414         
01415 
01416         tdyn *p = find_event(w, bp, t);
01417 
01418         inc_interpolated_pos(p, t, pos, bn);
01419         bp = bp->get_parent();
01420     }
01421 
01422     return pos;
01423 }
01424 
01425 void worldbundle::print_worldline(char *name,
01426                                   real dt)      
01427 {
01428     
01429     
01430 
01431     int loc = find_index(name);                 
01432                                                 
01433     if (loc >= 0) {
01434 
01435         worldline *w = bundle[loc];
01436         segment *s = w->get_first_segment();
01437 
01438         if (dt == 0) {
01439 
01440             while (s) {                             
01441 
01442                 tdyn *bn = s->get_first_event();    
01443                 tdyn *b = bn;
01444                 while (b) {                         
01445                     cout << "    " << b->get_time()
01446                          << " " << get_pos(w, b, bn) << endl << flush;
01447                     b = b->get_next();
01448                 }
01449 
01450                 s = s->get_next();
01451             }
01452 
01453         } else {
01454 
01455             real t = get_t_min();
01456             while (t < get_t_max() - 0.5*dt) {
01457 
01458                 
01459                 
01460 
01461                 while (s && s->get_t_end() < t) s = s->get_next();
01462 
01463                 if (s) {
01464                     tdyn *bn = s->get_first_event();
01465                     tdyn *b = find_event(w, bn, t);
01466                     cout << "    " << t
01467                          << " " << get_pos(w, b, bn) << endl << flush;
01468                 }
01469 
01470                 t += dt;
01471             }
01472         }
01473 
01474     } else
01475         cerr << name << " not found" << endl;
01476 }
01477 
01478 
01479 
01480 
01481 
01482 
01483 #include "print_local2.C"       
01484 
01485 
01486 
01487 #include "attach_new_node.C"    
01488 
01489 
01490 
01491 #include "update_node.C"        
01492 
01493 
01494 local INLINE void add_to_interpolated_tree(worldbundle *wb,
01495                                            worldline *w, segment *s,
01496                                            pdyn *root, real t, bool vel,
01497                                            bool debug)
01498 {
01499     
01500     
01501     
01502 
01503     
01504 
01505     tdyn *bn = s->get_first_event();
01506 
01507     if (debug) {
01508         cerr << "s = " << s << endl
01509              << "first event = " << bn << " "
01510              << bn->format_label() << " "
01511              << bn->get_time() << endl;
01512 
01513         print_details(wb, bn, t);
01514     }
01515 
01516     
01517     
01518     
01519 
01520     
01521     
01522     
01523     
01524 
01525     tdyn *top = bn;
01526     while (top->get_parent()
01527            && unique_id(top->get_parent()) > 0)
01528         top = top->get_parent();
01529 
01530     if (debug) {
01531         PRC(top); PRL(top->format_label());
01532         
01533     }
01534 
01535     
01536 
01537     for_all_nodes(tdyn, top, bb) {
01538 
01539         
01540 
01541         worldline *ww;
01542 
01543         if (bb == bn)
01544             ww = w;
01545         else {
01546             ww = wb->find_worldline(bb);
01547             if (!ww)
01548                 cerr << "create_interpolated_tree: error:"
01549                      << "can't find worldline of subtree member." << endl;
01550         }
01551 
01552         if (ww) {
01553 
01554             
01555 
01556             attach_new_node(wb, ww, root, top, bb, debug);
01557 
01558             
01559             
01560 
01561             update_node(wb, ww, t, bb, top, vel, debug);
01562         }
01563     }
01564 }
01565 
01566 int id_n_clump(unique_id_t id)                  
01567 {
01568 #ifndef NEW_UNIQUE_ID_T
01569     return (int) id;
01570 #else
01571     return (id>>ID_SHIFT);                      
01572 #endif
01573 }
01574 
01575 local inline bool id_is_leaf(unique_id_t id)
01576 {
01577     return (id_n_clump(id) == 1);
01578 }
01579 
01580 #define EPS 1.e-12
01581 
01582 pdyn *create_interpolated_tree(worldbundle *wb, real t,
01583                                bool vel)                
01584 {
01585     
01586     
01587     
01588 
01589     bool debug = false;
01590 
01591     
01592     
01593     
01594 
01595     real dt = t - wb->get_t_max();
01596     if (dt > EPS)
01597         return NULL;
01598     else if (dt > 0)
01599         t = wb->get_t_max();
01600 
01601     dt = t - wb->get_t_min();
01602     if (dt < -EPS)
01603         return NULL;
01604     else if (dt < 0)
01605         t = wb->get_t_min();
01606 
01607     
01608     
01609 
01610     worldlineptr *bundle = wb->get_bundle();
01611 
01612     for (int i = 0; i < wb->get_nw(); i++)
01613         bundle[i]->clear_tree_node();
01614 
01615     
01616 
01617     pdyn *root = new pdyn(NULL, NULL, false);
01618 
01619     
01620 
01621     root->set_system_time(t);
01622     root->set_pos(0);
01623 
01624     
01625     
01626     
01627 
01628     root->set_root(root);
01629     bundle[0]->set_tree_node(root);
01630 
01631     
01632     
01633     
01634     
01635     
01636 
01637     for (int i = 1; i < wb->get_nw(); i++) {
01638 
01639         worldline *w = bundle[i];
01640 
01641         if (!w->get_tree_node()) {
01642 
01643             
01644 
01645             unique_id_t id = w->get_id();
01646 
01647 
01648             if (id_is_leaf(id)) {
01649 
01650                 
01651 
01652                 if (debug) {
01653                     cerr.precision(16);
01654                     cerr << endl
01655                          << "following worldline " << i << ", id = "
01656                          << w->get_id() << endl;
01657                 }
01658 
01659                 segment *s = w->get_first_segment();
01660                 while (s && s->get_t_end() < t) s = s->get_next();
01661 
01662                 if (debug) {
01663                     PRC(w); cerr << "segment "; PRC(s);
01664                     print_events(s, t);
01665                 }
01666 
01667                 
01668                 
01669                 
01670 
01671                 if (s) add_to_interpolated_tree(wb, w, s,
01672                                                 root, t, vel, debug);
01673             }
01674         }
01675     }
01676 
01677     return root;
01678 }
01679 
01680 #else
01681 
01682 main(int argc, char *argv[])
01683 {
01684     
01685 
01686     if (argc <= 2) exit(1);
01687 
01688     ifstream s(argv[1]);
01689     if (!s) exit(2);
01690 
01691     real t = atof(argv[2]);
01692 
01693     worldbundle *wb = read_bundle(s);
01694 
01695     pdyn *root = create_interpolated_tree(wb, t, true);
01696     put_node(cout, *root, false);
01697     rmtree(root);
01698 
01699 #if 0
01700     
01701 
01702     wb->print();
01703 
01704     cerr << wb->get_nw() << " worldlines, "
01705          << count_segments(wb) << " segments, "
01706          << count_events(wb) << " events, t = "
01707          << wb->get_t_min() << " to " << wb->get_t_max()
01708          << endl;
01709 #endif
01710 
01711 #if 0
01712     
01713 
01714     char name[128];
01715     real t;
01716     while (1) {
01717         cerr << endl << "time, name: "; cin >> t >> name;
01718         if (cin.eof()) {
01719             cerr << endl;
01720             break;
01721         }
01722         int loc = wb->find_index(name);
01723         if (loc >= 0) {
01724             PRC(unique_id(name)); PRL(loc);
01725             worldline *w = wb->get_bundle()[loc];
01726             segment *s = w->get_first_segment();
01727             while (s && s->get_t_start() > t) s = s->get_next();
01728             print_event(w, s->get_first_event(), t);
01729         } else
01730             cerr << "not found" << endl;
01731     }
01732 #endif
01733 
01734 #if 0
01735     
01736     
01737 
01738     real dt;
01739     char name[128];
01740     while (1) {
01741 
01742         cerr << endl << "dt, name: " << flush; cin >> dt >> name;
01743         if (cin.eof()) {
01744             cerr << endl;
01745             break;
01746         }
01747 
01748         wb->print_worldline(name, dt);
01749     }
01750 #endif
01751 
01752 #if 0
01753     real t = 0.8;
01754     while (t < 0.85) {
01755         pdyn *root = create_interpolated_tree(wb, t);
01756         put_node(cout, *root, false);
01757         rmtree(root);
01758         t += 0.01;
01759     }
01760 #endif
01761 
01762 }
01763 
01764 #endif