Example #1
0
  // 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);
  }
Example #2
0
  /**
   * 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);
  }