ADMB Documentation  11.1.1016
 All Classes Files Functions Variables Typedefs Friends Defines
newdar.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: newdar.cpp 542 2012-07-10 21:04:06Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California 
00006  */
00007 #include "fvar.hpp"
00008 #ifdef __ZTC__
00009   #include <iostream.hpp>
00010 #endif
00011 
00012 #ifdef __TURBOC__
00013   #pragma hdrstop
00014   #pragma options -h-
00015   #include <iostream.h>
00016 #endif
00017 #include <stdlib.h>
00018 
00019 int num_free_obj=0;
00020 extern char demo_capacity[];
00021 extern char please_buy[];
00022 extern char otter_address1[];
00023 extern char otter_address2[];
00024 extern char otter_address3[];
00025 extern char otter_address4[];
00026 extern char otter_address5[];
00027 int ad_kill_flag=0;
00028 
00033 arr_link::arr_link()
00034 {
00035   prev=NULL;
00036   next=NULL;
00037   free_prev=NULL;
00038   free_next=NULL;
00039   status=0;
00040   // free_list_status=0;
00041   size=0;
00042   offset=0;
00043 }
00044 
00049 void arr_free_remove(arr_link * tmp)
00050 {
00051   num_free_obj--;
00052   // if this is the last free object reset list pointer
00053   if (!tmp->free_next) 
00054   {
00055     gradient_structure::ARR_LIST1->free_last=tmp->free_prev;
00056   }
00057   // This routine removes the link pointed to by tmp
00058   if (tmp->free_next)  // Make the one after it point to tmp->prev
00059   {
00060     tmp->free_next->free_prev = tmp->free_prev;
00061   }
00062 
00063   if (tmp->free_prev)  // Make the one before it point to tmp->next
00064   {
00065     tmp->free_prev->free_next = tmp->free_next;
00066   }
00067 }
00068     
00073 void arr_free_add(arr_link * tmp)
00074 {
00075   num_free_obj++;
00076   // This routine adds the link pointed to by tmp to  the end of the free list
00077   tmp->free_prev = gradient_structure::ARR_LIST1->free_last;
00078   gradient_structure::ARR_LIST1->free_last=tmp;
00079   tmp->free_next = NULL;
00080   if (tmp->free_prev) tmp->free_prev->free_next = tmp;
00081 }
00082 
00087 double_and_int * arr_new(unsigned int sz)
00088 {
00089   if (!gradient_structure::instances)
00090   {
00091     cerr << "Error -- you are trying to create a dvar_vector object"
00092             " when there is " << endl << "no object of type"
00093             " gradient_structure in scope " << endl;
00094     ad_exit(1);
00095   }
00096 
00097   char * temp_ptr;
00098 
00099   // this routine allocated a block of memory of sizeof(double)*sz bytes
00100   // for the gradients of an array or matrix of prevariables 
00101 
00102   arr_link * tmp = gradient_structure::ARR_LIST1->free_last;
00103 
00104   unsigned int bytes_needed=sizeof(double_and_int)*sz;
00105   int ss=0;
00106   if (ss)
00107   {
00108     double_and_int * tt=0;
00109     return tt;
00110   }
00111 
00112   while (tmp)
00113   {
00114     if (tmp->size >= bytes_needed)
00115     {
00116       // if the free block within 20 bytes of the size you want
00117       // simply mark it occupied and return it
00118 
00119       if (tmp->size <= bytes_needed + 50)
00120       {
00121         tmp->status = 1;
00122         // remove tmp from the free list
00123         arr_free_remove(tmp);
00124         
00125   temp_ptr = gradient_structure::ARRAY_MEMBLOCK_BASE + tmp->offset;
00126 
00127   (* (arr_link **) (temp_ptr)) = tmp; //put the address
00128             //tmp into the location pointed to
00129             //by temp_ptr
00130   return  (double_and_int *) (temp_ptr);
00131       }
00132       else
00133       {
00134   // otherwise split up this memory block and return
00135   // the part you need
00136 
00137   arr_link * tmp1 = new arr_link;
00138         gradient_structure::ARR_LIST1->number_arr_links += 1;
00139 
00140         // put the new link tmp1-> into the list BEFORE tmp->
00141 
00142         tmp1->prev=tmp->prev;
00143 
00144         if(tmp1->prev)
00145         {
00146           tmp1->prev->next=tmp1;
00147         }
00148 
00149         tmp1->next=tmp;
00150         tmp->prev=tmp1;
00151 
00152         // get the size of the new link and mark it free
00153 
00154         tmp1->size=bytes_needed;
00155   tmp1->status=1;
00156         tmp1->offset=tmp->offset;
00157 
00158         tmp->offset+=bytes_needed;
00159   tmp->size-=bytes_needed;
00160 
00161   temp_ptr = gradient_structure::ARRAY_MEMBLOCK_BASE + tmp1->offset;
00162 
00163   (* (arr_link **) (temp_ptr )) = tmp1; //put the address
00164            //pointed to by
00165            // tmp1 into the location pointed to
00166            //by temp_ptr
00167   return  (double_and_int *) (temp_ptr);
00168       }
00169     }
00170     tmp=tmp->free_prev;
00171   }
00172   // couldn't find a free block large enough
00173   // make a new block
00174 
00175   tmp = new arr_link;
00176   if (tmp==0)
00177   {
00178     cerr << "Error allocating new arr_link" << endl;
00179     ad_exit(1);
00180   }
00181 
00182   gradient_structure::ARR_LIST1->number_arr_links  += 1;
00183 
00184   tmp->prev = gradient_structure::ARR_LIST1->last; // the new block point back 
00185                                                  // at the previous last block
00186 
00187   if (gradient_structure::ARR_LIST1->last)
00188   {
00189     gradient_structure::ARR_LIST1->last->next = tmp; // the previous last 
00190                                                   // block point forward to tmp
00191   }                             
00192   gradient_structure::ARR_LIST1->last = tmp;         // tmp is the new last block
00193 
00194   tmp->next = 0;
00195 
00196   tmp->status = 1;
00197 
00198   tmp->offset = gradient_structure::ARR_LIST1->last_offset;
00199 
00200   gradient_structure::ARR_LIST1->last_offset += bytes_needed;
00201 
00202   if (gradient_structure::ARR_LIST1->last_offset>
00203     (unsigned int)gradient_structure::max_last_offset )
00204   {
00205     gradient_structure::max_last_offset=
00206       gradient_structure::ARR_LIST1->last_offset;
00207   }
00208 
00209   if (gradient_structure::ARR_LIST1->last_offset > gradient_structure::ARR_LIST1->max_last_offset)
00210   {
00211     gradient_structure::ARR_LIST1->max_last_offset=gradient_structure::ARR_LIST1->last_offset;
00212   }
00213 
00214   if( gradient_structure::ARR_LIST1->last_offset >=gradient_structure::ARRAY_MEMBLOCK_SIZE)
00215   {
00216 #if defined(AD_DEMO)
00217     cout << "demo capacity exceeded" << endl;
00218 #endif
00219     cout << gradient_structure::ARR_LIST1->last_offset <<">="
00220        <<  gradient_structure::ARRAY_MEMBLOCK_SIZE <<"\n";
00221 #if !defined(AD_DEMO)
00222     cout << " No memory for dvar_vectors\n"
00223    << " Need to increase ARRAY_MEMBLOCK_SIZE parameter\n"
00224       "In gradient_structure declaration\n";
00225 #else
00226     cout << demo_capacity << endl;
00227     cout << please_buy << endl;
00228     cout << otter_address1 << endl;
00229     cout << otter_address2 << endl;
00230     cout << otter_address3 << endl;
00231     cout << otter_address4 << endl;
00232     cout << otter_address5 << endl;
00233 #endif
00234     //throw gradient_structure::arrmemblerr();
00235     ad_exit(1);
00236   }
00237 
00238   tmp->size = bytes_needed;
00239 
00240   temp_ptr = gradient_structure::ARRAY_MEMBLOCK_BASE + tmp->offset;
00241 
00242   (*(arr_link **) (temp_ptr )) = tmp; //put the address 
00243                                    // tmp into the location pointed to
00244                                    //by temp_ptr
00245          
00246 //  return  (double_and_int *) (temp_ptr+sizeof(double_and_int));
00247   return  (double_and_int *) (temp_ptr);
00248 
00249 }
00250 
00255 void arr_free(double_and_int * varr)
00256 {
00257   // This routines frees up a memory block and
00258   // consolidates the free blocks if possible
00259   //cout<< "calling arr_free\n";
00260   char * temp_ptr;
00261   arr_link * ptr;
00262 
00263   temp_ptr = (char *) varr;
00264 
00265   //temp=sizeof(double_and_int);
00266 //  ptr = *(arr_link **) (temp_ptr-temp);
00267   ptr = *(arr_link **) (temp_ptr);
00268 
00269   //mark this block free
00270 
00271   ptr->status = 0;
00272  // cout <<"Marking arr_link with adress  "<<farptr_tolong(ptr)<<"free\n";
00273 
00274   // if there is a block after this add this one to the free list 
00275   if (ptr->next) arr_free_add(ptr);
00276   
00277   if (!ptr->next)  // Is this the last link?
00278   {
00279     // Check to see if ptr->prev is free and should be deleted as well
00280     // ... but first check to see if ptr is first block in list
00281     // which will be indicated by ptr->prev being a NULL pointer
00282     if (ptr->prev && !ptr->prev->status)
00283     {
00284       // delete ptr->prev
00285       gradient_structure::ARR_LIST1->last = ptr->prev->prev; 
00286       //if (gradient_structure::ARR_LIST1->last ==0) 
00287        // cout << "gradient_structure::ARR_LIST1->last =0 " << endl;
00288 
00289       gradient_structure::ARR_LIST1->last_offset -= ptr->size + ptr->prev->size;
00290       arr_free_remove(ptr->prev);
00291       arr_remove(&(ptr->prev));
00292     }
00293     else
00294     {
00295       gradient_structure::ARR_LIST1->last = ptr->prev; 
00296       //if (gradient_structure::ARR_LIST1->last ==0) 
00297        // cout << "gradient_structure::ARR_LIST1->last =0 " << endl;
00298       gradient_structure::ARR_LIST1->last_offset -= ptr->size;
00299     }
00300     arr_remove(&ptr);
00301   }
00302   else
00303   {
00304      // There is another link after this one?
00305 
00306     if (!ptr->next->status) // If yes is it free?
00307     {
00308       // add its memory capacity to the present one and delete it
00309 
00310       ptr->size += ptr->next->size;
00311 
00312       arr_free_remove(ptr->next);
00313       arr_remove(&ptr->next);
00314 
00315     }    
00316   
00317     if (ptr->prev)  // Is there another link before this one?
00318     {
00319       if (!ptr->prev->status) // If yes is it free?
00320       {
00321         // we will keep ptr->prev and add ptr to it
00322 
00323         ptr->prev->size += ptr->size;
00324         arr_free_remove(ptr);
00325         arr_remove(&ptr);
00326       }    
00327     }
00328   }
00329 }
00330 
00335 void check_derivative_values(const char * _s)
00336 {
00337   char * s = (char *) _s;
00338   //char label[20];
00339   save_identifier_string(s);
00340   gradient_structure::GRAD_STACK1->
00341     set_gradient_stack(df_check_derivative_values);
00342 }
00343 
00348 void check_derivative_values(const char * _s,int i)
00349 {
00350   char * s = (char *) _s;
00351   //char label[20];
00352   save_identifier_string(s);
00353   save_int_value(i);
00354   gradient_structure::GRAD_STACK1->
00355     set_gradient_stack(df_check_derivative_values_indexed);
00356 }
00357 
00358 void df_print_identifier_string(void);
00359 
00364 void insert_identifier_string(const char * _s)
00365 {
00366   char * s = (char *) _s;
00367   save_identifier_string(s);
00368   gradient_structure::GRAD_STACK1->
00369     set_gradient_stack(df_print_identifier_string);
00370 }
00371 
00376 void check_derivative_values_break(const char * _s,int i,int b)
00377 {
00378   char * s = (char *) _s;
00379   //char label[20];
00380   save_identifier_string(s);
00381   save_int_value(i);
00382   save_int_value(b);
00383   gradient_structure::GRAD_STACK1->
00384     set_gradient_stack(df_check_derivative_values_indexed_break);
00385 }
00386 
00387 void  rrkludge(double * temp_ptr){;}
00388 
00393 void df_check_derivative_values(void)
00394 {
00395   //char label[20];
00396   adstring str=get_string_marker();
00397   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00398   unsigned long int max_last_offset = 
00399     gradient_structure::ARR_LIST1->get_max_last_offset();
00400      unsigned int size = sizeof(double_and_int );
00401 
00402   int icount=0;
00403   int exit_flag=0;
00404   cout << str << endl;
00405   unsigned int i;
00406   for (i=0 ; i< (max_last_offset/size) ; i++ )
00407   {
00408     if (fabs(temp_ptr[i])>1.e+8) 
00409     {
00410       if (ad_kill_flag) exit_flag=1;
00411       icount++;
00412       cout << i << " " << temp_ptr[i] << endl; 
00413       if (icount>10) 
00414       {
00415          break;
00416       }
00417     }
00418   }
00419 
00420   icount=0;
00421   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00422   {
00423     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00424       > 1.e+8) 
00425     {
00426       icount++;
00427        cout << "dlist " << i << " " << setscientific() <<
00428          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00429           << endl;
00430       if (icount>10) 
00431       {
00432         if (ad_kill_flag) exit_flag=1;
00433         break;
00434       }
00435     }
00436   }
00437   if (exit_flag) exit(1);
00438 }
00439 
00440 //extern  ofstream gradlog;
00441 
00446 void df_print_identifier_string(void)
00447 {
00448   adstring str=get_string_marker();
00449   cout << "GS = " << str << endl;
00450   //gradlog << "GS = " << str << endl;
00451 }
00452 
00457 void df_check_derivative_values_indexed(void)
00458 {
00459   //char label[20];
00460   int index=restore_int_value();
00461   adstring str=get_string_marker();
00462   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00463   unsigned long int max_last_offset = 
00464     gradient_structure::ARR_LIST1->get_max_last_offset();
00465      unsigned int size = sizeof(double_and_int );
00466 
00467   int icount=0;
00468   int exit_flag=0;
00469   cout << str << " index = " << index << endl;
00470   unsigned int i;
00471   for (i=0 ; i< (max_last_offset/size) ; i++ )
00472   {
00473     if (fabs(temp_ptr[i])>1.e+8) 
00474     {
00475       if (ad_kill_flag) exit_flag=1;
00476       icount++;
00477       cout << i << " " << setscientific() << temp_ptr[i] << endl; 
00478       if (icount>10) break;
00479     }
00480   }
00481 
00482   icount=0;
00483   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00484   {
00485     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00486       > 1.e+8) 
00487     {
00488       icount++;
00489       if (ad_kill_flag) exit_flag=1;
00490        cout << "dlist " << i << " " << setscientific() <<
00491          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00492           << endl;
00493       if (icount>10) 
00494       {
00495          break;
00496       }
00497     }
00498   }
00499   if (exit_flag) exit(1);
00500 }
00501 
00506 void df_check_derivative_values_indexed_break(void)
00507 {
00508   //char label[20];
00509   int b=restore_int_value();
00510   int index=restore_int_value();
00511   adstring str=get_string_marker();
00512   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00513   unsigned long int max_last_offset = 
00514     gradient_structure::ARR_LIST1->get_max_last_offset();
00515      unsigned int size = sizeof(double_and_int );
00516 
00517   if (index<=b)
00518   {
00519     cout << "break condition" << endl;
00520   }
00521   int icount=0;
00522   int exit_flag=0;
00523   cout << str << " index = " << index << endl;
00524   unsigned int i;
00525   for (i=0 ; i< (max_last_offset/size) ; i++ )
00526   {
00527     if (fabs(temp_ptr[i])>1.e+8) 
00528     {
00529       if (ad_kill_flag) exit_flag=1;
00530       icount++;
00531       cout << i << " " << temp_ptr[i] << endl; 
00532       if (icount>10) break;
00533     }
00534   }
00535 
00536   icount=0;
00537   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00538   {
00539     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00540       > 1.e+8) 
00541     {
00542       icount++;
00543       if (ad_kill_flag) exit_flag=1;
00544        cout << "dlist " << i << " " << 
00545          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00546           << endl;
00547       if (icount>10) 
00548       {
00549          break;
00550       }
00551     }
00552   }
00553   if (exit_flag) exit(1);
00554 }
00555 
00560 void arr_remove(arr_link ** pptr)
00561 {
00562   arr_link * tmp = *pptr;
00563   // This routine removes the link pointed to by tmp
00564   if (tmp->next)  // Make the one after it point to tmp->prev
00565   {
00566     tmp->next->prev = tmp->prev;
00567   }
00568 
00569   if (tmp->prev)  // Make the one before it point to tmp->next
00570   {
00571     tmp->prev->next = tmp->next;
00572   }
00573 
00574   if (tmp == NULL)
00575   {
00576     cout <<" Error -- tried to delete NULL arr_link in arr_remove\n";
00577     ad_exit(23);
00578   }
00579   else
00580   {
00581 #ifdef DIAG
00582 #ifdef __ZTC__
00583       cout <<"Deleting an arr_link with adress  "<<_farptr_tolong(tmp)<<"\n";
00584 #else
00585       cout <<"Deleting an arr_link with adress  "<<farptr_tolong(tmp)<<"\n";
00586 #endif
00587 #endif
00588     delete tmp;
00589     tmp=NULL;
00590   }
00591   gradient_structure::ARR_LIST1->number_arr_links -= 1;
00592   //cout <<  "after delete number_arr_links = "<<  gradient_structure::ARR_LIST1->number_arr_links <<"\n";
00593 }