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 }
|
|
Generated on Tue May 21 2013 12:31:52 for ADMB Documentation by 1.8.0
|