// Qf <- function(par) private double qF(double[] par, ArrayRealVector y, ArrayRealVector w) { // fv <- solve((exp(-par[1])*W) + (exp(-par[2])*G), // (exp(-par[1])*W)%*%as.vector(y)) solver = new QRDecomposition( wM.scalarMultiply(FastMath.exp(-par[0])) .add(gM.scalarMultiply(FastMath.exp(-par[1])))) .getSolver(); fv = (ArrayRealVector) solver.solve(wM.scalarMultiply(FastMath.exp(-par[0])).operate(y)); // b <- diff(fv, differences=order) b = MatrixFunctions.diffV(fv, Controls.RW_ORDER); // DT <- determinant((exp(-par[1])*W) + (exp(-par[2])*G))$modulus double dt = new LUD( wM.scalarMultiply(FastMath.exp(-par[0])) .add(gM.scalarMultiply(FastMath.exp(-par[1])))) .getDeterminant(); // f <- -(N/2)*log(2*pi*exp(par[1])) + # 1 tempV = y.subtract(fv); double f = -(n / 2) * FastMath.log(2 * FastMath.PI * FastMath.exp(par[0])) // .5*sum(log(weights))- # 2 + 0.5 * MatrixFunctions.sumV(MatrixFunctions.logVec(w)) // sum(weights*(y-fv)^2)/(2*exp(par[1])) + # 3 - MatrixFunctions.sumV(w.ebeMultiply(tempV).ebeMultiply(tempV)) / (2 * FastMath.exp(par[0])) // (N/2)*log(2*pi) - # 4 + (n * FastMath.log(2 * FastMath.PI)) / 2 // ((N-order)/2)*log(2*pi*exp(par[2]))- # 5 - ((n - Controls.RW_ORDER) * FastMath.log(2 * FastMath.PI * FastMath.exp(par[1]))) / 2 // sum(b^2)/(2*exp(par[2])) - # 6 - MatrixFunctions.sumV(b.ebeMultiply(b)) / (2 * FastMath.exp(par[1])) // .5*DT # 7 - 0.5 * dt; // attributes(f) <- NULL // Pen <- if (penalty==TRUE) delta[1]*(par[1]-shift[1])^2 // + delta[2]*(par[2]-shift[2])^2 else 0 -f+Pen double pen = 0; if (Controls.PENALTY) { pen = delta.getEntry(0) * (par[0] - Controls.RW_SHIFT[0]) * (par[0] - Controls.RW_SHIFT[0]) + delta.getEntry(1) * (par[1] - Controls.RW_SHIFT[1]) * (par[1] - Controls.RW_SHIFT[1]); } // -f+Pen # no penalty yet return (-f + pen); }
/** * The main fitting method of Random Walk smoother. * * @param additiveFit - object of AdditiveFit class * @return residuals */ public ArrayRealVector solve(AdditiveFit additiveFit) { ArrayRealVector y = additiveFit.getZ(); ArrayRealVector w = additiveFit.getW(); int whichDistParameter = additiveFit.getWhichDistParameter(); // if (any(is.na(y))) for (int i = 0; i < y.getDimension(); i++) { if (Double.isNaN(y.getEntry(i))) { // weights[is.na(y)] <- 0 w.setEntry(i, 0.0); // y[is.na(y)] <- 0 y.setEntry(i, 0.0); } } // N <- length(y) n = y.getDimension(); // ------------------------------------------------------- BECOMES VERY SLOW HERE // W <- diag.spam(x=weights) # weights wM = (BlockRealMatrix) MatrixUtils.createRealDiagonalMatrix(w.getDataRef()); // E <- diag.spam(N) eM = MatrixFunctions.buildIdentityMatrix(n); // D <- diff(E, diff = order) # order dM = MatrixFunctions.diff(eM, Controls.RW_ORDER); // ------------------------------------------------------- FREEZES HERE // G <- t(D)%*%D gM = dM.transpose().multiply(dM); // logsig2e <- log(sig2e) # getting logs double logsig2e = FastMath.log(sigmasHash.get(whichDistParameter)[0]); // logsig2b <- log(sig2b) double logsig2b = FastMath.log(sigmasHash.get(whichDistParameter)[1]); // fv <- solve(exp(-logsig2e)*W + exp(-logsig2b)*G, // (exp(-logsig2e)*W)%*% as.vector(y)) solver = new QRDecomposition( wM.scalarMultiply(FastMath.exp(-logsig2e)) .add(gM.scalarMultiply(FastMath.exp(-logsig2b)))) .getSolver(); fv = (ArrayRealVector) solver.solve(wM.scalarMultiply(FastMath.exp(-logsig2e)).operate(y)); // if (sig2e.fix==FALSE && sig2b.fix==FALSE) # both estimated{ if (Controls.SIG2E_FIX) { if (Controls.SIG2B_FIX) { // out <- list() // par <- c(logsig2e, logsig2b) // out$par <- par // value.of.Q <- -Qf(par) valueOfQ = -qF(new double[] {logsig2e, logsig2b}, y, w); // se <- NULL se = null; } else { // par <- log(sum((D%*%fv)^2)/N) tempV = (ArrayRealVector) dM.operate(fv); logsig2b = FastMath.log(MatrixFunctions.sumV(tempV.ebeMultiply(tempV)) / n); // Qf1 <- function(par) Qf(c(logsig2e, par)) // out<-nlminb(start = par,objective = Qf1, // lower = c(-20), upper = c(20)) nonLinObj1.setResponse(y); nonLinObj1.setWeights(w); nonLinObj1.setLogsig2e(logsig2e); maxiter = new MaxIter(Controls.BOBYQA_MAX_ITER); maxeval = new MaxEval(Controls.BOBYQA_MAX_EVAL); initguess = new InitialGuess(new double[] {logsig2b, logsig2b}); bounds = new SimpleBounds( new double[] {-Double.MAX_VALUE, -Double.MAX_VALUE}, new double[] {Double.MAX_VALUE, Double.MAX_VALUE}); obj = new ObjectiveFunction(nonLinObj1); PointValuePair values = optimizer.optimize(maxiter, maxeval, obj, initguess, bounds, GoalType.MINIMIZE); logsig2b = values.getPoint()[0]; if (logsig2b > 20.0) { logsig2b = 20.0; valueOfQ = -qF(new double[] {logsig2e, logsig2b}, y, w); } else if (logsig2b < -20.0) { logsig2b = -20.0; valueOfQ = -qF(new double[] {logsig2e, logsig2b}, y, w); } else { valueOfQ = -values.getValue(); } // out$hessian <- optimHess(out$par, Qf1) // value.of.Q <- -out$objective // shes <- 1/out$hessian // se1 <- ifelse(shes>0, sqrt(shes), NA) // par <- c(logsig2e, out$par) // names(par) <- c("logsig2e", "logsig2b") /// out$par <- par // se <- c(NA, se1) // System.out.println(logsig2e+" "+logsig2b +" "+qF(new double[]{logsig2e, logsig2b}, y, // w)); } } else { if (Controls.SIG2B_FIX) { // par <- log(sum(weights*(y-fv)^2)/N) tempV = y.subtract(fv); logsig2e = FastMath.log(MatrixFunctions.sumV(tempV.ebeMultiply(tempV).ebeMultiply(w)) / n); // Qf2 <- function(par) Qf(c(par, logsig2b)) // out <- nlminb(start = par, objective = Qf2, // lower = c(-20), upper = c(20)) nonLinObj2.setResponse(y); nonLinObj2.setWeights(w); nonLinObj2.setLogsig2b(logsig2b); maxiter = new MaxIter(Controls.BOBYQA_MAX_ITER); maxeval = new MaxEval(Controls.BOBYQA_MAX_EVAL); initguess = new InitialGuess(new double[] {logsig2e, logsig2e}); bounds = new SimpleBounds( new double[] {-Double.MAX_VALUE, -Double.MAX_VALUE}, new double[] {Double.MAX_VALUE, Double.MAX_VALUE}); obj = new ObjectiveFunction(nonLinObj2); PointValuePair values = optimizer.optimize(maxiter, maxeval, obj, initguess, bounds, GoalType.MINIMIZE); logsig2e = values.getPoint()[0]; // out$hessian <- optimHess(out$par, Qf2) // value.of.Q <- -out$objective if (logsig2e > 20.0) { logsig2e = 20.0; valueOfQ = -qF(new double[] {logsig2e, logsig2b}, y, w); } else if (logsig2e < -20.0) { logsig2e = -20.0; valueOfQ = -qF(new double[] {logsig2e, logsig2b}, y, w); } else { valueOfQ = -values.getValue(); } // shes <- 1/out$hessian // se1 <- ifelse(shes>0, sqrt(shes), NA) // par <- c( out$par, logsig2b) // names(par) <- c("logsig2e", "logsig2b") // out$par <- par // se <- c(se1, NA) // System.out.println(logsig2e+" "+logsig2b +" "+qF(new double[]{logsig2e, logsig2b}, y, // w)); } else { // par <- c(logsig2e <- log(sum(weights*(y-fv)^2)/N), // logsig2b <-log(sum((D%*%fv)^2)/N)) tempV = y.subtract(fv); logsig2e = FastMath.log(MatrixFunctions.sumV(w.ebeMultiply(tempV).ebeMultiply(tempV)) / n); tempV = (ArrayRealVector) dM.operate(fv); logsig2b = FastMath.log(MatrixFunctions.sumV(tempV.ebeMultiply(tempV)) / n); nonLinObj.setResponse(y); nonLinObj.setWeights(w); // out <- nlminb(start = par, objective = Qf, // lower = c(-20, -20), upper = c(20, 20)) maxiter = new MaxIter(Controls.BOBYQA_MAX_ITER); maxeval = new MaxEval(Controls.BOBYQA_MAX_EVAL); initguess = new InitialGuess(new double[] {logsig2e, logsig2b}); bounds = new SimpleBounds(new double[] {-20.0, -20.0}, new double[] {20.0, 20.0}); obj = new ObjectiveFunction(nonLinObj); PointValuePair values = optimizer.optimize(maxiter, maxeval, obj, initguess, bounds, GoalType.MINIMIZE); logsig2e = values.getPoint()[0]; logsig2b = values.getPoint()[1]; // System.out.println(logsig2e+" "+logsig2b +" "+values.getValue()); // out$hessian <- optimHess(out$par, Qf) !!! Missing in Java // value.of.Q <- -out$objective valueOfQ = -values.getValue(); // shes <- try(solve(out$hessian)) // se <- if (any(class(shes)%in%"try-error")) // rep(NA_real_,2) else sqrt(diag(shes)) } } // fv <- solve(exp(-out$par[1])*W + exp(-out$par[2])*G, // (exp(-out$par[1])*W)%*% as.vector(y)) solver = new QRDecomposition( wM.scalarMultiply(FastMath.exp(-logsig2e)) .add(gM.scalarMultiply(FastMath.exp(-logsig2b)))) .getSolver(); fv = (ArrayRealVector) solver.solve(wM.scalarMultiply(FastMath.exp(-logsig2e)).operate(y)); sigmasHash.put( whichDistParameter, new Double[] {FastMath.exp(logsig2e), FastMath.exp(logsig2b)}); // b <- diff(fv, differences=order) b = MatrixFunctions.diffV(fv, Controls.RW_ORDER); // tr1 <- order + sum(b^2)/(exp(out$par[2])) # this always right // attributes(tr1) <- NULL double tr1 = Controls.RW_ORDER + MatrixFunctions.sumV(b.ebeMultiply(b)) / (FastMath.exp(logsig2b)); tempV = null; return y.subtract(fv); }