Glenn Schultz <glennmschultz <at> me.com> writes: > > Hello All, > I need some help with optimx, mostly due to my apparent lack of > imagination than optimx itself. Below is the pertinent code for > which I have a question. I am fitting to the term structure of swap > rates per Cox, Ingersoll, and Ross. As you can see the objective > function is CIRTune. I have set up the lower and upper bounds of > the model for each kappa, lambda, and theta. Everything works as > expected. > However, there is an additional constraint. > 2 * kappa * lamba >= sigma^2 > My question is as follows: should the constraint be worked into the > function or should I add an additional parameter in the function > that is controlled by lower and upper?
This is a general question about constrained optimization, not just about optimx (e.g. it would apply to the L-BFGS-B method for base::optim() as well). In general the best way to handle this (I think) would be reparameterize your model slightly, substituting gamma = 2*kappa*lambda-sigma^2 for either lambda or kappa. Then you know that gamma must be >=0, and you can compute the appropriate value of (e.g.) lambda = (gamma+sigma^2)/(2*kappa) on the fly from the specified values of kappa and gamma. This will automatically satisfy the lambda>0 constraint (if gamma, sigma, kappa are all >0), but you need to check what's necessary to satisfy the other (lambda<1) constraint; I haven't worked all the way through that ("left as an exercise"), but if it can't definitely be satisfied by an independent constraint on gamma then you're in trouble (you have to work out what values of kappa, sigma, and gamma could lead to lambda>1, then see if it's possible to prevent them by assigning independent constraints). If you *are* in trouble, then you need to find an optimizer that can handle nonlinear inequality constraints. I think the nloptr package might have one, or you can do this by hand (1) exactly by Lagrange multipliers or (2) approximately by imposing a nonlinear penalty when the constraint is violated. > #Objective function > CIRTune <- function(param = numeric(), > shortrate = numeric(), sigma = .015, cfmatrix = matrix(), > matmatrix = matrix()){ > kappa = param[1] > lambda = param[2] > theta = param[3] > > Disc <- CIRBondPrice(kappa = kappa, lambda = lambda, > theta = theta, shortrate = shortrate, T= matmatrix, > step = 0, sigma = sigma) > > CIRTune <- sqrt((sum(colSums((cfmatrix * Disc))^2))/ncol(matmatrix)) > return(CIRTune) > } > > # Fit the model to the market > fit <- optimx(par = c(.1, .003, .03), > fn = CIRTune, > method = "L-BFGS-B", > lower = c(rep(.001,3), > upper = rep(1, 3), > shortrate = shortrate, > sigma = .015, > cfmatrix = CIR.CF.Matrix, > matmatrix = CIR.Mat.Matrix) > close(CalCIR1) > return(fit) ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.