00001 /* 00002 * $Id$ 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 #ifndef OPT_LIB 00019 #include <cassert> 00020 #endif 00021 00022 int num_free_obj=0; 00023 int ad_kill_flag=0; 00024 00028 arr_link::arr_link() 00029 { 00030 prev = NULL; 00031 next = NULL; 00032 free_prev = NULL; 00033 free_next = NULL; 00034 status = 0; 00035 // free_list_status=0; 00036 size = 0; 00037 offset = 0; 00038 } 00039 00044 void arr_free_remove(arr_link * tmp) 00045 { 00046 num_free_obj--; 00047 // if this is the last free object reset list pointer 00048 if (!tmp->free_next) 00049 { 00050 gradient_structure::ARR_LIST1->free_last=tmp->free_prev; 00051 } 00052 // This routine removes the link pointed to by tmp 00053 if (tmp->free_next) // Make the one after it point to tmp->prev 00054 { 00055 tmp->free_next->free_prev = tmp->free_prev; 00056 } 00057 00058 if (tmp->free_prev) // Make the one before it point to tmp->next 00059 { 00060 tmp->free_prev->free_next = tmp->free_next; 00061 } 00062 } 00063 00068 void arr_free_add(arr_link * tmp) 00069 { 00070 num_free_obj++; 00071 // This routine adds the link pointed to by tmp to the end of the free list 00072 tmp->free_prev = gradient_structure::ARR_LIST1->free_last; 00073 gradient_structure::ARR_LIST1->free_last=tmp; 00074 tmp->free_next = NULL; 00075 if (tmp->free_prev) tmp->free_prev->free_next = tmp; 00076 } 00077 00082 double_and_int * arr_new(unsigned int sz) 00083 { 00084 if (!gradient_structure::instances) 00085 { 00086 cerr << "Error -- you are trying to create a dvar_vector object" 00087 " when there is " << endl << "no object of type" 00088 " gradient_structure in scope " << endl; 00089 ad_exit(1); 00090 } 00091 00092 char * temp_ptr; 00093 00094 // this routine allocated a block of memory of sizeof(double)*sz bytes 00095 // for the gradients of an array or matrix of prevariables 00096 00097 arr_link * tmp = gradient_structure::ARR_LIST1->free_last; 00098 00099 unsigned int bytes_needed = sz * (unsigned int)sizeof(double_and_int); 00100 00101 #ifdef DIAG 00102 int ss=0; 00103 if (ss) 00104 { 00105 double_and_int* tt=0; 00106 return tt; 00107 } 00108 #endif 00109 00110 while (tmp) 00111 { 00112 if (tmp->size >= bytes_needed) 00113 { 00114 // if the free block within 20 bytes of the size you want 00115 // simply mark it occupied and return it 00116 00117 if (tmp->size <= bytes_needed + 50) 00118 { 00119 tmp->status = 1; 00120 // remove tmp from the free list 00121 arr_free_remove(tmp); 00122 00123 temp_ptr = gradient_structure::ARRAY_MEMBLOCK_BASE + tmp->offset; 00124 00125 //put the address tmp into the location pointed to by temp_ptr 00126 (* (arr_link **) (temp_ptr)) = tmp; 00127 00128 return (double_and_int*)temp_ptr; 00129 } 00130 else 00131 { 00132 // otherwise split up this memory block and return 00133 // the part you need 00134 00135 arr_link* tmp1 = new arr_link; 00136 gradient_structure::ARR_LIST1->number_arr_links += 1; 00137 00138 // put the new link tmp1-> into the list BEFORE tmp-> 00139 00140 tmp1->prev=tmp->prev; 00141 00142 if(tmp1->prev) 00143 { 00144 tmp1->prev->next=tmp1; 00145 } 00146 00147 tmp1->next=tmp; 00148 tmp->prev=tmp1; 00149 00150 // get the size of the new link and mark it free 00151 00152 tmp1->size=bytes_needed; 00153 tmp1->status=1; 00154 tmp1->offset=tmp->offset; 00155 00156 tmp->offset+=bytes_needed; 00157 tmp->size-=bytes_needed; 00158 00159 temp_ptr = gradient_structure::ARRAY_MEMBLOCK_BASE + tmp1->offset; 00160 00161 //put the address pointed to by tmp1 into the location pointed to by temp_ptr 00162 (*(arr_link**)(temp_ptr)) = tmp1; 00163 00164 return (double_and_int*)temp_ptr; 00165 } 00166 } 00167 tmp=tmp->free_prev; 00168 } 00169 // couldn't find a free block large enough 00170 // make a new block 00171 00172 tmp = new arr_link; 00173 if (tmp==0) 00174 { 00175 cerr << "Error allocating new arr_link" << endl; 00176 ad_exit(1); 00177 } 00178 00179 gradient_structure::ARR_LIST1->number_arr_links += 1; 00180 00181 tmp->prev = gradient_structure::ARR_LIST1->last; // the new block point back 00182 // at the previous last block 00183 00184 if (gradient_structure::ARR_LIST1->last) 00185 { 00186 gradient_structure::ARR_LIST1->last->next = tmp; // the previous last 00187 // block point forward to tmp 00188 } 00189 gradient_structure::ARR_LIST1->last = tmp; // tmp is the new last block 00190 00191 tmp->next = 0; 00192 00193 tmp->status = 1; 00194 00195 tmp->offset = gradient_structure::ARR_LIST1->last_offset; 00196 00197 gradient_structure::ARR_LIST1->last_offset += bytes_needed; 00198 00199 if (gradient_structure::ARR_LIST1->last_offset> 00200 (unsigned int)gradient_structure::max_last_offset ) 00201 { 00202 gradient_structure::max_last_offset= 00203 gradient_structure::ARR_LIST1->last_offset; 00204 } 00205 00206 if (gradient_structure::ARR_LIST1->last_offset > 00207 gradient_structure::ARR_LIST1->max_last_offset) 00208 { 00209 gradient_structure::ARR_LIST1->max_last_offset = 00210 gradient_structure::ARR_LIST1->last_offset; 00211 } 00212 00213 if( gradient_structure::ARR_LIST1->last_offset >= 00214 gradient_structure::ARRAY_MEMBLOCK_SIZE) 00215 { 00216 cout << gradient_structure::ARR_LIST1->last_offset <<">=" 00217 << gradient_structure::ARRAY_MEMBLOCK_SIZE <<"\n"; 00218 cout << " No memory for dvar_vectors\n" 00219 << " Need to increase ARRAY_MEMBLOCK_SIZE parameter\n" 00220 "In gradient_structure declaration\n"; 00221 //throw gradient_structure::arrmemblerr(); 00222 ad_exit(1); 00223 } 00224 00225 tmp->size = bytes_needed; 00226 00227 temp_ptr = gradient_structure::ARRAY_MEMBLOCK_BASE + tmp->offset; 00228 00229 (*(arr_link **) (temp_ptr )) = tmp; //put the address 00230 // tmp into the location pointed to 00231 //by temp_ptr 00232 00233 // return (double_and_int *) (temp_ptr+sizeof(double_and_int)); 00234 return (double_and_int *) (temp_ptr); 00235 } 00236 00241 void arr_free(double_and_int * varr) 00242 { 00243 // This routines frees up a memory block and 00244 // consolidates the free blocks if possible 00245 //cout<< "calling arr_free\n"; 00246 char * temp_ptr; 00247 arr_link * ptr; 00248 00249 temp_ptr = (char *) varr; 00250 00251 //temp=sizeof(double_and_int); 00252 // ptr = *(arr_link **) (temp_ptr-temp); 00253 ptr = *(arr_link **) (temp_ptr); 00254 00255 //mark this block free 00256 00257 ptr->status = 0; 00258 // cout <<"Marking arr_link with adress "<<farptr_tolong(ptr)<<"free\n"; 00259 00260 // if there is a block after this add this one to the free list 00261 if (ptr->next) arr_free_add(ptr); 00262 00263 if (!ptr->next) // Is this the last link? 00264 { 00265 // Check to see if ptr->prev is free and should be deleted as well 00266 // ... but first check to see if ptr is first block in list 00267 // which will be indicated by ptr->prev being a NULL pointer 00268 if (ptr->prev && !ptr->prev->status) 00269 { 00270 // delete ptr->prev 00271 gradient_structure::ARR_LIST1->last = ptr->prev->prev; 00272 //if (gradient_structure::ARR_LIST1->last ==0) 00273 // cout << "gradient_structure::ARR_LIST1->last =0 " << endl; 00274 00275 gradient_structure::ARR_LIST1->last_offset -= ptr->size + ptr->prev->size; 00276 arr_free_remove(ptr->prev); 00277 arr_remove(&(ptr->prev)); 00278 } 00279 else 00280 { 00281 gradient_structure::ARR_LIST1->last = ptr->prev; 00282 //if (gradient_structure::ARR_LIST1->last ==0) 00283 // cout << "gradient_structure::ARR_LIST1->last =0 " << endl; 00284 gradient_structure::ARR_LIST1->last_offset -= ptr->size; 00285 } 00286 arr_remove(&ptr); 00287 } 00288 else 00289 { 00290 // There is another link after this one? 00291 00292 if (!ptr->next->status) // If yes is it free? 00293 { 00294 // add its memory capacity to the present one and delete it 00295 00296 ptr->size += ptr->next->size; 00297 00298 arr_free_remove(ptr->next); 00299 arr_remove(&ptr->next); 00300 } 00301 00302 if (ptr->prev) // Is there another link before this one? 00303 { 00304 if (!ptr->prev->status) // If yes is it free? 00305 { 00306 // we will keep ptr->prev and add ptr to it 00307 00308 ptr->prev->size += ptr->size; 00309 arr_free_remove(ptr); 00310 arr_remove(&ptr); 00311 } 00312 } 00313 } 00314 } 00315 00320 void check_derivative_values(const char * _s) 00321 { 00322 char * s = (char *) _s; 00323 //char label[20]; 00324 save_identifier_string(s); 00325 gradient_structure::GRAD_STACK1-> 00326 set_gradient_stack(df_check_derivative_values); 00327 } 00328 00333 void check_derivative_values(const char * _s,int i) 00334 { 00335 char * s = (char *) _s; 00336 //char label[20]; 00337 save_identifier_string(s); 00338 save_int_value(i); 00339 gradient_structure::GRAD_STACK1-> 00340 set_gradient_stack(df_check_derivative_values_indexed); 00341 } 00342 00343 void df_print_identifier_string(void); 00344 00349 void insert_identifier_string(const char * _s) 00350 { 00351 char * s = (char *) _s; 00352 save_identifier_string(s); 00353 gradient_structure::GRAD_STACK1-> 00354 set_gradient_stack(df_print_identifier_string); 00355 } 00356 00361 void check_derivative_values_break(const char * _s,int i,int b) 00362 { 00363 char * s = (char *) _s; 00364 //char label[20]; 00365 save_identifier_string(s); 00366 save_int_value(i); 00367 save_int_value(b); 00368 gradient_structure::GRAD_STACK1-> 00369 set_gradient_stack(df_check_derivative_values_indexed_break); 00370 } 00371 00376 void df_check_derivative_values(void) 00377 { 00378 //char label[20]; 00379 adstring str=get_string_marker(); 00380 double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE(); 00381 unsigned long int max_last_offset = 00382 gradient_structure::ARR_LIST1->get_max_last_offset(); 00383 size_t size = sizeof(double_and_int); 00384 00385 int icount=0; 00386 int exit_flag=0; 00387 cout << str << endl; 00388 unsigned int i; 00389 for (i=0 ; i< (max_last_offset/size) ; i++ ) 00390 { 00391 if (fabs(temp_ptr[i])>1.e+8) 00392 { 00393 if (ad_kill_flag) exit_flag=1; 00394 icount++; 00395 cout << i << " " << temp_ptr[i] << endl; 00396 if (icount>10) 00397 { 00398 break; 00399 } 00400 } 00401 } 00402 00403 icount=0; 00404 for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++) 00405 { 00406 if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i]) 00407 > 1.e+8) 00408 { 00409 icount++; 00410 cout << "dlist " << i << " " << setscientific() << 00411 * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i]) 00412 << endl; 00413 if (icount>10) 00414 { 00415 if (ad_kill_flag) exit_flag=1; 00416 break; 00417 } 00418 } 00419 } 00420 if (exit_flag) exit(1); 00421 } 00422 00423 //extern ofstream gradlog; 00424 00429 void df_print_identifier_string(void) 00430 { 00431 adstring str=get_string_marker(); 00432 cout << "GS = " << str << endl; 00433 //gradlog << "GS = " << str << endl; 00434 } 00435 00440 void df_check_derivative_values_indexed(void) 00441 { 00442 //char label[20]; 00443 int index=restore_int_value(); 00444 adstring str=get_string_marker(); 00445 double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE(); 00446 unsigned long int max_last_offset = 00447 gradient_structure::ARR_LIST1->get_max_last_offset(); 00448 size_t size = sizeof(double_and_int); 00449 00450 int icount=0; 00451 int exit_flag=0; 00452 cout << str << " index = " << index << endl; 00453 unsigned int i; 00454 for (i=0 ; i< (max_last_offset/size) ; i++ ) 00455 { 00456 if (fabs(temp_ptr[i])>1.e+8) 00457 { 00458 if (ad_kill_flag) exit_flag=1; 00459 icount++; 00460 cout << i << " " << setscientific() << temp_ptr[i] << endl; 00461 if (icount>10) break; 00462 } 00463 } 00464 00465 icount=0; 00466 for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++) 00467 { 00468 if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i]) 00469 > 1.e+8) 00470 { 00471 icount++; 00472 if (ad_kill_flag) exit_flag=1; 00473 cout << "dlist " << i << " " << setscientific() << 00474 * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i]) 00475 << endl; 00476 if (icount>10) 00477 { 00478 break; 00479 } 00480 } 00481 } 00482 if (exit_flag) exit(1); 00483 } 00484 00489 void df_check_derivative_values_indexed_break(void) 00490 { 00491 //char label[20]; 00492 int b=restore_int_value(); 00493 int index=restore_int_value(); 00494 adstring str=get_string_marker(); 00495 double * temp_ptr = gradient_structure::get_ARRAY_MEMBLOCK_BASE(); 00496 unsigned long int max_last_offset = 00497 gradient_structure::ARR_LIST1->get_max_last_offset(); 00498 size_t size = sizeof(double_and_int); 00499 00500 if (index<=b) 00501 { 00502 cout << "break condition" << endl; 00503 } 00504 int icount=0; 00505 int exit_flag=0; 00506 cout << str << " index = " << index << endl; 00507 unsigned int i; 00508 for (i=0 ; i< (max_last_offset/size) ; i++ ) 00509 { 00510 if (fabs(temp_ptr[i])>1.e+8) 00511 { 00512 if (ad_kill_flag) exit_flag=1; 00513 icount++; 00514 cout << i << " " << temp_ptr[i] << endl; 00515 if (icount>10) break; 00516 } 00517 } 00518 00519 icount=0; 00520 for (i=0; i<gradient_structure::GRAD_LIST->nlinks; i++) 00521 { 00522 if (* (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i]) 00523 > 1.e+8) 00524 { 00525 icount++; 00526 if (ad_kill_flag) exit_flag=1; 00527 cout << "dlist " << i << " " << 00528 * (double*) (gradient_structure::GRAD_LIST->dlink_addresses[i]) 00529 << endl; 00530 if (icount>10) 00531 { 00532 break; 00533 } 00534 } 00535 } 00536 if (exit_flag) exit(1); 00537 } 00538 00542 void arr_remove(arr_link** pptr) 00543 { 00544 #ifndef OPT_LIB 00545 assert(pptr != NULL); 00546 #endif 00547 00548 arr_link* tmp = *pptr; 00549 00550 if (tmp == NULL) 00551 { 00552 cout <<" Error -- tried to delete NULL arr_link in arr_remove\n"; 00553 ad_exit(23); 00554 } 00555 else 00556 { 00557 // This routine removes the link pointed to by tmp 00558 if (tmp->next) // Make the one after it point to tmp->prev 00559 { 00560 tmp->next->prev = tmp->prev; 00561 } 00562 if (tmp->prev) // Make the one before it point to tmp->next 00563 { 00564 tmp->prev->next = tmp->next; 00565 } 00566 00567 #ifdef DIAG 00568 cout << "Deleting an arr_link with adress " 00569 #ifdef __ZTC__ 00570 << _farptr_tolong(tmp) 00571 #else 00572 << farptr_tolong(tmp) 00573 #endif 00574 << "\n"; 00575 #endif 00576 00577 delete tmp; 00578 tmp = NULL; 00579 } 00580 gradient_structure::ARR_LIST1->number_arr_links -= 1; 00581 //cout << "after delete number_arr_links = " 00582 //<< gradient_structure::ARR_LIST1->number_arr_links <<"\n"; 00583 }
Generated on Tue Mar 8 2016 19:51:35 for ADMB Documentation by 1.8.0 |