00001
00007 # include <df1b2fun.h>
00008 # include <admodel.h>
00009
00010 #include <signal.h>
00011 #ifdef __MINGW64__
00012 #include <cassert>
00013 #endif
00014
00015 #if defined(_MSC_VER)
00016 void strip_full_path(const adstring& _s)
00017 {
00018 adstring& s = (adstring&)_s;
00019 size_t n = s.size();
00020 size_t i = n - 1;
00021 for (; i >= 1; i--)
00022 {
00023 if ( s(i) == '\\' || s(i) == '/' || s(i) == ':') break;
00024 }
00025 s = s(i + 1, n);
00026 }
00027 #endif
00028
00029 void set_signal_handlers(void)
00030 {
00031 signal(SIGFPE,exit_handler);
00032 signal(SIGSEGV,exit_handler);
00033 signal(SIGILL,exit_handler);
00034 signal(SIGINT,exit_handler);
00035 }
00036
00037 ad_comm::ad_comm(int _argc,char * _argv[])
00038 {
00039 if (option_match(_argc,_argv,"-version") > -1
00040 || option_match(_argc,_argv,"--version") > -1)
00041 {
00042 void banner(const adstring& program_name);
00043 banner(_argv[0]);
00044
00045 exit(0);
00046 }
00047
00048 ad_comm::argc=_argc;
00049 ad_comm::argv=_argv;
00050 if (option_match(_argc,_argv,"-time")>-1)
00051 {
00052 time_flag=1;
00053 }
00054 else
00055 {
00056 time_flag=0;
00057 }
00058 if (time_flag)
00059 {
00060 if (!ptm)
00061 {
00062 ptm=new adtimer();
00063 }
00064 if (!ptm1)
00065 {
00066 ptm1=new adtimer();
00067 }
00068 }
00069 no_atlas_flag=0;
00070 if (option_match(_argc,_argv,"-noatlas")>-1) no_atlas_flag=1;
00071
00072 #if defined(USE_ADPVM)
00073 int pvm_flag=0;
00074 if (option_match(_argc,_argv,"-slave")>-1) pvm_flag=2;
00075 if (option_match(_argc,_argv,"-master")>-1) pvm_flag=1;
00076
00077 if (pvm_flag)
00078 pvm_manager = new adpvm_manager(pvm_flag);
00079 else
00080 pvm_manager = NULL;
00081
00082 if (pvm_manager)
00083 {
00084 if (pvm_manager->mode==2)
00085 {
00086 int on=0; int nopt=0;
00087 if ( (on=option_match(_argc,_argv,"-slave",nopt))>-1)
00088 {
00089 if (nopt ==1)
00090 {
00091 pvm_manager->slave_number=atoi(ad_comm::argv[on+1]);
00092 }
00093 else
00094 {
00095 cerr << "Wrong number of options to -slave -- must be 1"
00096 " you have " << nopt << endl;
00097 ad_exit(1);
00098 }
00099 }
00100 if ( (on=option_match(_argc,_argv,"-slavedir",nopt))>-1)
00101 {
00102 if (nopt ==1)
00103 {
00104 ad_chdir(_argv[on+1]);
00105 }
00106 else
00107 {
00108 cerr << "Wrong number of options to -slavedir -- must be 1"
00109 " you have " << nopt << endl;
00110 }
00111 }
00112 }
00113 }
00114 #endif
00115
00116
00117
00118
00119
00120
00121
00122
00123 set_signal_handlers();
00124 adprogram_name=_argv[0];
00125
00126
00127 #if defined(_MSC_VER)
00128 strip_full_path(adprogram_name);
00129 #endif
00130 adstring workdir;
00131 ad_getcd(workdir);
00132 if (_argc>1)
00133 {
00134 if (option_match(_argc,_argv,"-?")>-1
00135 || option_match(_argc,_argv,"-help")>-1
00136 || option_match(_argc,_argv,"--help")>-1)
00137 {
00138
00139 for (size_t i = adprogram_name.size(); i >= 1; i--)
00140 {
00141 #ifdef _WIN32
00142 if (adprogram_name(i) == '\\')
00143 #else
00144 if (adprogram_name(i) == '/')
00145 #endif
00146 {
00147 adprogram_name=adprogram_name(i+1,adprogram_name.size());
00148 break;
00149 }
00150 }
00151
00152
00153 (*ad_printf)( "Usage: %s [options]\n\n",(char*)(adprogram_name));
00154
00155 (*ad_printf)( "Options:\n");
00156 (*ad_printf)( " -ainp FILE change default ascii input parameter "
00157 "filename to FILE\n");
00158 (*ad_printf)( " -binp FILE change default binary input parameter "
00159 "filename to FILE\n");
00160 (*ad_printf)( " -est only do the parameter estimation\n");
00161 (*ad_printf)( " -noest do not do the parameter estimation "
00162 "(optimization) \n");
00163 (*ad_printf)( " -ind FILE change default input data filename to "
00164 "FILE\n");
00165 (*ad_printf)( " -lmn N use limited memory quasi newton -- keep "
00166 "N steps\n");
00167 (*ad_printf)( " -lmn2 N use other limited memory quasi newton -- "
00168 "keep N steps\n");
00169 (*ad_printf)( " -ilmn N use other limited memory quasi newton "
00170 "for random effects models - keep N steps\n");
00171 (*ad_printf)( " -dd N check derivatives after N function "
00172 "evaluations\n");
00173 (*ad_printf)( " -lprof perform profile likelihood "
00174 "calculations\n");
00175 (*ad_printf)( " -maxph N increase the maximum phase number to "
00176 "N\n");
00177 (*ad_printf)( " -mcdiag use diagonal covariance matrix for mcmc "
00178 "with diagonal values 1\n");
00179 (*ad_printf)( " -mcmc [N] perform markov chain monte carlo with N "
00180 "simulations\n");
00181 (*ad_printf)( " -mcmult N multiplier N for mcmc default\n");
00182 (*ad_printf)( " -mcr resume previous mcmc\n");
00183 (*ad_printf)( " -mcrb N reduce amount of correlation in the "
00184 "covariance matrix 1<=N<=9\n");
00185 (*ad_printf)( " -mcnoscale don't rescale step size for mcmc "
00186 "depending on acceptance rate\n");
00187 (*ad_printf)( " -nosdmcmc turn off mcmc histogram calcs to make "
00188 "mcsave run faster\n");
00189 (*ad_printf)( " -mcprobe N use probing strategy for mcmc with "
00190 "factor N\n");
00191 (*ad_printf)( " -mcgrope N Deprecated, same as -mcprobe\n");
00192 (*ad_printf)( " -mcseed N seed for random number generator for "
00193 "markov chain monte carlo\n");
00194 (*ad_printf)( " -mcscale N rescale step size for first N "
00195 "evaluations\n");
00196 (*ad_printf)( " -mcsave N save the parameters for every Nth "
00197 "simulation\n");
00198 (*ad_printf)( " -mceval go through the saved mcmc values from a "
00199 "previous mcsave\n");
00200 (*ad_printf)( " -mcu use uniformaly distributed steps for "
00201 "mcmc instead of random normal\n");
00202 (*ad_printf)( " -crit N1,N2,... set gradient magnitude convergence "
00203 "criterion to N\n");
00204 (*ad_printf)( " -iprint N print out function minimizer report "
00205 "every N iterations\n");
00206 (*ad_printf)( " -maxfn N1,N2,.. set maximum number opf function eval's "
00207 "to N\n");
00208 (*ad_printf)( " -rs if function minimizer can't make "
00209 "progress rescale and try again\n");
00210
00211
00212 (*ad_printf)( " -nox suppress vector and gradient values in "
00213 "minimizer screen report\n");
00214 (*ad_printf)( " -phase N start minimization in phase N\n");
00215 (*ad_printf)( " -simplex use simplex for minimization -- "
00216 "deprecated, use -neldmead\n");
00217 (*ad_printf)( " -neldmead use Nelder-Mead simplex algorithm for "
00218 "minimization\n");
00219 (*ad_printf)( " -nohess don't do hessian or delta method for std "
00220 "dev\n");
00221 (*ad_printf)( " -eigvec calculate eigenvectors of the Hessian\n");
00222 (*ad_printf)( " -sdonly do delta method for std dev estimates "
00223 "without redoing hessian\n");
00224 (*ad_printf)( " -ams N set arrmblsize to N "
00225 "(ARRAY_MEMBLOCK_SIZE)\n");
00226 (*ad_printf)( " -cbs N set CMPDIF_BUFFER_SIZE to N "
00227 "(ARRAY_MEMBLOCK_SIZE)\n");
00228 (*ad_printf)( " -mno N set the maximum number of independent "
00229 "variables to N\n");
00230 (*ad_printf)( " -mdl N set the maximum number of dvariables to "
00231 "N\n");
00232 (*ad_printf)( " -gbs N set GRADSTACK_BUFFER_SIZE to N "
00233 "(ARRAY_MEMBLOCK_SIZE)\n");
00234 #if defined(USE_ADPVM)
00235 (*ad_printf)( " -master run as PVM master program\n");
00236 (*ad_printf)( " -slave run as PVM slave program\n");
00237 (*ad_printf)( " -pvmtime record timing information for PVM "
00238 "performance analysis\n");
00239 #endif
00240 (*ad_printf)( " -info show how to cite ADMB, license, and "
00241 "acknowledgements\n");
00242 (*ad_printf)( " -version show version information\n");
00243 (*ad_printf)( " -help show this message\n\n");
00244
00245
00246 (*ad_printf)( "Random effects options if applicable\n");
00247 (*ad_printf)( " -nr N maximum number of Newton-Raphson "
00248 "steps\n");
00249 (*ad_printf)( " -imaxfn N maximum number of evals in quasi-Newton "
00250 "inner optimization\n");
00251 (*ad_printf)( " -is N set importance sampling size to N\n");
00252 (*ad_printf)( " -isf N set importance sampling size funnel "
00253 "blocks to N\n");
00254 (*ad_printf)( " -isdiag print importance sampling diagnostics\n");
00255 (*ad_printf)( " -hybrid do hybrid Monte Carlo version of MCMC\n");
00256 (*ad_printf)( " -hbf set the hybrid bounded flag for bounded "
00257 "parameters\n");
00258 (*ad_printf)( " -hyeps mean step size for hybrid Monte Carlo\n");
00259 (*ad_printf)( " -hynstep number of steps for hybrid Monte "
00260 "Carlo\n");
00261 (*ad_printf)( " -noinit do not initialize RE before inner "
00262 "optimization\n");
00263 (*ad_printf)( " -ndi N set maximum number of separable calls\n");
00264 (*ad_printf)( " -ndb N set number of blocks for RE derivatives "
00265 "(reduce temp file size)\n");
00266 (*ad_printf)( " -ddnr use high precision Newton-Raphson, for "
00267 "banded Hessian case only\n");
00268 (*ad_printf)( " -nrdbg verbose reporting for debugging "
00269 "newton-raphson\n");
00270 # if defined(__MINI_MAX__)
00271 (*ad_printf)( " -mm N do minimax optimization\n");
00272 # endif
00273 (*ad_printf)( " -shess use sparse Hessian structure inner "
00274 "optimzation\n\n");
00275
00276 (*ad_printf)("Read online documentation at http://admb-project.org\n");
00277 (*ad_printf)("Contact <users@admb-project.org> for help.\n");
00278
00279 ad_exit(0);
00280 }
00281 else if (option_match(_argc,_argv,"-info") > -1)
00282 {
00283 (*ad_printf)("ADMB Information\n");
00284 (*ad_printf)("================\n\n");
00285
00286 (*ad_printf)("How to Cite ADMB\n");
00287 (*ad_printf)("----------------\n\n");
00288
00289 (*ad_printf)("Fournier, D.A., H.J. Skaug, J. Ancheta, J. Ianelli, "
00290 "A. Magnusson, M.N. Maunder,\n");
00291 (*ad_printf)("A. Nielsen, and J. Sibert. 2012. AD Model Builder: using "
00292 "automatic\n");
00293 (*ad_printf)("differentiation for statistical inference of highly "
00294 "parameterized complex\n");
00295 (*ad_printf)("nonlinear models. Optim. Methods Softw. 27:233-249.\n\n");
00296
00297
00298 (*ad_printf)("License\n");
00299 (*ad_printf)("-------\n\n");
00300
00301 (*ad_printf)("Copyright (c) 2008-2013\n");
00302 (*ad_printf)("Regents of the University of California and ADMB "
00303 "Foundation\n\n");
00304 (*ad_printf)("ADMB is free software and comes with ABSOLUTELY NO "
00305 "WARRANTY.\n");
00306 (*ad_printf)("You are welcome to redistribute it under certain "
00307 "conditions.\n\n");
00308 (*ad_printf)("AD Model Builder, or ADMB, was developed by David Fournier "
00309 "of Otter Research\n");
00310 (*ad_printf)("Ltd, Sidney, BC, Canada. In 2007, scientists from the "
00311 "University of Hawai'i at\n");
00312 (*ad_printf)("Manoa Pelagic Fisheries Research Program (John Sibert and "
00313 "Anders Nielsen) and\n");
00314 (*ad_printf)("the Inter-American Tropical Tuna Commission (Mark "
00315 "Maunder), in consultation with\n");
00316 (*ad_printf)("scientists from NOAA Fisheries (Richard Methot), created "
00317 "the non-profit ADMB\n");
00318 (*ad_printf)("Foundation (admb-foundation.org) with the goal of "
00319 "increasing the number of ADMB\n");
00320 (*ad_printf)("users by making the software free and open source. In "
00321 "partnership with NOAA\n");
00322 (*ad_printf)("Fisheries and the National Center for Ecological Analysis "
00323 "and Synthesis (NCEAS,\n");
00324 (*ad_printf)("www.nceas.ucsb.edu), the ADMB Foundation obtained funding "
00325 "from the Gordon and\n");
00326 (*ad_printf)("Betty Moore Foundation (www.moore.org) to acquire the "
00327 "copyright to the ADMB\n");
00328 (*ad_printf)("software suite, in order to make it broadly and freely "
00329 "available to the research\n");
00330 (*ad_printf)("community. In 2008 the copyright was transferred from "
00331 "Otter Research Ltd to the\n");
00332 (*ad_printf)("University of California. The binary files were released "
00333 "in November 2008 and\n");
00334 (*ad_printf)("the source code was released in December 2009. More "
00335 "information about the ADMB\n");
00336 (*ad_printf)("Project can be found at admb-project.org.\n\n");
00337 (*ad_printf)("ADMB was originally developed by David Fournier of Otter "
00338 "Research Ltd.\n\n");
00339 (*ad_printf)("It is now maintained by the ADMB Core Team, whose members "
00340 "are listed on\n");
00341 (*ad_printf)("http://admb-project.org/developers/core-team.\n");
00342
00343 ad_exit(0);
00344 }
00345 }
00346 allocate();
00347 }
00351 ad_comm::ad_comm()
00352 {
00353 allocate();
00354 }
00355 void ad_comm::allocate(void)
00356 {
00357 #if defined (_WIN32)
00358 directory_prefix='\\';
00359 #else
00360 directory_prefix='/';
00361 #endif
00362 adstring tmpstring;
00363
00364 #if defined(_MSC_VER)
00365
00366 for (int i = (int)adprogram_name.size(); i >= 1; i--)
00367 {
00368 if (adprogram_name(i)==directory_prefix)
00369 {
00370 adprogram_name=adprogram_name(i+1,adprogram_name.size());
00371 break;
00372 }
00373 }
00374 #endif
00375
00376 #if defined(_WIN32)
00377
00378 #ifdef __MINGW64__
00379 size_t _n = adprogram_name.size();
00380 assert(_n <= INT_MAX);
00381 int n = (int)_n;
00382 #else
00383 int n = (int)adprogram_name.size();
00384 #endif
00385 if (n > 4)
00386 {
00387 if (adprogram_name(n - 3) == '.'
00388 && tolower(adprogram_name(n - 2)) == 'e'
00389 && tolower(adprogram_name(n - 1)) == 'x'
00390 && tolower(adprogram_name(n)) == 'e')
00391 {
00392 n -= 4;
00393 }
00394 }
00395 adprogram_name=adprogram_name(1,n);
00396 #endif
00397
00398
00399 if (argc > 1)
00400 {
00401 int on=0;
00402 if ( (on=option_match(argc,argv,"-wd"))>-1)
00403 {
00404 if (on>argc-2 || argv[on+1][0] == '-')
00405 {
00406 cerr << "Invalid input data command line option"
00407 " -- ignored" << endl;
00408 }
00409 else
00410 {
00411 tmpstring = adstring(argv[on+1]);
00412 wd_flag=1;
00413 }
00414 }
00415 }
00416 if (length(tmpstring))
00417 {
00418 if (tmpstring(length(tmpstring)) == directory_prefix)
00419 {
00420 adprogram_name=tmpstring + adprogram_name;
00421 working_directory_path = tmpstring;
00422 }
00423 else
00424 {
00425 adprogram_name=tmpstring + directory_prefix + adprogram_name;
00426 working_directory_path = tmpstring + directory_prefix;
00427 }
00428 }
00429
00430 tmpstring=adprogram_name + adstring(".dat");
00431 if (argc > 1)
00432 {
00433 int on=0;
00434 if ( (on=option_match(argc,argv,"-ind"))>-1)
00435 {
00436 if (on>argc-2 || argv[on+1][0] == '-')
00437 {
00438 cerr << "Invalid input data command line option"
00439 " -- ignored" << endl;
00440 }
00441 else
00442 {
00443 tmpstring = adstring(argv[on+1]);
00444 }
00445 }
00446 }
00447 global_datafile= new cifstream(tmpstring);
00448 if (!global_datafile)
00449 {
00450 cerr << "Error trying to open data input file "
00451 << tmpstring << endl;
00452 }
00453 else
00454 {
00455 if (!(*global_datafile))
00456 {
00457 cerr << "Error trying to open data input file "
00458 << tmpstring << endl;
00459 delete global_datafile;
00460 global_datafile=NULL;
00461 }
00462 }
00463 adstring ts=adprogram_name + adstring(".log");
00464 global_logfile= new ofstream( (char*)ts);
00465
00466 int biopt=-1;
00467 int aiopt=-1;
00468 biopt=option_match(argc,argv,"-binp");
00469 aiopt=option_match(argc,argv,"-ainp");
00470
00471 tmpstring=adprogram_name + adstring(".bin");
00472 if (!global_bparfile && aiopt == -1)
00473 {
00474 if (biopt>-1)
00475 {
00476 if (biopt>argc-2 || argv[biopt+1][0] == '-')
00477 {
00478 cerr << "Invalid input parameter file command line option"
00479 " -- ignored" << endl;
00480 }
00481 else
00482 {
00483 tmpstring = adstring(argv[biopt+1]);
00484 }
00485 }
00486 global_bparfile= new uistream(tmpstring);
00487 if (global_bparfile)
00488 {
00489 if (!(*global_bparfile))
00490 {
00491 if (biopt>-1)
00492 {
00493 cerr << "Error trying to open binary inoput par file "
00494 << tmpstring << endl;
00495 exit(1);
00496 }
00497 delete global_bparfile;
00498 global_bparfile=NULL;
00499 }
00500 }
00501 }
00502 tmpstring=adprogram_name + adstring(".pin");
00503 if (!global_parfile)
00504 {
00505 if (aiopt>-1)
00506 {
00507 if (aiopt>argc-2 || argv[aiopt+1][0] == '-')
00508 {
00509 cerr << "Invalid input parameter file command line option"
00510 " -- ignored" << endl;
00511 }
00512 else
00513 {
00514 tmpstring = adstring(argv[aiopt+1]);
00515 }
00516 }
00517 global_parfile= new cifstream(tmpstring);
00518 if (global_parfile)
00519 {
00520 if (!(*global_parfile))
00521 {
00522 if (aiopt>-1)
00523 {
00524 cerr << "Error trying to open ascii inoput par file "
00525 << tmpstring << endl;
00526 exit(1);
00527 }
00528 delete global_parfile;
00529 global_parfile=NULL;
00530 }
00531 }
00532 }
00533 }
00534
00538 ad_comm::~ad_comm()
00539 {
00540 if (ptm)
00541 {
00542 delete ptm;
00543 ptm=0;
00544 }
00545 if (ptm1)
00546 {
00547 delete ptm1;
00548 ptm1=0;
00549 }
00550 if (global_datafile)
00551 {
00552 delete global_datafile;
00553 global_datafile=NULL;
00554 }
00555 if (global_parfile)
00556 {
00557 delete global_parfile;
00558 global_parfile=NULL;
00559 }
00560 if (global_logfile)
00561 {
00562 delete global_logfile;
00563 global_logfile=NULL;
00564 }
00565 }
00566
00567 void function_minimizer::pre_userfunction(void)
00568 {
00569 if (lapprox)
00570 {
00571 if (lapprox->hesstype==2)
00572 {
00573
00574 lapprox->separable_calls_counter=0;
00575 }
00576 }
00577 userfunction();
00578 if (lapprox)
00579 {
00580 if (lapprox->hesstype==2)
00581 {
00582 lapprox->num_separable_calls=lapprox->separable_calls_counter;
00583
00584 double tmp=0.0;
00585 int inner_opt_value=inner_opt();
00586 if (lapprox->saddlepointflag==2)
00587 {
00588 if (inner_opt_value !=0 )
00589 {
00590 for (int i = 1; i <= lapprox->num_separable_calls; i++)
00591 {
00592 tmp-=(*lapprox->separable_function_difference)(i);
00593 }
00594 value(*objective_function_value::pobjfun)=tmp;
00595 }
00596 }
00597 else
00598 {
00599 for (int i = 1; i <= lapprox->num_separable_calls; i++)
00600 {
00601 tmp+=(*lapprox->separable_function_difference)(i);
00602 }
00603 value(*objective_function_value::pobjfun)=tmp;
00604 }
00605 }
00606 }
00607 }