ADMB Documentation  11.1.2532
 All Classes Files Functions Variables Typedefs Friends Defines
newdar.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: newdar.cpp 2252 2014-08-27 17:49:26Z 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 
00378 void df_check_derivative_values(void)
00379 {
00380   //char label[20];
00381   adstring str=get_string_marker();
00382   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00383   unsigned long int max_last_offset =
00384     gradient_structure::ARR_LIST1->get_max_last_offset();
00385      unsigned int size = sizeof(double_and_int );
00386 
00387   int icount=0;
00388   int exit_flag=0;
00389   cout << str << endl;
00390   unsigned int i;
00391   for (i=0 ; i< (max_last_offset/size) ; i++ )
00392   {
00393     if (fabs(temp_ptr[i])>1.e+8)
00394     {
00395       if (ad_kill_flag) exit_flag=1;
00396       icount++;
00397       cout << i << " " << temp_ptr[i] << endl;
00398       if (icount>10)
00399       {
00400          break;
00401       }
00402     }
00403   }
00404 
00405   icount=0;
00406   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00407   {
00408     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00409       > 1.e+8)
00410     {
00411       icount++;
00412        cout << "dlist " << i << " " << setscientific() <<
00413          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00414           << endl;
00415       if (icount>10)
00416       {
00417         if (ad_kill_flag) exit_flag=1;
00418         break;
00419       }
00420     }
00421   }
00422   if (exit_flag) exit(1);
00423 }
00424 
00425 //extern  ofstream gradlog;
00426 
00431 void df_print_identifier_string(void)
00432 {
00433   adstring str=get_string_marker();
00434   cout << "GS = " << str << endl;
00435   //gradlog << "GS = " << str << endl;
00436 }
00437 
00442 void df_check_derivative_values_indexed(void)
00443 {
00444   //char label[20];
00445   int index=restore_int_value();
00446   adstring str=get_string_marker();
00447   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00448   unsigned long int max_last_offset =
00449     gradient_structure::ARR_LIST1->get_max_last_offset();
00450      unsigned int size = sizeof(double_and_int );
00451 
00452   int icount=0;
00453   int exit_flag=0;
00454   cout << str << " index = " << index << endl;
00455   unsigned int i;
00456   for (i=0 ; i< (max_last_offset/size) ; i++ )
00457   {
00458     if (fabs(temp_ptr[i])>1.e+8)
00459     {
00460       if (ad_kill_flag) exit_flag=1;
00461       icount++;
00462       cout << i << " " << setscientific() << temp_ptr[i] << endl;
00463       if (icount>10) break;
00464     }
00465   }
00466 
00467   icount=0;
00468   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00469   {
00470     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00471       > 1.e+8)
00472     {
00473       icount++;
00474       if (ad_kill_flag) exit_flag=1;
00475        cout << "dlist " << i << " " << setscientific() <<
00476          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00477           << endl;
00478       if (icount>10)
00479       {
00480          break;
00481       }
00482     }
00483   }
00484   if (exit_flag) exit(1);
00485 }
00486 
00491 void df_check_derivative_values_indexed_break(void)
00492 {
00493   //char label[20];
00494   int b=restore_int_value();
00495   int index=restore_int_value();
00496   adstring str=get_string_marker();
00497   double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE();
00498   unsigned long int max_last_offset =
00499     gradient_structure::ARR_LIST1->get_max_last_offset();
00500      unsigned int size = sizeof(double_and_int );
00501 
00502   if (index<=b)
00503   {
00504     cout << "break condition" << endl;
00505   }
00506   int icount=0;
00507   int exit_flag=0;
00508   cout << str << " index = " << index << endl;
00509   unsigned int i;
00510   for (i=0 ; i< (max_last_offset/size) ; i++ )
00511   {
00512     if (fabs(temp_ptr[i])>1.e+8)
00513     {
00514       if (ad_kill_flag) exit_flag=1;
00515       icount++;
00516       cout << i << " " << temp_ptr[i] << endl;
00517       if (icount>10) break;
00518     }
00519   }
00520 
00521   icount=0;
00522   for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++)
00523   {
00524     if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00525       > 1.e+8)
00526     {
00527       icount++;
00528       if (ad_kill_flag) exit_flag=1;
00529        cout << "dlist " << i << " " <<
00530          * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i])
00531           << endl;
00532       if (icount>10)
00533       {
00534          break;
00535       }
00536     }
00537   }
00538   if (exit_flag) exit(1);
00539 }
00540 
00545 void arr_remove(arr_link ** pptr)
00546 {
00547   arr_link * tmp = *pptr;
00548   // This routine removes the link pointed to by tmp
00549   if (tmp->next)  // Make the one after it point to tmp->prev
00550   {
00551     tmp->next->prev = tmp->prev;
00552   }
00553 
00554   if (tmp->prev)  // Make the one before it point to tmp->next
00555   {
00556     tmp->prev->next = tmp->next;
00557   }
00558 
00559   if (tmp == NULL)
00560   {
00561     cout <<" Error -- tried to delete NULL arr_link in arr_remove\n";
00562     ad_exit(23);
00563   }
00564   else
00565   {
00566 #ifdef DIAG
00567 #ifdef __ZTC__
00568       cout <<"Deleting an arr_link with adress  "<<_farptr_tolong(tmp)<<"\n";
00569 #else
00570       cout <<"Deleting an arr_link with adress  "<<farptr_tolong(tmp)<<"\n";
00571 #endif
00572 #endif
00573     delete tmp;
00574     tmp=NULL;
00575   }
00576   gradient_structure::ARR_LIST1->number_arr_links -= 1;
00577   //cout <<  "after delete number_arr_links = "
00578   //<<  gradient_structure::ARR_LIST1->number_arr_links <<"\n";
00579 }