protected double calculateLogFieldLikelihood() {

    if (!intervalsKnown) {
      // intervalsKnown -> false when handleModelChanged event occurs in super.
      wrapSetupIntervals();
      setupGMRFWeights();
      intervalsKnown = true;
    }

    double currentLike = 0;
    DenseVector diagonal1 = new DenseVector(fieldLength);
    DenseVector currentGamma = new DenseVector(popSizeParameter.getParameterValues());

    SymmTridiagMatrix currentQ =
        getScaledWeightMatrix(
            precisionParameter.getParameterValue(0), lambdaParameter.getParameterValue(0));
    currentQ.mult(currentGamma, diagonal1);

    //        currentLike += 0.5 * logGeneralizedDeterminant(currentQ) - 0.5 *
    // currentGamma.dot(diagonal1);

    currentLike +=
        0.5 * (fieldLength - 1) * Math.log(precisionParameter.getParameterValue(0))
            - 0.5 * currentGamma.dot(diagonal1);
    if (lambdaParameter.getParameterValue(0) == 1) {
      currentLike -= (fieldLength - 1) / 2.0 * LOG_TWO_TIMES_PI;
    } else {
      currentLike -= fieldLength / 2.0 * LOG_TWO_TIMES_PI;
    }

    return currentLike;
  }
 public SymmTridiagMatrix getStoredScaledWeightMatrix(double precision) {
   SymmTridiagMatrix a = storedWeightMatrix.copy();
   for (int i = 0; i < a.numRows() - 1; i++) {
     a.set(i, i, a.get(i, i) * precision);
     a.set(i + 1, i, a.get(i + 1, i) * precision);
   }
   a.set(fieldLength - 1, fieldLength - 1, a.get(fieldLength - 1, fieldLength - 1) * precision);
   return a;
 }
 protected void storeState() {
   super.storeState();
   System.arraycopy(
       coalescentIntervals, 0, storedCoalescentIntervals, 0, coalescentIntervals.length);
   System.arraycopy(
       sufficientStatistics, 0, storedSufficientStatistics, 0, sufficientStatistics.length);
   storedWeightMatrix = weightMatrix.copy();
   storedLogFieldLikelihood = logFieldLikelihood;
 }
  public SymmTridiagMatrix getStoredScaledWeightMatrix(double precision, double lambda) {
    if (lambda == 1) return getStoredScaledWeightMatrix(precision);

    SymmTridiagMatrix a = storedWeightMatrix.copy();
    for (int i = 0; i < a.numRows() - 1; i++) {
      a.set(i, i, precision * (1 - lambda + lambda * a.get(i, i)));
      a.set(i + 1, i, a.get(i + 1, i) * precision * lambda);
    }

    a.set(
        fieldLength - 1,
        fieldLength - 1,
        precision * (1 - lambda + lambda * a.get(fieldLength - 1, fieldLength - 1)));
    return a;
  }
  public static double logGeneralizedDeterminant(SymmTridiagMatrix X) {
    // Set up the eigenvalue solver
    SymmTridiagEVD eigen = new SymmTridiagEVD(X.numRows(), false);
    // Solve for the eigenvalues
    try {
      eigen.factor(X);
    } catch (NotConvergedException e) {
      throw new RuntimeException(
          "Not converged error in generalized determinate calculation.\n" + e.getMessage());
    }

    // Get the eigenvalues
    double[] x = eigen.getEigenvalues();

    double a = 0;
    for (double d : x) {
      if (d > 0.00001) a += Math.log(d);
    }

    return a;
  }
 public SymmTridiagMatrix getWeightMatrix() {
   return weightMatrix.copy();
 }