[r-cran-rgenoud] 01/04: New upstream version 5.7-12.4
Andreas Tille
tille at debian.org
Fri Oct 20 07:02:24 UTC 2017
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository r-cran-rgenoud.
commit e443147aa20626f9ca792534b96886d6ebd787f5
Author: Andreas Tille <tille at debian.org>
Date: Fri Oct 20 08:56:19 2017 +0200
New upstream version 5.7-12.4
---
.Rinstignore | 4 +
ChangeLog | 274 +++
DESCRIPTION | 16 +
INDEX | 1 +
MD5 | 39 +
NAMESPACE | 2 +
R/rgenoud.R | 1543 +++++++++++++++
R/zzz.R | 41 +
THANKS | 7 +
build/vignette.rds | Bin 0 -> 200 bytes
inst/CITATION | 37 +
inst/doc/Figures/fig1.pdf | Bin 0 -> 10167 bytes
inst/doc/Figures/lqdxmpl2B.pdf | Bin 0 -> 39263 bytes
inst/doc/rgenoud.R | 159 ++
inst/doc/rgenoud.Rnw | 1465 ++++++++++++++
inst/doc/rgenoud.bib | 1903 ++++++++++++++++++
inst/doc/rgenoud.pdf | Bin 0 -> 486498 bytes
man/genoud.Rd | 708 +++++++
src/change_order.cpp | 482 +++++
src/eval.cpp | 287 +++
src/evaluate.cpp | 4117 +++++++++++++++++++++++++++++++++++++++
src/frange_ran.cpp | 89 +
src/genoud.cpp | 188 ++
src/genoud.h | 274 +++
src/gradient.cpp | 870 +++++++++
src/gradient.h | 111 ++
src/math.cpp | 360 ++++
src/multiply.cpp | 107 +
src/numerics.cpp | 326 ++++
src/operators.cpp | 1182 +++++++++++
src/print_format.cpp | 237 +++
src/rgenoud.cpp | 273 +++
src/unif.cpp | 144 ++
src/unif.h | 36 +
src/urans.h | 26 +
tests/tests.R | 57 +
tests/tests.Rout.save | 162 ++
vignettes/Figures/fig1.pdf | Bin 0 -> 10167 bytes
vignettes/Figures/lqdxmpl2B.pdf | Bin 0 -> 39263 bytes
vignettes/rgenoud.Rnw | 1465 ++++++++++++++
vignettes/rgenoud.bib | 1903 ++++++++++++++++++
41 files changed, 18895 insertions(+)
diff --git a/.Rinstignore b/.Rinstignore
new file mode 100644
index 0000000..d212cd2
--- /dev/null
+++ b/.Rinstignore
@@ -0,0 +1,4 @@
+inst/doc/Figures/*
+inst/doc/Figures
+
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..0c4b2bf
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,274 @@
+2015-07-19 Version: 5.7-12.4
+ * genoud.R: creating visible binding for variable "indx"
+
+2015-07-18 Version: 5.7-12.3
+ * genoud.R: import non-base functions explicitly
+
+2015-07-17 Version: 5.7-12.2
+ * DESCRIPTION: improves description
+
+2013-06-28 Version: 5.7-12.1
+ * test.R: suppress message on load
+
+2013-06-28 Version: 5.7-12
+ * genoud.Rd: Updated the documentation to reflect the usage of the
+ 'parallel' package instead of the deprecated package 'snow'
+ * vignettes: moved vignettes from /inst/doc to /vignettes.
+
+2013-06-28 Version: 5.7-10
+ * genoud.R: now uses the 'parallel' package instead of the
+ deprecated package 'snow'
+
+2013-06-27 Version: 5.7-9.2
+ * evaluate.cpp: JaIntegerOptimization(), Correct memory
+ issue. When reading in an old population file a segmentation fault
+ could result when an old population file was read that had a
+ larger population than the new population. Issue only arose for
+ integer optimization.
+
+2013-05-06 Version: 5.7-9.1
+ * operators.cpp: oper5(), Simple Crossover, always hit the maximum
+ unique individual limit. Corrected the logic to only check for
+ unique children in the crossover portion. Note that this makes
+ results different from previous versions even if the random number
+ seeds are set.
+
+2012-06-03 Version: 5.7-8
+ * rgenoud.R: Added the following options back in for backward
+ compatibility, but a warning is printed if they are used:
+ output.path and output.append. Please use 'sink' instead.
+
+2012-06-03 Version: 5.7-7
+ * rgenoud.R: Call to optimHess() now explicitly names the arguments to be matched.
+
+2012-06-03 Version: 5.7-6
+ * evaluate.cpp: output streams are no longer flushed because of
+ R's rules about calling stdout.
+ * rgenoud.pdf: has been compacted to save space.
+ * .Rinstignore: new file has been added to sure that
+ inst/doc/Figures are not installed to save space.
+
+2012-06-03 Version: 5.7-5
+
+ * rgenoud.R: Because of the switch to Rprintf (see below), the
+ 'output.path' and 'output.append' options have been removed.
+ * evaluate.cpp: Routed printing calls through Rprintf rather than
+ fprintf. Made sure all error handling is done by R's error()
+ function. Many cpp files affected: genoud.cpp, genoud.h,
+ gradient.cpp, operators.cpp, math.cpp, numerics.cpp,
+ print_format.cpp.
+
+2012-06-02 Version: 5.7-4
+
+ * rgenoud.R: Removes calls to .Internal(optimhess). Now calls optimHess().
+ * zzz.R: Now uses packageStartupMessage() to display .onAttach message.
+
+2011-05-04 Version: 5.7-3
+
+ * rgenoud.Rd: Update for Journal of Statistical Software
+ * inst/CITATION: Final update for Journal of Statistical Software
+
+2011-04-16 Version: 5.7-2
+
+ * inst/CITATION: Updated for Journal of Statistical Software
+
+2010-08-26 Version: 5.7-1
+
+ * operators.cpp: Fixed boundary issue for integer optimization
+ (when 'data.type.int=TRUE') created by changes in the GNU CC
+ compiler, operators P3,P4,P5,P7 were affected.
+ * evaluate.cpp: See above and corrected printing of population means and variances when doing integer optimization.
+ * genound.h: See above
+ * print_format.cpp: Changed longs to ints to prevent warnings produced by the call to fscanf() in the ReadPopulation() file.
+
+2010-06-01 Version: 5.6-7
+
+ * rgenoud.R: Improved handling of the parent environment when the 'transform' option is used
+ * operators.ccp: Fixed boundary issue for the integer version of the Polytope Crossover operator (P5 and function JaIntegeroper4).
+
+2009-08-14 Version: 5.6-6
+
+ * rgenoud.Rd: Improved the documentation of the 'transform' option.
+
+2009-08-07 Version: 5.6-5
+
+ * rgenoud.Rnw: created vignette file to generate rgenoud.pdf,
+ rgenoud.tex and rgenoud.R. Support files also added---i.e.,
+ rgenoud.bib and figures in the inst/doc/Figures directory
+ added.
+
+ * COPYRIGHTS: file added
+
+ * COPYING: file added
+
+ * THANKS: file added
+
+2009-08-06 Version: 5.6-4
+
+ * evaluate.cpp: Adds boundary checking for the parameters returned
+ by the 'transform' option. For the transform option, only checks bounds in generation 0 because of computational efficiency
+ concerns. The standard bounds checking remains unchanged.
+
+ * genoud.Rd: Documentation updated to reflect above.
+
+2009-08-04 Version: 5.6-3
+
+ * print_format.cpp: Corrects issue when 'share.type=1' and
+ 'starting.values' are provided.
+
+ * evaluate.cpp and multiple other files: Some warning messages are
+ now simply notes.
+
+2009-08-03 Version: 5.6-2
+
+ * multiple files: optim() can now be called by any valid method
+ using the 'optim.method' option: namely one of "BFGS", "L-BFGS-B",
+ "Nelder-Mead", "CG", or "SANN".
+
+ * rgenoud.R: The error checking of user provided starting values has been improved.
+
+2009-08-03 Version: 5.6-1
+
+ * multiple files: Major revision. Adds the transform option which is required by the FAiR package by Ben Goodrich
+ <goodrich at fas.harvard.edu>.
+
+ * pint_format.cpp: share.type=1 works correctly again.
+
+ * multiple files: Printing is cleaning up when share.type=1, and relevant warning messages are improved.
+
+2009-03-13 Version: 5.5-1
+
+ * genoud.Rd: Corrected formatting issues in the help page.
+
+ * evaluate.cpp: Corrected overloading ambiguity between
+ "std::fmod(double, double)" and "std::fmod(long double, long
+ double)" which prevented building on Solaris.
+
+2008-01-04 Version: 5.4-7
+
+ * evaluate.cpp, rgenoud.cpp: The 'BFGSburnin' option may now be
+ set to a negative value. If \code{BFGSburnin < 0}, the BFGS will
+ be used if and when \code{wait.generations} is doubled because at
+ least one gradient is too large, which can only occur when
+ \code{gradient.check = TRUE}. Note that 'BFGSburnin' was an option
+ added in version 5.3-3. Premature use of the BFGS can lead to
+ convergence to a local minimum instead of the global one. This
+ option allows the user to control how many generations are run
+ before the BFGS is started. This option delays the use of both
+ the BFGS on the best individual and of the P9 operator.
+
+ * multiple files: Better interrupt handling. When genoud is
+ interrupted, it now prints a message on how to recover the best
+ individual found so far.
+
+ * multiple files: Helper function of analytical gradients is
+ enabled. Better checking to make sure that input parameters are
+ legal.
+
+ * rgenoud.R and other files: User may now pass in "control" (a
+ list of control parameters) for optim including control$fnscale.
+
+ * rgenoud.Rd: Updated rgenoud.Rd project.path description. It is
+ now noted in genoud.Rd that with boundary.enforcement=2, no
+ out-of-bounds evaluations will ever be requested. In this case,
+ boundary enforcement is also applied to the BFGS algorithm, which
+ prevents candidates from straying beyond the bounds defined by
+ \code{Domains}. Note that this forces the use of the "L-BFGS-B"
+ algorithm for \code{\link[stats]{optim}}. This algorithm requires
+ that all fit values and gradients be defined and finite for all
+ function evaluations. If this causes an error, it is suggested
+ that the "BFGS" algorithm be used instead by setting
+ \code{boundary.enforcement=1}.
+
+2007-11-19 Version: 5.3-4
+
+ * multiple files: Made some changes for the Portland Group
+ Compiler (pgCC). Converted some longs to ints.
+
+
+2007-10-18 Version: 5.3-3
+
+ * multiple files: A number of starting values can now be provided
+ by passing a matrix to the 'starting.values' option.
+
+ * multiple files: A new option has been added named 'BFGSburnin'
+ which control the number of generations which are run before the
+ BFGS is first used. Premature use of the BFGS can lead to
+ convergence to a local minimum instead of the global one. This
+ option allows the user to control how many generations are run
+ before the BFGS is started. This option delays the use of both
+ the BFGS on the best individual and of the P9 operator.
+
+ * rgenoud.R: The dimensions of the 'Domains' object are now
+ checked both if they have the correct number of dimensions and if
+ the values are sane.
+
+ * evaluate.cpp and other files: Fixed warnings in gcc >4.2:
+ evaluate.cpp:304: warning: deprecated conversion from string
+ constant to 'char*'
+
+ * evaluate.cpp: Fixed a MemoryMatrix issue with
+ data.type.int=TRUE. MemoryMatrix now gives the same results as
+ !MemoryMatrix. The issues was that the number of UniquePairs that
+ were hunted down for P6 and P8 were different between the two
+ setups.
+
+2007-08-04 Version: 5.1-14
+
+ * multiple files: Minor changes. Changed #includes so that the
+ package now compiles with Sun Studio compilers: extern "C" is not
+ needed for R header files. Added a regression suite to the "tests"
+ directory.
+
+2007-03-23 Version: 5.1-9
+
+ Major changes:
+
+ * multiple files: Lexical searching now allows for one of the fit
+ functions to be optimized by the derivative based optimizer. This
+ functionality is made available via the "BFGSfn" option. Also see
+ the "BFGShelp" option.
+
+ * multiple files: The 9th operator which takes the convex
+ combination of the parent and its BFGS fit can now by tuned via
+ the "P9mix" option. If this is set to equal 1, then the BFGS fit
+ is simply used.
+
+ Minor changes:
+
+ * multiple files: If BFGS results in out-of-bounds individuals,
+ warning is only printed if print.level > 1
+
+
+2007-02-20 Version: 5.0-5
+
+ * zzz.R: Prints version and build date on load.
+
+ * rgenoud.R: If starting values are provided and the lexical
+ option is TRUE, then the starting values instead of domains[,1]
+ are used to figure out how many return fits the function provides.
+
+2007-02-11 Version: 5.0-2
+
+ * genoud.Rd: Improved documentation file.
+
+2007-01-30 Version: 5.0-1
+
+ * evaluate.cpp: remove needless if statement in evaluate.cpp
+
+
+2007-01-30 Version: 5.0-0
+
+ * genoud.Rd: Multiple point crossover now accurately called simple crossover in docs
+
+ * operators.cpp: corrected whole mutation to actually do whole mutation
+
+ * evaluate.cpp: fixed minor no improvement bug which involved going from gen0 to gen1
+
+ * multiple files: simplified printing
+
+
+ Copyright 1997-2012 Walter R. Mebane, Jr. and Jasjeet S. Sekhon.
+ Copying and distribution of this file, without modification, are
+ permitted provided the copyright notice and this notice are
+ preserved.
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..fc77ff0
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,16 @@
+Package: rgenoud
+Version: 5.7-12.4
+Date: 2015-07-19
+Title: R Version of GENetic Optimization Using Derivatives
+Author: Walter R. Mebane, Jr. <wmebane at umich.edu>,
+ Jasjeet Singh Sekhon <sekhon at berkeley.edu>
+Maintainer: Jasjeet Singh Sekhon <sekhon at berkeley.edu>
+Description: A genetic algorithm plus derivative optimizer.
+Depends: R (>= 2.15), utils
+Suggests: parallel
+License: GPL-3
+URL: http://sekhon.berkeley.edu/rgenoud/
+NeedsCompilation: yes
+Packaged: 2015-07-20 00:50:19 UTC; jas
+Repository: CRAN
+Date/Publication: 2015-07-20 09:24:29
diff --git a/INDEX b/INDEX
new file mode 100644
index 0000000..f9f6735
--- /dev/null
+++ b/INDEX
@@ -0,0 +1 @@
+genoud GENetic Optimization Using Derivatives
diff --git a/MD5 b/MD5
new file mode 100644
index 0000000..83a7bee
--- /dev/null
+++ b/MD5
@@ -0,0 +1,39 @@
+03031d7393b444fb126b60b64e11fb87 *ChangeLog
+011cd745379495c2173b8c558a21430e *DESCRIPTION
+7041fdf1d47575612a5530f22815c74b *INDEX
+d0e648e7a542fefef8ded0093a377d0c *NAMESPACE
+e876d80633dfbe62bc02b1bfac2182cc *R/rgenoud.R
+1a33ab1680d185e8ac27ccbfee0a69c5 *R/zzz.R
+5b89fbb8f5ded1292c887abd380d9ed3 *THANKS
+b4e36fbfec752be4e34ac7be2a1df462 *build/vignette.rds
+c1555556931726b8c05fb5eca07023ed *inst/CITATION
+fc974e2bc8d4159f9ef7c20f2e4d2d40 *inst/doc/Figures/fig1.pdf
+c1c87156136ee41de970e4fce41fe4ed *inst/doc/Figures/lqdxmpl2B.pdf
+301934099bc3c999ad3b509374fccd7f *inst/doc/rgenoud.R
+688f42dd89519765ad82e2ec6eb8b9ce *inst/doc/rgenoud.Rnw
+6da32365e697f8c1d280b3bf1c346ef2 *inst/doc/rgenoud.bib
+5ff472c622145eb456da868ca0c1d987 *inst/doc/rgenoud.pdf
+e9bf210be99470cc4bc1dc2f33d7c6fb *man/genoud.Rd
+9e5f395a8f7532118c723dab203d314d *src/change_order.cpp
+0e2173333529000bcd8a2b2cdceec2c6 *src/eval.cpp
+41e73b115fe52a57d90f9771202ab5e7 *src/evaluate.cpp
+c064f9e6cdb0634bc0062a044f5d1eb6 *src/frange_ran.cpp
+1a9a34c6ab01598c176ef45ec10e5e70 *src/genoud.cpp
+dfa87419e843d8e6fb959e156004c550 *src/genoud.h
+3213f79851150f99629a7e2a1719a7d6 *src/gradient.cpp
+682a4a00ac9b06f5063f248f59989f0d *src/gradient.h
+824d9f5d338ecaa274098127fbfe987b *src/math.cpp
+1ac6ed98c2cb0267453dcdfe1c8029ce *src/multiply.cpp
+62b05e4d2b6ccf20af199dc8db6f4436 *src/numerics.cpp
+1dfcf27b62c83849ee8bd8b361d06e11 *src/operators.cpp
+33b6a2cd3d214a86355fb03ae840034d *src/print_format.cpp
+6232a071dae711bba098c886b76bbdee *src/rgenoud.cpp
+5a028c6ece078d870ee528ca300a9776 *src/unif.cpp
+fa19da33dee62a703d43ed766e8d2985 *src/unif.h
+4ef64fab110b8894a0a4871f34f5692f *src/urans.h
+1bd5ce070de3e38986c27c888120005e *tests/tests.R
+de48b17cafdb9e88eb76e1a6cd7b6074 *tests/tests.Rout.save
+fc974e2bc8d4159f9ef7c20f2e4d2d40 *vignettes/Figures/fig1.pdf
+c1c87156136ee41de970e4fce41fe4ed *vignettes/Figures/lqdxmpl2B.pdf
+688f42dd89519765ad82e2ec6eb8b9ce *vignettes/rgenoud.Rnw
+6da32365e697f8c1d280b3bf1c346ef2 *vignettes/rgenoud.bib
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644
index 0000000..f478ebf
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,2 @@
+#useDynlib(rgenoud)
+export(genoud)
diff --git a/R/rgenoud.R b/R/rgenoud.R
new file mode 100644
index 0000000..ba96a3c
--- /dev/null
+++ b/R/rgenoud.R
@@ -0,0 +1,1543 @@
+#
+# RGENOUD
+#
+# Walter R. Mebane, Jr.
+# University of Michigan
+# http://www-personal.umich.edu/~wmebane
+# <wmebane at umich.edu>
+#
+# Jasjeet Singh Sekhon
+# UC Berkeley
+# http://sekhon.berkeley.edu
+# <sekhon at berkeley.edu>
+#
+
+
+genoud <- function(fn, nvars, max=FALSE, pop.size=1000, max.generations=100, wait.generations=10,
+ hard.generation.limit=TRUE, starting.values=NULL, MemoryMatrix=TRUE,
+ Domains=NULL, default.domains=10, solution.tolerance=0.001,
+ gr=NULL, boundary.enforcement=0, lexical=FALSE, gradient.check=TRUE, BFGS=TRUE,
+ data.type.int=FALSE, hessian=FALSE, unif.seed=812821, int.seed=53058,
+ print.level=2, share.type=0, instance.number=0,
+ output.path="stdout", output.append=FALSE, project.path=NULL,
+ P1=50, P2=50, P3=50, P4=50, P5=50, P6=50, P7=50, P8=50, P9=0,
+ P9mix=NULL, BFGSburnin=0, BFGSfn=NULL, BFGShelp = NULL,
+ control = list(), optim.method=ifelse(boundary.enforcement < 2, "BFGS", "L-BFGS-B"),
+ transform=FALSE, debug=FALSE, cluster=FALSE, balance=FALSE, ...)
+{
+
+ if (transform!=FALSE & transform!=TRUE)
+ {
+ warning("'transform' must be TRUE or FALSE. Setting to FALSE")
+ transform <- FALSE
+ }
+ if(transform) {
+ return(do.call(what = genoud_transform,
+ args = as.list(match.call())[-1],
+ quote = FALSE,
+ envir = parent.frame()))
+ }
+
+ if(!is.null(BFGShelp) && !is.function(BFGShelp)) stop("'BFGShelp' must be NULL or a function")
+
+ #These used to be option. From >5.7-3, they are no longer available
+ #because R CMD check complains about calls to 'stdout'
+ if (output.path!="stdout")
+ {
+ output.path <- "stdout"
+ warning("'output.path' can no longer be changed. Please use 'sink'. Option is only provided for backward compatibility of the API.")
+ }
+ if(output.append!=FALSE)
+ {
+ output.append <- FALSE
+ warning("'output.append' can no longer be changed. Please use 'sink'. Option is only provided for backward compatibility of the API.")
+ }
+
+ if(!is.null(P9mix) && !is.double(P9mix)) {
+ stop("'P9mix' must be NULL or a number between 0 and 1")
+ } else {
+ if(is.null(P9mix)) {
+ P9mix <- -1
+ } else {
+ if(! ( (1 >= P9mix) && (P9mix > 0) ))
+ stop("'P9mix' must be NULL or a number between 0 and 1 (it may be equal to 1)")
+ }
+ }
+
+ if( (BFGSburnin < 0) & !gradient.check )
+ {
+ warning("If 'BFGSburnin' is negative, gradient.check must be TRUE for 'BFGSburnin' to have any effect.")
+ }
+
+ if(!is.list(control))
+ stop("'control' must be a list, see ?optim")
+ g.scale <- control$fnscale
+ if(!is.null(g.scale)) {
+ if(g.scale > 0 & max) {
+ stop("positive control$fnscale is inconsistent with maximization")
+ }
+ else if(g.scale < 0 & !max) {
+ stop("negative control$fnscale is inconsistent with minimization")
+ }
+ else if(g.scale == 0) {
+ stop("optim divides the function value by control$fnscale ",
+ "setting control$fnscale to zero is therefore impossible")
+ }
+ FiniteBadFitValue <- ifelse(max, -.Machine$double.xmax, .Machine$double.xmax)
+ }
+ else { # NULL g.scale
+ if (max == FALSE) {
+ g.scale <- 1
+ FiniteBadFitValue <- .Machine$double.xmax
+ }
+ else {
+ g.scale <- -1
+ FiniteBadFitValue <- -.Machine$double.xmax
+ }
+ }
+ control$fnscale <- g.scale
+
+ if(!lexical & !is.null(BFGSfn))
+ {
+ stop("'BFGSfn' can only be provided with lexical optimization or when 'transform=TRUE'")
+ }
+ if (!is.null(BFGSfn) & BFGS==FALSE)
+ {
+ if (!is.function(BFGSfn))
+ stop("IF 'BFGSfn' is not a function, it must be NULL")
+ warning("setting BFGS==TRUE because 'BFGSfn' is not null")
+ BFGS <- TRUE
+ }
+
+ fn1 <- function(par) {
+ fit <- fn(par, ...)
+
+ if(is.null(fit))
+ fit <- FiniteBadFitValue
+
+ if(length(fit)==1)
+ if(!is.finite(fit))
+ fit <- FiniteBadFitValue
+
+ return(fit)
+ }#end of fn1
+
+ if(!is.null(BFGShelp)) {
+ if (!is.null(gr)) {
+ gr1 <- function(par, helper = do.call(BFGShelp,
+ args = list(initial = par, done = TRUE))) {
+ gr(par, helper, ...)
+ }
+ } else gr1 <- NULL
+ }
+ else {
+ if (!is.null(gr)) {
+ gr1 <- function(par) gr(par, ...)
+ } else gr1 <- NULL
+ }
+
+ #setpath to tempdir
+ if(is.null(project.path))
+ {
+ project.path <- file.path(tempdir(), "genoud.pro")
+ }
+
+ #do we have stating values?
+ if (is.null(starting.values)) {
+ nStartingValues <- 0;
+ }
+ else if(is.matrix(starting.values)) {
+ if(any(dim(starting.values) == nvars)) {
+ if(nrow(starting.values) == nvars & ncol(starting.values) !=nvars) starting.values <- t(starting.values)
+ nStartingValues <- nrow(starting.values)
+ if(nStartingValues > pop.size) {
+ warning("increasing 'pop.size' because too many starting.values were provided")
+ pop.size <- nStartingValues
+ }
+ }
+ else {
+ warning("ignoring 'starting.values' because the wrong number of parameters was provided")
+ nStartingValues <- 0
+ }
+ }
+ else if(is.numeric(starting.values) | is.logical(starting.values)) {
+ nStartingValues <- 1;
+
+ if(length(starting.values)!=nvars)
+ {
+ nStartingValues <- 0
+ warning("Ignoring 'starting.values' because length(staring.values)!=nvars")
+ }
+ else starting.values <- matrix(starting.values, nrow = 1)
+ }
+ else stop("starting.values must be NULL, a vector, or a matrix")
+
+ #set output.type
+ if (output.path=="stdout")
+ {
+ output.type <- 0;
+ }
+ else
+ {
+ if (output.append)
+ {
+ output.type <- 2;
+ }
+ else
+ {
+ output.type <- 1;
+ }
+ }
+
+ # let's create the Domains if none have been passed.
+ if (!(is.matrix(Domains)))
+ {
+ Domains <- matrix(nrow=nvars, ncol=2);
+ for (i in 1:nvars)
+ {
+ Domains[i,1] <- -1*default.domains;
+ Domains[i,2] <- default.domains;
+ } # end of for loop
+ }
+ else if(nrow(Domains) != nvars) {
+ stop("number of rows in Domains must match 'nvars'")
+ }
+ else if(ncol(Domains) != 2) {
+ stop("number of cols in Domains must be 2")
+ }
+
+ if(!all(Domains[,1] <= Domains[,2])) {
+ stop("Domains[,1] must be less than or equal to Domains[,2]")
+ }
+ if(any(Domains[,1] == Domains[,2])) {
+ warning("some Domains[,1]==Domains[,2]")
+ }
+
+ # BG: now check all starting values are sane
+ if(nStartingValues > 0 && any(is.na(starting.values))) {
+ stop("Some starting values are NA")
+ }
+ if(nStartingValues > 0 && boundary.enforcement != 0 &&
+ !all(apply(starting.values, 1, FUN = function(x)
+ Domains[,1] <= x & x <= Domains[,2])) )
+ warning("'starting.values' which are outside of the bounds have been provided.
+ Continuing, but unexpected behavior can occur with 'boundary.enforcement!=0'")
+
+ # has the user provided any seeds?
+ if (unif.seed==812821 && int.seed==53058)
+ provide.seeds <- FALSE
+ else
+ provide.seeds <- TRUE;
+
+ #if lexical==TRUE we need to know how many items will be returned
+ if (lexical < 0)
+ {
+ warning("lexical < 0. Resetting to FALSE\n")
+ lexical <- 0
+ }
+ if (lexical>=1)
+ {
+ #creating visible binding for variable "indx"; although it is
+ #actually defined in fnLexicalSort() via an eval and paste
+ if (!exists("indx"))
+ {
+ indx <- NULL; rm(indx)
+ }
+ if(share.type > 0) {
+ warning("'share.type' being set to 0 because of lexical optimization")
+ share.type <- 0
+ }
+
+ if(nStartingValues)
+ {
+ foo <- fn1(starting.values[1,])
+ } else {
+ rfoo <- stats::runif(nrow(Domains), Domains[,1], Domains[,2])
+ if(data.type.int)
+ rfoo <- as.integer(round(rfoo))
+ foo <- fn1(rfoo)
+ }
+ foo.length <- length(as.vector(foo))
+ if(lexical > 1 && foo.length != lexical) {
+ warning(paste("Function returns a vector of length", foo.length,
+ "\nbut you specified lexical =", lexical))
+ }
+ if(foo.length == 1) {
+ lexical <- 0
+ warning("you specified lexical = TRUE but the function returns a scalar")
+ }
+ else lexical <- foo.length
+ }
+ else foo.length <- 1
+
+ if (lexical > 0)
+ {
+ if(is.null(BFGSfn))
+ {
+ #All derivative stuff is turned off if we are going to do lexical if BFGSfn is not provided
+ BFGS=FALSE
+ gradient.check=FALSE
+ if(hessian) {
+ warning("'hessian' being set to false because of lexical optimization. See 'BFGSfn' for workaround")
+ hessian=FALSE
+ }
+
+ P9 = 0
+ } else {
+ if(!is.null(BFGShelp)) {
+ fn1.bfgs <- function(par, helper = do.call(BFGShelp,
+ args = list(initial = par, done = TRUE),
+ envir = environment(fn))) {
+ fit <- BFGSfn(par, helper, ...)
+
+ if(is.null(fit)) fit <- FiniteBadFitValue
+
+ if(length(fit)==1) if(!is.finite(fit)) fit <- FiniteBadFitValue
+
+ return(fit)
+ }#end of fn1.bfgs
+ } else {
+ fn1.bfgs <- function(par) {
+ fit <- BFGSfn(par, ...)
+
+ if(is.null(fit)) fit <- FiniteBadFitValue
+
+ if(length(fit)==1) if(!is.finite(fit)) fit <- FiniteBadFitValue
+
+ return(fit)
+ }#end of fn1.bfgs
+ } # end else
+
+ if(is.null(gr)) {
+ gr <- function(par, helper = NA, ...)
+ {
+ gr.fn1.bfgs <- function(par, helper, FBFV) {
+ fit <- if(is.null(BFGShelp)) BFGSfn(par, ...) else BFGSfn(par, helper, ...)
+
+ if(is.null(fit))
+ fit <- FBFV
+
+ if(length(fit)==1)
+ if(!is.finite(fit))
+ fit <- FBFV
+
+ return(fit)
+ } # end of gr.fn1.bfgs
+ genoud.wrapper101.env <- new.env()
+ assign("x", par, envir = genoud.wrapper101.env)
+ assign("helper", helper, envir = genoud.wrapper101.env)
+ assign("FiniteBadFitValue", FiniteBadFitValue, envir = genoud.wrapper101.env)
+ foo <- as.double(attr(stats::numericDeriv(quote(gr.fn1.bfgs(x, helper, FiniteBadFitValue)), theta=c("x"), genoud.wrapper101.env), "gradient"))
+ return(foo)
+ } #end of gr
+ gr1 <- if(is.null(BFGShelp)) function(par, ...) gr(par) else
+ function(par, helper = do.call(BFGShelp, args = list(initial = par,
+ done = TRUE), envir = environment(fn))) {
+ gr(par, helper, ...)
+ } # end of gr1
+ } # end of if(!is.null(gr))
+ gr1func <- gr1
+ }# end of else
+ }#if lexical > 0
+ if (lexical==0)
+ lexical <- 1
+
+ #optim st
+ if(is.null(BFGSfn))
+ {
+ if(optim.method != "L-BFGS-B") {
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ ret <- stats::optim(foo.vals, fn=fn1, gr=gr1, method=optim.method,
+ control=control);
+ return(c(ret$value,ret$par));
+ } # end of genoud.optim.wrapper101
+ }
+ else {
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ ret <- stats::optim(foo.vals, fn=fn1, gr=gr1, method="L-BFGS-B",
+ lower = Domains[,1], upper = Domains[,2],
+ control=control);
+ return(c(ret$value,ret$par));
+ } # end of genoud.optim.wrapper101
+ }
+ } else {
+ if(optim.method != "L-BFGS-B") {
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ if(print.level > 2) {
+ fit <- fn1(foo.vals)
+ cat("\nPre-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+ if(is.null(BFGShelp)) {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method=optim.method,
+ control=control);
+ }
+ else {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method=optim.method,
+ control=control,
+ helper = do.call(BFGShelp, args = list(initial = foo.vals), envir = environment(fn)) );
+ }
+
+ if(print.level > 2)
+ {
+ cat("BFGS Fit:",ret$value,"\n")
+
+ fit <- fn1(ret$par)
+ cat("Post-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+
+ foo <- c(ret$value,ret$par)
+ return(foo);
+ } # end of genoud.optim.wrapper101
+ } else { # "L-BFGS-B"
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ if(print.level > 2) {
+ fit <- fn1(foo.vals)
+ cat("\nPre-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+ if(is.null(BFGShelp)) {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method="L-BFGS-B",
+ lower = Domains[,1],
+ upper = Domains[,2],
+ control=control);
+ }
+ else {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method="L-BFGS-B",
+ lower = Domains[,1],
+ upper = Domains[,2],
+ control=control,
+ helper = do.call(BFGShelp, args = list(initial = foo.vals), envir = environment(fn)) );
+ }
+
+ if(print.level > 2)
+ {
+ cat("BFGS Fit:",ret$value,"\n")
+
+ fit <- fn1(ret$par)
+ cat("Post-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+
+ foo <- c(ret$value,ret$par)
+ return(foo);
+ } # end of genoud.optim.wrapper101
+ }
+ }
+
+ # create the P vector
+ P <- vector(length=9, mode="numeric");
+ P[1] <- P1; P[2] <- P2; P[3] <- P3; P[4] <- P4;
+ P[5] <- P5; P[6] <- P6; P[7] <- P7; P[8] <- P8;
+ P[9] <- P9;
+
+ clustertrigger=1
+ if (is.logical(cluster))
+ {
+ if (cluster==FALSE) {
+ clustertrigger=0
+ } else {
+ stop("cluster option must be either FALSE, an object of the 'cluster' class (from the 'parallel' package) or a list of machines so 'genoud' can create such an object")
+ }
+ }
+
+ if(clustertrigger) {
+ parallel.exists = requireNamespace("parallel")
+ if (!parallel.exists) {
+ stop("The 'cluster' feature cannot be used unless the package 'parallel' can be loaded.")
+ }
+ }
+
+ if(clustertrigger)
+ {
+ if(!MemoryMatrix)
+ {
+ MemoryMatrix = TRUE
+ warning("MemoryMatrix has been set to 'TRUE' because the cluster option has been requested.")
+ }
+
+ GENclusterExport <- function (cl, list)
+ {
+ gets <- function(n, v) {
+ assign(n, v)
+ NULL
+ }
+ for (name in list) {
+ parallel::clusterCall(cl, gets, name, get(name))
+ }
+ }
+
+ ExpandDots <- function(...)
+ {
+ return(match.call())
+ }
+
+ dots <- ExpandDots(...)
+ if ( (length(dots) > 1) & balance==TRUE)
+ {
+ balance <- FALSE
+ warning("load balancing has been turned off because the function to be optimized requires extra arguments")
+ }
+
+ if (class(cluster)[1]=="SOCKcluster" | class(cluster)[1]=="PVMcluster" | class(cluster)[1]=="spawnedMPIcluster" | class(cluster)[1]=="MPIcluster") {
+ clustertrigger=1
+ cl <- cluster
+ GENclusterExport(cl, "fn")
+ GENclusterExport(cl, "fn1")
+ } else {
+ clustertrigger=2
+ cluster <- as.vector(cluster)
+ cat("Initializing Cluster\n")
+ cl <- parallel::makePSOCKcluster(cluster)
+ GENclusterExport(cl, "fn")
+ GENclusterExport(cl, "fn1")
+ }
+
+ if (length(cl) < 2 )
+ {
+ stop("You only have one node. You probably should not be using the cluster option")
+ }
+ }
+
+ fnLexicalSort <- function(mat, parms)
+ {
+ # parms = (1) MinMax, (2) nvars, (3) lexical_end, (4) type (0, vars, 1, obj)
+
+ decreasing=FALSE
+ if(parms[1]==1)
+ decreasing=TRUE
+
+ if(parms[4]==0)
+ {
+ #on nvars not on obj function
+ foo = "indx <- order("
+ for(i in (2:(parms[2]+1)) )
+ {
+ foo = paste(foo,"mat[,",i,"], ",sep="")
+ }
+ foo = paste(foo,"mat[,",parms[2]+2,"], ",sep="")
+ foo = paste(foo,"decreasing=FALSE)",sep="")
+ eval(parse(text=foo))
+ mat = mat[indx,]
+ } else {
+ #lexical on obj function
+ foo = "indx <- order(mat[,1], "
+ for(i in (parms[2]+3):parms[3] )
+ {
+ foo = paste(foo,"mat[,",i,"], ",sep="")
+ }
+ foo = paste(foo,"decreasing=",decreasing,")",sep="")
+ eval(parse(text=foo))
+ mat = mat[indx,]
+ }
+ return(mat)
+ }
+
+ fnMemoryMatrixEvaluate <- function(Memory, population, parms)
+ {
+ EVALUATE = -93813381
+
+ MinMax = parms[1]
+ nvars = parms[2]
+ lexical = parms[3]
+
+ lexical.end = ncol(population)
+ pop.size = nrow(population)
+
+ vars.indx <- 2:(nvars+1)
+ lexical.indx <- c(1,(nvars+3):lexical.end)
+
+ FIRSTTIME = TRUE
+ if (nrow(Memory) > 1)
+ FIRSTTIME = FALSE
+
+ nevaluate = 0
+
+ mfunc <- function(pop,memory)
+ {
+ f <- function(...) paste(..., sep=":")
+ a2 <- do.call("f", as.data.frame(pop))
+ b2 <- do.call("f", as.data.frame(memory))
+
+ return(match(a2,b2))
+ }
+
+ population.mat = matrix(population[,vars.indx], ncol=nvars)
+ if (!FIRSTTIME)
+ {
+ Memory.mat = matrix(Memory[,vars.indx], ncol=nvars)
+ match.matrix.indx <- mfunc(population.mat,Memory.mat)
+
+ for (i in 1:pop.size)
+ {
+ match.indx = match.matrix.indx[i]
+ found.match <- FALSE
+ if ( is.finite(match.indx) )
+ {
+ #this is needed because mfunc truncates floats (by the call to paste) to 15 digits
+# if (all(population.mat[i,]==Memory.mat[match.indx,]))
+# {
+ found.match <- TRUE
+ population[i,] <- Memory[match.indx,]
+# }
+ }
+ if(!found.match)
+ {
+ if (population[i,nvars+2] != 0) {
+ population[i,nvars+2] = EVALUATE
+ nevaluate = nevaluate+1
+ }
+ }
+ }
+ } else {
+ for (i in 1:pop.size)
+ {
+ population[i,nvars+2] = EVALUATE
+ nevaluate = nevaluate+1
+ }
+ }
+
+ #evaluation loop
+ if (nevaluate > 0)
+ {
+ eval.indx <- population[,nvars+2]==EVALUATE
+ ret=0
+ if (clustertrigger==0)
+ {
+ in.mat = matrix(population.mat[eval.indx,], ncol=nvars)
+ ret <- matrix(t(apply(in.mat, 1, fn1)), ncol=lexical)
+ } else {
+ if (balance==TRUE) {
+ in.mat = t(matrix(population.mat[eval.indx,], ncol=nvars))
+ cl.in <- as.list(as.data.frame(in.mat))
+ cl.out <- parallel::clusterApplyLB(cl, cl.in, fn1)
+ try(ret <- matrix(t(data.frame(cl.out)), ncol=lexical), TRUE)
+ if (!is.matrix(ret)) {
+ if (!debug) {
+ stop("Cluster returned an object which could not be turned into a data.frame. Cluster may be in bad state. Please consider restarting it. To see what the cluster returned please turn on the 'debug' option.")
+ } else {
+ cat("Cluster returned an object which could not be turned into a data.frame:\n")
+ print(cl.out)
+ stop("Cluster may be in bad state. Please consider restarting it.")
+ }
+ }
+ } else {
+ in.mat = matrix(population.mat[eval.indx,], ncol=nvars)
+ if(length(cl) > 1 )
+ {
+ cl.out = parallel::parRapply(cl, in.mat, fn1)
+ } else {
+ stop("You only have one node. Cluster option should not be used")
+ }
+
+ try(ret <- matrix(cl.out, byrow=TRUE, ncol=lexical), TRUE)
+ if (!is.matrix(ret)) {
+ if (!debug) {
+ stop("Cluster returned an object which could not be turned into a data.frame. Cluster may be in bad state. Please consider restarting it. To see what the cluster returned please turn on the 'debug' option.")
+ } else {
+ cat("Cluster returned an object which could not be turned into a data.frame:\n")
+ print(cl.out)
+ stop("Cluster may be in bad state. Please consider restarting it.")
+ }
+ }
+ }
+ } # else clustertrigger==0
+
+ if (lexical < 2)
+ {
+ population[eval.indx,1] = ret[,1]
+ } else {
+ population[eval.indx,lexical.indx] = ret
+ }
+ population[eval.indx,nvars+2] = 0
+
+ if(!FIRSTTIME)
+ {
+ Memory = rbind(Memory,population[eval.indx,])
+ } else {
+ Memory = matrix(population[eval.indx,], ncol=lexical.end)
+ FIRSTTIME = FALSE
+ }
+ }#end of nevaluate
+
+ if (lexical > 1)
+ {
+ population <- fnLexicalSort(population, c(MinMax,nvars,lexical.end,1))
+ } else {
+ if (MinMax==0)
+ {
+ population <- population[order(population[,1]),]
+ } else {
+ population <- population[order(population[,1], decreasing=TRUE),]
+ }
+ }
+
+ return(as.vector(c(nrow(Memory), Memory, population)))
+ } #end of fnMemoryMatrixEvaluate
+
+ if (!is.null(gr))
+ {
+ UserGradient = TRUE
+ gr1func <- gr1
+ } else {
+ UserGradient = FALSE
+ gr1func <- function() {}
+ }
+
+ if(data.type.int)
+ {
+ BFGS = FALSE
+ gradient.check=FALSE
+ }
+
+ if(is.matrix(starting.values))
+ starting.values <- t(starting.values)
+
+ #C++ code checks if at least Generation 0 has been run and if
+ #print.level>0 and project.path!="/dev/null". Otherwise, 'interrupted'
+ #remains FALSE
+ interrupted <- FALSE
+ interrupt.message <- paste("genoud interrupted:\none may recover the best solution found so far by executing")
+ interrupt.expression <- paste("pop <- read.table('",project.path,
+ "', comment.char = 'G')", sep = "")
+ interrupt.expression2 <- "best <- pop[pop$V1 == 1,, drop = FALSE]"
+ interrupt.expression3 <- paste("very.best <- as.matrix(best[nrow(best), ",
+ foo.length + 2, ":ncol(best)])", sep = "")
+ on.exit(if(interrupted) cat(interrupt.message, "\n", interrupt.expression, "\n",
+ interrupt.expression2, "\n", interrupt.expression3, "\n"))
+
+ gout <- .Call("rgenoud", as.function(fn1), new.env(),
+ as.integer(nvars), as.integer(pop.size), as.integer(max.generations),
+ as.integer(wait.generations),
+ as.integer(nStartingValues), as.double(starting.values),
+ as.vector(P), as.matrix(Domains),
+ as.integer(max), as.integer(gradient.check), as.integer(boundary.enforcement),
+ as.double(solution.tolerance), as.integer(BFGS), as.integer(data.type.int),
+ as.integer(provide.seeds), as.integer(unif.seed), as.integer(int.seed),
+ as.integer(print.level), as.integer(share.type), as.integer(instance.number),
+ as.integer(MemoryMatrix), as.integer(debug),
+ as.character(output.path), as.integer(output.type), as.character(project.path),
+ as.integer(hard.generation.limit),
+ as.function(genoud.optim.wrapper101),
+ as.integer(lexical), as.function(fnLexicalSort), as.function(fnMemoryMatrixEvaluate),
+ as.integer(UserGradient), as.function(gr1func), as.double(P9mix),
+ as.integer(BFGSburnin), as.integer(transform),
+ PACKAGE="rgenoud");
+
+ indx1 <- 4;
+ indx2 <- (indx1+lexical-1);
+ value=gout[indx1:indx2];
+
+ indx1 <- indx2+1
+ indx2 <- indx1+nvars-1
+ par = gout[indx1:indx2]
+
+ indx1 <- indx2+1
+ indx2 <- indx1+nvars-1
+ if(!gradient.check & !BFGS )
+ {
+ gradients= gout[indx1:indx2]
+ gradients = rep(NA, length(gradients))
+ } else {
+ gradients = gout[indx1:indx2]
+ }
+
+ indx1 <- indx2+1
+ indx2 <- indx1+8
+ operators=gout[indx1:indx2]
+
+ if (hessian==TRUE)
+ {
+ con <- list(trace = 0, fnscale = g.scale,
+ parscale = rep.int(1, length(par)), ndeps = rep.int(0.001, length(par)), maxit = 100,
+ abstol = -Inf, reltol = sqrt(.Machine$double.eps), alpha = 1,
+ beta = 0.5, gamma = 2, REPORT = 10, type = 1, lmm = 5,
+ factr = 1e+07, pgtol = 0, tmax = 10, temp = 10)
+
+ nm <- names(gout[5:(nvars+4)])
+
+ if(lexical == 1) {
+ hess.fn <- function(par) fn1(par, ...)
+ hess <- stats::optimHess(par=gout[5:(nvars+4)], fn=fn1, gr=gr1, control=con)
+ }
+ else {
+ help.stuff <- do.call(BFGShelp, args = list(initial = gout[5:(nvars+4)], done = TRUE),
+ envir = environment(fn))
+ hess.fn <- function(par, helper = help.stuff) fn1.bfgs(par, helper, ...)
+ hess <- stats::optimHess(par=gout[5:(nvars+4)], fn=hess.fn, gr=NULL, control=con)
+ }
+
+ hes <- 0.5 * (hess + t(hess))
+ if (!is.null(nm)) dimnames(hes) <- list(nm, nm)
+
+
+ ret <- list(value=value, par=par, gradients=gradients,
+ generations=gout[1], peakgeneration=gout[2], popsize=gout[3],
+ operators=operators,
+ hessian=hes)
+ }
+ else
+ {
+ ret <- list(value=value, par=par, gradients=gradients,
+ generations=gout[1], peakgeneration=gout[2], popsize=gout[3],
+ operators=operators)
+ }
+
+ if (clustertrigger==2)
+ parallel::stopCluster(cl)
+
+ interrupted <- FALSE
+
+ return(ret)
+} #end of genoud()
+
+genoud_transform <- function(fn, nvars, max=FALSE, pop.size=1000, max.generations=100, wait.generations=10,
+ hard.generation.limit=TRUE, starting.values=NULL, MemoryMatrix=TRUE,
+ Domains=NULL, default.domains=10, solution.tolerance=0.001,
+ gr=NULL, boundary.enforcement=0, lexical=FALSE, gradient.check=TRUE, BFGS=TRUE,
+ data.type.int=FALSE, hessian=FALSE, unif.seed=812821, int.seed=53058,
+ print.level=2, share.type=0, instance.number=0,
+ output.path="stdout", output.append=FALSE, project.path=NULL,
+ P1=50, P2=50, P3=50, P4=50, P5=50, P6=50, P7=50, P8=50, P9=0,
+ P9mix=NULL, BFGSburnin=0, BFGSfn=NULL, BFGShelp = NULL,
+ control = list(), optim.method=ifelse(boundary.enforcement < 2, "BFGS", "L-BFGS-B"),
+ transform=FALSE, debug=FALSE, cluster=FALSE, balance=FALSE, ...)
+{
+ #wrapper for the transform option. beta changes should go here as well
+ if(data.type.int)
+ stop("transform option cannot be used when 'data.type.int=TRUE'")
+
+ if(MemoryMatrix)
+ warning("setting MemoryMatrix to FALSE")
+
+ MemoryMatrix <- FALSE
+ if(!identical(cluster, FALSE)) warning("setting cluster to FALSE")
+ cluster <- FALSE
+
+ if(!is.null(BFGShelp) && !is.function(BFGShelp)) stop("'BFGShelp' must be NULL or a function")
+
+ #creating visible binding for variable "indx"; although it is
+ #actually defined in fnLexicalSort() via an eval and paste
+ if (!exists("indx"))
+ {
+ indx <- NULL; rm(indx)
+ }
+
+
+ if(!is.null(P9mix) && !is.double(P9mix)) {
+ stop("'P9mix' must be NULL or a number between 0 and 1")
+ } else {
+ if(is.null(P9mix)) {
+ P9mix <- -1
+ } else {
+ if(! ( (1 >= P9mix) && (P9mix > 0) ))
+ stop("'P9mix' must be NULL or a number between 0 and 1 (it may be equal to 1)")
+ }
+ }
+
+ if( (BFGSburnin < 0) & !gradient.check )
+ {
+ warning("If 'BFGSburnin' is negative, gradient.check must be TRUE for 'BFGSburnin' to have any effect.")
+ }
+
+ if(!is.list(control))
+ stop("'control' must be a list, see ?optim")
+ g.scale <- control$fnscale
+ if(!is.null(g.scale)) {
+ if(g.scale > 0 & max) {
+ stop("positive control$fnscale is inconsistent with maximization")
+ }
+ else if(g.scale < 0 & !max) {
+ stop("negative control$fnscale is inconsistent with minimization")
+ }
+ else if(g.scale == 0) {
+ stop("optim divides the function value by control$fnscale ",
+ "setting control$fnscale to zero is therefore impossible")
+ }
+ FiniteBadFitValue <- ifelse(max, -.Machine$double.xmax, .Machine$double.xmax)
+ }
+ else { # NULL g.scale
+ if (max == FALSE) {
+ g.scale <- 1
+ FiniteBadFitValue <- .Machine$double.xmax
+ }
+ else {
+ g.scale <- -1
+ FiniteBadFitValue <- -.Machine$double.xmax
+ }
+ }
+ control$fnscale <- g.scale
+
+ ## BFGSfn can (and probably should) be provided if transform = TRUE
+# if(!lexical & !is.null(BFGSfn))
+# {
+# stop("'BFGSfn' can only be provided with lexical optimization or when 'transform=TRUE'")
+# }
+ if (!is.null(BFGSfn) & BFGS==FALSE)
+ {
+ if (!is.function(BFGSfn))
+ stop("IF 'BFGSfn' is not a function, it must be NULL")
+ warning("setting BFGS==TRUE because 'BFGSfn' is not null")
+ BFGS <- TRUE
+ }
+
+ fn1 <- function(par) {
+ fit <- fn(par, ...)
+ if(!is.finite(fit[1])) fit[1] <- FiniteBadFitValue ## only catch [1]
+ return(fit)
+ }
+
+ if(!is.null(BFGShelp)) {
+ if (!is.null(gr)) {
+ gr1 <- function(par, helper = do.call(BFGShelp,
+ args = list(initial = par, done = TRUE))) {
+ gr(par, helper, ...)
+ }
+ } else gr1 <- NULL
+ }
+ else {
+ if (!is.null(gr)) {
+ gr1 <- function(par) gr(par, ...)
+ } else gr1 <- NULL
+ }
+
+ #setpath to tempdir
+ if(is.null(project.path))
+ {
+ project.path <- file.path(tempdir(), "genoud.pro")
+ }
+
+ #do we have stating values?
+ if (is.null(starting.values)) {
+ nStartingValues <- 0;
+ }
+ else if(is.matrix(starting.values)) {
+ if(any(dim(starting.values) == nvars)) {
+ if(nrow(starting.values) == nvars & ncol(starting.values) !=nvars) starting.values <- t(starting.values)
+ nStartingValues <- nrow(starting.values)
+ if(nStartingValues > pop.size) {
+ warning("increasing 'pop.size' because too many starting.values were provided")
+ pop.size <- nStartingValues
+ }
+ }
+ else {
+ warning("ignoring 'starting.values' because the wrong number of parameters was provided")
+ nStartingValues <- 0
+ }
+ }
+ else if(is.numeric(starting.values) | is.logical(starting.values)) {
+ nStartingValues <- 1;
+
+ if(length(starting.values)!=nvars)
+ {
+ nStartingValues <- 0
+ warning("Ignoring 'starting.values' because length(staring.values)!=nvars")
+ }
+ else starting.values <- matrix(starting.values, nrow = 1)
+ }
+ else stop("starting.values must be NULL, a vector, or a matrix")
+
+ #set output.type
+ if (output.path=="stdout")
+ {
+ output.type <- 0;
+ }
+ else
+ {
+ if (output.append)
+ {
+ output.type <- 2;
+ }
+ else
+ {
+ output.type <- 1;
+ }
+ }
+
+ # let's create the Domains if none have been passed.
+ if (!(is.matrix(Domains)))
+ {
+ Domains <- matrix(nrow=nvars, ncol=2);
+ for (i in 1:nvars)
+ {
+ Domains[i,1] <- -1*default.domains;
+ Domains[i,2] <- default.domains;
+ } # end of for loop
+ }
+ else if(nrow(Domains) != nvars) {
+ stop("number of rows in Domains must match 'nvars'")
+ }
+ else if(ncol(Domains) != 2) {
+ stop("number of cols in Domains must be 2")
+ }
+
+ if(!all(Domains[,1] <= Domains[,2])) {
+ stop("Domains[,1] must be less than or equal to Domains[,2]")
+ }
+ if(any(Domains[,1] == Domains[,2])) {
+ warning("some Domains[,1]==Domains[,2]")
+ }
+
+ # BG: now check all starting values are sane
+ if(nStartingValues > 0 && any(is.na(starting.values))) {
+ stop("Some starting values are NA")
+ }
+ if(nStartingValues > 0 && boundary.enforcement != 0 &&
+ !all(apply(starting.values, 1, FUN = function(x)
+ Domains[,1] <= x & x <= Domains[,2])) )
+ warning("'starting.values' which are outside of the bounds have been provided.
+ Continuing, but unexpected behavior can occur with 'boundary.enforcement!=0'")
+
+ # has the user provided any seeds?
+ if (unif.seed==812821 && int.seed==53058)
+ provide.seeds <- FALSE
+ else
+ provide.seeds <- TRUE;
+
+ # we need to know how many items will be returned bf fn()
+ if(nStartingValues)
+ {
+ foo <- fn1(starting.values[1,])
+ } else {
+ rfoo <- stats::runif(nrow(Domains), Domains[,1], Domains[,2])
+ foo <- fn1(rfoo)
+ }
+ foo.length <- length(c(foo))
+ if(foo.length <= nvars) stop("'fn' must return criteria and all transformed parameters")
+ lexical <- foo.length - nvars ## it is possible that lexical == 1 or lexical > 1
+
+ if (lexical >= 1) ## always TRUE
+ {
+ if(share.type > 0) {
+ warning("'share.type' being set to 0 because of 'transform' option")
+ share.type <- 0
+ }
+ if(is.null(BFGSfn))
+ {
+ #All derivative stuff is turned off if BFGSfn is not provided
+ BFGS <- FALSE
+ gradient.check <- FALSE
+ if(hessian) {
+ warning("'hessian' being set to false because of lexical optimization. See 'BFGSfn' for workaround")
+ hessian <- FALSE
+ }
+
+ P9 = 0
+ } else {
+ if(!is.null(BFGShelp)) {
+ fn1.bfgs <- function(par, helper = do.call(BFGShelp,
+ args = list(initial = par, done = TRUE),
+ envir = environment(fn))) {
+ fit <- BFGSfn(par, helper, ...)
+
+ if(is.null(fit)) fit <- FiniteBadFitValue
+
+ if(length(fit)==1) if(!is.finite(fit)) fit <- FiniteBadFitValue
+
+ return(fit)
+ }#end of fn1.bfgs
+ } else {
+ fn1.bfgs <- function(par) {
+ fit <- BFGSfn(par, ...)
+
+ if(is.null(fit)) fit <- FiniteBadFitValue
+
+ if(length(fit)==1) if(!is.finite(fit)) fit <- FiniteBadFitValue
+
+ return(fit)
+ }#end of fn1.bfgs
+ } # end else
+
+ if(is.null(gr)) { ## should we do numerical gradients when transform = TRUE?
+ gr <- function(par, helper = NA, ...)
+ {
+ gr.fn1.bfgs <- function(par, helper, FBFV) {
+ fit <- if(is.null(BFGShelp)) BFGSfn(par, ...) else BFGSfn(par, helper, ...)
+
+ if(is.null(fit))
+ fit <- FBFV
+
+ if(length(fit)==1)
+ if(!is.finite(fit))
+ fit <- FBFV
+
+ return(fit)
+ } # end of gr.fn1.bfgs
+ genoud.wrapper101.env <- new.env()
+ assign("x", par, envir = genoud.wrapper101.env)
+ assign("helper", helper, envir = genoud.wrapper101.env)
+ assign("FiniteBadFitValue", FiniteBadFitValue, envir = genoud.wrapper101.env)
+ foo <- as.double(attr(stats::numericDeriv(quote(gr.fn1.bfgs(x, helper, FiniteBadFitValue)), theta=c("x"), genoud.wrapper101.env), "gradient"))
+ return(foo)
+ } #end of gr
+ gr1 <- if(is.null(BFGShelp)) function(par, ...) gr(par) else
+ function(par, helper = do.call(BFGShelp, args = list(initial = par,
+ done = TRUE), envir = environment(fn))) {
+ gr(par, helper, ...)
+ } # end of gr1
+ } # end of if(!is.null(gr))
+ gr1func <- gr1
+ }# end of else
+ }#if lexical > 1
+
+ #optim st
+ if(is.null(BFGSfn))
+ {
+ if(optim.method != "L-BFGS-B") {
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ ret <- stats::optim(foo.vals, fn=fn1, gr=gr1, method=optim.method,
+ control=control);
+ return(c(ret$value,ret$par));
+ } # end of genoud.optim.wrapper101
+ }
+ else {
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ ret <- stats::optim(foo.vals, fn=fn1, gr=gr1, method="L-BFGS-B",
+ lower = Domains[,1], upper = Domains[,2],
+ control=control);
+ return(c(ret$value,ret$par));
+ } # end of genoud.optim.wrapper101
+ }
+ } else {
+ if(optim.method != "L-BFGS-B") {
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ if(print.level > 2) {
+ fit <- fn1(foo.vals)
+ cat("\nPre-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+ if(is.null(BFGShelp)) {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method=optim.method,
+ control=control);
+ }
+ else {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method=optim.method,
+ control=control,
+ helper = do.call(BFGShelp, args = list(initial = foo.vals), envir = environment(fn)) );
+ }
+
+ if(print.level > 2)
+ {
+ cat("BFGS Fit:",ret$value,"\n")
+
+ fit <- fn1(ret$par)
+ cat("Post-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+
+ foo <- c(ret$value,ret$par)
+ return(foo);
+ } # end of genoud.optim.wrapper101
+ } else { # "L-BFGS-B"
+ genoud.optim.wrapper101 <- function(foo.vals)
+ {
+ if(print.level > 2) {
+ fit <- fn1(foo.vals)
+ cat("\nPre-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+ if(is.null(BFGShelp)) {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method="L-BFGS-B",
+ lower = Domains[,1],
+ upper = Domains[,2],
+ control=control);
+ }
+ else {
+ ret <- stats::optim(foo.vals, fn=fn1.bfgs, gr=gr1, method="L-BFGS-B",
+ lower = Domains[,1],
+ upper = Domains[,2],
+ control=control,
+ helper = do.call(BFGShelp, args = list(initial = foo.vals), envir = environment(fn)) );
+ }
+
+ if(print.level > 2)
+ {
+ cat("BFGS Fit:",ret$value,"\n")
+
+ fit <- fn1(ret$par)
+ cat("Post-BFGS Complete Lexical Fit:\n")
+ print(fit)
+ }
+
+ foo <- c(ret$value,ret$par)
+ return(foo);
+ } # end of genoud.optim.wrapper101
+ }
+ }
+
+ # create the P vector
+ P <- vector(length=9, mode="numeric");
+ P[1] <- P1; P[2] <- P2; P[3] <- P3; P[4] <- P4;
+ P[5] <- P5; P[6] <- P6; P[7] <- P7; P[8] <- P8;
+ P[9] <- P9;
+
+ ## cluster is coerced to FALSE at the top so none of this matters
+ clustertrigger=1
+ if (is.logical(cluster))
+ {
+ if (cluster==FALSE) {
+ clustertrigger=0
+ } else {
+ stop("cluster option must be either FALSE, an object of the 'cluster' class (from the 'parallel' package) or a list of machines so 'genoud' can create such an object")
+ }
+ }
+
+ if(clustertrigger) {
+ parallel.exists = requireNamespace("parallel")
+ if (!parallel.exists) {
+ stop("The 'cluster' feature cannot be used unless the package 'parallel' can be loaded.")
+ }
+ }
+
+ if(clustertrigger)
+ {
+ if(!MemoryMatrix)
+ {
+ MemoryMatrix = TRUE
+ warning("MemoryMatrix has been set to 'TRUE' because the cluster option has been requested.")
+ }
+
+ GENclusterExport <- function (cl, list)
+ {
+ gets <- function(n, v) {
+ assign(n, v)
+ NULL
+ }
+ for (name in list) {
+ parallel::clusterCall(cl, gets, name, get(name))
+ }
+ }
+
+ ExpandDots <- function(...)
+ {
+ return(match.call())
+ }
+
+ dots <- ExpandDots(...)
+ if ( (length(dots) > 1) & balance==TRUE)
+ {
+ balance <- FALSE
+ warning("load balancing has been turned off because the function to be optimized requires extra arguments")
+ }
+
+ if (class(cluster)[1]=="SOCKcluster" | class(cluster)[1]=="PVMcluster" | class(cluster)[1]=="spawnedMPIcluster" | class(cluster)[1]=="MPIcluster") {
+ clustertrigger=1
+ cl <- cluster
+ GENclusterExport(cl, "fn")
+ GENclusterExport(cl, "fn1")
+ } else {
+ clustertrigger=2
+ cluster <- as.vector(cluster)
+ cat("Initializing Cluster\n")
+ cl <- parallel::makePSOCKcluster(cluster)
+ GENclusterExport(cl, "fn")
+ GENclusterExport(cl, "fn1")
+ }
+
+ if (length(cl) < 2 )
+ {
+ stop("You only have one node. You probably should not be using the cluster option")
+ }
+ }
+
+ fnLexicalSort <- function(mat, parms)
+ {
+ # parms = (1) MinMax, (2) nvars, (3) lexical_end, (4) type (0, vars, 1, obj)
+
+ decreasing=FALSE
+ if(parms[1]==1)
+ decreasing=TRUE
+
+ if(parms[4]==0)
+ {
+ #on nvars not on obj function
+ foo = "indx <- order("
+ for(i in (2:(parms[2]+1)) )
+ {
+ foo = paste(foo,"mat[,",i,"], ",sep="")
+ }
+ foo = paste(foo,"mat[,",parms[2]+2,"], ",sep="")
+ foo = paste(foo,"decreasing=FALSE)",sep="")
+ eval(parse(text=foo))
+ mat = mat[indx,]
+ } else {
+ #lexical on obj function
+ foo = "indx <- order(mat[,1], "
+ for(i in (parms[2]+3):parms[3] )
+ {
+ foo = paste(foo,"mat[,",i,"], ",sep="")
+ }
+ foo = paste(foo,"decreasing=",decreasing,")",sep="")
+ eval(parse(text=foo))
+ mat = mat[indx,]
+ }
+ return(mat)
+ }
+
+ fnMemoryMatrixEvaluate <- function(Memory, population, parms)
+ {
+ stop("this function should not be called when transform = TRUE")
+ EVALUATE = -93813381
+
+ MinMax = parms[1]
+ nvars = parms[2]
+ lexical = parms[3]
+
+ lexical.end = ncol(population)
+ pop.size = nrow(population)
+
+ vars.indx <- 2:(nvars+1)
+ lexical.indx <- c(1,(nvars+3):lexical.end)
+
+ FIRSTTIME = TRUE
+ if (nrow(Memory) > 1)
+ FIRSTTIME = FALSE
+
+ nevaluate = 0
+
+ mfunc <- function(pop,memory)
+ {
+ f <- function(...) paste(..., sep=":")
+ a2 <- do.call("f", as.data.frame(pop))
+ b2 <- do.call("f", as.data.frame(memory))
+
+ return(match(a2,b2))
+ }
+
+ population.mat = matrix(population[,vars.indx], ncol=nvars)
+ if (!FIRSTTIME)
+ {
+ Memory.mat = matrix(Memory[,vars.indx], ncol=nvars)
+ match.matrix.indx <- mfunc(population.mat,Memory.mat)
+
+ for (i in 1:pop.size)
+ {
+ match.indx = match.matrix.indx[i]
+ found.match <- FALSE
+ if ( is.finite(match.indx) )
+ {
+ #this is needed because mfunc truncates floats (by the call to paste) to 15 digits
+# if (all(population.mat[i,]==Memory.mat[match.indx,]))
+# {
+ found.match <- TRUE
+ population[i,] <- Memory[match.indx,]
+# }
+ }
+ if(!found.match)
+ {
+ if (population[i,nvars+2] != 0) {
+ population[i,nvars+2] = EVALUATE
+ nevaluate = nevaluate+1
+ }
+ }
+ }
+ } else {
+ for (i in 1:pop.size)
+ {
+ population[i,nvars+2] = EVALUATE
+ nevaluate = nevaluate+1
+ }
+ }
+
+ #evaluation loop
+ if (nevaluate > 0)
+ {
+ eval.indx <- population[,nvars+2]==EVALUATE
+ ret=0
+ if (clustertrigger==0)
+ {
+ in.mat = matrix(population.mat[eval.indx,], ncol=nvars)
+ ret <- matrix(t(apply(in.mat, 1, fn1)), ncol=lexical)
+ } else {
+ if (balance==TRUE) {
+ in.mat = t(matrix(population.mat[eval.indx,], ncol=nvars))
+ cl.in <- as.list(as.data.frame(in.mat))
+ cl.out <- parallel::clusterApplyLB(cl, cl.in, fn1)
+ try(ret <- matrix(t(data.frame(cl.out)), ncol=lexical), TRUE)
+ if (!is.matrix(ret)) {
+ if (!debug) {
+ stop("Cluster returned an object which could not be turned into a data.frame. Cluster may be in bad state. Please consider restarting it. To see what the cluster returned please turn on the 'debug' option.")
+ } else {
+ cat("Cluster returned an object which could not be turned into a data.frame:\n")
+ print(cl.out)
+ stop("Cluster may be in bad state. Please consider restarting it.")
+ }
+ }
+ } else {
+ in.mat = matrix(population.mat[eval.indx,], ncol=nvars)
+ if(length(cl) > 1 )
+ {
+ cl.out = parallel::parRapply(cl, in.mat, fn1)
+ } else {
+ stop("You only have one node. Cluster option should not be used")
+ }
+
+ try(ret <- matrix(cl.out, byrow=TRUE, ncol=lexical), TRUE)
+ if (!is.matrix(ret)) {
+ if (!debug) {
+ stop("Cluster returned an object which could not be turned into a data.frame. Cluster may be in bad state. Please consider restarting it. To see what the cluster returned please turn on the 'debug' option.")
+ } else {
+ cat("Cluster returned an object which could not be turned into a data.frame:\n")
+ print(cl.out)
+ stop("Cluster may be in bad state. Please consider restarting it.")
+ }
+ }
+ }
+ } # else clustertrigger==0
+
+ if (lexical < 2)
+ {
+ population[eval.indx,1] = ret[,1]
+ } else {
+ population[eval.indx,lexical.indx] = ret
+ }
+ population[eval.indx,nvars+2] = 0
+
+ if(!FIRSTTIME)
+ {
+ Memory = rbind(Memory,population[eval.indx,])
+ } else {
+ Memory = matrix(population[eval.indx,], ncol=lexical.end)
+ FIRSTTIME = FALSE
+ }
+ }#end of nevaluate
+
+ if (lexical > 1)
+ {
+ population <- fnLexicalSort(population, c(MinMax,nvars,lexical.end,1))
+ } else {
+ if (MinMax==0)
+ {
+ population <- population[order(population[,1]),]
+ } else {
+ population <- population[order(population[,1], decreasing=TRUE),]
+ }
+ }
+
+ return(as.vector(c(nrow(Memory), Memory, population)))
+ } #end of fnMemoryMatrixEvaluate
+
+ if (!is.null(gr))
+ {
+ UserGradient = TRUE
+ gr1func <- gr1
+ } else {
+ UserGradient = FALSE
+ gr1func <- function() {}
+ }
+
+ ## impossible
+ if(data.type.int)
+ {
+ BFGS = FALSE
+ gradient.check=FALSE
+ }
+
+ if(is.matrix(starting.values))
+ starting.values <- t(starting.values)
+
+ #C++ code checks if at least Generation 0 has been run and if
+ #print.level>0 and project.path!="/dev/null". Otherwise, 'interrupted'
+ #remains FALSE
+ interrupted <- FALSE
+ interrupt.message <- paste("genoud interrupted:\none may recover the best solution found so far by executing")
+ interrupt.expression <- paste("pop <- read.table('",project.path,
+ "', comment.char = 'G')", sep = "")
+ interrupt.expression2 <- "best <- pop[pop$V1 == 1,, drop = FALSE]"
+ interrupt.expression3 <- paste("very.best <- as.matrix(best[nrow(best), ",
+ foo.length + 2, ":ncol(best)])", sep = "")
+ on.exit(if(interrupted) cat(interrupt.message, "\n", interrupt.expression, "\n",
+ interrupt.expression2, "\n", interrupt.expression3, "\n"))
+
+ gout <- .Call("rgenoud", as.function(fn1), new.env(),
+ as.integer(nvars), as.integer(pop.size), as.integer(max.generations),
+ as.integer(wait.generations),
+ as.integer(nStartingValues), as.double(starting.values),
+ as.vector(P), as.matrix(Domains),
+ as.integer(max), as.integer(gradient.check), as.integer(boundary.enforcement),
+ as.double(solution.tolerance), as.integer(BFGS), as.integer(data.type.int),
+ as.integer(provide.seeds), as.integer(unif.seed), as.integer(int.seed),
+ as.integer(print.level), as.integer(share.type), as.integer(instance.number),
+ as.integer(MemoryMatrix), as.integer(debug),
+ as.character(output.path), as.integer(output.type), as.character(project.path),
+ as.integer(hard.generation.limit),
+ as.function(genoud.optim.wrapper101),
+ as.integer(lexical), as.function(fnLexicalSort), as.function(fnMemoryMatrixEvaluate),
+ as.integer(UserGradient), as.function(gr1func), as.double(P9mix),
+ as.integer(BFGSburnin), as.integer(transform),
+ PACKAGE="rgenoud");
+
+ indx1 <- 4;
+ indx2 <- (indx1+lexical-1);
+ value=gout[indx1:indx2];
+
+ indx1 <- indx2+1
+ indx2 <- indx1+nvars-1
+ par = gout[indx1:indx2]
+
+ indx1 <- indx2+1
+ indx2 <- indx1+nvars-1
+ if(!gradient.check & !BFGS )
+ {
+ gradients= gout[indx1:indx2]
+ gradients = rep(NA, length(gradients))
+ } else {
+ gradients = gout[indx1:indx2]
+ }
+
+ indx1 <- indx2+1
+ indx2 <- indx1+8
+ operators=gout[indx1:indx2]
+
+ if (hessian==TRUE) ## only TRUE if BFGSfn is provided
+ {
+ con <- list(trace = 0, fnscale = g.scale,
+ parscale = rep.int(1, length(par)), ndeps = rep.int(0.001, length(par)), maxit = 100,
+ abstol = -Inf, reltol = sqrt(.Machine$double.eps), alpha = 1,
+ beta = 0.5, gamma = 2, REPORT = 10, type = 1, lmm = 5,
+ factr = 1e+07, pgtol = 0, tmax = 10, temp = 10)
+
+ nm <- names(gout[5:(nvars+4)])
+
+# if(lexical == 1) {
+# hess.fn <- function(par) fn1(par, ...)
+# hess <- stats::optimHess(par=gout[5:(nvars+4)], fn=fn1, gr=gr1, control=con)
+# }
+# else {
+ help.stuff <- do.call(BFGShelp, args = list(initial = gout[5:(nvars+4)], done = TRUE),
+ envir = environment(fn))
+ hess.fn <- function(par, helper = help.stuff) fn1.bfgs(par, helper, ...)
+ hess <- stats::optimHess(par=gout[5:(nvars+4)], fn=hess.fn, gr=NULL, control=con)
+# }
+
+ hes <- 0.5 * (hess + t(hess))
+ if (!is.null(nm)) dimnames(hes) <- list(nm, nm)
+
+
+ ret <- list(value=value, par=par, gradients=gradients,
+ generations=gout[1], peakgeneration=gout[2], popsize=gout[3],
+ operators=operators,
+ hessian=hes)
+ }
+ else
+ {
+ ret <- list(value=value, par=par, gradients=gradients,
+ generations=gout[1], peakgeneration=gout[2], popsize=gout[3],
+ operators=operators)
+ }
+
+ if (clustertrigger==2)
+ parallel::stopCluster(cl)
+
+ interrupted <- FALSE
+
+ return(ret)
+}
diff --git a/R/zzz.R b/R/zzz.R
new file mode 100644
index 0000000..9d8e939
--- /dev/null
+++ b/R/zzz.R
@@ -0,0 +1,41 @@
+# RGENOUD
+#
+# Walter R. Mebane, Jr.
+# Cornell University
+# http://www-personal.umich.edu/~wmebane
+# <wmebane at umich.edu>
+#
+# Jasjeet Singh Sekhon
+# UC Berkeley
+# http://sekhon.berkeley.edu
+# <sekhon at berkeley.edu>
+#
+
+#.First.lib <- function(lib, pkg) library.dynam("rgenoud", pkg, lib)
+
+# use .onLoad instead of .First.lib for use with NAMESPACE and R(>= 1.7.0)
+.onLoad <- function(lib, pkg) {
+ library.dynam("rgenoud", pkg, lib)
+}#end of .onLoad
+
+.onUnload <- function(libpath) {
+ library.dynam.unload("rgenoud", libpath)
+}
+
+
+.onAttach <- function( ... )
+{
+ rgenoudLib <- dirname(system.file(package = "rgenoud"))
+ version <- utils::packageDescription("rgenoud", lib.loc = rgenoudLib)$Version
+ BuildDate <- utils::packageDescription("rgenoud", lib.loc = rgenoudLib)$Date
+
+ foo <- paste("## rgenoud (Version ", version, ", Build Date: ", BuildDate, ")\n",
+ "## See http://sekhon.berkeley.edu/rgenoud for additional documentation.\n",
+ "## Please cite software as:\n",
+ "## Walter Mebane, Jr. and Jasjeet S. Sekhon. 2011.\n",
+ "## ``Genetic Optimization Using Derivatives: The rgenoud package for R.''\n",
+ "## Journal of Statistical Software, 42(11): 1-26. \n##\n",
+ sep = "")
+
+ packageStartupMessage(foo)
+}
diff --git a/THANKS b/THANKS
new file mode 100644
index 0000000..e8316c1
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,7 @@
+The authors would like to thank the following people for their help and
+assistance:
+
+ Ben Goodrich <goodrich at fas.harvard.edu>
+ Erin Hartman <ekhartman at berkeley.edu>
+ Todd Rice <rice.toddm at gmail.com>
+ Jonathan Wand <wand at stanford.edu>
diff --git a/build/vignette.rds b/build/vignette.rds
new file mode 100644
index 0000000..3522ed8
Binary files /dev/null and b/build/vignette.rds differ
diff --git a/inst/CITATION b/inst/CITATION
new file mode 100644
index 0000000..ab1fc3b
--- /dev/null
+++ b/inst/CITATION
@@ -0,0 +1,37 @@
+citHeader("To cite 'rgenoud' in publications use:")
+
+citEntry(entry = "Article",
+ title = "Genetic Optimization Using Derivatives: The {rgenoud} Package for {R}",
+ author = personList(person(c("Walter", "R."), "Mebane, Jr."),
+ as.person("Jasjeet S. Sekhon")),
+ journal = "Journal of Statistical Software",
+ year = "2011",
+ volume = "42",
+ number = "11",
+ pages = "1--26",
+ url = "http://www.jstatsoft.org/v42/i11/",
+
+ textVersion =
+ paste("Walter R. Mebane, Jr., Jasjeet S. Sekhon (2011).",
+ "Genetic Optimization Using Derivatives: The rgenoud Package for R.",
+ "Journal of Statistical Software, 42(11), 1-26.",
+ "URL http://www.jstatsoft.org/v42/i11/.")
+)
+
+citEntry(header="To refer to the theory on which this package is based, also cite:",
+ entry="Article",
+ title = "Genetic Optimization Using Derivatives: Theory and Application to Nonlinear Models",
+ author = personList(as.person("Jasjeet S. Sekhon"),
+ person(c("Walter", "R."), "Mebane, Jr.")),
+ journal = "Political Analysis",
+ year = "1998",
+ volume = "7",
+ pages = "189--213",
+
+ textVersion =
+ paste("Jasjeet S. Sekhon, Walter R. Mebane, Jr. (1998).",
+ "Genetic Optimization Using Derivatives: Theory and Application to Nonlinear Models",
+ "Political Analysis, 7, 189-213.")
+)
+
+citFooter("BibTeX entries for LaTeX users: use\n", sQuote('toBibtex(citation("rgenoud"))'))
diff --git a/inst/doc/Figures/fig1.pdf b/inst/doc/Figures/fig1.pdf
new file mode 100644
index 0000000..6ee603f
Binary files /dev/null and b/inst/doc/Figures/fig1.pdf differ
diff --git a/inst/doc/Figures/lqdxmpl2B.pdf b/inst/doc/Figures/lqdxmpl2B.pdf
new file mode 100644
index 0000000..9f8cd43
Binary files /dev/null and b/inst/doc/Figures/lqdxmpl2B.pdf differ
diff --git a/inst/doc/rgenoud.R b/inst/doc/rgenoud.R
new file mode 100644
index 0000000..593d58e
--- /dev/null
+++ b/inst/doc/rgenoud.R
@@ -0,0 +1,159 @@
+### R code from vignette source 'rgenoud.Rnw'
+
+###################################################
+### code chunk number 1: rgenoud.Rnw:488-495
+###################################################
+ claw <- function(xx) {
+ x <- xx[1]
+ y <- (0.46*(dnorm(x,-1.0,2.0/3.0) + dnorm(x,1.0,2.0/3.0)) +
+ (1.0/300.0)*(dnorm(x,-0.5,.01) + dnorm(x,-1.0,.01) + dnorm(x,-1.5,.01)) +
+ (7.0/300.0)*(dnorm(x,0.5,.07) + dnorm(x,1.0,.07) + dnorm(x,1.5,.07)))
+ return(y)
+ }
+
+
+###################################################
+### code chunk number 2: rgenoud.Rnw:498-500
+###################################################
+library("rgenoud")
+claw1 <- genoud(claw, nvars=1, max=TRUE, pop.size=3000)
+
+
+###################################################
+### code chunk number 3: rgenoud.Rnw:855-877 (eval = FALSE)
+###################################################
+## source("supplemental.R")
+## gradcheck <- rep(TRUE,23)
+## gradcheck[6:7] <- FALSE
+## sizeset <- c(5000,10000)
+## genset <- c(30,100)
+## nreps <- 50
+## gsarray <- array(NA, dim=c(length(sizeset), length(genset), 23, nreps))
+## asc <- function(x) { as.character(x) }
+## dimnames(gsarray) <- list(asc(sizeset), asc(genset), NULL, NULL);
+## for (gsize in sizeset) {
+## for (ngens in genset) {
+## for (i in 1:23) {
+## for (j in 1:nreps) {
+## gsarray[as.character(gsize), as.character(ngens),i,j] <-
+## genoud(testfuncs[[i]], nvars=testNparms[i], pop.size=gsize,
+## max.gen=ngens, hard.gen=TRUE, Domains=testbounds[[i]],
+## solution.tol=1e-6, boundary=1, gradient.check=gradcheck[i],
+## print=0)$value
+## }
+## }
+## }
+## }
+
+
+###################################################
+### code chunk number 4: rgenoud.Rnw:1020-1027 (eval = FALSE)
+###################################################
+## LQDxmpl <- function(b) {
+## logistic <- function(x) { 1/(1+exp(-x)) }
+## sIQR <- function(y, yhat, n) {
+## IQR((y-yhat)/sqrt(yhat*(n-yhat)), na.rm=TRUE)
+## }
+## sIQR(y, m*logistic(x %*% b), m)
+## }
+
+
+###################################################
+### code chunk number 5: rgenoud.Rnw:1032-1038 (eval = FALSE)
+###################################################
+## m <- 100
+## x <- cbind(1,rnorm(1000),rnorm(1000))
+## b1 <- c(.5, 1, -1)
+## b2 <- c(0, -1, 1)
+## logistic <- function(x) { 1/(1+exp(-x)) }
+## y <- rbinom(1000, m, logistic(c(x[1:900,] %*% b1, x[901:1000,] %*% b2)))
+
+
+###################################################
+### code chunk number 6: rgenoud.Rnw:1047-1048 (eval = FALSE)
+###################################################
+## summary(glm1 <- glm(cbind(y,m-y) ~ x[,2] + x[,3], family="binomial"))
+
+
+###################################################
+### code chunk number 7: rgenoud.Rnw:1070-1073 (eval = FALSE)
+###################################################
+## suby <- y[1:900]
+## subx <- x[1:900,]
+## summary(glm2 <- glm(cbind(suby,m-suby) ~ subx[,2] + subx[,3], family="binomial"))
+
+
+###################################################
+### code chunk number 8: rgenoud.Rnw:1115-1132 (eval = FALSE)
+###################################################
+## dLQDxmpl <- function(b) {
+## eps <- 1e-10
+## logistic <- function(x) { 1/(1+exp(-x)) }
+## sIQR <- function(y, yhat, n) {
+## IQR((y-yhat)/sqrt(yhat*(n-yhat)), na.rm=TRUE)
+## }
+## dsIQR <- vector()
+## for (i in 1:length(b)) {
+## beps <- b
+## beps[i] <- b[i]+eps
+## dsIQR <-
+## c(dsIQR,
+## (sIQR(y, m*logistic(x %*% beps), m)-
+## sIQR(y, m*logistic(x %*% b), m))/eps)
+## }
+## return(dsIQR)
+## }
+
+
+###################################################
+### code chunk number 9: rgenoud.Rnw:1136-1151 (eval = FALSE)
+###################################################
+## blen <- 3
+## lenbseq <- length(bseq <- seq(-2,2,length=200))
+## bseq3 <- seq(-1.2,-.9,length=200)
+## bseq2 <- seq(.89,1.1,length=200)
+## IQRarr <- IQRarrA <- array(NA, dim=c((1+blen), lenbseq, lenbseq))
+## dimnames(IQRarrA) <- list(NULL, as.character(bseq), as.character(bseq))
+## dimnames(IQRarr) <- list(NULL, as.character(bseq2), as.character(bseq3))
+## for (i in 1:lenbseq) {
+## for (j in 1:lenbseq) {
+## IQRarrA[1,i,j] <- LQDxmpl(c(.5, bseq[i], bseq[j]))
+## IQRarrA[-1,i,j] <- dLQDxmpl(c(.5, bseq[i], bseq[j]))
+## IQRarr[1,i,j] <- LQDxmpl(c(.5, bseq2[i], bseq3[j]))
+## IQRarr[-1,i,j] <- dLQDxmpl(c(.5, bseq2[i], bseq3[j]))
+## }
+## }
+
+
+###################################################
+### code chunk number 10: rgenoud.Rnw:1154-1165 (eval = FALSE)
+###################################################
+## par(mfrow=c(2,2), lwd=.1)
+## contour(bseq,bseq, IQRarrA[1,,], main="IQR", xlab="b[2]", ylab="b[3]")
+## contour(bseq,bseq, IQRarrA[3,,], main="partial derivative w/r/t b[2]",
+## xlab="b[2]", ylab="b[3]")
+## loc2 <- (150:160)-5
+## loc3 <- (40:50)+5
+## contour(bseq[loc2],bseq[loc3], IQRarrA[3,loc2,loc3],
+## main="partial derivative w/r/t b[2]",
+## xlab="b[2]", ylab="b[3]")
+## contour(bseq2,bseq3, IQRarr[3,,], main="partial derivative w/r/t b[2]",
+## xlab="b[2]", ylab="b[3]")
+
+
+###################################################
+### code chunk number 11: rgenoud.Rnw:1221-1224 (eval = FALSE)
+###################################################
+## LQD1 <-
+## genoud(LQDxmpl, nvars=3, max=FALSE, pop.size=2000, max.generations=300,
+## wait.generations=100, gradient.check=FALSE, print=1)
+
+
+###################################################
+### code chunk number 12: rgenoud.Rnw:1292-1295 (eval = FALSE)
+###################################################
+## LQD1 <-
+## genoud(LQDxmpl, nvars=3, max=FALSE, pop.size=10000, max.generations=1000,
+## wait.generations=300, gradient.check=FALSE, print=1)
+
+
diff --git a/inst/doc/rgenoud.Rnw b/inst/doc/rgenoud.Rnw
new file mode 100644
index 0000000..c4b958b
--- /dev/null
+++ b/inst/doc/rgenoud.Rnw
@@ -0,0 +1,1465 @@
+\documentclass[nojss]{jss}
+
+\usepackage{amsmath}
+\usepackage{dcolumn}
+
+%%My declarations
+\newcommand{\hlink}{\htmladdnormallink}
+\newcommand{\MyPerp}{\perp \! \! \! \perp}
+
+\newcommand{\e}{\text{e-}}
+
+\newcolumntype{C}{>{$}c<{$}}
+\newcolumntype{L}{>{$}l<{$}}
+\newcolumntype{R}{>{$}r<{$}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% declarations for jss.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% almost as usual
+\author{Walter R. Mebane, Jr. \\
+ University of Michigan
+ \And
+ Jasjeet S. Sekhon \\
+ UC Berkeley}
+
+%% for pretty printing and a nice hypersummary also set:
+\title{Genetic Optimization Using Derivatives: The \pkg{rgenoud} Package for \proglang{R}}
+\Plaintitle{Genetic Optimization Using Derivatives: The rgenoud Package for R}
+\Plainauthor{Walter R. Mebane, Jr., Jasjeet S. Sekhon} %% comma-separated
+\Shorttitle{\pkg{rgenoud}: Genetic Optimization Using Derivatives in \proglang{R}}
+
+%% an abstract and keywords
+\Abstract{ This introduction to the \proglang{R} package \pkg{rgenoud}
+ is a modified version of \cite{MebaneJr.+Sekhon:2011}, published in
+ the \textit{Journal of Statistical Software}. That version of the
+ introduction contains higher resolution figures.
+
+ \code{genoud} is an \proglang{R} function that combines
+ evolutionary algorithm methods with a derivative-based
+ (quasi-Newton) method to solve difficult optimization problems.
+ \code{genoud} may also be used for optimization problems for which
+ derivatives do not exist. \code{genoud} solves problems that are nonlinear
+ or perhaps even discontinuous in the parameters of the function to
+ be optimized. When the function to be optimized (for
+ example, a log-likelihood) is nonlinear in the model's parameters,
+ the function will generally not be globally concave
+ and may have irregularities such as saddlepoints or discontinuities.
+ Optimization methods that rely on derivatives of the objective
+ function may be unable to find any optimum at all. Multiple local
+ optima may exist, so that there is no guarantee that a
+ derivative-based method will converge to the global optimum. On the
+ other hand, algorithms that do not use derivative information (such
+ as pure genetic algorithms) are for many problems needlessly poor at
+ local hill climbing. Most statistical problems are regular in a
+ neighborhood of the solution. Therefore, for some portion of the
+ search space, derivative information is useful. The function
+ supports parallel processing on multiple CPUs on a single machine or
+ a cluster of computers.}
+
+\Keywords{genetic algorithm, evolutionary program, optimization, parallel computing, \proglang{R}}
+\Plainkeywords{genetic algorithm, evolutionary program, optimization, parallel computing, R} %% without formatting
+%% at least one keyword must be supplied
+
+%% publication information
+%% NOTE: This needs to filled out ONLY IF THE PAPER WAS ACCEPTED.
+%% If it was not (yet) accepted, leave them commented.
+\Volume{42}
+\Issue{11}
+%\Month{September}
+\Year{2011}
+\Submitdate{2007-02-11}
+\Acceptdate{2007-11-21}
+
+%% The address of (at least) one author should be given
+%% in the following format:
+\Address{
+ Walter R. Mebane, Jr.\\
+% Professor\\
+ Department of Political Science\\
+ Department of Statistics\\
+ University of Michigan\\
+ Ann Arbor, MI 48109-1045\\
+ E-mail: \email{wmebane at umich.edu}\\
+ URL: \url{http://www.umich.edu/~wmebane} \\ [2ex]
+
+ Jasjeet S. Sekhon\\
+ Department of Political Science\\
+ Department of Statistics\\
+ 210 Barrows Hall \#1950\\
+ UC Berkeley\\
+ Berkeley, CA 94720-1950\\
+ E-mail: \email{sekhon at berkeley.edu}\\
+ URL: \url{http://sekhon.berkeley.edu}
+}
+%% It is also possible to add a telephone and fax number
+%% before the e-mail in the following format:
+%% Telephone: +43/1/31336-5053
+%% Fax: +43/1/31336-734
+
+%% for those who use Sweave please include the following line (with % symbols):
+%% need no \usepackage{Sweave.sty}
+
+%% end of declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\graphicspath{{Figures/}}
+
+\begin{document}
+\SweaveOpts{engine=R}
+%\VignetteIndexEntry{Using genoud}
+%\VignetteDepends{rgenoud}
+%\VignetteKeywords{rgenoud}
+%\VignettePackage{rgenoud}
+
+\section{Introduction}
+
+We developed the \proglang{R} package \pkg{rgenoud} to solve difficult
+optimization problems such as often arise when estimating nonlinear
+statistical models or solving complicated nonlinear, nonsmooth and
+even discontinuous functions.\footnote{The \pkg{rgenoud} software
+ package is available from the Comprehensive \proglang{R}
+ \citep{Rcore} Archive Network at
+ \url{http://CRAN.R-project.org/package=rgenoud}.} Optimization
+difficulties often arise when the objective function (for instance,
+the log-likelihood) is a nonlinear function of the parameters. In such
+cases the function to be optimized is usually not globally concave.
+An objective function that is not globally concave may have multiple
+local optima, saddle points, boundary solutions or discontinuities.
+While the objective function for a statistical model is often concave
+in a neighborhood of the optimal solution, that neighborhood is often
+a small proportion of the parameter space of potential interest, and
+outside that neighborhood the function may be irregular. In such
+cases, methods of optimization that depend entirely on derivatives can
+be unreliable and often are virtually unusable. Newton-Raphson and
+quasi-Newton methods are among the commonly used optimization methods
+that rely completely on derivatives. Such methods work well when the
+function to be optimized is regular and smooth over the domain of
+parameter values that is of interest, but otherwise the methods often
+fail \citep{GillMurrayWright1981}. Even in models where such methods
+can be expected to work most of the time, resampling techniques such
+as the bootstrap \citep{EfronTibshirani1994} can generate resamples in
+which derivative-based optimization algorithms encounter severe
+difficulties. This is unfortunate because the methods most frequently
+used for optimization in problems of statistical estimation are
+entirely based on derivatives.
+
+The \pkg{rgenoud} package has been used by wide variety of users and
+developers. More than twelve \proglang{R} packages currently rely upon
+\pkg{rgenoud} including:
+\pkg{anchors} \citep[analyzing survey data with
+anchoring vignettes,][]{Wand+King:2011,WandKingLau2007,KingWand2007};
+\pkg{BARD} \citep[automated redistricting,][]{Altman+McDonald:2011};
+\pkg{boolean} \citep[boolean binary response models,][]{braumoeller2003,BraumoellerGoodrichKline2006};
+\pkg{DiceOptim} \citep[kriging-based optimization for computer experiments,][]{DiceOptim};
+\pkg{FAiR} \citep[factor analysis,][]{goodrich.fair};
+\pkg{JOP} \citep[simultaneous optimization of multiple responses,][]{JOP};
+\pkg{KrigInv} \citep[kriging-based inversion,][]{KrigInv};
+\pkg{PKfit} \citep[data analysis in pharmacokinetics,][]{LeeLee2006};
+\pkg{Matching} \citep[propensity score and multivariate matching,][]{SekhonMatching,Sekhon:2011};
+\pkg{ivivc} \citep[in vitro-in vivo correlation modeling,][]{ivivc};
+\pkg{multinomRob} \citep[robust multinomial models,][]{MebaneSekhon.multinomRob,MebaneSekhon2004}; and
+\pkg{Synth} \citep[synthetic control group method for comparative case studies,][]{AbadieGardeazabal2003,synth2008,Abadie+Diamond+Hainmueller:2011}.
+
+We present in Section \ref{sec:examples} an example using benchmark functions
+taken from \citet{yao.liu.lin1999}, followed by an example motivated by the
+\code{multinomRob} package. The benchmark suite includes functions that are
+high-dimensional, discontinuous or that have many local optima. The
+\code{multinomRob} package robustly estimates overdispersed multinomial
+regression models and uses \pkg{rgenoud} to solve a least quartile difference
+(LQD) generalized S-estimator \citep{MebaneSekhon2004}. The LQD is not a
+smooth function of the regression model parameters. The function is
+continuous, but the parameter space is finely partitioned by nondifferentiable
+boundaries.
+
+In another paper in this volume, the \pkg{Matching} package and its
+use of \pkg{rgenoud} are described in detail \citep{Sekhon:2011}.
+\pkg{Matching} provides functions for multivariate and propensity
+score matching and for finding optimal covariate balance based on a
+genetic search algorithm implemented in \pkg{rgenoud}. The search
+over optimal matches is discontinuous so no derivatives are
+used.\footnote{The \code{BFGS} option of \code{genoud} is set to
+ \code{FALSE}, and the ninth operator which depends on derivatives is
+ not used.} The search also involves lexical
+optimization which is a unique feature implemented in
+\pkg{rgenoud}.\footnote{Lexical optimization is useful when there are
+ multiple fitness criteria; the parameters are chosen so as to
+ maximize fitness values in lexical order---i.e., the second fit criterion
+ is only considered if the parameters have the same fit for the
+ first. See the \code{lexical} option and \citet{Sekhon:2011} for
+ details. All of \code{genoud}'s options are described in the
+ \proglang{R} help file for the function.}
+
+% If one wishes to use such a model,
+%significant optimization difficulties may need to be overcome. For
+%example, the estimating functions of all of the following models are
+%not in general globally concave: models with multivariate qualitative
+%variables, censoring or endogenous switching
+%\citep{maddala1983,amemiya1985}; linear covariance structures
+%\citep{bollen1989}; models for durations or transitions with
+%unobserved heterogeneity \citep{HeckmanSinger1985,lancaster1990};
+%quasi-likelihood and extended quasi-likelihood models
+%\citep{McCullaghNelder1989} and systems based on such models
+%\citep{FahrmeirTutz1994}; and nonlinear simultaneous equation models
+%\citep{gallant1987}. For such models, optimization methods driven
+%entirely by derivatives are often unreliable. For some versions of
+%some of these models, algorithms such as EM that involve data
+%augmentation have been successfully applied to produce optimization
+%problems that derivative-based methods can solve
+%\citep[e.g.,][197]{lancaster1990}.
+
+The \pkg{rgenoud} package implements an updated and extended version
+of the \proglang{C} program \code{GENOUD} \citep{MebaneSekhon1997}
+described in \citep{SekhonMebane1998}. The many improvements include
+among other things the interface with \proglang{R}, which includes the
+ability to optimize functions written in \proglang{R}, options to
+optimize both floating point and integer-valued parameters, the
+ability to optimize loss functions which return multiple fitness values
+(lexical optimization), the ability to call \code{genoud} recursively,
+the ability to have the optimizer evaluate fits only for new parameter
+values, and the ability to use multiple computers, CPUs or cores to
+perform parallel computations.
+
+The \pkg{rgenoud} program combines an evolutionary algorithm with a
+quasi-Newton method. The quasi-Newton method is the
+Broyden-Fletcher-Goldfarb-Shanno (BFGS) method
+\citep[][119]{GillMurrayWright1981} implemented in \proglang{R}'s \code{optim}
+function. When the BFGS is being used, our program offers the option of using
+either \pkg{rgenoud}'s built-in numerical derivatives (which are based on
+code taken from \citealt[][337--344]{GillMurrayWright1981}) or user-supplied
+analytical derivatives.\footnote{User supplied derivatives may be provides via
+ the \code{gr} option.} Our program can also work without the BFGS, in which
+case no derivatives are needed and the optimizer will work even when the
+function is discontinuous. The primary benefit from using derivatives is that
+the algorithm will then quickly find a local optimum when a current set of
+trial solution parameter values is in a smooth neighborhood of the local
+optimum point. Appropriate use of the BFGS can make the algorithm converge to
+the global optimum much more quickly. But premature or excessive use of the
+BFGS can prevent convergence to the global optimum.\footnote{The user can
+ control whether \code{genoud} uses the BFGS at all (via the \code{BFGS}
+ option), and if operators that use the BFGS are used (via the \code{P9}
+ option), how often they are used.} As always, it is hazardous to rely on an
+optimizer's default settings. Our program does not eliminate the need for
+judgment, testing and patience.
+
+As Gill, Murray and Wright observe, ``there is no guaranteed strategy that
+will resolve every difficulty'' \citep[285]{GillMurrayWright1981}. In this article, we very briefly
+review the theory of random search algorithms that supports the assertion that
+\pkg{rgenoud} has a high probability of finding the global optimum when such
+exists. And we present three examples of how to use the \code{genoud}
+function: to optimize a simple but fiendish scalar Normal mixture model; to
+minimize a suite of benchmark functions that have previously been used to test
+evolutionary programming optimization algorithms; and to optimize a version of
+the only intermittently differentiable LQD estimator. Additional details on
+both the theory and performance of \code{genoud} can be found in our article
+that describes \code{GENOUD} \citep{SekhonMebane1998}.
+
+\section{Background on Genetic Optimization}
+
+An evolutionary algorithm (EA) uses a collection of heuristic rules to
+modify a population of trial solutions in such a way that each
+generation of trial values tends to be, on average, better than its
+predecessor. The measure for whether one trial solution is better
+than another is the trial solution's fitness value. In statistical
+applications, the fitness is a function of the summary statistic being
+optimized (e.g., the log-likelihood). \pkg{rgenoud} works for cases
+in which a solution is a vector of floating-point or integer numbers
+that serve as the parameters of a function to be optimized. The
+search for a solution proceeds via a set of heuristic rules, or
+\textit{operators}, each of which acts on one or more trial solutions
+from the current population to produce one or more trial solutions to
+be included in the new population. EAs do not require derivatives to
+exist or the function to be continuous in order find the global
+optimum.
+
+The EA in \pkg{rgenoud} is fundamentally a genetic algorithm (GA) in which
+the code-strings are vectors of numbers rather than bit
+strings, and the GA operators take special forms tuned for the
+floating-point or integer vector representation. A GA uses a set of randomized
+genetic operators to evolve a finite population of finite code-strings
+over a series of generations
+\citep{holland1975,goldberg1989,GrefenstetteBaker1989}. The operators
+used in GA implementations vary
+\citep{davis1991,FilhoTreleavenAlippi1994}, but in an analytical sense
+the basic set of operators can be defined as reproduction, mutation,
+crossover and inversion. The variation in these operators across different
+GA implementations reflects
+the variety of codes best suited for different applications.
+Reproduction entails selecting a code-string with a probability that
+increases with the code-string's fitness value. Crossover and
+inversion use pairs or larger sets of the selected code-strings to
+create new code-strings. Mutation randomly changes the values of
+elements of a single selected code-string.
+
+Used in suitable combinations, the genetic operators tend to improve
+average fitness of each successive generation, though there is no
+guarantee that average fitness will improve between every pair of
+successive generations. Average fitness may well decline. But
+theorems exist to prove that parts of the trial solutions that have above average
+fitness values in the current population are sampled at an
+exponential rate for inclusion in the subsequent population
+\citep[][139--140]{holland1975}. Each generation's population
+contains a biased sample of code-strings, so that a substring's
+performance in that population is a biased estimate of its average
+performance over all possible populations
+\citep{dejong1993,grefenstette1993}.
+
+The long-run properties of a GA may be understood by thinking of the GA as a
+Markov chain. A state of the chain is a code-string population of the size
+used in the GA. For code-strings of finite length and GA populations of
+finite size, the state space is finite. If such a GA uses random reproduction
+and random mutation, all states always have a positive probability of
+occurring. A finite GA with random reproduction and mutation is therefore
+approximately a finite and irreducible Markov
+chain.\footnote{\citet[][372--419]{feller1970} and
+ \citet[][107--142]{billingsley1986} review the relevant properties of Markov
+ chains. The randomness in an actual GA depends on the performance of
+ pseudorandom number generators. This and the limitations of floating point
+ arithmetic mean it is not literally true that an actual GA has a positive
+ probability of reaching any state from any other state, and some states may
+ in fact not be reachable from a given set of initial conditions.} An
+irreducible, finite Markov chain converges at an exponential rate to a unique
+stationary distribution \citep[][128]{billingsley1986}. This means that the
+probability that each population occurs rapidly converges to a constant,
+positive value. \citet{NixVose1992} and
+\citet{vose1993} use a Markov chain model to show that in a GA where the
+probability that each code-string is selected to reproduce is proportional to
+its observed fitness, the stationary distribution strongly emphasizes
+populations that contain code-strings that have high fitness values. They
+show that asymptotic in the population size---i.e., in the limit for a series
+of GAs with successively larger populations---populations that have suboptimal
+average fitness have probabilities approaching zero in the stationary
+distribution, while the probability for the population that has optimal
+average fitness approaches one. If $k>1$ populations have optimal average
+fitness, then in the limiting stationary distribution the probability for each
+approaches $1/k$.
+
+The theoretical results of Nix and Vose imply that a GA's success as an
+optimizer depends on having a sufficiently large population of code-strings.
+If the GA population is not sufficiently large, then the Markov chain that the
+GA approximately implements is converging to a stationary distribution in
+which the probabilities of optimal and suboptimal states are not sharply
+distinguished. Suboptimal populations can be as likely to occur as optimal
+ones. If the stationary distribution is not favorable, the run time in terms
+of generations needed to produce an optimal code-string will be excessive.
+For all but trivially small state spaces, an unfavorable stationary
+distribution can easily imply an expected running time in the millions of
+generations. But if the stationary distribution strongly emphasizes optimal
+populations, relatively few generations may be needed to find an optimal
+code-string. In general, the probability of producing an optimum in a fixed
+number of generations tends to increase with the GA population size.
+
+\begin{table}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\begin{enumerate}
+\item[\code{P1}] Cloning. Copy $\mathbf{X}_{t}$ into the next generation,
+ $\mathbf{X}_{t+1}$.
+\item[\code{P2}] Uniform Mutation. At random choose $i\in\mathbf{N}$. Select a value
+ $\tilde{x}_i \sim U(\underline{x}_i, \overline{x}_i)$. Set
+ $X_i=\tilde{x}_i$.
+\item[\code{P3}] Boundary Mutation. At random choose $i\in\mathbf{N}$. Set either
+ $X_i=\underline{x}_i$ or $X_i=\overline{x}_i$, with probability $1/2$ of
+ using each value.
+\item[\code{P4}] Non-uniform Mutation. At random choose $i\in\mathbf{N}$. Compute
+ $p = (1-t/T)^B u$, where $t$ is the current generation number, $T$ is the
+ maximum number of generations, $B>0$ is a tuning parameter and $u \sim
+ U(0,1)$. Set either $X_i=(1-p)x_i + p\underline{x}_i$ or $X_i=(1-p)x_i +
+ p\overline{x}_i$, with probability $1/2$ of using each value.
+\item[\code{P5}] Polytope Crossover. Using $m=\max(2,n)$ vectors
+ $\mathbf{x}$ from the current population and $m$ random numbers
+ $p_j\in(0,1)$ such that $\sum_{j=1}^m p_j = 1$, set $\mathbf{X} =
+ \sum_{j=1}^m p_j \mathbf{x}_j$.
+\item[\code{P6}] Simple Crossover. Choose a single integer $i$ from $\mathbf{N}$.
+ Using two parameter vectors, $\mathbf{x}$ and $\mathbf{y}$,
+ set $X_i = p x_i + (1-p) y_i$ and $Y_i = p y_i + (1-p)
+ x_i$, where $p\in(0,1)$ is a fixed number.
+\item[\code{P7}] Whole Non-uniform Mutation. Do non-uniform mutation for
+ all the elements of $\mathbf{X}$.
+\item[\code{P8}] Heuristic Crossover. Choose $p \sim U(0,1)$. Using two parameter
+ vectors, $\mathbf{x}$ and $\mathbf{y}$, compute $\mathbf{z} =
+ p(\mathbf{x} - \mathbf{y}) + \mathbf{x}$. If $\mathbf{z}$ satisfies
+ all constraints, use it. Otherwise choose another $p$ value and repeat.
+ Set $\mathbf{z}$ equal to the better of $\mathbf{x}$ and $\mathbf{y}$ if
+ a satisfactory mixed $\mathbf{z}$ is not found by a preset number of
+ attempts. In this fashion produce two $\mathbf{z}$ vectors.
+\item[\code{P9}] Local-minimum Crossover. Choose $p \sim U(0,1)$.
+ Starting with $\mathbf{x}$, run BFGS optimization up to a preset
+ number of iterations to produce $\mathbf{\tilde{x}}$. Compute
+ $\mathbf{z} = p\mathbf{\tilde{x}} + (1-p)\mathbf{x}$. If
+ $\mathbf{z}$ satisfies boundary constraints, use it. Otherwise
+ shrink $p$ by setting $p = p/2$ and recompute $\mathbf{z}$. If a
+ satisfactory $\mathbf{z}$ is not found by a preset number of
+ attempts, return $\mathbf{x}$. This operators is extremely
+ computationally intensive, use sparingly.
+\end{enumerate}
+
+\begin{flushleft}
+ Notation: \\ [2ex]
+ $\mathbf{X} =\begin{bmatrix}X_1,\dots,X_n\end{bmatrix}$ is the
+ vector of $n$ parameters $X_i$. $\underline{x}_i$ is the lower
+ bound and $\overline{x}_i$ is the upper bound on values for $X_i$.
+ $x_i$ is the current value of $X_i$, and $\mathbf{x}$ is the current
+ value of $\mathbf{X}$. $\mathbf{N} = \{1,\dots,n\}$. $p \sim
+ U(0,1)$ means that $p$ is drawn from the uniform distribution on the
+ $[0,1]$ interval.
+\end{flushleft}
+ \caption{`genoud' Operators. Adapted from \citet{SekhonMebane1998}.}
+\label{tab:operators}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+The evolutionary algorithm in \pkg{rgenoud} uses nine operators that
+are listed in Table~\ref{tab:operators}. The operators extend and
+modify a set of operators used in \code{GENOCOP}
+\citep{MichalewiczSwaminathanLogan1993, Michalewicz1992}. The
+operators are numbered using syntax matching that used to refer to
+them by \pkg{rgenoud}. The \textit{cloning} operator simply makes
+copies of the best trial solution in the current generation
+(independent of this operator, \pkg{rgenoud} always retains one
+instance of the best trial solution). The \textit{uniform mutation},
+\textit{boundary mutation} and \textit{non-uniform mutation} operators
+act on a single trial solution. Uniform mutation changes one
+parameter in the trial solution to a random value uniformly
+distributed on the domain specified for the parameter. Boundary
+mutation replaces one parameter with one of the bounds of its domain.
+Non-uniform mutation shrinks one parameter toward one of the bounds,
+with the amount of shrinkage decreasing as the generation count
+approaches the specified maximum number of generations. \textit{Whole
+ non-uniform mutation} does non-uniform mutation for all the
+parameters in the trial solution. \textit{Heuristic crossover} uses
+two trial solutions to produce a new trial solution located along a
+vector that starts at one trial solution and points away from the
+other one. \textit{Polytope crossover} (inspired by simplex search,
+\citealt[][94--95]{GillMurrayWright1981}) computes a trial solution
+that is a convex combination of as many trial solutions as there are
+parameters. \textit{Simple crossover} computes two trial solutions
+from two input trial solutions by swapping parameter values between
+the solutions after splitting the solutions at a randomly selected
+point. This operator can be especially effective if the ordering of
+the parameters in each trial solution is consequential.
+\textit{Local-minimum crossover} computes a new trial solution in two
+steps: first it does a preset number of BFGS iterations starting from
+the input trial solution; then it computes a convex combination of the
+input solutions and the BFGS iterate.
+
+
+\section{Examples}
+\label{sec:examples}
+
+The only function in the \pkg{rgenoud} package is \code{genoud}. The
+interface of this function is similar to that of the \code{optim}
+function in \proglang{R}. But the function has many additional
+arguments that control the behavior of the evolutionary algorithm.
+
+\subsection{Asymmetric Double Claw:}
+Our first example, which we also studied in \citet{SekhonMebane1998}, is a
+normal mixture called the Asymmetric Double Claw (ADC). We plot the function
+in Figure~\ref{fig:mixture1}.
+\begin{figure}
+ \caption{Normal Mixture: Asymmetric Double Claw}
+ \vspace{-.5in}
+ \label{fig:mixture1}
+ \begin{center}
+ \includegraphics{fig1.pdf}
+ \end{center}
+ \vspace{-.7in}
+\end{figure}
+Mathematically, this mixture is defined as
+\begin{eqnarray}
+ \label{eq:adclaw}
+ f_{\mathrm{ADC}} & =
+ \sum_{m=0}^{1} \frac{46}{100} \mathrm{N}\left(2m-1,\frac{2}{3}\right) +
+ \sum_{m=1}^{3} \frac{1}{300} \mathrm{N}\left(\frac{-m}{2},\frac{1}{100}\right) +
+ \sum_{m=1}^{3} \frac{7}{300} \mathrm{N}\left(\frac{m}{2},\frac{7}{100}\right),
+\end{eqnarray}
+where N is the normal density.
+
+The asymmetric double claw is difficult to maximize because there are
+many local solutions. There are five local maxima in Figure
+\ref{fig:mixture1}. Standard derivative-based optimizers would
+simply climb up the hill closest to the starting value.
+
+To optimize this normal mixture we must first create a function for it
+<<eval=true,results=hide>>=
+ claw <- function(xx) {
+ x <- xx[1]
+ y <- (0.46*(dnorm(x,-1.0,2.0/3.0) + dnorm(x,1.0,2.0/3.0)) +
+ (1.0/300.0)*(dnorm(x,-0.5,.01) + dnorm(x,-1.0,.01) + dnorm(x,-1.5,.01)) +
+ (7.0/300.0)*(dnorm(x,0.5,.07) + dnorm(x,1.0,.07) + dnorm(x,1.5,.07)))
+ return(y)
+ }
+@
+And we now make a call to \pkg{rgenoud} using this function:
+<<eval=true,results=hide>>=
+library("rgenoud")
+claw1 <- genoud(claw, nvars=1, max=TRUE, pop.size=3000)
+@
+
+The first argument of \code{genoud} is the function to be optimized. The first
+argument of that function must be the vector of parameters over which
+optimizing is to occur. Generally, the function should return a
+scalar result.\footnote{The function to be optimized may return a
+ vector if one wishes to do lexical optimization. Please see
+ the \code{lexical} option to \code{genoud}.} The second argument of \code{genoud} in this example
+(\code{nvars}) is
+the number of variables the function to be optimized takes.
+The third argument, \code{max=TRUE}, tells
+\code{genoud} to maximize the function instead of its default behavior
+which is to minimize.
+
+The fourth option \code{pop.size} controls the most important part
+of the evolutionary algorithm, the population size. This is the
+number of individuals \code{genoud} uses to solve the optimization
+problem. As noted in the theoretical discussion, the theorems related
+to evolutionary algorithms are asymptotic in the population size so
+larger is generally better but obviously takes longer. The maximum
+solution of the double claw density is reliably found by \code{genoud}
+even using the default value of \code{pop.size=1000}.
+Reliability does increase as the \code{pop.size} is made larger.
+Unfortunately, because of the stochastic nature of the algorithm, it
+is impossible to generally answer the question of what is the best
+population size to use.
+
+Other options determine the maximum number of generations the evolutionary
+algorithm computes. These options are \code{max.generations},
+\code{wait.generations} and \code{hard.generation.limit}. The specified
+termination point also affects how some of the operators perform: the two
+non-uniform mutation operators introduce smaller ranges of variation in the
+trial solutions as the generation count approaches the specified
+\code{max.generations} value. There are many more options that can be used
+to fine-tune the behavior of the algorithm.
+
+The output printed by \code{genoud} is controlled by a \code{print.level}
+argument. The default value, \code{print.level=2}, produces relatively
+verbose output that gives extensive information about the set of operators
+being used and the progress of the optimization. Normally \proglang{R}
+conventions would suggest setting the default to be \code{print.level=0},
+which would suppress output to the screen, but because \code{genoud} runs may
+take a long time, it can be important for the user to receive some feedback to
+see the program has not died and to be able to see where the program got stuck
+if it eventually fails to make adequate progress.
+
+The output printed by the preceding invocation of \code{genoud}, which uses
+the default value for a \code{print.level} argument, is as follows.
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Fri Feb 9 19:33:42 2007
+Domains:
+ -1.000000e+01 <= X1 <= 1.000000e+01
+
+Data Type: Floating Point
+Operators (code number, name, population)
+ (1) Cloning........................... 372
+ (2) Uniform Mutation.................. 375
+ (3) Boundary Mutation................. 375
+ (4) Non-Uniform Mutation.............. 375
+ (5) Polytope Crossover................ 375
+ (6) Simple Crossover.................. 376
+ (7) Whole Non-Uniform Mutation........ 375
+ (8) Heuristic Crossover............... 376
+ (9) Local-Minimum Crossover........... 0
+
+HARD Maximum Number of Generations: 100
+Maximum Nonchanging Generations: 10
+Population size : 3000
+Convergence Tolerance: 1.000000e-03
+
+Using the BFGS Derivative Based Optimizer on the Best Individual Each Generation.
+Checking Gradients before Stopping.
+Using Out of Bounds Individuals.
+
+Maximization Problem.
+GENERATION: 0 (initializing the population)
+Fitness value... 4.112017e-01
+mean............ 4.990165e-02
+variance........ 9.708147e-03
+#unique......... 3000, #Total UniqueCount: 3000
+var 1:
+best............ 9.966758e-01
+mean............ 3.453097e-02
+variance........ 3.373681e+01
+
+GENERATION: 1
+Fitness value... 4.113123e-01
+mean............ 2.237095e-01
+variance........ 2.566140e-02
+#unique......... 1858, #Total UniqueCount: 4858
+var 1:
+best............ 9.995043e-01
+mean............ 4.615946e-01
+variance........ 7.447887e+00
+
+[...]
+
+GENERATION: 10
+Fitness value... 4.113123e-01
+mean............ 2.953888e-01
+variance........ 2.590842e-02
+#unique......... 1831, #Total UniqueCount: 21708
+var 1:
+best............ 9.995033e-01
+mean............ 8.403935e-01
+variance........ 5.363241e+00
+
+GENERATION: 11
+Fitness value... 4.113123e-01
+mean............ 2.908561e-01
+variance........ 2.733896e-02
+#unique......... 1835, #Total UniqueCount: 23543
+var 1:
+best............ 9.995033e-01
+mean............ 8.084638e-01
+variance........ 6.007372e+00
+
+'wait.generations' limit reached.
+No significant improvement in 10 generations.
+
+Solution Fitness Value: 4.113123e-01
+
+Parameters at the Solution (parameter, gradient):
+
+ X[ 1] : 9.995033e-01 G[ 1] : -6.343841e-09
+
+Solution Found Generation 1
+Number of Generations Run 11
+
+Fri Feb 9 19:33:45 2007
+Total run time : 0 hours 0 minutes and 3 seconds
+ \end{CodeOutput}
+\end{CodeChunk}
+
+%DESCRIBE OUTPUT
+
+After printing the date and time of the run, the program prints the domain of
+values it is allowing for each parameter of the function being optimized. In
+this case the default domain values are being used. Naturally it is important
+to specify domains wide enough to include the solution. In practice with
+highly nonlinear functions it is often better to specify domains that are
+relatively wide than to have domains that narrowly and perhaps even correctly
+bound the solution. This surprising behavior reflects the fact with a highly
+nonlinear function, a point that is close to the solution in the sense of
+simple numerical proximity may not be all that close in the sense of there
+being a short feasible path to get to the solution.
+
+Next the program prints the Data Type. This indicates whether the parameters
+of the function to be optimized are being treated as floating point numbers or
+integers. For more information about this, see the \code{data.type.int}
+argument.
+
+The program then displays the number of operators being used, followed by the
+values that describe the other characteristics set for this particular run:
+the maximum number of generations, the population size and the tolerance value
+to be used to determine when the parameter values will be deemed to have
+converged.
+
+The output then reports whether BFGS optimization will be applied to the best
+trial solution produced by the operators in each generation. For problems
+that are smooth and concave in a neighborhood of the global optimum, using the
+BFGS in this way can help \code{genoud} quickly converge once the best trial
+solution is in the correct neighborhood. This run of \code{genoud} will also
+compute the gradient at the best trial solution before stopping. In fact this
+gradient checking is used as a convergence check. The algorithm will not
+start counting its final set of generations (the \code{wait.generations})
+until each element of the gradient is smaller in magnitude than the
+convergence tolerance. Gradients are never used and BFGS optimization is not
+used when the parameters of the function to be optimized are integers.
+
+The next message describes how strictly \code{genoud} is enforcing the
+boundary constraints specified by the domain values. By default
+(\code{boundary.enforcement=0}), the trial solutions are allowed to wander
+freely outside the boundaries. The boundaries are used only to define domains
+for those operators that use the boundary information. Other settings of the
+\code{boundary.enforcement} argument induce either more stringent or
+completely strict enforcement of the boundary constraints. Notice that the
+boundary constraints apply to the parameters one at a time. To enforce
+constraints that are defined by more complicated functional or data-dependent
+relationships, one can include an appropriate penalty function as part of the
+definition of the function to be optimized, letting that function define an
+extremely high (if minimizing) or low (if maximizing) value to be returned if
+the desired conditions are violated.
+
+After reporting whether it is solving a minimization or a maximization problem,
+\code{genoud} reports summary statistics that describe the distribution of the
+fitness value and the parameter values across the trial solutions at the end
+of each generation. In the default case where \code{genoud} is keeping track
+of all the distinct solutions considered over the whole course of the
+optimizing run, these generational reports also include a report of the number
+of unique trial solutions in the current population and the number of unique
+solutions ever considered. The benefit of keeping track of the solutions is
+to avoid repeatedly evaluating the function being optimized for the
+identical set of parameter values. This can be an important efficiency when
+function evaluations are expensive, as they can be in statistical applications
+where the data are extensive. This tracking behavior is controlled by the
+\code{MemoryMatrix} argument.
+
+Upon convergence, or when the hard maximum generation limit is reached, the
+program prints the fitness value at the best trial solution and that
+solution's parameter values. In this case the solution was found after one
+generation. While the Asymmetric Double Claw might present a difficult
+challenge for a gradient-based optimizer that uses only local hill climbing,
+it is an almost trivially simple problem for \code{genoud}.
+
+\subsection{Benchmark Functions:}
+The second example is a suite of 23 benchmark nonlinear functions used
+in \citet{yao.liu.lin1999} to study a pair of evolutionary programming
+optimization algorithms. Function definitions are in
+Table~\ref{tab:23funcs}. Because it includes a random component and
+so lacks a reproducible minimum value, we ignore the function numbered
+function 7 in their sequence.\footnote{The omitted function is
+ $\sum_{i=1}^n ix_i^4 +U(0,1)$, where $U(0,1)$ is a uniformly
+ distributed random variable on the unit interval that takes a new
+ value whenever the function is evaluated. This stochastic aspect
+ means that even given the set of parameters that minimize the
+ nonstochastic component $\sum_{i=1}^n ix_i^4$, i.e., $x_i=0$, the
+ value of the function virtually never attains the minimum possible
+ value of zero. An optimizer that evaluated the function at $x_i=0$
+ would not in general obtain a function value smaller than the
+ function value obtained for a wide range of different parameter
+ values. Hence we do not consider this function to be a good test
+ for function optimization algorithms.} Implementations of these
+functions are available in the supplemental \proglang{R} file provided
+with this article.\footnote{This supplemental file is available at
+ \url{http://sekhon.berkeley.edu/rgenoud/func23.R}.} These
+\proglang{R} definitions include the values of the constants used in
+functions 14, 15 and 19 through 23. The function argument domains are
+restricted to the specific domains used by \citet{yao.liu.lin1999} via
+bounds that are stated in the list named \code{testbounds} in the
+supplemental file.
+
+\begin{table}
+ \begin{center}
+ \line(1,0){450}
+ \end{center}
+ \begin{tabular}{LLLL}
+\text{func.} & \text{definition} & n & \text{minimum}^a \\
+ 1 & \sum_{i=1}^n x_i^2 & 30 & 0 \\
+ 2 & \sum_{i=1}^n |x_i| + \prod_{i=1}^n |x_i| & 30 & 0 \\
+ 3 & \sum_{i=1}^n (\sum_{j=1}^i x_j)^2 & 30 & 0 \\
+ 4 & \max_i \{|x_i|, 1\leq i\leq n\} & 30 & 0 \\
+ 5 & \sum_{i=1}^{n-1} [100(x_{i+1}-x_i^2)^2 +(x_i-1)^2],
+ & 30 & 0 \\
+ 6 & \sum_{i=1}^n (\lfloor x_i + 0.5\rfloor)^2 & 30 & 0 \\
+ 7 & \sum_{i=1}^n ix_i^4 +U(0,1) & 30 & 0 \\
+ 8 & \sum_{i=1}^n -x_i\sin(\sqrt{|x_i|}) & 30 & -12569.5 \\
+ 9 & \sum_{i=1}^n [x_i^2-10\cos(2\pi x_i)+10] & 30 & 0 \\
+10 & -20\exp\left(-0.2\sqrt{n^{-1}\sum_{i=1}^n x_i^2}\,\right) \\
+ & \qquad -\exp(n^{-1}\sum_{i=1}^n\cos 2\pi x_i)+20+e & 30 & 0 \\
+11 & (1/1000) \sum_{i=1}^n x_i^2 -
+\prod_{i=1}^n\cos\left(x_i/\sqrt{i}\right) + 1 & 30 & 0 \\
+12 & n^{-1}\pi \left\{10 \sin^2(\pi y_1)+\sum_{i=1}^{n-1}(y_i-1)^2
+[1+10\sin^2(\pi y_{i+1})]+(y_n-1)^2\right\} \\
+ & \quad +\sum_{i=1}^n u(x_i,10,100,4), & 30 & 0 \\
+ & y_i=1+(x_i+1)/4, \quad u(x_i,a,k,m)=\begin{cases} k(x_i-a)^m, & x_i>a, \\
+ 0, & -a\leq x_i\leq a,\\ k(-x_i-a)^m, & x_i<-a,
+\end{cases} & \\
+13 & \left\{ \sin^2(3\pi
+ x_1)+\sum_{i=1}^{n-1}(x_i-1)^2[1+\sin^2(3\pi x_{i+1})]\right\}/10 \\
+ & \quad +(x_n-1)[1+\sin^2(2\pi x_n)]/10
++\sum_{i=1}^n u(x_i,5,100,4) & 30 & 0 \\
+14 & \left\{1/500+
+\sum_{j=1}^{25} 1/\left[j+\sum_{i=1}^2(x_i-a_{ij})^6\right]\right\}^{-1} & 2 & 1 \\
+15 & \sum_{i=1}^{11} [a_i-x_1(b_i^2+b_ix_2)/(b_i^2+b_ix_3+x_4)]^2 & 4 & 0.0003075 \\
+16 & 4x_1^2-2.1x_1^4+x_1^6/3+x_1x_2-4x_2^2+4x_2^4 & 2 & -1.0316285 \\
+17 & [x_2-5.1x_1^2/(4\pi^2) + 5x_1/\pi - 6]^2 +
+ 10[1-1/(8\pi)]\cos(x_1) + 10 & 2 & 0.398 \\
+18 & [1+(x_1+x_2+1)^2(19-14 x_1+3 x_1^2-14 x_2+6 x_1 x_2+3 x_2^2)] \\
+ & \quad \times [30+(2 x_1-3 x_2)^2 (18-32 x_1+12 x_1^2+48 x_2-36 x_1 x_2+27 x_2^2)] & 2 & 3 \\
+19 & -\sum_{i=1}^4 c_i\exp\left[-\sum_{j=1}^4 a_{ij}(x_i-p_{ij})^2\right] & 4 & -3.86 \\
+20 & -\sum_{i=1}^4 c_i\exp\left[-\sum_{j=1}^6 a_{ij}(x_i-p_{ij})^2\right] & 6 & -3.32 \\
+21 & \sum_{i=1}^5 [(x-a_i)^{\prime}(x-a_i)+c_i]^{-1} & 4 & -10 \\
+22 & \sum_{i=1}^7 [(x-a_i)^{\prime}(x-a_i)+c_i]^{-1} & 4 & -10 \\
+23 & \sum_{i=1}^{10} [(x-a_i)^{\prime}(x-a_i)+c_i]^{-1} & 4 & -10
+ \end{tabular}
+ \begin{flushleft}
+ Notes: $^a$Minimum function value within specified bounds as given by
+ \citet[85]{yao.liu.lin1999}.
+ \end{flushleft}
+ \vspace*{.1in}
+ \caption{23 Benchmark Functions}
+ \label{tab:23funcs}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+As \citet{yao.liu.lin1999} describe, optimizing each of functions
+1--13 presents a high-dimensional problem. These functions each have
+$n=30$ free parameters. Functions 1--5 are unimodal, with function 5
+being a 30-dimensional version of the banana-shaped Rosenbrock
+function. Function 6 is a step function. Function 6 has one minimum
+value that occurs when all arguments are in the interval
+$x_i\in[0,.5)$, and the function is discontinuous. Functions 8--13
+are multimodal, defined such that the number of local minima increases
+exponentially with the number of arguments.
+\citet[84]{yao.liu.lin1999} describe these functions as among ``the
+most difficult class of problems for many optimization algorithms
+(including [evolutionary programming]).'' Functions 14--23, which
+have between two and six free parameters each, each have only a few
+local minima. Nonetheless the evolutionary programming algorithms
+considered by \citet{yao.liu.lin1999} have trouble optimizing
+functions 21--23. Although \citet[85]{yao.liu.lin1999} state that
+each of these functions has a minimum value of $-10$, over 50
+replications the two algorithms they consider achieve solutions
+averaging between $-5.52$ and $-9.10$ \citep[88,
+Table~IV]{yao.liu.lin1999}.
+
+We use these benchmark functions to illustrate not only how effective
+\code{genoud} can be with a range of difficult problems, but also to emphasize
+an important aspect of how one should think about trying to tune the
+optimizer's performance. Theory regarding genetic algorithms suggests that
+optimal solutions are more likely to appear as both the population size of
+candidate solutions and the number of generations increase. In \code{genoud}
+two arguments determine the number of generations. One is
+\code{max.generations}: if \code{hard.generation.limit=TRUE}, then the value
+specified for \code{max.generations} is a binding upper limit. The other is
+\code{wait.generations}, which determines when the algorithm terminates if
+\code{hard.generation.limit=FALSE}. But even if
+\code{hard.generation.limit=TRUE}, then \code{wait.generations} determines for
+how many generations the algorithm continues once the best parameter vector
+and the value of the function being optimized appear to have settled down.
+The fact that the current best solution is not changing should not be treated
+as decisive, because this solution may be merely a local optimum or a
+saddlepoint. If the population size is sufficient, the algorithm tends to
+build a population of trial solutions that contain parameters in neighborhoods
+of all the competitive local optima in the domain defined by the parameter
+boundaries. Even while the current best solution is stable, the algorithm is
+improving the solutions near other local optima. So having a higher
+\code{wait.generations} value never worsens the algorithm's efficacy.
+
+Increasing \code{max.generations} may or may not in itself improve
+optimization. The value of \code{max.generations} sets the value of $T$ used
+in the mutation operators---operators 4 and 7 in Table~\ref{tab:operators}.
+These mutation operators perform random search near a trial solution that has
+been selected for mutation only when the current generation count is an
+appreciable fraction of $T$. So increasing \code{max.generations} without
+changing \code{wait.generations} increases the period during which random
+search is occurring over a wider domain. For multimodal functions such a
+wider search may be helpful, but sometimes failing to search more densely near
+the current trial solutions is not good.
+
+We use \code{genoud} to minimize the 23 functions using two values for
+\code{pop.size} (5000 and 10000) and two values for
+\code{max.generations} (30 and 100). Following
+\citet{yao.liu.lin1999}, we replicate each optimization 50 times. The
+following code describes the computations. The list \code{testfuncs},
+vector \code{testNparms} and list \code{testbounds} are defined in the
+supplemental \proglang{R} file, and it is assume that this file is
+loaded with the \code{source("supplemental.R")} command. The vector
+\code{gradcheck} is true for all elements except the ones corresponding
+to functions 6 and 7.
+<<eval=false>>=
+source("supplemental.R")
+gradcheck <- rep(TRUE,23)
+gradcheck[6:7] <- FALSE
+sizeset <- c(5000,10000)
+genset <- c(30,100)
+nreps <- 50
+gsarray <- array(NA, dim=c(length(sizeset), length(genset), 23, nreps))
+asc <- function(x) { as.character(x) }
+dimnames(gsarray) <- list(asc(sizeset), asc(genset), NULL, NULL);
+for (gsize in sizeset) {
+ for (ngens in genset) {
+ for (i in 1:23) {
+ for (j in 1:nreps) {
+ gsarray[as.character(gsize), as.character(ngens),i,j] <-
+ genoud(testfuncs[[i]], nvars=testNparms[i], pop.size=gsize,
+ max.gen=ngens, hard.gen=TRUE, Domains=testbounds[[i]],
+ solution.tol=1e-6, boundary=1, gradient.check=gradcheck[i],
+ print=0)$value
+ }
+ }
+ }
+}
+@
+
+Using \code{genoud} to minimize the benchmark functions produces excellent
+results, at least when the \code{pop.size} and \code{max.generations}
+arguments are sufficiently large. Table~\ref{tab:23mean} reports the mean
+function values for each configuration of the arguments. These values may be
+compared both to the true function minima given by \citet{yao.liu.lin1999}
+(see the rightmost column in Table~\ref{tab:23funcs}) and to the average
+minimum function values \citet{yao.liu.lin1999} report for their ``fast''
+evolutionary programming (FEP) algorithm, which appear in the last column of
+Table~\ref{tab:23mean}. The \code{genoud} averages for the \code{max.gen=100}
+configurations equal or are close to the true minima for all the functions
+except function 13. One can reasonably argue that the average solutions for
+function 5 are not as close to zero as might be desired: these averages are
+close to $10^{-7}$, while the averages for other functions that have a true
+minimum of zero are $10^{-15}$ or smaller. And the averages for functions 6,
+12 and 15 in the \code{pop.size=5000} case are off. The effect of increasing
+\code{pop.size} is apparent with respect to both those three functions and
+also functions 13 and 20--23: the average minima are smaller with
+\code{pop.size=10000} than with \code{pop.size=5000}. Except for functions 6
+and 12 in the \code{pop.size=5000} case and function 13, all the \code{genoud}
+solution averages for \code{max.gen=100} are either slightly or substantially
+better than the corresponding FEP solution averages.
+
+The results in Table~\ref{tab:23mean} clearly illustrate the potential
+consequences of not allowing \code{genoud} to run for a sufficient number of
+generations. While some of the \code{genoud} solutions for \code{max.gen=30}
+have competitive means, several of the means are not good at all.
+
+\begin{table}
+ \begin{center}
+ \line(1,0){450}
+ \end{center}
+ \begin{tabular}{llllll}
+ & \multicolumn{4}{c}{\code{genoud}} & \\ \cline{2-5}
+ & \multicolumn{2}{c}{\code{pop.size=5000}$^a$} & \multicolumn{2}{c}{\code{pop.size=10000}$^a$} & \\
+\text{func.} & \code{max=30} & \code{max=100} & \code{max=30} & \code{max=100} & \text{FEP}$^b$ \\
+ 1 & 1.453\e 32 & 1.658\e 32 & 2.416\e 32 & 6.134\e 32 & 5.7\e 4 \\
+ 2 & 6.55\e 16 & 7.212\e 16 & 9.652\e 16 & 1.043\e 15 & 8.1\e 3 \\
+ 3 & 4.633\e 18 & 3.918\e 18 & 3.787\e 18 & 4.032\e 18 & 1.6\e 2 \\
+ 4 & 6.203\e 17 & 6.542\e 17 & 9.453\e 17 & 7.85\e 17 & 0.3 \\
+ 5 & 0.07973 & 5.887\e 08 & 8.133\e 08 & 8.917\e 08 & 5.06 \\
+ 6 & 18.58 & 0.08 & 9.38 & 0 & 0 \\
+% 7 & 0.1114 & 0.07473 & 0.1114 & 0.06466 & 7.6\e 3 \\
+ 8 & -12569.49 & -12569.49 & -12569.49 & -12569.49 & -12554.5 \\
+ 9 & 2.786 & 0 & 0.9353 & 0 & 4.6\e 2 \\
+10 & 2.849 & 3.997\e 15 & 2.199 & 3.997\e 15 & 1.8\e 2 \\
+11 & 7.994\e 17 & 7.105\e 17 & 9.548\e 17 & 6.439\e 17 & 1.6\e 2 \\
+12 & 5.371\e 19 & 0.004147 & 0.002073 & 1.178\e 19 & 9.2\e 6 \\
+13 & 0.02095 & 0.006543 & 0.006629 & 0.003011 & 1.6\e 4 \\
+14 & 0.998 & 0.998 & 0.998 & 0.998 & 1.22 \\
+15 & 0.0003441 & 0.0004746 & 0.0003807 & 0.0003807 & 5.0\e 4 \\
+16 & -1.0316285 & -1.0316285 & -1.0316285 & -1.0316285 & -1.03 \\
+17 & 0.3979 & 0.3979 & 0.3979 & 0.3979 & 0.398 \\
+18 & 3 & 3 & 3 & 3 & 3.02 \\
+19 & -3.863 & -3.863 & -3.863 & -3.863 & -3.86 \\
+20 & -3.274 & -3.277 & -3.279 & -3.286 & -3.27 \\
+21 & -9.85 & -9.444 & -9.95 & -10.05 & -5.52 \\
+22 & -9.771 & -10.09 & -10.19 & -10.3 & -5.52 \\
+23 & -10.1 & -9.997 & -10.32 & -10.21 & -6.57
+ \end{tabular}
+ \begin{flushleft}
+ Note: $^b$Average minimum function values (over 50 replications) obtained
+ using \code{genoud}. $^a$Mean best function values (over 50 replications)
+ reported for the ''fast'' evolutionary programming algorithm, from
+ \citet[85 and 88, Tables II--IV]{yao.liu.lin1999}.
+ \end{flushleft}
+ \vspace*{.1in}
+ \caption{Mean Values of 22 Optimized Functions}
+ \label{tab:23mean}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+The effect of increasing \code{pop.size} are even more clearly apparent in
+Table~\ref{tab:23sdev}, which reports the standard deviations of the
+respective minima across the 50 replications. With the exceptions of
+functions 6, 12, 13, 15 and 21 with \code{pop.size=5000}, the \code{genoud}
+solutions for \code{max.gen=100} vary much less than the corresponding FEP
+solutions. For those functions and also for functions 20, 22 and 23, the
+\code{max.gen=100} solutions with \code{pop.size=10000} vary noticeably less
+than the solutions with \code{pop.size=5000}.
+
+\begin{table}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+ \begin{tabular}{llllll}
+ & \multicolumn{4}{c}{\code{genoud}} & \\ \cline{2-5}
+ & \multicolumn{2}{c}{\code{pop.size=5000}$^a$} & \multicolumn{2}{c}{\code{pop.size=10000}$^a$} & \\
+\text{func.} & \code{max=30} & \code{max=100} & \code{max=30} & \code{max=100} & \text{FEP}$^b$ \\
+ 1 & 9.997\e 32 & 7.059\e 32 & 9.562\e 32 & 2.1\e 31 & 1.3\e 4 \\
+ 2 & 1.668\e 15 & 1.621\e 15 & 2.116\e 15 & 2.102\e 15 & 7.7\e 4 \\
+ 3 & 4.568\e 18 & 3.342\e 18 & 4.38\e 18 & 5.136\e 18 & 1.4\e 2 \\
+ 4 & 1.793\e 16 & 1.758\e 16 & 2.055\e 16 & 2.002\e 16 & 0.5 \\
+ 5 & 0.5638 & 4.921\e 08 & 5.573\e 08 & 4.955\e 08 & 5.87 \\
+ 6 & 5.65 & 0.274 & 3.528 & 0 & 0 \\
+% 7 & 0.0837 & 0.05153 & 0.08042 & 0.04883 & 2.6\e 3 \\
+ 8 & 3.749\e 10 & 1.071\e 12 & 8.948\e 09 & 6.365\e 13 & 52.6 \\
+ 9 & 1.864 & 0 & 1.179 & 0 & 1.2\e 2 \\
+10 & 0.7146 & 0 & 0.702 & 0 & 2.1\e 3 \\
+11 & 1.209\e 16 & 1.582\e 16 & 1.289\e 16 & 8.713\e 17 & 2.2\e 2 \\
+12 & 2.336\e 18 & 0.02052 & 0.01466 & 7.423\e 19 & 3.6\e 6 \\
+13 & 0.03427 & 0.006867 & 0.006903 & 0.001508 & 7.3\e 5 \\
+14 & 5.638\e 12 & 8.894\e 11 & 1.029\e 12 & 4.35\e 12 & 0.56 \\
+15 & 0.0001813 & 0.0003546 & 0.000251 & 0.0002509 & 3.2\e 4 \\
+16 & 1.315\e 14 & 9.751\e 15 & 1.233\e 14 & 1.054\e 14 & 4.9\e 7 \\
+17 & 5.422\e 15 & 5.51\e 15 & 4.925\e 15 & 1.392\e 14 & 1.5\e 7 \\
+18 & 1.509\e 13 & 3.477\e 14 & 6.18\e 14 & 2.907\e 14 & 0.11 \\
+19 & 7.349\e 15 & 1.521\e 15 & 1.344\e 14 & 7.255\e 15 & 1.4\e 5 \\
+20 & 0.05884 & 0.0583 & 0.05765 & 0.05504 & 5.9\e 2 \\
+21 & 1.212 & 1.776 & 1.005 & 0.7145 & 1.59 \\
+22 & 1.937 & 1.269 & 1.052 & 0.7459 & 2.12 \\
+23 & 1.479 & 1.636 & 1.066 & 1.29 & 3.14
+ \end{tabular}
+ \begin{flushleft}
+ Note: $^a$Standard deviation of the minimum function values (over 50
+ replications) obtained using \code{genoud}. $^b$Standard deviation of the
+ best function values (over 50 replications) reported for the ''fast''
+ evolutionary programming algorithm, from \citet[85 and 88, Tables
+ II--IV]{yao.liu.lin1999}.
+ \end{flushleft}
+ \vspace*{.1in}
+ \caption{Standard Deviations of Values of 22 Optimized Functions}
+ \label{tab:23sdev}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+\subsection{A Logistic Least Quartile Difference Estimator:}
+Our third example is a version of the LQD estimator used in
+\code{multinomRob}. Using the \proglang{R} function \code{IQR} to compute the
+interquartile range, the function to be minimized may be defined as
+follows.\footnote{The LQD problem solved in \code{multinomRob} is somewhat
+ different. There the problem is to minimize the $\binom{h_{K}}{2}$ order
+ statistic of the set of absolute differences among the standardized
+ residuals, where $h_K$ is a function of the sample size and the number of
+ unknown regression model coefficients \citep{MebaneSekhon2004}. The problem
+ considered in the current example is simpler but exhibits similar estimation
+ difficulties.}
+<<eval=false>>=
+LQDxmpl <- function(b) {
+ logistic <- function(x) { 1/(1+exp(-x)) }
+ sIQR <- function(y, yhat, n) {
+ IQR((y-yhat)/sqrt(yhat*(n-yhat)), na.rm=TRUE)
+ }
+ sIQR(y, m*logistic(x %*% b), m)
+}
+@
+For this example we define \code{LQDxmpl} after we compute the simulated data,
+so the data vector \code{y}, matrix \code{x} and scalar \code{m} are in scope
+to evaluate to have the values we simulate:
+<<eval=false>>=
+m <- 100
+x <- cbind(1,rnorm(1000),rnorm(1000))
+b1 <- c(.5, 1, -1)
+b2 <- c(0, -1, 1)
+logistic <- function(x) { 1/(1+exp(-x)) }
+y <- rbinom(1000, m, logistic(c(x[1:900,] %*% b1, x[901:1000,] %*% b2)))
+@
+The data simulate substantial contamination. The first 900 observations are
+generated by one binomial regression model while the last 100 observations
+come from a very different model.
+
+Presuming we are interested in the model that generated the bulk of the data,
+ignoring the contamination in a generalized linear model with the binomial
+family produces very poor results:
+<<eval=false>>=
+summary(glm1 <- glm(cbind(y,m-y) ~ x[,2] + x[,3], family="binomial"))
+@
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Call:
+glm(formula = cbind(y, m - y) ~ x[, 2] + x[, 3], family = "binomial")
+
+Deviance Residuals:
+ Min 1Q Median 3Q Max
+-22.9168 -1.1693 0.3975 1.5895 24.6439
+
+Coefficients:
+ Estimate Std. Error z value Pr(>|z|)
+(Intercept) 0.439492 0.007097 61.93 <2e-16 ***
+x[, 2] 0.679847 0.007985 85.14 <2e-16 ***
+x[, 3] -0.716963 0.007852 -91.31 <2e-16 ***
+---
+Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+ \end{CodeOutput}
+\end{CodeChunk}
+Of course, if we knew which observations to omit the results would be much
+better:
+<<eval=false>>=
+suby <- y[1:900]
+subx <- x[1:900,]
+summary(glm2 <- glm(cbind(suby,m-suby) ~ subx[,2] + subx[,3], family="binomial"))
+@
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Call:
+glm(formula = cbind(suby, m - suby) ~ subx[, 2] + subx[, 3],
+ family = "binomial")
+
+Deviance Residuals:
+ Min 1Q Median 3Q Max
+-3.21478 -0.71699 0.03528 0.67867 2.88314
+
+Coefficients:
+ Estimate Std. Error z value Pr(>|z|)
+(Intercept) 0.501880 0.008036 62.46 <2e-16 ***
+subx[, 2] 1.003592 0.009779 102.63 <2e-16 ***
+subx[, 3] -0.984295 0.009437 -104.30 <2e-16 ***
+---
+Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+ \end{CodeOutput}
+\end{CodeChunk}
+But in practical applications it is unknown apriori which observations should
+be treated as outliers.
+
+As the definition of \code{LQDxmpl} indicates, the LQD is based on
+minimizing the interquartile range (IQR) of the standardized
+residuals. Because the quartiles correspond to different data points
+for different values of the regression coefficients, the fitness
+function is not smooth, which is to say it is not everywhere
+differentiable. In general, at every point in the parameter space
+where the identity of the first or third quartile point changes, the
+function is not differentiable. Figure~\ref{fig:lqd1} illustrates
+this. A higher resolution version of this figure is available in
+\cite{MebaneJr.+Sekhon:2011}---also see
+\url{http://sekhon.berkeley.edu/papers/rgenoudJSS.pdf}.
+
+The IQR clearly has a minimum in the vicinity of the coefficient
+values used to generate most of the data. But contour plots for the
+numerically evaluated partial derivative with respect to the second
+coefficient parameter testify to the function's local irregularity.
+The function we use to evaluate this numerical derivative is defined
+as follows.
+<<eval=false>>=
+dLQDxmpl <- function(b) {
+ eps <- 1e-10
+ logistic <- function(x) { 1/(1+exp(-x)) }
+ sIQR <- function(y, yhat, n) {
+ IQR((y-yhat)/sqrt(yhat*(n-yhat)), na.rm=TRUE)
+ }
+ dsIQR <- vector()
+ for (i in 1:length(b)) {
+ beps <- b
+ beps[i] <- b[i]+eps
+ dsIQR <-
+ c(dsIQR,
+ (sIQR(y, m*logistic(x %*% beps), m)-
+ sIQR(y, m*logistic(x %*% b), m))/eps)
+ }
+ return(dsIQR)
+}
+@
+Setting the intercept equal to 0.5, the code to generate the plotted values is
+% -rw-rw---- 1 wrm1 research 1878 Feb 10 2007 lqdxmpl2plotB.R
+<<eval=false>>=
+blen <- 3
+lenbseq <- length(bseq <- seq(-2,2,length=200))
+bseq3 <- seq(-1.2,-.9,length=200)
+bseq2 <- seq(.89,1.1,length=200)
+IQRarr <- IQRarrA <- array(NA, dim=c((1+blen), lenbseq, lenbseq))
+dimnames(IQRarrA) <- list(NULL, as.character(bseq), as.character(bseq))
+dimnames(IQRarr) <- list(NULL, as.character(bseq2), as.character(bseq3))
+for (i in 1:lenbseq) {
+ for (j in 1:lenbseq) {
+ IQRarrA[1,i,j] <- LQDxmpl(c(.5, bseq[i], bseq[j]))
+ IQRarrA[-1,i,j] <- dLQDxmpl(c(.5, bseq[i], bseq[j]))
+ IQRarr[1,i,j] <- LQDxmpl(c(.5, bseq2[i], bseq3[j]))
+ IQRarr[-1,i,j] <- dLQDxmpl(c(.5, bseq2[i], bseq3[j]))
+ }
+}
+@
+The following code produces the plots:
+<<eval=false>>=
+par(mfrow=c(2,2), lwd=.1)
+contour(bseq,bseq, IQRarrA[1,,], main="IQR", xlab="b[2]", ylab="b[3]")
+contour(bseq,bseq, IQRarrA[3,,], main="partial derivative w/r/t b[2]",
+ xlab="b[2]", ylab="b[3]")
+loc2 <- (150:160)-5
+loc3 <- (40:50)+5
+contour(bseq[loc2],bseq[loc3], IQRarrA[3,loc2,loc3],
+ main="partial derivative w/r/t b[2]",
+ xlab="b[2]", ylab="b[3]")
+contour(bseq2,bseq3, IQRarr[3,,], main="partial derivative w/r/t b[2]",
+ xlab="b[2]", ylab="b[3]")
+@
+If the IQR function were smooth, we would see clearly separated, slightly
+curved contour lines, reflecting the nonlinearity of the \code{logistic}
+function, but there is nothing like that. Instead, looking over the domain
+$[-2,2]^2$ for the second and third regression coefficient parameters, with
+200 points evaluated along each axis (the upper right plot), there is a
+splotchy cloud. This reflects the fact that the derivative changes sign very
+frequently over the domain: of the 40,000 points at which the derivative is
+evaluated, it is positive at 12,460 points and negative at 27,540 points.
+\begin{figure}[t]
+ \caption{Contour Plots of the LQD Fitness Function and of its Partial Derivatives}
+ \label{fig:lqd1}
+ \begin{center}
+ \includegraphics{lqdxmpl2B.pdf}
+% -rw-rw---- 1 wrm1 research 2745 Feb 10 23:15 lqdxmpl2plotB.Rout
+ \end{center}
+ \vspace{-.3in}
+\end{figure}
+
+The LQD fitness function is not appreciably smoother close to the true
+values. The bottom two plots show the partial derivatives with
+respect to the second coefficient parameter evaluated over the domain
+$[.89,1.1]\times[-1.2,-.9]$. The bottom left plot evaluates the
+derivatives at 11 points along each axis while the bottom right plot
+uses 200 points along each axis. In the left plot it is easier to see
+the intricacy of the partitioning of the parameter space as the
+identity of the first or third quartile point changes. The bottom
+right plot shows the intricacy in fact replicates at the finer grain
+of the more detailed evaluations (to see this it is probably necessary
+to magnify the plot while viewing online the \textit{Journal of
+ Statistical Software} version of this
+documentation).\footnote{Please see \cite{MebaneJr.+Sekhon:2011} or
+ \url{http://sekhon.berkeley.edu/papers/rgenoudJSS.pdf}.} Within
+this smaller domain the sign of the derivative changes even more
+frequently than it does over the domain $[-2,2]^2$: the derivative is
+positive at 18,098 points and negative at 21,902 points.
+
+While the LQD fitness function may be differentiable in a neighborhood of the
+global solution, that neighborhood, if it exists, is clearly not very big. As
+likely is that the global solution is located at a point where the function is
+not differentiable. Hence a numerically evaluated gradient is not meaningful
+for evaluating whether the solution has been found. At the true solution,
+numerical gradient values may differ substantially from zero.
+
+To use the LQD to estimate the binomial regression model parameters we use the
+following call to \code{genoud}. Because gradient information is of
+questionable relevance for this problem, we turn off the termination condition
+that the gradient at the solution be smaller than the value specified for the
+\code{solution.tolerance} argument. We retain the default setting
+\code{BFGS=TRUE} because, in principle, gradient-driven optimization may help
+in each of the many differentiable neighborhoods, even if it is useless across
+the nondifferentiable boundaries. Our experience optimizing the LQD
+\citep{MebaneSekhon2004} shows that using the BFGS in this way improves
+performance, even though the gradient is not useful for evaluating whether the
+solution has been found.
+<<eval=false>>=
+LQD1 <-
+ genoud(LQDxmpl, nvars=3, max=FALSE, pop.size=2000, max.generations=300,
+ wait.generations=100, gradient.check=FALSE, print=1)
+@
+This invocation of the \code{LQDxmpl} function matches the behavior of
+\code{multinomRob} in that it produces an estimate for the intercept parameter
+along with the other coefficients. In a linear regression context, the
+interquartile range statistic contains no information about the intercept, so
+the LQD is not an estimator for that parameter. With a binomial regression
+model there is some information about the intercept due to the nonlinearity of
+the \code{logistic} function. The LQD estimate for the intercept should
+nonetheless be expected not to be very good.
+
+Results from the preceding estimation are as follows.
+% macht:/home/xchg/jss07/rgenoud:
+% -rw-rw---- 1 wrm1 research 5080 Aug 7 02:31 lqdxmpl1b.Rout
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Tue Aug 7 02:27:08 2007
+Domains:
+ -1.000000e+01 <= X1 <= 1.000000e+01
+ -1.000000e+01 <= X2 <= 1.000000e+01
+ -1.000000e+01 <= X3 <= 1.000000e+01
+
+[...]
+
+HARD Maximum Number of Generations: 300
+Maximum Nonchanging Generations: 100
+Population size : 2000
+Convergence Tolerance: 1.000000e-06
+
+Using the BFGS Derivative Based Optimizer on the Best Individual Each Generation.
+Not Checking Gradients before Stopping.
+Using Out of Bounds Individuals.
+
+Minimization Problem.
+
+
+Generation# Solution Value
+
+ 0 4.951849e-01
+ 56 1.298922e-01
+ 57 1.298891e-01
+ 59 1.298848e-01
+ 60 1.298820e-01
+ 61 1.298793e-01
+ 62 1.298768e-01
+ 63 1.298744e-01
+
+'wait.generations' limit reached.
+No significant improvement in 100 generations.
+
+Solution Fitness Value: 1.298743e-01
+
+Parameters at the Solution (parameter, gradient):
+
+ X[ 1] : 8.130357e-02 G[ 1] : 9.616492e-03
+ X[ 2] : 8.889485e-01 G[ 2] : -1.167897e-01
+ X[ 3] : -9.327966e-01 G[ 3] : -3.090130e-02
+
+Solution Found Generation 63
+Number of Generations Run 164
+
+Tue Aug 7 02:31:09 2007
+Total run time : 0 hours 4 minutes and 1 seconds
+ \end{CodeOutput}
+\end{CodeChunk}
+Recall that the gradient is not reliably informative at the solution. To
+check whether this solution is believable, we might try reestimating the model
+using a larger population and larger specified number of generations:
+<<eval=false>>=
+LQD1 <-
+ genoud(LQDxmpl, nvars=3, max=FALSE, pop.size=10000, max.generations=1000,
+ wait.generations=300, gradient.check=FALSE, print=1)
+@
+At the price of a greatly increased running time (from four minutes up to
+one hour 53 minutes), the results are better than the
+first run (even though the summary measure of fit is slightly worse):
+% macht:/home/xchg/jss07/rgenoud:
+% -rw-rw---- 1 wrm1 research 5236 Aug 7 05:16 lqdxmpl1d.Rout
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Minimization Problem.
+
+
+Generation# Solution Value
+
+ 0 2.238865e-01
+ 2 1.301149e-01
+ 3 1.300544e-01
+ 4 1.300482e-01
+ 6 1.300375e-01
+ 7 1.300343e-01
+ 8 1.300323e-01
+ 134 1.299662e-01
+ 135 1.299099e-01
+ 136 1.298867e-01
+ 137 1.298843e-01
+ 138 1.298822e-01
+ 139 1.298791e-01
+ 141 1.298774e-01
+
+'wait.generations' limit reached.
+No significant improvement in 300 generations.
+
+Solution Fitness Value: 1.298770e-01
+
+Parameters at the Solution (parameter, gradient):
+
+ X[ 1] : 2.013748e-01 G[ 1] : -7.394125e-02
+ X[ 2] : 9.526390e-01 G[ 2] : 7.807607e-02
+ X[ 3] : -9.642458e-01 G[ 3] : 3.834052e-02
+
+Solution Found Generation 141
+Number of Generations Run 442
+
+Tue Aug 7 05:16:37 2007
+Total run time : 1 hours 53 minutes and 45 seconds
+ \end{CodeOutput}
+\end{CodeChunk}
+%$
+
+This example demonstrates a key difficulty that arises when optimizing
+irregular functions in the absence of gradients. It is difficult to assess
+when or whether an optimum has been found. The estimated coefficient values
+are close to the ones used to generate most of the data, except as expected
+the estimate for the intercept is not good. The estimates are better than if
+we had ignored the possibility of contamination. But whether these are the
+best possible estimates is not clear. If we were to use an even larger
+population and specify that an even greater number of generations be run,
+perhaps a better solution would be found.
+
+%http://sekhon.berkeley.edu/rgenoud/R/genoud_cluster_manual.R
+%http://sekhon.berkeley.edu/rgenoud/R/genoud_cluster_manual_tunnel.R
+
+%\code{genoud} can be tricked into doing constrained optimization by
+%passing in a function which contains a penalty function.
+
+Even for less irregular problems convergence is difficult to determine.
+Nonlinear optimizers often report false convergence, and users should not
+simply trust whatever convergence criteria an optimizer uses.
+\citet{McCulloughVinod2003} offer four criteria for verifying the solution of
+a nonlinear solver. These criteria are meaningful only for problems that meet
+regularity conditions at the solution, notably differentiability, and as such
+are not useful for the LQD example offered above. The four criteria are: (1)
+making sure the gradients are zero; (2) inspecting the solution path (i.e.,
+the trace) to make sure it follows the expected rate of convergence; (3)
+evaluating the Hessian to make sure it is well-conditioned;\footnote{Following
+ an exchange with \citet{DrukkerWiggins2004}, \citet{McCulloughVinod2004b}
+ modify their third suggestion to note that determining if the Hessian is
+ well-conditioned in part depends on how the data are scaled. That is, a
+ Hessian that appears to be ill-conditioned may be made well-conditioned by
+ rescaling. So if an Hessian appears to be ill-conditioned,
+ \citet{McCulloughVinod2004b} recommend that the analyst attempt to determine
+ if rescaling the data can result in a well-conditioned Hessian.} and (4)
+profiling the likelihood to ascertain if a quadratic approximation is
+adequate. One may need to take the results from \code{genoud} and pass them
+to \code{optim} to conduct some of these diagnostic tests such as to profile
+the likelihood. It is also good practice to use more than one optimizer to
+verify the solution \citep{stokes2004}.
+
+Note that \code{genoud} uses its own random number seeds and internal
+pseudorandom number generators to insure backward compatibility with
+the original C version of the software and to make cluster behavior
+more predictable. These seeds are set by the \code{unif.seed} and
+\code{int.seed} options. The \proglang{R} \code{set.seed} command is
+ignored by \code{genoud}.
+
+%user supplied gradients and lexical search?
+
+\section{Conclusion}
+\label{sec:conclusion}
+
+The \code{genoud} function provides many more options than can be reviewed in
+this brief paper. These options are described in the \proglang{R} help file.
+The most important option
+influencing how well the evolutionary algorithm works is the \code{pop.size}
+argument. This argument controls the population size---i.e., it is the number
+of individuals \code{genoud} uses to solve the optimization problem. As noted
+above, the theorems proving that genetic algorithms find good solutions are
+asymptotic in both population size and the number of generations. It is
+therefore important that the \code{pop.size} value not be small. On the other
+hand, computational time is finite so obvious trade-offs must be made. As the
+LQD example illustrates, a larger population size is not necessarily
+demonstrably better.
+The most important options to ensure that a good solution is found, aside from
+\code{pop.size}, are \code{wait.generations}, \code{max.generations} and
+\code{hard.generation.limit}.
+
+Many statistical models have objective functions that are nonlinear
+functions of the parameters, and optimizing such functions is tricky
+business \citep{AltmanGillMcDonald2003}. Optimization difficulties
+often arise even for problems that are generally considered to be
+simple. For a cautionary tale on how optimization can be a difficult
+task even for such problems see Stokes' (\citeyear{stokes2004}) effort
+to replicate a probit model estimated by \citet[pp. 335]{maddala1992}.
+A recent controversy over estimating a nonlinear model estimated by
+maximum likelihood offers another cautionary tale
+\citep{DrukkerWiggins2004,McCulloughVinod2003,McCulloughVinod2004a,McCulloughVinod2004b,SchacharNalebuff2004}.
+End users are generally surprised to learn that such optimization
+issues can arise, and that results can substantially vary across
+optimizers and software implementations.
+
+The \pkg{rgenoud} package provides a powerful and flexible global
+optimizer. When compared with traditional derivative-based
+optimization methods, \pkg{rgenoud} performs well
+\citep{SekhonMebane1998}. Optimization of irregular functions is,
+however, as much of an art as science. And an optimizer cannot be
+used without thought even for simple surfaces, let alone spaces that
+require a genetic algorithm. We hope that the availability of a
+scalable global optimizer will allow users to work with difficult
+functions more effectively.
+
+
+
+
+\bibliography{rgenoud}
+\end{document}
+
+% LocalWords: optima GillMurrayWright EfronTibshirani GENOUD MebaneSekhon LQD
+% LocalWords: SekhonMebane multinomRob overdispersed nondifferentiable Broyden
+% LocalWords: Goldfarb Shanno BFGS optim genoud EA EAs GA holland goldberg GAs
+% LocalWords: GrefenstetteBaker davis FilhoTreleavenAlippi generation's dejong
+% LocalWords: substring's grefenstette billingsley Vose NixVose vose GA's ADC
+% LocalWords: GENOCOP MichalewiczSwaminathanLogan Michalewicz Polytope dnorm
+% LocalWords: nvars Nonchanging UniqueCount var MemoryMatrix IQR LQDxmpl exp
+% LocalWords: sIQR yhat na rm cbind rnorm rbinom Min Std Pr Signif suby subx
+% LocalWords: apriori Raphson saddlepoints fn Genoud's gr hessian unif int ssh
+% LocalWords: Tausworthe stdout tempdir polytope musil deckard makeSOCKcluster
+% LocalWords: usernames username PVM MPI peakgeneration parm UC Outlier seq mu
+% LocalWords: lapply xlab ylab col biclaw mNd ALTMAN rgenoud WandKingLau PKfit
+% LocalWords: KingWand braumoeller BraumoellerGoodrichKline pharmacokinetics
+% LocalWords: LeeLee pseudorandom pdf glm rw wrm lqdxmpl cl makeCluster probit
+% LocalWords: localhost clusterExport stopCluster AltmanGillMcDonald GENetic
+% LocalWords: McCulloughVinod SchacharNalebuff GenMatch GUI URL boolean Sekhon
+% LocalWords: CPUs nonlinearity FAiR goodrich SekhonMatching ivivc vitro vivo
+% LocalWords: multinomial Synth AbadieGardeazabal synth nonsmooth Rcore maxima
+% LocalWords: resampling resamples optimizer's eval nonstochastic testbounds
+% LocalWords: LLLL func ij unimodal Rosenbrock multimodal minima saddlepoint
+% LocalWords: testfuncs testNparms gradcheck sizeset genset nreps gsarray tol
+% LocalWords: gsize ngens FEP LLLLLL sqrt dLQDxmpl eps dsIQR beps blen lenbseq
+% LocalWords: bseq IQRarr IQRarrA dimnames mfrow lwd loc online DrukkerWiggins
+% LocalWords: maddala funcs sapply runif ifelse rbind crossprod byrow vXXi
+% LocalWords: interquartile
diff --git a/inst/doc/rgenoud.bib b/inst/doc/rgenoud.bib
new file mode 100644
index 0000000..f72a55d
--- /dev/null
+++ b/inst/doc/rgenoud.bib
@@ -0,0 +1,1903 @@
+ at string{aer = "American Economic Review"}
+ at string{ajps= "American Journal of Political Science"}
+ at string(apq = "American Politics Quarterly")
+ at string{apsr= "American Political Science Review"}
+ at string{ams = "Annals of Mathematical Statistics"}
+ at string{aos = "Annals of Statistics"}
+ at string{bjps= "British Journal of Political Science"}
+ at string{ec = "Econometrica"}
+ at string{ier = "International Economic Review"}
+ at string{jasa= "Journal of the American Statistical Association"}
+ at string{je = "Journal of Econometrics"}
+ at string{jel = "Journal of Economic Literature"}
+ at string{jep = "Journal of Economic Perspectives"}
+ at string{jet = "Journal of Economic Theory"}
+ at string{jmcb= "Journal of Money, Credit, and Banking"}
+ at string{jme = "Journal of Monetary Economics"}
+ at string{jpe = "Journal of Political Economy"}
+ at string{jop = "Journal of Politics"}
+ at string{jrsa= "Journal of the Royal Statistical Society, Series A"}
+ at string{jrssb= "Journal of the Royal Statistical Society, Series B"}
+ at string{lsq = "Legislative Studies Quarterly"}
+ at string{pa = "Political Analysis"}
+ at string{pm = "Political Methodology"}
+ at string{pop = "Perspectives on Politics"}
+ at string{ps = "PS: Political Science and Politics"}
+ at string{qje = "Quarterly Journal of Economics"}
+
+ at string{c-h = "Chapman \& Hall"}
+ at string{cup = "Cambridge University Press"}
+ at string{cornell.up = "Cornell University Press"}
+ at string{hup = "Harvard University Press"}
+ at string{mit = "MIT Press"}
+ at string(pup = {Princeton University Press})
+ at string{s-v = "Springer-Verlag"}
+ at string(sup = "Stanford University Press")
+ at string{ucp = "University of California Press"}
+ at string{uchp = "University of Chicago Press"}
+ at string{ump = "University of Michigan Press"}
+ at string{yup = "Yale University Press"}
+ at string{cq = "Congressional Quarterly"}
+
+ at string{aa = "Ann Arbor"}
+ at string{berk= "Berkeley"}
+ at string{bos = "Boston"}
+ at string{cam = "Cambridge, MA"}
+ at string{camUK = "Cambridge, UK"}
+ at string{chic= "Chicago"}
+ at string{dc = "Washington, D.C."}
+ at string{nh = "New Haven"}
+ at string{nj = "New Jersey"}
+ at string{ny = "New York"}
+ at string{sf = "San Francisco"}
+ at string{st = "Stanford"}
+
+ at article( abadie2002,
+ author= {Abadie, Alberto},
+ title= {Bootstrap Tests for Distributional Treatment Effect in Instrumental Variable Models},
+ journal= jasa, volume=97, number=457,
+ pages= {284--292},
+ year= 2002
+)
+
+ at article( AbadieGardeazabal2003,
+ author= {Abadie, Alberto and Javier Gardeazabal},
+ title= {The Economic Costs of Conflict: a Case-Control Study for the Basque Country},
+ journal= aer, volume=92, number=1,
+ year= 2003
+)
+
+ at article( AbadieImbens_largesample,
+ author= {Abadie, Alberto and Guido Imbens},
+ title= {Large Sample Properties of Matching Estimators for Average Treatment Effects},
+ journal= ec,
+ year= "forthcoming"
+)
+
+ at Article{Abadie+Diamond+Hainmueller:2011,
+ author = {Alberto Abadie and Alexis Diamond and Jens Hainmueller},
+ title = {\pkg{Synth}: An \proglang{R} Package for Synthetic Control Methods in Comparative Case Studies},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at book( adams1805,
+ author= {Adams, John},
+ title= {Discourses on Davila: A Series of Papers on Political History},
+ publisher= {Da Capo Press}, address= {New York},
+ year= {1973 [1805]}
+)
+
+ at book( alesina1995,
+ author= {Alesina, Alberto and Howard Rosenthal},
+ title= {Partisan Politics, Divided Government, and the Economy},
+ publisher= cup, address= ny,
+ year= 1995
+)
+
+ at article( alesina1989,
+ author= {Alesina, Alberto and Howard Rosenthal},
+ title= {Partisan Cycles in {C}ongressional Elections and the Macroeconomy},
+ journal= apsr, volume=83,
+ pages= {373-398},
+ year= 1989
+)
+
+ at article( AlesinaLondregan1993,
+ author= {Alesina, Alberto and John Londregan and Howard Rosenthal},
+ title= {A Model of the Political Economy of the United States},
+ journal= apsr, volume=87,
+ number= 1,
+ pages= {12--33},
+ year= 1993
+)
+
+ at book( AltmanGillMcDonald2003,
+ author= {Altman, Micah and Jeff Gill and Michael McDonald},
+ title= {Numerical Issues in Statistical Computing for the Social Scientist},
+ publisher= {John Wiley and Sons}, address= {New York},
+ year= 2003
+)
+
+ at book( alvarez1997,
+ author= {Alvarez, R. Michael},
+ title= {Information and Elections},
+ publisher= {University of Michigan Press}, address= {Ann-Arbor},
+ year= 1997
+)
+
+ at book( AlvarezBrehm2002,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {Hard Choices, Easy Answers: Values, Information, and American Public Opinion},
+ publisher= pup, address= nj,
+ year= 2002
+)
+
+
+ at article( AlvarezBrehm1998,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {Speaking in Two Voices: American Equivocation about the Internal Revenue Service},
+ journal= ajps, volume=42,
+ number= 2,
+ pages= {418--452},
+ year= 1998
+)
+
+ at article( AlvarezBrehm1997,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {Are Americans Ambivalent Toward Racial Policies?},
+ journal= ajps, volume=41,
+ pages= {345--374},
+ year= 1997
+)
+
+ at article( AlvarezBrehm1995,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {American Ambivalence Toward Abortion Policy: A Heteroskedastic Probit Method for Assessing Conflicting Values},
+ journal= ajps, volume=39,
+ pages= {1055--1082},
+ year= 1995
+)
+
+ at book( althaus2003,
+ author= {Althaus, Scott L.},
+ title= {Collective Preferences in Democratic Politics: Opinion Surveys and the Will of the People},
+ publisher= cup, address= ny,
+ year= 2003
+)
+
+ at article( althaus1998,
+ author= {Althaus, Scott L.},
+ title= {Information Effects in Collective Preferences},
+ journal= apsr, volume=92,
+ number= 3,
+ pages= {545--558},
+ year= 1998
+)
+
+ at article( AldrichMcKelvey1977,
+ author= {Aldrich, John H. and Richard D. McKelvey},
+ title= {A Method of Scaling with Applications to the 1968 and 1972 Presidential Elections},
+ journal= apsr, volume=71, number=1,
+ pages= {111--130},
+ year= 1977
+)
+
+ at book( amemiya1985,
+ author= {Amemiya, Takeshi},
+ title= {Advanced Econometrics},
+ publisher= hup, address={Cambridge, MA},
+ year= {1985}
+)
+
+ at article( atkinson86,
+ author= {Atkinson, A. C.},
+ title= {Masking Unmasked},
+ journal= {Biometrika}, volume=73,
+ pages= {533--541},
+ year= 1986,
+ month= {Dec.}
+)
+
+ at article( austen-smith1996,
+ author= {Austen-Smith, David and Jeffrey S. Banks},
+ title= {Information Aggregation, Rationality, and the Condorcet Jury Theorem},
+ journal= apsr, volume=90,
+ pages= {34--45},
+ year= 1996
+)
+
+ at unpublished( bartels2003,
+ author= {Bartels, Larry M.},
+ title= {Homer Gets a Tax Cut: Inequality and Public Policy in the American Mind},
+ note= {Annual Meeting of the American Political Science Association, Philadelphia, August},
+ year= 2003
+)
+
+ at article( bartels1999,
+ author= {Bartels, Larry M.},
+ title= {Panel Effects in the National Election Studies},
+ journal= pa, volume=8,
+ number= 1,
+ year= 1999
+)
+
+ at article( bartels1996b,
+ author= {Bartels, Larry M.},
+ title= {Uninformed Votes: Information Effects in Presidential Elections},
+ journal= ajps, volume=40,
+ number= 1,
+ pages= {194--230},
+ year= 1996
+)
+
+ at article( bartels1986,
+ author= {Bartels, Larry M.},
+ title= "Issue Voting Under Uncertainty: An Empirical Test",
+ journal= ajps, volume=30,
+ number= 4,
+ pages= {709--728},
+ year= 1986
+)
+
+ at unpublished( battistin2004,
+ author= {Battistin, Erich and Andrew Chesher},
+ title= {Measurement Error Bias and Propensity Score Methods},
+ year= 2004,
+ note= "Working Paper"
+)
+
+ at article( bennett1988,
+ author= {Bennett, Stephen Earl},
+ title= {Know-nothings' Revisited: The Meaning of Political Ignorance Today},
+ journal= {Social Science Quarterly}, volume=69,
+ pages= {476--490},
+ year= 1988
+)
+
+ at article( berg1993,
+ author= {Berg, Sven},
+ title= {Condorcet's Jury Theorem, Dependency Among Jurors},
+ journal= {Social Choice and Welfare}, volume=10,
+ pages= {87--95},
+ year= 1993
+)
+
+ at book( berelson1954,
+ author= {Berelson, Bernard R. and Paul F. Lazarsfeld and William N. McPhee},
+ title= {Voting: A Study of Opinion Formation in a Presidential Campaign},
+ publisher= uchp, address= chic,
+ year= 1954
+)
+
+ at article( BertsimasTsitsiklis1993,
+ author= {Bertsimas, Dimitris and John Tsitsiklis},
+ title= {Simulated Annealing},
+ journal= "Statistical Science", volume=8, number=1,
+ pages= {10--15},
+ year= 1993
+)
+
+ at book( billingsley1986,
+ author= {Billingsley, Patrick},
+ title= {Probability and Measure},
+ publisher= "Wiley", address= "New York",
+ year= 1986
+)
+
+ at book( bollen1989,
+ author= {Bollen, Kenneth A.},
+ title= {Structural Equations with Latent Variables},
+ publisher= "Wiley", address={New York},
+ year= {1989}
+)
+
+ at unpublished( BowersHansen2005,
+ author= {Bowers, Jake and Ben Hansen},
+ title= {Attributing Effects to a Get-Out-The-Vote Campaign Using Full Matching and Randomization Inference},
+ note= "Working Paper",
+ year= 2005
+)
+
+ at article(braumoeller2003,
+ author= {Braumoeller, Bear F.},
+ title= {Causal Complexity and the Study of Politics},
+ journal= pa, volume=11, number=3,
+ pages= {209-233},
+ year= 2003
+)
+
+ at Manual{BraumoellerGoodrichKline2006,
+ author = {Braumoeller, Bear F. and Ben Goodrich and Jacob Kline},
+ title = {\pkg{Boolean}: Boolean Binary Response Models},
+ note = {\proglang{R}~package version~2.0-2},
+ url = {http://polisci.osu.edu/faculty/braumoeller/custom/Booleanbatch.html},
+ year = {2010},
+}
+
+ at article( BrunellNiNardo2004,
+ author= {Brunell, Thomas L. and John DiNardo},
+ title= {A Propensity Score Reweighting Approach to Estimating the Partisan Effects of Full Turnout in American Presidential Elections},
+ journal= pa, volume=12, number=1,
+ pages= {28--45},
+ year= 2004
+)
+
+ at book( bryce1888,
+ author= {Bryce, James},
+ title= {The American Commonwealth},
+ publisher= {Liberty Fund}, address= {Indianapolis},
+ year= "1995 [1888]"
+)
+
+ at article( bunce2000,
+ author= {Bunce, Valerie},
+ title= {Comparative Democratization: Big and Bounded Generalizations},
+ journal= {Comparative Political Studies}, volume=33, number={6/7},
+ pages= {703--724},
+ year= 2000
+)
+
+ at incollection( camp2004,
+ author= {Camp, Ai Roderic},
+ title= {Citizen Attitudes toward Democracy and Vicente Fox's Victory in 2000},
+ booktitle= {Mexico's Pivotal Democratic Election},
+ editor= {Jorge I. Dom\'{i}nguez and Chappell Lawson},
+ publisher= sup, address= "Stanford",
+ pages= {25--46},
+ year= 2004
+)
+
+ at book( campbell1960,
+ author= {Campbell, Angus and Philip E. Converse and Warren E. Miller and Donald E. Stokes},
+ title= {The {A}merican Voter},
+ publisher= {John Wiley \& Sons}, address= ny,
+ year= 1960
+)
+
+ at article( CantoniRonchetti2001,
+ author= {Cantoni, Eva and Elvezio Ronchetti},
+ title= {Robust Inference for Generalized Linear Models},
+ journal= jasa, volume=96,
+ pages= {1022--1030},
+ year= 2001
+)
+
+ at article( CarrollPederson1993,
+ author= {Carroll, R. J. and Pederson, Shane},
+ title= {On Robustness in the Logistic Regression Model},
+ journal= jrssb, volume=84,
+ number= 3,
+ pages= {693--706},
+ year= 1993
+)
+
+ at article{ cerny1985,
+ author = "Cerny, V.",
+ title = "Thermodynamical Approach to the Traveling Salesman Problem: An Efficient Simulation Algorithm",
+ journal = "Journal of Optimization Theory and Applications", number = "1",
+ volume = "45",
+ pages = "41--51",
+ year = "1985"
+}
+
+ at article( ChristakisIwashyna2003,
+ author= {Christakis, Nicholas A. and Iwashyna, Theodore I.},
+ title= "The Health Impact of Health Care on Families: A matched cohort study of hospice use by decedents and mortality outcomes in surviving, widowed spouses.",
+ journal= "Social Science \& Medicine", volume=57, number=3,
+ pages= {465--475},
+ year= 2003
+)
+
+ at article( CochranRubin1973,
+ author= {Cochran, William G. and Donald B. Rubin},
+ title= "Controlling Bias in Observational Studies: A Review",
+ journal= {Sankhya, $\mathrm{Ser.\ A}$}, volume=35,
+ pages= {417--446},
+ year= 1973
+)
+
+ at book( collier_christopher1971,
+ author= {Collier, Christopher},
+ title= {Roger Sherman's Connecticut: Yankee Politics and the American Revolution},
+ publisher= "Wesleyan University Press", address= "Middletown, Conn.",
+ year= 1971
+)
+
+ at book( conover1971,
+ author= {Conover, William J.},
+ title= {Practical Nonparametric Statistics},
+ publisher= {John Wiley \& Sons}, address= {New York},
+ year= {1971}
+)
+
+ at incollection( converse1964,
+ author= {Converse, Phillip},
+ title= {The Nature of Belief Systems in Mass Publics},
+ booktitle= {Ideology and Discontent},
+ editor= {David Apter},
+ publisher= {Free Press}, address= ny,
+ pages= {240--268},
+ year= 1964
+)
+
+ at article( cornfield1959,
+ author= {Cornfield, J. and W. Haenszel and E. Hammond and A. Lilienfeld and M. Shimkin and E. Wynder},
+ title= {Smoking and lunch cancer: Recent evidence and a discussion of some questions},
+ journal= {Journal of the National Cancer Institute}, volume=22,
+ pages= {173--203},
+ year= 1959
+)
+
+ at article( copas1988,
+ author= {Copas, J. B.},
+ title= {Binary Regression Models for Contaminated Data},
+ journal= jrssb, volume=50,
+ number= 2,
+ pages= {225--265},
+ year= 1988
+)
+
+ at book( cox1958,
+ author= {Cox, David R.},
+ title= {Planning of Experiments},
+ publisher= "Wiley", address= ny,
+ year= 1958
+)
+
+ at book( davis1991,
+ editor= {Davis, Lawrence},
+ title= {Handbook of Genetic Algorithms},
+ publisher= {Van Nostrand Reinhold}, address= {New York},
+ year= {1991}
+)
+
+ at article( dawid1979,
+ author= {Dawid, A. Phillip},
+ title= {Conditional Independence in Statistical Theory},
+ journal= jrssb, volume=41,
+ pages= {1--31},
+ number= 1,
+ year= 1979
+)
+
+ at incollection( dejong1993,
+ author= {De Jong, Kenneth A.},
+ title= {Genetic Algorithms Are Not Function Optimizers},
+ booktitle= {Foundations of Genetic Algorithms 2},
+ editor= {L.~Darrell Whitley},
+ publisher= {Morgan Kaufmann}, address= {San Mateo, CA},
+ year= 1993
+)
+
+ at Article{Dehejia2005,
+ author = {Rajeev Dehejia},
+ title = {Practical Propensity Score Matching: A Reply to Smith and Todd},
+ journal = {Journal of Econometrics},
+ year = {2005},
+ volume = {125}, number="1--2",
+ pages = {355--364},
+}
+
+ at Article{DehejiaWahba2002,
+ author = {Rajeev H. Dehejia and Sadek Wahba},
+ title = {Propensity Score Matching Methods for Nonexperimental Causal Studies},
+ journal = {Review of Economics and Statistics},
+ year = {2002},
+ volume = {84},
+ number = {1},
+ pages = {151--161},
+ month = {February},
+}
+
+ at article( DehejiaWahba1999,
+ author= {Dehejia, Rajeev and Sadek Wahba},
+ title= {Causal Effects in Non-Experimental Studies: Re-Evaluating the Evaluation of Training Programs},
+ journal= jasa, volume=94,
+ number= 448,
+ pages= {1053--1062},
+ year= 1999
+)
+
+ at unpublished( DehejiaWahba1997,
+ author= {Dehejia, Rajeev and Sadek Wahba},
+ title= {Causal Effects in Non-Experimental Studies: Re-Evaluating the Evaluation of Training Programs},
+ note= {Rejeev Dehejia, \textit{Econometric Methods for Program Evaluation}. Ph.D. Dissertation, Harvard University, Chapter 1},
+ year= 1997
+)
+
+ at book( delli1996,
+ author= {Delli Carpini, X. Michael and Scott Keeter},
+ title= {What Americans Know about Politics and Why It Matters},
+ publisher= {Yale University Press}, address= {New Haven},
+ year= 1996
+)
+
+ at article( delli1993,
+ author= {Delli Carpini, X. Michael and Scott Keeter},
+ title= {Measuring Political Knowledge: Putting First Things First},
+ journal= ajps, volume=37,
+ number = 4,
+ pages= {1179-1206},
+ year= 1993
+)
+
+ at Manual{DiceOptim,
+ author = {Ginsbourger, D. and O. Roustant},
+ title = {\pkg{DiceOptim}: Kriging-based optimization for computer experiments},
+ note = {\proglang{R}~package version~1.0},
+ url = {http://cran.r-project.org/package=DiceOptim},
+ year = {2010},
+}
+
+ at article( DipreteEngelhardt2004,
+ author= {Diprete, Thomas A. and Henriette Engelhardt},
+ title= {Estimating Causal Effects With Matching Methods in the Presence and Absence of Bias Cancellation},
+ journal= "Sociological Methods \& Research", volume=32, number=4,
+ pages= "501--528",
+ year= "2004",
+)
+
+ at incollection( dominguez2004,
+ author= {Dom\'{i}nguez, I. Jorge},
+ title= {Why and How Did Mexico's 2000 Presidential Election Campaign Matter?},
+ booktitle= {Mexico's Pivotal Democratic Election},
+ editor= {Jorge I. Dom\'{i}nguez and Chappell Lawson},
+ publisher= sup, address= "Stanford",
+ pages= {321--344},
+ year= 2004
+)
+
+ at article( drake1993,
+ author= {Drake, Christiana},
+ title= {Effects of Misspecification of the Propensity Score on Estimators of Treatment Effect},
+ journal= {Biometrics}, volume=49,
+ number= 4,
+ pages= {1231--1236},
+ year= 1993
+)
+
+ at article( DrukkerWiggins2004,
+ author= {Drukker, David M. and Vince Wiggins},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Comment},
+ journal= aer, volume=94, number=1,
+ pages= {397--399},
+ year= 2004
+)
+
+ at book( EfronTibshirani1994,
+ author= {Efron, Bradely and Robert J. Tibshirani},
+ title= {An Introduction to the Bootstrap},
+ publisher= {Chapman \& Hall}, address= {New York},
+ year= {1994}
+)
+
+ at article( EpsteinHoKing2005,
+ author= {Epstein, Lee and Daniel E. Ho and Gary King and Jeffrey A. Segal},
+ title= {The Supreme Court During Crisis: How War Affects only Non-War Cases},
+ journal= "New York University Law Review", volume=80, number=1,
+ pages= "1--116",
+ year= "2005",
+)
+
+ at article( erikson1988,
+ author= {Erikson, Robert S.},
+ title= {The Puzzle of Midterm Loss},
+ journal= jop, volume=50,
+ number = 4,
+ pages= {1012--1029},
+ year= 1988
+)
+
+ at book( FahrmeirTutz1994,
+ author= {Fahrmeir, Ludwig and Gerhard Tutz},
+ title= {Multivariate Statistical Modeling Based on Generalized Linear Models},
+ publisher= "Springer-Verlag", address= "New York",
+ year= 1994
+)
+
+ at book( fechner1860,
+ author= {Fechner, Gustav Theodor},
+ title= {Elements of psychophysics, Vol 1.},
+ note = {Translated by Helmut E. Adler and edited by D.H. Howes and E.G. Boring},
+ publisher= {Rinehart \& Winston}, address= ny,
+ year= "1966 [1860]"
+)
+
+ at book( feller1970,
+ author= {Feller, William},
+ title= {An Introduction to Probability Theory and Its Applications},
+ publisher= "Wiley", address= "New York",
+ note= "Vol.\ 1, 3d ed., revised printing",
+ year= 1970
+)
+
+ at article( FilhoTreleavenAlippi1994,
+ author= {Filho, Jose L. Ribeiro, Philip C. Treleaven and Cesare Alippi},
+ title= {Genetic Algorithm Programming Environments},
+ journal= {Computer}, volume=27,
+ pages= {28--43},
+ year= 1994
+)
+
+ at book( fiorina1996,
+ author= {Fiorina, Morris P.},
+ title= {Divided Government},
+ publisher= {Allyn \& Bacon}, address= "Boston",
+ edition= "2nd",
+ year= 1992
+)
+
+ at book( fisher1935,
+ author= {Fisher, Ronald A.},
+ title= {Design of Experiments},
+ publisher= {Hafner}, address= {New York},
+ year= {1935}
+)
+
+ at book( fishkin1997,
+ author= {James S. Fishkin},
+ title= {The Voice of the People: Public Opinion and Democracy},
+ edition= {2nd},
+ publisher= {Yale University Press}, address= {New Haven, CT},
+ year= {1997}
+)
+
+ at article( franklin1991,
+ author= {Franklin, Charles H.},
+ title= {Eschewing Obfuscation? Campaigns and the Perception of U.S. Senate Incumbents},
+ journal= apsr, volume=85,
+ number = 4,
+ pages= {1193--1214},
+ year= 1991
+)
+
+ at book( gallant1987,
+ author= {Gallant, A. Ronald},
+ title= {Nonlinear Statistical Models},
+ publisher= "Wiley", address= ny,
+ year= 1987
+)
+
+ at article( GalianiGertlerSchargrodsky2005,
+ author= {Galiani, Sebastian and Paul Gertler and Ernesto Schargrodsky},
+ title= {Water for Life: The Impact of the Privatization of Water Services on Child Mortality},
+ journal= jpe, volume=113, number=1,
+ pages= {83--120},
+ year= 2005
+)
+
+ at article( geddes1999,
+ author= {Geddes, Barbara},
+ title= {What Do We Know about Democratization},
+ journal= "Annual Review of Political Science", volume=2,
+ pages= {129--148},
+ year= 1999
+)
+
+ at book( GillMurrayWright1981,
+ author= {Gill, Philip E. and Walter Murray and Margaret H. Wright},
+ title= {Practical Optimization},
+ publisher= "Academic Press", address= "San Diego",
+ year= 1981
+)
+
+ at incollection( GrefenstetteBaker1989,
+ author= {Grefenstette, John J. and James E. Baker},
+ title= {How Genetic Algorithms Work: A Critical Look at Implicit Parallelism},
+ booktitle= {Proceedings of the Third International Conference on Genetic Algorithms},
+ publisher= "Morgan Kaufmann", address= "San Mateo, CA",
+ pages= {20--27},
+ year= 1989
+)
+
+ at article( GeyerThompson1995,
+ author= {Geyer, Charles J. and Elizabeth A. Thompson},
+ title= {Annealing Markov Chain Monte Carlo with Applications to Ancestral Inference},
+ journal= jasa, volume=90, number=431,
+ pages= {909--920},
+ year= 1995
+)
+
+ at book( goldberg1989,
+ author= {Goldberg, David E.},
+ title= {Genetic Algorithms in Search, Optimization, and Machine Learning},
+ publisher= "Addison-Wesley", address= "Reading, MA",
+ year= 1989
+)
+
+ at Manual{goodrich.fair,
+ author = {Goodrich, Ben},
+ title = {\pkg{FAiR}: Factor Analysis in \proglang{R}},
+ note = {\proglang{R}~package version~0.4-7},
+ url = {http://cran.r-project.org/package=FAiR},
+ year = {2011},
+}
+
+ at incollection( grefenstette1993,
+ author= {Grefenstette, John J.},
+ title= {Deception Considered Harmful},
+ booktitle= {Foundations of Genetic Algorithms 2},
+ editor= {L.~Darrell Whitley},
+ publisher= {Morgan Kaufmann}, address= {San Mateo, CA},
+ year= 1993
+)
+
+ at book( habermas1964,
+ author= {Habermas, J\"{u}rgen},
+ title= {The Structural Transformation of the Public Sphere: An Inquiry into a Category of Bourgeois Society},
+ note = {Translated by Thomas Burger},
+ publisher= mit, address= cam,
+ year= "1996 [1964]"
+)
+
+ at book( hall1992,
+ author= {Hall, Peter},
+ title= {The Bootstrap and Edgeworth Expansion},
+ publisher= {Springer-Verlag}, address= {New York},
+ year= {1992}
+)
+
+ at book( hampel1986,
+ author= {Hampel, Frank R. and Elvezio M. Ronchetti and Peter J. Rousseeuw and Werner A. Stahel},
+ title= {Robust Statistics: The Approach Based on Influence Functions},
+ publisher= {Wiley, John and Sons}, address= {New York},
+ year= 1986
+)
+
+ at article( HausmanWise1979,
+ author= {Hausman, Jerry A. and David A. Wise},
+ title= {Attrition Bias in Experimental and Panel Data: The Gary Income Maintenance Experiment},
+ journal= ec, volume=47,
+ pages= {455--473},
+ year= 1979
+)
+
+ at article( hirnao1998,
+ author= {Hirano, Keisuke and Guido W. Imbens and Geert Ridder and Donald B. Rubin},
+ title= {Combining Panel Data Sets with Attrition and Refreshment Samples},
+ journal= ec, volume=69,
+ pages= {1645--1659},
+ year= 1998
+)
+
+ at article( heckman1979,
+ author= {Heckman, James J},
+ title= {Sample Selection Bias as a Specification Error},
+ journal= ec, volume=47,
+ pages= {153--161},
+ year= 1979
+)
+
+ at article( heckman1998,
+ author= {Heckman, James J. and Hidehiko Ichimura and Jeffrey Smith and Petra Todd},
+ title= {Characterizing Selection Bias Using Experimental Data},
+ journal= ec, volume=66,
+ number = 5,
+ pages= {1017-1098},
+ year= 1998
+)
+
+\item
+, ed. 1985.
+\textit{.}
+New York: Cambridge University Press.
+
+ at book( HeckmanSinger1985,
+ editor= {Heckman, James J. and Burton Singer},
+ title= {Longitudinal Analysis of Labor Market Data},
+ publisher= cup, address={New York},
+ year= {1985}
+)
+
+ at unpublished{HerronWand2004,
+ author = {Herron, Michael C. and Jonathan Wand},
+ title = {Assessing Partisan Bias in Voting Technology: The Case of the 2004 New Hampshire Recount},
+ note = "Working Paper",
+ year = {2004},
+}
+
+ at article( hersh1982,
+ author= {Hersh, Seymour M.},
+ title= {The Price of Power: Kissinger, Nixon, and Chile},
+ journal= {The Atlantic Monthly}, month=12,
+ url= {http://www.theatlantic.com/issues/82dec/hersh.htm},
+ year= 1982
+)
+
+ at book( hettmansperger1984,
+ author= {Hettmansperger, T},
+ title= {Statistical Inference Based on Ranks},
+ publisher= "Wiley", address= ny,
+ year= 1984
+)
+
+ at article( holland1986,
+ author= {Holland, Paul W.},
+ title= {Statistics and Causal Inference},
+ journal= jasa, volume=81, number=396,
+ pages= {945--960},
+ year= 1986
+)
+
+ at book( holland1975,
+ author= {Holland, John H.},
+ title= {Adaptation in Natural and Artificial Systems},
+ publisher= "University of Michigan Press", address= "Ann Arbor",
+ year= 1975
+)
+
+ at article( HorvitzThompson1952,
+ author= {Horvitz, D. G. and D. J. Thompson},
+ title= {A Generalization of Sampling without Replacement from a Finite Universe},
+ journal= jasa, volume=47,
+ pages= {663--685},
+ year= 1952
+)
+
+ at book( huber1981,
+ author= {Huber, Peter J.},
+ title= {Robust Statistics},
+ publisher= {Wiley, John and Sons}, address= {New York},
+ year= 1981
+)
+
+ at book( huntington1968,
+ author= {Huntington, Samuel P.},
+ title= {Political Order in Changing Societies},
+ publisher= {Yale University Press}, address= {New Haven},
+ year= 1968
+)
+
+ at book( huntington1991,
+ author= {Huntington, Samuel P.},
+ title= {The Third Wave: Democratization in the Late Twentieth Century},
+ publisher= {University of Oklahoma Press}, address= {Norman and London},
+ year= 1991
+)
+
+ at article(KingWand2007,
+ author= {King, Gary and Jonathan Wand},
+ title= {Comparing Incomparable Survey Responses: Evaluating and Selecting Anchoring Vignettes},
+ journal= pa, volume=15,
+ pages= {46--66},
+ year= 2007
+)
+
+ at article{ KirkpatrickGelattVecchi83,
+ author = "S. Kirkpatrick and C. D. Gelatt and M. P. Vecchi",
+ title = "Optimization by Simulated Annealing",
+ journal = "Science", number = "4598",
+ volume = "220",
+ pages = "671--680",
+ year = "1983"
+}
+
+
+ at book( knuth1998,
+ author= {Knuth, Donald E.},
+ title= {The Art of Computer Programming, Vol. 2: Seminumerical Algorithms},
+ edition= "3rd",
+ publisher= "Addison-Wesley", address= "Reading: MA",
+ year= 1998
+)
+
+ at Manual{KrigInv,
+ author = {Victor Picheny and David Ginsbourger},
+ title = {\pkg{KrigInv}: Kriging-based Inversion for Deterministic and Noisy Computer Experiments},
+ note = {\proglang{R}~package version~1.1},
+ url = {http://CRAN.R-project.org/package=KrigInv},
+ year = {2011}
+}
+
+ at unpublished( krosnick2004,
+ author= {Holbrook, Allyson L. and Matthew K. Berent and Jon A. Krosnick and Penny S. Visser and David S. Boninger},
+ title= {Attitude Importance and the Accumulation of Attitude-Relevant Knowledge in Memory},
+ note= "Working Paper",
+ year= 2004
+)
+
+ at Manual{LeeLee2006,
+ author = {Lee, Chun-Ying and Yung-Jin Lee},
+ title = {\pkg{PKfit}: A Tool for Data Analysis in Pharmacokinetics},
+ note = {\proglang{R}~package version~1.1.8},
+ url = {http://CRAN.R-project.org/package=PKfit},
+ year = {2009},
+}
+
+ at Manual{ivivc,
+ author = {Hsin Ya Lee and Yung-Jin Lee},
+ title = {\pkg{ivivc}: in vitro-in vivo correlation (IVIVC) modeling},
+ note = {\proglang{R}~package version~0.1.5},
+ url = {http://CRAN.R-project.org/package=ivivc},
+ year = {2009}
+}
+
+ at article( imbens2000,
+ author= {Imbens, Guido W.},
+ title= "The Role of the Propensity Score in Estimating Dose-Response Functions",
+ journal= {Biometrika}, volume=87, number=3,
+ pages= {706--710},
+ year= 2000
+)
+
+ at Article{imai2005,
+ author = {Kosuke Imai},
+ title = {Do Get-Out-The-Vote Calls Reduce Turnout? The Importance of Statistical Methods for Field Experiments},
+ journal = apsr, volume = 99, number=2,
+ pages = "283--300",
+ year = {2005},
+}
+
+ at incollection( iyengar1990,
+ author= {Iyengar, Shanto},
+ title= {Shorts to Political Knowledge: Selective attention and the accessibility bias},
+ booktitle= {Information and the Democratic Process},
+ editor= {John Ferejohn and James Kuklinski},
+ publisher= {University of Illinois Press}, address= {Urbana},
+ year= 1990
+)
+
+ at unpublished( iyengar1986,
+ author= {Iyengar, Shanto},
+ title= {Whither Political Information},
+ note= {Report to the NES Board of Overseers. Center for Political Studies, University of Michigan},
+ year= 1986
+)
+
+ at Manual{JOP,
+ author = {Sonja Kuhnt and Nikolaus Rudak},
+ title = {\pkg{JOP}: Joint Optimization Plot},
+ note = {\proglang{R}~package version~2.0.1},
+ url = {http://cran.r-project.org/package=JOP},
+ year = {2011},
+}
+
+ at book( johnston2004,
+ author= {Johnston, Richard and Michael G. Hagen and Kathleen Hall Jamieson},
+ title= {The 2000 Presidential Election and the Foundations of Party Politics},
+ publisher= cup, address= ny,
+ year= 2004
+)
+
+ at book( johnston1992,
+ author= {Johnston, Richard and Andr\'{e} Blais and Henry E. Brady and Jean Cr\^{e}te},
+ title= {Letting the People Decide: Dynamics of a Canadian Election},
+ publisher= "McGill-Queen's University Press", address= "Montreal",
+ year= 1992
+)
+
+ at book( kornhauser1959,
+ author= {Kornhauser, William},
+ title= {The Politics of Mass Society},
+ publisher= {The Free Press}, address= {New York},
+ year= 1959
+)
+
+ at article( kunsch1989,
+ author= {Kunsch, H. R. and L. A. Stefanski and R. J. Carroll},
+ title= {Conditionally Unbiased Bounded-Influence Estimation in General Regression Models},
+ journal= jasa, volume=84,
+ pages= {460--466},
+ year= 1989
+)
+
+ at book( lancaster1990,
+ editor= {Lancaster, Tony},
+ title= {The Econometric Analysis of Transition Data},
+ publisher= cup, address={New York},
+ year= {1990}
+)
+
+ at Article{lalonde1986,
+ author = {Robert LaLonde},
+ title = {Evaluating the Econometric Evaluations of Training Programs with Experimental Data},
+ journal = {American Economic Review},
+ year = {1986},
+ OPTkey = {},
+ volume = {76},
+ OPTnumber = {4},
+ pages = {604--20},
+ month = {September},
+ OPTnote = {},
+ OPTannote = {}
+}
+
+ at incollection( lawson2004,
+ author= {Lawson, Chappell},
+ title= {Introduction},
+ booktitle= {Mexico's Pivotal Democratic Election},
+ editor= {Jorge I. Dom\'{i}nguez and Chappell Lawson},
+ publisher= sup, address= "Stanford",
+ pages= {1--21},
+ year= 2004
+)
+
+ at article( lipset1959,
+ author= {Lipset, Seymour Martin},
+ title= {Some Social Requisites of Democracy: Economic Development and Political Legitimacy},
+ journal= apsr, volume=53, number=1,
+ pages= {69--105},
+ year= 1959
+)
+
+ at book( LittleRubin1987,
+ author= {Little, Roderick J. A. and Rubin, Donald B.},
+ title= {Statistical Analysis with Missing Data},
+ publisher= {J. Wiley \& Sons}, address= ny,
+ year= 1987
+)
+
+ at unpublished( lupia2004,
+ author= {Lupia, Arthur},
+ title= {Questioning Our Competence: Tasks, Institutions, and the Limited Practical Relevance of Common Political Knowledge Measures},
+ note= "Working Paper",
+ year= 2004
+)
+
+ at article( luskin2002,
+ author= {Luskin, Robert C. and James S. Fishkin and Roger Jowell},
+ title= {Considered Opinions: Deliberative Polling in Britain},
+ journal= bjps, volume=32,
+ pages= {455--487},
+ year= 2002
+)
+
+ at book( MccullaghNelder1989,
+ author= {McCullagh, Peter and John A. Nelder},
+ title= {Generalized Linear Models},
+ edition= "2nd",
+ publisher= c-h, address= ny,
+ year= 1989
+)
+
+ at article( McCulloughVinod2004a,
+ author= {McCullough, B. D. and H. D. Vinod},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Reply},
+ journal= aer, volume=94, number=1,
+ pages= {391--396},
+ year= 2004
+)
+
+ at article( McCulloughVinod2004b,
+ author= {McCullough, B. D. and H. D. Vinod},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Reply},
+ journal= aer, volume=94, number=1,
+ pages= {400--403},
+ year= 2004
+)
+
+ at article( McCulloughVinod2003,
+ author= {McCullough, B. D. and H. D. Vinod},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study},
+ journal= aer, volume=93, number=3,
+ pages= {873--892},
+ year= 2003
+)
+
+ at article( mckelvey1985a,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Elections with Limited
+Information: A Fulfilled Expectations Model Using Contemporaneous Poll and
+Endorsement Data as Information Sources},
+ journal= jet, volume=36,
+ pages= {55--85},
+ year= 1985
+)
+
+ at article( mckelvey1985b,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Sequential Elections with Limited Information},
+ journal= ajps, volume=29, number=3,
+ pages= {480--512},
+ year= 1985
+)
+
+ at article( mckelvey1986,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Information, Electoral Equilibria, and the Democratic Ideal},
+ journal= jop, volume=48, number=4,
+ pages= {909--937},
+ year= 1986
+)
+
+ at article( mcgraw1990,
+ author= {McGraw, Kathleen and Neil Pinney},
+ title= {The Effects of General and Domain-Specific Expertise on Political Memory and Judgement},
+ journal= {Social Cognition}, volume=8,
+ pages= {9--30},
+ year= 1990
+)
+
+ at article( mckelvey1985a,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Elections with Limited
+Information: A Fulfilled Expectations Model Using Contemporaneous Poll and
+Endorsement Data as Information Sources},
+ journal= jet, volume=36,
+ pages= {55--85},
+ year= 1985
+)
+
+ at article( mckelvey1985b,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Sequential Elections with Limited Information},
+ journal= ajps, volume=29, number=3,
+ pages= {480--512},
+ year= 1985
+)
+
+ at article( mckelvey1986,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Information, Electoral Equilibria, and the Democratic Ideal},
+ journal= jop, volume=48, number=4,
+ pages= {909--937},
+ year= 1986
+)
+
+ at article( McNemar1947,
+ author= {McNemar, Q.},
+ title= {Note on the Sampling Error of the Differences Between Correlated Proportions or Percentage},
+ journal= {Psychometrika}, volume=12,
+ pages= {153--157},
+ year= 1947
+)
+
+ at book( maddala1992,
+ author= {Maddala, G.S.},
+ title= {Introduction to Econometrics},
+ edition= "2nd",
+ publisher= {MacMillan}, address= {New York},
+ year= "1992"
+)
+
+ at book( maddala1983,
+ author= {Maddala, G.S.p},
+ title= {Limited-Dependent and Qualitative Variables in Econometrics},
+ publisher= cup, address={New York},
+ year= {1983}
+)
+
+ at article{ MarinariParisi1992,
+ author = "E. Marinari and G. Parisi",
+ title = "Simulated tempering: A New Monte Carlo Scheme",
+ journal = "Europhysics Letters", number = "19",
+ volume = "6",
+ pages = "451--455",
+ year = "1992"
+}
+
+ at article( MannWhitney1947,
+ author= {Mann, H. and Whitney, D},
+ title= {On a Test of Whether One of Two Random Variables is Stochastically Larger than the Other},
+ journal= {Annals of Mathematical Statistics}, volume=18,
+ pages= {50--60},
+ year= 1947
+)
+
+ at Article{MebaneJr.+Sekhon:2011,
+ author = {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title = {Genetic Optimization Using Derivatives: The \pkg{rgenoud} Package for \proglang{R}},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at article( mebane2000,
+ author= {Mebane, Jr., Walter R.},
+ title= {Coordination, Moderation and Institutional Balancing in American Presidential and House Elections},
+ journal= apsr, volume=94,
+ number = 1,
+ pages= {37--57},
+ year= 2000
+)
+
+ at Manual{MebaneSekhon1997,
+ author = {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title = {GENetic Optimization Using Derivatives (GENOUD)},
+ note = {Computer program available upon request},
+ year = {1997}
+}
+
+ at article( MebaneSekhon2004,
+ author= {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title= {Robust Estimation and Outlier Detection for Overdispersed Multinomial Models of Count Data},
+ journal= ajps, volume=48,
+ number = 2,
+ pages= {391--410},
+ year= 2004
+)
+
+ at Manual{MebaneSekhon.multinomRob,
+ author = {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title = {\pkg{multinomRob}: Robust Estimation of Overdispersed Multinomial Regression Models},
+ note = {\proglang{R}~package version~1.8-4},
+ url = {http://CRAN.R-project.org/package=multinomRob},
+ year = {2009},
+}
+
+ at article( MebaneSekhon2002,
+ author= {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title= {Coordination and Policy Moderation at Midterm},
+ journal= apsr, volume=96,
+ number = 1,
+ pages= {141--157},
+ year= 2002
+)
+
+ at unpublished( MebaneSekhon1998,
+ author= {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title= {GENetic Optimization Using Derivatives (GENOUD)},
+ note = {Software Package. \url{http://sekhon.berkeley.edu/rgenoud/}},
+ year= 1998
+)
+
+ at book( Michalewicz1992,
+ author= {Michalewicz, Zbigniew},
+ title= {Genetic Algorithms + Data Structures = Evolution Programs},
+ publisher= s-v, address= {New York},
+ year= {1992}
+)
+
+ at unpublished( MichalewiczSwaminathanLogan1993,
+ author= {Michalewicz, Zbigniew and Swarnalatha Swaminathan and Thomas D. Logan},
+ title= {GENOCOP (version 2.0)},
+ note = {C language computer program source code.
+\url{http://www.cs.adelaide.edu.au/~zbyszek/EvolSyst/genocop2.0.tar.Z}},
+ year= 1993
+)
+
+ at book( mes2002,
+ author= {Erikson, Robert S. and Michael B. MacKuen and James A. Stimson},
+ title= {The Macro Polity},
+ publisher= cup, address= {New York},
+ year= {2002}
+)
+
+ at incollection( miller1986,
+ author= {Miller, Nicholas R},
+ title= {Information, Electorates, and Democracy: Some Extensions and
+Interpretations of the Condorcet Jury Theorem},
+ booktitle= {Information Pooling and Group Decision Making},
+ editor= {Bernard Grofman and Guillermo Owen},
+ publisher= {JAI}, address= {Greenwich, CT},
+ year= 1986
+)
+
+ at article{MitchellKrzanowski1989,
+ author = {Mitchell, Ann F. S. and Wojtek J. Krzanowski},
+ title = {Amendments and Corrections: The Mahalanobis Distance and Elliptic Distributions},
+ journal = {Biometrika},
+ year = {1989},
+ volume = {76},
+ number = {2},
+ pages = {407},
+}
+
+ at article{MitchellKrzanowski1985,
+ author = {Mitchell, Ann F. S. and Wojtek J. Krzanowski},
+ title = {The Mahalanobis Distance and Elliptic Distributions},
+ journal = {Biometrika},
+ year = {1985},
+ volume = {72},
+ number = {2},
+ pages = {464--467},
+}
+
+ at book( neuman86,
+ author= {Neuman, W. Russell},
+ title= {The Paradox of Mass Politics: Knowledge and Opinion in the {A}merican Electorate},
+ publisher= hup, address= cam,
+ year= 1986
+)
+
+ at article( NixVose1992,
+ author= {Nix, Allen E. and Michael D. Vose},
+ title= {Modeling Genetic Algorithms with Markov Chains},
+ journal= {Annals of Mathematics and Artificial Intelligence}, volume=5,
+ pages= {79--88},
+ year= 1992
+)
+
+ at book( page1992,
+ author= {Page, Benjamin I. and Robert Y. Shapiro},
+ title= {The Rational Public: Fifty Years of Trends in {A}mericans' Policy Preferences},
+ publisher= uchp, address= chic,
+ year= 1992
+)
+
+ at article( PalfreyPoole1987,
+ author= {Palfrey, Thomas R. and Keith T. Poole},
+ title= {The Relationship between Information, Ideology, and Voting Behavior},
+ journal= ajps, volume=31,
+ number = 3,
+ pages= {511--530},
+ year= 1987
+)
+
+ at book( patterson2002,
+ author= {Patterson, Thomas E.},
+ title= {The Vanishing Voter: Public Involvement in an Age of Uncertainty},
+ publisher= "Alfred A. Knopf", address= "New York",
+ year= 2002
+)
+
+ at book( popkin1991,
+ author= {Popkin, Samuel L},
+ title= {The Reasoning Voter: Communication and Persuasion in Presidential Campaigns},
+ publisher= uchp, address= chic,
+ year= 1991
+)
+
+ at article( PriceZaller1993,
+ author= {Price, Vincent and John Zaller},
+ title= {Who Gets the News? Alternative Measures of News Reception and Their Implications for Research},
+ journal= {Public Opinion Quarterly}, volume=57, number=2,
+ pages= {133--164},
+ year= 1993
+)
+
+ at article( pryor2003,
+ author= {Pryor, Kane},
+ title= {A national state of confusion},
+ journal= {Salon.com}, month=6, day=2,
+ url= {http://www.salon.com/opinion/feature/2003/02/06/iraq_poll},
+ note= "Accessed 07/05/2004",
+ year= 2003
+)
+
+ at book( putnam2000,
+ author= {Putnam, Robert D.},
+ title= {Bowling Alone: The Collapse and Revival of American Community},
+ publisher= "Simon \& Schuster", address= ny,
+ year= 2000
+)
+
+ at book( rosenbaum2002,
+ author= {Rosenbaum, Paul R.},
+ title= {Observational Studies},
+ edition= "2nd",
+ publisher= "Springer-Verlag", address= ny,
+ year= 2002
+)
+
+ at article( Rosenbaum1999,
+ author= {Rosenbaum, Paul R.},
+ title= {Using Quantile Averages in Matched Observational Studies},
+ journal= {Applied Statistics}, volume=48,
+ number= 1,
+ pages= {63--78},
+ year= 1999
+)
+
+ at article( Rosenbaum1993,
+ author= {Rosenbaum, Paul R.},
+ title= {Comparison of Multivariate Matching Methods: Structures, Distances, and Algorithms},
+ journal= {Journal of Computational and Graphical Statistics}, volume=2,
+ number= 4,
+ pages= {405--420},
+ year= 1993
+)
+
+ at article( Rosenbaum1991,
+ author= {Rosenbaum, Paul R.},
+ title= {A Characterization of Optimal Designs for Observational Studies},
+ journal= jrssb, volume=53,
+ number= 3,
+ pages= {597--610},
+ year= 1991
+)
+
+ at article( Rosenbaum1989,
+ author= {Rosenbaum, Paul R.},
+ title= {Optimal Matching for Observational Studies},
+ journal= jasa, volume=84,
+ number= 408,
+ pages= {1024--1032},
+ year= 1989
+)
+
+ at article( RosenbaumRubin1985,
+ author= {Rosenbaum, Paul R. and Donald B. Rubin},
+ title= {Constructing a Control Group Using Multivariate Matched Sampling Methods That Incorporate the Propensity Score},
+ journal= {The American Statistician}, volume=39,
+ number= 1,
+ pages= {33--38},
+ year= 1985
+)
+
+ at article( RosenbaumRubin1984,
+ author= {Rosenbaum, Paul R. and Donald B. Rubin},
+ title= {Reducing Bias in Observational Studies Using Subclassification on the Propensity Score},
+ journal= jasa, volume=79,
+ number= 387,
+ pages= {516--524},
+ year= 1984
+)
+
+ at article( RosenbaumRubin1983,
+ author= {Rosenbaum, Paul R. and Donald B. Rubin},
+ title= {The Central Role of the Propensity Score in Observational Studies for Causal Effects},
+ journal= {Biometrika}, volume=70,
+ number= 1,
+ pages= {41--55},
+ year= 1983
+)
+
+ at article( rubin2001,
+ author= {Rubin, Donald B},
+ title= "Using Propensity Scores to Help Design Observational Studies: Application to the Tobacco Litigation",
+ journal= "Health Services \& Outcomes Research Methodology", volume=2, number=1,
+ pages= "169--188",
+ year= 2001
+)
+
+ at article( rubin1997,
+ author= {Rubin, Donald B},
+ title= "Estimating Causal Effects from Large Data Sets Using Propensity Scores",
+ journal= {Annals of Internal Medicine}, volume=127, number="8S",
+ pages= "757--763",
+ year= 1997
+)
+
+ at book( rubinMI1987,
+ author= {Rubin, Donald B.},
+ title= {Multiple Imputation for Nonresponse in Surveys},
+ publisher= {J. Wiley \& Sons}, address= ny,
+ year= 1987
+)
+
+ at article( rubin1980,
+ author= {Rubin, Donald B.},
+ title= "Bias Reduction Using Mahalanobis-Metric Matching",
+ journal= {Biometrics}, volume=36,
+ number = 2,
+ pages= {293--298},
+ year= 1980
+)
+
+ at article( rubin1979,
+ author= {Rubin, Donald B.},
+ title= "Using Multivariate Sampling and Regression Adjustment to Control Bias in Observational Studies",
+ journal= jasa, volume=74,
+ pages= {318--328},
+ year= 1979
+)
+
+ at article( rubin1978,
+ author= {Rubin, Donald B.},
+ title= {Bayesian Inference for Causal Effects: The Role of Randomization},
+ journal= {Annals of Statistics}, volume=6, number=1,
+ pages= {34--58},
+ year= 1978
+)
+
+ at article( rubin1977,
+ author= {Rubin, Donald B.},
+ title= {Assignment to a Treatment Group on the Basis of a Covariate},
+ journal= {Journal of Educational Statistics}, volume=2,
+ pages= {1--26},
+ year= 1977
+)
+
+ at article( rubin1976,
+ author= {Rubin, Donald B.},
+ title= {Multivariate Matching Methods That are Equal Percent Bias Reducing, I: Some Examples},
+ journal= {Biometrics},
+ volume = 32,
+ number = 1,
+ pages= {109--120},
+ year= 1976
+)
+
+ at article( rubin1976b,
+ author= {Rubin, Donald B.},
+ title= {Multivariate Matching Methods That are Equal Percent Bias Reducing, II: Maximums on Bias Reduction for Fixed Sample Sizes},
+ journal= {Biometrics},
+ volume = 32,
+ number = 1,
+ pages= {121--132},
+ year= 1976
+)
+
+ at article( rubinMI1976,
+ author= {Rubin, Donald B.},
+ title= {Inference and Missing Data},
+ journal= {Biometrika}, volume=63,
+ pages= {581-592},
+ year= 1976
+)
+
+ at article( rubin1973a,
+ author= {Rubin, Donald B.},
+ title= "Matching to Remove Bias in Observational Studies",
+ journal= {Biometrics}, volume=29,
+ pages= {159--184},
+ year= 1973
+)
+
+ at article( rubin1973b,
+ author= {Rubin, Donald B.},
+ title= "The Use of Matching and Regression Adjustment to Remove Bias in Observational Studies",
+ journal= {Biometrics}, volume=29,
+ pages= {185--203},
+ year= 1973
+)
+
+ at unpublished( RubinStuart,
+ author= {Rubin, Donald B. and Elizabeth A. Stuart},
+ title= {Affinely Invariant Matching Methods with Discriminant Mixtures of Proportional Ellipsoidally Symmetric Distributions},
+ note= "Working Paper",
+ year= 2005
+)
+
+ at article( RubinThomas1996,
+ author= {Rubin, Donald B. and Neal Thomas},
+ title= "Matching Using Estimated Propensity Scores: Relating Theory to Practice",
+ journal= {Biometrics}, volume=52, number=1,
+ pages= {249--264},
+ year= 1996
+)
+
+ at article( RubinThomas1992,
+ author= {Rubin, Donald B. and Neal Thomas},
+ title= "Affinely Invariant Matching Methods with Ellipsoidal Distributions",
+ journal= aos, volume=20, number=2,
+ pages= {1079--1093},
+ year= 1992
+)
+
+ at article( RubinThomas1992b,
+ author= {Rubin, Donald B. and Neal Thomas},
+ title= "Characterizing the Effect of Matching Using Linear Propensity Score Methods with Normal Distributions",
+ journal= "Biometrika", volume=79, number=4,
+ pages= {797--809},
+ year= 1992
+)
+
+
+
+ at article( rustow1970,
+ author= {Rustow, Dankwart A.},
+ title= {Transitions to Democracy: Toward a Dynamic Model},
+ journal= {Comparative Politics}, volume=2, number=3,
+ pages= {337--363},
+ year= 1970
+)
+
+ at article(SchacharNalebuff2004,
+ author= {Shachar, Ron and Barry Nalebuff},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Comment},
+ journal= aer, volume=94, number=1,
+ pages= {382-390},
+ year= 2004
+)
+
+ at book( schafer1997a,
+ author= {Schafer, Joseph L.},
+ title= {Analysis of Incomplete Multivariate Data},
+ publisher= c-h, address= "London",
+ year= 1997
+)
+
+ at unpublished( schafer1997b,
+ author= {Schafer, Joseph L.},
+ title= {Imputation of missing covariates under a general linear mixed model},
+ note= {Technical report, Dept. of Statistics, Penn State University},
+ year= 1997
+)
+
+ at Manual{SekhonMatching,
+ author = {Jasjeet S. Sekhon},
+ title = {\pkg{Matching}: Multivariate and Propensity Score Matching with Automated Balance Search},
+ note = {\proglang{R}~package version~4.7-12},
+ url = {http://CRAN.R-project.org/package=Matching},
+ year = {2011},
+}
+
+ at article( sekhon2004,
+ author= {Sekhon, Jasjeet S.},
+ title= {Quality Meets Quantity: Case Studies, Conditional Probability and Counterfactuals},
+ journal= pop, volume=2,
+ number = 2,
+ pages= {281--293},
+ year= 2004
+)
+
+ at unpublished( SekhonInformation,
+ author= {Sekhon, Jasjeet S.},
+ title= "The Varying Role of Voter Information Across Democratic Societies",
+ note = "Working Paper",
+ url= {http://sekhon.berkeley.edu/papers/SekhonInformation.pdf},
+ year= 2004
+)
+
+ at article( SekhonMebane1998,
+ author= {Sekhon, Jasjeet Singh and Mebane, Jr., Walter R.},
+ title= {Genetic Optimization Using Derivatives: Theory and Application to Nonlinear Models},
+ journal= {Political Analysis}, volume={7},
+ pages= {189--203},
+ year= 1998
+)
+
+ at unpublished( sekhon_glmRob,
+ author= {Sekhon, Jasjeet S.},
+ title= {Robust Alternatives to Binary Logit and Probit: With
+ reanalysis of Fearon and Laitin's (2003) ``Ethnicity, Insurgency and
+ Civil War'' and Bartels's (1996) ``Uninformed Votes: Information Effects in
+ Presidential Elections.},
+ note= "Working Paper",
+ year= 2004
+)
+
+ at book( smith_charles1956,
+ author= {Smith, Charles Page},
+ title= {James Wilson, Founding Father, 1742-1798},
+ publisher= "University of North Carolina Press", address= "Chapel Hill",
+ year= 1956
+)
+
+ at article( smith_herbert1997,
+ author= {Smith, Herbert L.},
+ title= {Matching with Multiple Controls to Estimate Treatment Effects in Observational Studies},
+ journal= "Sociological Methodology", volume=27,
+ pages= "305--353",
+ year= "1997"
+)
+
+ at article( SmithTodd2005a,
+ author= {Smith, Jeffrey and Petra Todd},
+ title= {Does Matching Overcome LaLonde's Critique of Nonexperimental Estimators?},
+ journal= je, volume=125, number="1--2",
+ pages= "305--353",
+ year= "2005"
+)
+
+ at article( SmithTodd2005b,
+ author= {Smith, Jeffrey and Petra Todd},
+ title= {Rejoinder},
+ journal= je, volume=125, number="1--2",
+ pages= "365--375",
+ year= "2005"
+)
+
+ at article{SmithTodd2001,
+ author = {Jeffrey A. Smith and Petra E. Todd},
+ title = {Reconciling Conflicting Evidence on the Performance of Propensity Score Matching Methods},
+ journal = {AEA Papers and Proceedings},
+ year = {2001},
+ volume = {91},
+ number = {2},
+ pages = {112--118},
+}
+
+ at book( sniderman1991,
+ author= {Sniderman, Paul M. and Richard Brody and Philip E. Tetlock},
+ title= {Reasoning and Choice: Explorations in Political Psychology},
+ publisher= cup, address= ny,
+ year= 1991
+)
+
+ at incollection( sniderman1993,
+ author= {Sniderman, Paul M.},
+ title= {The New Look in Public Opinion Research},
+ booktitle= {Political Science: The State of the Discipline II},
+ editor= {Ada W. Finifter},
+ publisher= {American Political Science Association},
+ address= {Washington, DC},
+ year= 1993
+)
+
+ at book( snyder2000,
+ author= {Snyder, Jack},
+ title= {From Voting to Violence: Democratization and Nationalist Conflict},
+ publisher= {W. W. Norton}, address= ny,
+ year= 2000
+)
+
+ at article( stephens1974,
+ author= {Stephens, M. A.},
+ title= {EDF Statistics for Goodness of Fit and Some Comparisons},
+ journal= jasa, volume=69,
+ pages= {730--737},
+ year= 1974
+)
+
+ at article( stokes2004,
+ author= {Stokes, Houston},
+ title= {On the Advantage of Using Two or More Econometric Software Systems to Solve the Same Problem},
+ journal= {Journal of Economic and Social Measurement}, volume=29, number="1-3",
+ pages= {307--320},
+ year= 2004
+)
+
+ at Manual{synth2008,
+ author = {Alexis Diamond and Jens Hainmueller},
+ title = {\pkg{Synth}: Synthetic Control Group Method for Comparative Case Studies},
+ note = {\proglang{R}~package version~0.1-6},
+ url = {http://CRAN.R-project.org/package=Synth},
+ year = {2008}
+}
+
+ at incollection( vose1993,
+ author= {Vose, Michael D.},
+ title= {Modeling Simple Genetic Algorithms},
+ booktitle= {Foundations of Genetic Algorithms 2},
+ editor= {L.~Darrell Whitley},
+ publisher= {Morgan Kaufmann}, address= {San Mateo, CA},
+ year= 1993
+)
+
+ at Manual{WandKingLau2007,
+ author = {Wand, Jonathan and Gary King and Olivia Lau},
+ title = {\pkg{Anchors}: Software for Anchoring Vignette Data},
+ note = {\proglang{R}~package version~2.0},
+ url = {http://wand.stanford.edu/anchors/},
+ year = {2008}
+}
+
+ at book( wilcox1997,
+ author= {Wilcox, Rand R.},
+ title= {Introduction to Robust Estimation},
+ publisher= {Academic Press}, address= {San Diego, CA},
+ year= 1997
+)
+
+ at article( wilcoxon1945,
+ author= {Wilcoxon, F},
+ title= {Individual Comparisons by Ranking Methods},
+ journal= {Biometrics}, volume=1,
+ pages= {8083},
+ year= 1945
+)
+
+ at article( WinshipMorgan1999,
+ author= {Winship, Christopher and Stephen Morgan},
+ title= {The estimation of causal effects from observational data},
+ journal= "Annual Review of Sociology", volume=25,
+ pages= "659--707",
+ year= "1999"
+)
+
+ at article( wittman1989,
+ author= {Wittman, Donald A},
+ title= {Why Democracies Produce Efficient Results},
+ journal= jpe, volume=97,
+ pages= {1395--1424},
+ year= 1989
+)
+
+ at article( yao.liu.lin1999,
+ author= {Yao, Xin and Yong Liu and Guangming Lin},
+ title= {Evolutionary Programming Made Faster},
+ journal= {IEEE Transactions on Evolutionary Computation}, volume=3,
+ month= {July}, number= 2,
+ pages= {82--102},
+ year= 1999
+)
+
+ at article( yule1899,
+ author= {Yule, Undy G.},
+ title= {An Investigation into the Causes of Changes in Pauperism in England, Chiefly During the Last Two Intercensal Decades (Part I.)},
+ journal= {Journal of the Royal Statistical Society}, volume=62,
+ number = 2,
+ pages= {249--295},
+ year= 1899
+)
+
+ at incollection( zaller2004,
+ author= {Zaller, John R},
+ title= {Floating Voters in U.S.\ Presidential Elections, 1948--1996},
+ booktitle= {Studies in Public Opinion: Gauging Attitudes, Nonattitudes, Measurement Error and Change},
+ editor= {Willem Saris and Paul Sniderman},
+ publisher= pup,
+ address= nj,
+ year= "forthcoming"
+)
+
+ at book( zaller1992,
+ author= {Zaller, John R},
+ title= {The Nature and Origins of Mass Opinion},
+ publisher= cup, address= ny,
+ year= 1992
+)
+
+ at unpublished( zaller1986,
+ author= {Zaller, John R.},
+ title= {Analysis of Information Items in the 1985 NES Pilot Study},
+ note= {NES Pilot Study Report. Center for Political Studies, University of Michigan},
+ year= 1986
+)
+
+ at unpublished( zaller1985,
+ author= {Zaller, John R.},
+ title= {Proposal for the Measurement of Political Information},
+ note= {Report to the NES Board of Overseers. Center for Political Studies, University of Michigan},
+ year= 1985
+)
+
+ at book( zakaria2003,
+ author= {Zakaria, Fareed},
+ title= {The Future of Freedom: Illiberal Democracy at Home and Abroad},
+ publisher= {W. W. Norton}, address= {New York},
+ year= 2003
+)
+
+ at article( zakaria1998,
+ author= {Zakaria, Fareed},
+ title= {Doubts About Democracy},
+ journal= {Newsweek}, Month="January", day=5,
+ year= 1998
+)
+
+ at article( zakaria1997,
+ author= {Zakaria, Fareed},
+ title= {The Rise of Illiberal Democracy},
+ journal= {Foreign Affairs}, volume=76, number=6,
+ pages= {249--295},
+ year= 1997
+)
+
+ at Article{Altman+McDonald:2011,
+ author = {Micah Altman and Michael P. McDonald},
+ title = {\pkg{BARD}: Better Automated Redistricting},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at Article{Wand+King:2011,
+ author = {Jonathan Wand and Gary King},
+ title = {\pkg{Anchors}: Software for Anchoring Vignette Data},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at Article{Sekhon:2011,
+ author = {Jasjeet S. Sekhon},
+ title = {Multivariate and Propensity Score Matching Software with Automated
+ Balance Optimization: The \pkg{Matching} Package for \proglang{R}},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at Manual{Rcore,
+ title = {R: A Language and Environment for Statistical Computing},
+ author = {{R Development Core Team}},
+ organization = {R Foundation for Statistical Computing},
+ address = {Vienna, Austria},
+ year = {2009},
+ note = {{ISBN} 3-900051-07-0},
+ url = {http://www.R-project.org},
+}
+
+ at Comment LocalWords: apsr booktitle Finifter Zaller NES Iyengar Shanto Brehm
+ at Comment LocalWords: AlvarezBrehm ajps HorvitzThompson Horvitz jasa ny kunsch
+ at Comment LocalWords: MannWhitney Psychometrika Biometrika rubinMI Stefanski
+ at Comment LocalWords: Cantoni Elvezio Ronchetti CarrollPederson Pederson jssrb
+ at Comment LocalWords: copas jrssb sekhon glmRob Probit Fearon Laitin's althaus
+ at Comment LocalWords: Bartels's MebaneSekhon Keisuke Geert ec Allyson Berent
+ at Comment LocalWords: Krosnick Visser Boninger Hausman Kosuke Rosenbaum Bon Ai
+ at Comment LocalWords: Kornhauser Jamieson hersh url huntington Zakaria Fareed
+ at Comment LocalWords: zakaria rustow Dankwart Lipset geddes MacKuen Brunell
+ at Comment LocalWords: BrunellNiNardo DiNardo Reweighting AldrichMcKelvey rubin
+ at Comment LocalWords: McKelvey imbens abadie incollection dominguez nguez jop
+ at Comment LocalWords: Chappell Ordeshook Lupia fishkin Subclassification Jong
+ at Comment LocalWords: CochranRubin BertsimasTsitsiklis Bertsimas Dimitris Yung
+ at Comment LocalWords: Tsitsiklis Kaufmann Quantile Ellipsoidally Galiani Segal
+ at Comment LocalWords: Gertler Schargrodsky GalianiGertlerSchargrodsky Diprete
+ at Comment LocalWords: DipreteEngelhardt Engelhardt herbert Winship Jin PKfit
+ at Comment LocalWords: WinshipMorgan BowersHansen Pharmacokinetics Vinod aer
+ at Comment LocalWords: McCulloughVinod SchacharNalebuff Shachar Nalebuff Hsin
+ at Comment LocalWords: AltmanGillMcDonald Braumoeller Jasjeet ivivc vitro vivo
+ @Comment LocalWords: IVIVC Hainmueller Synth Mebane GENetic
+ @Comment LocalWords: GENOUD DiceOptim Ginsbourger Roustant
+ @Comment LocalWords: Kriging
diff --git a/inst/doc/rgenoud.pdf b/inst/doc/rgenoud.pdf
new file mode 100644
index 0000000..4632ed4
Binary files /dev/null and b/inst/doc/rgenoud.pdf differ
diff --git a/man/genoud.Rd b/man/genoud.Rd
new file mode 100644
index 0000000..8f13eb4
--- /dev/null
+++ b/man/genoud.Rd
@@ -0,0 +1,708 @@
+\name{genoud}
+\alias{genoud}
+\title{
+ GENetic Optimization Using Derivatives
+}
+\description{
+ \code{Genoud} is a function that combines evolutionary search
+ algorithms with derivative-based (Newton or quasi-Newton) methods to
+ solve difficult optimization problems. \code{Genoud} may also be
+ used for optimization problems for which derivatives do not exist.
+ \code{Genoud}, via the \code{cluster} option, supports the use of
+ multiple computers, CPUs or cores to perform parallel computations.
+}
+
+\usage{genoud(fn, nvars, max=FALSE, pop.size=1000, max.generations=100, wait.generations=10,
+ hard.generation.limit=TRUE, starting.values=NULL, MemoryMatrix=TRUE,
+ Domains=NULL, default.domains=10, solution.tolerance=0.001,
+ gr=NULL, boundary.enforcement=0, lexical=FALSE, gradient.check=TRUE,
+ BFGS=TRUE, data.type.int=FALSE, hessian=FALSE,
+ unif.seed=812821, int.seed=53058,
+ print.level=2, share.type=0, instance.number=0,
+ output.path="stdout", output.append=FALSE, project.path=NULL,
+ P1=50, P2=50, P3=50, P4=50, P5=50, P6=50, P7=50, P8=50, P9=0,
+ P9mix=NULL, BFGSburnin=0, BFGSfn=NULL, BFGShelp=NULL,
+ control=list(),
+ optim.method=ifelse(boundary.enforcement < 2, "BFGS", "L-BFGS-B"),
+ transform=FALSE, debug=FALSE, cluster=FALSE, balance=FALSE, ...)
+}
+\arguments{
+ \item{fn}{
+ The function to be minimized (or maximized if
+ max=\code{TRUE}). The first argument of the function must be the
+ vector of parameters over which minimizing is to
+ occur. The function must return a scalar result (unless
+ \code{lexical=TRUE}).
+
+ For example, if we wish to \emph{maximize} the \code{sin()}
+ function. We can simply call genoud by \code{genoud(sin,
+ nvars=1,max=TRUE)}.}
+ \item{nvars}{The number of parameters to be selected for the function to be minimized (or
+ maximized).}
+ \item{max}{
+ Maximization (\code{TRUE}) or Minimizing (\code{FALSE}). Determines
+ if \code{genoud} minimizes or maximizes the objective function.}
+ \item{pop.size}{
+ Population Size. This is the number of individuals \code{genoud} uses to
+ solve the optimization problem. There are several restrictions on
+ what the value of this number can be. No matter what population
+ size the user requests, the number is automatically adjusted to make
+ certain that the relevant restrictions are satisfied. These
+ restrictions originate
+ in what is required by several of the operators. In particular,
+ operators 6 (Simple Crossover) and 8 (Heuristic
+ Crossover) require an even number of individuals to work on---i.e., they
+ require two parents. Therefore, the \code{pop.size} variable and the
+ operators sets must be such that these three operators have an even
+ number of individuals to work with. If this does not occur, the
+ population size is automatically increased until this constraint is
+ satisfied.}
+ \item{max.generations}{
+ Maximum Generations. This is the maximum number of generations that
+ \code{genoud} will run when attempting to optimize a function. This is a
+ \emph{soft} limit. The maximum generation limit will be binding for
+ \code{genoud} only if \code{hard.generation.limit} has
+ been set equal to \code{TRUE}. If it has not been set equal to
+ \code{TRUE}, two soft triggers control when \code{genoud} stops:
+ \code{wait.generations} and \code{gradient.check}. \cr
+
+ Although the \code{max.generations} variable is not, by default,
+ binding, it is nevertheless important because many operators use it
+ to adjust
+ their behavior. In essence, many of the operators become less random
+ as the generation count gets closer to the \code{max.generations}
+ limit. If
+ the limit is hit and \code{genoud} decides to
+ continue working, \code{genoud} automatically increases the
+ \code{max.generation}
+ limit.\cr
+
+ Please see \code{MemoryMatrix} for some important interactions
+ with memory management.}
+ \item{wait.generations}{
+ If there is no improvement in the objective function in this number
+ of generations, \code{genoud} will think that it has
+ found the optimum. If the
+ \code{gradient.check} trigger has been
+ turned on, \code{genoud} will only start counting \code{wait.generations}
+ if the gradients are within
+ \code{solution.tolerance} of zero. The
+ other variables controlling termination are
+ \code{max.generations} and \code{hard.generation.limit}.}
+ \item{hard.generation.limit}{
+ This logical variable determines if the \code{max.generations}
+ variable is a binding constraint for \code{genoud}. If
+ \code{hard.generation.limit} is \code{FALSE}, then \code{genoud} may exceed
+ the \code{max.generations} count if either the objective function
+ has improved within a given number of generations (determined by
+ \code{wait.generations}) or if the gradients are not zero
+ (determined by \code{gradient.check}). \cr
+
+ Please see \code{MemoryMatrix} for some important interactions
+ with memory management.}
+ \item{starting.values}{A vector or matrix containing parameter values
+ which \code{genoud} will use at startup. Using this option, the user
+ may insert one or more individuals into the starting population. If a
+ matrix is provided, the columns should be the variables and the rows
+ the individuals. \code{genoud} will randomly create the other
+ individuals.}
+ \item{MemoryMatrix}{
+ This variable controls if \code{genoud} sets up a memory matrix. Such a
+ matrix ensures that \code{genoud} will request the fitness evaluation of a
+ given set of parameters only once. The variable may
+ be \code{TRUE} or \code{FALSE}. If it is \code{FALSE}, \code{genoud} will
+ be aggressive in conserving memory. The most significant negative
+ implication of this variable being set to \code{FALSE} is that
+ \code{genoud} will no longer maintain a memory matrix of all evaluated
+ individuals. Therefore, \code{genoud} may request evaluations which it has
+ already previously requested. \cr
+
+ Note that when \code{nvars} or \code{pop.size} are large, the memory
+ matrix consumes a large amount of RAM. \code{Genoud}'s memory matrix will
+ require somewhat less memory if the user sets
+ \code{hard.generation.limit} equal to \code{TRUE}.}
+ \item{Domains}{
+ This is a \code{nvars} \eqn{\times 2}{*2}
+ matrix. For each variable, in the first column is the lower bound and
+ in the second column the upper bound. None of \code{genoud}'s
+ starting population will be
+ generated outside of the bounds. But some of the operators may
+ generate children which
+ will be outside of the bounds unless the
+ \code{boundary.enforcement} flag is
+ turned on. \cr
+
+ If the user does not provide any values for Domains, \code{genoud} will setup
+ default domains using \code{default.domains}. \cr
+
+ For linear and nonlinear constraints please see the discussion in
+ the \code{Note} section.}
+ \item{default.domains}{
+ If the user does not want to provide a \code{Domains} matrix,
+ domains may nevertheless be set by the user with this easy to use
+ scalar option. \code{Genoud} will create a
+ Domains matrix by setting the lower bound for all of the parameters
+ equal to -1 \eqn{\times}{*} \code{default.domains} and the upper
+ bound equal to \code{default.domains}.}
+ \item{solution.tolerance}{
+ This is the tolerance level used by \code{genoud}. Numbers within
+ \code{solution.tolerance} are considered to be equal. This is
+ particularly
+ important when it comes to evaluating \code{wait.generations} and
+ conducting the \code{gradient.check}.}
+ \item{gr}{A function to provide the gradient for the \code{BFGS}
+ optimizer. If it is \code{NULL}, numerical gradients will be used
+ instead.}
+ \item{boundary.enforcement}{
+ This variable determines the degree to which \code{genoud} obeys the
+ boundary constraints. Notwithstanding the value of the variable,
+ none of \code{genoud}'s starting population values will be outside
+ of the bounds. \cr
+
+ \code{boundary.enforcement} has three possible values: 0 (anything goes), 1
+ (partial), and 2 (no trespassing):
+ \itemize{
+ \item{\emph{0: Anything Goes}}{
+ This option allows any of the operators to
+ create out-of-bounds individuals and these individuals will be
+ included in the
+ population if their fit values are good enough. The boundaries are only
+ important when generating random individuals.}
+ \item{\emph{1: partial enforcement}}{
+ This allows operators (particularly those operators
+ which use the derivative based optimizer, BFGS) to go out-of-bounds
+ during the creation of an individual (i.e., out-of-bounds values
+ will often be evaluated). But when the operator has decided
+ on an individual, it \emph{must} be in bounds to be acceptable.}
+ \item{\emph{2: No Trespassing}}{
+ No out-of-bounds evaluations will ever be requested. In this
+ case, boundary enforcement is also applied to the BFGS
+ algorithm, which prevents candidates from straying beyond the
+ bounds defined by \code{Domains}. Note that this forces the use
+ of the L-BFGS-B algorithm for \code{\link[stats]{optim}}.
+ This algorithm requires that all fit values and gradients be
+ defined and finite for all function evaluations. If this causes
+ an error, it is suggested that the BFGS algorithm be used
+ instead by setting \code{boundary.enforcement=1}.}}}
+ \item{lexical}{This option enables lexical optimization. This is
+ where there are multiple fit criteria and the parameters are chosen so
+ as to maximize fitness values in lexical order---i.e., the second fit
+ criterion is only relevant if the parameters have the same fit for the
+ first etc. The fit function used with this option should return a
+ numeric vector of fitness values in lexical order. This option
+ can take on the values of \code{FALSE}, \code{TRUE} or an integer
+ equal to the number of fit criteria which are returned by \code{fn}.
+ The \code{value} object which is returned by \code{genoud} will
+ include all of the fit criteria at the solution. The
+ \code{\link[Matching]{GenMatch}} function makes extensive use of this
+ option.}
+ \item{gradient.check}{
+ If this variable is \code{TRUE}, \code{genoud} will not start counting
+ \code{wait.generations} unless each gradient is
+ \code{solution.tolerance} close to zero. This
+ variable has no effect if the \code{max.generations} limit has been
+ hit and the \code{hard.generation.limit} option has been set to
+ \code{TRUE}. If \code{BFGSburnin < 0}, then it will be ignored unless
+ \code{gradient.check = TRUE}. }
+\item{BFGS}{
+ This variable denotes whether or not \code{genoud} applies a
+ quasi-Newton derivative optimizer (BFGS) to the best individual at
+ the end of each generation after the initial one. See the
+ \code{optim.method} option to change the optimizer. Setting BFGS to
+ \code{FALSE} does not mean that the BFGS will never be used. In
+ particular, if you want BFGS never to be used, \code{P9} (the
+ Local-Minimum Crossover operator) must also be set to zero.}
+ \item{data.type.int}{
+ This option sets the data type of the parameters of the function to
+ be optimized. If the variable is \code{TRUE}, \code{genoud} will
+ search over integers when it optimizes the parameters. \cr
+
+ With integer parameters, \code{genoud} never uses derivative
+ information. This implies that the BFGS quasi-Newton optimizer is
+ never used---i.e., the \code{BFGS} flag is set to \code{FALSE}. It
+ also implies
+ that Operator 9 (Local-Minimum Crossover) is set to zero and that
+ gradient checking (as a convergence criterion) is turned off. No
+ matter what other options have been set to,
+ \code{data.type.int} takes precedence---i.e., if \code{genoud} is told that
+ it is searching over an integer parameter space, gradient
+ information is never considered. \cr
+
+ There is no option to mix integer and floating point parameters. If
+ one wants to mix the two, it is suggested that the user pick integer type
+ and in the objective function map a particular integer range into a
+ floating point number range. For example, tell \code{genoud} to search
+ from 0 to 100 and divide by 100 to obtain a search grid of 0 to 1.0
+ (by .1). \cr
+
+ Alternatively, the user could use floating point numbers and round
+ the appropriate parameters to the nearest integer inside \code{fn}
+ before the criterion (or criteria if \code{lexical = TRUE}) is
+ evaluated. In that case, the \code{transform} option can be used to
+ create the next generation from the current generation when the
+ appropriate parameters are in the rounded state.
+ }
+ \item{hessian}{
+ When this flag is set to \code{TRUE}, \code{genoud} will return the
+ hessian matrix at the solution as part of its return list. A user
+ can use this matrix to calculate standard errors.}
+ \item{unif.seed}{This sets the seed for the floating-point
+ pseudorandom number generator \code{genoud} uses. The default value of this
+ seed is 81282. \code{genoud} uses its own internal pseudorandom number
+ generator (a Tausworthe-Lewis-Payne generator) to allow for recursive
+ and parallel calls to \code{genoud}. Repeated invocations without specifying
+ this argument cause the program to continue drawing from its internal
+ pseudorandom number stream, which is preserved in a static structure
+ between invocations during the same R session, so the second
+ invocation does not use the same pseudorandom numbers as the first.
+ To produce exactly the same results in a subsequent invocation, one
+ must explicitly provide the same, nondefault value for this argument.
+ \code{genoud} does not use the seed set by R's
+ \code{\link{set.seed}} function. This will change in a subsequent version.}
+ \item{int.seed}{This sets the seed for the integer pseudorandom number
+ generator \code{genoud} uses. The default value of this seed is 53058. \code{genoud}
+ uses its own internal pseudorandom number generator (a
+ Tausworthe-Lewis-Payne generator) to allow for recursive and parallel
+ calls to \code{genoud}. Repeated invocations without specifying this
+ argument cause the program to continue drawing from its internal
+ pseudorandom number stream, which is preserved in a static structure
+ between invocations during the same R session, so the second
+ invocation does not use the same pseudorandom numbers as the first.
+ To produce exactly the same results in a subsequent invocation, one
+ must explicitly provide the same, nondefault value for this argument.
+ \code{genoud} does not use the seed set by R's
+ \code{\link{set.seed}} function. This will change in a subsequent version.}
+ \item{print.level}{
+ This variable controls the level of printing that \code{genoud} does. There
+ are four possible levels: 0 (minimal printing), 1 (normal), 2
+ (detailed), and 3 (debug). If level 2 is selected, \code{genoud} will
+ print details about the population at each generation. The
+ \code{print.level} variable also significantly affects how much
+ detail is placed in the project file---see \code{project.path}.
+ Note that R convention would have
+ us at print level 0 (minimal printing). However, because \code{genoud}
+ runs may take a long time, it is important for the user to receive
+ feedback. Hence, print level 2 has been set as the default.}
+ \item{share.type}{
+ If \code{share.type} is equal to 1, then \code{genoud}, at
+ startup, checks to see if there is an existing project file (see
+ \code{project.path}). If such a file exists, it initializes its
+ original population using it. This option can be used neither with
+ the \code{lexical} nor the \code{transform} options.\cr
+
+ If the project file contains a smaller population than the current
+ \code{genoud} run, \code{genoud} will randomly create the necessary individuals. If
+ the project file contains a larger population than the current \code{genoud}
+ run, \code{genoud} will kill the necessary individuals using exponential
+ selection. \cr
+
+ If the number of variables (see \code{nvars})
+ reported in the project file is different from the current \code{genoud} run,
+ \code{genoud} does not use the project file (regardless of the value of
+ \code{share.type}) and \code{genoud} generates the necessary starting
+ population at random.}
+ \item{instance.number}{
+ This number (starting from 0) denotes the number of recursive
+ instances of \code{genoud}. \code{genoud} then sets up its random number
+ generators and other such structures so that the multiple instances
+ do not interfere with each other. It is
+ up to the user to make certain that the different instances of
+ \code{genoud} are not writing to
+ the same output file(s): see \code{project.path}. \cr
+
+ For the R version of \code{genoud} this variable is of limited
+ use. It is basically there in case a \code{genoud} run is being
+ used to optimize the result of another \code{genoud} run (i.e., a
+ recursive implementation).}
+ \item{output.path}{This option is no longer supported. It used to
+ allow one to redirect the output. Now please use
+ \code{\link{sink}}. The option remains in order to provide
+ backward compatibility for the API.}
+ \item{output.append}{This option is no longer supported. Please see
+ \code{\link{sink}}. The option remains in order to provide
+ backward compatibility for the API.}
+ \item{project.path}{ This is the path of the \code{genoud} project
+ file. The project file prints one individual per line with the fit
+ value(s) printed first and then the parameter values. By default
+ \code{genoud} places its output in a file called "genoud.pro"
+ located in the temporary directory provided by
+ \code{\link{tempdir}}. The behavior of the project file depends
+ on the \code{print.level} chosen. If the \code{print.level}
+ variable is set to 1, then the project file is rewritten after
+ each generation. Therefore, only the currently fully completed
+ generation is included in the file. If the \code{print.level}
+ variable is set to 2, then each new generation is simply appended
+ to the project file. For \code{print.level=0}, the project file
+ is not created. }
+ \item{P1}{ This is the cloning operator.
+ \code{genoud} always clones the best individual each generation.
+ But this operator clones others as well. Please see the Operators
+ Section for details about operators and how they are weighted.}
+ \item{P2}{ This is the uniform mutation operator. One parameter
+ of the parent is mutated. Please see the Operators Section for
+ details about operators and how they are weighted.}
+ \item{P3}{
+ This is the boundary mutation operator. This operator finds a
+ parent and mutates one of its parameters towards the boundary.
+ Please see the Operators Section for details about operators and
+ how they are weighted.}
+ \item{P4}{ Non-Uniform Mutation. Please
+ see the Operators Section for details about operators and how they
+ are weighted.}
+ \item{P5}{ This is the polytope crossover. Please
+ see the Operators Section for details about operators and how they
+ are weighted.}
+ \item{P6}{ Simple Crossover. Please see the
+ Operators Section for details about operators and how they are
+ weighted.}
+ \item{P7}{ Whole Non-Uniform Mutation. Please see the
+ Operators Section for details about operators and how they are
+ weighted.}
+ \item{P8}{ Heuristic Crossover. Please see the
+ Operators Section for details about operators and how they are
+ weighted.}
+ \item{P9}{ Local-Minimum Crossover: BFGS. This is
+ rather CPU intensive, and should be generally used less than the
+ other operators. Please see the Operators Section for details
+ about operators and how they are weighted.}
+ \item{P9mix}{This is
+ a tuning parameter for the \code{P9} operator. The local-minimum
+ crossover operator by default takes the convex combination of the
+ result of a BFGS optimization and the parent individual. By
+ default the mixing (weight) parameter for the convex combination
+ is chosen by a uniform random draw between 0 and 1. The
+ \code{P9mix} option allows the user to select this mixing
+ parameter. It may be any number greater than 0 and less than or
+ equal to 1. If 1, then the BFGS result is simply used.}
+ \item{BFGSburnin}{The number of generations which are run before
+ the BFGS is first used. Premature use of the BFGS can lead to
+ convergence to a local optimum instead of the global one. This
+ option allows the user to control how many generations are run
+ before the BFGS is started and would logically be a non-negative
+ integer. However, if \code{BFGSburnin < 0}, the BFGS will be used
+ if and when \code{wait.generations} is doubled because at least
+ one gradient is too large, which can only occur when
+ \code{gradient.check = TRUE}. This option delays the use of both
+ the BFGS on the best individual and the \code{P9} operator. }
+ \item{BFGSfn}{This is a function for the BFGS optimizer to
+ optimize, if one wants to make it distinct from the \code{fn}
+ function. This is useful when doing \code{lexical} optimization
+ because otherwise a derivative based optimizer cannot be used
+ (since it requires a single fit value). It is suggested that if
+ this functionality is being used, both the \code{fn} and
+ \code{BFGSfn} functions obtain all of the arguments they need
+ (except for the parameters being optimized) by lexical scope
+ instead of being passed in as arguments to the functions.
+ Alternatively, one may use the \code{BFGShelp} option to pass
+ arguments to \code{BFGSfn}. If \code{print.level > 2}, the results
+ from the BFGS optimizer are printed every time it is called.}
+ \item{BFGShelp}{An optional function to pass arguments to
+ \code{BFGSfn}. This function should take an argument named
+ `initial', an argument named `done' that defaults to \code{FALSE},
+ or at least allow \code{...} to be an argument. \code{BFGSfn}
+ must have an argument named `helper' if \code{BFGShelp} is used
+ because the call to \code{\link[stats]{optim}} includes the hard-coded
+ expression \code{helper = do.call(BFGShelp, args = list(initial =
+ foo.vals), envir = environment(fn)))}, which evaluates the
+ \code{BFGShelp} function in the environment of \code{BFGSfn}
+ (\code{fn} is just a wrapper for \code{BFGSfn}) at \code{par =
+ foo.vals} where \code{foo.vals} contains the starting values for
+ the BFGS algorithm. The `done' argument to \code{BFGSfn} is used
+ if the user requests that the Hessian be calculated at the
+ \code{genoud} solution.}
+ \item{control}{A list of control
+ parameters that is passed to \code{\link[stats]{optim}} if
+ \code{BFGS = TRUE} or \code{P9 > 0}. Please see the
+ \code{\link[stats]{optim}} documentation for details. }
+ \item{optim.method}{A character string among those that are admissible for the
+ \code{method} argument to the \code{\link{optim}} function, namely one of
+ \code{"BFGS"}, \code{"L-BFGS-B"}, \code{"Nelder-Mead"}, \code{"CG"}, or \code{"SANN"}.
+ By default, \code{optim.method} is \code{"BFGS"} if \code{boundary.enforcement < 2}
+ and is \code{"L-BFGS-B"} if \code{boundary.enforcement = 2}. For discontinuous
+ objective functions, it may be advisable to select \code{"Nelder-Mead"} or \code{"SANN"}.
+ If selecting \code{"L-BFGS-B"} causes an error message, it may be advisable to
+ select another method or to adjust the \code{control} argument. Note that the various
+ arguments of \code{genoud} that involve the four letters \dQuote{BFGS} continue to
+ be passed to \code{\link[stats]{optim}} even if \code{optim.method != "BFGS"}.}
+ \item{transform}{A logical that defaults to \code{FALSE}. If
+ \code{TRUE}, it signifies that \code{fn} will return a numeric
+ vector that contains the fit criterion (or fit criteria if
+ \code{lexical = TRUE}), followed by the parameters. If this option
+ is used, \code{fn} should have the following general form in
+ its body:\cr
+ \code{par <- myTransformation(par)}\cr
+ \code{criter <- myObjective(par)}\cr
+ \code{return( c(criter, par) )}\cr
+ This option is useful when parameter transformations are necessary
+ because the next generation of the population will be created from
+ the current generation in the transformed state, rather than the
+ original state. This option can be used by users to implement their
+ own operators. \cr
+
+ There are some issues that should be kept in mind. This option cannot
+ be used when \code{data.type.int = TRUE}. Also, this option coerces
+ \code{MemoryMatrix} to be \code{FALSE}, implying that the \code{cluster}
+ option cannot be used. And, unless \code{BFGSfn} is specified, this option coerces
+ \code{gradient.check} to \code{FALSE}, \code{BFGS} to \code{FALSE},
+ and \code{P9} to \code{0}. If \code{BFGSfn} is specified, that function should
+ perform the transformation but should only return a scalar fit criterion,
+ for example:\cr
+ \code{par <- myTransformation(par)}\cr
+ \code{criter <- myCriterion(par)}\cr
+ \code{return(criter)}\cr
+
+ Finally, if \code{boundary.enforcement > 0}, care must be taken to
+ assure that the transformed parameters are within the \code{Domains},
+ otherwise unpredictable results could occur. In this case, the transformations are
+ checked for consistency with \code{Domains} but only in the initial generation
+ (to avoid an unacceptable loss in computational speed). }
+ \item{debug}{ This
+ variable turns on some debugging information. This variable may
+ be \code{TRUE} or \code{FALSE}.}
+ \item{cluster}{This can either be an
+ object of the 'cluster' class returned by one of the
+ \code{\link[parallel]{makeCluster}} commands in the \code{parallel} package or a
+ vector of machine names so \code{genoud} can setup the cluster
+ automatically. If it is the latter, the vector should look like:
+ \cr \code{c("localhost","musil","musil","deckard")}.\cr This
+ vector would create a cluster with four nodes: one on the
+ localhost another on "deckard" and two on the machine named
+ "musil". Two nodes on a given machine make sense if the machine
+ has two or more chips/cores. \code{genoud} will setup a SOCK
+ cluster by a call to \code{\link[parallel]{makePSOCKcluster}}. This
+ will require the user to type in her password for each node as the
+ cluster is by default created via \code{ssh}. One can add on
+ usernames to the machine name if it differs from the current
+ shell: "username at musil". Other cluster types, such as PVM and
+ MPI, which do not require passwords can be created by directly
+ calling \code{\link[parallel]{makeCluster}}, and then passing the
+ returned cluster object to \code{genoud}. For an example of how to
+ manually setup up a cluster with a direct call to
+ \code{\link[parallel]{makeCluster}} see
+ \url{http://sekhon.berkeley.edu/rgenoud/R/genoud_cluster_manual.R}.
+ For an example of how to get around a firewall by ssh tunneling
+ see:
+ \url{http://sekhon.berkeley.edu/rgenoud/R/genoud_cluster_manual_tunnel.R}.}
+ \item{balance}{This logical flag controls if load balancing is
+ done across the cluster. Load balancing can result in better
+ cluster utilization; however, increased communication can reduce
+ performance. This option is best used if the function being
+ optimized takes at least several minutes to calculate or if the
+ nodes in the cluster vary significantly in their performance. If
+ cluster==FALSE, this option has no effect.}
+ \item{...}{Further arguments to be passed to \code{fn} and
+ \code{gr}.} }
+
+\details{\code{Genoud} solves problems that are nonlinear or
+ perhaps even discontinuous in the parameters of the function to be
+ optimized. When a statistical model's estimating function (for
+ example, a log-likelihood) is nonlinear in the model's parameters,
+ the function to be optimized will generally not be globally
+ concave and may have irregularities such as saddlepoints or
+ discontinuities. Optimization methods that rely on derivatives of
+ the objective function may be unable to find any optimum at all.
+ Multiple local optima may exist, so that there is no guarantee
+ that a derivative-based method will converge to the global
+ optimum. On the other hand, algorithms that do not use derivative
+ information (such as pure genetic algorithms) are for many
+ problems needlessly poor at local hill climbing. Most statistical
+ problems are regular in a neighborhood of the solution.
+ Therefore, for some portion of the search space, derivative
+ information is useful for such problems. \code{Genoud} also works
+ well for problems that no derivative information exists. For
+ additional documentation and examples please see
+ \url{http://sekhon.berkeley.edu/rgenoud}.}
+
+\value{\code{genoud} returns a list
+ with 7 objects. 8 objects are returned if the user has requested
+ the hessian to be calculated at the solution. Please see the
+ \code{hessian} option. The returned objects are:
+
+ \item{value}{
+ This variable contains the fitness value at the solution. If
+ \code{lexical} optimization was requested, it is a vector.}
+ \item{par}{
+ This vector contains the parameter values found at the solution.}
+ \item{gradients}{
+ This vector contains the gradients found at the solution. If no
+ gradients were calculated, they are reported to be \code{NA}.}
+ \item{generations}{
+ This variable contains the number of generations \code{genoud} ran for.}
+ \item{peakgeneration}{
+ This variable contains the generation number at which \code{genoud} found
+ the solution.}
+ \item{pop.size}{
+ This variable contains the population size that \code{genoud} actually used.
+ See \code{pop.size} for why this value may differ from the
+ population size the user requested.}
+ \item{operators}{
+ This vector reports the actual number of operators (of each type)
+ \code{genoud} used. Please see the Operators Section for details.}
+ \item{hessian}{
+ If the user has requested the hessian
+ matrix to be returned (via the \code{hessian} flag), the hessian
+ at the solution will be returned. The user may use this matrix to calculate standard
+ errors.}
+}
+\section{Operators}{
+ \code{Genoud} has nine operators that it uses. The integer values which are
+ assigned to each of these operators (P1\eqn{\cdots}{...}P9) are
+ weights.
+ \code{Genoud} calculates the sum of \eqn{s = P1+P2+\cdots+P9}{s =
+ P1+P2+...+P9}. Each operator is
+ assigned a weight equal to \eqn{W_{n} = \frac{s}{P_{n}}}{W_n =
+ s/(P_n)}. The number of
+ times an operator is called usually equals \eqn{c_{n} = W_{n} \times
+ pop.size}{c_n = W_n * pop.size}. \cr
+
+ Operators 6 (Simple Crossover) and 8 (Heuristic
+ Crossover) require an even number of individuals to work on---i.e.,
+ they require two parents. Therefore, the \code{pop.size} variable and
+ the operators sets must be such that these three operators have an
+ even number of individuals to work with. If this does not occur,
+ \code{genoud} automatically upwardly adjusts the population size to make this
+ constraint hold. \cr
+
+ Strong uniqueness checks have been built into the operators to help
+ ensure that the operators produce offspring different from their
+ parents, but this does not always happen. \cr
+
+ Note that \code{genoud} always keeps the best individual each generation. \cr
+
+ \code{genoud}'s 9 operators are: \cr
+
+ \enumerate{
+ \item Cloning
+ \item Uniform Mutation
+ \item Boundary Mutation
+ \item Non-Uniform Crossover
+ \item Polytope Crossover
+ \item Simple Crossover
+ \item Whole Non-Uniform Mutation
+ \item Heuristic Crossover
+ \item Local-Minimum Crossover: BFGS}
+ For more information please see Table 1 of the reference article:
+ \url{http://sekhon.berkeley.edu/papers/rgenoudJSS.pdf}.}
+\note{
+ The most important options affecting performance are those determining
+ population size (\code{pop.size}) and the
+ number of generations the algorithm runs
+ (\code{max.generations}, \code{wait.generations},
+ \code{hard.generation.limit} and \code{gradient.check}). Search
+ performance is expected to improve as
+ the population size and the number of generations the program runs for
+ increase. These and the other options should be adjusted for the
+ problem at hand. Please pay particular attention to the search
+ domains (\code{Domains} and \code{default.domains}). For more information
+ please see the reference article. \cr
+
+ Linear and nonlinear constraints among the parameters can be
+ introduced by users in their fit function. For example, if
+ the sum of parameters 1 and 2 must be less than 725, the following can
+ be placed in the fit function the user is going to have \code{genoud}
+ maximize: \code{if ( (parm1 + parm2) >= 725) \{ return(-99999999) \}}.
+ In this example, a very bad fit value is returned to \code{genoud} if the
+ linear constrain is violated. \code{genoud} will then attempt to find
+ parameter values that satisfy the constraint. \cr
+
+ Alternatively, one can use lexical optimization where the first criterion is a
+ binary variable that equals 1.0 iff \code{ (parm1 + parm2) < 725} and the
+ second criterion is the fit function, which should also be passed to
+ \code{BFGSfn}. All candidates where \code{ (parm1 + parm2) >= 725} will be
+ ranked below all candidates where \code{ (parm1 + parm2) < 725} and within
+ these two groups, candidates will be ranked by their fit on the second
+ criterion. The optimal candidate is thus the one with the best fit on the
+ second criterion among candidates that satisfy this restriction.}
+\references{
+
+ Mebane, Walter R., Jr. and Jasjeet S. Sekhon. 2011. "Genetic
+ Optimization Using Derivatives: The rgenoud Package for R."
+ \emph{Journal of Statistical Software}, 42(11): 1-26.
+ \url{http://www.jstatsoft.org/v42/i11/} \cr
+
+ Sekhon, Jasjeet Singh and Walter R. Mebane, Jr. 1998. ``Genetic
+ Optimization Using Derivatives: Theory and Application to Nonlinear
+ Models.'' \emph{Political Analysis}, 7: 187-210.
+ \url{http://sekhon.berkeley.edu/genoud/genoud.pdf} \cr
+
+ Mebane, Walter R., Jr. and Jasjeet S. Sekhon. 2004. ``Robust
+ Estimation and Outlier Detection for Overdispersed Multinomial Models
+ of Count Data.'' \emph{American Journal of Political Science}, 48
+ (April): 391-410. \url{http://sekhon.berkeley.edu/multinom.pdf} \cr
+
+ Bright, H. and R. Enison. 1979. Quasi-Random Number Sequences from a
+ Long-Period TLP Generator with Remarks on Application to
+ Cryptography. \emph{Computing Surveys}, 11(4): 357-370.
+}
+\author{Walter R. Mebane, Jr., University of Michigan,
+ \email{wmebane at umich.edu}, \url{http://www-personal.umich.edu/~wmebane/} \cr
+
+ Jasjeet S. Sekhon, UC Berkeley, \email{sekhon at berkeley.edu},
+ \url{http://sekhon.berkeley.edu/}}
+\seealso{
+ \code{\link[stats]{optim}}.
+}
+\examples{
+#maximize the sin function
+ sin1 <- genoud(sin, nvars=1, max=TRUE)
+
+#minimize the sin function
+ sin2 <- genoud(sin, nvars=1, max=FALSE)
+
+\dontrun{
+#maximize a univariate normal mixture which looks like a claw
+ claw <- function(xx) {
+ x <- xx[1]
+ y <- (0.46*(dnorm(x,-1.0,2.0/3.0) + dnorm(x,1.0,2.0/3.0)) +
+ (1.0/300.0)*(dnorm(x,-0.5,.01) + dnorm(x,-1.0,.01) + dnorm(x,-1.5,.01)) +
+ (7.0/300.0)*(dnorm(x,0.5,.07) + dnorm(x,1.0,.07) + dnorm(x,1.5,.07)))
+ return(y)
+ }
+ claw1 <- genoud(claw, nvars=1,pop.size=3000,max=TRUE)
+}
+
+\dontrun{
+#Plot the previous run
+ xx <- seq(-3,3,.05)
+ plot(xx,lapply(xx,claw),type="l",xlab="Parameter",ylab="Fit",
+ main="GENOUD: Maximize the Claw Density")
+ points(claw1$par,claw1$value,col="red")
+
+# Maximize a bivariate normal mixture which looks like a claw.
+ biclaw <- function(xx) {
+ mNd2 <- function(x1, x2, mu1, mu2, sigma1, sigma2, rho)
+ {
+ z1 <- (x1-mu1)/sigma1
+ z2 <- (x2-mu2)/sigma2
+ w <- (1.0/(2.0*pi*sigma1*sigma2*sqrt(1-rho*rho)))
+ w <- w*exp(-0.5*(z1*z1 - 2*rho*z1*z2 + z2*z2)/(1-rho*rho))
+ return(w)
+ }
+ x1 <- xx[1]+1
+ x2 <- xx[2]+1
+
+ y <- (0.5*mNd2(x1,x2,0.0,0.0,1.0,1.0,0.0) +
+ 0.1*(mNd2(x1,x2,-1.0,-1.0,0.1,0.1,0.0) +
+ mNd2(x1,x2,-0.5,-0.5,0.1,0.1,0.0) +
+ mNd2(x1,x2,0.0,0.0,0.1,0.1,0.0) +
+ mNd2(x1,x2,0.5,0.5,0.1,0.1,0.0) +
+ mNd2(x1,x2,1.0,1.0,0.1,0.1,0.0)))
+
+ return(y)
+ }
+ biclaw1 <- genoud(biclaw, default.domains=20, nvars=2,pop.size=5000,max=TRUE)
+}
+# For more examples see: http://sekhon.berkeley.edu/rgenoud/R.
+}
+\keyword{optimize}
+\keyword{nonlinear}
+% LocalWords: genoud GENetic GAs fn nvars max MemoryMatrix BFGS hessian unif
+% LocalWords: stdout Polytope cr emph eqn GENOUD's peakgeneration dfrac optim
+% LocalWords: seealso saddlepoints lapply xlab ylab biclaw mNd polytope cdots
+% LocalWords: frac url jasjeet RGENOUD PVM MPI parm Overdispersed UC dontrun
+% LocalWords: bivariate CPUs startup Genoud's GenMatch tempdir makeCluster
+% LocalWords: localhost musil deckard makePSOCKcluster usernames univariate
+% LocalWords: SANN dQuote BFGSburnin BFGSfn BFGShelp myCriterion iff Mebane TLP
+% LocalWords: Singh rgenoud Multinomial Enison dnorm pseudorandom Tausworthe
+% LocalWords: nondefault args vals envir Nelder myTransformation criter
+% LocalWords: myObjective
diff --git a/src/change_order.cpp b/src/change_order.cpp
new file mode 100644
index 0000000..711502d
--- /dev/null
+++ b/src/change_order.cpp
@@ -0,0 +1,482 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ $Header: /home/jsekhon/xchg/genoud/rgenoud.distribution/sources/RCS/change_order.cpp,v 2.15 2005/10/29 06:14:44 jsekhon Exp jsekhon $
+
+*/
+
+
+#include "genoud.h"
+
+
+void get_var_order(IVECTOR tot, IVECTOR cart, IMATRIX var_order)
+ /* IVECTOR tot, array with total number of variables and equalities
+ cart; array with the subscript of the variables to be eliminated
+ IMATRIX var_order; matrix with the variables in one column and a tag in the
+ other to identify as to whether it is to be eliminated
+ or not
+ */
+{
+ int i;
+
+ for(i=1; i<=tot[0]; i++)
+ {
+ var_order[i][1] = i;
+ var_order[i][2] = 0;
+ }
+
+ for(i=1; i<=tot[1]; i++)
+ var_order[cart[i]][2] = 1;
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_x1_x2() */
+/* */
+/* SYNOPSIS : void find_x1_x2(tot,var_order,eq_co,x1,x2) */
+/* */
+/* DESCRIPTION : This function splits the original vector of */
+/* variables into x1 and x2, where x1 consists */
+/* of the 'p' variables to be eliminated and */
+/* x2 consists of the remaining variables */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_x1_x2(int tot, IMATRIX var_order, IVECTOR x1, IVECTOR x2)
+ /*
+ int tot; total number of variables
+ IMATRIX var_order; array of variables with tag identifying them
+ to be eliminated
+ IVECTOR x1, array of variables to be eliminated
+ x2; array of remaining variables
+ */
+{
+ int i,j=1,k=1;
+
+ for(i=1; i<=tot; i++)
+ {
+ if(var_order[i][2] == 1)
+ x1[j++] = var_order[i][1];
+ else
+ x2[k++] = var_order[i][1];
+ }
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_ac1_ac2() */
+/* */
+/* SYNOPSIS : void find_ac1_ac2(t1,t2,t3,x1,x2,mat,ac1,ac2)*/
+/* */
+/* DESCRIPTION : This function splits the original equality */
+/* or the inequality matrix into two matrices; */
+/* the p-equalities or the inequalities and the*/
+/* remaining part of the matrix */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_ac1_ac2(int t1, int t2, int t3, IVECTOR x1, IVECTOR x2, MATRIX mat, MATRIX ac1, MATRIX ac2)
+ /*
+ int t1,t2,t3;
+ IVECTOR x1,x2; the variables corresponding to the split matrices
+ MATRIX mat, the original matrix to be split
+ ac1,ac2; the split matrices
+ */
+{
+ int i,j;
+
+ for(i=1; i<=t1; i++)
+ for(j=1; j<=t2; j++)
+ ac1[j][i] = mat[j][x1[i]];
+
+ for(i=1; i<=t3; i++)
+ for(j=1; j<=t2; j++)
+ ac2[j][i] = mat[j][x2[i]];
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_lu1_lu2() */
+/* */
+/* SYNOPSIS : void find_lu1_lu2_(tot,x1,x2,dom,dom1,dom2) */
+/* */
+/* DESCRIPTION : This function splits the lower or the upper */
+/* bounds of the total domain constraints into */
+/* two groups, one with the domain constraints */
+/* for the variables to be eliminated and the */
+/* other one for the remaining variables */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_lu1_lu2(IVECTOR tot, IVECTOR x1, IVECTOR x2, VECTOR dom, VECTOR dom1, VECTOR dom2)
+ /*
+ IVECTOR tot,x1,x2;
+ VECTOR dom, the original array of the lower or the upper bounds
+ dom1,dom2; the original bounds split in to two groups
+ */
+{
+ int i;
+
+ for(i=1; i<=tot[1]; i++)
+ dom1[i] = dom[x1[i]];
+
+ for(i=1; i<=tot[0]-tot[1]; i++)
+ dom2[i] = dom[x2[i]];
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_limits() */
+/* */
+/* SYNOPSIS : void find_limits(tot,domains,llim,ulim) */
+/* */
+/* DESCRIPTION : This function forms seperate arrays for the */
+/* lower and upper limits of the domains from */
+/* the original domain constraints read already*/
+/* from the input file */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_limits(int tot, MATRIX domains, VECTOR llim, VECTOR ulim)
+ /*
+ int tot;
+ MATRIX domains; matrix containing the domain variables and the limits
+ VECTOR llim,ulim; vectors of lower and upper limits
+ */
+{
+ int i;
+
+ for(i=1; i<=tot; i++)
+ {
+ llim[i] = domains[i][1];
+ ulim[i] = domains[i][3];
+ }
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_new_in_eq() */
+/* */
+/* SYNOPSIS : void find_new_in_eq(a1b.a1a2,ll,ul,rc,newin) */
+/* */
+/* DESCRIPTION : This function converts the original */
+/* equality constraints into domain */
+/* constraints eliminating the p-equalities */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_new_in_eq(VECTOR a1b, MATRIX a1a2, VECTOR ll, VECTOR ul, INDEX rc, MATRIX newin)
+ /*
+ VECTOR a1b, the product of a-inverse and b
+ ll,ul; upper and lower limits of the domain constraints
+ MATRIX a1a2, the products of a-inverse and matrix a2
+ newin; the final matrix with domain constraints
+ INDEX rc;
+ */
+{
+ int i,j;
+
+ for(i=1; i<=rc.r; i++)
+ for(j=1; j<=rc.c; j++)
+ if(j==1)
+ newin[i][j] = ll[i] - a1b[i];/*eliminating the constrants from the*/
+ else if(j==rc.c) /*equations in the domain constraints*/
+ newin[i][j] = ul[i] - a1b[i];
+ else
+ newin[i][j] = 0 - a1a2[i][j-1];
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_org_in_eq() */
+/* */
+/* SYNOPSIS : void find_org_in_eq(a1_b,a1_a2,vec_d,c1,c2, */
+/* c1row,a1a2,org_ineq)*/
+/* */
+/* DESCRIPTION : This function converts the original */
+/* inequality constraints into domain */
+/* constraints, with the variables other than */
+/* the p-variables eliminated */
+/* */
+/* FUNCTIONS CALLED : matrix(). */
+/* mmprod(), */
+/* mvprod(), */
+/* Gvector(), */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_org_in_eq(VECTOR a1_b, MATRIX a1_a2, VECTOR vec_d, MATRIX c1, MATRIX c2, int c1row,
+ INDEX a1a2, MATRIX org_ineq)
+ /*
+ VECTOR vec_d, the RHS constant vector
+ a1_b; product of a1-inverse and b
+ MATRIX a1_a2, product of a1-inverse and a2
+ org_ineq, the converted inequalities into domains
+ c1,c2; p_inequalities and the remaining inequalities
+ int c1row;
+ INDEX a1a2; rows and columns of the matrices
+ */
+{
+ int i,j;
+ VECTOR temp;
+ MATRIX mat;
+
+ temp = Gvector(1,c1row);
+ mat = matrix(1,c1row,1,a1a2.c-1);
+
+ mvprod(c1row,a1a2.r,temp,c1,a1_b);/*matrix, vector product C1.invA1.b*/
+ mmprod(c1row,a1a2.r,a1a2.c-1,mat,c1,a1_a2);/*matrix, matrix product*/
+
+ for(i=1; i<=c1row; i++)
+ for(j=1; j<=a1a2.c; j++)
+ {
+ if (j==a1a2.c)
+ org_ineq[i][j] = vec_d[i] - temp[i];
+ else
+ org_ineq[i][j] = c2[i][j] - mat[i][j];
+ }
+ free_vector(temp,1);
+ free_matrix(mat,1,c1row,1);
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : initialize() */
+/* */
+/* SYNOPSIS : void initialize(mat,rc) */
+/* */
+/* DESCRIPTION : This function initializes all the components */
+/* of the given matrix to zero */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void initialize(MATRIX mat, INDEX rc)
+ /*
+ MATRIX mat;
+ INDEX rc;
+ */
+{
+ int i,j;
+
+ for(i=1; i<=rc.r; i++)
+ for(j=1; j<=rc.c; j++)
+ mat[i][j] = 0.0;
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_final_mat1() */
+/* */
+/* SYNOPSIS : void find_final_mat1(x2,l2,u2,finmat,row,col)*/
+/* */
+/* DESCRIPTION : This function copies the remaining original */
+/* domain constraints on to the final matrix */
+/* to be printed */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_final_mat1(VECTOR l2, VECTOR u2, MATRIX finmat, int row, int col)
+ /*
+ MATRIX finmat;
+ VECTOR l2,u2;
+ int row,col;
+ */
+{
+ int i,j=2;
+
+ for(i=1; i<=row; i++)
+ {
+ finmat[i][1] = l2[i];
+ finmat[i][col] = u2[i];
+ finmat[i][j++] = 1.0;
+ }
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_final_mat2() */
+/* */
+/* SYNOPSIS : void find_final_mat2(newin,r,c,finr,finmat) */
+/* */
+/* DESCRIPTION : This function appends the new inequalities */
+/* got from the original equalities, on to the */
+/* final matrix to be printed */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_final_mat2(MATRIX newin, int r, int c, int finr, MATRIX finmat)
+ /*
+ MATRIX newin,finmat;
+ int r,c,finr;
+ */
+{
+ int i,j;
+
+ for(i=1; i<=r; i++)
+ {
+ for(j=1; j<=c; j++)
+ finmat[finr][j] = newin[i][j];
+ finr++;
+ }
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_final_mat3() */
+/* */
+/* SYNOPSIS : void find_final_mat3(orgin,r,c,finr,finmat) */
+/* */
+/* DESCRIPTION : This function appends the inequalities, which*/
+/* were converted into domain constraints, on */
+/* to the final matrix to be printed */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void find_final_mat3(MATRIX orgin, int r, int c, int finr, MATRIX finmat)
+ /*
+ MATRIX orgin,finmat;
+ int r,c,finr;
+ */
+{
+ int i,j;
+
+ for(i=1; i<=r; i++)
+ {
+ finmat[finr][1] = MIN;
+ for(j=1; j<=c; j++)
+ finmat[finr][j+1] = orgin[i][j];
+ finr++;
+ }
+}
diff --git a/src/eval.cpp b/src/eval.cpp
new file mode 100644
index 0000000..64b8c25
--- /dev/null
+++ b/src/eval.cpp
@@ -0,0 +1,287 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ University of Michigan
+ http://www-personal.umich.edu/~wmebane
+ <wmebane at umich.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ August 3, 2009
+
+*/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "genoud.h"
+
+extern "C"
+{
+ double evaluate(SEXP fn, SEXP rho, double *X, long nvars, short int MinMax)
+ {
+ SEXP R_fcall, Rx;
+ double fit;
+ long i;
+ int isFinite=0;
+
+ PROTECT(Rx = allocVector(REALSXP, nvars));
+
+ for (i=0; i<nvars; i++)
+ {
+ REAL(Rx)[i] = X[(i+1)];
+ }
+
+ PROTECT(R_fcall = lang2(fn, R_NilValue));
+ SETCADR(R_fcall, Rx);
+ fit = REAL(eval(R_fcall, rho))[0];
+ UNPROTECT(2);
+
+ isFinite = R_finite(fit);
+ if (!isFinite)
+ {
+ if (MinMax)
+ {
+ return(-1*DOUBLEMAX);
+ }
+ else
+ {
+ return(DOUBLEMAX);
+ }
+ }
+
+
+ return(fit);
+ } /* double evaluate(SEXP fn, VECTOR X, long nvars, short int MinMax) */
+
+
+ void EvaluateLexical(SEXP fn, SEXP rho,
+ double *X, long nvars, long lexical, short int MinMax, double *ret)
+ {
+ SEXP R_fcall, Rx, Rret;
+ long i;
+ int isFinite=0;
+
+ PROTECT(Rx = allocVector(REALSXP, nvars));
+
+ for (i=0; i<nvars; i++)
+ {
+ REAL(Rx)[i] = X[i+1];
+ }
+
+ PROTECT(R_fcall = lang2(fn, R_NilValue));
+ SETCADR(R_fcall, Rx);
+ Rret = eval(R_fcall, rho);
+
+ for (i=0; i<lexical; i++)
+ {
+ ret[i] = REAL(Rret)[i];
+ isFinite = R_finite(ret[i]);
+ if (!isFinite)
+ {
+ if (MinMax)
+ {
+ ret[i]=(-1*DOUBLEMAX);
+ }
+ else
+ {
+ ret[i]=(DOUBLEMAX);
+ }
+ }
+ }
+ UNPROTECT(2);
+ } /* void EvaluateLexical(SEXP fn, SEXP rho */
+
+
+ void EvaluateTransform(SEXP fn, SEXP rho,
+ double *X, long nvars, long lexical, short int MinMax, double *ret)
+ {
+ SEXP R_fcall, Rx, Rret;
+ long i;
+ int isFinite=0;
+
+ PROTECT(Rx = allocVector(REALSXP, nvars));
+
+ for (i=0; i<nvars; i++)
+ {
+ REAL(Rx)[i] = X[i+1];
+ }
+
+ PROTECT(R_fcall = lang2(fn, R_NilValue));
+ SETCADR(R_fcall, Rx);
+ Rret = eval(R_fcall, rho);
+
+ for (i=0; i<lexical; i++)
+ {
+ ret[i] = REAL(Rret)[i];
+ isFinite = R_finite(ret[i]);
+ if (!isFinite)
+ {
+ if (MinMax)
+ {
+ ret[i]=(-1*DOUBLEMAX);
+ }
+ else
+ {
+ ret[i]=(DOUBLEMAX);
+ }
+ }
+ }
+ for(i=0; i<nvars; i++) // this is the only part that differs from EvaluateLexical
+ {
+ X[(i+1)] = REAL(Rret)[(i+lexical)];
+ }
+ UNPROTECT(2);
+ } /* void EvaluateTransform(SEXP fn, SEXP rho */
+
+ void userGradientfn(SEXP fnGR, SEXP rho, double *parms, double *grad, long nvars)
+ {
+ SEXP Rparms, R_fcall, Rgrad;
+ long i;
+
+ PROTECT(Rparms = allocVector(REALSXP, nvars));
+ PROTECT(Rgrad = allocVector(REALSXP, nvars));
+
+ for(i=0; i<nvars; i++)
+ {
+ REAL(Rparms)[i] = parms[i];
+ }
+
+ PROTECT(R_fcall = lang2(fnGR, R_NilValue));
+ SETCADR(R_fcall, Rparms);
+ Rgrad = eval(R_fcall, rho);
+
+ for(i=0; i<nvars; i++)
+ {
+ grad[i] = REAL(Rgrad)[i];
+ }
+
+ UNPROTECT(3);
+ } /* void userGradientfn(SEXP fnGR, SEXP rho, double *parms, double *grad, long nvars) */
+
+
+ void RlexicalSort(SEXP fnLexicalSort, SEXP rho,
+ double **population,
+ short int MinMax, long pop_size, long nvars, long lexical_end,
+ short int type)
+ {
+ SEXP parms, MAT, R_fcall, MATret;
+ long i,j,k=0;
+
+ /* MinMax: 0 min, 1 max */
+ /* parms = (1) MinMax, (2) nvars, (3) lexical_end, (4) [nvars/or lexical sort] */
+ /* using: #define M(ROW,COL,NCOLS) (((ROW)*(NCOLS))+(COL)) */
+
+ PROTECT(MAT = allocMatrix(REALSXP, pop_size, lexical_end));
+ PROTECT(parms = allocVector(REALSXP, 4));
+
+ REAL(parms)[0] = MinMax;
+ REAL(parms)[1] = nvars;
+ REAL(parms)[2] = lexical_end;
+ REAL(parms)[3] = type; /* 0=nvars, 1=lexical on obj function */
+
+ for(j=0; j<lexical_end; j++)
+ for (i=1; i<=pop_size; i++)
+ {
+ {
+ REAL(MAT)[k] = population[i][j];
+ k++;
+ }
+ }
+
+ PROTECT(R_fcall = lang3(fnLexicalSort, MAT, parms));
+ SETCADR(R_fcall, parms);
+ SETCADR(R_fcall, MAT);
+ MATret = eval(R_fcall, rho);
+
+ k = 0;
+ for(j=0; j<lexical_end; j++)
+ for (i=1; i<=pop_size; i++)
+ {
+ {
+ population[i][j] = REAL(MATret)[k];
+ k++;
+ }
+ }
+ UNPROTECT(3);
+ }
+
+ long RmemoryMatrixEvaluate(SEXP fnMemoryMatrixEvaluate, SEXP rho,
+ double **Memory, double **population,
+ short int MinMax, long pop_size, long UniqueCount,
+ long nvars, long lexical, long lexical_end)
+ {
+ SEXP parms, Rmemory, Rpopulation, R_fcall, Rret;
+ long i,j,k;
+
+ /* MinMax: 0 min, 1 max */
+ /* parms = (1) MinMax, (2) UniqueCount, (3) nvars, (4) lexical */
+
+ PROTECT(Rmemory = allocMatrix(REALSXP, UniqueCount, lexical_end));
+ PROTECT(Rpopulation = allocMatrix(REALSXP, pop_size, lexical_end));
+ PROTECT(parms = allocVector(REALSXP, 3));
+
+ REAL(parms)[0] = MinMax;
+ REAL(parms)[1] = nvars;
+ REAL(parms)[2] = lexical;
+
+ if(UniqueCount > 1)
+ {
+ k=0;
+ for(j=0; j<lexical_end; j++)
+ for (i=1; i<=UniqueCount; i++)
+ {
+ {
+ REAL(Rmemory)[k] = Memory[i][j];
+ k++;
+ }
+ }
+ }
+
+ k =0;
+ for(j=0; j<lexical_end; j++)
+ for (i=1; i<=pop_size; i++)
+ {
+ {
+ REAL(Rpopulation)[k] = population[i][j];
+ k++;
+ }
+ }
+
+ PROTECT(R_fcall = lang4(fnMemoryMatrixEvaluate, Rmemory, Rpopulation, parms));
+ SETCADR(R_fcall, parms);
+ SETCADR(R_fcall, Rpopulation);
+ SETCADR(R_fcall, Rmemory);
+ Rret = eval(R_fcall, rho);
+
+ UniqueCount = (long) REAL(Rret)[0];
+ k =1;
+ for(j=0; j<lexical_end; j++)
+ for (i=1; i<=UniqueCount; i++)
+ {
+ {
+ Memory[i][j] = REAL(Rret)[k];
+ k++;
+ }
+ }
+
+ for(j=0; j<lexical_end; j++)
+ for (i=1; i<=pop_size; i++)
+ {
+ {
+ population[i][j] = REAL(Rret)[k];
+ k++;
+ }
+ }
+
+ UNPROTECT(4);
+ return(UniqueCount);
+ }
+} /* end of extern "C" */
+
diff --git a/src/evaluate.cpp b/src/evaluate.cpp
new file mode 100644
index 0000000..8fc32ba
--- /dev/null
+++ b/src/evaluate.cpp
@@ -0,0 +1,4117 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ University of Michigan
+ http://www-personal.umich.edu/~wmebane
+ <wmebane at umich.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ June 27, 2013
+
+*/
+
+#include "genoud.h"
+#include "gradient.h"
+
+extern "C"
+{
+
+ double genoud_optim(SEXP fn_optim, SEXP rho, double *X, long parameters);
+
+ void RlexicalSort(SEXP fnLexicalSort, SEXP rho,
+ double **population,
+ short int MinMax, long pop_size, long nvars, long lexical_end,
+ short int type);
+
+ long RmemoryMatrixEvaluate(SEXP fnMemoryMatrixEvaluate, SEXP rho,
+ double **Memory, double **population,
+ short int MinMax, long pop_size, long UniqueCount,
+ long nvars, long lexical, long lexical_end);
+
+ void userGradientfn(SEXP fnGR, SEXP rho, double *parms, double *grad, long nvars);
+}
+
+long Gnvars[MAXINSTANCES];
+struct GND_IOstructure *ExternStructure;
+
+int JaIntegerCMP(double **a, double **b)
+{
+ extern long Gnvars[MAXINSTANCES];
+ extern struct GND_IOstructure *ExternStructure;
+
+
+ long i = 0;
+ long nvars;
+
+ nvars=Gnvars[ExternStructure->InstanceNumber];
+
+ for (i=1; i<=nvars; i++) {
+ if ( (int) a[0][i] != (int) b[0][i])
+ break;
+ }
+
+ if ( (int) a[0][i] > (int) b[0][i]) i = 1;
+ else if ( (int) a[0][i] < (int) b[0][i]) i = -1;
+
+ return i;
+} /* end of JaIntegerCMP */
+
+
+int JaDoubleCMP(double **a, double **b)
+{
+ extern long Gnvars[MAXINSTANCES];
+ extern struct GND_IOstructure *ExternStructure;
+
+ long i = 0;
+ long nvars;
+
+ nvars=Gnvars[ExternStructure->InstanceNumber];
+
+ for (i=1; i<=nvars; i++) {
+ if ( a[0][i] != b[0][i])
+ break;
+ }
+
+ if ( a[0][i] > b[0][i]) i = 1;
+ else if ( a[0][i] < b[0][i]) i = -1;
+
+ return i;
+} /* end of JaCMP */
+
+
+/* Cummulative probability on crossover */
+/* Random probability on mutation */
+/* NO multiple hits per agent possible */
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : optimization() */
+/* */
+/* SYNOPSIS : double optimization(X,x1,x2,fin_mat,rc,tot_eq) */
+/* */
+/* DESCRIPTION : This procedure initializes the population */
+/* with the values X passed from main, and */
+/* evaluates them. After assigning weight */
+/* for each member of the populaiton, a group */
+/* of them are chosen to reproduce and a group */
+/* is chosen to die. Genetic operators are */
+/* applied and a new generation is produced */
+/* to replace the members that died. This */
+/* cycle continues for the number of times, */
+/* user specifies in the input file */
+/* */
+/* FUNCTIONS CALLED : assign_probab(), */
+/* evaluate(), */
+/* find_cum_probab(), */
+/* find_live_die(), */
+/* find_parent(), */
+/* ivector(), */
+/* matrix(), */
+/* oper1(), */
+/* oper2(), */
+/* oper3(), */
+/* oper4(), */
+/* oper5(), */
+/* oper6(), */
+/* print_population(), */
+/* sort(), */
+/* Gvector() was vector(). */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/********************************************************************************/
+
+void optimization(struct GND_IOstructure *Structure, VECTOR X,
+ MATRIX domains)
+{
+
+ extern struct GND_IOstructure *ExternStructure;
+
+ MATRIX
+ new_genera, /*Temporary storage for the new generation*/
+ population, /*Population of x2 variables*/
+ temp;
+
+ VECTOR probab, /*Probability of agents to die or live*/
+ cum_probab, /*Cumilative probability of agents*/
+ t_vec;
+
+ IVECTOR live;
+ /* for oper4 */
+ IVECTOR parents;
+
+
+
+ long count_gener= 1; /*Counter to keep track of the number of generations*/
+ unsigned long peak_cnt;
+
+ int /*Total number of agents chosen to reproduce*/
+ j1,
+ j2,
+ j3,
+ j4,
+ j5,
+ j6,
+ j7,
+ j8,
+ oper,
+ ocnt,
+ B, /*Parameter for the 3rd operator - nonuniform mutation*/
+ STEP, /*Parameter for the 5th operator - simple arithmetical crossover*/
+ first_live=0, /*Index of the two parents for crossover parents*/
+ second_live=0,
+ first_die, /*Index of the two parents for crossover death*/
+ second_die,
+ die_now; /*index of agent to replace in current operation*/
+
+ long i,j, s, k;
+ /* for oper 4 */
+ int p2use;
+
+
+ double Q; /*Probability of the best agent*/
+ FLAG same;
+ double **Jnew;
+
+ double bfgsfit;
+
+ double *grad, *evalX, *finalhessin, *bfgsoutX;
+
+ int nochange_gen=0;
+
+ double oldfitvalue=0;
+
+ int IncreaseGenerations;
+ short int GradientTrigger=0;
+ short int BoundaryTrigger;
+ long InstanceNumber;
+
+ long nvars, MaxGenerations, WaitGenerations, count;
+ long pop_size, P, P0, P1, P2, P3, P4, P5, P6, P7, P8;
+ short int MinMax, GradientCheck, BoundaryEnforcement, UseBFGS, HardMaximumNumber=0;
+ double SolutionTolerance, *Results, *Gradients;
+ short PrintLevel, HardGenerationLimit;
+
+ /* Old variables which may change when SetRunTimeParameters is run during a run! */
+ long pop_size_old;
+
+ /* Summary Statistics (mean, variance etc) */
+ /* double popmean, popvar, popwrk, popstat; */
+
+ /* Population Print population*/
+ FILE *popout;
+ long *tobs, nnull;
+ double *mean, *var, *skew, *kur;
+
+ /* Stuff for the Unique Stuff (how's that for an informative comment! */
+ /* A big Matrix which remembers all of our past evaluations. It's
+ maximum memory is set in genoud.h */
+ extern long Gnvars[MAXINSTANCES];
+ double **Memory;
+ long MemorySize=0, UniqueCount=0, OldUniqueCount=0;
+
+ /* fine two unique parents count */
+ long SameCount, UniquePairs;
+
+ ExternStructure=Structure;
+
+ Results=Structure->oResults;
+ Gradients=Structure->oGradients;
+
+ /* Structure Done */
+ SetRunTimeParameters(Structure, 1,
+ &pop_size, &nvars, &MaxGenerations, &WaitGenerations,
+ &MinMax, &GradientCheck, &BoundaryEnforcement, &UseBFGS, &SolutionTolerance,
+ &InstanceNumber, &P, &P0, &P1, &P2, &P3, &P4, &P5, &P6, &P7, &P8,
+ &PrintLevel, &HardGenerationLimit);
+
+ /*Space allocation for all the vectors and matrices involved*/
+ long lexical_end = (Structure->Lexical-1)+nvars+2;
+ /* population[][0] = fitness value (first)
+ population[][1:nvars] = parameter values
+ population[][nvars+1] = flag for fitting
+ population[][(nvars+2):((Structure->Lexical-1)+nvars+2)] = other fitness for Lexical fitting
+ */
+ population = JaMatrixAllocate(pop_size+2, lexical_end);
+ new_genera = JaMatrixAllocate(pop_size+2, lexical_end);
+
+ /* reset population to get rid of odd things being passed to R */
+ for(i=1; i<=pop_size; i++)
+ {
+ for(j=0; j<lexical_end; j++)
+ {
+ population[i][j] = 0;
+ }
+ }
+
+ VECTOR LexicalReturn;
+ VECTOR oldfitvalueVEC;
+ short int LexicalFitsImproving;
+ /* Transform is logically similar to Lexical even if there is only one fit criterion */
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ LexicalReturn = (double *) malloc(Structure->Lexical*sizeof(double));
+ oldfitvalueVEC = (double *) malloc(Structure->Lexical*sizeof(double));
+ }
+
+ temp = matrix(0,nvars+1,0,nvars);
+ probab = Gvector(1,pop_size);
+ t_vec = Gvector(1,nvars);
+ cum_probab = Gvector(1,pop_size);
+ live = ivector(1,pop_size);
+
+ /*for oper4 Find max(2,nvars) parents for crossover operator 4*/
+ p2use = nvars > 2 ? nvars : 2;
+ parents = ivector(1,p2use);
+
+ Gnvars[Structure->InstanceNumber]=nvars;
+
+ if (Structure->MemoryUsage==1)
+ {
+ if (HardGenerationLimit==0)
+ MemorySize=3*(MaxGenerations+1)*pop_size+1+pop_size;
+ else
+ MemorySize=(MaxGenerations+1)*pop_size+1+pop_size;
+
+ Memory = JaMatrixAllocate(MemorySize, lexical_end);
+ }
+
+ grad = (double *) malloc((nvars)*sizeof(double));
+ evalX = (double *) malloc((nvars)*sizeof(double));
+ finalhessin = (double *) malloc(((nvars*nvars)+(nvars))*sizeof(double));
+ bfgsoutX = (double *) malloc((nvars+1)*sizeof(double));
+
+ /* populationstats variables */
+ mean = (double *) malloc((nvars+1)*sizeof(double));
+ var = (double *) malloc((nvars+1)*sizeof(double));
+ skew = (double *) malloc((nvars+1)*sizeof(double));
+ kur = (double *) malloc((nvars+1)*sizeof(double));
+ tobs = (long *) malloc((nvars+1)*sizeof(long));
+
+ Q=0.5;
+ B=6;
+ STEP=10;
+
+ if(PrintLevel>0)
+ {
+ switch(MinMax) {
+ case 0:
+ Rprintf("Minimization Problem.\n");
+ break;
+ case 1:
+ Rprintf("Maximization Problem.\n");
+ break;
+ }
+ }
+
+ /*
+ if (PrintLevel>2) {
+ Rprintf("Parameter B (hardcoded): %d\n", B);
+ Rprintf("Parameter Q (hardcoded): %f\n", Q);
+ }
+ */
+
+ peak_cnt = 0;
+
+ pop_size_old=0;
+ if (Structure->ShareType == 1 || Structure->ShareType == 3) {
+
+ if(PrintLevel>0)
+ Rprintf( "Using old population file to initialize new population.\n");
+
+ if((popout = fopen(Structure->ProjectPath, "r")) == NULL) {
+ Rprintf(" Generating new population\n");
+ warning("Unable to open the old project file: %s", Structure->ProjectPath);
+ }
+ else {
+ pop_size_old=ReadPopulation(population, pop_size, nvars, popout, PrintLevel);
+ fclose(popout);
+ if (pop_size_old<2) {
+ warning("The old population file appears to be from a different genoud specification.");
+ pop_size_old=0;
+ }
+ }
+ if (PrintLevel>1) {
+ if((popout = fopen(Structure->ProjectPath, "a")) == NULL) {
+ warning("Unable to open the project file: %s", Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ fclose(popout);
+ }
+ } /* end of ShareType 0 */
+ else {
+ if (PrintLevel>1) {
+ if((popout = fopen(Structure->ProjectPath, "w")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ fclose(popout);
+ }
+ }
+
+ /* The new initial value matrix: setting a new initial value for every individual */
+ if (ExternStructure->nStartingValues > 0)
+ {
+ /* Adjust old starting values (from ReadPopulation) so we have enough room for our
+ starting.values */
+ pop_size_old = pop_size_old-ExternStructure->nStartingValues-1;
+ if (pop_size_old < 0)
+ pop_size_old = 0;
+
+ // seed the starting values until we run out of population or starting values!
+ j = pop_size_old;
+
+ for(s=0; s<ExternStructure->nStartingValues; s++) {
+ j++;
+ for(i=1; i<=nvars; i++) {
+ population[j][i] = ExternStructure->StartingValues[s][i-1];
+ population[j][nvars+1] = -1.0;
+ }
+ } // end of for loop
+ pop_size_old = j;
+
+ // randomly add on people if we still have population left over!
+ for(j=pop_size_old+1; j<=pop_size; j++) {
+ for(i=1; i<=nvars; i++) {
+ population[j][i] = frange_ran(domains[i][1], domains[i][3]);
+ population[j][nvars+1] = -1.0;
+ }
+ }
+ } // end of we have starting values!
+ else
+ {
+ for(j=pop_size_old+1; j<=pop_size; j++) {
+ for(i=1; i<=nvars; i++) {
+ population[j][i] = frange_ran(domains[i][1], domains[i][3]);
+ population[j][nvars+1] = -1.0;
+ }
+ }
+ } // end of else
+
+ if (Structure->MemoryUsage==1)
+ {
+ OldUniqueCount=UniqueCount;
+
+ if (UniqueCount==0)
+ UniqueCount = 1;
+
+ UniqueCount = RmemoryMatrixEvaluate(Structure->fnMemoryMatrixEvaluate, Structure->rho,
+ Memory, population,
+ MinMax, pop_size, UniqueCount,
+ nvars, Structure->Lexical, lexical_end);
+
+ if ( (UniqueCount+pop_size) >= MemorySize )
+ {
+ Structure->MemoryUsage=0;
+ warning("Turned Off MemoryMatrix because memory usage was too great.");
+ } /* end of if */
+ } // end of Memory based evaluation
+ else
+ {
+ for (i=1; i<=pop_size; i++)
+ {
+ if (population[i][nvars+1]==-1.0 || population[i][nvars+1]==11.0)
+ {
+ for(j=1; j<=nvars; j++)
+ X[j] = population[i][j];
+
+ if (Structure->whichFUN == 1) // neither Lexical, nor Transform
+ {
+ population[i][0] = evaluate(Structure->fn, Structure->rho, X, nvars, MinMax);
+ }
+ else if(Structure->whichFUN == 2) // Lexical but not Transform
+ {
+ EvaluateLexical(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+
+ population[i][0] = LexicalReturn[0];
+ count = 0;
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ count++;
+ population[i][j] = LexicalReturn[count];
+ }
+ } // else if
+ else // Transform
+ {
+ EvaluateTransform(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+
+ population[i][0] = LexicalReturn[0];
+ count = 0;
+ if(Structure->Lexical > 1)
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ count++;
+ population[i][j] = LexicalReturn[count];
+ }
+ if (BoundaryEnforcement==0)
+ for(j=1; j<=nvars; j++)
+ {
+ population[i][j] = X[j];
+ }
+ else
+ for(j=1; j<=nvars; j++)
+ {
+ if(X[j] < domains[j][1])
+ {
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nNOTE: Transformed individual below lower bound.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e \t Bound: %e\n\n",
+ count_gener, j, X[j], domains[j][1]);
+ }
+ warning("Transformed individual below lower bound. Generation: %d; Parameter: %d; Value: %e; Bound: %e",
+ count_gener, j, X[j], domains[j][1]);
+ }
+ if(X[j] > domains[j][3])
+ {
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nNOTE: Transformed individual above upper bound.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e \t Bound: %e\n\n",
+ count_gener, j, X[j], domains[j][3]);
+ }
+ warning("Transformed individual above upper bound. Generation: %d; Parameter: %d; Value: %e; Bound: %e",
+ count_gener, j, X[j], domains[j][3]);
+ }
+ population[i][j] = X[j]; // put the transformation in anyway
+ }//end for
+ }//end Transform
+ }
+ } //end of i loop
+ } // end of default evaluation
+
+ if(Structure->MemoryUsage!=1)
+ {
+ /*Sort the initial individuals based on their evaluation function*/
+ if (Structure->Lexical < 2)
+ {
+ sort(MinMax,population,pop_size,0);
+ }
+ else
+ {
+ /* in eval.cpp because it is like the EvaluateLexical() function */
+ RlexicalSort(Structure->fnLexicalSort, Structure->rho,
+ population,
+ MinMax, pop_size, nvars, lexical_end, 1);
+ }
+ }
+
+ peak_cnt = count_gener;
+
+ /* since we are on generation 0 */
+ oldfitvalue=population[1][0];
+ if(Structure->Lexical > 1)
+ {
+ oldfitvalueVEC[0]=population[1][0];
+ k = 1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ oldfitvalueVEC[k]=population[1][i];
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ }
+
+ /*
+ if(PrintLevel>0)
+ {
+ Rprintf("\nThe best initial individual is:\n");
+ print_vector(population[1],1,nvars,output);
+
+ if (Structure->Lexical > 1)
+ {
+ Rprintf("\nbest (lexical) fitness:\n");
+ Rprintf("%e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ } else {
+ Rprintf("\nbest fitness: %e\n", population[1][0]);
+ }
+ Rprintf("\n");
+
+ if (Structure->Lexical > 1)
+ {
+ Rprintf("The worst (lexical) fitness is:\n");
+ Rprintf("%e ", population[pop_size][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[pop_size][j]);
+ }
+ Rprintf("\n");
+ } else {
+ Rprintf("The worst fit is: %e\n",
+ population[pop_size][0]);
+ }
+ Rprintf("\n");
+ }
+ */
+
+ if(PrintLevel==1)
+ {
+ if (Structure->Lexical > 1)
+ {
+ Rprintf("\n\nGeneration#\t Solution Values (lexical)\n");
+ Rprintf("\n%7d \t%e ", 0, population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ } else {
+ Rprintf("\n\nGeneration#\t Solution Value\n");
+ Rprintf("\n%7d \t%e\n", 0, population[1][0]);
+ }
+ }
+
+ /* compute and print mean and variance of population */
+ if (PrintLevel>1) {
+ Rprintf("GENERATION: 0 (initializing the population)\n");
+ populationstats(population, pop_size, nvars, mean, var, skew, kur, tobs);
+
+ if(Structure->Lexical > 1)
+ {
+ Rprintf( "Lexical Fit..... %e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf( "Fitness value... %e\n", population[1][0]);
+ Rprintf( "mean............ %e\n", mean[0]);
+ Rprintf( "variance........ %e\n", var[0]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ }
+
+ nnull = pop_size-tobs[0];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ if(Structure->MemoryUsage==1)
+ Rprintf( "#unique......... %d, #Total UniqueCount: %d\n",
+ UniqueCount-OldUniqueCount, UniqueCount);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+
+ for (i=1; i<=nvars; i++) {
+ Rprintf( "var %d:\n", i);
+ Rprintf( "best............ %e\n", population[1][i]);
+ Rprintf( "mean............ %e\n", mean[i]);
+ Rprintf( "variance........ %e\n", var[i]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ nnull = pop_size-tobs[i];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+ }
+ } /* end of printlevel if */
+
+ /* if(PrintLevel>0)
+ fflush(output); */
+
+ /* Print the population file */
+ if ( PrintLevel == 1 ) {
+ if((popout = fopen(Structure->ProjectPath, "w")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, 0, (int) Structure->Lexical, population, popout);
+ fclose(popout);
+ } /* end of PrintLevel if */
+ if ( PrintLevel>1 ) {
+ if((popout = fopen(Structure->ProjectPath, "a")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, 0, (int) Structure->Lexical, population, popout);
+ fflush(popout);
+ fclose(popout);
+ }
+
+ /* Interrupt setup. Let's print a nice message to recover the best
+ solution so far if at least generation 0 has been run */
+ if (PrintLevel > 0 & (strcmp(Structure->ProjectPath, "/dev/null")!=0))
+ setVar(install("interrupted"), ScalarLogical(1), Structure->rho);
+
+ /*Assigning probability of survival for each of the agent, with the*/
+ /*probability provided by the user for the best agent*/
+ assign_probab(probab,pop_size,Q);
+
+ /*Finding the cumulative probability of the agents*/
+ find_cum_probab(cum_probab,probab,pop_size);
+
+ /*Reproducing and evaluating for the total number of generations times*/
+ do
+ {
+
+ /*Initializing the live vector*/
+ for(j=1; j<=pop_size; j++)
+ {
+ live[j] = 0;
+ for(i=0; i<lexical_end; i++)
+ new_genera[j][i] = population[j][i];
+ new_genera[j][nvars+1]=0;
+ }
+
+ /*Finding the agents that will die and the agents that will reproduce*/
+ find_live(cum_probab,live,pop_size,P);
+ /* set die_now counter to start replacements with the worst agent.
+ use of die_now is okay if the entire population (except the previous
+ best) is to be replaced in each generation */
+ die_now = pop_size;
+
+ j1=j2=j3=j4=j5=j6=j7=j8=0;
+
+ /* This was causing a difference to appear between MemoryMatrix and !MemoryMatrix runs see oper5 and oper7
+ UniquePairs= UniqueCount-OldUniqueCount;
+ UniquePairs= (int) (0.5*(UniquePairs*UniquePairs-UniquePairs));
+ if ( MAX_OPER_UNIQUE_TRY < UniquePairs)
+ UniquePairs = MAX_OPER_UNIQUE_TRY;
+ */
+ UniquePairs = MAX_OPER_UNIQUE_TRY;
+
+ /* main operator loop */
+ while(j1+j2+j3+j4+j4+j5+j5+j6+j7+j7+j8 < P)
+ {
+ oper = irange_ran(1,8);
+ switch (oper)
+ {
+ case 1:
+ /* JS Description: Uniform Mutation */
+ /*Applying the first operator, uniform mutation*/
+ if (j1 < P1)
+ {
+ /*Find one parent for mutation operator 1*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 1.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ for (ocnt = irange_ran(1,nvars); ocnt>0; ocnt--)
+ oper1(t_vec,domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j1++;
+ }
+ break;
+ case 2:
+ /* JS Description: Boundary Mutation */
+ /*Applying the second operator, boundary mutation*/
+ if (j2 < P2)
+ {
+ /*Find one parent for mutation operator 2*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 2.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ oper2(t_vec,domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j2++;
+ }
+ break;
+ case 3:
+ /* JS Description: Non-uniform Mutation */
+ /*Applying the third operator, non-uniform mutation*/
+ if (j3 < P3)
+ {
+ /*Find one parent for mutation operator 3*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 3.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ for (ocnt = irange_ran(1,nvars); ocnt>0; ocnt--)
+ oper3(t_vec,domains,nvars,MaxGenerations,count_gener,B);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j3++;
+ }
+ break;
+
+ case 4:
+ /*Applying the fourth operator, GENOUD Polytope Crossover */
+ if (j4 < (int) P4)
+ {
+ /*Find max(2,nvars) parents for crossover operator 4*/
+ for (i=1; i<p2use; i++) {
+ parents[i] = find_parent(live,pop_size);
+ live[parents[i]]++; /* no decr. first p2use-1 parents */
+ }
+ parents[p2use] = find_parent(live,pop_size);
+ /* check that agents to replace are in range */
+ if (die_now < 2) {
+ error("No agents to be replaced\n");
+ }
+ new_genera[die_now][nvars+1] = 4.0;
+ for(j=1; j<=p2use; j++)
+ for(i=1; i<=nvars; i++)
+ temp[j][i] = population[parents[j]][i];
+ oper4(temp,p2use,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = temp[1][i];
+ die_now--;
+ j4++;
+ }
+ break;
+ case 5:
+ /* JS Description: Simple Crossover
+ Applying the fifth operator, simple arithmetical crossover*/
+ if (j5 < (int) P5/2)
+ {
+ /*Find two distinct parents for crossover operator 5*/
+ same = TRUE;
+ SameCount=0;
+ while (same==TRUE) {
+ SameCount++;
+
+ first_live = find_parent(live,pop_size);
+ second_live = find_parent(live,pop_size);
+
+ if (SameCount >= (UniquePairs) )
+ break;
+
+ for(i=1; i<=nvars; i++)
+ {
+ if (population[first_live][i] != population[second_live][i])
+ {
+ same = FALSE;
+ break;
+ }
+ }
+ } /* end of while same==TRUE loop */
+ /* check that agents to replace are in range */
+ if (die_now < 3) {
+ error("Not enough agents to be replaced\n");
+ }
+ live[first_live]--;
+ live[second_live]--;
+ first_die = die_now-- ;
+ second_die = die_now-- ;
+ new_genera[first_die][nvars+1] = 5.0;
+ new_genera[second_die][nvars+1] = 5.0;
+ if (!same)
+ {
+ for(i=1; i<=nvars; i++)
+ {
+ temp[1][i] = population[first_live][i];
+ temp[2][i] = population[second_live][i];
+ }
+ oper5(temp[1],temp[2],STEP,domains,nvars);
+ for(i=1; i<=nvars; i++)
+ {
+ new_genera[first_die][i] = temp[1][i];
+ new_genera[second_die][i] = temp[2][i];
+ }
+ }
+ else {
+ /* copy agent chosen twice into two new indivs */
+ for(i=1; i<=nvars; i++) {
+ new_genera[first_die][i] =
+ population[first_live][i];
+ new_genera[second_die][i] =
+ population[second_live][i];
+ }
+ }
+ j5++;
+ }
+ break;
+ case 6:
+ /* JS Description: Whole Non-uniform Mutation */
+ /*Applying the sixth operator, whole non-uniform mutation*/
+ if (j6 < P6)
+ {
+ /*Find one parent for mutation operator 6*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 6.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ oper6(t_vec,domains,nvars,MaxGenerations,count_gener,B);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j6++;
+ }
+ break;
+ case 7:
+ /* JS Description: Heuristic Crossover */
+ /*Applying the seventh operator*/
+ if (j7 < (int) P7/2)
+ {
+ /*Find two distinct parents for operator 7*/
+ same = TRUE;
+ SameCount=0;
+ while (same==TRUE) {
+ SameCount++;
+
+ first_live = find_parent(live,pop_size);
+ second_live = find_parent(live,pop_size);
+
+ if (SameCount >= (UniquePairs) )
+ break;
+
+ for(i=1; i<=nvars; i++)
+ {
+ if (population[first_live][i] != population[second_live][i])
+ {
+ same = FALSE;
+ break;
+ }
+ }
+ } /* end of while same==TRUE loop */
+ /* check that agents to replace are in range */
+ if (die_now < 3) {
+ error("Not enough agents to be replaced\n");
+ }
+ live[first_live]--;
+ live[second_live]--;
+ first_die = die_now-- ;
+ second_die = die_now-- ;
+ new_genera[first_die][nvars+1] = 7.0;
+ new_genera[second_die][nvars+1] = 7.0;
+ if (!same) {
+ if (first_live < second_live)
+ /* first agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[first_live][i];
+ temp[1][i] = population[second_live][i];
+ }
+ else
+ /* second agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[second_live][i];
+ temp[1][i] = population[first_live][i];
+ }
+ oper7(temp[1],temp[2],domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[first_die][i] = temp[1][i];
+ if (first_live < second_live)
+ /* first agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[first_live][i];
+ temp[1][i] = population[second_live][i];
+ }
+ else
+ /* second agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[second_live][i];
+ temp[1][i] = population[first_live][i];
+ }
+ oper7(temp[1],temp[2],domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[second_die][i] = temp[1][i];
+ }
+ else {
+ /* copy agent chosen twice into two new indivs */
+ for(i=1; i<=nvars; i++) {
+ new_genera[first_die][i] =
+ population[first_live][i];
+ new_genera[second_die][i] =
+ population[second_live][i];
+ }
+ }
+ j7++;
+ }
+ case 8:
+ /* JS Description: Local-Minimum Crossover */
+ /*Applying the eighth operator, homotopy (BFGS) */
+ if (j8 < P8 & (Structure->BFGSburnin >= 0) & (count_gener > Structure->BFGSburnin))
+ {
+ /*Find one parent for BFGS operator 1*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 8.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ oper8(Structure->fn_optim, Structure->rho, t_vec, domains, SolutionTolerance,
+ nvars, BoundaryEnforcement, PrintLevel,
+ Structure->P9mix);
+
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j8++;
+ }
+ break;
+ }
+ }
+
+ /*Replace the population with the new generation */
+ Jnew = new_genera;
+ new_genera = population;
+ population = Jnew;
+
+ if (Structure->MemoryUsage==1)
+ {
+ OldUniqueCount=UniqueCount;
+
+ UniqueCount = RmemoryMatrixEvaluate(Structure->fnMemoryMatrixEvaluate, Structure->rho,
+ Memory, population,
+ MinMax, pop_size, UniqueCount,
+ nvars, Structure->Lexical, lexical_end);
+
+ if ( (UniqueCount+pop_size) >= MemorySize )
+ {
+ Structure->MemoryUsage=0;
+ warning("Turned Off MemoryMatrix because memory usage was too great.");
+ } /* end of if */
+ } // end of MemoryUsage==1
+ else
+ {
+ for (i=1; i<=pop_size; i++)
+ {
+ if (population[i][nvars+1]!=0)
+ {
+ for(j=1; j<=nvars; j++)
+ X[j] = population[i][j];
+
+ if (Structure->whichFUN == 1) // neither Lexical, nor Transform
+ {
+ population[i][0] = evaluate(Structure->fn, Structure->rho, X, nvars, MinMax);
+ }
+ else if(Structure->whichFUN == 2) // Lexical but not Transform
+ {
+ EvaluateLexical(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+
+ population[i][0] = LexicalReturn[0];
+ count = 0;
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ count++;
+ population[i][j] = LexicalReturn[count];
+ }
+ }
+ else // Transform
+ {
+ EvaluateTransform(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+
+ population[i][0] = LexicalReturn[0];
+ count = 0;
+ if(Structure->Lexical > 1) for(j=(nvars+2);j<lexical_end;j++)
+ {
+ count++;
+ population[i][j] = LexicalReturn[count];
+ }
+ for(j=1; j<=nvars; j++)
+ {
+ population[i][j] = X[j];
+ }
+ }
+ }
+ } //end of i loop
+ } //end of default evaluation scheme
+
+ if(Structure->MemoryUsage!=1)
+ {
+ /*Sort the new population based on their evaluation function*/
+ if (Structure->Lexical < 2)
+ {
+ sort(MinMax,population,pop_size,0);
+ }
+ else
+ {
+ /* in eval.cpp because it is like the EvaluateLexical() function */
+ RlexicalSort(Structure->fnLexicalSort, Structure->rho,
+ population,
+ MinMax, pop_size, nvars, lexical_end, 1);
+ }
+ }
+
+ /* apply the bfgs to the best individual */
+ if (UseBFGS != 0 & (Structure->BFGSburnin >= 0) & (count_gener > Structure->BFGSburnin)) {
+ for (i=1; i<=nvars; i++)
+ {
+ bfgsoutX[i-1]=population[1][i];
+ }
+
+ bfgsfit = genoud_optim(Structure->fn_optim, Structure->rho, bfgsoutX, nvars);
+
+ if (Structure->whichFUN == 1) // neither Lexical, nor Transform
+ {
+ switch(MinMax) {
+ case 0:
+ if (population[1][0] > bfgsfit) /* minimize */
+ {
+ /* is the BFGS individual in the bounds? */
+ BoundaryTrigger=0; /* outside of bounds ? */
+ for (i=0; i<nvars; i++) {
+ j = i+1;
+ if (bfgsoutX[i] < domains[j][1]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n\n",
+ count_gener, i+1, bfgsoutX[i]);
+ Rprintf("NOTE: Fit: %e\n\n", bfgsfit);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ if (bfgsoutX[i] > domains[j][3]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n",
+ count_gener, i+1, bfgsoutX[i]);
+ Rprintf("NOTE: Fit: %e\n\n", bfgsfit);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ } /* end for loop */
+
+ /* if we use out of bounds individuals then proceed */
+ /* 0=anything goes, 1: regular; 2: no trespassing! */
+ if (BoundaryEnforcement==0) {
+ for(i=1;i<=nvars;i++)
+ {
+ population[1][i]=bfgsoutX[i-1];
+ }
+ population[1][0]=bfgsfit;
+ }
+ else if (BoundaryTrigger==0) {
+ for(i=1;i<=nvars;i++)
+ {
+ population[1][i]=bfgsoutX[i-1];
+ }
+ population[1][0]=bfgsfit;
+ }
+ } /* end if (population[1][0] > bfgs) */
+ case 1:
+ if (population[1][0] < bfgsfit) /* maximize */
+ {
+ /* is the BFGS individual in the bounds? */
+ BoundaryTrigger=0; /* outside of bounds ? */
+ for (i=0; i<nvars; i++) {
+ j = i+1;
+ if (bfgsoutX[i] < domains[j][1]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n\n",
+ count_gener, i+1, bfgsoutX[i]);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ if (bfgsoutX[i] > domains[j][3]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n\n",
+ count_gener, i+1, bfgsoutX[i]);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ } /* end for loop */
+
+ /* if we we use out of bounds individuals then proceed */
+ /* 0=anything goes, 1: regular; 2: no trespassing! */
+ if (BoundaryEnforcement==0) {
+ for(i=1;i<=nvars;i++)
+ {
+ population[1][i]=bfgsoutX[i-1];
+ }
+ population[1][0]=bfgsfit;
+ }
+ else if (BoundaryTrigger==0) {
+ for(i=1;i<=nvars;i++)
+ {
+ population[1][i]=bfgsoutX[i-1];
+ }
+ population[1][0]=bfgsfit;
+ }
+ } /* end if (population[1][0] < bfgsfit) */
+ } /* end switch */
+ }/*end of NOT lexical bfgs hit */
+ else if(Structure->whichFUN == 2) // Lexical but not Transform
+ {
+ /* is the BFGS individual in the bounds? */
+ BoundaryTrigger=0; /* outside of bounds ? */
+ for (i=0; i<nvars; i++) {
+ j = i+1;
+ if (bfgsoutX[i] < domains[j][1]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n\n",
+ count_gener, i+1, bfgsoutX[i]);
+ Rprintf("NOTE: Fit: %e\n\n", bfgsfit);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ if (bfgsoutX[i] > domains[j][3]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n",
+ count_gener, i+1, bfgsoutX[i]);
+ Rprintf("NOTE: Fit: %e\n\n", bfgsfit);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ } /* end for loop */
+
+ /* if we use out of bounds individuals then proceed */
+ /* 0=anything goes, 1: regular; 2: no trespassing! */
+ /* Add new individual to the END because we are doing lexical stuff */
+ if (BoundaryEnforcement==0) {
+ for(i=1;i<=nvars;i++)
+ {
+ population[(pop_size-1)][i]=bfgsoutX[i-1];
+ X[i] = bfgsoutX[i-1];
+ }
+ EvaluateLexical(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+ population[(pop_size-1)][0] = LexicalReturn[0];
+ count = 0;
+ for(i=(nvars+2);i<lexical_end;i++)
+ {
+ count++;
+ population[(pop_size-1)][i] = LexicalReturn[count];
+ }
+
+ /* REDO SORT. This is inefficient becase we only changed 1 individual*/
+ RlexicalSort(Structure->fnLexicalSort, Structure->rho,
+ population,
+ MinMax, pop_size, nvars, lexical_end, 1);
+ }
+ else if (BoundaryTrigger==0) {
+ for(i=1;i<=nvars;i++)
+ {
+ population[(pop_size-1)][i]=bfgsoutX[i-1];
+ X[i] = bfgsoutX[i-1];
+ }
+ EvaluateLexical(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+ population[(pop_size-1)][0] = LexicalReturn[0];
+ count = 0;
+ for(i=(nvars+2);i<lexical_end;i++)
+ {
+ count++;
+ population[(pop_size-1)][i] = LexicalReturn[count];
+ }
+
+ /* REDO SORT. This is inefficient becase we only changed 1 individual*/
+ RlexicalSort(Structure->fnLexicalSort, Structure->rho,
+ population,
+ MinMax, pop_size, nvars, lexical_end, 1);
+ }
+ } /*end of LEXICAL bfgs hit */
+ else // Transform
+ {
+ for(j=1; j<=nvars; j++)
+ {
+ X[j] = bfgsoutX[(j-1)];
+ }
+ // Call EvaluateTransform now to transform X
+ EvaluateTransform(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+
+ /* is the BFGS individual in the bounds? */
+ BoundaryTrigger=0; /* outside of bounds ? */
+ for (j=1; i<=nvars; i++) {
+ if (X[j] < domains[j][1]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n\n",
+ count_gener, j, X[j]);
+ Rprintf("NOTE: Fit: %e\n\n", bfgsfit);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ if (X[j] > domains[j][3]) {
+ BoundaryTrigger=1;
+ if (PrintLevel>1)
+ {
+ Rprintf(
+ "\nNOTE: BFGS hit on best individual produced Out of Boundary individual.\n");
+ Rprintf("NOTE: Generation: %d \t Parameter: %d \t Value: %e\n",
+ count_gener, j, X[j]);
+ Rprintf("NOTE: Fit: %e\n\n", bfgsfit);
+ }
+ warning("BFGS hit on best individual produced Out of Boundary individual.");
+ }
+ } /* end for loop */
+
+ /* if we use out of bounds individuals then proceed */
+ /* 0=anything goes, 1: regular; 2: no trespassing! */
+ /* Figure out why BoundaryEnforcement==0 and BoundaryTrigerr==0 are separate above */
+ if (BoundaryEnforcement == 0 || BoundaryTrigger == 0) {
+ if(Structure->Lexical < 2) // Transform but not Lexical
+ {
+ for(i=1; i<=nvars; i++)
+ {
+ population[1][i] = X[i];
+ }
+ population[1][0] = LexicalReturn[0]; // from ~45 lines above
+ }
+ else /* Add new individual to the END because we are doing Transform and Lexical */
+ {
+ for(i=1;i<=nvars;i++)
+ {
+ population[(pop_size-1)][i] = X[i];
+ }
+ population[(pop_size-1)][0] = LexicalReturn[0]; // from ~55 lines above
+ count = 0;
+ for(i=(nvars+2);i<lexical_end;i++)
+ {
+ count++;
+ population[(pop_size-1)][i] = LexicalReturn[count];
+ }
+
+ /* REDO SORT. This is inefficient becase we only changed 1 individual*/
+ RlexicalSort(Structure->fnLexicalSort, Structure->rho,
+ population,
+ MinMax, pop_size, nvars, lexical_end, 1);
+ }
+ } /* end of boundary enforcment */
+ } /*end of TRANSFORM bfgs hit */
+ } /* end of UseBFGS */
+
+ /* check to see if fit is improving */
+ if(Structure->Lexical < 2)
+ {
+ switch(MinMax)
+ {
+ case 0:
+ if ( (oldfitvalue - SolutionTolerance) > population[1][0]) {
+ nochange_gen=0;
+ oldfitvalue=population[1][0];
+ peak_cnt = count_gener;
+ }
+ else nochange_gen++;
+ break;
+ case 1:
+ if ( (oldfitvalue + SolutionTolerance) < population[1][0]) {
+ nochange_gen=0;
+ oldfitvalue=population[1][0];
+ peak_cnt = count_gener;
+ }
+ else nochange_gen++;
+ break;
+ }
+ } /* if(Structure->Lexical < 2) */
+ else
+ {
+ switch(MinMax)
+ {
+ case 0:
+ LexicalFitsImproving = 0;
+ if ( (oldfitvalue - SolutionTolerance) > population[1][0])
+ {
+ LexicalFitsImproving = 1;
+ }
+ else
+ {
+ k=1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ if ( (oldfitvalueVEC[k] - SolutionTolerance) > population[1][i] ) {
+ LexicalFitsImproving = 1;
+ break;
+ } /* (oldfitvalueVEC[k] - SolutionTolerance) > population[1][i] ) */
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ } /* else if ( (oldfitvalue - SolutionTolerance) > population[1][0]) */
+ if (LexicalFitsImproving)
+ {
+ nochange_gen = 0;
+ peak_cnt = count_gener;
+ oldfitvalue=population[1][0];
+ oldfitvalueVEC[0]=population[1][0];
+ k = 1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ oldfitvalueVEC[k]=population[1][i];
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ }
+ else
+ nochange_gen++;
+ break;
+ case 1:
+ LexicalFitsImproving = 0;
+ if ( (oldfitvalue + SolutionTolerance) < population[1][0])
+ {
+ LexicalFitsImproving = 1;
+ }
+ else
+ {
+ k=1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ if ( (oldfitvalueVEC[k] + SolutionTolerance) < population[1][i] ) {
+ LexicalFitsImproving = 1;
+ break;
+ } /* (oldfitvalueVEC[k] - SolutionTolerance) > population[1][i] ) */
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ } /* else if ( (oldfitvalue - SolutionTolerance) > population[1][0]) */
+ if (LexicalFitsImproving)
+ {
+ nochange_gen = 0;
+ peak_cnt = count_gener;
+ oldfitvalue=population[1][0];
+ oldfitvalueVEC[0]=population[1][0];
+ k = 1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ oldfitvalueVEC[k]=population[1][i];
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ }
+ else
+ nochange_gen++;
+ break;
+ } /* switch(MinMax) */
+ } /* else (Structure->Lexical > 2) */
+
+ if(PrintLevel==1)
+ {
+ if( nochange_gen==0 )
+ {
+ if(Structure->Lexical > 1)
+ {
+ Rprintf("\n%7d \t%e ", count_gener, population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf("%7d \t%e\n",
+ count_gener,population[1][0]);
+ /* fflush(output); */
+ }
+ }
+ }
+
+ /* compute and print mean and variance of population */
+ if (PrintLevel>1) {
+ Rprintf("\nGENERATION: %d\n", count_gener);
+ populationstats(population, pop_size, nvars, mean, var, skew, kur, tobs);
+
+ if(Structure->Lexical > 1)
+ {
+ Rprintf( "Lexical Fit..... %e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf( "Fitness value... %e\n", population[1][0]);
+ Rprintf( "mean............ %e\n", mean[0]);
+ Rprintf( "variance........ %e\n", var[0]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ }
+
+ nnull = pop_size-tobs[0];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ if(Structure->MemoryUsage==1)
+ Rprintf( "#unique......... %d, #Total UniqueCount: %d\n",
+ UniqueCount-OldUniqueCount, UniqueCount);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+
+ for (i=1; i<=nvars; i++) {
+ Rprintf( "var %d:\n", i);
+ Rprintf( "best............ %e\n", population[1][i]);
+ Rprintf( "mean............ %e\n", mean[i]);
+ Rprintf( "variance........ %e\n", var[i]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ nnull = pop_size-tobs[i];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+ }
+ } /* end of printlevel if */
+
+ /* if (PrintLevel>0)
+ fflush(output); */
+
+ /* Print the population file */
+ if ( PrintLevel == 1 ) {
+ if((popout = fopen(Structure->ProjectPath, "w")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, (int) count_gener, (int) Structure->Lexical, population, popout);
+ fclose(popout);
+ } /* end of PrintLevel if */
+ if ( PrintLevel>1) {
+ if((popout = fopen(Structure->ProjectPath, "a")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, (int) count_gener, (int) Structure->Lexical, population, popout);
+ fflush(popout);
+ fclose(popout);
+ }
+
+ if (nochange_gen > (WaitGenerations)) {
+ /* increase the number of WaitGenerations if the gradients are NOT zero! */
+ if (GradientCheck==0) {
+ if(PrintLevel>0)
+ {
+ Rprintf("\n'wait.generations' limit reached.\n");
+ Rprintf("No significant improvement in %d generations.\n", nochange_gen-1);
+ /* fflush(output); */
+ }
+ MaxGenerations = 0;
+ nochange_gen=0;
+ }
+ else
+ {
+ for (i=1; i<=nvars; i++)
+ {
+ bfgsoutX[i-1]=population[1][i];
+ }
+ if(Structure->UserGradient==0)
+ {
+ gradient(Structure->fn, Structure->rho,
+ bfgsoutX, grad, nvars, MinMax, BoundaryEnforcement, domains);
+ }
+ else
+ {
+ userGradientfn(Structure->fnGR, Structure->rho, bfgsoutX, grad, nvars);
+ }
+ GradientTrigger = 0;
+ for (i=0; i<nvars; i++) {
+ if (fabs(grad[i]) > SolutionTolerance) {
+ GradientTrigger = 1;
+ break;
+ }
+ } /* end for loop */
+ if (GradientTrigger==1) {
+ IncreaseGenerations = WaitGenerations;
+ WaitGenerations += IncreaseGenerations;
+ if(Structure->BFGSburnin < 0) Structure->BFGSburnin = 0;
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nDoubling 'wait.generations' limit to %d (from %d) ",
+ WaitGenerations, IncreaseGenerations);
+ Rprintf("because at least one gradient is too large.\n");
+ Rprintf("G[%d]: %e\t Solution Tolerance: %e\n\n",
+ i+1, grad[i], SolutionTolerance);
+ }
+ }
+ else {
+ if(PrintLevel>0)
+ {
+ Rprintf("\n'wait.generations' limit reached.\n");
+ Rprintf("No significant improvement in %d generations.\n", nochange_gen-1);
+ /* fflush(output); */
+ }
+ MaxGenerations = 0;
+ nochange_gen=0;
+ }
+ }/* end else loop */
+ } /* end of if (nochange_gen > (WaitGenerations)) { */
+
+ if ( (count_gener == MaxGenerations) && (GradientTrigger==1) )
+ {
+ if (HardGenerationLimit==0)
+ {
+ IncreaseGenerations = MaxGenerations;
+ MaxGenerations += IncreaseGenerations;
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nIncreasing 'max.generations' limit by %d generations to %d ",
+ IncreaseGenerations, MaxGenerations);
+ Rprintf("because at least one gradient is too large.\n\n");
+ }
+ } // if (Structure->HardGenerationLimit==0)
+ else
+ {
+ HardMaximumNumber = 1;
+ warning("Stopped because hard maximum generation limit was hit.\nAt least one gradient is too large.");
+ if(PrintLevel>0)
+ {
+ Rprintf("\nNOTE: HARD MAXIMUM GENERATION LIMIT HIT\n");
+ Rprintf(" At least one gradient is too large\n");
+ }
+ } // else
+ } // if ( (count_gener == MaxGenerations) && (GradientTrigger==1) )
+
+
+ /* increase the number of generations if fitness has been improving */
+ if ( (count_gener == MaxGenerations) && (nochange_gen < WaitGenerations) ) {
+ if (HardGenerationLimit==0)
+ {
+ if (WaitGenerations > MaxGenerations) {
+ IncreaseGenerations = WaitGenerations;
+ MaxGenerations += (int) (IncreaseGenerations);
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nIncreasing 'max.generations' limit by %d generations to %d ",
+ IncreaseGenerations, MaxGenerations);
+ Rprintf("because the fitness is still impoving.\n\n");
+ }
+ }
+ else {
+ IncreaseGenerations = MaxGenerations;
+ MaxGenerations += (int) (IncreaseGenerations);
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nIncreasing 'max.generations' limit by %d generations to %d ",
+ IncreaseGenerations, MaxGenerations);
+ Rprintf("because the fitness is still improving.\n\n");
+ }
+ }
+ } // if (Structure->HardGenerationLimit==0)
+ else
+ {
+ if (HardMaximumNumber==0)
+ {
+ warning("Stopped because hard maximum generation limit was hit.");
+ if(PrintLevel>0)
+ {
+ Rprintf("\nNOTE: HARD MAXIMUM GENERATION LIMIT HIT\n");
+ }
+ } /* end of if HardMax */
+ }
+ } // if ( (count_gener == MaxGenerations) && (nochange_gen < WaitGenerations) )
+
+ /* if(PrintLevel>0)
+ fflush(output); */
+
+ } /* end of do loop */
+ /*Increment iteration count and test whether all generations are done*/
+ while (++count_gener <= MaxGenerations);
+
+ if(PrintLevel>0)
+ {
+ if(Structure->Lexical > 1)
+ {
+ Rprintf("\nSolution Lexical Fitness Value:\n");
+ Rprintf("%e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf("\nSolution Fitness Value: %e\n", population[1][0]);
+ }
+ if (GradientCheck==0 && UseBFGS==0)
+ Rprintf("\nParameters at the Solution:\n\n");
+ else
+ Rprintf("\nParameters at the Solution (parameter, gradient):\n\n");
+ }
+
+ /* output data structure */
+ Structure->oPeakGeneration=peak_cnt;
+ Structure->oGenerations=count_gener-1;
+
+ /* obtain gradients */
+ /* print best solution */
+ if (GradientCheck==0 && UseBFGS==0)
+ {
+ for(j = 1; j <= nvars; j++) {
+ i = j-1;
+ if(PrintLevel>0)
+ Rprintf(" X[%2d] :\t%e\n",j,population[1][j]);
+ grad[i] = -1.0;
+ Results[i] = population[1][j];
+ Gradients[i] = grad[i];
+ }
+ } /* end of if (GradientCheck==0 && UseBFGS==0) */
+ else
+ {
+ for (i=1; i<=nvars; i++)
+ {
+ bfgsoutX[i-1]=population[1][i];
+ }
+ if(Structure->UserGradient==0)
+ {
+ gradient(Structure->fn, Structure->rho,
+ bfgsoutX, grad, nvars, MinMax, BoundaryEnforcement, domains);
+ }
+ else
+ {
+ userGradientfn(Structure->fnGR, Structure->rho, bfgsoutX, grad, nvars);
+ }
+
+ for(j = 1; j <= nvars; j++) {
+ i = j-1;
+ if(PrintLevel>0)
+ Rprintf(" X[%2d] :\t%e\tG[%2d] :\t%e\n",j,population[1][j],j,grad[i]);
+ Results[i] = population[1][j];
+ Gradients[i] = grad[i];
+ }
+ } /* end of else (GradientCheck==0 && UseBFGS==0) */
+
+ Structure->oFitValues[0]=population[1][0];
+ if (Structure->Lexical > 1)
+ {
+ k = 1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ Structure->oFitValues[k]=population[1][i];
+ k++;
+ }
+ }
+
+ /* free memory */
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1 || Structure->Transform == 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+} /* end optimiztion function */
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : sort() */
+/* */
+/* SYNOPSIS : void sort(MinMax, population,pop_size, */
+/* variable) */
+/* */
+/* DESCRIPTION : This function sorts the population, in the */
+/* ascending or the descending order of the */
+/* evaluation function, depending on whether */
+/* it is a maximization or a minimization */
+/* function, respectively. */
+/* */
+/* As an alternative, the sortq function below */
+/* can be used, That sorting function uses */
+/* the quicksort algorithm. */
+/* */
+/* */
+/* FUNCTIONS CALLED : swap() */
+/* */
+/* CALLING FUNCITONS : optimization() */
+/* */
+/********************************************************************************/
+void sort(short int MinMax, MATRIX population, int pop_size,
+ long nvar)
+ /*
+ short int MinMax; Tells whether it is a maximizaiton or a minimization function
+ int pop_size; Population size
+ MATRIX population; Array of population
+ */
+{
+ int i,j;
+
+
+ /*If MinMax is 0 sorts in the descending order, and*/
+ /*if it is 1 sorts in the ascending order*/
+ /*Sorted in ascending or descending order, based on*/
+ /*the evaluated values of each of the agents*/
+ switch(MinMax)
+ {
+ case 0 :
+ for(i=1; i<=pop_size; i++)
+ for(j=i+1; j<=pop_size; j++)
+ if(population[i][nvar] > population[j][nvar])
+ swap(&population[i],&population[j]);
+ break;
+
+ case 1 :
+ for(i=1; i<=pop_size; i++)
+ for(j=i+1; j<=pop_size; j++)
+ if(population[i][nvar] < population[j][nvar])
+ swap(&population[i],&population[j]);
+ break;
+ }
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : swap() */
+/* */
+/* SYNOPSIS : void swap(x,y) */
+/* */
+/* DESCRIPTION : This function interchanges the values of */
+/* x and y. */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : sort() */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+void swap(double **x, double **y)
+ /* double **x,**y; */
+{
+ double *temp;
+
+ temp = *x;
+ *x = *y;
+ *y = temp;
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_parent() */
+/* */
+/* SYNOPSIS : int find_parent(live,pop_size) */
+/* */
+/* DESCRIPTION : This function returns the index of the */
+/* agent in the population, which is to be */
+/* chosen for reproduction. */
+/* */
+/* FUNCTIONS CALLED : irange_ran() */
+/* */
+/* CALLING FUNCITONS : optimization() */
+/* */
+/* */
+/********************************************************************************/
+
+int find_parent(IVECTOR live, int pop_size)
+ /*
+ int pop_size; Population size
+ IVECTOR live; Vector containing the number of times each agent
+ is going to reproduce
+ */
+{
+ int i,temp,t1=0,tot=0;
+
+ /*Finding the total number of parents to reproduce*/
+ for(i=1; i<=pop_size; i++)
+ tot = tot + live[i];
+ if(tot==0)
+ {
+ error("No agents to select");
+ }
+
+ /*Choosing one of them randomly*/
+ temp = irange_ran(1,tot);
+
+ tot = 0;
+ i = 1;
+ do{
+ if(live[i]!=0)
+ t1 = i;
+ tot = tot + live[i++];
+ }while(tot<temp);
+
+ /*Decrementing the number of times the parent chosen is going to reproduce*/
+ // live[t1]--;
+ return(t1);
+}
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : assign_probab() */
+/* */
+/* SYNOPSIS : void assign_probab(probab,pop_size,Q) */
+/* */
+/* DESCRIPTION : This function assigns probability of survival*/
+/* to each of the agents determined by the */
+/* value provided by the user for the */
+/* probability of the best agnet. */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : optimization() */
+/* */
+/* */
+/********************************************************************************/
+
+
+void assign_probab(VECTOR probab, int pop_size, double Q)
+ /*
+ int pop_size; Population size
+ double Q; The probability of survival of the best agent
+ VECTOR probab; Array to contain the probability of survival
+ of each of the agents
+ */
+{
+ int i;
+
+ /* Q, Q(1-Q)^1, Q(1-Q)^2 ... Q(1-Q)^n */
+ for(i=1; i<=pop_size; i++)
+ probab[i] = Q * x_pow_y(1-Q,i-1);
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : x_pow_y() */
+/* */
+/* SYNOPSIS : double x_pow_y(x,y) */
+/* */
+/* DESCRIPTION : This function returns the value of x to the */
+/* power of y. */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : assign_probab() */
+/* */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+double x_pow_y(double x, int y)
+ /*
+ double x;
+ int y;
+ */
+{
+ int i;
+ double tot = 1.0;
+
+ for(i=0; i < y; i++)
+ tot = tot * x;
+ return(tot);
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_cum__probab() */
+/* */
+/* SYNOPSIS : void find_cum__probab(cum_probab,probab, */
+/* pop_size)*/
+/* */
+/* DESCRIPTION : This function finds the cumulative */
+/* probability of each of the agents, from the */
+/* individual probability found earlier. */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : optimization() */
+/* */
+/********************************************************************************/
+
+
+
+void find_cum_probab(VECTOR cum_probab, VECTOR probab, int pop_size)
+ /*
+ int pop_size; Population size
+ VECTOR probab, Individual probability of survival of each of the agent
+ cum_probab; Cumulative probability of survival of each of the agent
+ */
+{
+ int i;
+
+ cum_probab[1] = probab[1];
+
+ for(i=2; i<=pop_size; i++)
+ cum_probab[i] = cum_probab[i-1] + probab[i];
+
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_live() */
+/* */
+/* SYNOPSIS : void find_live(cum_probab,live,pop_size,P4+P5*/
+/* */
+/* DESCRIPTION : This function finds the agents from the */
+/* population, who are going to live - those */
+/* who are going to reproduce, which is done */
+/* based on the cumulative probability of */
+/* survival of each of the agents. */
+/* */
+/* FUNCTIONS CALLED : frange_ran() */
+/* */
+/* CALLING FUNCITONS : optimization() */
+/* */
+/* */
+/********************************************************************************/
+
+
+void find_live(VECTOR cum_probab, IVECTOR live, int pop_size, int P)
+ /*
+ VECTOR cum_probab; Cumulative probability
+ IVECTOR live; Agents that are going to reproduce
+ int pop_size, Population size
+ P; Total number of parents needed to reproduce
+ */
+{
+ double random;
+ int count=0,/*Count of the number of agents chosen to live*/
+ i;
+
+ do
+ {
+ /*Choosing a random cumulative probability*/
+ random = frange_ran(0.0,1.0);
+ i=0;
+ /*Finding the agent with the chosen cumulative probability*/
+ do{
+ i++;
+ }while((random > cum_probab[i]) && (i< pop_size));
+
+ /*Chosing the parent with that probability to reproduce*/
+ if(count < P)
+ {
+ live[i]++;
+ count++;
+ }
+ }while(count < P);
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_die() */
+/* */
+/* SYNOPSIS : void find_die(cum_probab,die,pop_size,P4+P5) */
+/* */
+/* DESCRIPTION : This function finds the agents from the */
+/* population, who are going to die. */
+/* */
+/* FUNCTIONS CALLED : frange_ran() */
+/* */
+/* CALLING FUNCITONS : optimization() */
+/* */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+int find_die(VECTOR cum_probab, IVECTOR die, int pop_size)
+ /*
+ VECTOR cum_probab; Cumulative probability
+ IVECTOR die; Agents that are going to die
+ int pop_size; Population size
+ */
+{
+ double random;
+ int i;
+ int done = FALSE;
+
+ do
+ {
+ /*Choosing a random cumulative probability*/
+ random = frange_ran(0.0,1.0);
+ i=0;
+ /*Finding the agent with the chosen cumulative probability*/
+ do{
+ i++;
+ }
+ while((random > cum_probab[i]) && (i< pop_size));
+
+ /*Chosing the agent to die*/
+ if ((die[pop_size+1-i] == 0) && (i < pop_size))
+ done = TRUE;
+ }
+ while(!done);
+ return(pop_size+1-i);
+}
+
+
+
+void SetRunTimeParameters(struct GND_IOstructure *Structure,
+ short FirstTime,
+ long *PopSize, long *nvars, long *MaxGenerations, long *WaitGenerations,
+ short *MinMax, short *GradientCheck, short *BoundaryEnforcement, short *UseBFGS,
+ double *SolutionTolerance,
+ long *InstanceNumber, long *P, long *P0, long *P1, long *P2, long *P3, long *P4, long *P5,
+ long *P6, long *P7, long *P8, short *PrintLevel,
+ short *HardGenerationLimit)
+{
+ double tP;
+ int i;
+
+ *PopSize=Structure->PopSize;
+ *nvars=Structure->nvars;
+ *MaxGenerations=Structure->MaxGenerations;
+ *WaitGenerations=Structure->WaitGenerations;
+
+ if (FirstTime==1)
+ *HardGenerationLimit=Structure->HardGenerationLimit;
+
+ *MinMax=Structure->MinMax;
+ *GradientCheck=Structure->GradientCheck;
+ *BoundaryEnforcement=Structure->BoundaryEnforcement;
+ *UseBFGS=Structure->UseBFGS;
+ *InstanceNumber=Structure->InstanceNumber;
+
+ *SolutionTolerance=Structure->SolutionTolerance;
+ *PrintLevel=Structure->PrintLevel;
+
+ /* Check to make sure that all operators are positve numbers! */
+ if (Structure->P[0] < 0 ) {
+ warning("Operator 1 (Cloning) was Assigned an Illegal Value: %d.", Structure->P[0]);
+ Structure->P[0]=0.0;
+ }
+ if (Structure->P[1] < 0 ) {
+ warning("Operator 1 (Uniform Mutation) was Assigned an Illegal Value: %d.", Structure->P[1]);
+ Structure->P[1]=0.0;
+ }
+ if (Structure->P[2] < 0 ) {
+ warning("Operator 3 (Boundary Mutation) was Assigned an Illegal Value: %d.", Structure->P[2]);
+ Structure->P[2]=0;
+ }
+ if (Structure->P[3] < 0 ) {
+ warning("Operator 4 (Non-Uniform Mutation) was Assigned an Illegal Value: %d.",
+ Structure->P[3]);
+ Structure->P[3]=0;
+ }
+ if (Structure->P[4] < 0 ) {
+ warning("Operator 5 (Polytope Crossover) was Assigned an Illegal Value: %d.",
+ Structure->P[4]);
+ Structure->P[4]=0;
+ }
+ if (Structure->P[5] < 0 ) {
+ warning("Operator 6 (Simple Crossover) was Assigned an Illegal Value: %d.",
+ Structure->P[5]);
+ Structure->P[5]=0;
+ }
+ if (Structure->P[6] < 0 ) {
+ warning("Operator 7 (Whole Non-Uniform Mutation) was Assigned an Illegal Value: %d.",
+ Structure->P[6]);
+ Structure->P[6]=0;
+ }
+ if (Structure->P[7] < 0 ) {
+ warning("Operator 8 (Heuristic Crossover) was Assigned an Illegal Value: %d.",
+ Structure->P[7]);
+ Structure->P[7]=0;
+ }
+
+ /* if DataType==1 (i.e., integer) we are not giong to use any gradient information etc. */
+ if (Structure->DataType==1) {
+ *UseBFGS=0;
+ *GradientCheck=0;
+
+ if (Structure->P[8] > 0) {
+ warning("Operator 9 (Local-Minimum Crossover) was Assigned an Illegal Value: %d\nThis is an illegal value because we are working with integer data.",
+ Structure->P[8]);
+ Structure->P[8]=0;
+ } /* end of if */
+ }
+ else {
+ if (Structure->P[8] < 0 ) {
+ warning("Operator 9 (Local-Minimum Crossover) was Assigned an Illegal Value: %d.",
+ Structure->P[8]);
+ Structure->P[8]=0;
+ }
+ } /* end of else */
+
+ /* Let's figure out the number of operators we need. Move stuff to absolute space */
+ tP = 0;
+ for (i=0; i<9; i++) {
+ tP = tP + Structure->P[i] ;
+ }
+
+ if (tP > 0) {
+ *P0 = Iround( (Structure->P[0] / tP) * (double) (*PopSize-2) );
+ *P1 = Iround( (Structure->P[1] / tP) * (*PopSize-2) );
+ *P2 = Iround( (Structure->P[2] / tP) * (*PopSize-2) );
+ *P3 = Iround( (Structure->P[3] / tP) * (*PopSize-2) );
+ *P4 = Iround( (Structure->P[4] / tP) * (*PopSize-2) );
+ *P5 = Iround( (Structure->P[5] / tP) * (*PopSize-2) );
+ *P6 = Iround( (Structure->P[6] / tP) * (*PopSize-2) );
+ *P7 = Iround( (Structure->P[7] / tP) * (*PopSize-2) );
+ *P8 = Iround( (Structure->P[8] / tP) * (*PopSize-2) );
+ }
+ else {
+ *P0 = 0;
+ *P1 = 0;
+ *P2 = 0;
+ *P3 = 0;
+ *P4 = 0;
+ *P5 = 0;
+ *P6 = 0;
+ *P7 = 0;
+ *P8 = 0;
+ }
+
+ /* Check to make sure that all operators (i.e., 5, 7) which have to be even numbers are */
+ if (fmod((long double) *P5, (long double) 2) > 0.0) {
+ if(Structure->PrintLevel>2)
+ {
+ Rprintf("\nNOTE: Operator 6 (Simple Crossover) may only be started\n");
+ Rprintf("NOTE: an even number of times. I am increasing this operator by one.\n");
+ }
+ *P5=*P5+1;
+ }
+ if (fmod((long double) *P7, (long double) 2) > 0.0) {
+ if(Structure->PrintLevel>2)
+ {
+ Rprintf("\nNOTE: Operator 8 (Heuristic Crossover) may only be started\n");
+ Rprintf("NOTE: an even number of times. I am increasing this operator by one.\n");
+ }
+ *P7=*P7+1;
+ }
+
+ /*P is the total number of parents needed for applying all the operators*/
+ *P = *P1 + *P2 + *P3 + *P4 + *P5 + *P6 + *P7 + *P8;
+ if(*P > *PopSize)
+ {
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("\nNOTE: The total number of operators greater than population size\n");
+ }
+
+ if (fmod((long double) *P+1, (long double) 2) > 0.0) {
+ *PopSize = *P+2;
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("NOTE: I'm increasing the population size to %d (operators+2).\n", *PopSize);
+ }
+ }
+ else {
+ *PopSize = *P+1;
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("NOTE: I'm increasing the population size to %d (operators+1).\n", *PopSize);
+ }
+ }
+ }
+ else if ( *P== *PopSize) {
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("\nNOTE: The total number of operators equal to the population size\n");
+ }
+
+ if (fmod( (long double) *P+1, (long double) 2) > 0.0) {
+ *PopSize = *P+2;
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("NOTE: I'm increasing the population size to %d (operators+2).\n", *PopSize);
+ }
+ }
+ else {
+ *PopSize = *P+1;
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("NOTE: I'm increasing the population size to %d (operators+1).\n", *PopSize);
+ }
+ }
+ }
+
+ if (fmod( (long double) *PopSize, (long double) 2) > 0.0) {
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("NOTE: population size is not an even number\n");
+ Rprintf(" increasing population size by 1\n");
+ }
+ *PopSize=*PopSize+1;
+ }
+
+ /* return PopSize and P values to the return data structure */
+ *P0 = *PopSize-*P-1;
+ Structure->oP[0]=*P0;
+ Structure->oP[1]=*P1;
+ Structure->oP[2]=*P2;
+ Structure->oP[3]=*P3;
+ Structure->oP[4]=*P4;
+ Structure->oP[5]=*P5;
+ Structure->oP[6]=*P6;
+ Structure->oP[7]=*P7;
+ Structure->oP[8]=*P8;
+ Structure->oPopSize=*PopSize;
+
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf( "\n");
+ if (Structure->DataType==1) Rprintf( "Data Type: Integer\n");
+ else Rprintf( "Data Type: Floating Point\n");
+
+ Rprintf("Operators (code number, name, population) \n");
+ Rprintf("\t(1) Cloning........................... \t%d\n", *P0);
+ Rprintf("\t(2) Uniform Mutation.................. \t%d\n", *P1);
+ Rprintf("\t(3) Boundary Mutation................. \t%d\n", *P2);
+ Rprintf("\t(4) Non-Uniform Mutation.............. \t%d\n", *P3);
+ Rprintf("\t(5) Polytope Crossover................ \t%d\n", *P4);
+ Rprintf("\t(6) Simple Crossover.................. \t%d\n", *P5);
+ Rprintf("\t(7) Whole Non-Uniform Mutation........ \t%d\n", *P6);
+ Rprintf("\t(8) Heuristic Crossover............... \t%d\n", *P7);
+ Rprintf("\t(9) Local-Minimum Crossover........... \t%d\n\n", *P8);
+ if (*HardGenerationLimit==0)
+ Rprintf("SOFT Maximum Number of Generations: %lu\n", *MaxGenerations);
+ else
+ Rprintf("HARD Maximum Number of Generations: %lu\n", *MaxGenerations);
+ Rprintf("Maximum Nonchanging Generations: %lu\n", *WaitGenerations);
+ Rprintf("Population size : %d\n", *PopSize);
+ Rprintf("Convergence Tolerance: %e\n", *SolutionTolerance);
+
+ Rprintf( "\n");
+ if (*UseBFGS !=0) {
+ Rprintf(
+ "Using the BFGS Derivative Based Optimizer on the Best Individual Each Generation.\n");
+ }
+ else {
+ Rprintf(
+ "Not Using the BFGS Derivative Based Optimizer on the Best Individual Each Generation.\n");
+ }
+ if (*GradientCheck==0)
+ Rprintf("Not Checking Gradients before Stopping.\n");
+ else
+ Rprintf("Checking Gradients before Stopping.\n");
+
+ if (*BoundaryEnforcement==0)
+ Rprintf("Using Out of Bounds Individuals.\n\n");
+ else if (*BoundaryEnforcement==1)
+ Rprintf("Not Using Out of Bounds Individuals But Allowing Trespassing.\n\n");
+ else if (*BoundaryEnforcement==2)
+ Rprintf("Not Using Out of Bounds Individuals and Not Allowing Trespassing.\n\n");
+ }
+
+ /* if(Structure->PrintLevel>0)
+ fflush(output); */
+
+} /* End SetOperators */
+
+
+/********************************************************************************/
+/* JaIntegerOptimization: */
+/* */
+/* This function assumes that the X variables are integers. */
+/* */
+/* The cross over operators are different! */
+/* */
+/********************************************************************************/
+
+void JaIntegerOptimization(struct GND_IOstructure *Structure, VECTOR X,
+ MATRIX domains)
+{
+ extern struct GND_IOstructure *ExternStructure;
+
+ MATRIX new_genera, /*Temporary storage for the new generation*/
+ population, /*Population of x2 variables*/
+ temp;
+
+ VECTOR probab, /*Probability of agents to die or live*/
+ cum_probab, /*Cumilative probability of agents*/
+ t_vec;
+
+ IVECTOR live;
+ /* for oper4 */
+ IVECTOR parents;
+
+
+ long count_gener= 1; /*Counter to keep track of the number of generations*/
+ unsigned long peak_cnt;
+
+ int /*Total number of agents chosen to reproduce*/
+ j1,
+ j2,
+ j3,
+ j4,
+ j5,
+ j6,
+ j7,
+ j8,
+ oper,
+ ocnt,
+ B, /*Parameter for the 3rd operator - nonuniform mutation*/
+ STEP, /*Parameter for the 5th operator - simple arithmetical crossover*/
+ first_live=0, /*Index of the two parents for crossover parents*/
+ second_live=0,
+ first_die, /*Index of the two parents for crossover death*/
+ second_die,
+ die_now; /*index of agent to replace in current operation*/
+
+ long i,j, s, k;
+
+ /* for oper 4 */
+ int p2use;
+
+
+ double Q; /*Probability of the best agent*/
+ FLAG same;
+ double **Jnew;
+
+ double *grad, *evalX, *finalhessin, *bfgsoutX;
+
+ int nochange_gen=0;
+
+ double oldfitvalue=0;
+
+ int IncreaseGenerations;
+ short int GradientTrigger=0;
+ long InstanceNumber;
+
+ long nvars, MaxGenerations, WaitGenerations, count;
+ long pop_size, P, P0, P1, P2, P3, P4, P5, P6, P7, P8;
+ short int MinMax, GradientCheck, BoundaryEnforcement, UseBFGS, HardMaximumNumber=0;
+ double SolutionTolerance, *Results, *Gradients;
+ short PrintLevel, HardGenerationLimit;
+
+ /* Old variables which may change when SetRunTimeParameters is run during a run! */
+ long pop_size_old;
+
+ /* Summary Statistics (mean, variance etc) */
+ /* double popmean, popvar, popwrk, popstat; */
+
+ /* Population Print population*/
+ FILE *popout;
+ long *tobs, nnull;
+ double *mean, *var, *skew, *kur;
+
+ /* Stuff for the Unique Stuff (how's that for an informative comment! */
+ /* A big Matrix which remembers all of our past evaluations. It's
+ maximum memory is set in genoud.h */
+ extern long Gnvars[MAXINSTANCES];
+ double **Memory;
+ long MemorySize=0, UniqueCount=0, OldUniqueCount=0;
+
+ /* fine two unique parents count */
+ long SameCount, UniquePairs;
+
+ ExternStructure=Structure;
+
+ Results=Structure->oResults;
+ Gradients=Structure->oGradients;
+
+ /* Structure Done */
+ SetRunTimeParameters(Structure, 1,
+ &pop_size, &nvars, &MaxGenerations, &WaitGenerations,
+ &MinMax, &GradientCheck, &BoundaryEnforcement, &UseBFGS, &SolutionTolerance,
+ &InstanceNumber, &P, &P0, &P1, &P2, &P3, &P4, &P5, &P6, &P7, &P8,
+ &PrintLevel, &HardGenerationLimit);
+
+ /*Space allocation for all the vectors and matrices involved*/
+ long lexical_end = (Structure->Lexical-1)+nvars+2;
+ /* population[][0] = fitness value (first)
+ population[][1:nvars] = parameter values
+ population[][nvars+1] = flag for fitting
+ population[][(nvars+2):((Structure->Lexical-1)+nvars+2)] = other fitness for Lexical fitting
+ */
+ population = JaMatrixAllocate(pop_size+2, lexical_end);
+ new_genera = JaMatrixAllocate(pop_size+2, lexical_end);
+
+ /* reset population to get rid of odd things being passed to R */
+ for(i=1; i<=pop_size; i++)
+ {
+ for(j=0; j<lexical_end; j++)
+ {
+ population[i][j] = 0;
+ }
+ }
+
+ VECTOR LexicalReturn;
+ VECTOR oldfitvalueVEC;
+ short int LexicalFitsImproving;
+ if(Structure->Lexical > 1)
+ {
+ LexicalReturn = (double *) malloc(Structure->Lexical*sizeof(double));
+ oldfitvalueVEC = (double *) malloc(Structure->Lexical*sizeof(double));
+ }
+
+ temp = matrix(0,nvars+1,0,nvars);
+ probab = Gvector(1,pop_size);
+ t_vec = Gvector(1,nvars);
+ cum_probab = Gvector(1,pop_size);
+ live = ivector(1,pop_size);
+
+ /*for oper4 Find max(2,nvars) parents for crossover operator 4*/
+ p2use = nvars > 2 ? nvars : 2;
+ parents = ivector(1,p2use);
+
+ Gnvars[Structure->InstanceNumber]=nvars;
+
+ if (Structure->MemoryUsage==1)
+ {
+ if (HardGenerationLimit==0)
+ MemorySize=3*(MaxGenerations+1)*pop_size+1+pop_size;
+ else
+ MemorySize=(MaxGenerations+1)*pop_size+1+pop_size;
+
+ Memory = JaMatrixAllocate(MemorySize, lexical_end);
+ }
+
+ grad = (double *) malloc((nvars)*sizeof(double));
+ evalX = (double *) malloc((nvars)*sizeof(double));
+ finalhessin = (double *) malloc(((nvars*nvars)+(nvars))*sizeof(double));
+ bfgsoutX = (double *) malloc((nvars+1)*sizeof(double));
+
+ /* populationstats variables */
+ mean = (double *) malloc((nvars+1)*sizeof(double));
+ var = (double *) malloc((nvars+1)*sizeof(double));
+ skew = (double *) malloc((nvars+1)*sizeof(double));
+ kur = (double *) malloc((nvars+1)*sizeof(double));
+ tobs = (long *) malloc((nvars+1)*sizeof(long));
+
+ /* JS: Integer Q was different, why? Q=0.2; */
+ Q=0.5;
+ B=6;
+ STEP=10;
+
+ if(PrintLevel>0)
+ {
+ switch(MinMax) {
+ case 0:
+ Rprintf("Minimization Problem.\n");
+ break;
+ case 1:
+ Rprintf("Maximization Problem.\n");
+ break;
+ }
+ }
+
+ /*
+ if (PrintLevel>2) {
+ Rprintf("Parameter B (hardcoded): %d\n", B);
+ Rprintf("Parameter Q (hardcoded): %f\n", Q);
+ }
+ */
+
+ peak_cnt = 0;
+
+ pop_size_old=0;
+ if (Structure->ShareType == 1 || Structure->ShareType == 3) {
+
+ if(PrintLevel>0)
+ Rprintf( "Using old population file to initialize new population\n");
+
+ if((popout = fopen(Structure->ProjectPath, "r")) == NULL) {
+ Rprintf(" Generating new population\n");
+ warning("Unable to open the old project file: %s", Structure->ProjectPath);
+ }
+ else {
+ pop_size_old=ReadPopulation(population, pop_size, nvars, popout, PrintLevel);
+ fclose(popout);
+
+ for (i=1; i<=pop_size; i++) {
+ for (j=1; j<=nvars; j++) {
+ population[i][j] = (int) population[i][j];
+ }
+ }
+
+ if (pop_size_old<2) {
+ warning("The old population file appears to be from a different genoud specification.");
+ pop_size_old=0;
+ }
+ }
+ if (PrintLevel>1) {
+ if((popout = fopen(Structure->ProjectPath, "a")) == NULL) {
+ warning("Unable to open the project file: %s", Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ fclose(popout);
+ }
+ } /* end of ShareType 0 */
+ else {
+ if (PrintLevel>1) {
+ if((popout = fopen(Structure->ProjectPath, "w")) == NULL) {
+ warning("Unable to open the project file: %s", Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ fclose(popout);
+ }
+ }
+
+ /* The new initial value matrix: setting a new initial value for every individual */
+ if (ExternStructure->nStartingValues > 0)
+ {
+ /* Adjust old starting values (from ReadPopulation) so we have enough room for our
+ starting.values */
+ pop_size_old = pop_size_old-ExternStructure->nStartingValues-1;
+ if (pop_size_old < 0)
+ pop_size_old = 0;
+
+ // seed the starting values until we run out of population or starting values!
+ j = pop_size_old;
+
+ for(s=0; s<ExternStructure->nStartingValues; s++) {
+ j++;
+ for(i=1; i<=nvars; i++) {
+ population[j][i] = (int) ExternStructure->StartingValues[s][i-1];
+ population[j][nvars+1] = -1.0;
+ }
+ } // end of for loop
+ pop_size_old = j;
+
+ // randomly add on people if we still have population left over!
+ for(j=pop_size_old+1; j<=pop_size; j++) {
+ for(i=1; i<=nvars; i++) {
+ population[j][i] = (int) frange_ran(domains[i][1], domains[i][3]);
+ population[j][nvars+1] = -1.0;
+ }
+ }
+ } // end of we have starting values!
+ else
+ {
+ for(j=pop_size_old+1; j<=pop_size; j++) {
+ for(i=1; i<=nvars; i++) {
+ population[j][i] = (int) frange_ran(domains[i][1], domains[i][3]);
+ population[j][nvars+1] = -1.0;
+ }
+ }
+ } // end of else
+
+
+ if (Structure->MemoryUsage==1)
+ {
+ OldUniqueCount=UniqueCount;
+
+ if (UniqueCount==0)
+ UniqueCount = 1;
+
+ UniqueCount = RmemoryMatrixEvaluate(Structure->fnMemoryMatrixEvaluate, Structure->rho,
+ Memory, population,
+ MinMax, pop_size, UniqueCount,
+ nvars, Structure->Lexical, lexical_end);
+
+ if ( (UniqueCount+pop_size) >= MemorySize )
+ {
+ Structure->MemoryUsage=0;
+ warning("Turned Off MemoryMatrix because memory usage was too great.");
+ } /* end of if */
+ } // end of Memory based evaluation
+ else
+ {
+ for (i=1; i<=pop_size; i++)
+ {
+ if (population[i][nvars+1]==-1.0 || population[i][nvars+1]==11.0)
+ {
+ for(j=1; j<=nvars; j++)
+ X[j] = population[i][j];
+
+ if (Structure->Lexical < 2)
+ {
+ population[i][0] = evaluate(Structure->fn, Structure->rho, X, nvars, MinMax);
+ }
+ else
+ {
+ EvaluateLexical(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+
+ population[i][0] = LexicalReturn[0];
+ count = 0;
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ count++;
+ population[i][j] = LexicalReturn[count];
+ }
+ } // else
+ }
+ } //end of i loop
+ } // end of default evaluation
+
+ if(Structure->MemoryUsage!=1)
+ {
+ /*Sort the initial individuals based on their evaluation function*/
+ if (Structure->Lexical < 2)
+ {
+ sort(MinMax,population,pop_size,0);
+ }
+ else
+ {
+ /* in eval.cpp because it is like the EvaluateLexical() function */
+ RlexicalSort(Structure->fnLexicalSort, Structure->rho,
+ population,
+ MinMax, pop_size, nvars, lexical_end, 1);
+ }
+ }
+
+ peak_cnt = count_gener;
+
+ /* since we are on generation 0 */
+ oldfitvalue=population[1][0];
+ if(Structure->Lexical > 1)
+ {
+ oldfitvalueVEC[0]=population[1][0];
+ k = 1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ oldfitvalueVEC[k]=population[1][i];
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ }
+
+ /*
+ if(PrintLevel>0)
+ {
+ Rprintf("\nThe best initial individual is:\n");
+ print_vector(population[1],1,nvars,output);
+
+ if (Structure->Lexical > 1)
+ {
+ Rprintf("\nbest (lexical) fitness:\n");
+ Rprintf("%e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ } else {
+ Rprintf("\nbest fitness: %e\n", population[1][0]);
+ }
+ Rprintf("\n");
+
+ if (Structure->Lexical > 1)
+ {
+ Rprintf("The worst (lexical) fitness is:\n");
+ Rprintf("%e ", population[pop_size][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[pop_size][j]);
+ }
+ Rprintf("\n");
+ } else {
+ Rprintf("The worst fit is: %e\n",
+ population[pop_size][0]);
+ }
+ Rprintf("\n");
+ }
+ */
+
+ if(PrintLevel==1)
+ {
+ if (Structure->Lexical > 1)
+ {
+ Rprintf("\n\nGeneration#\t Solution Values (lexical)\n");
+ Rprintf("\n%7d \t%e ", 0, population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ } else {
+ Rprintf("\n\nGeneration#\t Solution Value\n");
+ Rprintf("\n%7d \t%e\n", 0, population[1][0]);
+ }
+ }
+
+ /* compute and print mean and variance of population */
+ if (PrintLevel>1) {
+ Rprintf("GENERATION: 0 (initializing the population)\n");
+ populationstats(population, pop_size, nvars, mean, var, skew, kur, tobs);
+
+ if(Structure->Lexical > 1)
+ {
+ Rprintf( "Lexical Fit..... %e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf( "Fitness value... %e\n", population[1][0]);
+ Rprintf( "mean............ %e\n", mean[0]);
+ Rprintf( "variance........ %e\n", var[0]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ }
+ nnull = pop_size-tobs[0];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ if(Structure->MemoryUsage==1)
+ Rprintf( "#unique......... %d, #Total UniqueCount: %d\n",
+ UniqueCount-OldUniqueCount, UniqueCount);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+
+ for (i=1; i<=nvars; i++) {
+ Rprintf( "var %d:\n", i);
+ Rprintf( "best............ %e\n", population[1][i]);
+ Rprintf( "mean............ %e\n", mean[i]);
+ Rprintf( "variance........ %e\n", var[i]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ nnull = pop_size-tobs[i];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+ }
+ } /* end of printlevel if */
+
+ /* if(PrintLevel>0)
+ fflush(output); */
+
+ /* Print the population file */
+ if ( PrintLevel == 1 ) {
+ if((popout = fopen(Structure->ProjectPath, "w")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, 0, (int) Structure->Lexical, population, popout);
+ fclose(popout);
+ } /* end of PrintLevel if */
+ if ( PrintLevel>1) {
+ if((popout = fopen(Structure->ProjectPath, "a")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, 0, (int) Structure->Lexical, population, popout);
+ fflush(popout);
+ fclose(popout);
+ }
+
+ /* Interrupt setup. Let's print a nice message to recover the best
+ solution so far if at least generation 0 has been run */
+ if (PrintLevel > 0 & (strcmp(Structure->ProjectPath, "/dev/null")!=0))
+ setVar(install("interrupted"), ScalarLogical(1), Structure->rho);
+
+ /*Assigning probability of survival for each of the agent, with the*/
+ /*probability provided by the user for the best agent*/
+ assign_probab(probab,pop_size,Q);
+
+ /*Finding the cumulative probability of the agents*/
+ find_cum_probab(cum_probab,probab,pop_size);
+
+ /*Reproducing and evaluating for the total number of generations times*/
+ do
+ {
+
+ /*Initializing the live vector*/
+ for(j=1; j<=pop_size; j++)
+ {
+ live[j] = 0;
+ for(i=0; i<lexical_end; i++)
+ new_genera[j][i] = population[j][i];
+ new_genera[j][nvars+1]=0;
+ }
+
+ /*Finding the agents that will die and the agents that will reproduce*/
+ find_live(cum_probab,live,pop_size,P);
+ /* set die_now counter to start replacements with the worst agent.
+ use of die_now is okay if the entire population (except the previous
+ best) is to be replaced in each generation */
+ die_now = pop_size;
+
+ j1=j2=j3=j4=j5=j6=j7=j8=0;
+
+ /* This was causing a difference to appear between MemoryMatrix and !MemoryMatrix runs see oper5 and oper7
+ UniquePairs= UniqueCount-OldUniqueCount;
+ UniquePairs= (int) (0.5*(UniquePairs*UniquePairs-UniquePairs));
+ if ( MAX_OPER_UNIQUE_TRY < UniquePairs)
+ UniquePairs = MAX_OPER_UNIQUE_TRY;
+ */
+ UniquePairs = MAX_OPER_UNIQUE_TRY;
+
+ /* main operator loop */
+ while(j1+j2+j3+j4+j4+j5+j5+j6+j7+j7 < P)
+ {
+ oper = irange_ran(1,7);
+ switch (oper)
+ {
+ case 1:
+ /* JS Description: Uniform Mutation */
+ /*Applying the first operator, uniform mutation*/
+ if (j1 < P1)
+ {
+ /*Find one parent for mutation operator 1*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error("No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 1.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ for (ocnt = irange_ran(1,nvars); ocnt>0; ocnt--)
+ JaIntegerOper1(t_vec,domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j1++;
+ }
+ break;
+ case 2:
+ /* JS Description: Boundary Mutation */
+ /*Applying the second operator, boundary mutation*/
+ if (j2 < P2)
+ {
+ /*Find one parent for mutation operator 2*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 2.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ JaIntegerOper2(t_vec,domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j2++;
+ }
+ break;
+ case 3:
+ /* JS Description: Non-uniform Mutation */
+ /*Applying the third operator, non-uniform mutation*/
+ if (j3 < P3)
+ {
+ /*Find one parent for mutation operator 3*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 3.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ for (ocnt = irange_ran(1,nvars); ocnt>0; ocnt--)
+ JaIntegerOper3(t_vec,domains,nvars,MaxGenerations,count_gener,B);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j3++;
+ }
+ break;
+
+ case 4:
+ /*Applying the fourth operator, GENOUD Polytope Crossover */
+ if (j4 < (int) P4)
+ {
+ /*Find max(2,nvars) parents for crossover operator 4*/
+ for (i=1; i<p2use; i++) {
+ parents[i] = find_parent(live,pop_size);
+ live[parents[i]]++; /* no decr. first p2use-1 parents */
+ }
+ parents[p2use] = find_parent(live,pop_size);
+ /* check that agents to replace are in range */
+ if (die_now < 2) {
+ error("No agents to be replaced\n");
+ }
+ new_genera[die_now][nvars+1] = 4.0;
+ for(j=1; j<=p2use; j++)
+ for(i=1; i<=nvars; i++)
+ temp[j][i] = population[parents[j]][i];
+ JaIntegeroper4(temp,p2use,nvars,domains);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = temp[1][i];
+ die_now--;
+ j4++;
+ }
+ break;
+ case 5:
+ /* JS Description: Simple Crossover
+ Applying the fifth operator, simple arithmetical crossover*/
+ if (j5 < (int) P5/2)
+ {
+ /*Find two distinct parents for crossover operator 5*/
+ same = TRUE;
+ SameCount=0;
+ while (same==TRUE) {
+ SameCount++;
+
+ first_live = find_parent(live,pop_size);
+ second_live = find_parent(live,pop_size);
+
+ if (SameCount >= (UniquePairs) )
+ break;
+
+ for(i=1; i<=nvars; i++)
+ {
+ if ((int) population[first_live][i] != (int) population[second_live][i])
+ {
+ same = FALSE;
+ break;
+ }
+ }
+ } /* end of while same==TRUE loop */
+ /* check that agents to replace are in range */
+ if (die_now < 3) {
+ error("Not enough agents to be replaced\n");
+ }
+ live[first_live]--;
+ live[second_live]--;
+ first_die = die_now-- ;
+ second_die = die_now-- ;
+ new_genera[first_die][nvars+1] = 5.0;
+ new_genera[second_die][nvars+1] = 5.0;
+ if (!same)
+ {
+ for(i=1; i<=nvars; i++)
+ {
+ temp[1][i] = population[first_live][i];
+ temp[2][i] = population[second_live][i];
+ }
+ JaIntegerOper5(temp[1],temp[2],STEP,domains,nvars);
+ for(i=1; i<=nvars; i++)
+ {
+ new_genera[first_die][i] = temp[1][i];
+ new_genera[second_die][i] = temp[2][i];
+ }
+ }
+ else {
+ /* copy agent chosen twice into two new indivs */
+ for(i=1; i<=nvars; i++) {
+ new_genera[first_die][i] =
+ population[first_live][i];
+ new_genera[second_die][i] =
+ population[second_live][i];
+ }
+ }
+ j5++;
+ }
+ break;
+ case 6:
+ /* JS Description: Whole Non-uniform Mutation */
+ /*Applying the sixth operator, whole non-uniform mutation*/
+ if (j6 < P6)
+ {
+ /*Find one parent for mutation operator 6*/
+ first_live = find_parent(live,pop_size);
+ live[first_live]--;
+ /* check that agent to replace is in range */
+ if (die_now < 2) {
+ error( "No agents to be replaced\n");
+ }
+
+ new_genera[die_now][nvars+1] = 6.0;
+ for(i=1; i<=nvars; i++)
+ t_vec[i] = population[first_live][i];
+ JaIntegerOper6(t_vec,domains,nvars,MaxGenerations,count_gener,B);
+ for(i=1; i<=nvars; i++)
+ new_genera[die_now][i] = t_vec[i];
+ die_now--;
+ j6++;
+ }
+ break;
+ case 7:
+ /* JS Description: Heuristic Crossover */
+ /*Applying the seventh operator*/
+ if (j7 < (int) P7/2)
+ {
+ /*Find two distinct parents for operator 7*/
+ same = TRUE;
+ SameCount=0;
+ while (same==TRUE) {
+ SameCount++;
+ first_live = find_parent(live,pop_size);
+ second_live = find_parent(live,pop_size);
+
+ if (SameCount >= (UniquePairs) )
+ break;
+
+ for(i=1; i<=nvars; i++)
+ {
+ if ((int) population[first_live][i] != (int) population[second_live][i])
+ {
+ same = FALSE;
+ break;
+ }
+ }
+ } /* end of while same==TRUE loop */
+ /* check that agents to replace are in range */
+ if (die_now < 3) {
+ error("Not enough agents to be replaced\n");
+ }
+ live[first_live]--;
+ live[second_live]--;
+ first_die = die_now-- ;
+ second_die = die_now-- ;
+ new_genera[first_die][nvars+1] = 7.0;
+ new_genera[second_die][nvars+1] = 7.0;
+ if (!same) {
+ if (first_live < second_live)
+ /* first agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[first_live][i];
+ temp[1][i] = population[second_live][i];
+ }
+ else
+ /* second agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[second_live][i];
+ temp[1][i] = population[first_live][i];
+ }
+ JaIntegerOper7(temp[1],temp[2],domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[first_die][i] = temp[1][i];
+ if (first_live < second_live)
+ /* first agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[first_live][i];
+ temp[1][i] = population[second_live][i];
+ }
+ else
+ /* second agent is better agent */
+ for(i=1; i<=nvars; i++) {
+ temp[2][i] = population[second_live][i];
+ temp[1][i] = population[first_live][i];
+ }
+ JaIntegerOper7(temp[1],temp[2],domains,nvars);
+ for(i=1; i<=nvars; i++)
+ new_genera[second_die][i] = temp[1][i];
+ }
+ else {
+ /* copy agent chosen twice into two new indivs */
+ for(i=1; i<=nvars; i++) {
+ new_genera[first_die][i] =
+ population[first_live][i];
+ new_genera[second_die][i] =
+ population[second_live][i];
+ }
+ }
+ j7++;
+ }
+ }
+ }
+
+ /*Replace the population with the new generation */
+ Jnew = new_genera;
+ new_genera = population;
+ population = Jnew;
+
+ if (Structure->MemoryUsage==1)
+ {
+ OldUniqueCount=UniqueCount;
+
+ UniqueCount = RmemoryMatrixEvaluate(Structure->fnMemoryMatrixEvaluate, Structure->rho,
+ Memory, population,
+ MinMax, pop_size, UniqueCount,
+ nvars, Structure->Lexical, lexical_end);
+
+ if ( (UniqueCount+pop_size) >= MemorySize )
+ {
+ Structure->MemoryUsage=0;
+ warning("Turned Off MemoryMatrix because memory usage was too great.");
+ } /* end of if */
+ } // end of MemoryUsage==1
+ else
+ {
+ for (i=1; i<=pop_size; i++)
+ {
+ if (population[i][nvars+1]!=0)
+ {
+ for(j=1; j<=nvars; j++)
+ X[j] = population[i][j];
+
+ if (Structure->Lexical < 2)
+ {
+ population[i][0] = evaluate(Structure->fn, Structure->rho, X, nvars, MinMax);
+ }
+ else
+ {
+ EvaluateLexical(Structure->fn, Structure->rho,
+ X, nvars, Structure->Lexical, MinMax, LexicalReturn);
+ population[i][0] = LexicalReturn[0];
+ count = 0;
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ count++;
+ population[i][j] = LexicalReturn[count];
+ }
+ }
+ }
+ } //end of i loop
+ } //end of default evaluation scheme
+
+ if(Structure->MemoryUsage!=1)
+ {
+ /*Sort the new population based on their evaluation function*/
+ if (Structure->Lexical < 2)
+ {
+ sort(MinMax,population,pop_size,0);
+ }
+ else
+ {
+ /* in eval.cpp because it is like the EvaluateLexical() function */
+ RlexicalSort(Structure->fnLexicalSort, Structure->rho,
+ population,
+ MinMax, pop_size, nvars, lexical_end, 1);
+ }
+ }
+
+ /* check to see if fit is improving */
+ if(Structure->Lexical < 2)
+ {
+ switch(MinMax)
+ {
+ case 0:
+ if ( (oldfitvalue - SolutionTolerance) > population[1][0]) {
+ nochange_gen=0;
+ oldfitvalue=population[1][0];
+ peak_cnt = count_gener;
+ }
+ else nochange_gen++;
+ break;
+ case 1:
+ if ( (oldfitvalue + SolutionTolerance) < population[1][0]) {
+ nochange_gen=0;
+ oldfitvalue=population[1][0];
+ peak_cnt = count_gener;
+ }
+ else nochange_gen++;
+ break;
+ }
+ } /* if(Structure->Lexical < 2) */
+ else
+ {
+ switch(MinMax)
+ {
+ case 0:
+ LexicalFitsImproving = 0;
+ if ( (oldfitvalue - SolutionTolerance) > population[1][0])
+ {
+ LexicalFitsImproving = 1;
+ }
+ else
+ {
+ k=1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ if ( (oldfitvalueVEC[k] - SolutionTolerance) > population[1][i] ) {
+ LexicalFitsImproving = 1;
+ break;
+ } /* (oldfitvalueVEC[k] - SolutionTolerance) > population[1][i] ) */
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ } /* else if ( (oldfitvalue - SolutionTolerance) > population[1][0]) */
+ if (LexicalFitsImproving)
+ {
+ nochange_gen = 0;
+ peak_cnt = count_gener;
+ oldfitvalue=population[1][0];
+ oldfitvalueVEC[0]=population[1][0];
+ k=1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ oldfitvalueVEC[k]=population[1][i];
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ }
+ else
+ nochange_gen++;
+ break;
+ case 1:
+ LexicalFitsImproving = 0;
+ if ( (oldfitvalue + SolutionTolerance) < population[1][0])
+ {
+ LexicalFitsImproving = 1;
+ }
+ else
+ {
+ k=1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ if ( (oldfitvalueVEC[k] + SolutionTolerance) < population[1][i] ) {
+ LexicalFitsImproving = 1;
+ break;
+ } /* (oldfitvalueVEC[k] - SolutionTolerance) > population[1][i] ) */
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ } /* else if ( (oldfitvalue - SolutionTolerance) > population[1][0]) */
+ if (LexicalFitsImproving)
+ {
+ nochange_gen = 0;
+ peak_cnt = count_gener;
+ oldfitvalue=population[1][0];
+ oldfitvalueVEC[0]=population[1][0];
+ k=1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ oldfitvalueVEC[k]=population[1][i];
+ k++;
+ } /* for (i=(nvars+2);i<lexical_end;i++) */
+ }
+ else
+ nochange_gen++;
+ break;
+ } /* switch(MinMax) */
+ } /* else (Structure->Lexical > 2) */
+
+
+ if(PrintLevel==1)
+ {
+ if( nochange_gen==0 )
+ {
+ if(Structure->Lexical > 1)
+ {
+ Rprintf("\n%7d \t%e ", count_gener, population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf("%7d \t%e\n",
+ count_gener,population[1][0]);
+ /* fflush(output); */
+ }
+ }
+ }
+
+ /* compute and print mean and variance of population */
+ if (PrintLevel>1) {
+ Rprintf("\nGENERATION: %d\n", count_gener);
+ populationstats(population, pop_size, nvars, mean, var, skew, kur, tobs);
+
+ if(Structure->Lexical > 1)
+ {
+ Rprintf( "Lexical Fit..... %e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf( "Fitness value... %e\n", population[1][0]);
+ Rprintf( "mean............ %e\n", mean[0]);
+ Rprintf( "variance........ %e\n", var[0]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ }
+
+ nnull = pop_size-tobs[0];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ if(Structure->MemoryUsage==1)
+ Rprintf( "#unique......... %d, #Total UniqueCount: %d\n",
+ UniqueCount-OldUniqueCount, UniqueCount);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+
+ for (i=1; i<=nvars; i++) {
+ Rprintf( "var %d:\n", i);
+ Rprintf( "best............ %e\n", population[1][i]);
+ Rprintf( "mean............ %e\n", mean[i]);
+ Rprintf( "variance........ %e\n", var[i]);
+ /*
+ Rprintf( "skewness........ %e\n", skew[i]);
+ Rprintf( "kurtosis........ %e\n", kur[i]);
+ */
+ nnull = pop_size-tobs[i];
+ if(nnull > 0)
+ Rprintf( "#null........... %d\n", nnull);
+ /* Rprintf( "tobs............ %d\n", tobs[i]); */
+ }
+ } /* end of printlevel if */
+
+ /* if (PrintLevel>0)
+ fflush(output); */
+
+ /* Print the population file */
+ if ( PrintLevel == 1 ) {
+ if((popout = fopen(Structure->ProjectPath, "w")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, (int) count_gener, (int) Structure->Lexical, population, popout);
+ fclose(popout);
+ } /* end of PrintLevel if */
+ if ( PrintLevel>1) {
+ if((popout = fopen(Structure->ProjectPath, "a")) == NULL) {
+ Rprintf("Unable to open the project file: %s",
+ Structure->ProjectPath);
+
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ /* free numeric.c allocations */
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+
+ error("Fatal Error. See output for diagnostic information.");
+ }
+ print_population((int) pop_size, (int) nvars, (int) count_gener, (int) Structure->Lexical, population, popout);
+ fflush(popout);
+ fclose(popout);
+ }
+
+ if (nochange_gen > (WaitGenerations)) {
+ /* increase the number of WaitGenerations if the gradients are NOT zero! */
+ if (GradientCheck==0) {
+ if(PrintLevel>0)
+ {
+ Rprintf("\n'wait.generations' limit reached.\n");
+ Rprintf("No significant improvement in %d generations.\n", nochange_gen-1);
+ /* fflush(output); */
+ }
+ MaxGenerations = 0;
+ nochange_gen=0;
+ }
+ else
+ {
+ for (i=1; i<=nvars; i++)
+ {
+ bfgsoutX[i-1]=population[1][i];
+ }
+ if(Structure->UserGradient==0)
+ {
+ gradient(Structure->fn, Structure->rho,
+ bfgsoutX, grad, nvars, MinMax, BoundaryEnforcement, domains);
+ }
+ else
+ {
+ userGradientfn(Structure->fnGR, Structure->rho, bfgsoutX, grad, nvars);
+ }
+ GradientTrigger = 0;
+ for (i=0; i<nvars; i++) {
+ if (fabs(grad[i]) > SolutionTolerance) {
+ GradientTrigger = 1;
+ break;
+ }
+ } /* end for loop */
+ if (GradientTrigger==1) {
+ IncreaseGenerations = WaitGenerations;
+ WaitGenerations += IncreaseGenerations;
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nDoubling 'wait.generations' limit to %d (from %d) ",
+ WaitGenerations, IncreaseGenerations);
+ Rprintf("because at least one gradient is too large.\n");
+ Rprintf("G[%d]: %e\t Solution Tolerance: %e\n\n",
+ i+1, grad[i], SolutionTolerance);
+ }
+ }
+ else {
+ if(PrintLevel>0)
+ {
+ Rprintf("\n'wait.generations' limit reached.\n");
+ Rprintf("No significant improvement in %d generations.\n", nochange_gen-1);
+ /* fflush(output); */
+ }
+ MaxGenerations = 0;
+ nochange_gen=0;
+ }
+ }/* end else loop */
+ } /* end of if (nochange_gen > (WaitGenerations)) { */
+
+ if ( (count_gener == MaxGenerations) && (GradientTrigger==1) )
+ {
+ if (HardGenerationLimit==0)
+ {
+ IncreaseGenerations = MaxGenerations;
+ MaxGenerations += IncreaseGenerations;
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nIncreasing 'max.generations' limit by %d generations to %d ",
+ IncreaseGenerations, MaxGenerations);
+ Rprintf("because at least one gradient is too large.\n\n");
+ }
+ } // if (Structure->HardGenerationLimit==0)
+ else
+ {
+ HardMaximumNumber = 1;
+ warning("Stopped because hard maximum generation limit was hit.\nAt least one gradient is too large.");
+ if(PrintLevel>0)
+ {
+ Rprintf("\nNOTE: HARD MAXIMUM GENERATION LIMIT HIT\n");
+ Rprintf(" At least one gradient is too large\n");
+ }
+ } // else
+ } // if ( (count_gener == MaxGenerations) && (GradientTrigger==1) )
+
+
+ /* increase the number of generations if fitness has been improving */
+ if ( (count_gener == MaxGenerations) && (nochange_gen < WaitGenerations) ) {
+ if (HardGenerationLimit==0)
+ {
+ if (WaitGenerations > MaxGenerations) {
+ IncreaseGenerations = WaitGenerations;
+ MaxGenerations += (int) (IncreaseGenerations);
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nIncreasing 'max.generations' limit by %d generations to %d ",
+ IncreaseGenerations, MaxGenerations);
+ Rprintf("because the fitness is still impoving.\n\n");
+ }
+ }
+ else {
+ IncreaseGenerations = MaxGenerations;
+ MaxGenerations += (int) (IncreaseGenerations);
+ if(PrintLevel>0)
+ {
+ Rprintf(
+ "\nIncreasing 'max.generations' limit by %d generations to %d ",
+ IncreaseGenerations, MaxGenerations);
+ Rprintf("because the fitness is still improving.\n\n");
+ }
+ }
+ } // if (Structure->HardGenerationLimit==0)
+ else
+ {
+ if (HardMaximumNumber==0)
+ {
+ warning("Stopped because hard maximum generation limit was hit.");
+ if(PrintLevel>0)
+ {
+ Rprintf("\nNOTE: HARD MAXIMUM GENERATION LIMIT HIT\n");
+ }
+ } /* end of if HardMax */
+ }
+ } // if ( (count_gener == MaxGenerations) && (nochange_gen < WaitGenerations) )
+
+ /* if(PrintLevel>0)
+ fflush(output); */
+
+ } /* end of do loop */
+ /*Increment iteration count and test whether all generations are done*/
+ while (++count_gener <= MaxGenerations);
+
+ if(PrintLevel>0)
+ {
+ if(Structure->Lexical > 1)
+ {
+ Rprintf("\nSolution Lexical Fitness Value:\n");
+ Rprintf("%e ", population[1][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ Rprintf("%e ", population[1][j]);
+ }
+ Rprintf("\n");
+ }
+ else
+ {
+ Rprintf("\nSolution Fitness Value: %e\n", population[1][0]);
+ }
+ if (GradientCheck==0 && UseBFGS==0)
+ Rprintf("\nParameters at the Solution:\n\n");
+ else
+ Rprintf("\nParameters at the Solution (parameter, gradient):\n\n");
+ }
+
+ /* output data structure */
+ Structure->oPeakGeneration=peak_cnt;
+ Structure->oGenerations=count_gener-1;
+
+ /* obtain gradients */
+ /* print best solution */
+ if (GradientCheck==0 && UseBFGS==0)
+ {
+ for(j = 1; j <= nvars; j++) {
+ i = j-1;
+ if(PrintLevel>0)
+ Rprintf(" X[%2d] :\t%e\n",j,population[1][j]);
+ grad[i] = -1.0;
+ Results[i] = population[1][j];
+ Gradients[i] = grad[i];
+ }
+ } /* end of if (GradientCheck==0 && UseBFGS==0) */
+ else
+ {
+ for (i=1; i<=nvars; i++)
+ {
+ bfgsoutX[i-1]=population[1][i];
+ }
+ if(Structure->UserGradient==0)
+ {
+ gradient(Structure->fn, Structure->rho,
+ bfgsoutX, grad, nvars, MinMax, BoundaryEnforcement, domains);
+ }
+ else
+ {
+ userGradientfn(Structure->fnGR, Structure->rho, bfgsoutX, grad, nvars);
+ }
+
+ for(j = 1; j <= nvars; j++) {
+ i = j-1;
+ if(PrintLevel>0)
+ Rprintf(" X[%2d] :\t%e\tG[%2d] :\t%e\n",j,population[1][j],j,grad[i]);
+ Results[i] = population[1][j];
+ Gradients[i] = grad[i];
+ }
+ } /* end of else (GradientCheck==0 && UseBFGS==0) */
+
+ Structure->oFitValues[0]=population[1][0];
+ if (Structure->Lexical > 1)
+ {
+ k = 1;
+ for (i=(nvars+2);i<lexical_end;i++) {
+ Structure->oFitValues[k]=population[1][i];
+ k++;
+ }
+ }
+
+ /* free memory */
+ /* free populationstats stuff */
+ free(mean);
+ free(var);
+ free(skew);
+ free(kur);
+ free(tobs);
+
+ free(bfgsoutX);
+ free(finalhessin);
+ free(evalX);
+ free(grad);
+
+ if (Structure->MemoryUsage==1)
+ JaMatrixFree(Memory, MemorySize);
+
+ JaMatrixFree(population, pop_size+2);
+ JaMatrixFree(new_genera, pop_size+2);
+
+ free_matrix(temp, 0, nvars+1, 0);
+ free_vector(probab, 1);
+ free_vector(t_vec, 1);
+ free_vector(cum_probab, 1);
+ free_ivector(live, 1);
+ free_ivector(parents, 1);
+
+ if(Structure->Lexical > 1)
+ {
+ free(LexicalReturn);
+ free(oldfitvalueVEC);
+ }
+} /* end JaIntegerOptimization */
+
+
+
+/********************************************************************************/
+/* JaIntegerSort(): */
+/* */
+/* This function sorts a double** on an integer basis. */
+/* The function also assumes that the double** is indexed from 1 in its rows */
+/* and from zero in its columns. */
+/* */
+/********************************************************************************/
+
+void JaIntegerSort(double **InMatrix, long n, long k)
+{
+ /* extern int JaIntegerCMP(); */
+ long i, j;
+ double **Tmp;
+ extern long Gnvars[MAXINSTANCES];
+ long nvars;
+
+ Tmp = JaMatrixAllocate(n, k);
+
+ nvars=Gnvars[ExternStructure->InstanceNumber];
+
+ for (i=1; i<=n; i++) {
+ for (j=0; j<k; j++) {
+ Tmp[i-1][j] = InMatrix[i][j];
+ }
+ }
+
+ for (i=1; i<=n; i++) {
+ for (j=0; j<k; j++) {
+ InMatrix[i][j] = Tmp[i-1][j];
+ }
+ }
+
+ JaMatrixFree(Tmp, n);
+} /* end of JaIntegerSort */
+
+
+/********************************************************************************/
+/* JaDoubleSort(): */
+/* */
+/* This function sorts a double** on an double basis. */
+/* The function also assumes that the double** is indexed from 1 in its rows */
+/* and from zero in its columns. */
+/* */
+/********************************************************************************/
+
+void JaDoubleSort(double **InMatrix, long n, long k)
+{
+ /* extern int JaDoubleCMP(); */
+ long i, j;
+ double **Tmp;
+ extern long Gnvars[MAXINSTANCES];
+ long nvars;
+
+ Tmp = JaMatrixAllocate(n, k);
+
+ nvars=Gnvars[ExternStructure->InstanceNumber];
+
+ for (i=1; i<=n; i++) {
+ for (j=0; j<k; j++) {
+ Tmp[i-1][j] = InMatrix[i][j];
+ }
+ }
+
+ for (i=1; i<=n; i++) {
+ for (j=0; j<k; j++) {
+ InMatrix[i][j] = Tmp[i-1][j];
+ }
+ }
+
+ JaMatrixFree(Tmp, n);
+} /* end of JaDoubleSort */
+
+
+
diff --git a/src/frange_ran.cpp b/src/frange_ran.cpp
new file mode 100644
index 0000000..0abf29c
--- /dev/null
+++ b/src/frange_ran.cpp
@@ -0,0 +1,89 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ $Header: /home/jsekhon/xchg/genoud/rgenoud.distribution/sources/RCS/frange_ran.cpp,v 2.15 2005/10/29 06:14:44 jsekhon Exp jsekhon $
+
+*/
+
+#include "genoud.h"
+
+/* replacements for random number functions in GENOCOP's frange_ran.c */
+
+#include "unif.h"
+#include "urans.h"
+
+double newunif(void)
+{
+ extern int NewUnifSeed[MAXTHREADS];
+ extern int ThreadNumber;
+ /* static integer aux[TLPAUXSIZE], iseed = NEWUNIFSEED ;*/
+ static integer aux[TLPAUXSIZE];
+ double wrkout;
+ double wrk;
+
+ /* get a random uniform double on (0,1] */
+ ruxorv (&NewUnifSeed[ThreadNumber], 1, &wrk, aux);
+ wrkout = (double) wrk;
+ return(wrkout);
+}
+
+double frange_ran(double llim, double ulim)
+ /*
+ double ulim;
+ double llim;
+ */
+{
+
+ /*llim, ulim: The upper and lower limits between which the random
+ number is to be generated*/
+
+ double num1, diff = ulim - llim;
+
+ if (diff == 0)
+ return(llim);
+ else if(diff < 0.0001)
+ return((flip() == TAIL) ? llim : ulim);
+ do {
+// printf("num1: %lf, ulim: %lf, llim: %lf\n",num1,ulim,llim);
+// fflush(stdout);
+ num1 = llim + newunif()*(ulim-llim) ;
+ }
+ while((num1<llim)||(num1>ulim));
+
+// printf("fr2\n");
+// fflush(stdout);
+ return(num1);
+}
+
+unsigned int randint (void)
+{
+ extern int RandIntSeed[MAXTHREADS];
+ extern int ThreadNumber;
+ /* static integer aux[TLPAUXSIZE], iseed = RANDINTSEED ; */
+ static integer aux[TLPAUXSIZE];
+ integer wrk;
+ int num;
+
+ /* get a signed 32-bit number from the TLP generator */
+ tlpseq (&RandIntSeed[ThreadNumber], 1, &wrk, aux);
+ /* truncate to 16 bits */
+ num = wrk%65535;
+ return (num);
+}
+
+unsigned int newrand (void)
+{
+ return (randint());
+}
+
diff --git a/src/genoud.cpp b/src/genoud.cpp
new file mode 100644
index 0000000..2dbb33a
--- /dev/null
+++ b/src/genoud.cpp
@@ -0,0 +1,188 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ June 3, 2012
+*/
+
+#include "genoud.h"
+#include "unif.h"
+
+/* unif.h integer definition */
+int NewUnifSeed[MAXTHREADS];
+int RandIntSeed[MAXTHREADS];
+int ThreadNumber;
+
+extern double func4g(double *X);
+
+void genoud(struct GND_IOstructure *Structure)
+{
+
+ extern int NewUnifSeed[MAXTHREADS];
+ extern int RandIntSeed[MAXTHREADS];
+ extern int ThreadNumber;
+
+ MATRIX
+ domains, /*Matrix for Domains*/
+ final_mat; /*The final Domain*/
+
+ VECTOR
+ LowerBounds,
+ UpperBounds,
+ X; /*Initial values for the variables*/
+
+ INDEX
+ fin; /*Size of final matrix*/
+
+ int
+ i, /*Counter variable*/
+ nvars; /*Remaining variables after p-variables were eliminated*/
+
+ time_t start_time,
+ stop_time;
+ double delta_time;
+ long hours, minutes, seconds;
+ char time_str[27];
+
+ static long BaseNewUnifSeed=81282,
+ BaseRandIntSeed=53058;
+ static short firsttime=1;
+
+ /* FILE *output; */
+
+ /* Lamarck Child Test Variables */
+ // char LVMchar[1000];
+ long LVMreturn;
+
+/********************************************************************************/
+
+ LVMreturn=0;
+ time(&start_time);
+ strcpy(time_str, ctime(&start_time));
+
+ /* Fault Tolerant MinMax */
+ if (Structure->MinMax > 0) Structure->MinMax=1;
+ else Structure->MinMax=0;
+
+ if (Structure->OutputType!=0) {
+ error("output path/type must be the 'R' default");
+ } /* else {
+ output=stdout;
+ } */
+
+ if(Structure->PrintLevel>0)
+ Rprintf("\n\n%s",time_str);
+
+ ThreadNumber=Structure->ThreadNumber;
+ if (ThreadNumber > MAXTHREADS) {
+ error("No more than %d threads allowed\n\n", MAXTHREADS);
+ }
+ if (Structure->ProvideSeeds == 1) {
+ /*
+ Only toggle the instance number if we have threads! */
+ NewUnifSeed[ThreadNumber] = Structure->UnifSeed;
+ RandIntSeed[ThreadNumber] = Structure->IntSeed;
+ }
+ else {
+ /* If a Seed is NOT provided, use the base random number and run from that base!
+ In other words, might as well the ThreadNumber equal to 0
+ */
+ if (firsttime==1) {
+ NewUnifSeed[0] = BaseNewUnifSeed;
+ RandIntSeed[0] = BaseRandIntSeed;
+ firsttime=0;
+ }
+ ThreadNumber = 0;
+ }
+
+ fin.r = Structure->nvars; /*total number of inequalities + domains*/
+ fin.c = Structure->nvars+2; /*x2 variables + lower limits + upper limits*/
+
+ nvars = Structure->nvars;
+
+ /*Allocating memory for all the vectors and matrices*/
+ final_mat = matrix(1,fin.r,1,fin.c);
+ domains = matrix(1,nvars,1,3);
+ LowerBounds = Gvector(1, nvars);
+ UpperBounds = Gvector(1, nvars);
+ X = Gvector(1,nvars);
+
+ /* SETUP DOMAINS */
+
+ /* alter the domains when we are using integers because of the "open
+ set" problem. We only extend the UPPER domain bound */
+ if (Structure->DataType==1) {
+ for(i=0; i<Structure->nvars; i++)
+ Structure->Domains[i][1] = Structure->Domains[i][1] + 0.99999;
+ }
+
+ for(i=1; i<=Structure->nvars; i++)
+ {
+ domains[i][1] = Structure->Domains[i-1][0];
+ domains[i][2] = (double) i;
+ domains[i][3] = Structure->Domains[i-1][1];
+ }
+
+ for (i=1; i<=nvars; i++)
+ {
+ LowerBounds[i] = domains[i][1];
+ UpperBounds[i] = domains[i][3];
+ }
+
+ /*Initialization*/
+ if(Structure->PrintLevel>0)
+ print_domains(domains,nvars,Structure->DataType);
+
+ if (Structure->DataType==1) {
+ JaIntegerOptimization(Structure, X, domains);
+ }
+ else {
+ optimization(Structure, X, domains);
+ }
+
+ /* free memory */
+ free_matrix(final_mat,1,fin.r,1);
+ free_matrix(domains, 1, nvars, 1);
+ free_vector(LowerBounds,1);
+ free_vector(UpperBounds,1);
+ free_vector(X,1);
+
+ /* print final numbers and the time this has taken */
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf( "\n");
+ Rprintf( "Solution Found Generation %d\n", Structure->oPeakGeneration);
+ Rprintf( "Number of Generations Run %d\n", Structure->oGenerations);
+ }
+ time(&stop_time);
+
+ strcpy(time_str, ctime(&stop_time));
+ if(Structure->PrintLevel>0)
+ Rprintf("\n%s",time_str);
+
+ delta_time = difftime(stop_time, start_time);
+ hours = (int) (delta_time/3600);
+ minutes = (int) (delta_time - (hours*3600))/60;
+ seconds = (int) delta_time - (hours*3600) - (minutes*60);
+
+ if(Structure->PrintLevel>0)
+ {
+ Rprintf("Total run time : %d hours %d minutes and %d seconds\n",
+ hours, minutes, seconds);
+ /* fflush(output); */
+ }
+
+ /* no longer allowed */
+ /* if (Structure->OutputType==1) fclose(output); */
+}
+
diff --git a/src/genoud.h b/src/genoud.h
new file mode 100644
index 0000000..ed0e242
--- /dev/null
+++ b/src/genoud.h
@@ -0,0 +1,274 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ June 3, 2012
+
+*/
+
+#include<R.h>
+#include<stdio.h>
+#include<stdlib.h>
+#include<cmath>
+#include<time.h>
+#include<string.h>
+#include<stdarg.h>
+#include<Rdefines.h>
+
+extern "C"
+{
+ /* function definitions */
+ double evaluate(SEXP fn, SEXP rho, double *X, long nvars, short int MinMax);
+ void EvaluateLexical(SEXP fn, SEXP rho,
+ double *X, long nvars, long lexical, short int MinMax, double *ret);
+ void EvaluateTransform(SEXP fn, SEXP rho,
+ double *X, long nvars, long lexical, short int MinMax, double *ret);
+} /*end of extern C */
+
+#define M(ROW,COL,NCOLS) (((ROW)*(NCOLS))+(COL))
+#define EVALUATE -645271937
+#define DOUBLEMAX DOUBLE_XMAX
+#define MAXPATH 1000
+#define MAXTHREADS 20
+#define MAXINSTANCES 20
+#define ERROR_CODE -99999
+#define MAX_OPER_UNIQUE_TRY 1000
+
+#define TRUE 1
+#define FALSE 0
+
+#define DOS_SYS FALSE /* set to true for dos, false for unix */
+#define UNIX_SYS TRUE /* set to true for unix, false for dos */
+
+#define flip() ((int) ((newrand()*(long)2)/(long) 65535))
+#define MIN -32768
+#define MAX 32768
+#define HEAD 1
+#define TAIL 0
+#define TRIES 1000
+#define MULT 25173
+#define INCR 13849
+#define MOD ((long int) 65536)
+#define SHUFFLE 256 /* size of random number shuffle array */
+#define EST_OFFSET 0 /* offset in hours from Eastern Standard Time zone) */
+
+#define NOTDONE_ADD 0.25
+/* number of generations with no changes to be treated as convergence at
+ generation limit */
+#define NOTDONE_LIM 50
+
+typedef double **MATRIX;
+typedef double *VECTOR;
+typedef int **IMATRIX;
+typedef int *IVECTOR;
+typedef int FLAG;
+typedef int TOSS;
+typedef struct {int r; int c;}INDEX;
+
+
+
+struct GND_IOstructure
+{
+ /* --- Basic Input Parameters ---- */
+ SEXP fn;
+ SEXP rho;
+ SEXP fnLexicalSort;
+ SEXP fnMemoryMatrixEvaluate;
+ SEXP fnGR;
+ SEXP fn_optim;
+ long nvars;
+ long PopSize;
+ long MaxGenerations;
+ long WaitGenerations;
+ double P[9]; /* Operators */
+ double **Domains;
+ short MinMax;
+ short GradientCheck;
+ short BoundaryEnforcement; /* 0=anything goes, 1: regular; 2: no trespassing! */
+ double SolutionTolerance;
+ long ThreadNumber; /* indexed from zero */
+ long InstanceNumber; /* indexed from zero, the number of parallel runs */
+ short UseBFGS; /* Use BFGS on the Best Individual 1= True, 0=False */
+ short DataType; /* 1== integer, everything else equals float */
+ short MemoryUsage; /* 0=minimize, 1=normal */
+ short Debug; /* T, F */
+ short HardGenerationLimit; // T, F
+
+ /* Starting Values (if we want to provide any) */
+ double **StartingValues; /* a matrix of starting values (each set consists of a row) */
+ long nStartingValues; /* number of starting values */
+
+ /* Random Number Stuff */
+ short ProvideSeeds; /* 0: no, 1: yes */
+ long UnifSeed;
+ long IntSeed;
+
+ /* --- Ouput Diagnostics --- */
+ double *oFitValues;
+ double *oResults;
+ double *oGradients;
+ long oP[9]; /* operators used */
+ long oGenerations;
+ long oPeakGeneration;
+ long oPopSize;
+
+ /* Output Files */
+ char* OutputPath;
+ char* ProjectPath;
+
+ /* I/O types */
+ short OutputType;
+ short PrintLevel;
+
+ /* Parallel Processing Stuff */
+ short ShareType;
+
+ /* lexical sorting */
+ long Lexical;
+
+ short int UserGradient;
+
+ /* Operator Options */
+ double P9mix;
+ int BFGSburnin;
+
+ /* Transform Related Variables */
+ short int whichFUN; /* 1, 2, or 3 corresponding to which evaluate function to call */
+ short int Transform; /* 0 or 1 indicating whether transformed parameters are returned */
+};
+
+/* bfgs.c */
+void dfgsmin(SEXP fn, SEXP rho,
+ double *p, int n, double gtol, int *iter, double *fret, double *hessian,
+ short int MinMax, short int BoundaryEnforcement, long InstanceNumber,
+ double **Domains, short PrintLevel, FILE *output);
+
+/* change_order.c file */
+void get_var_order(IVECTOR tot, IVECTOR cart, IMATRIX var_order);
+void find_x1_x2(int tot, IMATRIX var_order, IVECTOR x1, IVECTOR x2);
+void find_ac1_ac2(int t1, int t2, int t3, IVECTOR x1, IVECTOR x2, MATRIX mat, MATRIX ac1, MATRIX ac2);
+void find_lu1_lu2(IVECTOR tot, IVECTOR x1, IVECTOR x2, VECTOR dom, VECTOR dom1, VECTOR dom2);
+void find_limits(int tot, MATRIX domains, VECTOR llim, VECTOR ulim);
+void find_new_in_eq(VECTOR a1b, MATRIX a1a2, VECTOR ll, VECTOR ul, INDEX rc, MATRIX newin);
+void find_org_in_eq(VECTOR a1_b, MATRIX a1_a2, VECTOR vec_d, MATRIX c1, MATRIX c2, int c1row,
+ INDEX a1a2, MATRIX org_ineq);
+void initialize(MATRIX mat, INDEX rc);
+void find_final_mat1(VECTOR l2, VECTOR u2, MATRIX finmat, int row, int col);
+void find_final_mat2(MATRIX newin, int r, int c, int finr, MATRIX finmat);
+void find_final_mat3(MATRIX orgin, int r, int c, int finr, MATRIX finmat);
+
+/* evaluate.c */
+void optimization(struct GND_IOstructure *Structure, VECTOR X,
+ MATRIX domains);
+void sort(short int MinMax, MATRIX population, int pop_size,
+ long nvar);
+void swap(double **x, double **y);
+int find_parent(IVECTOR live, int pop_size);
+void assign_probab(VECTOR probab, int pop_size, double Q);
+double x_pow_y(double x, int y);
+void find_cum_probab(VECTOR cum_probab, VECTOR probab, int pop_size);
+void find_live(VECTOR cum_probab, IVECTOR live, int pop_size, int P);
+int find_die(VECTOR cum_probab, IVECTOR die, int pop_size);
+void SetRunTimeParameters(struct GND_IOstructure *Structure,
+ short FirstTime,
+ long *PopSize, long *nvars, long *MaxGenerations, long *WaitGenerations,
+ short *MinMax, short *GradientCheck, short *BoundaryEnforcement, short *UseBFGS,
+ double *SolutionTolerance,
+ long *InstanceNumber, long *P, long *P0, long *P1, long *P2, long *P3, long *P4, long *P5,
+ long *P6, long *P7, long *P8, short *PrintLevel,
+ short *HardGenerationLimit);
+void JaIntegerOptimization(struct GND_IOstructure *Structure, VECTOR X,
+ MATRIX domains);
+void JaIntegerSort(double **InMatrix, long n, long k);
+int JaIntegerCMP(double **a, double **b) ;
+void JaDoubleSort(double **InMatrix, long n, long k);
+int JaDoubleCMP(double **a, double **b) ;
+
+/* frange_ran.c */
+double newunif(void);
+double frange_ran(double llim, double ulim);
+unsigned int randint(void);
+unsigned int newrand(void);
+
+/* math.c */
+/* Not needed here. In here for completeness! */
+void add(double *in1, double *in2, double *out, int row, int col);
+void copy(double *in, double *target, int row, int col);
+void multi(double *in1, double *in2, double *out,
+ int row1, int col1, int row2, int col2, int outrowcol[2]);
+void scalarmulti(double scalar, double *in1, double *out, int row, int col) ;
+void scalarmultioffdiag(double scalar, double *in1, double *out, int row, int col) ;
+void subtract(double *in1, double *in2, double *out, int row, int col);
+double trace(double *a, int n);
+void transpose(double *orig_matrix, double *t_matrix, int orig_rows, int orig_columns);
+void copy_matrix(MATRIX mat1, MATRIX mat2, int lr, int ur, int lc, int uc);
+int Iround(double in);
+void samplestats(double **obsdata, int numobsv, int novarsv, int weightflag,
+ double *weightdata);
+void populationstats(double **popdata, int numobsv, int novarsv,
+ double *mean, double *var, double *skew, double *kur,
+ long *tobs);
+
+/* multiply.c */
+void mmprod(int m, int nm, int n, MATRIX mul_cm, MATRIX mul_am, MATRIX mul_bm);
+void mvprod(int m, int nm, VECTOR cm, MATRIX am, VECTOR bm);
+
+/* numerics.c */
+double **JaMatrixAllocate(long n, long k);
+void JaMatrixFree(double **M, long k);
+short **JaShortMatrixAllocate(long nobs, long nvars);
+void JaShortMatrixFree(double **M, long nobs);
+MATRIX matrix(int nrl, int nrh, int ncl, int nch);
+void nrerror(char error_text[]);
+double *Gvector(int nl, int nh);
+int **imatrix(int nrl, int nrh, int ncl, int nch);
+int *ivector(int nl, int nh);
+void free_vector(double *v, int nl);
+void free_ivector(int *v, int nl);
+void free_matrix(double **m, int nrl, int nrh, int ncl);
+void free_imatrix(int **m, int nrl, int nrh, int ncl);
+
+
+/* operators.c file */
+void oper1(VECTOR parent, double **domains, int nvars);
+void oper2(VECTOR parent, double **domains, int nvars);
+void oper3(VECTOR parent, double **domains, int nvars, int T, int t, int B);
+void oper4(MATRIX p, int p2use, int nvars);
+void oper5(VECTOR p1, VECTOR p2, int STEP, double **domains, int nvars);
+void oper6(VECTOR parent, double **domains, int nvars, int T, int t, int B);
+void oper7(VECTOR p1, VECTOR p2, double **domains, int nvars);
+void oper8(SEXP fn, SEXP rho,
+ VECTOR parent, MATRIX domains,
+ double SolutionTolerance, long nvars,
+ short BoundaryEnforcement,
+ short PrintLevel, double mix);
+void find_range(double *llim, double *ulim, int comp, double **domains, int nvars, VECTOR parent);
+void find_rangeInt(int *llim, int *ulim, int comp, double **domains, int nvars, VECTOR parent);
+int irange_ran(int llim, int ulim);
+double get_F(int T, int t, double y, int B);
+void JaIntegerOper1(VECTOR parent, double **domains, int nvars);
+void JaIntegerOper2(VECTOR parent, double **domains, int nvars);
+void JaIntegerOper3(VECTOR parent, double **domains, int nvars, int T, int t, int B);
+void JaIntegeroper4(MATRIX p, int p2use, int nvars, double **domains);
+void JaIntegerOper5(VECTOR p1, VECTOR p2, int STEP, double **domains, int nvars);
+void JaIntegerOper6(VECTOR parent, double **domains, int nvars, int T, int t, int B);
+void JaIntegerOper7(VECTOR p1, VECTOR p2, double **domains, int nvars);
+FLAG InBounds(VECTOR child, double **domains, int nvars);
+
+/*print_format.c */
+long ReadPopulation(double **Data, long NewPopSize, long NewVars, FILE *fp, short PrintLevel);
+void print_domains(MATRIX equal, int t_equ, short DataType);
+void print_population(int popsize, int nvars, int generation, int
+ lexical, double **foo, FILE *out);
+
+
diff --git a/src/gradient.cpp b/src/gradient.cpp
new file mode 100644
index 0000000..0cd25ed
--- /dev/null
+++ b/src/gradient.cpp
@@ -0,0 +1,870 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ June 2, 2012
+
+*/
+
+#include "genoud.h"
+#include "gradient.h"
+
+double GammaLN(double xx)
+{
+ double cof[6] = {
+ 76.18009173,
+ -86.50532033,
+ 24.01409822,
+ -1.231739516,
+ 0.12085003E-2,
+ -0.536382E-5,
+ };
+
+ double stp = 2.50662827465;
+ double x, tmp, ser;
+ int j;
+
+ x = xx - 1.0;
+
+ tmp = x + 5.5;
+
+ tmp = (x + 0.5) * log(tmp) - tmp;
+
+ ser = 1.0;
+
+ for (j = 0; j < 6; j++)
+ {
+ x += 1.0;
+ ser += cof[j] / x;
+ }
+
+ return tmp + log(stp * ser);
+}
+
+double VMgamma(double xx)
+{
+ #define PI2 3.141592654
+
+ if (xx > 0) return exp(GammaLN(xx));
+ else if (xx < 0) return PI2 / exp(GammaLN(1 - xx)) / sin( PI2 * (1 - xx));
+ else return 0;
+
+}
+
+
+
+/*
+ func4g is required by the gradient code. It takes what is in
+ evaluate() and increments it down by 1
+
+ NOTE: funco() (which not used here) does not increment evaluate() down by 1.
+ The code internal to the function does this.
+ */
+
+double func4g(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax, short BoundaryEnforcement,
+ double **Domains)
+{
+ double fit;
+ short BoundaryTrigger=0;
+ long i;
+
+ if (BoundaryEnforcement==2) {
+ for (i=0; i<nvars; i++) {
+ if (X[i] < Domains[(i+1)][1]) {
+ BoundaryTrigger=1;
+ break;
+ }
+ if (X[i] > Domains[(i+1)][3]){
+ BoundaryTrigger=1;
+ break;
+ }
+ }
+
+ if (BoundaryTrigger > 0) {
+ // *Status=-3;
+ // min
+ if (MinMax==0) return(-1*DOUBLEMAX);
+ //max
+ else return(DOUBLEMAX);
+ }
+ }
+
+ if (MinMax==0) fit=evaluate(fn, rho, X-1, nvars, MinMax);
+ else fit = -1*evaluate(fn, rho, X-1, nvars, MinMax);
+ return(fit);
+}
+
+/* replace gradient() body with analytical gradient code, if desired.
+ by default, numerical gradients with the intervals in *optint are used
+
+ arguments (must be identical in any replacement code):
+ *p, vector of parameters, p[0] is the first parameter;
+ *g, vector that will hold the gradient, allocated by caller,
+ g[0] is the derivative for the first parameter;
+ nparms, the number of parameters, p[nparms-1] is the last parameter.
+*/
+void gradient(SEXP fn, SEXP rho,
+ double *p, double *g, long nparms, short MinMax, short BoundaryEnforcement,
+ double **Domains)
+{
+
+ double *wrk;
+ int ndiffs;
+
+ /* formally declared global in graddata.h */
+ // double *epsacc, *optint, *ihessians;
+ double *epsacc, *optint;
+
+ optint = (double *) malloc(nparms*sizeof(double));
+ epsacc = (double *) malloc(nparms*sizeof(double));
+ wrk = (double *) malloc(nparms*sizeof(double));
+
+ ndiffs = 9; /* order of differences for num grad optimal interval calcs */
+
+ estoptint(fn, rho, epsacc, optint, nparms, ndiffs, 2, p, func4g,
+ MinMax, BoundaryEnforcement, Domains);
+
+ /* numgradc: numerical gradient, central-difference */
+ numgradc(fn, rho, epsacc, optint, nparms, p, g, wrk, func4g, MinMax,
+ BoundaryEnforcement, Domains);
+
+ free(wrk);
+ free(epsacc);
+ free(optint);
+
+ return;
+}
+
+/* numerical gradient, forward-difference */
+/* see Gill, Murray and Wright, 1981, "Practical Optimization," p. 342 */
+
+/* invals, grads, wrk should point to double w[nparms+1] arrays;
+ func is the function whose gradient is to be evaluated */
+void numgrad(SEXP fn, SEXP rho,
+ double *epsacc, double *optint,
+ int nparms, double *invals, double *grads, double *wrk,
+ double (*func)(SEXP fn, SEXP rho, double *X, int nvars, short int MinMax),
+ short MinMax)
+{
+ int i;
+ // double u, rf, fplus, fminus;
+ double u, fplus, fminus;
+ double epsuse;
+ double duse;
+
+ /* evaluate func at the input point */
+ u = func(fn, rho, invals, nparms, MinMax);
+
+ /* copy the parameter values for point at which to evaluate the gradient */
+ for (i=0; i<nparms; i++) wrk[i] = invals[i];
+
+ /* evaluate the gradient */
+ for (i=0; i<nparms; i++) {
+ epsuse = epsacc[i];
+ duse = optint[i];
+ wrk[i] += duse;
+ grads[i] = (func(fn, rho, wrk, nparms, MinMax) - u) / duse ;
+
+ /* check the gradient */
+ if (2.0*epsuse / (duse*fabs(grads[i])) > 0.1) { /* switch to central-diff */
+ duse = pow(duse, 2.0/3.0); /* see GMW p 131 */
+ wrk[i] = invals[i] + duse;
+ fplus = func(fn, rho, wrk, nparms, MinMax);
+ wrk[i] = invals[i] - duse;
+ fminus = func(fn, rho, wrk, nparms, MinMax);
+ grads[i] = (fplus-fminus) * 0.5 / duse ;
+ }
+ wrk[i] = invals[i];
+ }
+}
+
+
+/* numerical gradient, central-difference */
+/* see Gill, Murray and Wright, 1981, "Practical Optimization," p. 342 */
+
+/* invals, grads, wrk should point to double w[nparms+1] arrays;
+ func is the function whose gradient is to be evaluated */
+void numgradc(SEXP fn, SEXP rho,
+ double *epsacc, double *optint,
+ int nparms, double *invals, double *grads, double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains)
+{
+ int i;
+ // double u, rf, fplus, fminus;
+ double u, fplus, fminus;
+ double epsuse;
+ double duse;
+
+ /* evaluate func at the input point */
+ u = func(fn, rho, invals, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ /* copy the parameter values for point at which to evaluate the gradient */
+ for (i=0; i<nparms; i++) wrk[i] = invals[i];
+
+ /* evaluate the gradient */
+ for (i=0; i<nparms; i++) {
+
+ epsuse = epsacc[i];
+ duse = optint[i];
+ duse = pow(duse, 2.0/3.0); /* see GMW p 131 */
+ wrk[i] = invals[i] + duse;
+ fplus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i] - duse;
+ fminus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ grads[i] = (fplus-fminus) * 0.5 / duse ;
+ wrk[i] = invals[i];
+ }
+}
+
+#ifdef NEVERDEFINED
+/* numerical outer-product of gradient, central-difference */
+/* return pointer to full numerical OPG */
+/* uses central differences: */
+/* phi2 = (f(x+hi ei) - f(x-hi ei)) * (f(x+hj ej) - f(x-hj ej)) */
+/* invals, grads, wrk should point to double w[nparms+1] arrays;
+ func is the function whose gradient is to be evaluated */
+double *numopgc(double *epsacc, double *optint,
+ int nparms, int nobs, double *invals, double *opg, double *wrk,
+ int (*func)(double *X, double *outvec))
+{
+ double *outvec, *outplus, *outminus, *outdiff;
+
+ int i,j,k, idx;
+ int ni = 0;
+ double hi, ih;
+ double phi2, dini;
+
+ double *hfuse = optint;
+
+ outvec = (double *) malloc(nobs*sizeof(double));
+ outplus = (double *) malloc(nobs*nparms*sizeof(double));
+ outminus = (double *) malloc(nobs*nparms*sizeof(double));
+ outdiff = (double *) malloc(nobs*nparms*sizeof(double));
+
+ /* allocate storage for the hessian */
+ opg = (double *) calloc(nparms*nparms,sizeof(double));
+
+ /* evaluate func at the input point */
+ /* parameters, ooutvec=nobs */
+ /* evaluates the function (i.e., the likelihood) at each observation */
+ func(invals-1, outvec);
+
+ /* copy the parameter values for point at which to evaluate the gradient */
+ for (i=0; i<nparms; i++) wrk[i] = invals[i];
+
+ /* evaluate the gradient elements */
+ for (i=0; i<nparms; i++) {
+ hi = pow(hfuse[i], 2.0/3.0);
+ wrk[i] = invals[i] + hi;
+ func(wrk-1, outplus+i*nobs);
+ wrk[i] = invals[i] - hi;
+ func(wrk-1, outminus+i*nobs);
+ wrk[i] = invals[i];
+
+ ih = 0.5 / hi;
+ for (k=0; k<nobs; k++) {
+ idx = i*nobs+k;
+ outdiff[idx] = (outplus[idx] - outminus[idx]) * ih ;
+ }
+ }
+ for (i=0; i<nparms; i++) {
+ idx = i*nparms;
+ for (j=0; j<=i; j++) {
+ phi2 = 0.0;
+ for (k=0; k<nobs; k++) {
+ phi2 += outdiff[i*nobs+k] * outdiff[j*nobs+k];
+ }
+ opg[i*nparms + j] = phi2;
+ if (i!=j) opg[j*nparms + i] = phi2;
+ }
+ }
+ free(outdiff);
+ free(outminus);
+ free(outplus);
+ free(outvec);
+
+ return opg;
+}
+#endif
+
+/* estimate accuracy */
+/* see Gill, Murray and Wright, 1981, "Practical Optimization," p. 337 */
+
+double **eaccuracy(SEXP fn, SEXP rho,
+ int nparms, int ndiffs, double h, double *invals,
+ double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains)
+{
+ double **table;
+
+ int i,j,k, idx;
+ int nsteps = 1+2*ndiffs, nrows = nparms*nsteps, ncols = ndiffs+1;
+ double u, huse, v;
+ double scale = 2.0*pow(10.0,6.0);
+
+ /* allocate storage for the table to differences to be returned */
+ table = (double **) malloc(ncols*sizeof(double *));
+ for (i=0; i<ncols; i++)
+ table[i] = (double *) calloc(nrows, sizeof(double));
+
+ /* evaluate func at the input point */
+ u = func(fn, rho, invals, nparms, MinMax, BoundaryEnforcement, Domains);
+ for (i=0; i<nparms; i++) table[0][i*nsteps] = u;
+
+ /* copy the parameter values for point at which to evaluate the gradient */
+ for (i=0; i<nparms; i++) wrk[i] = invals[i];
+
+ /* evaluate the offsets */
+ for (i=0; i<nparms; i++) {
+ /* make sure huse is sufficiently small */
+ v = fabs(invals[i]);
+ huse = h;
+ if (v>EPS*scale) {
+ while (huse > v/scale)
+ huse *= 0.1;
+ }
+ for (j=1; j<nsteps; j++) {
+ wrk[i] += huse;
+ table[0][i*nsteps+j] = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains) ;
+ }
+ wrk[i] = invals[i];
+ }
+
+ /* compute the differences */
+ for (i=0; i<nparms; i++) {
+ idx = i*nsteps;
+ for (j=0; j<ndiffs; j++) {
+ for (k=0; k<nsteps-j-1; k++) {
+ table[j+1][idx+k] = table[j][idx+k+1] - table[j][idx+k];
+ }
+ }
+ }
+ return table;
+}
+
+/* estimate intervals for use in numerical gradients */
+/* see Gill, Murray and Wright, 1981, "Practical Optimization," p. 343-344 */
+
+struct estints *algfd(SEXP fn, SEXP rho,
+ int nparms, double *eps, double *invals, double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains)
+{
+ struct estints *outstruc;
+
+ // int i,j,k;
+ int i, k;
+ int K = 20;
+ int errval = 0;
+ double omega = 1.0, eta = 1.0;
+ double u;
+ double hf, hk, hbar, hs, hphi=0;
+ double fplus, fminus, phi, phif, phib, phic, phi2, cf, cb, c2;
+ // double fplus, fminus, phi, phic, phi2, c2;
+ double ef, ebar;
+
+ /* allocate structure to return */
+ outstruc = (struct estints *) malloc(sizeof(struct estints));
+ outstruc->errors = (int *) calloc(nparms, sizeof(int));
+ outstruc->hf = (double *) calloc(nparms, sizeof(double));
+ outstruc->phi = (double *) calloc(nparms, sizeof(double));
+ outstruc->phic = (double *) calloc(nparms, sizeof(double));
+ outstruc->phi2 = (double *) calloc(nparms, sizeof(double));
+ outstruc->ef = (double *) calloc(nparms, sizeof(double));
+ outstruc->nparms = nparms;
+
+ /* evaluate func at the input point */
+ u = func(fn, rho, invals, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ /* copy the parameter values for point at which to evaluate the gradient */
+ for (i=0; i<nparms; i++) wrk[i] = invals[i];
+
+ for (i=0; i<nparms; i++) {
+ // #ifdef NEVERDEFINED
+ FD1:
+ hbar = 2.0*(eta+fabs(invals[i]))* sqrt(eps[i]/(omega + fabs(u))) ;
+ hk = 10.0 * hbar;
+ k = 0;
+ fdestimates(fn, rho, i, u, invals, wrk, eps[i], hk,
+ &fplus, &fminus, &phif, &phib, &phic, &phi2, &cf, &cb, &c2,
+ func, nparms, MinMax, BoundaryEnforcement, Domains);
+ hs = -1.0;
+ FD2:
+ if ((cf>cb ? cf : cb) <= 0.1) hs = hk;
+ if (0.001 <= c2 && c2 <= 0.1) {
+ hphi = hk;
+ goto FD5;
+ }
+ if (0.001 > c2) goto FD4;
+ FD3:
+ do {
+ k++;
+ hk *= 10.0;
+ fdestimates(fn, rho, i, u, invals, wrk, eps[i], hk,
+ &fplus, &fminus, &phif, &phib, &phic, &phi2, &cf, &cb, &c2,
+ func, nparms, MinMax, BoundaryEnforcement, Domains);
+ if (hs<0 && ((cf>cb ? cf : cb) <= 0.1)) hs = hk;
+ if (c2 <= 0.1) {
+ hphi = hk;
+ goto FD5;
+ }
+ } while (k<K);
+ if (k==K) goto FD6;
+ FD4:
+ do {
+ k++;
+ hk /= 10.0;
+ fdestimates(fn, rho, i, u, invals, wrk, eps[i], hk,
+ &fplus, &fminus, &phif, &phib, &phic, &phi2, &cf, &cb, &c2,
+ func, nparms, MinMax, BoundaryEnforcement, Domains);
+ if (c2 > 0.1) {
+ hphi = hk * 10.0;
+ goto FD5;
+ }
+ if ((cf>cb ? cf : cb) <= 0.1) hs = hk;
+ if (0.001 <= c2 && c2 <= 0.1) {
+ hphi = hk;
+ goto FD5;
+ }
+ } while (k<K);
+ if (k==K) goto FD6;
+ FD5:
+ hf = 2.0*sqrt(eps[i]/fabs(phi2));
+ wrk[i] = invals[i] + hf;
+ fplus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+ phi = (fplus-u)/hf;
+ wrk[i] = invals[i] + hphi;
+ fplus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i] - hphi;
+ fminus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i];
+ phic = (fplus-fminus)/(2.0*hphi);
+
+ ef = hf*fabs(phi2)*0.5 + 2.0*eps[i]/hf ;
+ ebar = fabs(phi-phic);
+
+ outstruc->hf[i] = hf;
+ outstruc->phi[i] = phi;
+ outstruc->phic[i] = phic;
+ outstruc->phi2[i] = phi2;
+ outstruc->ef[i] = ef;
+ if ((ef>ebar ? ef : ebar) <= 0.5*fabs(phi)) {
+ outstruc->errors[i] = 0;
+ }
+ else
+ outstruc->errors[i] = 1;
+ continue;
+ FD6:
+ if (hs<0) {
+ hf = hbar;
+ phi = phi2 = ef = 0.0;
+ errval = 2;
+ }
+ else if (hs > 0 && c2 > 0.1) {
+ hf = hs;
+ wrk[i] = invals[i] + hf;
+ fplus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i];
+ phi = (fplus-u)/hf;
+ phi2 = 0.0;
+ ef = 2.0*eps[i]/hf ;
+ errval = 3;
+ }
+ else {
+ hf = hk;
+ wrk[i] = invals[i] + hf;
+ fplus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ phi = (fplus-u)/hf;
+ wrk[i] = invals[i] - hf;
+ fminus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i];
+ phic = (fplus-fminus)/(2.0*hf);
+ ef = hf*fabs(phi2)*0.5 + 2.0*eps[i]/hf ;
+ errval = 4;
+ }
+ outstruc->hf[i] = hf;
+ outstruc->phi[i] = phi;
+ outstruc->phic[i] = phic;
+ outstruc->phi2[i] = phi2;
+ outstruc->ef[i] = ef;
+ outstruc->errors[i] = errval;
+ // #endif
+ }
+ return outstruc;
+}
+
+void fdestimates(SEXP fn, SEXP rho,
+ int parm, double fvalue, double *invals, double *wrk,
+ double eps, double h,
+ double *fplus, double *fminus,
+ double *phif, double *phib, double *phic, double *phi2,
+ double *cf, double *cb, double *c2,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ int nparms, short MinMax, short BoundaryEnforcement, double **Domains)
+{
+ double ih = 1.0/h;
+
+ wrk[parm] = invals[parm] + h;
+ *fplus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[parm] = invals[parm] - h;
+ *fminus = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[parm] = invals[parm];
+ *phif = (*fplus-fvalue) * ih;
+ *phib = (fvalue-*fminus) * ih;
+ *phic = (*fplus-*fminus) * 0.5 * ih;
+ *phi2 = (*phif-*phib) * ih;
+ *cf = 2.0*eps*ih/fabs(*phif);
+ *cb = 2.0*eps*ih/fabs(*phib);
+ *c2 = 4.0*eps*ih*ih/fabs(*phi2);
+}
+
+/* put strict lower triangle of numerical hessian into instruc->hessian */
+/* instruc should have been set by algfd */
+struct estints *numhessian(struct estints *instruc, double *invals, double *wrk,
+ double (*func)(double *))
+{
+ int nparms;
+ double *fplusi = NULL;
+
+ int i,j;
+ double hi, hj, ih, jh;
+ double fvalue, fplus, phi2;
+
+ nparms = instruc->nparms;
+ fplusi = (double *) malloc(nparms*sizeof(double));
+
+
+ /* allocate storage for the hessian */
+ instruc->hessian = (double *) calloc((nparms*(nparms+1))/2,sizeof(double));
+
+ /* evaluate func at the input point */
+ fvalue = func(invals);
+
+ /* copy the parameter values for point at which to evaluate the gradient */
+ for (i=0; i<nparms; i++) wrk[i] = invals[i];
+
+ for (i=0; i<nparms; i++) {
+ wrk[i] = invals[i] + instruc->hf[i];
+ fplusi[i] = func(wrk);
+ wrk[i] = invals[i];
+ }
+ for (i=1; i<nparms; i++) {
+ hi = instruc->hf[i];
+ ih = 1.0/hi;
+ wrk[i] = invals[i] + hi;
+ for (j=0; j<i; j++) {
+ hj = instruc->hf[j];
+ jh = 1.0/hj;
+ wrk[j] = invals[j] + hj;
+ fplus = func(wrk);
+ wrk[j] = invals[j];
+ phi2 = (fplus - fplusi[i] - fplusi[j] + fvalue) * ih * jh;
+ instruc->hessian[(i*(i-1))/2 + j] = phi2;
+ }
+ wrk[i] = invals[i];
+ }
+
+ free(fplusi);
+ return instruc;
+}
+
+/* put strict lower triangle of numerical hessian into instruc->hessian */
+/* uses central differences: */
+/* phi2 =
+ f(x+hj ej+hi ei) - f(x+hj ej-hi ei) - f(x-hj ej+hi ei) + f(x-hj ej-hi ei) */
+/* instruc should have been set by algfd */
+struct estints *numhessianc(SEXP fn, SEXP rho,
+ struct estints *instruc, double *invals, double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains)
+{
+ int nparms;
+ int nelems;
+ double *fplusi;
+ double *fminusi;
+ double *fppi;
+ double *fpmi;
+ double *fmmi;
+
+ int i,j, idx;
+ double hi, hj, ih, jh;
+ // double fvalue, fplus, fminus, phi2;
+ double fvalue, phi2;
+
+ nparms = instruc->nparms;
+ nelems = (nparms*(nparms-1))/2;
+ fplusi = (double *) malloc(nparms*sizeof(double));
+ fminusi = (double *) malloc(nparms*sizeof(double));
+ fppi = (double *) malloc(nelems*sizeof(double));
+ fpmi = (double *) malloc(nparms*nparms*sizeof(double));
+ fmmi = (double *) malloc(nelems*sizeof(double));
+
+ /* allocate storage for the hessian */
+ instruc->hessian = (double *) calloc(nelems,sizeof(double));
+
+ /* evaluate func at the input point */
+ fvalue = func(fn, rho, invals, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ /* copy the parameter values for point at which to evaluate the gradient */
+ for (i=0; i<nparms; i++) wrk[i] = invals[i];
+
+ for (i=0; i<nparms; i++) {
+ hi = pow(instruc->hf[i], 2.0/3.0);
+ idx = (i*(i-1))/2;
+ wrk[i] = invals[i] + 2.0*hi;
+ fplusi[i] = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i] - 2.0*hi;
+ fminusi[i] = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ for (j=0; j<i; j++) {
+ hj = pow(instruc->hf[j], 2.0/3.0);
+ wrk[i] = invals[i] + hi;
+ wrk[j] = invals[j] + hj;
+ fppi[idx + j] = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i] + hi;
+ wrk[j] = invals[j] - hj;
+ fpmi[i*nparms + j] = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i] - hi;
+ wrk[j] = invals[j] + hj;
+ fpmi[j*nparms + i] = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[i] = invals[i] - hi;
+ wrk[j] = invals[j] - hj;
+ fmmi[idx + j] = func(fn, rho, wrk, nparms, MinMax, BoundaryEnforcement, Domains);
+
+ wrk[j] = invals[j];
+ }
+ wrk[i] = invals[i];
+ }
+ for (i=0; i<nparms; i++) {
+ hi = pow(instruc->hf[i], 2.0/3.0);
+ ih = 1.0/hi;
+ idx = (i*(i-1))/2;
+ phi2 = (fplusi[i] - 2.0*fvalue + fminusi[i]) * ih * ih * 0.25;
+ instruc->phi2[i] = phi2;
+ for (j=0; j<i; j++) {
+ hj = pow(instruc->hf[j], 2.0/3.0);
+ jh = 1.0/hj;
+ phi2 = (fppi[idx+j] - fpmi[j*nparms+i] - fpmi[i*nparms+j] + fmmi[idx+j])
+ * ih * jh * 0.25;
+ instruc->hessian[idx + j] = phi2;
+ }
+ }
+
+ free(fmmi);
+ free(fpmi);
+ free(fppi);
+ free(fplusi);
+
+ return instruc;
+}
+
+void estoptint(SEXP fn, SEXP rho,
+ double *epsacc, double *optint,
+ int nparms, int ndiffs, int pflag, double *invals,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax, short BoundaryEnforcement,
+ double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains)
+{
+ double *wrk;
+
+ int i,j,k;
+ // int nsteps=1+2*ndiffs, nrows=nparms*nsteps, ncols=ndiffs+1;
+ int nsteps=1+2*ndiffs;
+ double h, beta, dwrk;
+ double **table;
+ struct estints *estructure;
+
+ wrk = (double *) malloc(nparms*(ndiffs+1)*sizeof(double));
+
+ h = 0.0000002;
+
+ table = eaccuracy(fn, rho, nparms, ndiffs, h, invals, wrk, func, MinMax,
+ BoundaryEnforcement, Domains);
+
+ for (i=0; i<nparms*ndiffs; i++) wrk[i] = 0.0;
+
+ for (i=0; i<nparms; i++) {
+ for (j=0; j<ndiffs; j++) {
+ for (k=1; k<=ndiffs; k++) {
+ /* find largest difference of each order for each parm */
+ dwrk = fabs(table[j+1][i*nsteps+k]);
+ if (wrk[i*ndiffs+j] < dwrk) wrk[i*ndiffs+j] = dwrk;
+ }
+ beta = sqrt(VMgamma(1.0+2.0*(1.0+(double)j))/pow(VMgamma(2.0+(double)j),2.0));
+ wrk[i*ndiffs+j] /= beta;
+ }
+ }
+ /* put estimates for highest difference order into epsacc */
+ for (i=0; i<nparms; i++) {
+ dwrk = wrk[i*ndiffs+ndiffs-1];
+ /* make sure epsacc values >= EPS */
+ epsacc[i] = (dwrk > EPS ? dwrk : EPS) ;
+ }
+
+#ifdef NEVERDEFINED
+ Rprintf("accuracy estimates:\n");
+ for (i=0; i<nparms; i++) {
+ Rprintf("parm = %d\n", i+1);
+ for (j=0; j<ndiffs; j++) {
+ Rprintf(" %14.7e", wrk[i*ndiffs+j]);
+ }
+ Rprintf("\n");
+ }
+
+ Rprintf("difference table:\n");
+ for (i=0; i<nparms; i++) {
+ Rprintf("parm = %d\n", i+1);
+ for (j=0; j<=ndiffs; j++) {
+ for (k=0; k<=ndiffs; k++) {
+ Rprintf(" %14.7e", table[j][i*nsteps+k]);
+ }
+ Rprintf("\n");
+ }
+ }
+#endif
+
+ estructure = algfd(fn, rho, nparms, epsacc, invals, wrk, func, MinMax,
+ BoundaryEnforcement, Domains);
+
+ if (pflag==1) {
+ Rprintf("err interval f' fc' f'' errorbound\n");
+ for (i=0; i<nparms; i++) {
+ Rprintf(" %d ", estructure->errors[i]);
+ Rprintf(" %17.10e", estructure->hf[i]);
+ Rprintf(" %17.10e", estructure->phi[i]);
+ Rprintf(" %17.10e", estructure->phic[i]);
+ Rprintf(" %17.10e", estructure->phi2[i]);
+ Rprintf(" %17.10e", estructure->ef[i]);
+ Rprintf("\n");
+ }
+ }
+
+ /* put estimates for optimal interval into optint */
+ for (i=0; i<nparms; i++) {
+ optint[i] = estructure->hf[i];
+ }
+
+ free(table);
+ free(wrk);
+ /* free the estructure */
+ free(estructure->errors);
+ free(estructure->hf);
+ free(estructure->phi);
+ free(estructure->phic);
+ free(estructure->phi2);
+ free(estructure->ef);
+ free(estructure);
+}
+
+void dohessians(SEXP fn, SEXP rho,
+ double *epsacc,
+ int nparms, int nobs, int ndiffs, double *invals,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcment, double **Domains),
+ double (*funco)(double *, double *),
+ short MinMax, short BoundaryEnforcement, double **Domains)
+{
+ double *wrk;
+
+ int i,j;
+ // int nsteps=1+2*ndiffs, nrows=nparms*nsteps, ncols=ndiffs+1;
+ // int nsteps=1+2*ndiffs;
+ struct estints *estructure;
+
+ // double *opg;
+
+ wrk = (double *) malloc(nparms*(ndiffs+1)*sizeof(double));
+
+ estructure = algfd(fn, rho, nparms, epsacc, invals, wrk, func, MinMax,
+ BoundaryEnforcement, Domains);
+
+#ifdef NEVERDEFINED
+ /* numerical hessian, using forward differences for off-diagonal elements */
+ numhessian(estructure, invals, wrk, func);
+ Rprintf("numerical hessian, forward differences:\n");
+ for (i=0; i<nparms; i++) {
+ for (j=0; j<nparms; j++) {
+ if (i==j)
+ Rprintf(" %19.12e", estructure->phi2[i] / 2.0);
+ else if (i>j)
+ Rprintf(" %19.12e", estructure->hessian[(i*(i-1))/2 + j] / 2.0);
+ else if (j>i)
+ Rprintf(" %19.12e", estructure->hessian[(j*(j-1))/2 + i] / 2.0);
+ }
+ Rprintf("\n");
+ }
+ /* fflush(stdout); */
+#endif
+
+ /* numerical hessian, using central differences */
+ numhessianc(fn, rho, estructure, invals, wrk, func, MinMax, BoundaryEnforcement,
+ Domains);
+
+ Rprintf("numerical hessian, central differences:\n");
+ for (i=0; i<nparms; i++) {
+ for (j=0; j<nparms; j++) {
+ if (i==j)
+ Rprintf(" %19.12e", estructure->phi2[i] / 2.0);
+ else if (i>j)
+ Rprintf(" %19.12e", estructure->hessian[(i*(i-1))/2 + j] / 2.0);
+ else if (j>i)
+ Rprintf(" %19.12e", estructure->hessian[(j*(j-1))/2 + i] / 2.0);
+ }
+ Rprintf("\n");
+ }
+ /* fflush(stdout); */
+
+#ifdef NEVERDEFINED
+ /* numerical outer product of gradients, using central differences */
+ if (funco != NULL) {
+ opg = numopgc(nparms, nobs, invals, opg, wrk, funco);
+ Rprintf("numerical outer product of gradients, central differences:\n");
+ for (i=0; i<nparms; i++) {
+ for (j=0; j<nparms; j++)
+ Rprintf(" %19.12e", opg[i*nparms+j] / 2.0);
+ Rprintf("\n");
+ }
+ /* fflush(stdout); */
+ }
+#endif
+
+ free(wrk);
+}
diff --git a/src/gradient.h b/src/gradient.h
new file mode 100644
index 0000000..54f4849
--- /dev/null
+++ b/src/gradient.h
@@ -0,0 +1,111 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ $Header: /home/jsekhon/xchg/genoud/rgenoud.distribution/sources/RCS/gradient.h,v 2.15 2005/10/29 06:14:44 jsekhon Exp jsekhon $
+
+*/
+
+#define EPS 0.000000000000001 /* machine precision */
+
+void gradient(SEXP fn, SEXP rho,
+ double *p, double *g, long nparms, short MinMax, short BoundaryEnforcement,
+ double **Domains);
+
+double func4g(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax, short BoundaryEnforcement,
+ double **Domains);
+
+void numgrad(SEXP fn, SEXP rho,
+ double *epsacc, double *optint,
+ int nparms, double *invals, double *grads, double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, int nvars, short int MinMax),
+ short MinMax);
+
+void numgradc(SEXP fn, SEXP rho,
+ double *epsacc, double *optint,
+ int nparms, double *invals, double *grads, double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains);
+
+extern double *numopgc(double *epsacc, double *optint,
+ int nparms, int nobs, double *invals, double *opg, double *wrk,
+ int (*func)(double *X, double *outvec));
+
+double **eaccuracy(SEXP fn, SEXP rho,
+ int nparms, int ndiffs, double h, double *invals,
+ double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains);
+
+struct estints {
+ int nparms;
+ int *errors; /* 0 == OK, >=1 == error */
+ double
+ *hf, /* interval */
+ *phi, /* f' (first derivative) */
+ *phic, /* f' (first derivative, central-difference) */
+ *phi2, /* f'' (second derivative) */
+ *ef, /* error bound */
+ *hessian; /* hessian matrix (lower triangle) */
+};
+
+struct estints *algfd(SEXP fn, SEXP rho,
+ int nparms, double *eps, double *invals, double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains);
+
+void fdestimates(SEXP fn, SEXP rho,
+ int parm, double fvalue, double *invals, double *wrk,
+ double eps, double h,
+ double *fplus, double *fminus,
+ double *phif, double *phib, double *phic, double *phi2,
+ double *cf, double *cb, double *c2,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ int nparms, short MinMax, short BoundaryEnforcement, double **Domains);
+
+struct estints *numhessian(struct estints *instruc, double *invals, double *wrk,
+ double (*func)(double *));
+
+struct estints *numhessianc(SEXP fn, SEXP rho,
+ struct estints *instruc, double *invals, double *wrk,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcement, double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains);
+
+void estoptint(SEXP fn, SEXP rho,
+ double *epsacc, double *optint,
+ int nparms, int ndiffs, int pflag, double *invals,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax, short BoundaryEnforcement,
+ double **Domains),
+ short MinMax, short BoundaryEnforcement, double **Domains);
+
+void dohessians(SEXP fn, SEXP rho,
+ double *epsacc,
+ int nparms, int nobs, int ndiffs, double *invals,
+ double (*func)(SEXP fn, SEXP rho,
+ double *X, long nvars, short MinMax,
+ short BoundaryEnforcment, double **Domains),
+ double (*funco)(double *, double *),
+ short MinMax, short BoundaryEnforcement, double **Domains);
diff --git a/src/math.cpp b/src/math.cpp
new file mode 100644
index 0000000..3b3e61c
--- /dev/null
+++ b/src/math.cpp
@@ -0,0 +1,360 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ June 3, 2012
+
+*/
+
+#include "genoud.h"
+
+void add(double *in1, double *in2, double
+ *out, int row, int col)
+{ int i, j, idx;
+
+ for (i=0;i<row;i++) {
+ for (j=0;j<col;j++) {
+ idx=M(i,j,col);
+ out[idx]=in1[idx]+in2[idx];
+ }
+ }
+}
+
+
+void copy(double *in, double *target, int row, int col)
+{
+ int i, j, idx;
+
+ for (i=0;i<row;i++) {
+ for (j=0;j<col;j++) {
+ idx=M(i,j,col);
+ target[idx]=in[idx];
+ }
+ }
+}
+
+
+void multi(double *in1, double *in2, double *out,
+ int row1, int col1, int row2, int col2, int outrowcol[2],
+ FILE *output)
+{
+ int oi, oj, i;
+
+if (col1!=row2) {
+ error("The matrices are not conformable for muliplication\n");
+}
+
+outrowcol[0]=row1;
+outrowcol[1]=col2;
+
+for (oi=0;oi<outrowcol[0];oi++) {
+ for (oj=0;oj<outrowcol[1];oj++) {
+ out[M(oi,oj,outrowcol[1])] = 0.0;
+ }
+}
+
+for (oi=0;oi<outrowcol[0];oi++) {
+ for (oj=0;oj<outrowcol[1];oj++) {
+ for (i=0;i<col1;i++) {
+ out[M(oi,oj,outrowcol[1])] += in1[M(oi,i,col1)]*in2[M(i,oj,col2)];
+
+ }
+ }
+}
+
+} /* end of multi.c */
+
+
+
+void scalarmulti(double scalar, double *in1, double *out, int row, int col)
+{
+ int i, j, idx;
+
+ for (i=0;i<row;i++) {
+ for (j=0;j<col;j++) {
+ idx=M(i,j,col);
+ out[idx]=scalar*in1[idx];
+ }
+ }
+}
+
+void scalarmultioffdiag(double scalar, double *in1, double *out, int row, int col)
+{
+ int i, j, idx;
+
+ for (i=0;i<row;i++) {
+ for (j=0;j<col;j++) {
+ idx=M(i,j,col);
+ if (i==j)
+ out[idx] = in1[idx];
+ else
+ out[idx] = scalar*in1[idx];
+ }
+ }
+}
+
+void subtract(double *in1, double *in2,
+ double *out, int row, int col) { int i, j, idx;
+
+ for (i=0;i<row;i++) {
+ for (j=0;j<col;j++) {
+ idx=M(i,j,col);
+ out[idx]=in1[idx]-in2[idx];
+ }
+ }
+}
+
+double trace(double *a, int n)
+{
+
+int i;
+double out;
+out=0.0;
+
+ for (i=0;i<n;i++) {
+ out += a[M(i,i,n)];
+}
+
+ return out;
+}
+
+
+void transpose(double *orig_matrix,
+ double *t_matrix,
+ int orig_rows, int orig_columns)
+{
+ int i, j, idx, t_idx;
+
+
+ for(i=0;i<orig_rows;i++) {
+ for(j=0;j<orig_columns;j++) {
+ idx = M(i,j,orig_columns);
+ t_idx = M(j,i,orig_rows);
+ t_matrix[t_idx]=orig_matrix[idx];
+ }
+ }
+
+} /* end transpose */
+
+
+void copy_matrix(MATRIX mat1, MATRIX mat2, int lr, int ur, int lc, int uc)
+ /*
+ int lr,ur,lc,uc;
+ MATRIX mat1,mat2;
+ */
+{
+ int i,j;
+
+ for(i=lr; i<=ur; i++)
+ for(j=lc; j<=uc; j++)
+ mat2[i][j] = mat1[i][j];
+}
+
+
+/* this rounds a double to the closest integer */
+int Iround(double in)
+{
+ double ip, frac;
+
+ frac = modf(in, &ip);
+ if (frac < 0.5) return( (int) ip);
+ else return( (int) ip+ (int) 1.0);
+}
+
+
+/* This function computs some sample statistics */
+void samplestats(double **obsdata, int numobsv, int novarsv, int weightflag,
+ double *weightdata, FILE *output)
+{
+ double *mean, *var, *skew, *kur;
+ double *rmu, *rvar, *rskew, *rkur;
+
+ int i, j, maxnovars, nobs, nvars;
+ double sum[4], x1, x2, wsum, iwsum;
+ double dinobs;
+
+ maxnovars = novarsv;
+
+ mean = (double *) malloc((size_t) maxnovars*sizeof(double));
+ var = (double *) malloc((size_t) maxnovars*sizeof(double));
+ skew = (double *) malloc((size_t) maxnovars*sizeof(double));
+ kur = (double *) malloc((size_t) maxnovars*sizeof(double));
+
+ rmu = (double *) malloc((size_t) maxnovars*sizeof(double));
+ rvar = (double *) malloc((size_t) maxnovars*sizeof(double));
+ rskew = (double *) malloc((size_t) maxnovars*sizeof(double));
+ rkur = (double *) malloc((size_t) maxnovars*sizeof(double));
+
+ nobs = numobsv;
+ nvars = novarsv;
+ dinobs = 1.0 / nobs;
+
+ if (weightflag==0) {
+ for (j=0; j<nvars; j++) {
+ sum[0] = 0.0;
+ for (i=0; i<nobs; i++) {
+ sum[0] += obsdata[i][j];
+ }
+ sum[0] *= dinobs;
+ sum[1] = 0.0; sum[2] = 0.0; sum[3] = 0.0;
+ for (i=0; i<nobs; i++) {
+ x1 = obsdata[i][j] - sum[0];
+ x2 = x1*x1;
+ sum[1] += x2;
+ x2 *= x1;
+ sum[2] += x2;
+ x2 *= x1;
+ sum[3] += x2;
+ }
+ rmu[j] = sum[0];
+ rvar[j] = sum[1] * dinobs;
+ rskew[j] = sum[2] * dinobs;
+ rkur[j] = sum[3] * dinobs;
+ }
+
+ for (j=0; j<nvars; j++) {
+ mean[j] = rmu[j];
+ x1 = rvar[j] ;
+ var[j] = x1;
+ x2 = 1.0 / (x1*x1) ;
+ kur[j] = rkur[j] * x2;
+ skew[j] = rskew[j] * sqrt(x2/x1);
+
+ Rprintf("var %d:\n", j+1);
+ Rprintf("sample mean = %f\n", mean[j]);
+ Rprintf("sample var = %f\n", var[j]);
+ Rprintf("sample skewness = %f\n", skew[j]);
+ Rprintf("sample kurtosis = %f\n", kur[j]);
+ }
+ }
+ else if (weightflag==1) {
+ for (wsum = 0.0, i=0; i<nobs; i++) wsum += weightdata[i];
+ iwsum = 1.0/wsum;
+
+ for (j=0; j<nvars; j++) {
+ sum[0] = 0.0;
+ for (i=0; i<nobs; i++) {
+ sum[0] += obsdata[i][j] * weightdata[i];
+ }
+ sum[0] *= iwsum;
+ sum[1] = 0.0; sum[2] = 0.0; sum[3] = 0.0;
+ for (i=0; i<nobs; i++) {
+ x1 = obsdata[i][j] - sum[0];
+ x2 = x1*x1;
+ sum[1] += x2 * weightdata[i];
+ x2 *= x1;
+ sum[2] += x2 * weightdata[i];
+ x2 *= x1;
+ sum[3] += x2 * weightdata[i];
+ }
+ rmu[j] = sum[0];
+ rvar[j] = sum[1] * iwsum;
+ rskew[j] = sum[2] * iwsum;
+ rkur[j] = sum[3] * iwsum;
+ }
+
+ for (j=0; j<nvars; j++) {
+ mean[j] = rmu[j];
+ x1 = rvar[j] ;
+ var[j] = x1;
+ x2 = 1.0 / (x1*x1) ;
+ kur[j] = rkur[j] * x2;
+ skew[j] = rskew[j] * sqrt(x2/x1);
+
+ Rprintf("var %d:\n", j+1);
+ Rprintf("sample mean = %f\n", mean[j]);
+ Rprintf("sample var = %f\n", var[j]);
+ Rprintf("sample skewness = %f\n", skew[j]);
+ Rprintf("sample kurtosis = %f\n", kur[j]);
+ }
+ }
+
+ /* free data and work storage */
+ free(rkur);
+ free(rskew);
+ free(rvar);
+ free(rmu);
+ free(kur);
+ free(skew);
+ free(var);
+ free(mean);
+}
+
+
+/* This function computs some sample statistics for the population matrix */
+void populationstats(double **popdata, int numobsv, int novarsv,
+ double *mean, double *var, double *skew, double *kur,
+ long *tobs)
+{
+ double *rvar, *rskew, *rkur;
+
+ long i, j, maxnovars, nobs, nvars;
+ double sum[4], x1, x2;
+ double dinobs;
+
+ maxnovars = novarsv+1;
+
+ rvar = (double *) malloc(maxnovars*sizeof(double));
+ rskew = (double *) malloc(maxnovars*sizeof(double));
+ rkur = (double *) malloc(maxnovars*sizeof(double));
+
+ nobs = numobsv;
+ nvars = novarsv;
+ dinobs = 1.0 / nobs;
+
+ for (j=0; j<=nvars; j++) {
+ tobs[j] = nobs;
+ sum[0] = 0.0;
+ for (i=1; i<=nobs; i++) {
+ if (popdata[i][j] > DOUBLEMAX) {
+ tobs[j]=tobs[j]-1;
+ }
+ if (popdata[i][j] < -1*DOUBLEMAX) {
+ tobs[j]=tobs[j]-1;
+ }
+ else sum[0] += popdata[i][j];
+ }
+ dinobs = 1.0/tobs[j];
+ sum[0] *= dinobs;
+ sum[1] = 0.0; sum[2] = 0.0; sum[3] = 0.0;
+ for (i=1; i<=nobs; i++) {
+ if ( (popdata[i][j] < DOUBLEMAX) && (popdata[i][j] > -1*DOUBLEMAX) )
+ {
+ x1 = popdata[i][j] - sum[0];
+ x2 = x1*x1;
+ sum[1] += x2;
+ x2 *= x1;
+ sum[2] += x2;
+ x2 *= x1;
+ sum[3] += x2;
+ } /* end of if */
+ } /* end of i loop */
+ mean[j] = sum[0];
+ rvar[j] = sum[1] * dinobs;
+ rskew[j] = sum[2] * dinobs;
+ rkur[j] = sum[3] * dinobs;
+ } /* end of j loop */
+
+ for (j=0; j<=nvars; j++) {
+ x1 = rvar[j] ;
+ var[j] = x1;
+ x2 = 1.0 / (x1*x1) ;
+ kur[j] = rkur[j] * x2;
+ skew[j] = rskew[j] * sqrt(x2/x1);
+ }
+
+ /* free data and work storage */
+ free(rkur);
+ free(rskew);
+ free(rvar);
+}
diff --git a/src/multiply.cpp b/src/multiply.cpp
new file mode 100644
index 0000000..9275397
--- /dev/null
+++ b/src/multiply.cpp
@@ -0,0 +1,107 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ $Header: /home/jsekhon/xchg/genoud/rgenoud.distribution/sources/RCS/multiply.cpp,v 2.15 2005/10/29 06:14:44 jsekhon Exp jsekhon $
+
+*/
+
+#include "genoud.h"
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : mmprod() */
+/* */
+/* SYNOPSIS : void mmprod(m,nm,n,mul_cm,mul_am,mul_bm) */
+/* */
+/* DESCRIPTION : This function finds the product of two */
+/* double matrices */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : find_org_in_eq(), */
+/* main(). */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void mmprod(int m, int nm, int n, MATRIX mul_cm, MATRIX mul_am, MATRIX mul_bm)
+ /*
+ int m, row of mul_am matrix
+ nm, column of mul_am and row of mul_bm matrices
+ n; row of mul_bm matrix
+ MATRIX mul_cm, the final matrix
+ mul_am, the first matrix to be multiplied
+ mul_bm; the second matrix to be multiplied
+ */
+{
+ int i,j,k; /*counter variables, where i=m, j=nm, k=n*/
+
+ for(i= 1; i<=m; i++)
+ for(j = 1; j<=n; j++)
+ {
+ mul_cm[i][j] = 0.0;
+ for (k= 1;k<nm+1;k++)
+ mul_cm[i][j] = mul_am[i][k]*mul_bm[k][j] + mul_cm[i][j];
+ }
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : mvprod() */
+/* */
+/* SYNOPSIS : void mvprod(m,nm,cm,am,bm) */
+/* */
+/* DESCRIPTION : This function finds the product of a double */
+/* vector and a double matrix */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : find_org_in_eq(), */
+/* main(). */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void mvprod(int m, int nm, VECTOR cm, MATRIX am, VECTOR bm)
+ /*
+ int m, row of matrix am and length of vector cm
+ nm; column of matrix am
+ VECTOR cm, the final vector
+ bm; original vector
+ MATRIX am; original matrix
+ */
+{
+int i,k; /*counter variables, where i=m, k=nm*/
+
+ for (i = 1; i<=m; i++)
+ {
+ cm[i]=0.0;
+ for (k = 1; k<=nm; k++)
+ cm[i] = cm[i] + am[i][k]*bm[k];
+ }
+}
+
diff --git a/src/numerics.cpp b/src/numerics.cpp
new file mode 100644
index 0000000..42b0cd0
--- /dev/null
+++ b/src/numerics.cpp
@@ -0,0 +1,326 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ June 2, 2012
+
+*/
+
+#include "genoud.h"
+
+double **JaMatrixAllocate(long nobs, long nvars)
+{
+ long i;
+ double **M;
+
+ M= (double **) malloc(nobs*sizeof(double *));
+ for (i=0; i<nobs; i++) {
+ M[i] = (double *) malloc(nvars*sizeof(double));
+ }
+ return(M);
+}
+
+void JaMatrixFree(double **M, long nobs)
+{
+ long i;
+
+ if (M == NULL)
+ return;
+ else
+ {
+ for (i=0; i<nobs; i++) {
+ free(M[i]);
+ }
+ }
+ free(M);
+}
+
+short **JaShortMatrixAllocate(long nobs, long nvars)
+{
+ long i;
+ short **M;
+
+ M= (short **) malloc(nobs*sizeof(short *));
+ for (i=0; i<nobs; i++) {
+ M[i] = (short *) malloc(nvars*sizeof(short));
+ }
+ return(M);
+}
+
+void JaShortMatrixFree(double **M, long nobs)
+{
+ long i;
+
+ if (M == NULL)
+ return;
+ else
+ {
+ for (i=0; i<nobs; i++) {
+ free( (short *) M[i]);
+ }
+ }
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : nrerror() */
+/* */
+/* SYNOPSIS : void nrerror(error_text) */
+/* */
+/* DESCRIPTION : This function gives out an error message on */
+/* to the standard output. */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : Gvector() was vector() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+#ifdef NEVERDEFINED
+/* Dated GENOUD Memory run-time error */
+void nrerror(char error_text[])
+{
+ error("Dated GENOUD Memory run-time error...\n %s.\n ...now exiting to system...\n",error_text);
+}
+#endif
+
+/* Dated fault tolerant GENOUD Memory run-time error */
+#ifdef NEVERDEFINED
+void nrerror(char error_text[])
+{
+ warning("Dated GENOUD Memory run-time error...\n %s.\n I SHOULD exit the system, but I will not because of cheap fault tolerance.\n",error_text);
+ return;
+}
+#endif
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : Gvector() */
+/* */
+/* SYNOPSIS : double *Gvector(nl,nh) */
+/* */
+/* DESCRIPTION : This function returns a single dimensional */
+/* double array after allocating memory from */
+/* indices nl to nh */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : find_org_in_eq(), */
+/* initialize_x2(), */
+/* oper1(), */
+/* oper2(), */
+/* oper3(), */
+/* optimization(), */
+/* main(). */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+VECTOR Gvector(int nl, int nh)
+{
+ VECTOR v;
+
+ if (nh < nl)
+ return(NULL);
+
+ v=(double *)malloc((unsigned) (nh-nl+1)*sizeof(double));
+ /* if (!v) nrerror("allocation failure in Gvector()"); */
+ return v-nl;
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : ivector() */
+/* */
+/* SYNOPSIS : int *vector(nl,nh) */
+/* */
+/* DESCRIPTION : This function returns a single dimensional */
+/* integer array after allocating memory from */
+/* indices nl to nh */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : find_probability(), */
+/* initialize_x2(), */
+/* main(), */
+/* optimization(), */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+IVECTOR ivector(int nl, int nh)
+{
+ IVECTOR v;
+
+ if (nh < nl)
+ return(NULL);
+
+ v=(int *)malloc((unsigned) (nh-nl+1)*sizeof(int));
+ /* if (!v) nrerror("allocation failure in ivector()"); */
+ return v-nl;
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : matrix() */
+/* */
+/* SYNOPSIS : double *matrix(nrl,nrh,ncl,nch) */
+/* */
+/* DESCRIPTION : This function returns a two dimensional */
+/* double array after allocating memory for the */
+/* rows from indices nrl to nrh, and for the */
+/* columns from ncl to nch */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : det(), */
+/* find_org_in_eq(), */
+/* initialize_x2(), */
+/* inverse(), */
+/* main(), */
+/* oper4(), */
+/* oper5(), */
+/* optimization(), */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+MATRIX matrix(int nrl, int nrh, int ncl, int nch)
+{
+ int i;
+ MATRIX m;
+
+ if (nrh < nrl)
+ return(NULL);
+ if (nch < ncl)
+ return(NULL);
+
+ m=(double **) malloc((unsigned) (nrh-nrl+1)*sizeof(double*));
+ /* if (!m) nrerror("allocation failure 1 in matrix()"); */
+ m -= nrl;
+
+ for(i=nrl;i<=nrh;i++) {
+ m[i]=(double *) malloc((unsigned) (nch-ncl+1)*sizeof(double));
+ /* if (!m[i]) nrerror("allocation failure 2 in matrix()"); */
+ m[i] -= ncl;
+ }
+ return m;
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : imatrix() */
+/* */
+/* SYNOPSIS : int *imatrix(nrl,nrh,ncl,nch) */
+/* */
+/* DESCRIPTION : This function returns a two dimensional */
+/* integer array after allocating memory for */
+/* the rows from indices nrl to nrh, and for */
+/* the columns from ncl to nch */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : find_probability(), */
+/* */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+IMATRIX imatrix(int nrl, int nrh, int ncl, int nch)
+{
+ int i;
+ IMATRIX m;
+
+ if (nrh < nrl)
+ return(NULL);
+ if (nch < ncl)
+ return(NULL);
+
+ m=(int **)malloc((unsigned) (nrh-nrl+1)*sizeof(int*));
+ /* if (!m) nrerror("allocation failure 1 in imatrix()"); */
+ m -= nrl;
+
+ for(i=nrl;i<=nrh;i++) {
+ m[i]=(int *)malloc((unsigned) (nch-ncl+1)*sizeof(int));
+ /* if (!m[i]) nrerror("allocation failure 2 in imatrix()"); */
+ m[i] -= ncl;
+ }
+ return m;
+}
+
+void free_vector(double *v, int nl)
+{
+ if (v == NULL)
+ return;
+ else
+ free((double*) (v+nl));
+}
+
+void free_ivector(int *v, int nl)
+{
+ if (v == NULL)
+ return;
+ else
+ free((unsigned int*) (v+nl));
+}
+void free_matrix(double **m, int nrl, int nrh, int ncl)
+{
+ int i;
+
+ if (m == NULL)
+ return;
+ else
+ {
+ for(i=nrh;i>=nrl;i--) free((double*) (m[i]+ncl));
+ free((double*) (m+nrl));
+ }
+}
+void free_imatrix(int **m, int nrl, int nrh, int ncl)
+{
+ int i;
+
+ if (m == NULL)
+ return;
+ else
+ {
+ for(i=nrh;i>=nrl;i--) free((unsigned int*) (m[i]+ncl));
+ free((unsigned int*) (m+nrl));
+ }
+}
+
diff --git a/src/operators.cpp b/src/operators.cpp
new file mode 100644
index 0000000..4aa100c
--- /dev/null
+++ b/src/operators.cpp
@@ -0,0 +1,1182 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ University of Michigan
+ http://www-personal.umich.edu/~wmebane/
+ <wmebane at umich.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ May 6, 2013
+
+*/
+
+#include "genoud.h"
+
+extern "C"
+{
+ double genoud_optim(SEXP fn_optim, SEXP rho, double *X, long parameters);
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper1() */
+/* Uniform Mutation */
+/* */
+/* SYNOPSIS : void oper1(parent,domains,nvars) */
+/* */
+/* DESCRIPTION : This function returns a new vector generated */
+/* from the parent vector, after applying */
+/* the operator, uniform mutation. */
+/* */
+/********************************************************************************/
+
+void oper1(VECTOR parent, double **domains, int nvars)
+ /* VECTOR parent; The parent vector*/
+{
+ int comp;
+ double llim,ulim;/*Lower and Upper limits of the value to be mutated*/
+
+ FLAG SAME;
+ double tmp;
+ long count;
+
+ count=0;
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+
+ comp = irange_ran(1,nvars);
+
+ /*Finding the lower and upper limits between which the values are to be mutated*/
+ find_range(&llim,&ulim,comp,domains,nvars,parent);
+
+ /*Find a random value between the lower and the upper limits, to substitute*/
+ /*for the old value*/
+ tmp = frange_ran(llim,ulim);
+
+ if ( parent[comp] != tmp)
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+ } /* end of while */
+
+ parent[comp] = tmp;
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper2() */
+/* Boundary Mutatation */
+/* No Uniqueness checking here */
+/* Don't use this oper often! */
+/* */
+/********************************************************************************/
+
+
+void oper2(VECTOR parent, double **domains, int nvars)
+ /* VECTOR parent; The parent vector*/
+ /* MATRIX fin_mat; The final matrix*/
+{
+ int comp;
+ double llim,ulim;/*Lower and Upper limits of the value to be mutated*/
+
+ FLAG SAME;
+ double tmp;
+ long count;
+
+ count=0;
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+
+ comp = irange_ran(1,nvars);
+
+ /*Finding the lower and upper limits between which the values are to be mutated*/
+ find_range(&llim,&ulim,comp,domains,nvars,parent);
+
+ /*Replace either the lower limit or the upper limit at random,*/
+ /*for the old value*/
+ tmp = (flip() == TAIL) ? llim : ulim;
+
+ if ( tmp != parent[comp])
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+ } /* end of while */
+
+ parent[comp] = tmp;
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper3() */
+/* */
+/* SYNOPSIS : void oper3(parent,fin_mat,r,c,T,t,B) */
+/* */
+/********************************************************************************/
+
+void oper3(VECTOR parent, double **domains, int nvars, int T, int t, int B)
+ /* VECTOR parent; */
+ /* unsigned long T; Total number of generations*/
+ /* unsigned long t; Current generation number*/
+ /* int B; */
+{
+ int comp;
+ double llim,ulim;
+
+ FLAG SAME;
+ double tmp;
+ long count;
+
+ count=0;
+
+ SAME=TRUE;
+ while (SAME==TRUE) {
+ count++;
+
+ comp = irange_ran(1,nvars);
+ find_range(&llim,&ulim,comp,domains,nvars,parent);
+
+ /*From the current value of the component to be mutated, chooose at random*/
+ /*whether to mutate with a lesser value or a greater value*/
+ /*Then find a value lesser or greater than the original value from the*/
+ /*function get_f()*/
+ tmp = (flip() == TAIL) ? parent[comp]-get_F(T,t,parent[comp]-llim,B) :
+ parent[comp]+get_F(T,t,ulim-parent[comp],B);
+
+ if ( parent[comp] != tmp)
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+ } /* end of while */
+
+ parent[comp] = tmp;
+}
+
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper4() */
+/* Polytope Crossover */
+/* */
+/* */
+/********************************************************************************/
+
+void oper4(MATRIX p, int p2use, int nvars)
+ /* int p The parents chosen for crossover */
+ /* p2use; number of parents (rows) in p */
+ /* int nvars Length of the parameter vector (cols in p) */
+{
+ double *A, sum;
+ int i,k;
+
+ A = (double *) malloc((p2use+1)*sizeof(double));
+
+ sum=0.0;
+ for (k=1; k<=p2use; k++) {
+ do
+ A[k] = frange_ran(0.0,1.0);
+ while (A[k]==0.0); /* insure A[k] is above 0.0 */
+ sum += A[k];
+ }
+ sum = 1.0/sum;
+ for (k=1; k<=p2use; k++) { /* rescale A[k] to sum to 1.0 */
+ A[k] *= sum;
+ }
+
+ for(i=1; i<=nvars; i++) {
+ sum = p[1][i] * A[1];
+ for (k=2; k<=p2use; k++)
+ sum += p[k][i] * A[k];
+ p[1][i] = sum;
+ }
+
+ free(A);
+} /* end of oper4 */
+
+#ifdef NEVERDEFINED
+/* This is the arithmetic crossover operator */
+void oper4(VECTOR p1, VECTOR p2, int nvars)
+ /* VECTOR p1,p2; The two parents chosen for crossover*/
+ /* int nvars; Length of the vector*/
+{
+ double **child;
+ long i;
+ double A;
+
+ FLAG SAME;
+ long count, tcount;
+
+ child = JaMatrixAllocate(3, nvars+1);
+
+ count=0;
+
+ SAME=TRUE;
+ while (SAME==TRUE) {
+ count++;
+
+ do
+ A = frange_ran(0.0,1.0);
+ while (A==0); /* insure A is above 0 */
+
+ for(i=1; i<=nvars; i++)
+ {
+ child[1][i] = p1[i] * A + p2[i] * (1.0-A);
+ child[2][i] = p2[i] * A + p1[i] * (1.0-A);
+ }
+
+ if (count >= MAX_OPER_UNIQUE_TRY)
+ {
+ SAME=FALSE;
+ break;
+ }
+
+ /* Are the two new individuals unique? */
+ tcount=0;
+ for (i=1; i<=nvars; i++) {
+ if ( (int) child[1][i] != (int) p1[i] )
+ tcount++;
+
+ if ( (int) child[2][i] != (int) p2[i] )
+ tcount++;
+ } /* end of i loop */
+
+ if (tcount==(nvars*2)) SAME=FALSE;
+ } /* end of while */
+
+ for(i=1; i<=nvars; i++)
+ {
+ p1[i] = child[1][i];
+ p2[i] = child[2][i];
+ }
+
+ JaMatrixFree(child, 3);
+} /* end of oper4() */
+#endif
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper5() */
+/* Simple Crossover */
+/* */
+/********************************************************************************/
+
+void oper5(VECTOR p1, VECTOR p2, int STEP, double **domains, int nvars)
+ /* VECTOR p1,p2; *The two parents for crossing over*/
+ /* int STEP; *Parameter for the crossover*/
+{
+ MATRIX child;
+ FLAG BFLAG1 = FALSE,/*Check to see if the newly created vectors satisfies the*/
+ BFLAG2 = FALSE;/*set of constraints*/
+ int i,n=1,cut;
+
+ /* unique check variables */
+ FLAG SAME;
+ int count, tcount, ccount;
+
+ child = matrix(1,2,1,nvars);
+
+ count=0;
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+
+ /*Get a random spot on the vector for crossover*/
+ cut = irange_ran(1,nvars);
+ /*Copy the parent vectors on to the child vectors*/
+ for(i=1; i<=cut; i++)
+ {
+ child[1][i] = p1[i];
+ child[2][i] = p2[i];
+ }
+ do
+ {
+ /*Cross the two vectors*/
+ ccount = 0;
+ for(i=cut + 1; i<=nvars; i++)
+ {
+ child[1][i] = p1[i] * (double)n/(double)STEP + p2[i] * (1.0-(double)n/(double)STEP);
+ child[2][i] = p2[i] * (double)n/(double)STEP + p1[i] * (1.0-(double)n/(double)STEP);
+ ccount++;
+ }
+
+ /*Check to see if they satisfy the constraints*/
+ BFLAG1 = InBounds(child[1],domains,nvars);
+ BFLAG2 = InBounds(child[2],domains,nvars);
+ n++;
+ /*If the constraints not satisfied, then generate another*/
+ /*set of crossed over values*/
+ }while((n<=STEP) && ((BFLAG1 == FALSE) || (BFLAG2 == FALSE)));
+
+ /* Are the two new individuals unique? */
+ if (count >= MAX_OPER_UNIQUE_TRY)
+ {
+ SAME=FALSE;
+ break;
+ }
+
+ tcount=0;
+ for (i=cut+1; i<=nvars; i++) {
+ if ( child[1][i] != p1[i] )
+ tcount++;
+
+ if ( child[2][i] != p2[i] )
+ tcount++;
+ } /* end of i loop */
+
+ if (tcount>=(ccount*2)) SAME=FALSE;
+
+ } /* end of while (SAME==TRUE) */
+
+ if (BFLAG1==TRUE && BFLAG2==TRUE)
+ {
+ for(i=1; i<=nvars; i++)
+ {
+ p1[i] = child[1][i];
+ p2[i] = child[2][i];
+ }
+ }
+
+ free_matrix(child,1,2,1);
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper6() */
+/* Whole Non-Uniform Mutation */
+/* */
+/********************************************************************************/
+
+
+void oper6(VECTOR parent, double **domains, int nvars, int T, int t, int B)
+ /* VECTOR parent;
+ MATRIX fin_mat;
+ unsigned long T; Total number of generations
+ unsigned long t; Current generation number
+ int B; */
+{
+ int i;
+ double llim,ulim;
+
+ /* unique check variables */
+ FLAG SAME;
+ long count;
+ double tmp=0;
+
+ count=0;
+ SAME=TRUE;
+
+ while (SAME==TRUE)
+ {
+ for (i=1; i<=nvars; i++)
+ {
+ count++;
+ find_range(&llim,&ulim,i,domains,nvars,parent);
+
+ /*From the current value of the component to be mutated, chooose at random*/
+ /*whether to mutate with a lesser value or a greater value*/
+ /*Then find a value lesser or greater than the original value from the*/
+ /*function get_f()*/
+ tmp = (flip() == TAIL) ? parent[i]-get_F(T,t,parent[i]-llim,B) :
+ parent[i]+get_F(T,t,ulim-parent[i],B);
+
+ if ( parent[i] != tmp)
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+
+ parent[i] = tmp;
+ }//end of for loop
+ } // end of while loop
+}//oper6
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper7() */
+/* Heuristic Crossover */
+/* */
+/********************************************************************************/
+
+void oper7(VECTOR p1, VECTOR p2, double **domains, int nvars)
+{
+ VECTOR child;
+ FLAG BFLAG = FALSE;/*Check to see if the newly created vector satisfies the*/
+ /*set of constraints*/
+ int i,n=2,tries=MAX_OPER_UNIQUE_TRY;
+ double A;
+
+ /* unique check variables */
+ FLAG SAME;
+ long count;
+
+ child = Gvector(1,nvars);
+
+ count=0;
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+
+ do
+ {
+ A = frange_ran(0.0,1.0);
+ for(i=1; i<=nvars; i++)
+ child[i] = ( A * (p2[i] - p1[i]) + p2[i] );
+
+ /*Check to see if it satisfies the constraints*/
+ BFLAG = InBounds(child,domains,nvars);
+ n++;
+ /*If the constraints not satisfied, then try again */
+ }
+ while((n<=tries) && (BFLAG == FALSE));
+
+ /* Is the new individual unique? */
+ if (count >= MAX_OPER_UNIQUE_TRY)
+ {
+ SAME=FALSE;
+ break;
+ }
+
+ for (i=1; i<=nvars; i++) {
+ if ( child[i] != p1[i] ) {
+ SAME=FALSE;
+ break;
+ }
+ }
+
+ } /* end of while SAME loop */
+
+ if (BFLAG==TRUE)
+ {
+ for(i=1; i<=nvars; i++)
+ p1[i] = child[i];
+ }
+
+
+ free_vector(child,1);
+} /* end of oper7() */
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_range() */
+/* */
+/* SYNOPSIS : void find_range(llim,ulim,domains,nvars, */
+/* parent */
+/* */
+/* DESCRIPTION : This function finds the upper and lower */
+/* limits, within which the mutation should */
+/* occur. */
+/* */
+/********************************************************************************/
+
+void find_range(double *llim, double *ulim, int comp, double **domains, int nvars, VECTOR parent)
+ /* double *llim,*ulim; Upper and lower limits*/
+ /* int comp; Component of the vector to be mutated*/
+ /* VECTOR parent; The vector with the values of the variables*/
+{
+ double A, B;
+
+ A = frange_ran(0.0,1.0);
+ B = 1.0 - A;
+
+ *llim = (A*domains[comp][1]) + B* parent[comp];
+
+ A = frange_ran(0.0,1.0);
+ B = 1.0 - A;
+
+ *ulim = B * parent[comp] + (A*domains[comp][3]);
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : find_rangeInt() */
+/* */
+/* SYNOPSIS : void find_range(llim,ulim,domains,nvars, */
+/* parent */
+/* */
+/* DESCRIPTION : This function finds the upper and lower */
+/* limits, within which the mutation should */
+/* occur. */
+/* */
+/********************************************************************************/
+
+void find_rangeInt(int *llim, int *ulim, int comp, double **domains, int nvars, VECTOR parent)
+ /* int *llim,*ulim; Upper and lower limits*/
+ /* int comp; Component of the vector to be mutated*/
+ /* VECTOR parent; The vector with the values of the variables*/
+{
+ double A, B;
+
+ A = frange_ran(0.0,1.0);
+ B = 1.0 - A;
+
+ *llim = (int) ( (A*domains[comp][1]) + B* parent[comp]);
+ if( (int) domains[comp][1] > *llim)
+ *llim = (int) domains[comp][1];
+
+ A = frange_ran(0.0,1.0);
+ B = 1.0 - A;
+
+ *ulim = (int) ( B * parent[comp] + (A*domains[comp][3]) );
+ if( (int) domains[comp][3] < *ulim)
+ *ulim = (int) domains[comp][3];
+
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : irange_ran() */
+/* */
+/* SYNOPSIS : int irange_ran(llim,ulim) */
+/* */
+/* DESCRIPTION : This function returns a random integer */
+/* between the llim and ulim. */
+/* */
+/********************************************************************************/
+int irange_ran(int llim, int ulim)
+{
+ int num;
+
+ do
+ num = llim + ((int) ((newrand()*(long)(ulim-llim+1))/(long) 65535));
+ while ((num < llim) || (num > ulim));
+ return(num);
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : get_F() */
+/* */
+/* SYNOPSIS : double get_F(T,t,y,B) */
+/* */
+/* DESCRIPTION : This function returns the double value which */
+/* is the evaluated value of the function, */
+/* needed for the operators 3 and 6 */
+/* */
+/********************************************************************************/
+
+double get_F(int T, int t, double y, int B)
+ /*
+ unsigned long t,T;
+ int B;
+ double y;
+ */
+{
+ double factor;
+
+ factor = (double) pow(1.0 - (double)t/(double)T,(double)B);
+ factor = factor * frange_ran(0.0,1.0);
+ if (factor < 0.00001)
+ factor = 0.00001;
+ return(y * factor);
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : oper8() */
+/* Local-Minimum Crossover: bfgs */
+/* */
+/* SYNOPSIS : void oper8(parent,fin_mat,rc) */
+/* */
+/* DESCRIPTION : This function returns a new vector generated */
+/* from the parent vector, after applying */
+/* the operator, BFGS. */
+/* */
+/* */
+/* CALLING FUNCITONS : optimization() */
+/* */
+/********************************************************************************/
+
+void oper8(SEXP fn_optim, SEXP rho,
+ VECTOR parent, MATRIX domains,
+ double SolutionTolerance, long nvars,
+ short BoundaryEnforcement,
+ short PrintLevel,
+ double mix)
+{
+
+ double *parm, *work;
+ long i, j, btest;
+ double bfgsfit;
+ double A, B;
+
+ parm = (double *) malloc((nvars+1)*sizeof(double));
+ work = (double *) malloc((nvars+1)*sizeof(double));
+
+ if( mix < 0)
+ {
+ A = frange_ran(0.0,1.0);
+ }
+ else
+ {
+ A = mix;
+ }
+ B = 1.0 - A;
+
+ for (i=0; i<nvars; i++) {
+ parm[i] = parent[i+1];
+ }
+
+ bfgsfit = genoud_optim(fn_optim, rho, parm, nvars);
+
+ if (BoundaryEnforcement==0) {
+ for(i=1; i<=nvars; i++) {
+ parent[i] = A * parm[i-1] + B * parent[i];
+ }
+ }
+ else {
+ for (j=0; j<20; j++)
+ {
+ btest = 0;
+ for (i=1; i<=nvars; i++)
+ {
+ work[i] = A * parm[i-1] + B * parent[i];
+
+ btest = (domains[i][1] > work[i]) || (work[i] > domains[i][3]) ;
+ /* shrink point until all parameters are in bounds */
+ if (btest)
+ {
+ if(PrintLevel > 1)
+ {
+ Rprintf("NOTE: killing out-of-bounds individual created by bfgs oper(9). fit:%10.8lf\n",bfgsfit);
+ Rprintf("NOTE: oper(9) Parameter: %d \t Value: %e\n\n", i, work[i]);
+ }
+ warning("killed out-of-bounds individual created by bfgs oper(9)");
+ }
+ }
+ if (btest==0) break;
+ A *= 0.5 ;
+ B = 1.0 - A;
+ }
+ if (j<20)
+ {
+ /* leave parent unchanged if not in boundary after 20 halvings */
+ for (i=1; i<=nvars; i++)
+ {
+ parent[i] = work[i];
+ }
+ }
+ }
+
+ free(work);
+ free(parm);
+
+ return ;
+}
+
+/********************************************************************************/
+/* Integer Operators! */
+/* */
+/********************************************************************************/
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : JaIntegerOper1() */
+/* Uniform Mutation */
+/* */
+/* SYNOPSIS : void oper1(parent,fin_mat,rc) */
+/* */
+/* DESCRIPTION : This function returns a new vector generated */
+/* from the parent vector, after applying */
+/* the operator, uniform mutation. */
+/* */
+/********************************************************************************/
+
+void JaIntegerOper1(VECTOR parent, double **domains, int nvars)
+ /* VECTOR parent; The parent vector*/
+ /* MATRIX fin_mat; The final matrix*/
+ /* INDEX rc; Row and column of the final matrix*/
+{
+ long comp;
+ int llim,ulim;/*Lower and Upper limits of the value to be mutated*/
+ FLAG SAME;
+ int tmp;
+ long count;
+
+ count=0;
+
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+ comp = irange_ran(1,nvars);
+
+ /*Finding the lower and upper limits between which the values are to be mutated*/
+ find_rangeInt(&llim,&ulim,comp,domains,nvars,parent);
+
+ /*Find a random value between the lower and the upper limits, to substitute*/
+ /*for the old value*/
+ tmp = irange_ran(llim,ulim);
+
+ if ( (int) parent[comp] != (int) tmp)
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+ } /* end of while */
+
+ parent[comp] = (int) tmp;
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : JaIntegerOper2() */
+/* Boundary Mutatation */
+/* No Uniqueness checking here */
+/* Don't use this oper often! */
+/* */
+/********************************************************************************/
+
+void JaIntegerOper2(VECTOR parent, double **domains, int nvars)
+ /* VECTOR parent; The parent vector*/
+ /* MATRIX fin_mat; The final matrix*/
+ /* INDEX rc; Row and column of the final matrix*/
+{
+ int comp;
+ int llim,ulim;/*Lower and Upper limits of the value to be mutated*/
+
+ FLAG SAME;
+ int tmp;
+ long count;
+
+ count=0;
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+
+ comp = irange_ran(1,nvars);
+
+ /*Finding the lower and upper limits between which the values are to be mutated*/
+ find_rangeInt(&llim,&ulim,comp,domains,nvars,parent);
+
+ /*Replace either the lower limit or the upper limit at random,*/
+ /*for the old value*/
+ tmp = (int) (flip() == TAIL) ? llim : ulim;
+
+ if ( (int) tmp != (int) parent[comp])
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+ } /* end of while */
+
+ parent[comp] = (int) tmp;
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : JaIntegeroper3() */
+/* Non-Uniform Mutation */
+/* */
+/* SYNOPSIS : VECTOR oper3(parent,fin_mat,r,c,T,t,B) */
+/* */
+/* DESCRIPTION : This function returns a new vector generated */
+/* from the parent vector, after applying */
+/* the operator, non-uniform mutation. */
+/* */
+/********************************************************************************/
+
+void JaIntegerOper3(VECTOR parent, double **domains, int nvars, int T, int t, int B)
+ /* VECTOR parent;
+ MATRIX fin_mat;
+ INDEX rc; */
+ /* unsigned long T; Total number of generations*/
+ /* unsigned long t; Current generation number*/
+ /* int B; */
+{
+ int comp;
+ int llim,ulim;
+
+ FLAG SAME;
+ int tmp;
+ long count;
+
+ count=0;
+
+ SAME=TRUE;
+ while (SAME==TRUE) {
+ count++;
+ comp = irange_ran(1,nvars);
+
+ find_rangeInt(&llim,&ulim,comp,domains,nvars,parent);
+
+ /*From the current value of the component to be mutated, chooose at random*/
+ /*whether to mutate with a lesser value or a greater value*/
+ /*Then find a value lesser or greater than the original value from the*/
+ /*function get_f()*/
+ tmp =
+ (int) (flip() == TAIL) ? parent[comp]-get_F(T,t,parent[comp]-llim,B) :
+ parent[comp]+get_F(T,t,ulim-parent[comp],B);
+
+ if ( (int) parent[comp] != (int) tmp)
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+ } /* end of while */
+ parent[comp] = (int) tmp;
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : JaIntegeroper4() */
+/* Polytope Crossover */
+/* */
+/* */
+/********************************************************************************/
+
+void JaIntegeroper4(MATRIX p, int p2use, int nvars, double **domains)
+ /* int p The parents chosen for crossover */
+ /* p2use; number of parents (rows) in p */
+ /* int nvars Length of the parameter vector (cols in p) */
+{
+ double *A, sum;
+ int i,k;
+
+ A = (double *) malloc((p2use+1)*sizeof(double));
+
+ sum=0.0;
+ for (k=1; k<=p2use; k++) {
+ do
+ A[k] = frange_ran(0.0,1.0);
+ while (A[k]==0.0); /* insure A[k] is above 0.0 */
+ sum += A[k];
+ }
+ sum = 1.0/sum;
+ for (k=1; k<=p2use; k++) { /* rescale A[k] to sum to 1.0 */
+ A[k] *= sum;
+ }
+
+ for(i=1; i<=nvars; i++) {
+ sum = p[1][i] * A[1];
+ for (k=2; k<=p2use; k++)
+ sum += p[k][i] * A[k];
+
+ p[1][i] = (int) sum;
+
+ if( (int) domains[i][1] > (int) p[1][i])
+ p[1][i] = (int) domains[i][1];
+ if( (int) domains[i][3] < (int) p[1][i])
+ p[1][i] = (int) domains[i][3];
+ }
+
+ free(A);
+}
+
+
+#ifdef NEVERDEFINED
+void JaIntegerOper4(VECTOR p1, VECTOR p2, int nvars)
+ /* VECTOR p1,p2; The two parents chosen for crossover*/
+ /* int nvars; Length of the vector*/
+{
+ double **child;
+ long i;
+ double A;
+
+ FLAG SAME;
+ long count, tcount;
+
+ child = JaMatrixAllocate(3, nvars+1);
+
+ count=0;
+
+ SAME=TRUE;
+ while (SAME==TRUE) {
+ count++;
+
+ do
+ A = frange_ran(0.0,1.0);
+ while (A==0); /* insure A is above 0 */
+
+ for(i=1; i<=nvars; i++)
+ {
+ child[1][i] = ( p1[i] * A + p2[i] * (1.0-A) );
+ child[2][i] = ( p2[i] * A + p1[i] * (1.0-A) );
+ }
+
+ if (count >= MAX_OPER_UNIQUE_TRY)
+ {
+ SAME=FALSE;
+ break;
+ }
+
+ /* Are the two new individuals unique? */
+ tcount=0;
+ for (i=1; i<=nvars; i++) {
+ if ( (int) child[1][i] != (int) p1[i] )
+ tcount++;
+
+ if ( (int) child[2][i] != (int) p2[i] )
+ tcount++;
+ } /* end of i loop */
+
+ if (tcount==(nvars*2)) SAME=FALSE;
+ } /* end of SAME while */
+
+ for(i=1; i<=nvars; i++)
+ {
+ p1[i] = (int) child[1][i];
+ p2[i] = (int) child[2][i];
+ }
+
+
+ JaMatrixFree(child, 3);
+} /* end of JaIntegerOper4 */
+#endif
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : JaIntegerOper5() */
+/* Simple Crossover */
+/* */
+/* SYNOPSIS : void oper5(p1,p2,STEP,rc,fin_mat,X,x2) */
+/* */
+/* DESCRIPTION : This function returns two new vectors */
+/* generated after simple arithmetical */
+/* crossover, from the two parent vectors. */
+/* */
+/********************************************************************************/
+
+void JaIntegerOper5(VECTOR p1, VECTOR p2, int STEP, double **domains, int nvars)
+ /* VECTOR p1,p2; *The two parents for crossing over*/
+ /* INDEX rc; *Row and column of the final matrix*/
+ /* MATRIX fin_mat; *The final matrix*/
+ /* int STEP; *Parameter for the crossover*/
+{
+ MATRIX child;
+ FLAG BFLAG1 = FALSE,/*Check to see if the newly created vectors satisfies the*/
+ BFLAG2 = FALSE;/*set of constraints*/
+ int i,n=1,cut;
+
+ /* unique check variables */
+ FLAG SAME;
+ int count, tcount, ccount;
+
+
+ child = matrix(1,2,1,nvars);
+
+ count=0;
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+ /*Get a random spot on the vector for crossover*/
+ cut = irange_ran(1,nvars);
+ /*Copy the parent vectors on to the child vectors*/
+ for(i=1; i<=cut; i++)
+ {
+ child[1][i] = p1[i];
+ child[2][i] = p2[i];
+ }
+ do
+ {
+ /*Cross the two vectors*/
+ ccount = 0;
+ for(i=cut + 1; i<=nvars; i++)
+ {
+ child[1][i] = p1[i] * (double)n/(double)STEP + p2[i] * (1.0-(double)n/(double)STEP);
+ child[2][i] = p2[i] * (double)n/(double)STEP + p1[i] * (1.0-(double)n/(double)STEP);
+ ccount++;
+ }
+
+ /*Check to see if they satisfy the constraints*/
+ BFLAG1 = InBounds(child[1],domains,nvars);
+ BFLAG2 = InBounds(child[2],domains,nvars);
+ n++;
+ /*If the constraints not satisfied, then generate another*/
+ /*set of crossed over values*/
+ }while((n<=STEP) && ((BFLAG1 == FALSE) || (BFLAG2 == FALSE)));
+
+ /* Are the two new individuals unique? */
+ if (count >= MAX_OPER_UNIQUE_TRY)
+ {
+ SAME=FALSE;
+ break;
+ }
+
+ tcount=0;
+ for (i=cut+1; i<=nvars; i++) {
+ if ( (int) child[1][i] != (int) p1[i] )
+ tcount++;
+
+ if ( (int) child[2][i] != (int) p2[i] )
+ tcount++;
+ } /* end of i loop */
+
+ if (tcount>=(ccount*2)) SAME=FALSE;
+
+ } /* end of while (SAME==TRUE); */
+
+ if (BFLAG1==TRUE && BFLAG2==TRUE)
+ {
+ for(i=1; i<=nvars; i++)
+ {
+ p1[i] = (int) child[1][i];
+ p2[i] = (int) child[2][i];
+ }
+ }
+
+ free_matrix(child,1,2,1);
+}
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : JaIntegerOper6() */
+/* Whole Non-Uniform Mutation */
+/* */
+/********************************************************************************/
+
+
+void JaIntegerOper6(VECTOR parent, double **domains, int nvars, int T, int t, int B)
+ /* VECTOR parent;
+ unsigned long T; Total number of generations
+ unsigned long t; Current generation number
+ int B; */
+{
+ int i;
+ int llim,ulim;
+
+ /* unique check variables */
+ FLAG SAME;
+ long count;
+ int tmp;
+
+ count=0;
+ SAME=TRUE;
+
+ while (SAME==TRUE)
+ {
+ for (i=1; i<=nvars; i++)
+ {
+ count++;
+ find_rangeInt(&llim,&ulim,i,domains,nvars,parent);
+
+ /*From the current value of the component to be mutated, chooose at random*/
+ /*whether to mutate with a lesser value or a greater value*/
+ /*Then find a value lesser or greater than the original value from the*/
+ /*function get_f()*/
+ tmp = (int) (flip() == TAIL) ? parent[i]-get_F(T,t,parent[i]-llim,B) :
+ parent[i]+get_F(T,t,ulim-parent[i],B);
+
+ if ( (int) parent[i] != (int) tmp)
+ SAME=FALSE;
+ else if (count >= MAX_OPER_UNIQUE_TRY)
+ SAME=FALSE;
+
+ parent[i] = (int) tmp;
+ }//end of for loop
+ } // end of while loop
+}//oper6
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : JaIntegerOper7() */
+/* Heuristic Crossover */
+/* */
+/********************************************************************************/
+
+void JaIntegerOper7(VECTOR p1, VECTOR p2, double **domains, int nvars)
+{
+ VECTOR child;
+ FLAG BFLAG = FALSE;/*Check to see if the newly created vector satisfies the*/
+ /*set of constraints*/
+ int i,n=2,tries=MAX_OPER_UNIQUE_TRY;
+ double A;
+
+ /* unique check variables */
+ FLAG SAME;
+ long count;
+
+ child = Gvector(1,nvars);
+
+ count=0;
+ SAME=TRUE;
+ while (SAME==TRUE)
+ {
+ count++;
+
+ do
+ {
+ A = frange_ran(0.0,1.0);
+ for(i=1; i<=nvars; i++)
+ child[i] = (int) ( A * (p2[i] - p1[i]) + p2[i] );
+
+ /*Check to see if it satisfies the constraints*/
+ BFLAG = InBounds(child,domains,nvars);
+ n++;
+ /*If the constraints not satisfied, then try again */
+ }
+ while((n<=tries) && (BFLAG == FALSE));
+
+ /* Is the new individual unique? */
+ if (count >= MAX_OPER_UNIQUE_TRY)
+ {
+ SAME=FALSE;
+ break;
+ }
+
+ for (i=1; i<=nvars; i++) {
+ if ( (int) child[i] != (int) p1[i] ) {
+ SAME=FALSE;
+ break;
+ }
+ }
+
+ } /* end of while SAME loop */
+
+ if (BFLAG==TRUE)
+ {
+ for(i=1; i<=nvars; i++)
+ p1[i] = (int) child[i];
+ }
+
+
+ free_vector(child,1);
+} /* end of JaIntegerOper7() */
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : InBounds(child, domains, nvars) */
+/* */
+/* DESCRIPTION : This function returns TRUE or FALSE depending*/
+/* on whether the vector passed satisfies all */
+/* the constraints or not. */
+/* */
+/********************************************************************************/
+FLAG InBounds(VECTOR child, double **domains, int nvars)
+ /* VECTOR child; The vector to be checked for violation of constriants*/
+{
+ int i;
+
+
+ for(i=1; i<=nvars; i++)
+ {
+ if( (child[i] < domains[i][1]) || (child[i] > domains[i][3]) )
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
diff --git a/src/print_format.cpp b/src/print_format.cpp
new file mode 100644
index 0000000..43c557e
--- /dev/null
+++ b/src/print_format.cpp
@@ -0,0 +1,237 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ June 3, 2012
+
+*/
+
+
+#include "genoud.h"
+
+
+/********************************************************************************/
+/* ReadPopulation(): */
+/* */
+/* This function reads in an old population file and initializes the */
+/* newpopulation with it. */
+/* */
+/* */
+/********************************************************************************/
+
+long ReadPopulation(double **Data, long NewPopSize, long NewVars, FILE *fp, short PrintLevel)
+{
+ char ctmp[MAXPATH];
+ int generation, PopSize, nvars, UsePopSize, FitVals;
+ int i, j, ltmp, fint;
+ double **OldData;
+ short trip=0;
+
+ /* This reads the "Generations:" name */
+
+ while(!(feof(fp))) {
+
+ /* pos = ftell(fp); */
+
+ fint = fscanf(fp, "%s", ctmp);
+ fint = fscanf(fp, " %d", &generation);
+
+ if(PrintLevel>0)
+ Rprintf( "Generation: %d\n", generation);
+ /* This reads the "Population" name */
+ fint = fscanf(fp, "%s", ctmp);
+ /* This reads the "Size:" name */
+ fint = fscanf(fp, "%s", ctmp);
+ fint = fscanf(fp, " %d", &PopSize);
+
+ if(PrintLevel>0 & trip==0)
+ Rprintf( "Population Size: %d\n", PopSize);
+
+ fint = fscanf(fp, "%s", ctmp); /* reads "Fit" */
+ fint = fscanf(fp, "%s", ctmp); /* reads "Values:" */
+ fint = fscanf(fp, "%d", &FitVals); /* reads number of fit values */
+
+ if(FitVals > 1)
+ warning("Reading an existing population file is not supported for Fit Values != 1");
+
+ /* This reads the "Variables:" name */
+ fint = fscanf(fp, "%s", ctmp);
+ fint = fscanf(fp, " %d", &nvars);
+
+ if(PrintLevel>0 & trip==0)
+ Rprintf( "Number of Variables: %d\n", nvars);
+
+ if (trip==0) {
+ if (nvars!=NewVars) return(0);
+
+ OldData = JaMatrixAllocate(PopSize+2, nvars+2);
+ trip++;
+ }
+
+ /* loop over the main data part */
+ for (i=1; i<=PopSize; i++) {
+ fint = fscanf(fp,"%d",<mp);
+ for (j=0; j<=nvars; j++) {
+ fint = fscanf(fp,"%lf", &OldData[i][j]);
+ }
+ }
+
+ }
+
+ /* Map OldData to Data */
+ if (NewPopSize < PopSize) UsePopSize = NewPopSize;
+ else UsePopSize=PopSize;
+ for (i=1; i<=UsePopSize; i++) {
+ Data[i][nvars+1] = 0.0;
+ for (j=0; j<=nvars; j++) {
+ Data[i][j] = OldData[i][j];
+ }
+ }
+
+ /* let's print the population file */
+ if(PrintLevel>1)
+ {
+ Rprintf( "\nRead in Population. Used Population Size: %d\n", UsePopSize);
+ for (i=1; i<=UsePopSize; i++) {
+ Rprintf( "%d \t", i);
+ for (j=0; j<=nvars; j++) {
+ Rprintf( "%e \t", Data[i][j]);
+ }
+ Rprintf( "\n");
+ }
+ Rprintf( "\n");
+ /* fflush(output); */
+ }
+
+ JaMatrixFree(OldData, PopSize);
+ return(PopSize);
+} /* end Read Population */
+
+
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : print_domains() */
+/* */
+/* SYNOPSIS : void print_domains(equal,t_equ) */
+/* */
+/* DESCRIPTION : This function prints the matrix passed, on to*/
+/* the standard output, in the format of */
+/* domains. */
+/* */
+/* FUNCTIONS CALLED : None */
+/* */
+/* CALLING FUNCITONS : main() */
+/* */
+/* */
+/* REV DATE BY DESCRIPTION */
+/* --- ---- -- ----------- */
+/* */
+/* */
+/********************************************************************************/
+
+
+
+
+void print_domains(MATRIX equal, int t_equ, short DataType)
+ /*
+ MATRIX equal; the domains matrix, with the upper and lower limits
+ int t_equ; *the total number of domains
+ */
+{
+ int i,j;
+
+ Rprintf("Domains:\n");
+ //Integer
+ if (DataType==1)
+ {
+ for(i=1; i<=t_equ; i++)
+ {
+ for(j=1; j<=3; j++)
+ {
+ if(j == 2)
+ Rprintf(" <= X%-2d <= ",(int)equal[i][j]);
+ else
+ Rprintf(" %d ",(int) equal[i][j]);
+ }
+ Rprintf("\n");
+ }
+ } else {
+ for(i=1; i<=t_equ; i++)
+ {
+ for(j=1; j<=3; j++)
+ {
+ if(j == 2)
+ Rprintf(" <= X%-2d <= ",(int)equal[i][j]);
+ else
+ Rprintf(" %e ",equal[i][j]);
+ }
+ Rprintf("\n");
+ }
+ }
+}
+
+/********************************************************************************/
+/* */
+/* FUNCTION NAME : print_population() */
+/* */
+/********************************************************************************/
+
+void print_population(int popsize, int nvars, int generation, int lexical, double **foo, FILE *out)
+{
+ int i,j;
+
+ if (lexical < 2)
+ {
+ fprintf(out,"Generation: %d \t Population Size: %d \t Fit Values: 1 \t Variables: %d\n\n",
+ generation, popsize, nvars);
+ for(i = 1; i <= popsize; i++)
+ {
+ fprintf(out,"%d \t %e \t",i, foo[i][0]);
+ for (j = 1; j <= nvars; j++)
+ {
+ fprintf(out,"%e \t ",foo[i][j]);
+ }
+ fprintf(out,"\n");
+ }
+ fprintf(out,"\n\n");
+ }
+ else
+ {
+ long lexical_end = lexical-1+nvars+2;
+
+ fprintf(out,"Generation: %d \t Population Size: %d \t Fit Values: %d \t Variables: %d\n\n",
+ generation, popsize, lexical, nvars);
+ for(i = 1; i <= popsize; i++)
+ {
+ fprintf(out,"%d \t ", i);
+
+ /* print lexical fit values */
+ fprintf(out,"%e \t ",foo[i][0]);
+ for(j=(nvars+2);j<lexical_end;j++)
+ {
+ fprintf(out,"%e \t ",foo[i][j]);
+ }
+
+ /* print variables */
+ for (j = 1; j <= nvars; j++)
+ {
+ fprintf(out,"%e \t ",foo[i][j]);
+ }
+ fprintf(out,"\n");
+ }
+ fprintf(out,"\n\n");
+ }
+} /* end */
+
+
diff --git a/src/rgenoud.cpp b/src/rgenoud.cpp
new file mode 100644
index 0000000..8db0382
--- /dev/null
+++ b/src/rgenoud.cpp
@@ -0,0 +1,273 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ August 3, 2009
+*/
+
+#include "genoud.h"
+
+void genoud(struct GND_IOstructure *Structure);
+
+extern "C"
+{
+
+ // mkanswer
+ SEXP mkans(double *oFitValues, double *oResults, double *oGradients, long *oP, long oGenerations,
+ long oPeakGeneration, long oPopSize, long nvars, long lexical)
+ {
+ SEXP ans;
+ long length, i, indx, operators;
+
+ operators=9;
+ length= lexical + (nvars*2) + 3 + operators;
+
+ PROTECT(ans=allocVector(REALSXP,length));
+ REAL(ans)[0] = (double) oGenerations;
+ REAL(ans)[1] = (double) oPeakGeneration;
+ REAL(ans)[2] = (double) oPopSize;
+ indx = 2;
+ // include fit values
+ for (i=0; i<lexical; i++) {
+ indx++;
+ REAL(ans)[indx] = oFitValues[i];
+ }
+ // include results
+ for (i=0; i<nvars; i++) {
+ indx++;
+ REAL(ans)[indx] = oResults[i];
+ }
+ // include gradients
+ for (i=0; i<nvars; i++) {
+ indx++;
+ REAL(ans)[indx] = oGradients[i];
+ }
+ // include the actual operator count
+ for (i=0; i<operators; i++) {
+ indx++;
+ REAL(ans)[indx] = oP[i];
+ }
+ UNPROTECT(1);
+
+ return(ans);
+ } // end of mkans
+
+
+ double genoud_optim(SEXP fn_optim, SEXP rho, double *X, long parameters)
+ {
+ SEXP ans, R_fcall, x;
+ double fit;
+ long i;
+
+ PROTECT(x = allocVector(REALSXP, parameters));
+
+ for (i=0; i<parameters; i++)
+ {
+ REAL(x)[i] = X[i];
+ }
+
+ PROTECT(R_fcall = lang2(fn_optim, R_NilValue));
+ SETCADR(R_fcall, x);
+
+ ans = eval(R_fcall, rho);
+ fit = REAL(ans)[0];
+
+ for(i=0; i<parameters; i++)
+ {
+ X[i] = REAL(ans)[i+1];
+ }
+
+ UNPROTECT(2);
+ return(fit);
+ } // end of genoud_optim()
+
+
+
+ SEXP rgenoud(SEXP fn, SEXP rho,
+ SEXP nvars, SEXP pop_size, SEXP max_generations, SEXP wait_generations,
+ SEXP n_starting_values, SEXP starting_values,
+ SEXP P, SEXP Domains,
+ SEXP max, SEXP gradient_check, SEXP boundary_enforcement,
+ SEXP solution_tolerance, SEXP BFGS, SEXP data_type_int,
+ SEXP provide_seeds, SEXP unif_seed, SEXP int_seed,
+ SEXP print_level, SEXP share_type, SEXP instance_number,
+ SEXP MemoryMatrix, SEXP Debug,
+ SEXP output_path, SEXP output_type, SEXP project_path,
+ SEXP hard_generation_limit,
+ SEXP fn_optim,
+ SEXP lexical, SEXP fnLexicalSort, SEXP fnMemoryMatrixEvaluate,
+ SEXP RuserGradient, SEXP fnGR,
+ SEXP RP9mix, SEXP BFGSburnin, SEXP transform)
+ {
+
+ SEXP ret;
+ long parameters, i, j;
+
+ double *FitValues, *Results, *Gradients;
+
+ if(!isEnvironment(rho))
+ error ("`rho' should be an environment");
+
+ parameters = asInteger(nvars);
+
+ // setup GENOUD
+ struct GND_IOstructure *MainStructure;
+ MainStructure = (struct GND_IOstructure *) malloc(sizeof(struct GND_IOstructure));
+
+ double **domains;
+ domains = (double **) malloc(parameters*sizeof(double));
+ for (i=0; i<parameters; i++) {
+ domains[i] = (double *) malloc(2*sizeof(double));
+ }
+
+ for (j=0; j<2; j++) {
+ for (i=0; i<parameters; i++) {
+ domains[i][j] = REAL(Domains)[i + j*parameters];
+ }
+ }
+
+ // starting values
+ double **StartingValues;
+ int nStartingValues;
+ nStartingValues = asInteger(n_starting_values);
+ if (nStartingValues > 0) {
+ /* need to free a matrix of StaringValues below */
+ StartingValues = (double **) malloc(nStartingValues*sizeof(double));
+ for (i=0; i<nStartingValues; i++) {
+ StartingValues[i] = (double *) malloc(parameters*sizeof(double));
+ for(j=0; j<parameters; j++)
+ StartingValues[i][j] = REAL(starting_values)[(i * parameters + j)];
+ }
+ }
+
+ MainStructure->fn=fn;
+ MainStructure->rho=rho;
+ MainStructure->fnLexicalSort=fnLexicalSort;
+ MainStructure->fnMemoryMatrixEvaluate=fnMemoryMatrixEvaluate;
+ MainStructure->fnGR=fnGR;
+ MainStructure->fn_optim=fn_optim;
+ MainStructure->Lexical=asInteger(lexical);
+ MainStructure->UserGradient=asInteger(RuserGradient);
+ MainStructure->nvars=parameters;
+ MainStructure->PopSize=asInteger(pop_size);
+ MainStructure->MaxGenerations=asInteger(max_generations);
+ MainStructure->WaitGenerations=asInteger(wait_generations);
+ MainStructure->HardGenerationLimit=asInteger(hard_generation_limit);
+ MainStructure->nStartingValues=nStartingValues;
+ MainStructure->StartingValues=StartingValues;
+ MainStructure->P[0]=REAL(P)[0];
+ MainStructure->P[1]=REAL(P)[1];
+ MainStructure->P[2]=REAL(P)[2];
+ MainStructure->P[3]=REAL(P)[3];
+ MainStructure->P[4]=REAL(P)[4];
+ MainStructure->P[5]=REAL(P)[5];
+ MainStructure->P[6]=REAL(P)[6];
+ MainStructure->P[7]=REAL(P)[7];
+ MainStructure->P[8]=REAL(P)[8];
+ MainStructure->Domains=domains;
+ MainStructure->MinMax=asInteger(max);
+ MainStructure->GradientCheck=asInteger(gradient_check);
+ MainStructure->BoundaryEnforcement=asInteger(boundary_enforcement);
+ MainStructure->SolutionTolerance=asReal(solution_tolerance);
+ MainStructure->UseBFGS=asInteger(BFGS);
+
+ MainStructure->MemoryUsage=asInteger(MemoryMatrix);
+ MainStructure->Debug=asInteger(Debug);
+
+ MainStructure->InstanceNumber=asInteger(instance_number);
+
+ MainStructure->ProvideSeeds=asInteger(provide_seeds);
+ MainStructure->UnifSeed=asInteger(unif_seed);
+ MainStructure->IntSeed=asInteger(int_seed);
+ MainStructure->PrintLevel=asInteger(print_level);
+ MainStructure->DataType=asInteger(data_type_int);
+
+ /*
+ Share Type:
+ (0) no reading of the existing project file and no looking at the public population file
+ (1) reading of any existing project file, but no examining of public population file
+ (2) NO reading of any existing project file but examination of public population file
+ (3) BOTH reading of any existing project file AND examination of public population file
+ */
+ MainStructure->ShareType=asInteger(share_type);
+
+ //Paths
+ char OutputPath[1000], ProjectPath[1000];
+ strcpy(OutputPath,STRING_VALUE(output_path));
+ strcpy(ProjectPath,STRING_VALUE(project_path));
+ MainStructure->OutputPath=OutputPath;
+ MainStructure->ProjectPath=ProjectPath;
+ MainStructure->OutputType=asInteger(output_type);
+
+ /* output data structures */
+ FitValues = (double *) malloc(MainStructure->Lexical*sizeof(double));
+ Results = (double *) malloc(parameters*sizeof(double));
+ Gradients = (double *) malloc(parameters*sizeof(double));
+
+ MainStructure->oFitValues=FitValues;
+ MainStructure->oResults=Results;
+ MainStructure->oGradients=Gradients;
+
+ /* from setupGenoud */
+ /* output data structures */
+ MainStructure->oGenerations=0;
+ MainStructure->oPeakGeneration=0;
+ MainStructure->oPopSize=0;
+ MainStructure->ThreadNumber=0;
+
+ /* Operator Options */
+ MainStructure->P9mix=asReal(RP9mix);
+ MainStructure->BFGSburnin=asInteger(BFGSburnin);
+
+ /* Transform Related Variables */
+ /* whichFUN == 3 implies EvaluateTransform should be called */
+ /* whichFUN == 2 implies EvaluateLexical should be called */
+ /* whichFUN == 1 implies evaluate should be called */
+ MainStructure->Transform=asInteger(transform);
+ if(MainStructure->Transform == 1)
+ MainStructure->whichFUN = 3;
+ else if(MainStructure->Lexical > 1)
+ MainStructure->whichFUN = 2;
+ else
+ MainStructure->whichFUN = 1;
+
+ genoud(MainStructure);
+
+ ret = mkans(MainStructure->oFitValues,
+ MainStructure->oResults, MainStructure->oGradients, MainStructure->oP,
+ MainStructure->oGenerations, MainStructure->oPeakGeneration,
+ MainStructure->oPopSize, MainStructure->nvars, MainStructure->Lexical);
+
+ // Free memory
+ free(MainStructure);
+ for (i=0; i<parameters; i++)
+ free(domains[i]);
+ free(domains);
+ free(Results);
+ free(Gradients);
+ free(FitValues);
+
+ if (nStartingValues > 0) {
+ for (i=0; i<nStartingValues; i++)
+ free(StartingValues[i]);
+ free(StartingValues);
+ }
+
+ return(ret);
+ } // end of rgenoud()
+
+} // end of extern "C"
+
+
+
+
diff --git a/src/unif.cpp b/src/unif.cpp
new file mode 100644
index 0000000..86b75bf
--- /dev/null
+++ b/src/unif.cpp
@@ -0,0 +1,144 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ $Header: /home/jsekhon/xchg/genoud/rgenoud.distribution/sources/RCS/unif.cpp,v 2.15 2005/10/29 06:14:44 jsekhon Exp jsekhon $
+
+*/
+
+
+#include <stdio.h>
+#include "unif.h"
+
+void ruxorv (integer *iseed, int n, double *rvec, integer *aux)
+{
+/* the double precision random uniforms in rvec have only 31 random bits
+ set *iseed!=0 to reinitialize the sequence, else use *iseed==0
+ *iseed always equals 0 on return
+ aux points to an integer vector of length > 1279+3
+*/
+ int i, ibloc, nw;
+ static integer wrk[TLPDBSIZ];
+ double fk = 1.0/((double) TLPMOD) ;
+
+ /* if n==0, initialize the TLP seed vector in aux[] and return */
+ if (n == 0) {
+ /* initialize only if *iseed > 0 */
+ if (*iseed != 0) tlpseq (iseed, 0, wrk, aux);
+ } else {
+ nw = n;
+ ibloc = 0;
+ while (nw > TLPDBSIZ) {
+ tlpseq (iseed, TLPDBSIZ, wrk, aux);
+ if (ibloc > 0) {
+ for (i=0; i<TLPDBSIZ; i++) rvec[ibloc+i] = wrk[i] * fk ;
+ } else {
+ for (i=0; i<TLPDBSIZ; i++) rvec[i] = wrk[i] * fk ;
+ }
+ nw -= TLPDBSIZ;
+ ibloc += TLPDBSIZ;
+ } ;
+ if (nw > 0) {
+ tlpseq (iseed, nw, wrk, aux);
+ if (ibloc > 0) {
+ for (i=0; i<nw; i++) rvec[ibloc+i] = wrk[i] * fk;
+ } else {
+ for (i=0; i<nw; i++) rvec[i] = wrk[i] * fk;
+ }
+ }
+ }
+}
+
+/* Tausworthe-Lewis-Payne generator,
+ for primitive trinomial with k=K, q=Q. Here K=1279, Q=216.
+ see Bratley, Fox and Schrage (1983, 190) and Bright and Enison (1979)
+*/
+void tlpseq (integer *iseed, int n, integer *rvec, integer *aux)
+{
+ static integer k = 1279, q = 216, k0 = 89, q0 = 38,
+ seed = (integer) 524287 ;
+ static integer aux0[89+3];
+ int i;
+ integer seedw;
+
+ /* aux is a vector of length > k+3 */
+ /* initialize aux if nonzero *iseed is supplied or
+ if aux[k+2] is not set to the magic value */
+ if (*iseed != ZEROI || aux[k+2] != k) {
+ if (*iseed < ZEROI) *iseed = -(*iseed);
+ seedw = (*iseed != seed) ? (*iseed ^ seed) : seed ;
+ *iseed = ZEROI;
+ for (i=0; i<k0; i++) {
+ tauint (&seedw) ;
+ aux0[i] = seedw;
+ }
+ aux0[k0] = k0 - 1;
+ aux0[k0+1] = aux0[k0] - q0;
+ aux0[k0+2] = k0;
+ /* initialize the k=K, q=Q generator using the k=89, q=38 generator */
+ tlpcor (k0, k, aux, aux0);
+ /* store initial recurrence location indexes and the magic value in aux */
+ aux[k] = k - 1;
+ aux[k+1] = aux[k] - q;
+ aux[k+2] = k;
+ }
+ if (n > 0) tlpcor (k, n, rvec, aux);
+}
+
+/* Tausworthe-Lewis-Payne generator, core recursion.
+ assumes aux is valid
+ see Bratley, Fox and Schrage (1983, 190) and Bright and Enison (1979)
+*/
+void tlpcor (integer k, int n, integer *rvec, integer *aux)
+{
+ /* aux is a vector of length k+2 */
+ int ii;
+ integer i, j, inew;
+
+ /* get the recursion location indexes out of AUX */
+ i = aux[k];
+ j = aux[k+1];
+ for (ii=0; ii<n; ii++) {
+ inew = aux[j] ^ aux[i] ;
+ aux[i] = inew;
+ rvec[ii] = inew;
+ j = j==0 ? k-1 : j - 1;
+ i = i==0 ? k-1 : i - 1;
+ }
+ /* store the recursion location indexes in aux */
+ aux[k] = i;
+ aux[k+1] = j;
+}
+
+void tauint (integer *ix)
+{
+/* Tausworthe generator (integer part)
+ requires full-word logical operations, 32-bit words, and
+ two's complement arithmetic
+ from Bratley, Fox and Schrage (1983, 203)
+ a recommended initial value for IX is 524287
+*/
+ integer i, j;
+
+ i = *ix;
+ /* do the right shift */
+ j = i/8192;
+ /* exclusive-or */
+ j ^= i;
+ /* lower-order bits are done. now do the rest */
+ i = j;
+ /* do the left shift */
+ j <<= 18;
+ /* exclusive-or, handling cases where the left shift makes j negative */
+ *ix = j<0 ? i^(-j) : i^j ;
+}
diff --git a/src/unif.h b/src/unif.h
new file mode 100644
index 0000000..1262c9f
--- /dev/null
+++ b/src/unif.h
@@ -0,0 +1,36 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ $Header: /home/jsekhon/xchg/genoud/rgenoud.distribution/sources/RCS/unif.h,v 2.15 2005/10/29 06:14:44 jsekhon Exp jsekhon $
+
+*/
+
+
+/* Tausworthe-Lewis-Payne generator */
+
+#ifndef DEFTLPGEN
+typedef int integer;
+
+#define TLPAUXSIZE 1300
+#define TLPDBSIZ 2000
+#define ZEROI ((integer)0)
+#define TLPMOD 2147483647
+
+void ruxorv (integer *, int, double *, integer *);
+void tlpseq (integer *, int, integer *, integer *);
+void tauint (integer *);
+void tlpcor (integer, int, integer *, integer *);
+
+#define DEFTLPGEN
+#endif
diff --git a/src/urans.h b/src/urans.h
new file mode 100644
index 0000000..61c2336
--- /dev/null
+++ b/src/urans.h
@@ -0,0 +1,26 @@
+/*
+
+ RGENOUD
+
+ Walter R. Mebane, Jr.
+ Cornell University
+ http://macht.arts.cornell.edu/wrm1
+ <wrm1 at macht.arts.cornell.edu>
+
+ Jasjeet Singh Sekhon
+ UC Berkeley
+ http://sekhon.polisci.berkeley.edu
+ <sekhon at berkeley.edu>
+
+ $Header: /home/jsekhon/xchg/genoud/rgenoud.distribution/sources/RCS/urans.h,v 2.15 2005/10/29 06:14:44 jsekhon Exp jsekhon $
+
+*/
+
+
+/* set seeds for the random number generators */
+
+#ifndef DEFURANS
+#define NEWUNIFSEED 81345
+#define RANDINTSEED 98711
+#define DEFURANS
+#endif
diff --git a/tests/tests.R b/tests/tests.R
new file mode 100644
index 0000000..429473e
--- /dev/null
+++ b/tests/tests.R
@@ -0,0 +1,57 @@
+suppressMessages(library(rgenoud))
+
+#maximize the sin function
+sin1 <- genoud(sin, nvars=1, max=TRUE, unif.seed=912821, int.seed=93058, print.level=0)
+sin1$value <- signif(sin1$value,6)
+sin1$par <- signif(sin1$par,6)
+sin1$gradients <- signif(sin1$gradients,6)
+print(sin1)
+
+#minimize the sin function
+sin2 <- genoud(sin, nvars=1, max=FALSE, unif.seed=912821, int.seed=93058, print.level=0)
+sin2$value <- signif(sin2$value,6)
+sin2$par <- signif(sin2$par,6)
+sin2$gradients <- signif(sin2$gradients,6)
+print(sin2)
+
+#maximize a univariate normal mixture which looks like a claw
+claw <- function(xx) {
+ x <- xx[1]
+ y <- (0.46*(dnorm(x,-1.0,2.0/3.0) + dnorm(x,1.0,2.0/3.0)) +
+ (1.0/300.0)*(dnorm(x,-0.5,.01) + dnorm(x,-1.0,.01) + dnorm(x,-1.5,.01)) +
+ (7.0/300.0)*(dnorm(x,0.5,.07) + dnorm(x,1.0,.07) + dnorm(x,1.5,.07)))
+ return(y)
+}
+claw1 <- genoud(claw, nvars=1,pop.size=3000,max=TRUE, unif.seed=912821, int.seed=93058, print.level=0)
+claw1$value <- signif(claw1$value,6)
+claw1$par <- signif(claw1$par,6)
+claw1$gradients <- signif(claw1$gradients,6)
+print(claw1)
+
+# Maximize a bivariate normal mixture which looks like a claw.
+biclaw <- function(xx) {
+ mNd2 <- function(x1, x2, mu1, mu2, sigma1, sigma2, rho)
+ {
+ z1 <- (x1-mu1)/sigma1
+ z2 <- (x2-mu2)/sigma2
+ w <- (1.0/(2.0*pi*sigma1*sigma2*sqrt(1-rho*rho)))
+ w <- w*exp(-0.5*(z1*z1 - 2*rho*z1*z2 + z2*z2)/(1-rho*rho))
+ return(w)
+ }
+ x1 <- xx[1]+1
+ x2 <- xx[2]+1
+
+ y <- (0.5*mNd2(x1,x2,0.0,0.0,1.0,1.0,0.0) +
+ 0.1*(mNd2(x1,x2,-1.0,-1.0,0.1,0.1,0.0) +
+ mNd2(x1,x2,-0.5,-0.5,0.1,0.1,0.0) +
+ mNd2(x1,x2,0.0,0.0,0.1,0.1,0.0) +
+ mNd2(x1,x2,0.5,0.5,0.1,0.1,0.0) +
+ mNd2(x1,x2,1.0,1.0,0.1,0.1,0.0)))
+
+ return(y)
+}
+biclaw1 <- genoud(biclaw, default.domains=20, nvars=2,pop.size=5000,max=TRUE, unif.seed=912821, int.seed=93058, print.level=0)
+biclaw1$value <- signif(biclaw1$value,6)
+biclaw1$par <- signif(biclaw1$par,6)
+biclaw1$gradients <- signif(biclaw1$gradients,6)
+print(biclaw1)
diff --git a/tests/tests.Rout.save b/tests/tests.Rout.save
new file mode 100644
index 0000000..dac3f5c
--- /dev/null
+++ b/tests/tests.Rout.save
@@ -0,0 +1,162 @@
+
+R version 3.2.1 (2015-06-18) -- "World-Famous Astronaut"
+Copyright (C) 2015 The R Foundation for Statistical Computing
+Platform: x86_64-apple-darwin13.4.0 (64-bit)
+
+R is free software and comes with ABSOLUTELY NO WARRANTY.
+You are welcome to redistribute it under certain conditions.
+Type 'license()' or 'licence()' for distribution details.
+
+R is a collaborative project with many contributors.
+Type 'contributors()' for more information and
+'citation()' on how to cite R or R packages in publications.
+
+Type 'demo()' for some demos, 'help()' for on-line help, or
+'help.start()' for an HTML browser interface to help.
+Type 'q()' to quit R.
+
+> suppressMessages(library(rgenoud))
+>
+> #maximize the sin function
+> sin1 <- genoud(sin, nvars=1, max=TRUE, unif.seed=912821, int.seed=93058, print.level=0)
+> sin1$value <- signif(sin1$value,6)
+> sin1$par <- signif(sin1$par,6)
+> sin1$gradients <- signif(sin1$gradients,6)
+> print(sin1)
+$value
+[1] 1
+
+$par
+[1] 7.85398
+
+$gradients
+[1] -3.8465e-11
+
+$generations
+[1] 11
+
+$peakgeneration
+[1] 1
+
+$popsize
+[1] 1000
+
+$operators
+[1] 122 125 125 125 125 126 125 126 0
+
+>
+> #minimize the sin function
+> sin2 <- genoud(sin, nvars=1, max=FALSE, unif.seed=912821, int.seed=93058, print.level=0)
+> sin2$value <- signif(sin2$value,6)
+> sin2$par <- signif(sin2$par,6)
+> sin2$gradients <- signif(sin2$gradients,6)
+> print(sin2)
+$value
+[1] -1
+
+$par
+[1] -1.5708
+
+$gradients
+[1] 5.94475e-11
+
+$generations
+[1] 11
+
+$peakgeneration
+[1] 1
+
+$popsize
+[1] 1000
+
+$operators
+[1] 122 125 125 125 125 126 125 126 0
+
+>
+> #maximize a univariate normal mixture which looks like a claw
+> claw <- function(xx) {
++ x <- xx[1]
++ y <- (0.46*(dnorm(x,-1.0,2.0/3.0) + dnorm(x,1.0,2.0/3.0)) +
++ (1.0/300.0)*(dnorm(x,-0.5,.01) + dnorm(x,-1.0,.01) + dnorm(x,-1.5,.01)) +
++ (7.0/300.0)*(dnorm(x,0.5,.07) + dnorm(x,1.0,.07) + dnorm(x,1.5,.07)))
++ return(y)
++ }
+> claw1 <- genoud(claw, nvars=1,pop.size=3000,max=TRUE, unif.seed=912821, int.seed=93058, print.level=0)
+> claw1$value <- signif(claw1$value,6)
+> claw1$par <- signif(claw1$par,6)
+> claw1$gradients <- signif(claw1$gradients,6)
+> print(claw1)
+$value
+[1] 0.411312
+
+$par
+[1] 0.999503
+
+$gradients
+[1] -1.27716e-06
+
+$generations
+[1] 11
+
+$peakgeneration
+[1] 1
+
+$popsize
+[1] 3000
+
+$operators
+[1] 372 375 375 375 375 376 375 376 0
+
+>
+> # Maximize a bivariate normal mixture which looks like a claw.
+> biclaw <- function(xx) {
++ mNd2 <- function(x1, x2, mu1, mu2, sigma1, sigma2, rho)
++ {
++ z1 <- (x1-mu1)/sigma1
++ z2 <- (x2-mu2)/sigma2
++ w <- (1.0/(2.0*pi*sigma1*sigma2*sqrt(1-rho*rho)))
++ w <- w*exp(-0.5*(z1*z1 - 2*rho*z1*z2 + z2*z2)/(1-rho*rho))
++ return(w)
++ }
++ x1 <- xx[1]+1
++ x2 <- xx[2]+1
++
++ y <- (0.5*mNd2(x1,x2,0.0,0.0,1.0,1.0,0.0) +
++ 0.1*(mNd2(x1,x2,-1.0,-1.0,0.1,0.1,0.0) +
++ mNd2(x1,x2,-0.5,-0.5,0.1,0.1,0.0) +
++ mNd2(x1,x2,0.0,0.0,0.1,0.1,0.0) +
++ mNd2(x1,x2,0.5,0.5,0.1,0.1,0.0) +
++ mNd2(x1,x2,1.0,1.0,0.1,0.1,0.0)))
++
++ return(y)
++ }
+> biclaw1 <- genoud(biclaw, default.domains=20, nvars=2,pop.size=5000,max=TRUE, unif.seed=912821, int.seed=93058, print.level=0)
+> biclaw1$value <- signif(biclaw1$value,6)
+> biclaw1$par <- signif(biclaw1$par,6)
+> biclaw1$gradients <- signif(biclaw1$gradients,6)
+> print(biclaw1)
+$value
+[1] 1.67113
+
+$par
+[1] -1 -1
+
+$gradients
+[1] 2.49105e-08 -3.42757e-08
+
+$generations
+[1] 12
+
+$peakgeneration
+[1] 1
+
+$popsize
+[1] 5000
+
+$operators
+[1] 622 625 625 625 625 626 625 626 0
+
+>
+> proc.time()
+ user system elapsed
+ 6.218 0.141 6.384
diff --git a/vignettes/Figures/fig1.pdf b/vignettes/Figures/fig1.pdf
new file mode 100644
index 0000000..6ee603f
Binary files /dev/null and b/vignettes/Figures/fig1.pdf differ
diff --git a/vignettes/Figures/lqdxmpl2B.pdf b/vignettes/Figures/lqdxmpl2B.pdf
new file mode 100644
index 0000000..9f8cd43
Binary files /dev/null and b/vignettes/Figures/lqdxmpl2B.pdf differ
diff --git a/vignettes/rgenoud.Rnw b/vignettes/rgenoud.Rnw
new file mode 100644
index 0000000..c4b958b
--- /dev/null
+++ b/vignettes/rgenoud.Rnw
@@ -0,0 +1,1465 @@
+\documentclass[nojss]{jss}
+
+\usepackage{amsmath}
+\usepackage{dcolumn}
+
+%%My declarations
+\newcommand{\hlink}{\htmladdnormallink}
+\newcommand{\MyPerp}{\perp \! \! \! \perp}
+
+\newcommand{\e}{\text{e-}}
+
+\newcolumntype{C}{>{$}c<{$}}
+\newcolumntype{L}{>{$}l<{$}}
+\newcolumntype{R}{>{$}r<{$}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% declarations for jss.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% almost as usual
+\author{Walter R. Mebane, Jr. \\
+ University of Michigan
+ \And
+ Jasjeet S. Sekhon \\
+ UC Berkeley}
+
+%% for pretty printing and a nice hypersummary also set:
+\title{Genetic Optimization Using Derivatives: The \pkg{rgenoud} Package for \proglang{R}}
+\Plaintitle{Genetic Optimization Using Derivatives: The rgenoud Package for R}
+\Plainauthor{Walter R. Mebane, Jr., Jasjeet S. Sekhon} %% comma-separated
+\Shorttitle{\pkg{rgenoud}: Genetic Optimization Using Derivatives in \proglang{R}}
+
+%% an abstract and keywords
+\Abstract{ This introduction to the \proglang{R} package \pkg{rgenoud}
+ is a modified version of \cite{MebaneJr.+Sekhon:2011}, published in
+ the \textit{Journal of Statistical Software}. That version of the
+ introduction contains higher resolution figures.
+
+ \code{genoud} is an \proglang{R} function that combines
+ evolutionary algorithm methods with a derivative-based
+ (quasi-Newton) method to solve difficult optimization problems.
+ \code{genoud} may also be used for optimization problems for which
+ derivatives do not exist. \code{genoud} solves problems that are nonlinear
+ or perhaps even discontinuous in the parameters of the function to
+ be optimized. When the function to be optimized (for
+ example, a log-likelihood) is nonlinear in the model's parameters,
+ the function will generally not be globally concave
+ and may have irregularities such as saddlepoints or discontinuities.
+ Optimization methods that rely on derivatives of the objective
+ function may be unable to find any optimum at all. Multiple local
+ optima may exist, so that there is no guarantee that a
+ derivative-based method will converge to the global optimum. On the
+ other hand, algorithms that do not use derivative information (such
+ as pure genetic algorithms) are for many problems needlessly poor at
+ local hill climbing. Most statistical problems are regular in a
+ neighborhood of the solution. Therefore, for some portion of the
+ search space, derivative information is useful. The function
+ supports parallel processing on multiple CPUs on a single machine or
+ a cluster of computers.}
+
+\Keywords{genetic algorithm, evolutionary program, optimization, parallel computing, \proglang{R}}
+\Plainkeywords{genetic algorithm, evolutionary program, optimization, parallel computing, R} %% without formatting
+%% at least one keyword must be supplied
+
+%% publication information
+%% NOTE: This needs to filled out ONLY IF THE PAPER WAS ACCEPTED.
+%% If it was not (yet) accepted, leave them commented.
+\Volume{42}
+\Issue{11}
+%\Month{September}
+\Year{2011}
+\Submitdate{2007-02-11}
+\Acceptdate{2007-11-21}
+
+%% The address of (at least) one author should be given
+%% in the following format:
+\Address{
+ Walter R. Mebane, Jr.\\
+% Professor\\
+ Department of Political Science\\
+ Department of Statistics\\
+ University of Michigan\\
+ Ann Arbor, MI 48109-1045\\
+ E-mail: \email{wmebane at umich.edu}\\
+ URL: \url{http://www.umich.edu/~wmebane} \\ [2ex]
+
+ Jasjeet S. Sekhon\\
+ Department of Political Science\\
+ Department of Statistics\\
+ 210 Barrows Hall \#1950\\
+ UC Berkeley\\
+ Berkeley, CA 94720-1950\\
+ E-mail: \email{sekhon at berkeley.edu}\\
+ URL: \url{http://sekhon.berkeley.edu}
+}
+%% It is also possible to add a telephone and fax number
+%% before the e-mail in the following format:
+%% Telephone: +43/1/31336-5053
+%% Fax: +43/1/31336-734
+
+%% for those who use Sweave please include the following line (with % symbols):
+%% need no \usepackage{Sweave.sty}
+
+%% end of declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\graphicspath{{Figures/}}
+
+\begin{document}
+\SweaveOpts{engine=R}
+%\VignetteIndexEntry{Using genoud}
+%\VignetteDepends{rgenoud}
+%\VignetteKeywords{rgenoud}
+%\VignettePackage{rgenoud}
+
+\section{Introduction}
+
+We developed the \proglang{R} package \pkg{rgenoud} to solve difficult
+optimization problems such as often arise when estimating nonlinear
+statistical models or solving complicated nonlinear, nonsmooth and
+even discontinuous functions.\footnote{The \pkg{rgenoud} software
+ package is available from the Comprehensive \proglang{R}
+ \citep{Rcore} Archive Network at
+ \url{http://CRAN.R-project.org/package=rgenoud}.} Optimization
+difficulties often arise when the objective function (for instance,
+the log-likelihood) is a nonlinear function of the parameters. In such
+cases the function to be optimized is usually not globally concave.
+An objective function that is not globally concave may have multiple
+local optima, saddle points, boundary solutions or discontinuities.
+While the objective function for a statistical model is often concave
+in a neighborhood of the optimal solution, that neighborhood is often
+a small proportion of the parameter space of potential interest, and
+outside that neighborhood the function may be irregular. In such
+cases, methods of optimization that depend entirely on derivatives can
+be unreliable and often are virtually unusable. Newton-Raphson and
+quasi-Newton methods are among the commonly used optimization methods
+that rely completely on derivatives. Such methods work well when the
+function to be optimized is regular and smooth over the domain of
+parameter values that is of interest, but otherwise the methods often
+fail \citep{GillMurrayWright1981}. Even in models where such methods
+can be expected to work most of the time, resampling techniques such
+as the bootstrap \citep{EfronTibshirani1994} can generate resamples in
+which derivative-based optimization algorithms encounter severe
+difficulties. This is unfortunate because the methods most frequently
+used for optimization in problems of statistical estimation are
+entirely based on derivatives.
+
+The \pkg{rgenoud} package has been used by wide variety of users and
+developers. More than twelve \proglang{R} packages currently rely upon
+\pkg{rgenoud} including:
+\pkg{anchors} \citep[analyzing survey data with
+anchoring vignettes,][]{Wand+King:2011,WandKingLau2007,KingWand2007};
+\pkg{BARD} \citep[automated redistricting,][]{Altman+McDonald:2011};
+\pkg{boolean} \citep[boolean binary response models,][]{braumoeller2003,BraumoellerGoodrichKline2006};
+\pkg{DiceOptim} \citep[kriging-based optimization for computer experiments,][]{DiceOptim};
+\pkg{FAiR} \citep[factor analysis,][]{goodrich.fair};
+\pkg{JOP} \citep[simultaneous optimization of multiple responses,][]{JOP};
+\pkg{KrigInv} \citep[kriging-based inversion,][]{KrigInv};
+\pkg{PKfit} \citep[data analysis in pharmacokinetics,][]{LeeLee2006};
+\pkg{Matching} \citep[propensity score and multivariate matching,][]{SekhonMatching,Sekhon:2011};
+\pkg{ivivc} \citep[in vitro-in vivo correlation modeling,][]{ivivc};
+\pkg{multinomRob} \citep[robust multinomial models,][]{MebaneSekhon.multinomRob,MebaneSekhon2004}; and
+\pkg{Synth} \citep[synthetic control group method for comparative case studies,][]{AbadieGardeazabal2003,synth2008,Abadie+Diamond+Hainmueller:2011}.
+
+We present in Section \ref{sec:examples} an example using benchmark functions
+taken from \citet{yao.liu.lin1999}, followed by an example motivated by the
+\code{multinomRob} package. The benchmark suite includes functions that are
+high-dimensional, discontinuous or that have many local optima. The
+\code{multinomRob} package robustly estimates overdispersed multinomial
+regression models and uses \pkg{rgenoud} to solve a least quartile difference
+(LQD) generalized S-estimator \citep{MebaneSekhon2004}. The LQD is not a
+smooth function of the regression model parameters. The function is
+continuous, but the parameter space is finely partitioned by nondifferentiable
+boundaries.
+
+In another paper in this volume, the \pkg{Matching} package and its
+use of \pkg{rgenoud} are described in detail \citep{Sekhon:2011}.
+\pkg{Matching} provides functions for multivariate and propensity
+score matching and for finding optimal covariate balance based on a
+genetic search algorithm implemented in \pkg{rgenoud}. The search
+over optimal matches is discontinuous so no derivatives are
+used.\footnote{The \code{BFGS} option of \code{genoud} is set to
+ \code{FALSE}, and the ninth operator which depends on derivatives is
+ not used.} The search also involves lexical
+optimization which is a unique feature implemented in
+\pkg{rgenoud}.\footnote{Lexical optimization is useful when there are
+ multiple fitness criteria; the parameters are chosen so as to
+ maximize fitness values in lexical order---i.e., the second fit criterion
+ is only considered if the parameters have the same fit for the
+ first. See the \code{lexical} option and \citet{Sekhon:2011} for
+ details. All of \code{genoud}'s options are described in the
+ \proglang{R} help file for the function.}
+
+% If one wishes to use such a model,
+%significant optimization difficulties may need to be overcome. For
+%example, the estimating functions of all of the following models are
+%not in general globally concave: models with multivariate qualitative
+%variables, censoring or endogenous switching
+%\citep{maddala1983,amemiya1985}; linear covariance structures
+%\citep{bollen1989}; models for durations or transitions with
+%unobserved heterogeneity \citep{HeckmanSinger1985,lancaster1990};
+%quasi-likelihood and extended quasi-likelihood models
+%\citep{McCullaghNelder1989} and systems based on such models
+%\citep{FahrmeirTutz1994}; and nonlinear simultaneous equation models
+%\citep{gallant1987}. For such models, optimization methods driven
+%entirely by derivatives are often unreliable. For some versions of
+%some of these models, algorithms such as EM that involve data
+%augmentation have been successfully applied to produce optimization
+%problems that derivative-based methods can solve
+%\citep[e.g.,][197]{lancaster1990}.
+
+The \pkg{rgenoud} package implements an updated and extended version
+of the \proglang{C} program \code{GENOUD} \citep{MebaneSekhon1997}
+described in \citep{SekhonMebane1998}. The many improvements include
+among other things the interface with \proglang{R}, which includes the
+ability to optimize functions written in \proglang{R}, options to
+optimize both floating point and integer-valued parameters, the
+ability to optimize loss functions which return multiple fitness values
+(lexical optimization), the ability to call \code{genoud} recursively,
+the ability to have the optimizer evaluate fits only for new parameter
+values, and the ability to use multiple computers, CPUs or cores to
+perform parallel computations.
+
+The \pkg{rgenoud} program combines an evolutionary algorithm with a
+quasi-Newton method. The quasi-Newton method is the
+Broyden-Fletcher-Goldfarb-Shanno (BFGS) method
+\citep[][119]{GillMurrayWright1981} implemented in \proglang{R}'s \code{optim}
+function. When the BFGS is being used, our program offers the option of using
+either \pkg{rgenoud}'s built-in numerical derivatives (which are based on
+code taken from \citealt[][337--344]{GillMurrayWright1981}) or user-supplied
+analytical derivatives.\footnote{User supplied derivatives may be provides via
+ the \code{gr} option.} Our program can also work without the BFGS, in which
+case no derivatives are needed and the optimizer will work even when the
+function is discontinuous. The primary benefit from using derivatives is that
+the algorithm will then quickly find a local optimum when a current set of
+trial solution parameter values is in a smooth neighborhood of the local
+optimum point. Appropriate use of the BFGS can make the algorithm converge to
+the global optimum much more quickly. But premature or excessive use of the
+BFGS can prevent convergence to the global optimum.\footnote{The user can
+ control whether \code{genoud} uses the BFGS at all (via the \code{BFGS}
+ option), and if operators that use the BFGS are used (via the \code{P9}
+ option), how often they are used.} As always, it is hazardous to rely on an
+optimizer's default settings. Our program does not eliminate the need for
+judgment, testing and patience.
+
+As Gill, Murray and Wright observe, ``there is no guaranteed strategy that
+will resolve every difficulty'' \citep[285]{GillMurrayWright1981}. In this article, we very briefly
+review the theory of random search algorithms that supports the assertion that
+\pkg{rgenoud} has a high probability of finding the global optimum when such
+exists. And we present three examples of how to use the \code{genoud}
+function: to optimize a simple but fiendish scalar Normal mixture model; to
+minimize a suite of benchmark functions that have previously been used to test
+evolutionary programming optimization algorithms; and to optimize a version of
+the only intermittently differentiable LQD estimator. Additional details on
+both the theory and performance of \code{genoud} can be found in our article
+that describes \code{GENOUD} \citep{SekhonMebane1998}.
+
+\section{Background on Genetic Optimization}
+
+An evolutionary algorithm (EA) uses a collection of heuristic rules to
+modify a population of trial solutions in such a way that each
+generation of trial values tends to be, on average, better than its
+predecessor. The measure for whether one trial solution is better
+than another is the trial solution's fitness value. In statistical
+applications, the fitness is a function of the summary statistic being
+optimized (e.g., the log-likelihood). \pkg{rgenoud} works for cases
+in which a solution is a vector of floating-point or integer numbers
+that serve as the parameters of a function to be optimized. The
+search for a solution proceeds via a set of heuristic rules, or
+\textit{operators}, each of which acts on one or more trial solutions
+from the current population to produce one or more trial solutions to
+be included in the new population. EAs do not require derivatives to
+exist or the function to be continuous in order find the global
+optimum.
+
+The EA in \pkg{rgenoud} is fundamentally a genetic algorithm (GA) in which
+the code-strings are vectors of numbers rather than bit
+strings, and the GA operators take special forms tuned for the
+floating-point or integer vector representation. A GA uses a set of randomized
+genetic operators to evolve a finite population of finite code-strings
+over a series of generations
+\citep{holland1975,goldberg1989,GrefenstetteBaker1989}. The operators
+used in GA implementations vary
+\citep{davis1991,FilhoTreleavenAlippi1994}, but in an analytical sense
+the basic set of operators can be defined as reproduction, mutation,
+crossover and inversion. The variation in these operators across different
+GA implementations reflects
+the variety of codes best suited for different applications.
+Reproduction entails selecting a code-string with a probability that
+increases with the code-string's fitness value. Crossover and
+inversion use pairs or larger sets of the selected code-strings to
+create new code-strings. Mutation randomly changes the values of
+elements of a single selected code-string.
+
+Used in suitable combinations, the genetic operators tend to improve
+average fitness of each successive generation, though there is no
+guarantee that average fitness will improve between every pair of
+successive generations. Average fitness may well decline. But
+theorems exist to prove that parts of the trial solutions that have above average
+fitness values in the current population are sampled at an
+exponential rate for inclusion in the subsequent population
+\citep[][139--140]{holland1975}. Each generation's population
+contains a biased sample of code-strings, so that a substring's
+performance in that population is a biased estimate of its average
+performance over all possible populations
+\citep{dejong1993,grefenstette1993}.
+
+The long-run properties of a GA may be understood by thinking of the GA as a
+Markov chain. A state of the chain is a code-string population of the size
+used in the GA. For code-strings of finite length and GA populations of
+finite size, the state space is finite. If such a GA uses random reproduction
+and random mutation, all states always have a positive probability of
+occurring. A finite GA with random reproduction and mutation is therefore
+approximately a finite and irreducible Markov
+chain.\footnote{\citet[][372--419]{feller1970} and
+ \citet[][107--142]{billingsley1986} review the relevant properties of Markov
+ chains. The randomness in an actual GA depends on the performance of
+ pseudorandom number generators. This and the limitations of floating point
+ arithmetic mean it is not literally true that an actual GA has a positive
+ probability of reaching any state from any other state, and some states may
+ in fact not be reachable from a given set of initial conditions.} An
+irreducible, finite Markov chain converges at an exponential rate to a unique
+stationary distribution \citep[][128]{billingsley1986}. This means that the
+probability that each population occurs rapidly converges to a constant,
+positive value. \citet{NixVose1992} and
+\citet{vose1993} use a Markov chain model to show that in a GA where the
+probability that each code-string is selected to reproduce is proportional to
+its observed fitness, the stationary distribution strongly emphasizes
+populations that contain code-strings that have high fitness values. They
+show that asymptotic in the population size---i.e., in the limit for a series
+of GAs with successively larger populations---populations that have suboptimal
+average fitness have probabilities approaching zero in the stationary
+distribution, while the probability for the population that has optimal
+average fitness approaches one. If $k>1$ populations have optimal average
+fitness, then in the limiting stationary distribution the probability for each
+approaches $1/k$.
+
+The theoretical results of Nix and Vose imply that a GA's success as an
+optimizer depends on having a sufficiently large population of code-strings.
+If the GA population is not sufficiently large, then the Markov chain that the
+GA approximately implements is converging to a stationary distribution in
+which the probabilities of optimal and suboptimal states are not sharply
+distinguished. Suboptimal populations can be as likely to occur as optimal
+ones. If the stationary distribution is not favorable, the run time in terms
+of generations needed to produce an optimal code-string will be excessive.
+For all but trivially small state spaces, an unfavorable stationary
+distribution can easily imply an expected running time in the millions of
+generations. But if the stationary distribution strongly emphasizes optimal
+populations, relatively few generations may be needed to find an optimal
+code-string. In general, the probability of producing an optimum in a fixed
+number of generations tends to increase with the GA population size.
+
+\begin{table}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\begin{enumerate}
+\item[\code{P1}] Cloning. Copy $\mathbf{X}_{t}$ into the next generation,
+ $\mathbf{X}_{t+1}$.
+\item[\code{P2}] Uniform Mutation. At random choose $i\in\mathbf{N}$. Select a value
+ $\tilde{x}_i \sim U(\underline{x}_i, \overline{x}_i)$. Set
+ $X_i=\tilde{x}_i$.
+\item[\code{P3}] Boundary Mutation. At random choose $i\in\mathbf{N}$. Set either
+ $X_i=\underline{x}_i$ or $X_i=\overline{x}_i$, with probability $1/2$ of
+ using each value.
+\item[\code{P4}] Non-uniform Mutation. At random choose $i\in\mathbf{N}$. Compute
+ $p = (1-t/T)^B u$, where $t$ is the current generation number, $T$ is the
+ maximum number of generations, $B>0$ is a tuning parameter and $u \sim
+ U(0,1)$. Set either $X_i=(1-p)x_i + p\underline{x}_i$ or $X_i=(1-p)x_i +
+ p\overline{x}_i$, with probability $1/2$ of using each value.
+\item[\code{P5}] Polytope Crossover. Using $m=\max(2,n)$ vectors
+ $\mathbf{x}$ from the current population and $m$ random numbers
+ $p_j\in(0,1)$ such that $\sum_{j=1}^m p_j = 1$, set $\mathbf{X} =
+ \sum_{j=1}^m p_j \mathbf{x}_j$.
+\item[\code{P6}] Simple Crossover. Choose a single integer $i$ from $\mathbf{N}$.
+ Using two parameter vectors, $\mathbf{x}$ and $\mathbf{y}$,
+ set $X_i = p x_i + (1-p) y_i$ and $Y_i = p y_i + (1-p)
+ x_i$, where $p\in(0,1)$ is a fixed number.
+\item[\code{P7}] Whole Non-uniform Mutation. Do non-uniform mutation for
+ all the elements of $\mathbf{X}$.
+\item[\code{P8}] Heuristic Crossover. Choose $p \sim U(0,1)$. Using two parameter
+ vectors, $\mathbf{x}$ and $\mathbf{y}$, compute $\mathbf{z} =
+ p(\mathbf{x} - \mathbf{y}) + \mathbf{x}$. If $\mathbf{z}$ satisfies
+ all constraints, use it. Otherwise choose another $p$ value and repeat.
+ Set $\mathbf{z}$ equal to the better of $\mathbf{x}$ and $\mathbf{y}$ if
+ a satisfactory mixed $\mathbf{z}$ is not found by a preset number of
+ attempts. In this fashion produce two $\mathbf{z}$ vectors.
+\item[\code{P9}] Local-minimum Crossover. Choose $p \sim U(0,1)$.
+ Starting with $\mathbf{x}$, run BFGS optimization up to a preset
+ number of iterations to produce $\mathbf{\tilde{x}}$. Compute
+ $\mathbf{z} = p\mathbf{\tilde{x}} + (1-p)\mathbf{x}$. If
+ $\mathbf{z}$ satisfies boundary constraints, use it. Otherwise
+ shrink $p$ by setting $p = p/2$ and recompute $\mathbf{z}$. If a
+ satisfactory $\mathbf{z}$ is not found by a preset number of
+ attempts, return $\mathbf{x}$. This operators is extremely
+ computationally intensive, use sparingly.
+\end{enumerate}
+
+\begin{flushleft}
+ Notation: \\ [2ex]
+ $\mathbf{X} =\begin{bmatrix}X_1,\dots,X_n\end{bmatrix}$ is the
+ vector of $n$ parameters $X_i$. $\underline{x}_i$ is the lower
+ bound and $\overline{x}_i$ is the upper bound on values for $X_i$.
+ $x_i$ is the current value of $X_i$, and $\mathbf{x}$ is the current
+ value of $\mathbf{X}$. $\mathbf{N} = \{1,\dots,n\}$. $p \sim
+ U(0,1)$ means that $p$ is drawn from the uniform distribution on the
+ $[0,1]$ interval.
+\end{flushleft}
+ \caption{`genoud' Operators. Adapted from \citet{SekhonMebane1998}.}
+\label{tab:operators}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+The evolutionary algorithm in \pkg{rgenoud} uses nine operators that
+are listed in Table~\ref{tab:operators}. The operators extend and
+modify a set of operators used in \code{GENOCOP}
+\citep{MichalewiczSwaminathanLogan1993, Michalewicz1992}. The
+operators are numbered using syntax matching that used to refer to
+them by \pkg{rgenoud}. The \textit{cloning} operator simply makes
+copies of the best trial solution in the current generation
+(independent of this operator, \pkg{rgenoud} always retains one
+instance of the best trial solution). The \textit{uniform mutation},
+\textit{boundary mutation} and \textit{non-uniform mutation} operators
+act on a single trial solution. Uniform mutation changes one
+parameter in the trial solution to a random value uniformly
+distributed on the domain specified for the parameter. Boundary
+mutation replaces one parameter with one of the bounds of its domain.
+Non-uniform mutation shrinks one parameter toward one of the bounds,
+with the amount of shrinkage decreasing as the generation count
+approaches the specified maximum number of generations. \textit{Whole
+ non-uniform mutation} does non-uniform mutation for all the
+parameters in the trial solution. \textit{Heuristic crossover} uses
+two trial solutions to produce a new trial solution located along a
+vector that starts at one trial solution and points away from the
+other one. \textit{Polytope crossover} (inspired by simplex search,
+\citealt[][94--95]{GillMurrayWright1981}) computes a trial solution
+that is a convex combination of as many trial solutions as there are
+parameters. \textit{Simple crossover} computes two trial solutions
+from two input trial solutions by swapping parameter values between
+the solutions after splitting the solutions at a randomly selected
+point. This operator can be especially effective if the ordering of
+the parameters in each trial solution is consequential.
+\textit{Local-minimum crossover} computes a new trial solution in two
+steps: first it does a preset number of BFGS iterations starting from
+the input trial solution; then it computes a convex combination of the
+input solutions and the BFGS iterate.
+
+
+\section{Examples}
+\label{sec:examples}
+
+The only function in the \pkg{rgenoud} package is \code{genoud}. The
+interface of this function is similar to that of the \code{optim}
+function in \proglang{R}. But the function has many additional
+arguments that control the behavior of the evolutionary algorithm.
+
+\subsection{Asymmetric Double Claw:}
+Our first example, which we also studied in \citet{SekhonMebane1998}, is a
+normal mixture called the Asymmetric Double Claw (ADC). We plot the function
+in Figure~\ref{fig:mixture1}.
+\begin{figure}
+ \caption{Normal Mixture: Asymmetric Double Claw}
+ \vspace{-.5in}
+ \label{fig:mixture1}
+ \begin{center}
+ \includegraphics{fig1.pdf}
+ \end{center}
+ \vspace{-.7in}
+\end{figure}
+Mathematically, this mixture is defined as
+\begin{eqnarray}
+ \label{eq:adclaw}
+ f_{\mathrm{ADC}} & =
+ \sum_{m=0}^{1} \frac{46}{100} \mathrm{N}\left(2m-1,\frac{2}{3}\right) +
+ \sum_{m=1}^{3} \frac{1}{300} \mathrm{N}\left(\frac{-m}{2},\frac{1}{100}\right) +
+ \sum_{m=1}^{3} \frac{7}{300} \mathrm{N}\left(\frac{m}{2},\frac{7}{100}\right),
+\end{eqnarray}
+where N is the normal density.
+
+The asymmetric double claw is difficult to maximize because there are
+many local solutions. There are five local maxima in Figure
+\ref{fig:mixture1}. Standard derivative-based optimizers would
+simply climb up the hill closest to the starting value.
+
+To optimize this normal mixture we must first create a function for it
+<<eval=true,results=hide>>=
+ claw <- function(xx) {
+ x <- xx[1]
+ y <- (0.46*(dnorm(x,-1.0,2.0/3.0) + dnorm(x,1.0,2.0/3.0)) +
+ (1.0/300.0)*(dnorm(x,-0.5,.01) + dnorm(x,-1.0,.01) + dnorm(x,-1.5,.01)) +
+ (7.0/300.0)*(dnorm(x,0.5,.07) + dnorm(x,1.0,.07) + dnorm(x,1.5,.07)))
+ return(y)
+ }
+@
+And we now make a call to \pkg{rgenoud} using this function:
+<<eval=true,results=hide>>=
+library("rgenoud")
+claw1 <- genoud(claw, nvars=1, max=TRUE, pop.size=3000)
+@
+
+The first argument of \code{genoud} is the function to be optimized. The first
+argument of that function must be the vector of parameters over which
+optimizing is to occur. Generally, the function should return a
+scalar result.\footnote{The function to be optimized may return a
+ vector if one wishes to do lexical optimization. Please see
+ the \code{lexical} option to \code{genoud}.} The second argument of \code{genoud} in this example
+(\code{nvars}) is
+the number of variables the function to be optimized takes.
+The third argument, \code{max=TRUE}, tells
+\code{genoud} to maximize the function instead of its default behavior
+which is to minimize.
+
+The fourth option \code{pop.size} controls the most important part
+of the evolutionary algorithm, the population size. This is the
+number of individuals \code{genoud} uses to solve the optimization
+problem. As noted in the theoretical discussion, the theorems related
+to evolutionary algorithms are asymptotic in the population size so
+larger is generally better but obviously takes longer. The maximum
+solution of the double claw density is reliably found by \code{genoud}
+even using the default value of \code{pop.size=1000}.
+Reliability does increase as the \code{pop.size} is made larger.
+Unfortunately, because of the stochastic nature of the algorithm, it
+is impossible to generally answer the question of what is the best
+population size to use.
+
+Other options determine the maximum number of generations the evolutionary
+algorithm computes. These options are \code{max.generations},
+\code{wait.generations} and \code{hard.generation.limit}. The specified
+termination point also affects how some of the operators perform: the two
+non-uniform mutation operators introduce smaller ranges of variation in the
+trial solutions as the generation count approaches the specified
+\code{max.generations} value. There are many more options that can be used
+to fine-tune the behavior of the algorithm.
+
+The output printed by \code{genoud} is controlled by a \code{print.level}
+argument. The default value, \code{print.level=2}, produces relatively
+verbose output that gives extensive information about the set of operators
+being used and the progress of the optimization. Normally \proglang{R}
+conventions would suggest setting the default to be \code{print.level=0},
+which would suppress output to the screen, but because \code{genoud} runs may
+take a long time, it can be important for the user to receive some feedback to
+see the program has not died and to be able to see where the program got stuck
+if it eventually fails to make adequate progress.
+
+The output printed by the preceding invocation of \code{genoud}, which uses
+the default value for a \code{print.level} argument, is as follows.
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Fri Feb 9 19:33:42 2007
+Domains:
+ -1.000000e+01 <= X1 <= 1.000000e+01
+
+Data Type: Floating Point
+Operators (code number, name, population)
+ (1) Cloning........................... 372
+ (2) Uniform Mutation.................. 375
+ (3) Boundary Mutation................. 375
+ (4) Non-Uniform Mutation.............. 375
+ (5) Polytope Crossover................ 375
+ (6) Simple Crossover.................. 376
+ (7) Whole Non-Uniform Mutation........ 375
+ (8) Heuristic Crossover............... 376
+ (9) Local-Minimum Crossover........... 0
+
+HARD Maximum Number of Generations: 100
+Maximum Nonchanging Generations: 10
+Population size : 3000
+Convergence Tolerance: 1.000000e-03
+
+Using the BFGS Derivative Based Optimizer on the Best Individual Each Generation.
+Checking Gradients before Stopping.
+Using Out of Bounds Individuals.
+
+Maximization Problem.
+GENERATION: 0 (initializing the population)
+Fitness value... 4.112017e-01
+mean............ 4.990165e-02
+variance........ 9.708147e-03
+#unique......... 3000, #Total UniqueCount: 3000
+var 1:
+best............ 9.966758e-01
+mean............ 3.453097e-02
+variance........ 3.373681e+01
+
+GENERATION: 1
+Fitness value... 4.113123e-01
+mean............ 2.237095e-01
+variance........ 2.566140e-02
+#unique......... 1858, #Total UniqueCount: 4858
+var 1:
+best............ 9.995043e-01
+mean............ 4.615946e-01
+variance........ 7.447887e+00
+
+[...]
+
+GENERATION: 10
+Fitness value... 4.113123e-01
+mean............ 2.953888e-01
+variance........ 2.590842e-02
+#unique......... 1831, #Total UniqueCount: 21708
+var 1:
+best............ 9.995033e-01
+mean............ 8.403935e-01
+variance........ 5.363241e+00
+
+GENERATION: 11
+Fitness value... 4.113123e-01
+mean............ 2.908561e-01
+variance........ 2.733896e-02
+#unique......... 1835, #Total UniqueCount: 23543
+var 1:
+best............ 9.995033e-01
+mean............ 8.084638e-01
+variance........ 6.007372e+00
+
+'wait.generations' limit reached.
+No significant improvement in 10 generations.
+
+Solution Fitness Value: 4.113123e-01
+
+Parameters at the Solution (parameter, gradient):
+
+ X[ 1] : 9.995033e-01 G[ 1] : -6.343841e-09
+
+Solution Found Generation 1
+Number of Generations Run 11
+
+Fri Feb 9 19:33:45 2007
+Total run time : 0 hours 0 minutes and 3 seconds
+ \end{CodeOutput}
+\end{CodeChunk}
+
+%DESCRIBE OUTPUT
+
+After printing the date and time of the run, the program prints the domain of
+values it is allowing for each parameter of the function being optimized. In
+this case the default domain values are being used. Naturally it is important
+to specify domains wide enough to include the solution. In practice with
+highly nonlinear functions it is often better to specify domains that are
+relatively wide than to have domains that narrowly and perhaps even correctly
+bound the solution. This surprising behavior reflects the fact with a highly
+nonlinear function, a point that is close to the solution in the sense of
+simple numerical proximity may not be all that close in the sense of there
+being a short feasible path to get to the solution.
+
+Next the program prints the Data Type. This indicates whether the parameters
+of the function to be optimized are being treated as floating point numbers or
+integers. For more information about this, see the \code{data.type.int}
+argument.
+
+The program then displays the number of operators being used, followed by the
+values that describe the other characteristics set for this particular run:
+the maximum number of generations, the population size and the tolerance value
+to be used to determine when the parameter values will be deemed to have
+converged.
+
+The output then reports whether BFGS optimization will be applied to the best
+trial solution produced by the operators in each generation. For problems
+that are smooth and concave in a neighborhood of the global optimum, using the
+BFGS in this way can help \code{genoud} quickly converge once the best trial
+solution is in the correct neighborhood. This run of \code{genoud} will also
+compute the gradient at the best trial solution before stopping. In fact this
+gradient checking is used as a convergence check. The algorithm will not
+start counting its final set of generations (the \code{wait.generations})
+until each element of the gradient is smaller in magnitude than the
+convergence tolerance. Gradients are never used and BFGS optimization is not
+used when the parameters of the function to be optimized are integers.
+
+The next message describes how strictly \code{genoud} is enforcing the
+boundary constraints specified by the domain values. By default
+(\code{boundary.enforcement=0}), the trial solutions are allowed to wander
+freely outside the boundaries. The boundaries are used only to define domains
+for those operators that use the boundary information. Other settings of the
+\code{boundary.enforcement} argument induce either more stringent or
+completely strict enforcement of the boundary constraints. Notice that the
+boundary constraints apply to the parameters one at a time. To enforce
+constraints that are defined by more complicated functional or data-dependent
+relationships, one can include an appropriate penalty function as part of the
+definition of the function to be optimized, letting that function define an
+extremely high (if minimizing) or low (if maximizing) value to be returned if
+the desired conditions are violated.
+
+After reporting whether it is solving a minimization or a maximization problem,
+\code{genoud} reports summary statistics that describe the distribution of the
+fitness value and the parameter values across the trial solutions at the end
+of each generation. In the default case where \code{genoud} is keeping track
+of all the distinct solutions considered over the whole course of the
+optimizing run, these generational reports also include a report of the number
+of unique trial solutions in the current population and the number of unique
+solutions ever considered. The benefit of keeping track of the solutions is
+to avoid repeatedly evaluating the function being optimized for the
+identical set of parameter values. This can be an important efficiency when
+function evaluations are expensive, as they can be in statistical applications
+where the data are extensive. This tracking behavior is controlled by the
+\code{MemoryMatrix} argument.
+
+Upon convergence, or when the hard maximum generation limit is reached, the
+program prints the fitness value at the best trial solution and that
+solution's parameter values. In this case the solution was found after one
+generation. While the Asymmetric Double Claw might present a difficult
+challenge for a gradient-based optimizer that uses only local hill climbing,
+it is an almost trivially simple problem for \code{genoud}.
+
+\subsection{Benchmark Functions:}
+The second example is a suite of 23 benchmark nonlinear functions used
+in \citet{yao.liu.lin1999} to study a pair of evolutionary programming
+optimization algorithms. Function definitions are in
+Table~\ref{tab:23funcs}. Because it includes a random component and
+so lacks a reproducible minimum value, we ignore the function numbered
+function 7 in their sequence.\footnote{The omitted function is
+ $\sum_{i=1}^n ix_i^4 +U(0,1)$, where $U(0,1)$ is a uniformly
+ distributed random variable on the unit interval that takes a new
+ value whenever the function is evaluated. This stochastic aspect
+ means that even given the set of parameters that minimize the
+ nonstochastic component $\sum_{i=1}^n ix_i^4$, i.e., $x_i=0$, the
+ value of the function virtually never attains the minimum possible
+ value of zero. An optimizer that evaluated the function at $x_i=0$
+ would not in general obtain a function value smaller than the
+ function value obtained for a wide range of different parameter
+ values. Hence we do not consider this function to be a good test
+ for function optimization algorithms.} Implementations of these
+functions are available in the supplemental \proglang{R} file provided
+with this article.\footnote{This supplemental file is available at
+ \url{http://sekhon.berkeley.edu/rgenoud/func23.R}.} These
+\proglang{R} definitions include the values of the constants used in
+functions 14, 15 and 19 through 23. The function argument domains are
+restricted to the specific domains used by \citet{yao.liu.lin1999} via
+bounds that are stated in the list named \code{testbounds} in the
+supplemental file.
+
+\begin{table}
+ \begin{center}
+ \line(1,0){450}
+ \end{center}
+ \begin{tabular}{LLLL}
+\text{func.} & \text{definition} & n & \text{minimum}^a \\
+ 1 & \sum_{i=1}^n x_i^2 & 30 & 0 \\
+ 2 & \sum_{i=1}^n |x_i| + \prod_{i=1}^n |x_i| & 30 & 0 \\
+ 3 & \sum_{i=1}^n (\sum_{j=1}^i x_j)^2 & 30 & 0 \\
+ 4 & \max_i \{|x_i|, 1\leq i\leq n\} & 30 & 0 \\
+ 5 & \sum_{i=1}^{n-1} [100(x_{i+1}-x_i^2)^2 +(x_i-1)^2],
+ & 30 & 0 \\
+ 6 & \sum_{i=1}^n (\lfloor x_i + 0.5\rfloor)^2 & 30 & 0 \\
+ 7 & \sum_{i=1}^n ix_i^4 +U(0,1) & 30 & 0 \\
+ 8 & \sum_{i=1}^n -x_i\sin(\sqrt{|x_i|}) & 30 & -12569.5 \\
+ 9 & \sum_{i=1}^n [x_i^2-10\cos(2\pi x_i)+10] & 30 & 0 \\
+10 & -20\exp\left(-0.2\sqrt{n^{-1}\sum_{i=1}^n x_i^2}\,\right) \\
+ & \qquad -\exp(n^{-1}\sum_{i=1}^n\cos 2\pi x_i)+20+e & 30 & 0 \\
+11 & (1/1000) \sum_{i=1}^n x_i^2 -
+\prod_{i=1}^n\cos\left(x_i/\sqrt{i}\right) + 1 & 30 & 0 \\
+12 & n^{-1}\pi \left\{10 \sin^2(\pi y_1)+\sum_{i=1}^{n-1}(y_i-1)^2
+[1+10\sin^2(\pi y_{i+1})]+(y_n-1)^2\right\} \\
+ & \quad +\sum_{i=1}^n u(x_i,10,100,4), & 30 & 0 \\
+ & y_i=1+(x_i+1)/4, \quad u(x_i,a,k,m)=\begin{cases} k(x_i-a)^m, & x_i>a, \\
+ 0, & -a\leq x_i\leq a,\\ k(-x_i-a)^m, & x_i<-a,
+\end{cases} & \\
+13 & \left\{ \sin^2(3\pi
+ x_1)+\sum_{i=1}^{n-1}(x_i-1)^2[1+\sin^2(3\pi x_{i+1})]\right\}/10 \\
+ & \quad +(x_n-1)[1+\sin^2(2\pi x_n)]/10
++\sum_{i=1}^n u(x_i,5,100,4) & 30 & 0 \\
+14 & \left\{1/500+
+\sum_{j=1}^{25} 1/\left[j+\sum_{i=1}^2(x_i-a_{ij})^6\right]\right\}^{-1} & 2 & 1 \\
+15 & \sum_{i=1}^{11} [a_i-x_1(b_i^2+b_ix_2)/(b_i^2+b_ix_3+x_4)]^2 & 4 & 0.0003075 \\
+16 & 4x_1^2-2.1x_1^4+x_1^6/3+x_1x_2-4x_2^2+4x_2^4 & 2 & -1.0316285 \\
+17 & [x_2-5.1x_1^2/(4\pi^2) + 5x_1/\pi - 6]^2 +
+ 10[1-1/(8\pi)]\cos(x_1) + 10 & 2 & 0.398 \\
+18 & [1+(x_1+x_2+1)^2(19-14 x_1+3 x_1^2-14 x_2+6 x_1 x_2+3 x_2^2)] \\
+ & \quad \times [30+(2 x_1-3 x_2)^2 (18-32 x_1+12 x_1^2+48 x_2-36 x_1 x_2+27 x_2^2)] & 2 & 3 \\
+19 & -\sum_{i=1}^4 c_i\exp\left[-\sum_{j=1}^4 a_{ij}(x_i-p_{ij})^2\right] & 4 & -3.86 \\
+20 & -\sum_{i=1}^4 c_i\exp\left[-\sum_{j=1}^6 a_{ij}(x_i-p_{ij})^2\right] & 6 & -3.32 \\
+21 & \sum_{i=1}^5 [(x-a_i)^{\prime}(x-a_i)+c_i]^{-1} & 4 & -10 \\
+22 & \sum_{i=1}^7 [(x-a_i)^{\prime}(x-a_i)+c_i]^{-1} & 4 & -10 \\
+23 & \sum_{i=1}^{10} [(x-a_i)^{\prime}(x-a_i)+c_i]^{-1} & 4 & -10
+ \end{tabular}
+ \begin{flushleft}
+ Notes: $^a$Minimum function value within specified bounds as given by
+ \citet[85]{yao.liu.lin1999}.
+ \end{flushleft}
+ \vspace*{.1in}
+ \caption{23 Benchmark Functions}
+ \label{tab:23funcs}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+As \citet{yao.liu.lin1999} describe, optimizing each of functions
+1--13 presents a high-dimensional problem. These functions each have
+$n=30$ free parameters. Functions 1--5 are unimodal, with function 5
+being a 30-dimensional version of the banana-shaped Rosenbrock
+function. Function 6 is a step function. Function 6 has one minimum
+value that occurs when all arguments are in the interval
+$x_i\in[0,.5)$, and the function is discontinuous. Functions 8--13
+are multimodal, defined such that the number of local minima increases
+exponentially with the number of arguments.
+\citet[84]{yao.liu.lin1999} describe these functions as among ``the
+most difficult class of problems for many optimization algorithms
+(including [evolutionary programming]).'' Functions 14--23, which
+have between two and six free parameters each, each have only a few
+local minima. Nonetheless the evolutionary programming algorithms
+considered by \citet{yao.liu.lin1999} have trouble optimizing
+functions 21--23. Although \citet[85]{yao.liu.lin1999} state that
+each of these functions has a minimum value of $-10$, over 50
+replications the two algorithms they consider achieve solutions
+averaging between $-5.52$ and $-9.10$ \citep[88,
+Table~IV]{yao.liu.lin1999}.
+
+We use these benchmark functions to illustrate not only how effective
+\code{genoud} can be with a range of difficult problems, but also to emphasize
+an important aspect of how one should think about trying to tune the
+optimizer's performance. Theory regarding genetic algorithms suggests that
+optimal solutions are more likely to appear as both the population size of
+candidate solutions and the number of generations increase. In \code{genoud}
+two arguments determine the number of generations. One is
+\code{max.generations}: if \code{hard.generation.limit=TRUE}, then the value
+specified for \code{max.generations} is a binding upper limit. The other is
+\code{wait.generations}, which determines when the algorithm terminates if
+\code{hard.generation.limit=FALSE}. But even if
+\code{hard.generation.limit=TRUE}, then \code{wait.generations} determines for
+how many generations the algorithm continues once the best parameter vector
+and the value of the function being optimized appear to have settled down.
+The fact that the current best solution is not changing should not be treated
+as decisive, because this solution may be merely a local optimum or a
+saddlepoint. If the population size is sufficient, the algorithm tends to
+build a population of trial solutions that contain parameters in neighborhoods
+of all the competitive local optima in the domain defined by the parameter
+boundaries. Even while the current best solution is stable, the algorithm is
+improving the solutions near other local optima. So having a higher
+\code{wait.generations} value never worsens the algorithm's efficacy.
+
+Increasing \code{max.generations} may or may not in itself improve
+optimization. The value of \code{max.generations} sets the value of $T$ used
+in the mutation operators---operators 4 and 7 in Table~\ref{tab:operators}.
+These mutation operators perform random search near a trial solution that has
+been selected for mutation only when the current generation count is an
+appreciable fraction of $T$. So increasing \code{max.generations} without
+changing \code{wait.generations} increases the period during which random
+search is occurring over a wider domain. For multimodal functions such a
+wider search may be helpful, but sometimes failing to search more densely near
+the current trial solutions is not good.
+
+We use \code{genoud} to minimize the 23 functions using two values for
+\code{pop.size} (5000 and 10000) and two values for
+\code{max.generations} (30 and 100). Following
+\citet{yao.liu.lin1999}, we replicate each optimization 50 times. The
+following code describes the computations. The list \code{testfuncs},
+vector \code{testNparms} and list \code{testbounds} are defined in the
+supplemental \proglang{R} file, and it is assume that this file is
+loaded with the \code{source("supplemental.R")} command. The vector
+\code{gradcheck} is true for all elements except the ones corresponding
+to functions 6 and 7.
+<<eval=false>>=
+source("supplemental.R")
+gradcheck <- rep(TRUE,23)
+gradcheck[6:7] <- FALSE
+sizeset <- c(5000,10000)
+genset <- c(30,100)
+nreps <- 50
+gsarray <- array(NA, dim=c(length(sizeset), length(genset), 23, nreps))
+asc <- function(x) { as.character(x) }
+dimnames(gsarray) <- list(asc(sizeset), asc(genset), NULL, NULL);
+for (gsize in sizeset) {
+ for (ngens in genset) {
+ for (i in 1:23) {
+ for (j in 1:nreps) {
+ gsarray[as.character(gsize), as.character(ngens),i,j] <-
+ genoud(testfuncs[[i]], nvars=testNparms[i], pop.size=gsize,
+ max.gen=ngens, hard.gen=TRUE, Domains=testbounds[[i]],
+ solution.tol=1e-6, boundary=1, gradient.check=gradcheck[i],
+ print=0)$value
+ }
+ }
+ }
+}
+@
+
+Using \code{genoud} to minimize the benchmark functions produces excellent
+results, at least when the \code{pop.size} and \code{max.generations}
+arguments are sufficiently large. Table~\ref{tab:23mean} reports the mean
+function values for each configuration of the arguments. These values may be
+compared both to the true function minima given by \citet{yao.liu.lin1999}
+(see the rightmost column in Table~\ref{tab:23funcs}) and to the average
+minimum function values \citet{yao.liu.lin1999} report for their ``fast''
+evolutionary programming (FEP) algorithm, which appear in the last column of
+Table~\ref{tab:23mean}. The \code{genoud} averages for the \code{max.gen=100}
+configurations equal or are close to the true minima for all the functions
+except function 13. One can reasonably argue that the average solutions for
+function 5 are not as close to zero as might be desired: these averages are
+close to $10^{-7}$, while the averages for other functions that have a true
+minimum of zero are $10^{-15}$ or smaller. And the averages for functions 6,
+12 and 15 in the \code{pop.size=5000} case are off. The effect of increasing
+\code{pop.size} is apparent with respect to both those three functions and
+also functions 13 and 20--23: the average minima are smaller with
+\code{pop.size=10000} than with \code{pop.size=5000}. Except for functions 6
+and 12 in the \code{pop.size=5000} case and function 13, all the \code{genoud}
+solution averages for \code{max.gen=100} are either slightly or substantially
+better than the corresponding FEP solution averages.
+
+The results in Table~\ref{tab:23mean} clearly illustrate the potential
+consequences of not allowing \code{genoud} to run for a sufficient number of
+generations. While some of the \code{genoud} solutions for \code{max.gen=30}
+have competitive means, several of the means are not good at all.
+
+\begin{table}
+ \begin{center}
+ \line(1,0){450}
+ \end{center}
+ \begin{tabular}{llllll}
+ & \multicolumn{4}{c}{\code{genoud}} & \\ \cline{2-5}
+ & \multicolumn{2}{c}{\code{pop.size=5000}$^a$} & \multicolumn{2}{c}{\code{pop.size=10000}$^a$} & \\
+\text{func.} & \code{max=30} & \code{max=100} & \code{max=30} & \code{max=100} & \text{FEP}$^b$ \\
+ 1 & 1.453\e 32 & 1.658\e 32 & 2.416\e 32 & 6.134\e 32 & 5.7\e 4 \\
+ 2 & 6.55\e 16 & 7.212\e 16 & 9.652\e 16 & 1.043\e 15 & 8.1\e 3 \\
+ 3 & 4.633\e 18 & 3.918\e 18 & 3.787\e 18 & 4.032\e 18 & 1.6\e 2 \\
+ 4 & 6.203\e 17 & 6.542\e 17 & 9.453\e 17 & 7.85\e 17 & 0.3 \\
+ 5 & 0.07973 & 5.887\e 08 & 8.133\e 08 & 8.917\e 08 & 5.06 \\
+ 6 & 18.58 & 0.08 & 9.38 & 0 & 0 \\
+% 7 & 0.1114 & 0.07473 & 0.1114 & 0.06466 & 7.6\e 3 \\
+ 8 & -12569.49 & -12569.49 & -12569.49 & -12569.49 & -12554.5 \\
+ 9 & 2.786 & 0 & 0.9353 & 0 & 4.6\e 2 \\
+10 & 2.849 & 3.997\e 15 & 2.199 & 3.997\e 15 & 1.8\e 2 \\
+11 & 7.994\e 17 & 7.105\e 17 & 9.548\e 17 & 6.439\e 17 & 1.6\e 2 \\
+12 & 5.371\e 19 & 0.004147 & 0.002073 & 1.178\e 19 & 9.2\e 6 \\
+13 & 0.02095 & 0.006543 & 0.006629 & 0.003011 & 1.6\e 4 \\
+14 & 0.998 & 0.998 & 0.998 & 0.998 & 1.22 \\
+15 & 0.0003441 & 0.0004746 & 0.0003807 & 0.0003807 & 5.0\e 4 \\
+16 & -1.0316285 & -1.0316285 & -1.0316285 & -1.0316285 & -1.03 \\
+17 & 0.3979 & 0.3979 & 0.3979 & 0.3979 & 0.398 \\
+18 & 3 & 3 & 3 & 3 & 3.02 \\
+19 & -3.863 & -3.863 & -3.863 & -3.863 & -3.86 \\
+20 & -3.274 & -3.277 & -3.279 & -3.286 & -3.27 \\
+21 & -9.85 & -9.444 & -9.95 & -10.05 & -5.52 \\
+22 & -9.771 & -10.09 & -10.19 & -10.3 & -5.52 \\
+23 & -10.1 & -9.997 & -10.32 & -10.21 & -6.57
+ \end{tabular}
+ \begin{flushleft}
+ Note: $^b$Average minimum function values (over 50 replications) obtained
+ using \code{genoud}. $^a$Mean best function values (over 50 replications)
+ reported for the ''fast'' evolutionary programming algorithm, from
+ \citet[85 and 88, Tables II--IV]{yao.liu.lin1999}.
+ \end{flushleft}
+ \vspace*{.1in}
+ \caption{Mean Values of 22 Optimized Functions}
+ \label{tab:23mean}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+The effect of increasing \code{pop.size} are even more clearly apparent in
+Table~\ref{tab:23sdev}, which reports the standard deviations of the
+respective minima across the 50 replications. With the exceptions of
+functions 6, 12, 13, 15 and 21 with \code{pop.size=5000}, the \code{genoud}
+solutions for \code{max.gen=100} vary much less than the corresponding FEP
+solutions. For those functions and also for functions 20, 22 and 23, the
+\code{max.gen=100} solutions with \code{pop.size=10000} vary noticeably less
+than the solutions with \code{pop.size=5000}.
+
+\begin{table}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+ \begin{tabular}{llllll}
+ & \multicolumn{4}{c}{\code{genoud}} & \\ \cline{2-5}
+ & \multicolumn{2}{c}{\code{pop.size=5000}$^a$} & \multicolumn{2}{c}{\code{pop.size=10000}$^a$} & \\
+\text{func.} & \code{max=30} & \code{max=100} & \code{max=30} & \code{max=100} & \text{FEP}$^b$ \\
+ 1 & 9.997\e 32 & 7.059\e 32 & 9.562\e 32 & 2.1\e 31 & 1.3\e 4 \\
+ 2 & 1.668\e 15 & 1.621\e 15 & 2.116\e 15 & 2.102\e 15 & 7.7\e 4 \\
+ 3 & 4.568\e 18 & 3.342\e 18 & 4.38\e 18 & 5.136\e 18 & 1.4\e 2 \\
+ 4 & 1.793\e 16 & 1.758\e 16 & 2.055\e 16 & 2.002\e 16 & 0.5 \\
+ 5 & 0.5638 & 4.921\e 08 & 5.573\e 08 & 4.955\e 08 & 5.87 \\
+ 6 & 5.65 & 0.274 & 3.528 & 0 & 0 \\
+% 7 & 0.0837 & 0.05153 & 0.08042 & 0.04883 & 2.6\e 3 \\
+ 8 & 3.749\e 10 & 1.071\e 12 & 8.948\e 09 & 6.365\e 13 & 52.6 \\
+ 9 & 1.864 & 0 & 1.179 & 0 & 1.2\e 2 \\
+10 & 0.7146 & 0 & 0.702 & 0 & 2.1\e 3 \\
+11 & 1.209\e 16 & 1.582\e 16 & 1.289\e 16 & 8.713\e 17 & 2.2\e 2 \\
+12 & 2.336\e 18 & 0.02052 & 0.01466 & 7.423\e 19 & 3.6\e 6 \\
+13 & 0.03427 & 0.006867 & 0.006903 & 0.001508 & 7.3\e 5 \\
+14 & 5.638\e 12 & 8.894\e 11 & 1.029\e 12 & 4.35\e 12 & 0.56 \\
+15 & 0.0001813 & 0.0003546 & 0.000251 & 0.0002509 & 3.2\e 4 \\
+16 & 1.315\e 14 & 9.751\e 15 & 1.233\e 14 & 1.054\e 14 & 4.9\e 7 \\
+17 & 5.422\e 15 & 5.51\e 15 & 4.925\e 15 & 1.392\e 14 & 1.5\e 7 \\
+18 & 1.509\e 13 & 3.477\e 14 & 6.18\e 14 & 2.907\e 14 & 0.11 \\
+19 & 7.349\e 15 & 1.521\e 15 & 1.344\e 14 & 7.255\e 15 & 1.4\e 5 \\
+20 & 0.05884 & 0.0583 & 0.05765 & 0.05504 & 5.9\e 2 \\
+21 & 1.212 & 1.776 & 1.005 & 0.7145 & 1.59 \\
+22 & 1.937 & 1.269 & 1.052 & 0.7459 & 2.12 \\
+23 & 1.479 & 1.636 & 1.066 & 1.29 & 3.14
+ \end{tabular}
+ \begin{flushleft}
+ Note: $^a$Standard deviation of the minimum function values (over 50
+ replications) obtained using \code{genoud}. $^b$Standard deviation of the
+ best function values (over 50 replications) reported for the ''fast''
+ evolutionary programming algorithm, from \citet[85 and 88, Tables
+ II--IV]{yao.liu.lin1999}.
+ \end{flushleft}
+ \vspace*{.1in}
+ \caption{Standard Deviations of Values of 22 Optimized Functions}
+ \label{tab:23sdev}
+\begin{center}
+ \line(1,0){450}
+\end{center}
+\end{table}
+
+\subsection{A Logistic Least Quartile Difference Estimator:}
+Our third example is a version of the LQD estimator used in
+\code{multinomRob}. Using the \proglang{R} function \code{IQR} to compute the
+interquartile range, the function to be minimized may be defined as
+follows.\footnote{The LQD problem solved in \code{multinomRob} is somewhat
+ different. There the problem is to minimize the $\binom{h_{K}}{2}$ order
+ statistic of the set of absolute differences among the standardized
+ residuals, where $h_K$ is a function of the sample size and the number of
+ unknown regression model coefficients \citep{MebaneSekhon2004}. The problem
+ considered in the current example is simpler but exhibits similar estimation
+ difficulties.}
+<<eval=false>>=
+LQDxmpl <- function(b) {
+ logistic <- function(x) { 1/(1+exp(-x)) }
+ sIQR <- function(y, yhat, n) {
+ IQR((y-yhat)/sqrt(yhat*(n-yhat)), na.rm=TRUE)
+ }
+ sIQR(y, m*logistic(x %*% b), m)
+}
+@
+For this example we define \code{LQDxmpl} after we compute the simulated data,
+so the data vector \code{y}, matrix \code{x} and scalar \code{m} are in scope
+to evaluate to have the values we simulate:
+<<eval=false>>=
+m <- 100
+x <- cbind(1,rnorm(1000),rnorm(1000))
+b1 <- c(.5, 1, -1)
+b2 <- c(0, -1, 1)
+logistic <- function(x) { 1/(1+exp(-x)) }
+y <- rbinom(1000, m, logistic(c(x[1:900,] %*% b1, x[901:1000,] %*% b2)))
+@
+The data simulate substantial contamination. The first 900 observations are
+generated by one binomial regression model while the last 100 observations
+come from a very different model.
+
+Presuming we are interested in the model that generated the bulk of the data,
+ignoring the contamination in a generalized linear model with the binomial
+family produces very poor results:
+<<eval=false>>=
+summary(glm1 <- glm(cbind(y,m-y) ~ x[,2] + x[,3], family="binomial"))
+@
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Call:
+glm(formula = cbind(y, m - y) ~ x[, 2] + x[, 3], family = "binomial")
+
+Deviance Residuals:
+ Min 1Q Median 3Q Max
+-22.9168 -1.1693 0.3975 1.5895 24.6439
+
+Coefficients:
+ Estimate Std. Error z value Pr(>|z|)
+(Intercept) 0.439492 0.007097 61.93 <2e-16 ***
+x[, 2] 0.679847 0.007985 85.14 <2e-16 ***
+x[, 3] -0.716963 0.007852 -91.31 <2e-16 ***
+---
+Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+ \end{CodeOutput}
+\end{CodeChunk}
+Of course, if we knew which observations to omit the results would be much
+better:
+<<eval=false>>=
+suby <- y[1:900]
+subx <- x[1:900,]
+summary(glm2 <- glm(cbind(suby,m-suby) ~ subx[,2] + subx[,3], family="binomial"))
+@
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Call:
+glm(formula = cbind(suby, m - suby) ~ subx[, 2] + subx[, 3],
+ family = "binomial")
+
+Deviance Residuals:
+ Min 1Q Median 3Q Max
+-3.21478 -0.71699 0.03528 0.67867 2.88314
+
+Coefficients:
+ Estimate Std. Error z value Pr(>|z|)
+(Intercept) 0.501880 0.008036 62.46 <2e-16 ***
+subx[, 2] 1.003592 0.009779 102.63 <2e-16 ***
+subx[, 3] -0.984295 0.009437 -104.30 <2e-16 ***
+---
+Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
+ \end{CodeOutput}
+\end{CodeChunk}
+But in practical applications it is unknown apriori which observations should
+be treated as outliers.
+
+As the definition of \code{LQDxmpl} indicates, the LQD is based on
+minimizing the interquartile range (IQR) of the standardized
+residuals. Because the quartiles correspond to different data points
+for different values of the regression coefficients, the fitness
+function is not smooth, which is to say it is not everywhere
+differentiable. In general, at every point in the parameter space
+where the identity of the first or third quartile point changes, the
+function is not differentiable. Figure~\ref{fig:lqd1} illustrates
+this. A higher resolution version of this figure is available in
+\cite{MebaneJr.+Sekhon:2011}---also see
+\url{http://sekhon.berkeley.edu/papers/rgenoudJSS.pdf}.
+
+The IQR clearly has a minimum in the vicinity of the coefficient
+values used to generate most of the data. But contour plots for the
+numerically evaluated partial derivative with respect to the second
+coefficient parameter testify to the function's local irregularity.
+The function we use to evaluate this numerical derivative is defined
+as follows.
+<<eval=false>>=
+dLQDxmpl <- function(b) {
+ eps <- 1e-10
+ logistic <- function(x) { 1/(1+exp(-x)) }
+ sIQR <- function(y, yhat, n) {
+ IQR((y-yhat)/sqrt(yhat*(n-yhat)), na.rm=TRUE)
+ }
+ dsIQR <- vector()
+ for (i in 1:length(b)) {
+ beps <- b
+ beps[i] <- b[i]+eps
+ dsIQR <-
+ c(dsIQR,
+ (sIQR(y, m*logistic(x %*% beps), m)-
+ sIQR(y, m*logistic(x %*% b), m))/eps)
+ }
+ return(dsIQR)
+}
+@
+Setting the intercept equal to 0.5, the code to generate the plotted values is
+% -rw-rw---- 1 wrm1 research 1878 Feb 10 2007 lqdxmpl2plotB.R
+<<eval=false>>=
+blen <- 3
+lenbseq <- length(bseq <- seq(-2,2,length=200))
+bseq3 <- seq(-1.2,-.9,length=200)
+bseq2 <- seq(.89,1.1,length=200)
+IQRarr <- IQRarrA <- array(NA, dim=c((1+blen), lenbseq, lenbseq))
+dimnames(IQRarrA) <- list(NULL, as.character(bseq), as.character(bseq))
+dimnames(IQRarr) <- list(NULL, as.character(bseq2), as.character(bseq3))
+for (i in 1:lenbseq) {
+ for (j in 1:lenbseq) {
+ IQRarrA[1,i,j] <- LQDxmpl(c(.5, bseq[i], bseq[j]))
+ IQRarrA[-1,i,j] <- dLQDxmpl(c(.5, bseq[i], bseq[j]))
+ IQRarr[1,i,j] <- LQDxmpl(c(.5, bseq2[i], bseq3[j]))
+ IQRarr[-1,i,j] <- dLQDxmpl(c(.5, bseq2[i], bseq3[j]))
+ }
+}
+@
+The following code produces the plots:
+<<eval=false>>=
+par(mfrow=c(2,2), lwd=.1)
+contour(bseq,bseq, IQRarrA[1,,], main="IQR", xlab="b[2]", ylab="b[3]")
+contour(bseq,bseq, IQRarrA[3,,], main="partial derivative w/r/t b[2]",
+ xlab="b[2]", ylab="b[3]")
+loc2 <- (150:160)-5
+loc3 <- (40:50)+5
+contour(bseq[loc2],bseq[loc3], IQRarrA[3,loc2,loc3],
+ main="partial derivative w/r/t b[2]",
+ xlab="b[2]", ylab="b[3]")
+contour(bseq2,bseq3, IQRarr[3,,], main="partial derivative w/r/t b[2]",
+ xlab="b[2]", ylab="b[3]")
+@
+If the IQR function were smooth, we would see clearly separated, slightly
+curved contour lines, reflecting the nonlinearity of the \code{logistic}
+function, but there is nothing like that. Instead, looking over the domain
+$[-2,2]^2$ for the second and third regression coefficient parameters, with
+200 points evaluated along each axis (the upper right plot), there is a
+splotchy cloud. This reflects the fact that the derivative changes sign very
+frequently over the domain: of the 40,000 points at which the derivative is
+evaluated, it is positive at 12,460 points and negative at 27,540 points.
+\begin{figure}[t]
+ \caption{Contour Plots of the LQD Fitness Function and of its Partial Derivatives}
+ \label{fig:lqd1}
+ \begin{center}
+ \includegraphics{lqdxmpl2B.pdf}
+% -rw-rw---- 1 wrm1 research 2745 Feb 10 23:15 lqdxmpl2plotB.Rout
+ \end{center}
+ \vspace{-.3in}
+\end{figure}
+
+The LQD fitness function is not appreciably smoother close to the true
+values. The bottom two plots show the partial derivatives with
+respect to the second coefficient parameter evaluated over the domain
+$[.89,1.1]\times[-1.2,-.9]$. The bottom left plot evaluates the
+derivatives at 11 points along each axis while the bottom right plot
+uses 200 points along each axis. In the left plot it is easier to see
+the intricacy of the partitioning of the parameter space as the
+identity of the first or third quartile point changes. The bottom
+right plot shows the intricacy in fact replicates at the finer grain
+of the more detailed evaluations (to see this it is probably necessary
+to magnify the plot while viewing online the \textit{Journal of
+ Statistical Software} version of this
+documentation).\footnote{Please see \cite{MebaneJr.+Sekhon:2011} or
+ \url{http://sekhon.berkeley.edu/papers/rgenoudJSS.pdf}.} Within
+this smaller domain the sign of the derivative changes even more
+frequently than it does over the domain $[-2,2]^2$: the derivative is
+positive at 18,098 points and negative at 21,902 points.
+
+While the LQD fitness function may be differentiable in a neighborhood of the
+global solution, that neighborhood, if it exists, is clearly not very big. As
+likely is that the global solution is located at a point where the function is
+not differentiable. Hence a numerically evaluated gradient is not meaningful
+for evaluating whether the solution has been found. At the true solution,
+numerical gradient values may differ substantially from zero.
+
+To use the LQD to estimate the binomial regression model parameters we use the
+following call to \code{genoud}. Because gradient information is of
+questionable relevance for this problem, we turn off the termination condition
+that the gradient at the solution be smaller than the value specified for the
+\code{solution.tolerance} argument. We retain the default setting
+\code{BFGS=TRUE} because, in principle, gradient-driven optimization may help
+in each of the many differentiable neighborhoods, even if it is useless across
+the nondifferentiable boundaries. Our experience optimizing the LQD
+\citep{MebaneSekhon2004} shows that using the BFGS in this way improves
+performance, even though the gradient is not useful for evaluating whether the
+solution has been found.
+<<eval=false>>=
+LQD1 <-
+ genoud(LQDxmpl, nvars=3, max=FALSE, pop.size=2000, max.generations=300,
+ wait.generations=100, gradient.check=FALSE, print=1)
+@
+This invocation of the \code{LQDxmpl} function matches the behavior of
+\code{multinomRob} in that it produces an estimate for the intercept parameter
+along with the other coefficients. In a linear regression context, the
+interquartile range statistic contains no information about the intercept, so
+the LQD is not an estimator for that parameter. With a binomial regression
+model there is some information about the intercept due to the nonlinearity of
+the \code{logistic} function. The LQD estimate for the intercept should
+nonetheless be expected not to be very good.
+
+Results from the preceding estimation are as follows.
+% macht:/home/xchg/jss07/rgenoud:
+% -rw-rw---- 1 wrm1 research 5080 Aug 7 02:31 lqdxmpl1b.Rout
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Tue Aug 7 02:27:08 2007
+Domains:
+ -1.000000e+01 <= X1 <= 1.000000e+01
+ -1.000000e+01 <= X2 <= 1.000000e+01
+ -1.000000e+01 <= X3 <= 1.000000e+01
+
+[...]
+
+HARD Maximum Number of Generations: 300
+Maximum Nonchanging Generations: 100
+Population size : 2000
+Convergence Tolerance: 1.000000e-06
+
+Using the BFGS Derivative Based Optimizer on the Best Individual Each Generation.
+Not Checking Gradients before Stopping.
+Using Out of Bounds Individuals.
+
+Minimization Problem.
+
+
+Generation# Solution Value
+
+ 0 4.951849e-01
+ 56 1.298922e-01
+ 57 1.298891e-01
+ 59 1.298848e-01
+ 60 1.298820e-01
+ 61 1.298793e-01
+ 62 1.298768e-01
+ 63 1.298744e-01
+
+'wait.generations' limit reached.
+No significant improvement in 100 generations.
+
+Solution Fitness Value: 1.298743e-01
+
+Parameters at the Solution (parameter, gradient):
+
+ X[ 1] : 8.130357e-02 G[ 1] : 9.616492e-03
+ X[ 2] : 8.889485e-01 G[ 2] : -1.167897e-01
+ X[ 3] : -9.327966e-01 G[ 3] : -3.090130e-02
+
+Solution Found Generation 63
+Number of Generations Run 164
+
+Tue Aug 7 02:31:09 2007
+Total run time : 0 hours 4 minutes and 1 seconds
+ \end{CodeOutput}
+\end{CodeChunk}
+Recall that the gradient is not reliably informative at the solution. To
+check whether this solution is believable, we might try reestimating the model
+using a larger population and larger specified number of generations:
+<<eval=false>>=
+LQD1 <-
+ genoud(LQDxmpl, nvars=3, max=FALSE, pop.size=10000, max.generations=1000,
+ wait.generations=300, gradient.check=FALSE, print=1)
+@
+At the price of a greatly increased running time (from four minutes up to
+one hour 53 minutes), the results are better than the
+first run (even though the summary measure of fit is slightly worse):
+% macht:/home/xchg/jss07/rgenoud:
+% -rw-rw---- 1 wrm1 research 5236 Aug 7 05:16 lqdxmpl1d.Rout
+\begin{CodeChunk}
+ \begin{CodeOutput}
+Minimization Problem.
+
+
+Generation# Solution Value
+
+ 0 2.238865e-01
+ 2 1.301149e-01
+ 3 1.300544e-01
+ 4 1.300482e-01
+ 6 1.300375e-01
+ 7 1.300343e-01
+ 8 1.300323e-01
+ 134 1.299662e-01
+ 135 1.299099e-01
+ 136 1.298867e-01
+ 137 1.298843e-01
+ 138 1.298822e-01
+ 139 1.298791e-01
+ 141 1.298774e-01
+
+'wait.generations' limit reached.
+No significant improvement in 300 generations.
+
+Solution Fitness Value: 1.298770e-01
+
+Parameters at the Solution (parameter, gradient):
+
+ X[ 1] : 2.013748e-01 G[ 1] : -7.394125e-02
+ X[ 2] : 9.526390e-01 G[ 2] : 7.807607e-02
+ X[ 3] : -9.642458e-01 G[ 3] : 3.834052e-02
+
+Solution Found Generation 141
+Number of Generations Run 442
+
+Tue Aug 7 05:16:37 2007
+Total run time : 1 hours 53 minutes and 45 seconds
+ \end{CodeOutput}
+\end{CodeChunk}
+%$
+
+This example demonstrates a key difficulty that arises when optimizing
+irregular functions in the absence of gradients. It is difficult to assess
+when or whether an optimum has been found. The estimated coefficient values
+are close to the ones used to generate most of the data, except as expected
+the estimate for the intercept is not good. The estimates are better than if
+we had ignored the possibility of contamination. But whether these are the
+best possible estimates is not clear. If we were to use an even larger
+population and specify that an even greater number of generations be run,
+perhaps a better solution would be found.
+
+%http://sekhon.berkeley.edu/rgenoud/R/genoud_cluster_manual.R
+%http://sekhon.berkeley.edu/rgenoud/R/genoud_cluster_manual_tunnel.R
+
+%\code{genoud} can be tricked into doing constrained optimization by
+%passing in a function which contains a penalty function.
+
+Even for less irregular problems convergence is difficult to determine.
+Nonlinear optimizers often report false convergence, and users should not
+simply trust whatever convergence criteria an optimizer uses.
+\citet{McCulloughVinod2003} offer four criteria for verifying the solution of
+a nonlinear solver. These criteria are meaningful only for problems that meet
+regularity conditions at the solution, notably differentiability, and as such
+are not useful for the LQD example offered above. The four criteria are: (1)
+making sure the gradients are zero; (2) inspecting the solution path (i.e.,
+the trace) to make sure it follows the expected rate of convergence; (3)
+evaluating the Hessian to make sure it is well-conditioned;\footnote{Following
+ an exchange with \citet{DrukkerWiggins2004}, \citet{McCulloughVinod2004b}
+ modify their third suggestion to note that determining if the Hessian is
+ well-conditioned in part depends on how the data are scaled. That is, a
+ Hessian that appears to be ill-conditioned may be made well-conditioned by
+ rescaling. So if an Hessian appears to be ill-conditioned,
+ \citet{McCulloughVinod2004b} recommend that the analyst attempt to determine
+ if rescaling the data can result in a well-conditioned Hessian.} and (4)
+profiling the likelihood to ascertain if a quadratic approximation is
+adequate. One may need to take the results from \code{genoud} and pass them
+to \code{optim} to conduct some of these diagnostic tests such as to profile
+the likelihood. It is also good practice to use more than one optimizer to
+verify the solution \citep{stokes2004}.
+
+Note that \code{genoud} uses its own random number seeds and internal
+pseudorandom number generators to insure backward compatibility with
+the original C version of the software and to make cluster behavior
+more predictable. These seeds are set by the \code{unif.seed} and
+\code{int.seed} options. The \proglang{R} \code{set.seed} command is
+ignored by \code{genoud}.
+
+%user supplied gradients and lexical search?
+
+\section{Conclusion}
+\label{sec:conclusion}
+
+The \code{genoud} function provides many more options than can be reviewed in
+this brief paper. These options are described in the \proglang{R} help file.
+The most important option
+influencing how well the evolutionary algorithm works is the \code{pop.size}
+argument. This argument controls the population size---i.e., it is the number
+of individuals \code{genoud} uses to solve the optimization problem. As noted
+above, the theorems proving that genetic algorithms find good solutions are
+asymptotic in both population size and the number of generations. It is
+therefore important that the \code{pop.size} value not be small. On the other
+hand, computational time is finite so obvious trade-offs must be made. As the
+LQD example illustrates, a larger population size is not necessarily
+demonstrably better.
+The most important options to ensure that a good solution is found, aside from
+\code{pop.size}, are \code{wait.generations}, \code{max.generations} and
+\code{hard.generation.limit}.
+
+Many statistical models have objective functions that are nonlinear
+functions of the parameters, and optimizing such functions is tricky
+business \citep{AltmanGillMcDonald2003}. Optimization difficulties
+often arise even for problems that are generally considered to be
+simple. For a cautionary tale on how optimization can be a difficult
+task even for such problems see Stokes' (\citeyear{stokes2004}) effort
+to replicate a probit model estimated by \citet[pp. 335]{maddala1992}.
+A recent controversy over estimating a nonlinear model estimated by
+maximum likelihood offers another cautionary tale
+\citep{DrukkerWiggins2004,McCulloughVinod2003,McCulloughVinod2004a,McCulloughVinod2004b,SchacharNalebuff2004}.
+End users are generally surprised to learn that such optimization
+issues can arise, and that results can substantially vary across
+optimizers and software implementations.
+
+The \pkg{rgenoud} package provides a powerful and flexible global
+optimizer. When compared with traditional derivative-based
+optimization methods, \pkg{rgenoud} performs well
+\citep{SekhonMebane1998}. Optimization of irregular functions is,
+however, as much of an art as science. And an optimizer cannot be
+used without thought even for simple surfaces, let alone spaces that
+require a genetic algorithm. We hope that the availability of a
+scalable global optimizer will allow users to work with difficult
+functions more effectively.
+
+
+
+
+\bibliography{rgenoud}
+\end{document}
+
+% LocalWords: optima GillMurrayWright EfronTibshirani GENOUD MebaneSekhon LQD
+% LocalWords: SekhonMebane multinomRob overdispersed nondifferentiable Broyden
+% LocalWords: Goldfarb Shanno BFGS optim genoud EA EAs GA holland goldberg GAs
+% LocalWords: GrefenstetteBaker davis FilhoTreleavenAlippi generation's dejong
+% LocalWords: substring's grefenstette billingsley Vose NixVose vose GA's ADC
+% LocalWords: GENOCOP MichalewiczSwaminathanLogan Michalewicz Polytope dnorm
+% LocalWords: nvars Nonchanging UniqueCount var MemoryMatrix IQR LQDxmpl exp
+% LocalWords: sIQR yhat na rm cbind rnorm rbinom Min Std Pr Signif suby subx
+% LocalWords: apriori Raphson saddlepoints fn Genoud's gr hessian unif int ssh
+% LocalWords: Tausworthe stdout tempdir polytope musil deckard makeSOCKcluster
+% LocalWords: usernames username PVM MPI peakgeneration parm UC Outlier seq mu
+% LocalWords: lapply xlab ylab col biclaw mNd ALTMAN rgenoud WandKingLau PKfit
+% LocalWords: KingWand braumoeller BraumoellerGoodrichKline pharmacokinetics
+% LocalWords: LeeLee pseudorandom pdf glm rw wrm lqdxmpl cl makeCluster probit
+% LocalWords: localhost clusterExport stopCluster AltmanGillMcDonald GENetic
+% LocalWords: McCulloughVinod SchacharNalebuff GenMatch GUI URL boolean Sekhon
+% LocalWords: CPUs nonlinearity FAiR goodrich SekhonMatching ivivc vitro vivo
+% LocalWords: multinomial Synth AbadieGardeazabal synth nonsmooth Rcore maxima
+% LocalWords: resampling resamples optimizer's eval nonstochastic testbounds
+% LocalWords: LLLL func ij unimodal Rosenbrock multimodal minima saddlepoint
+% LocalWords: testfuncs testNparms gradcheck sizeset genset nreps gsarray tol
+% LocalWords: gsize ngens FEP LLLLLL sqrt dLQDxmpl eps dsIQR beps blen lenbseq
+% LocalWords: bseq IQRarr IQRarrA dimnames mfrow lwd loc online DrukkerWiggins
+% LocalWords: maddala funcs sapply runif ifelse rbind crossprod byrow vXXi
+% LocalWords: interquartile
diff --git a/vignettes/rgenoud.bib b/vignettes/rgenoud.bib
new file mode 100644
index 0000000..f72a55d
--- /dev/null
+++ b/vignettes/rgenoud.bib
@@ -0,0 +1,1903 @@
+ at string{aer = "American Economic Review"}
+ at string{ajps= "American Journal of Political Science"}
+ at string(apq = "American Politics Quarterly")
+ at string{apsr= "American Political Science Review"}
+ at string{ams = "Annals of Mathematical Statistics"}
+ at string{aos = "Annals of Statistics"}
+ at string{bjps= "British Journal of Political Science"}
+ at string{ec = "Econometrica"}
+ at string{ier = "International Economic Review"}
+ at string{jasa= "Journal of the American Statistical Association"}
+ at string{je = "Journal of Econometrics"}
+ at string{jel = "Journal of Economic Literature"}
+ at string{jep = "Journal of Economic Perspectives"}
+ at string{jet = "Journal of Economic Theory"}
+ at string{jmcb= "Journal of Money, Credit, and Banking"}
+ at string{jme = "Journal of Monetary Economics"}
+ at string{jpe = "Journal of Political Economy"}
+ at string{jop = "Journal of Politics"}
+ at string{jrsa= "Journal of the Royal Statistical Society, Series A"}
+ at string{jrssb= "Journal of the Royal Statistical Society, Series B"}
+ at string{lsq = "Legislative Studies Quarterly"}
+ at string{pa = "Political Analysis"}
+ at string{pm = "Political Methodology"}
+ at string{pop = "Perspectives on Politics"}
+ at string{ps = "PS: Political Science and Politics"}
+ at string{qje = "Quarterly Journal of Economics"}
+
+ at string{c-h = "Chapman \& Hall"}
+ at string{cup = "Cambridge University Press"}
+ at string{cornell.up = "Cornell University Press"}
+ at string{hup = "Harvard University Press"}
+ at string{mit = "MIT Press"}
+ at string(pup = {Princeton University Press})
+ at string{s-v = "Springer-Verlag"}
+ at string(sup = "Stanford University Press")
+ at string{ucp = "University of California Press"}
+ at string{uchp = "University of Chicago Press"}
+ at string{ump = "University of Michigan Press"}
+ at string{yup = "Yale University Press"}
+ at string{cq = "Congressional Quarterly"}
+
+ at string{aa = "Ann Arbor"}
+ at string{berk= "Berkeley"}
+ at string{bos = "Boston"}
+ at string{cam = "Cambridge, MA"}
+ at string{camUK = "Cambridge, UK"}
+ at string{chic= "Chicago"}
+ at string{dc = "Washington, D.C."}
+ at string{nh = "New Haven"}
+ at string{nj = "New Jersey"}
+ at string{ny = "New York"}
+ at string{sf = "San Francisco"}
+ at string{st = "Stanford"}
+
+ at article( abadie2002,
+ author= {Abadie, Alberto},
+ title= {Bootstrap Tests for Distributional Treatment Effect in Instrumental Variable Models},
+ journal= jasa, volume=97, number=457,
+ pages= {284--292},
+ year= 2002
+)
+
+ at article( AbadieGardeazabal2003,
+ author= {Abadie, Alberto and Javier Gardeazabal},
+ title= {The Economic Costs of Conflict: a Case-Control Study for the Basque Country},
+ journal= aer, volume=92, number=1,
+ year= 2003
+)
+
+ at article( AbadieImbens_largesample,
+ author= {Abadie, Alberto and Guido Imbens},
+ title= {Large Sample Properties of Matching Estimators for Average Treatment Effects},
+ journal= ec,
+ year= "forthcoming"
+)
+
+ at Article{Abadie+Diamond+Hainmueller:2011,
+ author = {Alberto Abadie and Alexis Diamond and Jens Hainmueller},
+ title = {\pkg{Synth}: An \proglang{R} Package for Synthetic Control Methods in Comparative Case Studies},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at book( adams1805,
+ author= {Adams, John},
+ title= {Discourses on Davila: A Series of Papers on Political History},
+ publisher= {Da Capo Press}, address= {New York},
+ year= {1973 [1805]}
+)
+
+ at book( alesina1995,
+ author= {Alesina, Alberto and Howard Rosenthal},
+ title= {Partisan Politics, Divided Government, and the Economy},
+ publisher= cup, address= ny,
+ year= 1995
+)
+
+ at article( alesina1989,
+ author= {Alesina, Alberto and Howard Rosenthal},
+ title= {Partisan Cycles in {C}ongressional Elections and the Macroeconomy},
+ journal= apsr, volume=83,
+ pages= {373-398},
+ year= 1989
+)
+
+ at article( AlesinaLondregan1993,
+ author= {Alesina, Alberto and John Londregan and Howard Rosenthal},
+ title= {A Model of the Political Economy of the United States},
+ journal= apsr, volume=87,
+ number= 1,
+ pages= {12--33},
+ year= 1993
+)
+
+ at book( AltmanGillMcDonald2003,
+ author= {Altman, Micah and Jeff Gill and Michael McDonald},
+ title= {Numerical Issues in Statistical Computing for the Social Scientist},
+ publisher= {John Wiley and Sons}, address= {New York},
+ year= 2003
+)
+
+ at book( alvarez1997,
+ author= {Alvarez, R. Michael},
+ title= {Information and Elections},
+ publisher= {University of Michigan Press}, address= {Ann-Arbor},
+ year= 1997
+)
+
+ at book( AlvarezBrehm2002,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {Hard Choices, Easy Answers: Values, Information, and American Public Opinion},
+ publisher= pup, address= nj,
+ year= 2002
+)
+
+
+ at article( AlvarezBrehm1998,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {Speaking in Two Voices: American Equivocation about the Internal Revenue Service},
+ journal= ajps, volume=42,
+ number= 2,
+ pages= {418--452},
+ year= 1998
+)
+
+ at article( AlvarezBrehm1997,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {Are Americans Ambivalent Toward Racial Policies?},
+ journal= ajps, volume=41,
+ pages= {345--374},
+ year= 1997
+)
+
+ at article( AlvarezBrehm1995,
+ author= {Alvarez, R. Michael and John Brehm},
+ title= {American Ambivalence Toward Abortion Policy: A Heteroskedastic Probit Method for Assessing Conflicting Values},
+ journal= ajps, volume=39,
+ pages= {1055--1082},
+ year= 1995
+)
+
+ at book( althaus2003,
+ author= {Althaus, Scott L.},
+ title= {Collective Preferences in Democratic Politics: Opinion Surveys and the Will of the People},
+ publisher= cup, address= ny,
+ year= 2003
+)
+
+ at article( althaus1998,
+ author= {Althaus, Scott L.},
+ title= {Information Effects in Collective Preferences},
+ journal= apsr, volume=92,
+ number= 3,
+ pages= {545--558},
+ year= 1998
+)
+
+ at article( AldrichMcKelvey1977,
+ author= {Aldrich, John H. and Richard D. McKelvey},
+ title= {A Method of Scaling with Applications to the 1968 and 1972 Presidential Elections},
+ journal= apsr, volume=71, number=1,
+ pages= {111--130},
+ year= 1977
+)
+
+ at book( amemiya1985,
+ author= {Amemiya, Takeshi},
+ title= {Advanced Econometrics},
+ publisher= hup, address={Cambridge, MA},
+ year= {1985}
+)
+
+ at article( atkinson86,
+ author= {Atkinson, A. C.},
+ title= {Masking Unmasked},
+ journal= {Biometrika}, volume=73,
+ pages= {533--541},
+ year= 1986,
+ month= {Dec.}
+)
+
+ at article( austen-smith1996,
+ author= {Austen-Smith, David and Jeffrey S. Banks},
+ title= {Information Aggregation, Rationality, and the Condorcet Jury Theorem},
+ journal= apsr, volume=90,
+ pages= {34--45},
+ year= 1996
+)
+
+ at unpublished( bartels2003,
+ author= {Bartels, Larry M.},
+ title= {Homer Gets a Tax Cut: Inequality and Public Policy in the American Mind},
+ note= {Annual Meeting of the American Political Science Association, Philadelphia, August},
+ year= 2003
+)
+
+ at article( bartels1999,
+ author= {Bartels, Larry M.},
+ title= {Panel Effects in the National Election Studies},
+ journal= pa, volume=8,
+ number= 1,
+ year= 1999
+)
+
+ at article( bartels1996b,
+ author= {Bartels, Larry M.},
+ title= {Uninformed Votes: Information Effects in Presidential Elections},
+ journal= ajps, volume=40,
+ number= 1,
+ pages= {194--230},
+ year= 1996
+)
+
+ at article( bartels1986,
+ author= {Bartels, Larry M.},
+ title= "Issue Voting Under Uncertainty: An Empirical Test",
+ journal= ajps, volume=30,
+ number= 4,
+ pages= {709--728},
+ year= 1986
+)
+
+ at unpublished( battistin2004,
+ author= {Battistin, Erich and Andrew Chesher},
+ title= {Measurement Error Bias and Propensity Score Methods},
+ year= 2004,
+ note= "Working Paper"
+)
+
+ at article( bennett1988,
+ author= {Bennett, Stephen Earl},
+ title= {Know-nothings' Revisited: The Meaning of Political Ignorance Today},
+ journal= {Social Science Quarterly}, volume=69,
+ pages= {476--490},
+ year= 1988
+)
+
+ at article( berg1993,
+ author= {Berg, Sven},
+ title= {Condorcet's Jury Theorem, Dependency Among Jurors},
+ journal= {Social Choice and Welfare}, volume=10,
+ pages= {87--95},
+ year= 1993
+)
+
+ at book( berelson1954,
+ author= {Berelson, Bernard R. and Paul F. Lazarsfeld and William N. McPhee},
+ title= {Voting: A Study of Opinion Formation in a Presidential Campaign},
+ publisher= uchp, address= chic,
+ year= 1954
+)
+
+ at article( BertsimasTsitsiklis1993,
+ author= {Bertsimas, Dimitris and John Tsitsiklis},
+ title= {Simulated Annealing},
+ journal= "Statistical Science", volume=8, number=1,
+ pages= {10--15},
+ year= 1993
+)
+
+ at book( billingsley1986,
+ author= {Billingsley, Patrick},
+ title= {Probability and Measure},
+ publisher= "Wiley", address= "New York",
+ year= 1986
+)
+
+ at book( bollen1989,
+ author= {Bollen, Kenneth A.},
+ title= {Structural Equations with Latent Variables},
+ publisher= "Wiley", address={New York},
+ year= {1989}
+)
+
+ at unpublished( BowersHansen2005,
+ author= {Bowers, Jake and Ben Hansen},
+ title= {Attributing Effects to a Get-Out-The-Vote Campaign Using Full Matching and Randomization Inference},
+ note= "Working Paper",
+ year= 2005
+)
+
+ at article(braumoeller2003,
+ author= {Braumoeller, Bear F.},
+ title= {Causal Complexity and the Study of Politics},
+ journal= pa, volume=11, number=3,
+ pages= {209-233},
+ year= 2003
+)
+
+ at Manual{BraumoellerGoodrichKline2006,
+ author = {Braumoeller, Bear F. and Ben Goodrich and Jacob Kline},
+ title = {\pkg{Boolean}: Boolean Binary Response Models},
+ note = {\proglang{R}~package version~2.0-2},
+ url = {http://polisci.osu.edu/faculty/braumoeller/custom/Booleanbatch.html},
+ year = {2010},
+}
+
+ at article( BrunellNiNardo2004,
+ author= {Brunell, Thomas L. and John DiNardo},
+ title= {A Propensity Score Reweighting Approach to Estimating the Partisan Effects of Full Turnout in American Presidential Elections},
+ journal= pa, volume=12, number=1,
+ pages= {28--45},
+ year= 2004
+)
+
+ at book( bryce1888,
+ author= {Bryce, James},
+ title= {The American Commonwealth},
+ publisher= {Liberty Fund}, address= {Indianapolis},
+ year= "1995 [1888]"
+)
+
+ at article( bunce2000,
+ author= {Bunce, Valerie},
+ title= {Comparative Democratization: Big and Bounded Generalizations},
+ journal= {Comparative Political Studies}, volume=33, number={6/7},
+ pages= {703--724},
+ year= 2000
+)
+
+ at incollection( camp2004,
+ author= {Camp, Ai Roderic},
+ title= {Citizen Attitudes toward Democracy and Vicente Fox's Victory in 2000},
+ booktitle= {Mexico's Pivotal Democratic Election},
+ editor= {Jorge I. Dom\'{i}nguez and Chappell Lawson},
+ publisher= sup, address= "Stanford",
+ pages= {25--46},
+ year= 2004
+)
+
+ at book( campbell1960,
+ author= {Campbell, Angus and Philip E. Converse and Warren E. Miller and Donald E. Stokes},
+ title= {The {A}merican Voter},
+ publisher= {John Wiley \& Sons}, address= ny,
+ year= 1960
+)
+
+ at article( CantoniRonchetti2001,
+ author= {Cantoni, Eva and Elvezio Ronchetti},
+ title= {Robust Inference for Generalized Linear Models},
+ journal= jasa, volume=96,
+ pages= {1022--1030},
+ year= 2001
+)
+
+ at article( CarrollPederson1993,
+ author= {Carroll, R. J. and Pederson, Shane},
+ title= {On Robustness in the Logistic Regression Model},
+ journal= jrssb, volume=84,
+ number= 3,
+ pages= {693--706},
+ year= 1993
+)
+
+ at article{ cerny1985,
+ author = "Cerny, V.",
+ title = "Thermodynamical Approach to the Traveling Salesman Problem: An Efficient Simulation Algorithm",
+ journal = "Journal of Optimization Theory and Applications", number = "1",
+ volume = "45",
+ pages = "41--51",
+ year = "1985"
+}
+
+ at article( ChristakisIwashyna2003,
+ author= {Christakis, Nicholas A. and Iwashyna, Theodore I.},
+ title= "The Health Impact of Health Care on Families: A matched cohort study of hospice use by decedents and mortality outcomes in surviving, widowed spouses.",
+ journal= "Social Science \& Medicine", volume=57, number=3,
+ pages= {465--475},
+ year= 2003
+)
+
+ at article( CochranRubin1973,
+ author= {Cochran, William G. and Donald B. Rubin},
+ title= "Controlling Bias in Observational Studies: A Review",
+ journal= {Sankhya, $\mathrm{Ser.\ A}$}, volume=35,
+ pages= {417--446},
+ year= 1973
+)
+
+ at book( collier_christopher1971,
+ author= {Collier, Christopher},
+ title= {Roger Sherman's Connecticut: Yankee Politics and the American Revolution},
+ publisher= "Wesleyan University Press", address= "Middletown, Conn.",
+ year= 1971
+)
+
+ at book( conover1971,
+ author= {Conover, William J.},
+ title= {Practical Nonparametric Statistics},
+ publisher= {John Wiley \& Sons}, address= {New York},
+ year= {1971}
+)
+
+ at incollection( converse1964,
+ author= {Converse, Phillip},
+ title= {The Nature of Belief Systems in Mass Publics},
+ booktitle= {Ideology and Discontent},
+ editor= {David Apter},
+ publisher= {Free Press}, address= ny,
+ pages= {240--268},
+ year= 1964
+)
+
+ at article( cornfield1959,
+ author= {Cornfield, J. and W. Haenszel and E. Hammond and A. Lilienfeld and M. Shimkin and E. Wynder},
+ title= {Smoking and lunch cancer: Recent evidence and a discussion of some questions},
+ journal= {Journal of the National Cancer Institute}, volume=22,
+ pages= {173--203},
+ year= 1959
+)
+
+ at article( copas1988,
+ author= {Copas, J. B.},
+ title= {Binary Regression Models for Contaminated Data},
+ journal= jrssb, volume=50,
+ number= 2,
+ pages= {225--265},
+ year= 1988
+)
+
+ at book( cox1958,
+ author= {Cox, David R.},
+ title= {Planning of Experiments},
+ publisher= "Wiley", address= ny,
+ year= 1958
+)
+
+ at book( davis1991,
+ editor= {Davis, Lawrence},
+ title= {Handbook of Genetic Algorithms},
+ publisher= {Van Nostrand Reinhold}, address= {New York},
+ year= {1991}
+)
+
+ at article( dawid1979,
+ author= {Dawid, A. Phillip},
+ title= {Conditional Independence in Statistical Theory},
+ journal= jrssb, volume=41,
+ pages= {1--31},
+ number= 1,
+ year= 1979
+)
+
+ at incollection( dejong1993,
+ author= {De Jong, Kenneth A.},
+ title= {Genetic Algorithms Are Not Function Optimizers},
+ booktitle= {Foundations of Genetic Algorithms 2},
+ editor= {L.~Darrell Whitley},
+ publisher= {Morgan Kaufmann}, address= {San Mateo, CA},
+ year= 1993
+)
+
+ at Article{Dehejia2005,
+ author = {Rajeev Dehejia},
+ title = {Practical Propensity Score Matching: A Reply to Smith and Todd},
+ journal = {Journal of Econometrics},
+ year = {2005},
+ volume = {125}, number="1--2",
+ pages = {355--364},
+}
+
+ at Article{DehejiaWahba2002,
+ author = {Rajeev H. Dehejia and Sadek Wahba},
+ title = {Propensity Score Matching Methods for Nonexperimental Causal Studies},
+ journal = {Review of Economics and Statistics},
+ year = {2002},
+ volume = {84},
+ number = {1},
+ pages = {151--161},
+ month = {February},
+}
+
+ at article( DehejiaWahba1999,
+ author= {Dehejia, Rajeev and Sadek Wahba},
+ title= {Causal Effects in Non-Experimental Studies: Re-Evaluating the Evaluation of Training Programs},
+ journal= jasa, volume=94,
+ number= 448,
+ pages= {1053--1062},
+ year= 1999
+)
+
+ at unpublished( DehejiaWahba1997,
+ author= {Dehejia, Rajeev and Sadek Wahba},
+ title= {Causal Effects in Non-Experimental Studies: Re-Evaluating the Evaluation of Training Programs},
+ note= {Rejeev Dehejia, \textit{Econometric Methods for Program Evaluation}. Ph.D. Dissertation, Harvard University, Chapter 1},
+ year= 1997
+)
+
+ at book( delli1996,
+ author= {Delli Carpini, X. Michael and Scott Keeter},
+ title= {What Americans Know about Politics and Why It Matters},
+ publisher= {Yale University Press}, address= {New Haven},
+ year= 1996
+)
+
+ at article( delli1993,
+ author= {Delli Carpini, X. Michael and Scott Keeter},
+ title= {Measuring Political Knowledge: Putting First Things First},
+ journal= ajps, volume=37,
+ number = 4,
+ pages= {1179-1206},
+ year= 1993
+)
+
+ at Manual{DiceOptim,
+ author = {Ginsbourger, D. and O. Roustant},
+ title = {\pkg{DiceOptim}: Kriging-based optimization for computer experiments},
+ note = {\proglang{R}~package version~1.0},
+ url = {http://cran.r-project.org/package=DiceOptim},
+ year = {2010},
+}
+
+ at article( DipreteEngelhardt2004,
+ author= {Diprete, Thomas A. and Henriette Engelhardt},
+ title= {Estimating Causal Effects With Matching Methods in the Presence and Absence of Bias Cancellation},
+ journal= "Sociological Methods \& Research", volume=32, number=4,
+ pages= "501--528",
+ year= "2004",
+)
+
+ at incollection( dominguez2004,
+ author= {Dom\'{i}nguez, I. Jorge},
+ title= {Why and How Did Mexico's 2000 Presidential Election Campaign Matter?},
+ booktitle= {Mexico's Pivotal Democratic Election},
+ editor= {Jorge I. Dom\'{i}nguez and Chappell Lawson},
+ publisher= sup, address= "Stanford",
+ pages= {321--344},
+ year= 2004
+)
+
+ at article( drake1993,
+ author= {Drake, Christiana},
+ title= {Effects of Misspecification of the Propensity Score on Estimators of Treatment Effect},
+ journal= {Biometrics}, volume=49,
+ number= 4,
+ pages= {1231--1236},
+ year= 1993
+)
+
+ at article( DrukkerWiggins2004,
+ author= {Drukker, David M. and Vince Wiggins},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Comment},
+ journal= aer, volume=94, number=1,
+ pages= {397--399},
+ year= 2004
+)
+
+ at book( EfronTibshirani1994,
+ author= {Efron, Bradely and Robert J. Tibshirani},
+ title= {An Introduction to the Bootstrap},
+ publisher= {Chapman \& Hall}, address= {New York},
+ year= {1994}
+)
+
+ at article( EpsteinHoKing2005,
+ author= {Epstein, Lee and Daniel E. Ho and Gary King and Jeffrey A. Segal},
+ title= {The Supreme Court During Crisis: How War Affects only Non-War Cases},
+ journal= "New York University Law Review", volume=80, number=1,
+ pages= "1--116",
+ year= "2005",
+)
+
+ at article( erikson1988,
+ author= {Erikson, Robert S.},
+ title= {The Puzzle of Midterm Loss},
+ journal= jop, volume=50,
+ number = 4,
+ pages= {1012--1029},
+ year= 1988
+)
+
+ at book( FahrmeirTutz1994,
+ author= {Fahrmeir, Ludwig and Gerhard Tutz},
+ title= {Multivariate Statistical Modeling Based on Generalized Linear Models},
+ publisher= "Springer-Verlag", address= "New York",
+ year= 1994
+)
+
+ at book( fechner1860,
+ author= {Fechner, Gustav Theodor},
+ title= {Elements of psychophysics, Vol 1.},
+ note = {Translated by Helmut E. Adler and edited by D.H. Howes and E.G. Boring},
+ publisher= {Rinehart \& Winston}, address= ny,
+ year= "1966 [1860]"
+)
+
+ at book( feller1970,
+ author= {Feller, William},
+ title= {An Introduction to Probability Theory and Its Applications},
+ publisher= "Wiley", address= "New York",
+ note= "Vol.\ 1, 3d ed., revised printing",
+ year= 1970
+)
+
+ at article( FilhoTreleavenAlippi1994,
+ author= {Filho, Jose L. Ribeiro, Philip C. Treleaven and Cesare Alippi},
+ title= {Genetic Algorithm Programming Environments},
+ journal= {Computer}, volume=27,
+ pages= {28--43},
+ year= 1994
+)
+
+ at book( fiorina1996,
+ author= {Fiorina, Morris P.},
+ title= {Divided Government},
+ publisher= {Allyn \& Bacon}, address= "Boston",
+ edition= "2nd",
+ year= 1992
+)
+
+ at book( fisher1935,
+ author= {Fisher, Ronald A.},
+ title= {Design of Experiments},
+ publisher= {Hafner}, address= {New York},
+ year= {1935}
+)
+
+ at book( fishkin1997,
+ author= {James S. Fishkin},
+ title= {The Voice of the People: Public Opinion and Democracy},
+ edition= {2nd},
+ publisher= {Yale University Press}, address= {New Haven, CT},
+ year= {1997}
+)
+
+ at article( franklin1991,
+ author= {Franklin, Charles H.},
+ title= {Eschewing Obfuscation? Campaigns and the Perception of U.S. Senate Incumbents},
+ journal= apsr, volume=85,
+ number = 4,
+ pages= {1193--1214},
+ year= 1991
+)
+
+ at book( gallant1987,
+ author= {Gallant, A. Ronald},
+ title= {Nonlinear Statistical Models},
+ publisher= "Wiley", address= ny,
+ year= 1987
+)
+
+ at article( GalianiGertlerSchargrodsky2005,
+ author= {Galiani, Sebastian and Paul Gertler and Ernesto Schargrodsky},
+ title= {Water for Life: The Impact of the Privatization of Water Services on Child Mortality},
+ journal= jpe, volume=113, number=1,
+ pages= {83--120},
+ year= 2005
+)
+
+ at article( geddes1999,
+ author= {Geddes, Barbara},
+ title= {What Do We Know about Democratization},
+ journal= "Annual Review of Political Science", volume=2,
+ pages= {129--148},
+ year= 1999
+)
+
+ at book( GillMurrayWright1981,
+ author= {Gill, Philip E. and Walter Murray and Margaret H. Wright},
+ title= {Practical Optimization},
+ publisher= "Academic Press", address= "San Diego",
+ year= 1981
+)
+
+ at incollection( GrefenstetteBaker1989,
+ author= {Grefenstette, John J. and James E. Baker},
+ title= {How Genetic Algorithms Work: A Critical Look at Implicit Parallelism},
+ booktitle= {Proceedings of the Third International Conference on Genetic Algorithms},
+ publisher= "Morgan Kaufmann", address= "San Mateo, CA",
+ pages= {20--27},
+ year= 1989
+)
+
+ at article( GeyerThompson1995,
+ author= {Geyer, Charles J. and Elizabeth A. Thompson},
+ title= {Annealing Markov Chain Monte Carlo with Applications to Ancestral Inference},
+ journal= jasa, volume=90, number=431,
+ pages= {909--920},
+ year= 1995
+)
+
+ at book( goldberg1989,
+ author= {Goldberg, David E.},
+ title= {Genetic Algorithms in Search, Optimization, and Machine Learning},
+ publisher= "Addison-Wesley", address= "Reading, MA",
+ year= 1989
+)
+
+ at Manual{goodrich.fair,
+ author = {Goodrich, Ben},
+ title = {\pkg{FAiR}: Factor Analysis in \proglang{R}},
+ note = {\proglang{R}~package version~0.4-7},
+ url = {http://cran.r-project.org/package=FAiR},
+ year = {2011},
+}
+
+ at incollection( grefenstette1993,
+ author= {Grefenstette, John J.},
+ title= {Deception Considered Harmful},
+ booktitle= {Foundations of Genetic Algorithms 2},
+ editor= {L.~Darrell Whitley},
+ publisher= {Morgan Kaufmann}, address= {San Mateo, CA},
+ year= 1993
+)
+
+ at book( habermas1964,
+ author= {Habermas, J\"{u}rgen},
+ title= {The Structural Transformation of the Public Sphere: An Inquiry into a Category of Bourgeois Society},
+ note = {Translated by Thomas Burger},
+ publisher= mit, address= cam,
+ year= "1996 [1964]"
+)
+
+ at book( hall1992,
+ author= {Hall, Peter},
+ title= {The Bootstrap and Edgeworth Expansion},
+ publisher= {Springer-Verlag}, address= {New York},
+ year= {1992}
+)
+
+ at book( hampel1986,
+ author= {Hampel, Frank R. and Elvezio M. Ronchetti and Peter J. Rousseeuw and Werner A. Stahel},
+ title= {Robust Statistics: The Approach Based on Influence Functions},
+ publisher= {Wiley, John and Sons}, address= {New York},
+ year= 1986
+)
+
+ at article( HausmanWise1979,
+ author= {Hausman, Jerry A. and David A. Wise},
+ title= {Attrition Bias in Experimental and Panel Data: The Gary Income Maintenance Experiment},
+ journal= ec, volume=47,
+ pages= {455--473},
+ year= 1979
+)
+
+ at article( hirnao1998,
+ author= {Hirano, Keisuke and Guido W. Imbens and Geert Ridder and Donald B. Rubin},
+ title= {Combining Panel Data Sets with Attrition and Refreshment Samples},
+ journal= ec, volume=69,
+ pages= {1645--1659},
+ year= 1998
+)
+
+ at article( heckman1979,
+ author= {Heckman, James J},
+ title= {Sample Selection Bias as a Specification Error},
+ journal= ec, volume=47,
+ pages= {153--161},
+ year= 1979
+)
+
+ at article( heckman1998,
+ author= {Heckman, James J. and Hidehiko Ichimura and Jeffrey Smith and Petra Todd},
+ title= {Characterizing Selection Bias Using Experimental Data},
+ journal= ec, volume=66,
+ number = 5,
+ pages= {1017-1098},
+ year= 1998
+)
+
+\item
+, ed. 1985.
+\textit{.}
+New York: Cambridge University Press.
+
+ at book( HeckmanSinger1985,
+ editor= {Heckman, James J. and Burton Singer},
+ title= {Longitudinal Analysis of Labor Market Data},
+ publisher= cup, address={New York},
+ year= {1985}
+)
+
+ at unpublished{HerronWand2004,
+ author = {Herron, Michael C. and Jonathan Wand},
+ title = {Assessing Partisan Bias in Voting Technology: The Case of the 2004 New Hampshire Recount},
+ note = "Working Paper",
+ year = {2004},
+}
+
+ at article( hersh1982,
+ author= {Hersh, Seymour M.},
+ title= {The Price of Power: Kissinger, Nixon, and Chile},
+ journal= {The Atlantic Monthly}, month=12,
+ url= {http://www.theatlantic.com/issues/82dec/hersh.htm},
+ year= 1982
+)
+
+ at book( hettmansperger1984,
+ author= {Hettmansperger, T},
+ title= {Statistical Inference Based on Ranks},
+ publisher= "Wiley", address= ny,
+ year= 1984
+)
+
+ at article( holland1986,
+ author= {Holland, Paul W.},
+ title= {Statistics and Causal Inference},
+ journal= jasa, volume=81, number=396,
+ pages= {945--960},
+ year= 1986
+)
+
+ at book( holland1975,
+ author= {Holland, John H.},
+ title= {Adaptation in Natural and Artificial Systems},
+ publisher= "University of Michigan Press", address= "Ann Arbor",
+ year= 1975
+)
+
+ at article( HorvitzThompson1952,
+ author= {Horvitz, D. G. and D. J. Thompson},
+ title= {A Generalization of Sampling without Replacement from a Finite Universe},
+ journal= jasa, volume=47,
+ pages= {663--685},
+ year= 1952
+)
+
+ at book( huber1981,
+ author= {Huber, Peter J.},
+ title= {Robust Statistics},
+ publisher= {Wiley, John and Sons}, address= {New York},
+ year= 1981
+)
+
+ at book( huntington1968,
+ author= {Huntington, Samuel P.},
+ title= {Political Order in Changing Societies},
+ publisher= {Yale University Press}, address= {New Haven},
+ year= 1968
+)
+
+ at book( huntington1991,
+ author= {Huntington, Samuel P.},
+ title= {The Third Wave: Democratization in the Late Twentieth Century},
+ publisher= {University of Oklahoma Press}, address= {Norman and London},
+ year= 1991
+)
+
+ at article(KingWand2007,
+ author= {King, Gary and Jonathan Wand},
+ title= {Comparing Incomparable Survey Responses: Evaluating and Selecting Anchoring Vignettes},
+ journal= pa, volume=15,
+ pages= {46--66},
+ year= 2007
+)
+
+ at article{ KirkpatrickGelattVecchi83,
+ author = "S. Kirkpatrick and C. D. Gelatt and M. P. Vecchi",
+ title = "Optimization by Simulated Annealing",
+ journal = "Science", number = "4598",
+ volume = "220",
+ pages = "671--680",
+ year = "1983"
+}
+
+
+ at book( knuth1998,
+ author= {Knuth, Donald E.},
+ title= {The Art of Computer Programming, Vol. 2: Seminumerical Algorithms},
+ edition= "3rd",
+ publisher= "Addison-Wesley", address= "Reading: MA",
+ year= 1998
+)
+
+ at Manual{KrigInv,
+ author = {Victor Picheny and David Ginsbourger},
+ title = {\pkg{KrigInv}: Kriging-based Inversion for Deterministic and Noisy Computer Experiments},
+ note = {\proglang{R}~package version~1.1},
+ url = {http://CRAN.R-project.org/package=KrigInv},
+ year = {2011}
+}
+
+ at unpublished( krosnick2004,
+ author= {Holbrook, Allyson L. and Matthew K. Berent and Jon A. Krosnick and Penny S. Visser and David S. Boninger},
+ title= {Attitude Importance and the Accumulation of Attitude-Relevant Knowledge in Memory},
+ note= "Working Paper",
+ year= 2004
+)
+
+ at Manual{LeeLee2006,
+ author = {Lee, Chun-Ying and Yung-Jin Lee},
+ title = {\pkg{PKfit}: A Tool for Data Analysis in Pharmacokinetics},
+ note = {\proglang{R}~package version~1.1.8},
+ url = {http://CRAN.R-project.org/package=PKfit},
+ year = {2009},
+}
+
+ at Manual{ivivc,
+ author = {Hsin Ya Lee and Yung-Jin Lee},
+ title = {\pkg{ivivc}: in vitro-in vivo correlation (IVIVC) modeling},
+ note = {\proglang{R}~package version~0.1.5},
+ url = {http://CRAN.R-project.org/package=ivivc},
+ year = {2009}
+}
+
+ at article( imbens2000,
+ author= {Imbens, Guido W.},
+ title= "The Role of the Propensity Score in Estimating Dose-Response Functions",
+ journal= {Biometrika}, volume=87, number=3,
+ pages= {706--710},
+ year= 2000
+)
+
+ at Article{imai2005,
+ author = {Kosuke Imai},
+ title = {Do Get-Out-The-Vote Calls Reduce Turnout? The Importance of Statistical Methods for Field Experiments},
+ journal = apsr, volume = 99, number=2,
+ pages = "283--300",
+ year = {2005},
+}
+
+ at incollection( iyengar1990,
+ author= {Iyengar, Shanto},
+ title= {Shorts to Political Knowledge: Selective attention and the accessibility bias},
+ booktitle= {Information and the Democratic Process},
+ editor= {John Ferejohn and James Kuklinski},
+ publisher= {University of Illinois Press}, address= {Urbana},
+ year= 1990
+)
+
+ at unpublished( iyengar1986,
+ author= {Iyengar, Shanto},
+ title= {Whither Political Information},
+ note= {Report to the NES Board of Overseers. Center for Political Studies, University of Michigan},
+ year= 1986
+)
+
+ at Manual{JOP,
+ author = {Sonja Kuhnt and Nikolaus Rudak},
+ title = {\pkg{JOP}: Joint Optimization Plot},
+ note = {\proglang{R}~package version~2.0.1},
+ url = {http://cran.r-project.org/package=JOP},
+ year = {2011},
+}
+
+ at book( johnston2004,
+ author= {Johnston, Richard and Michael G. Hagen and Kathleen Hall Jamieson},
+ title= {The 2000 Presidential Election and the Foundations of Party Politics},
+ publisher= cup, address= ny,
+ year= 2004
+)
+
+ at book( johnston1992,
+ author= {Johnston, Richard and Andr\'{e} Blais and Henry E. Brady and Jean Cr\^{e}te},
+ title= {Letting the People Decide: Dynamics of a Canadian Election},
+ publisher= "McGill-Queen's University Press", address= "Montreal",
+ year= 1992
+)
+
+ at book( kornhauser1959,
+ author= {Kornhauser, William},
+ title= {The Politics of Mass Society},
+ publisher= {The Free Press}, address= {New York},
+ year= 1959
+)
+
+ at article( kunsch1989,
+ author= {Kunsch, H. R. and L. A. Stefanski and R. J. Carroll},
+ title= {Conditionally Unbiased Bounded-Influence Estimation in General Regression Models},
+ journal= jasa, volume=84,
+ pages= {460--466},
+ year= 1989
+)
+
+ at book( lancaster1990,
+ editor= {Lancaster, Tony},
+ title= {The Econometric Analysis of Transition Data},
+ publisher= cup, address={New York},
+ year= {1990}
+)
+
+ at Article{lalonde1986,
+ author = {Robert LaLonde},
+ title = {Evaluating the Econometric Evaluations of Training Programs with Experimental Data},
+ journal = {American Economic Review},
+ year = {1986},
+ OPTkey = {},
+ volume = {76},
+ OPTnumber = {4},
+ pages = {604--20},
+ month = {September},
+ OPTnote = {},
+ OPTannote = {}
+}
+
+ at incollection( lawson2004,
+ author= {Lawson, Chappell},
+ title= {Introduction},
+ booktitle= {Mexico's Pivotal Democratic Election},
+ editor= {Jorge I. Dom\'{i}nguez and Chappell Lawson},
+ publisher= sup, address= "Stanford",
+ pages= {1--21},
+ year= 2004
+)
+
+ at article( lipset1959,
+ author= {Lipset, Seymour Martin},
+ title= {Some Social Requisites of Democracy: Economic Development and Political Legitimacy},
+ journal= apsr, volume=53, number=1,
+ pages= {69--105},
+ year= 1959
+)
+
+ at book( LittleRubin1987,
+ author= {Little, Roderick J. A. and Rubin, Donald B.},
+ title= {Statistical Analysis with Missing Data},
+ publisher= {J. Wiley \& Sons}, address= ny,
+ year= 1987
+)
+
+ at unpublished( lupia2004,
+ author= {Lupia, Arthur},
+ title= {Questioning Our Competence: Tasks, Institutions, and the Limited Practical Relevance of Common Political Knowledge Measures},
+ note= "Working Paper",
+ year= 2004
+)
+
+ at article( luskin2002,
+ author= {Luskin, Robert C. and James S. Fishkin and Roger Jowell},
+ title= {Considered Opinions: Deliberative Polling in Britain},
+ journal= bjps, volume=32,
+ pages= {455--487},
+ year= 2002
+)
+
+ at book( MccullaghNelder1989,
+ author= {McCullagh, Peter and John A. Nelder},
+ title= {Generalized Linear Models},
+ edition= "2nd",
+ publisher= c-h, address= ny,
+ year= 1989
+)
+
+ at article( McCulloughVinod2004a,
+ author= {McCullough, B. D. and H. D. Vinod},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Reply},
+ journal= aer, volume=94, number=1,
+ pages= {391--396},
+ year= 2004
+)
+
+ at article( McCulloughVinod2004b,
+ author= {McCullough, B. D. and H. D. Vinod},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Reply},
+ journal= aer, volume=94, number=1,
+ pages= {400--403},
+ year= 2004
+)
+
+ at article( McCulloughVinod2003,
+ author= {McCullough, B. D. and H. D. Vinod},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study},
+ journal= aer, volume=93, number=3,
+ pages= {873--892},
+ year= 2003
+)
+
+ at article( mckelvey1985a,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Elections with Limited
+Information: A Fulfilled Expectations Model Using Contemporaneous Poll and
+Endorsement Data as Information Sources},
+ journal= jet, volume=36,
+ pages= {55--85},
+ year= 1985
+)
+
+ at article( mckelvey1985b,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Sequential Elections with Limited Information},
+ journal= ajps, volume=29, number=3,
+ pages= {480--512},
+ year= 1985
+)
+
+ at article( mckelvey1986,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Information, Electoral Equilibria, and the Democratic Ideal},
+ journal= jop, volume=48, number=4,
+ pages= {909--937},
+ year= 1986
+)
+
+ at article( mcgraw1990,
+ author= {McGraw, Kathleen and Neil Pinney},
+ title= {The Effects of General and Domain-Specific Expertise on Political Memory and Judgement},
+ journal= {Social Cognition}, volume=8,
+ pages= {9--30},
+ year= 1990
+)
+
+ at article( mckelvey1985a,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Elections with Limited
+Information: A Fulfilled Expectations Model Using Contemporaneous Poll and
+Endorsement Data as Information Sources},
+ journal= jet, volume=36,
+ pages= {55--85},
+ year= 1985
+)
+
+ at article( mckelvey1985b,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Sequential Elections with Limited Information},
+ journal= ajps, volume=29, number=3,
+ pages= {480--512},
+ year= 1985
+)
+
+ at article( mckelvey1986,
+ author= {McKelvey, Richard D. and Peter C. Ordeshook},
+ title= {Information, Electoral Equilibria, and the Democratic Ideal},
+ journal= jop, volume=48, number=4,
+ pages= {909--937},
+ year= 1986
+)
+
+ at article( McNemar1947,
+ author= {McNemar, Q.},
+ title= {Note on the Sampling Error of the Differences Between Correlated Proportions or Percentage},
+ journal= {Psychometrika}, volume=12,
+ pages= {153--157},
+ year= 1947
+)
+
+ at book( maddala1992,
+ author= {Maddala, G.S.},
+ title= {Introduction to Econometrics},
+ edition= "2nd",
+ publisher= {MacMillan}, address= {New York},
+ year= "1992"
+)
+
+ at book( maddala1983,
+ author= {Maddala, G.S.p},
+ title= {Limited-Dependent and Qualitative Variables in Econometrics},
+ publisher= cup, address={New York},
+ year= {1983}
+)
+
+ at article{ MarinariParisi1992,
+ author = "E. Marinari and G. Parisi",
+ title = "Simulated tempering: A New Monte Carlo Scheme",
+ journal = "Europhysics Letters", number = "19",
+ volume = "6",
+ pages = "451--455",
+ year = "1992"
+}
+
+ at article( MannWhitney1947,
+ author= {Mann, H. and Whitney, D},
+ title= {On a Test of Whether One of Two Random Variables is Stochastically Larger than the Other},
+ journal= {Annals of Mathematical Statistics}, volume=18,
+ pages= {50--60},
+ year= 1947
+)
+
+ at Article{MebaneJr.+Sekhon:2011,
+ author = {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title = {Genetic Optimization Using Derivatives: The \pkg{rgenoud} Package for \proglang{R}},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at article( mebane2000,
+ author= {Mebane, Jr., Walter R.},
+ title= {Coordination, Moderation and Institutional Balancing in American Presidential and House Elections},
+ journal= apsr, volume=94,
+ number = 1,
+ pages= {37--57},
+ year= 2000
+)
+
+ at Manual{MebaneSekhon1997,
+ author = {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title = {GENetic Optimization Using Derivatives (GENOUD)},
+ note = {Computer program available upon request},
+ year = {1997}
+}
+
+ at article( MebaneSekhon2004,
+ author= {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title= {Robust Estimation and Outlier Detection for Overdispersed Multinomial Models of Count Data},
+ journal= ajps, volume=48,
+ number = 2,
+ pages= {391--410},
+ year= 2004
+)
+
+ at Manual{MebaneSekhon.multinomRob,
+ author = {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title = {\pkg{multinomRob}: Robust Estimation of Overdispersed Multinomial Regression Models},
+ note = {\proglang{R}~package version~1.8-4},
+ url = {http://CRAN.R-project.org/package=multinomRob},
+ year = {2009},
+}
+
+ at article( MebaneSekhon2002,
+ author= {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title= {Coordination and Policy Moderation at Midterm},
+ journal= apsr, volume=96,
+ number = 1,
+ pages= {141--157},
+ year= 2002
+)
+
+ at unpublished( MebaneSekhon1998,
+ author= {Mebane, Jr., Walter R. and Jasjeet S. Sekhon},
+ title= {GENetic Optimization Using Derivatives (GENOUD)},
+ note = {Software Package. \url{http://sekhon.berkeley.edu/rgenoud/}},
+ year= 1998
+)
+
+ at book( Michalewicz1992,
+ author= {Michalewicz, Zbigniew},
+ title= {Genetic Algorithms + Data Structures = Evolution Programs},
+ publisher= s-v, address= {New York},
+ year= {1992}
+)
+
+ at unpublished( MichalewiczSwaminathanLogan1993,
+ author= {Michalewicz, Zbigniew and Swarnalatha Swaminathan and Thomas D. Logan},
+ title= {GENOCOP (version 2.0)},
+ note = {C language computer program source code.
+\url{http://www.cs.adelaide.edu.au/~zbyszek/EvolSyst/genocop2.0.tar.Z}},
+ year= 1993
+)
+
+ at book( mes2002,
+ author= {Erikson, Robert S. and Michael B. MacKuen and James A. Stimson},
+ title= {The Macro Polity},
+ publisher= cup, address= {New York},
+ year= {2002}
+)
+
+ at incollection( miller1986,
+ author= {Miller, Nicholas R},
+ title= {Information, Electorates, and Democracy: Some Extensions and
+Interpretations of the Condorcet Jury Theorem},
+ booktitle= {Information Pooling and Group Decision Making},
+ editor= {Bernard Grofman and Guillermo Owen},
+ publisher= {JAI}, address= {Greenwich, CT},
+ year= 1986
+)
+
+ at article{MitchellKrzanowski1989,
+ author = {Mitchell, Ann F. S. and Wojtek J. Krzanowski},
+ title = {Amendments and Corrections: The Mahalanobis Distance and Elliptic Distributions},
+ journal = {Biometrika},
+ year = {1989},
+ volume = {76},
+ number = {2},
+ pages = {407},
+}
+
+ at article{MitchellKrzanowski1985,
+ author = {Mitchell, Ann F. S. and Wojtek J. Krzanowski},
+ title = {The Mahalanobis Distance and Elliptic Distributions},
+ journal = {Biometrika},
+ year = {1985},
+ volume = {72},
+ number = {2},
+ pages = {464--467},
+}
+
+ at book( neuman86,
+ author= {Neuman, W. Russell},
+ title= {The Paradox of Mass Politics: Knowledge and Opinion in the {A}merican Electorate},
+ publisher= hup, address= cam,
+ year= 1986
+)
+
+ at article( NixVose1992,
+ author= {Nix, Allen E. and Michael D. Vose},
+ title= {Modeling Genetic Algorithms with Markov Chains},
+ journal= {Annals of Mathematics and Artificial Intelligence}, volume=5,
+ pages= {79--88},
+ year= 1992
+)
+
+ at book( page1992,
+ author= {Page, Benjamin I. and Robert Y. Shapiro},
+ title= {The Rational Public: Fifty Years of Trends in {A}mericans' Policy Preferences},
+ publisher= uchp, address= chic,
+ year= 1992
+)
+
+ at article( PalfreyPoole1987,
+ author= {Palfrey, Thomas R. and Keith T. Poole},
+ title= {The Relationship between Information, Ideology, and Voting Behavior},
+ journal= ajps, volume=31,
+ number = 3,
+ pages= {511--530},
+ year= 1987
+)
+
+ at book( patterson2002,
+ author= {Patterson, Thomas E.},
+ title= {The Vanishing Voter: Public Involvement in an Age of Uncertainty},
+ publisher= "Alfred A. Knopf", address= "New York",
+ year= 2002
+)
+
+ at book( popkin1991,
+ author= {Popkin, Samuel L},
+ title= {The Reasoning Voter: Communication and Persuasion in Presidential Campaigns},
+ publisher= uchp, address= chic,
+ year= 1991
+)
+
+ at article( PriceZaller1993,
+ author= {Price, Vincent and John Zaller},
+ title= {Who Gets the News? Alternative Measures of News Reception and Their Implications for Research},
+ journal= {Public Opinion Quarterly}, volume=57, number=2,
+ pages= {133--164},
+ year= 1993
+)
+
+ at article( pryor2003,
+ author= {Pryor, Kane},
+ title= {A national state of confusion},
+ journal= {Salon.com}, month=6, day=2,
+ url= {http://www.salon.com/opinion/feature/2003/02/06/iraq_poll},
+ note= "Accessed 07/05/2004",
+ year= 2003
+)
+
+ at book( putnam2000,
+ author= {Putnam, Robert D.},
+ title= {Bowling Alone: The Collapse and Revival of American Community},
+ publisher= "Simon \& Schuster", address= ny,
+ year= 2000
+)
+
+ at book( rosenbaum2002,
+ author= {Rosenbaum, Paul R.},
+ title= {Observational Studies},
+ edition= "2nd",
+ publisher= "Springer-Verlag", address= ny,
+ year= 2002
+)
+
+ at article( Rosenbaum1999,
+ author= {Rosenbaum, Paul R.},
+ title= {Using Quantile Averages in Matched Observational Studies},
+ journal= {Applied Statistics}, volume=48,
+ number= 1,
+ pages= {63--78},
+ year= 1999
+)
+
+ at article( Rosenbaum1993,
+ author= {Rosenbaum, Paul R.},
+ title= {Comparison of Multivariate Matching Methods: Structures, Distances, and Algorithms},
+ journal= {Journal of Computational and Graphical Statistics}, volume=2,
+ number= 4,
+ pages= {405--420},
+ year= 1993
+)
+
+ at article( Rosenbaum1991,
+ author= {Rosenbaum, Paul R.},
+ title= {A Characterization of Optimal Designs for Observational Studies},
+ journal= jrssb, volume=53,
+ number= 3,
+ pages= {597--610},
+ year= 1991
+)
+
+ at article( Rosenbaum1989,
+ author= {Rosenbaum, Paul R.},
+ title= {Optimal Matching for Observational Studies},
+ journal= jasa, volume=84,
+ number= 408,
+ pages= {1024--1032},
+ year= 1989
+)
+
+ at article( RosenbaumRubin1985,
+ author= {Rosenbaum, Paul R. and Donald B. Rubin},
+ title= {Constructing a Control Group Using Multivariate Matched Sampling Methods That Incorporate the Propensity Score},
+ journal= {The American Statistician}, volume=39,
+ number= 1,
+ pages= {33--38},
+ year= 1985
+)
+
+ at article( RosenbaumRubin1984,
+ author= {Rosenbaum, Paul R. and Donald B. Rubin},
+ title= {Reducing Bias in Observational Studies Using Subclassification on the Propensity Score},
+ journal= jasa, volume=79,
+ number= 387,
+ pages= {516--524},
+ year= 1984
+)
+
+ at article( RosenbaumRubin1983,
+ author= {Rosenbaum, Paul R. and Donald B. Rubin},
+ title= {The Central Role of the Propensity Score in Observational Studies for Causal Effects},
+ journal= {Biometrika}, volume=70,
+ number= 1,
+ pages= {41--55},
+ year= 1983
+)
+
+ at article( rubin2001,
+ author= {Rubin, Donald B},
+ title= "Using Propensity Scores to Help Design Observational Studies: Application to the Tobacco Litigation",
+ journal= "Health Services \& Outcomes Research Methodology", volume=2, number=1,
+ pages= "169--188",
+ year= 2001
+)
+
+ at article( rubin1997,
+ author= {Rubin, Donald B},
+ title= "Estimating Causal Effects from Large Data Sets Using Propensity Scores",
+ journal= {Annals of Internal Medicine}, volume=127, number="8S",
+ pages= "757--763",
+ year= 1997
+)
+
+ at book( rubinMI1987,
+ author= {Rubin, Donald B.},
+ title= {Multiple Imputation for Nonresponse in Surveys},
+ publisher= {J. Wiley \& Sons}, address= ny,
+ year= 1987
+)
+
+ at article( rubin1980,
+ author= {Rubin, Donald B.},
+ title= "Bias Reduction Using Mahalanobis-Metric Matching",
+ journal= {Biometrics}, volume=36,
+ number = 2,
+ pages= {293--298},
+ year= 1980
+)
+
+ at article( rubin1979,
+ author= {Rubin, Donald B.},
+ title= "Using Multivariate Sampling and Regression Adjustment to Control Bias in Observational Studies",
+ journal= jasa, volume=74,
+ pages= {318--328},
+ year= 1979
+)
+
+ at article( rubin1978,
+ author= {Rubin, Donald B.},
+ title= {Bayesian Inference for Causal Effects: The Role of Randomization},
+ journal= {Annals of Statistics}, volume=6, number=1,
+ pages= {34--58},
+ year= 1978
+)
+
+ at article( rubin1977,
+ author= {Rubin, Donald B.},
+ title= {Assignment to a Treatment Group on the Basis of a Covariate},
+ journal= {Journal of Educational Statistics}, volume=2,
+ pages= {1--26},
+ year= 1977
+)
+
+ at article( rubin1976,
+ author= {Rubin, Donald B.},
+ title= {Multivariate Matching Methods That are Equal Percent Bias Reducing, I: Some Examples},
+ journal= {Biometrics},
+ volume = 32,
+ number = 1,
+ pages= {109--120},
+ year= 1976
+)
+
+ at article( rubin1976b,
+ author= {Rubin, Donald B.},
+ title= {Multivariate Matching Methods That are Equal Percent Bias Reducing, II: Maximums on Bias Reduction for Fixed Sample Sizes},
+ journal= {Biometrics},
+ volume = 32,
+ number = 1,
+ pages= {121--132},
+ year= 1976
+)
+
+ at article( rubinMI1976,
+ author= {Rubin, Donald B.},
+ title= {Inference and Missing Data},
+ journal= {Biometrika}, volume=63,
+ pages= {581-592},
+ year= 1976
+)
+
+ at article( rubin1973a,
+ author= {Rubin, Donald B.},
+ title= "Matching to Remove Bias in Observational Studies",
+ journal= {Biometrics}, volume=29,
+ pages= {159--184},
+ year= 1973
+)
+
+ at article( rubin1973b,
+ author= {Rubin, Donald B.},
+ title= "The Use of Matching and Regression Adjustment to Remove Bias in Observational Studies",
+ journal= {Biometrics}, volume=29,
+ pages= {185--203},
+ year= 1973
+)
+
+ at unpublished( RubinStuart,
+ author= {Rubin, Donald B. and Elizabeth A. Stuart},
+ title= {Affinely Invariant Matching Methods with Discriminant Mixtures of Proportional Ellipsoidally Symmetric Distributions},
+ note= "Working Paper",
+ year= 2005
+)
+
+ at article( RubinThomas1996,
+ author= {Rubin, Donald B. and Neal Thomas},
+ title= "Matching Using Estimated Propensity Scores: Relating Theory to Practice",
+ journal= {Biometrics}, volume=52, number=1,
+ pages= {249--264},
+ year= 1996
+)
+
+ at article( RubinThomas1992,
+ author= {Rubin, Donald B. and Neal Thomas},
+ title= "Affinely Invariant Matching Methods with Ellipsoidal Distributions",
+ journal= aos, volume=20, number=2,
+ pages= {1079--1093},
+ year= 1992
+)
+
+ at article( RubinThomas1992b,
+ author= {Rubin, Donald B. and Neal Thomas},
+ title= "Characterizing the Effect of Matching Using Linear Propensity Score Methods with Normal Distributions",
+ journal= "Biometrika", volume=79, number=4,
+ pages= {797--809},
+ year= 1992
+)
+
+
+
+ at article( rustow1970,
+ author= {Rustow, Dankwart A.},
+ title= {Transitions to Democracy: Toward a Dynamic Model},
+ journal= {Comparative Politics}, volume=2, number=3,
+ pages= {337--363},
+ year= 1970
+)
+
+ at article(SchacharNalebuff2004,
+ author= {Shachar, Ron and Barry Nalebuff},
+ title= {Verifying the Solution from a Nonlinear Solver: A Case Study: Comment},
+ journal= aer, volume=94, number=1,
+ pages= {382-390},
+ year= 2004
+)
+
+ at book( schafer1997a,
+ author= {Schafer, Joseph L.},
+ title= {Analysis of Incomplete Multivariate Data},
+ publisher= c-h, address= "London",
+ year= 1997
+)
+
+ at unpublished( schafer1997b,
+ author= {Schafer, Joseph L.},
+ title= {Imputation of missing covariates under a general linear mixed model},
+ note= {Technical report, Dept. of Statistics, Penn State University},
+ year= 1997
+)
+
+ at Manual{SekhonMatching,
+ author = {Jasjeet S. Sekhon},
+ title = {\pkg{Matching}: Multivariate and Propensity Score Matching with Automated Balance Search},
+ note = {\proglang{R}~package version~4.7-12},
+ url = {http://CRAN.R-project.org/package=Matching},
+ year = {2011},
+}
+
+ at article( sekhon2004,
+ author= {Sekhon, Jasjeet S.},
+ title= {Quality Meets Quantity: Case Studies, Conditional Probability and Counterfactuals},
+ journal= pop, volume=2,
+ number = 2,
+ pages= {281--293},
+ year= 2004
+)
+
+ at unpublished( SekhonInformation,
+ author= {Sekhon, Jasjeet S.},
+ title= "The Varying Role of Voter Information Across Democratic Societies",
+ note = "Working Paper",
+ url= {http://sekhon.berkeley.edu/papers/SekhonInformation.pdf},
+ year= 2004
+)
+
+ at article( SekhonMebane1998,
+ author= {Sekhon, Jasjeet Singh and Mebane, Jr., Walter R.},
+ title= {Genetic Optimization Using Derivatives: Theory and Application to Nonlinear Models},
+ journal= {Political Analysis}, volume={7},
+ pages= {189--203},
+ year= 1998
+)
+
+ at unpublished( sekhon_glmRob,
+ author= {Sekhon, Jasjeet S.},
+ title= {Robust Alternatives to Binary Logit and Probit: With
+ reanalysis of Fearon and Laitin's (2003) ``Ethnicity, Insurgency and
+ Civil War'' and Bartels's (1996) ``Uninformed Votes: Information Effects in
+ Presidential Elections.},
+ note= "Working Paper",
+ year= 2004
+)
+
+ at book( smith_charles1956,
+ author= {Smith, Charles Page},
+ title= {James Wilson, Founding Father, 1742-1798},
+ publisher= "University of North Carolina Press", address= "Chapel Hill",
+ year= 1956
+)
+
+ at article( smith_herbert1997,
+ author= {Smith, Herbert L.},
+ title= {Matching with Multiple Controls to Estimate Treatment Effects in Observational Studies},
+ journal= "Sociological Methodology", volume=27,
+ pages= "305--353",
+ year= "1997"
+)
+
+ at article( SmithTodd2005a,
+ author= {Smith, Jeffrey and Petra Todd},
+ title= {Does Matching Overcome LaLonde's Critique of Nonexperimental Estimators?},
+ journal= je, volume=125, number="1--2",
+ pages= "305--353",
+ year= "2005"
+)
+
+ at article( SmithTodd2005b,
+ author= {Smith, Jeffrey and Petra Todd},
+ title= {Rejoinder},
+ journal= je, volume=125, number="1--2",
+ pages= "365--375",
+ year= "2005"
+)
+
+ at article{SmithTodd2001,
+ author = {Jeffrey A. Smith and Petra E. Todd},
+ title = {Reconciling Conflicting Evidence on the Performance of Propensity Score Matching Methods},
+ journal = {AEA Papers and Proceedings},
+ year = {2001},
+ volume = {91},
+ number = {2},
+ pages = {112--118},
+}
+
+ at book( sniderman1991,
+ author= {Sniderman, Paul M. and Richard Brody and Philip E. Tetlock},
+ title= {Reasoning and Choice: Explorations in Political Psychology},
+ publisher= cup, address= ny,
+ year= 1991
+)
+
+ at incollection( sniderman1993,
+ author= {Sniderman, Paul M.},
+ title= {The New Look in Public Opinion Research},
+ booktitle= {Political Science: The State of the Discipline II},
+ editor= {Ada W. Finifter},
+ publisher= {American Political Science Association},
+ address= {Washington, DC},
+ year= 1993
+)
+
+ at book( snyder2000,
+ author= {Snyder, Jack},
+ title= {From Voting to Violence: Democratization and Nationalist Conflict},
+ publisher= {W. W. Norton}, address= ny,
+ year= 2000
+)
+
+ at article( stephens1974,
+ author= {Stephens, M. A.},
+ title= {EDF Statistics for Goodness of Fit and Some Comparisons},
+ journal= jasa, volume=69,
+ pages= {730--737},
+ year= 1974
+)
+
+ at article( stokes2004,
+ author= {Stokes, Houston},
+ title= {On the Advantage of Using Two or More Econometric Software Systems to Solve the Same Problem},
+ journal= {Journal of Economic and Social Measurement}, volume=29, number="1-3",
+ pages= {307--320},
+ year= 2004
+)
+
+ at Manual{synth2008,
+ author = {Alexis Diamond and Jens Hainmueller},
+ title = {\pkg{Synth}: Synthetic Control Group Method for Comparative Case Studies},
+ note = {\proglang{R}~package version~0.1-6},
+ url = {http://CRAN.R-project.org/package=Synth},
+ year = {2008}
+}
+
+ at incollection( vose1993,
+ author= {Vose, Michael D.},
+ title= {Modeling Simple Genetic Algorithms},
+ booktitle= {Foundations of Genetic Algorithms 2},
+ editor= {L.~Darrell Whitley},
+ publisher= {Morgan Kaufmann}, address= {San Mateo, CA},
+ year= 1993
+)
+
+ at Manual{WandKingLau2007,
+ author = {Wand, Jonathan and Gary King and Olivia Lau},
+ title = {\pkg{Anchors}: Software for Anchoring Vignette Data},
+ note = {\proglang{R}~package version~2.0},
+ url = {http://wand.stanford.edu/anchors/},
+ year = {2008}
+}
+
+ at book( wilcox1997,
+ author= {Wilcox, Rand R.},
+ title= {Introduction to Robust Estimation},
+ publisher= {Academic Press}, address= {San Diego, CA},
+ year= 1997
+)
+
+ at article( wilcoxon1945,
+ author= {Wilcoxon, F},
+ title= {Individual Comparisons by Ranking Methods},
+ journal= {Biometrics}, volume=1,
+ pages= {8083},
+ year= 1945
+)
+
+ at article( WinshipMorgan1999,
+ author= {Winship, Christopher and Stephen Morgan},
+ title= {The estimation of causal effects from observational data},
+ journal= "Annual Review of Sociology", volume=25,
+ pages= "659--707",
+ year= "1999"
+)
+
+ at article( wittman1989,
+ author= {Wittman, Donald A},
+ title= {Why Democracies Produce Efficient Results},
+ journal= jpe, volume=97,
+ pages= {1395--1424},
+ year= 1989
+)
+
+ at article( yao.liu.lin1999,
+ author= {Yao, Xin and Yong Liu and Guangming Lin},
+ title= {Evolutionary Programming Made Faster},
+ journal= {IEEE Transactions on Evolutionary Computation}, volume=3,
+ month= {July}, number= 2,
+ pages= {82--102},
+ year= 1999
+)
+
+ at article( yule1899,
+ author= {Yule, Undy G.},
+ title= {An Investigation into the Causes of Changes in Pauperism in England, Chiefly During the Last Two Intercensal Decades (Part I.)},
+ journal= {Journal of the Royal Statistical Society}, volume=62,
+ number = 2,
+ pages= {249--295},
+ year= 1899
+)
+
+ at incollection( zaller2004,
+ author= {Zaller, John R},
+ title= {Floating Voters in U.S.\ Presidential Elections, 1948--1996},
+ booktitle= {Studies in Public Opinion: Gauging Attitudes, Nonattitudes, Measurement Error and Change},
+ editor= {Willem Saris and Paul Sniderman},
+ publisher= pup,
+ address= nj,
+ year= "forthcoming"
+)
+
+ at book( zaller1992,
+ author= {Zaller, John R},
+ title= {The Nature and Origins of Mass Opinion},
+ publisher= cup, address= ny,
+ year= 1992
+)
+
+ at unpublished( zaller1986,
+ author= {Zaller, John R.},
+ title= {Analysis of Information Items in the 1985 NES Pilot Study},
+ note= {NES Pilot Study Report. Center for Political Studies, University of Michigan},
+ year= 1986
+)
+
+ at unpublished( zaller1985,
+ author= {Zaller, John R.},
+ title= {Proposal for the Measurement of Political Information},
+ note= {Report to the NES Board of Overseers. Center for Political Studies, University of Michigan},
+ year= 1985
+)
+
+ at book( zakaria2003,
+ author= {Zakaria, Fareed},
+ title= {The Future of Freedom: Illiberal Democracy at Home and Abroad},
+ publisher= {W. W. Norton}, address= {New York},
+ year= 2003
+)
+
+ at article( zakaria1998,
+ author= {Zakaria, Fareed},
+ title= {Doubts About Democracy},
+ journal= {Newsweek}, Month="January", day=5,
+ year= 1998
+)
+
+ at article( zakaria1997,
+ author= {Zakaria, Fareed},
+ title= {The Rise of Illiberal Democracy},
+ journal= {Foreign Affairs}, volume=76, number=6,
+ pages= {249--295},
+ year= 1997
+)
+
+ at Article{Altman+McDonald:2011,
+ author = {Micah Altman and Michael P. McDonald},
+ title = {\pkg{BARD}: Better Automated Redistricting},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at Article{Wand+King:2011,
+ author = {Jonathan Wand and Gary King},
+ title = {\pkg{Anchors}: Software for Anchoring Vignette Data},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at Article{Sekhon:2011,
+ author = {Jasjeet S. Sekhon},
+ title = {Multivariate and Propensity Score Matching Software with Automated
+ Balance Optimization: The \pkg{Matching} Package for \proglang{R}},
+ journal = {Journal of Statistical Software},
+ year = {2011},
+ note = {Forthcoming},
+ url = {http://www.jstatsoft.org/}
+}
+
+ at Manual{Rcore,
+ title = {R: A Language and Environment for Statistical Computing},
+ author = {{R Development Core Team}},
+ organization = {R Foundation for Statistical Computing},
+ address = {Vienna, Austria},
+ year = {2009},
+ note = {{ISBN} 3-900051-07-0},
+ url = {http://www.R-project.org},
+}
+
+ at Comment LocalWords: apsr booktitle Finifter Zaller NES Iyengar Shanto Brehm
+ at Comment LocalWords: AlvarezBrehm ajps HorvitzThompson Horvitz jasa ny kunsch
+ at Comment LocalWords: MannWhitney Psychometrika Biometrika rubinMI Stefanski
+ at Comment LocalWords: Cantoni Elvezio Ronchetti CarrollPederson Pederson jssrb
+ at Comment LocalWords: copas jrssb sekhon glmRob Probit Fearon Laitin's althaus
+ at Comment LocalWords: Bartels's MebaneSekhon Keisuke Geert ec Allyson Berent
+ at Comment LocalWords: Krosnick Visser Boninger Hausman Kosuke Rosenbaum Bon Ai
+ at Comment LocalWords: Kornhauser Jamieson hersh url huntington Zakaria Fareed
+ at Comment LocalWords: zakaria rustow Dankwart Lipset geddes MacKuen Brunell
+ at Comment LocalWords: BrunellNiNardo DiNardo Reweighting AldrichMcKelvey rubin
+ at Comment LocalWords: McKelvey imbens abadie incollection dominguez nguez jop
+ at Comment LocalWords: Chappell Ordeshook Lupia fishkin Subclassification Jong
+ at Comment LocalWords: CochranRubin BertsimasTsitsiklis Bertsimas Dimitris Yung
+ at Comment LocalWords: Tsitsiklis Kaufmann Quantile Ellipsoidally Galiani Segal
+ at Comment LocalWords: Gertler Schargrodsky GalianiGertlerSchargrodsky Diprete
+ at Comment LocalWords: DipreteEngelhardt Engelhardt herbert Winship Jin PKfit
+ at Comment LocalWords: WinshipMorgan BowersHansen Pharmacokinetics Vinod aer
+ at Comment LocalWords: McCulloughVinod SchacharNalebuff Shachar Nalebuff Hsin
+ at Comment LocalWords: AltmanGillMcDonald Braumoeller Jasjeet ivivc vitro vivo
+ @Comment LocalWords: IVIVC Hainmueller Synth Mebane GENetic
+ @Comment LocalWords: GENOUD DiceOptim Ginsbourger Roustant
+ @Comment LocalWords: Kriging
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/r-cran-rgenoud.git
More information about the debian-science-commits
mailing list