ADMB Documentation  11.1.2192
 All Classes Files Functions Variables Typedefs Friends Defines
newdar.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: newdar.cpp 1716 2014-03-03 20:34:53Z 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         //put the address tmp into the location pointed to by temp_ptr
00128         (* (arr_link **) (temp_ptr)) = tmp;
00129 
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    //put the address pointed to by tmp1 into the location pointed to by temp_ptr
00164         (*(arr_link**)(temp_ptr)) = tmp1;
00165 
00166         return (double_and_int*)temp_ptr;
00167       }
00168     }
00169     tmp=tmp->free_prev;
00170   }
00171   // couldn't find a free block large enough
00172   // make a new block
00173 
00174   tmp = new arr_link;
00175   if (tmp==0)
00176   {
00177     cerr << "Error allocating new arr_link" << endl;
00178     ad_exit(1);
00179   }
00180 
00181   gradient_structure::ARR_LIST1->number_arr_links  += 1;
00182 
00183   tmp->prev = gradient_structure::ARR_LIST1->last; // the new block point back
00184                                                  // at the previous last block
00185 
00186   if (gradient_structure::ARR_LIST1->last)
00187   {
00188     gradient_structure::ARR_LIST1->last->next = tmp; // the previous last
00189                                                   // block point forward to tmp
00190   }
00191   gradient_structure::ARR_LIST1->last = tmp;        // tmp is the new last block
00192 
00193   tmp->next = 0;
00194 
00195   tmp->status = 1;
00196 
00197   tmp->offset = gradient_structure::ARR_LIST1->last_offset;
00198 
00199   gradient_structure::ARR_LIST1->last_offset += bytes_needed;
00200 
00201   if (gradient_structure::ARR_LIST1->last_offset>
00202     (unsigned int)gradient_structure::max_last_offset )
00203   {
00204     gradient_structure::max_last_offset=
00205       gradient_structure::ARR_LIST1->last_offset;
00206   }
00207 
00208   if (gradient_structure::ARR_LIST1->last_offset >
00209     gradient_structure::ARR_LIST1->max_last_offset)
00210   {
00211     gradient_structure::ARR_LIST1->max_last_offset =
00212      gradient_structure::ARR_LIST1->last_offset;
00213   }
00214 
00215   if( gradient_structure::ARR_LIST1->last_offset >=
00216     gradient_structure::ARRAY_MEMBLOCK_SIZE)
00217   {
00218     cout << gradient_structure::ARR_LIST1->last_offset <<">="
00219          <<  gradient_structure::ARRAY_MEMBLOCK_SIZE <<"\n";
00220     cout << " No memory for dvar_vectors\n"
00221          << " Need to increase ARRAY_MEMBLOCK_SIZE parameter\n"
00222       "In gradient_structure declaration\n";
00223     //throw gradient_structure::arrmemblerr();
00224     ad_exit(1);
00225   }
00226 
00227   tmp->size = bytes_needed;
00228 
00229   temp_ptr = gradient_structure::ARRAY_MEMBLOCK_BASE + tmp->offset;
00230 
00231   (*(arr_link **) (temp_ptr )) = tmp; //put the address
00232                                    // tmp into the location pointed to
00233                                    //by temp_ptr
00234 
00235 //  return  (double_and_int *) (temp_ptr+sizeof(double_and_int));
00236   return  (double_and_int *) (temp_ptr);
00237 }
00238 
00243 void arr_free(double_and_int * varr)
00244 {
00245   // This routines frees up a memory block and
00246   // consolidates the free blocks if possible
00247   //cout<< "calling arr_free\n";
00248   char * temp_ptr;
00249   arr_link * ptr;
00250 
00251   temp_ptr = (char *) varr;
00252 
00253   //temp=sizeof(double_and_int);
00254 //  ptr = *(arr_link **) (temp_ptr-temp);
00255   ptr = *(arr_link **) (temp_ptr);
00256 
00257   //mark this block free
00258 
00259   ptr->status = 0;
00260  // cout <<"Marking arr_link with adress  "<<farptr_tolong(ptr)<<"free\n";
00261 
00262   // if there is a block after this add this one to the free list
00263   if (ptr->next) arr_free_add(ptr);
00264 
00265   if (!ptr->next)  // Is this the last link?
00266   {
00267     // Check to see if ptr->prev is free and should be deleted as well
00268     // ... but first check to see if ptr is first block in list
00269     // which will be indicated by ptr->prev being a NULL pointer
00270     if (ptr->prev && !ptr->prev->status)
00271     {
00272       // delete ptr->prev
00273       gradient_structure::ARR_LIST1->last = ptr->prev->prev;
00274       //if (gradient_structure::ARR_LIST1->last ==0)
00275        // cout << "gradient_structure::ARR_LIST1->last =0 " << endl;
00276 
00277       gradient_structure::ARR_LIST1->last_offset -= ptr->size + ptr->prev->size;
00278       arr_free_remove(ptr->prev);
00279       arr_remove(&(ptr->prev));
00280     }
00281     else
00282     {
00283       gradient_structure::ARR_LIST1->last = ptr->prev;
00284       //if (gradient_structure::ARR_LIST1->last ==0)
00285        // cout << "gradient_structure::ARR_LIST1->last =0 " << endl;
00286       gradient_structure::ARR_LIST1->last_offset -= ptr->size;
00287     }
00288     arr_remove(&ptr);
00289   }
00290   else
00291   {
00292      // There is another link after this one?
00293 
00294     if (!ptr->next->status) // If yes is it free?
00295     {
00296       // add its memory capacity to the present one and delete it
00297 
00298       ptr->size += ptr->next->size;
00299 
00300       arr_free_remove(ptr->next);
00301       arr_remove(&ptr->next);
00302     }
00303 
00304     if (ptr->prev)  // Is there another link before this one?
00305     {
00306       if (!ptr->prev->status) // If yes is it free?
00307       {
00308         // we will keep ptr->prev and add ptr to it
00309 
00310         ptr->prev->size += ptr->size;
00311         arr_free_remove(ptr);
00312         arr_remove(&ptr);
00313       }
00314     }
00315   }
00316 }
00317 
00322 void check_derivative_values(const char * _s)
00323 {
00324   char * s = (char *) _s;
00325   //char label[20];
00326   save_identifier_string(s);
00327   gradient_structure::GRAD_STACK1->
00328     set_gradient_stack(df_check_derivative_values);
00329 }
00330 
00335 void check_derivative_values(const char * _s,int i)
00336 {
00337   char * s = (char *) _s;
00338   //char label[20];
00339   save_identifier_string(s);
00340   save_int_value(i);
00341   gradient_structure::GRAD_STACK1->
00342     set_gradient_stack(df_check_derivative_values_indexed);
00343 }
00344 
00345 void df_print_identifier_string(void);
00346 
00351 void insert_identifier_string(const char * _s)
00352 {
00353   char * s = (char *) _s;
00354   save_identifier_string(s);
00355   gradient_structure::GRAD_STACK1->
00356     set_gradient_stack(df_print_identifier_string);
00357 }
00358 
00363 void check_derivative_values_break(const char * _s,int i,int b)
00364 {
00365   char * s = (char *) _s;
00366   //char label[20];
00367   save_identifier_string(s);
00368   save_int_value(i);
00369   save_int_value(b);
00370   gradient_structure::GRAD_STACK1->
00371     set_gradient_stack(df_check_derivative_values_indexed_break);
00372 }
00373 
00374 void  rrkludge(double * temp_ptr){;}
00375 
00380 void df_check_derivative_values(void)
00381 {
00382   //char label[20];
00383   adstring str=get_string_marker();
00384   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00385   unsigned long int max_last_offset =
00386     gradient_structure::ARR_LIST1->get_max_last_offset();
00387      unsigned int size = sizeof(double_and_int );
00388 
00389   int icount=0;
00390   int exit_flag=0;
00391   cout << str << endl;
00392   unsigned int i;
00393   for (i=0 ; i< (max_last_offset/size) ; i++ )
00394   {
00395     if (fabs(temp_ptr[i])>1.e+8)
00396     {
00397       if (ad_kill_flag) exit_flag=1;
00398       icount++;
00399       cout << i << " " << temp_ptr[i] << endl;
00400       if (icount>10)
00401       {
00402          break;
00403       }
00404     }
00405   }
00406 
00407   icount=0;
00408   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00409   {
00410     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00411       > 1.e+8)
00412     {
00413       icount++;
00414        cout << "dlist " << i << " " << setscientific() <<
00415          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00416           << endl;
00417       if (icount>10)
00418       {
00419         if (ad_kill_flag) exit_flag=1;
00420         break;
00421       }
00422     }
00423   }
00424   if (exit_flag) exit(1);
00425 }
00426 
00427 //extern  ofstream gradlog;
00428 
00433 void df_print_identifier_string(void)
00434 {
00435   adstring str=get_string_marker();
00436   cout << "GS = " << str << endl;
00437   //gradlog << "GS = " << str << endl;
00438 }
00439 
00444 void df_check_derivative_values_indexed(void)
00445 {
00446   //char label[20];
00447   int index=restore_int_value();
00448   adstring str=get_string_marker();
00449   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00450   unsigned long int max_last_offset =
00451     gradient_structure::ARR_LIST1->get_max_last_offset();
00452      unsigned int size = sizeof(double_and_int );
00453 
00454   int icount=0;
00455   int exit_flag=0;
00456   cout << str << " index = " << index << endl;
00457   unsigned int i;
00458   for (i=0 ; i< (max_last_offset/size) ; i++ )
00459   {
00460     if (fabs(temp_ptr[i])>1.e+8)
00461     {
00462       if (ad_kill_flag) exit_flag=1;
00463       icount++;
00464       cout << i << " " << setscientific() << temp_ptr[i] << endl;
00465       if (icount>10) break;
00466     }
00467   }
00468 
00469   icount=0;
00470   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00471   {
00472     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00473       > 1.e+8)
00474     {
00475       icount++;
00476       if (ad_kill_flag) exit_flag=1;
00477        cout << "dlist " << i << " " << setscientific() <<
00478          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00479           << endl;
00480       if (icount>10)
00481       {
00482          break;
00483       }
00484     }
00485   }
00486   if (exit_flag) exit(1);
00487 }
00488 
00493 void df_check_derivative_values_indexed_break(void)
00494 {
00495   //char label[20];
00496   int b=restore_int_value();
00497   int index=restore_int_value();
00498   adstring str=get_string_marker();
00499   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00500   unsigned long int max_last_offset =
00501     gradient_structure::ARR_LIST1->get_max_last_offset();
00502      unsigned int size = sizeof(double_and_int );
00503 
00504   if (index<=b)
00505   {
00506     cout << "break condition" << endl;
00507   }
00508   int icount=0;
00509   int exit_flag=0;
00510   cout << str << " index = " << index << endl;
00511   unsigned int i;
00512   for (i=0 ; i< (max_last_offset/size) ; i++ )
00513   {
00514     if (fabs(temp_ptr[i])>1.e+8)
00515     {
00516       if (ad_kill_flag) exit_flag=1;
00517       icount++;
00518       cout << i << " " << temp_ptr[i] << endl;
00519       if (icount>10) break;
00520     }
00521   }
00522 
00523   icount=0;
00524   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00525   {
00526     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00527       > 1.e+8)
00528     {
00529       icount++;
00530       if (ad_kill_flag) exit_flag=1;
00531        cout << "dlist " << i << " " <<
00532          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00533           << endl;
00534       if (icount>10)
00535       {
00536          break;
00537       }
00538     }
00539   }
00540   if (exit_flag) exit(1);
00541 }
00542 
00547 void arr_remove(arr_link ** pptr)
00548 {
00549   arr_link * tmp = *pptr;
00550   // This routine removes the link pointed to by tmp
00551   if (tmp->next)  // Make the one after it point to tmp->prev
00552   {
00553     tmp->next->prev = tmp->prev;
00554   }
00555 
00556   if (tmp->prev)  // Make the one before it point to tmp->next
00557   {
00558     tmp->prev->next = tmp->next;
00559   }
00560 
00561   if (tmp == NULL)
00562   {
00563     cout <<" Error -- tried to delete NULL arr_link in arr_remove\n";
00564     ad_exit(23);
00565   }
00566   else
00567   {
00568 #ifdef DIAG
00569 #ifdef __ZTC__
00570       cout <<"Deleting an arr_link with adress  "<<_farptr_tolong(tmp)<<"\n";
00571 #else
00572       cout <<"Deleting an arr_link with adress  "<<farptr_tolong(tmp)<<"\n";
00573 #endif
00574 #endif
00575     delete tmp;
00576     tmp=NULL;
00577   }
00578   gradient_structure::ARR_LIST1->number_arr_links -= 1;
00579   //cout <<  "after delete number_arr_links = "
00580   //<<  gradient_structure::ARR_LIST1->number_arr_links <<"\n";
00581 }