public double execute(long in1, long in2) throws DMLRuntimeException { switch (bFunc) { case MAX: case CUMMAX: return (in1 >= in2 ? in1 : in2); case MIN: case CUMMIN: return (in1 <= in2 ? in1 : in2); case MAXINDEX: return (in1 >= in2) ? 1 : 0; case MININDEX: return (in1 <= in2) ? 1 : 0; case LOG: // if ( in1 <= 0 ) // throw new DMLRuntimeException("Builtin.execute(): logarithm can be computed only for // non-negative numbers."); if (FASTMATH) return (FastMath.log(in1) / FastMath.log(in2)); else return (Math.log(in1) / Math.log(in2)); case LOG_NZ: if (FASTMATH) return (in1 == 0) ? 0 : (FastMath.log(in1) / FastMath.log(in2)); else return (in1 == 0) ? 0 : (Math.log(in1) / Math.log(in2)); default: throw new DMLRuntimeException("Builtin.execute(): Unknown operation: " + bFunc); } }
/** * Compute the logarithm of the PMF for a binomial distribution using the saddle point expansion. * * @param x the value at which the probability is evaluated. * @param n the number of trials. * @param p the probability of success. * @param q the probability of failure (1 - p). * @return log(p(x)). */ static double logBinomialProbability(int x, int n, double p, double q) { double ret; if (x == 0) { if (p < 0.1) { ret = -getDeviancePart(n, n * q) - n * p; } else { ret = n * FastMath.log(q); } } else if (x == n) { if (q < 0.1) { ret = -getDeviancePart(n, n * p) - n * q; } else { ret = n * FastMath.log(p); } } else { ret = getStirlingError(n) - getStirlingError(x) - getStirlingError(n - x) - getDeviancePart(x, n * p) - getDeviancePart(n - x, n * q); double f = (MathUtils.TWO_PI * x * (n - x)) / n; ret = -0.5 * FastMath.log(f) + ret; } return ret; }
/** * Calculate the probability of a new category being used for the item being sold. See * CategoryCountSpread.xlsx * * @param auctionNumber Count of auctions to submit, including this. Starts from 1. * @param logParam * @return */ public static boolean useNewAuctionCategory(int auctionNumber, double logParam, double rand) { if (auctionNumber < 1 || logParam < 1) throw new IllegalArgumentException(); if (auctionNumber == 1) return true; // log( (x + 1) / x), log-base to be given double probNewCat = FastMath.log(1 + (double) 1 / auctionNumber) / FastMath.log(logParam); return rand < probNewCat; // new category }
public double execute(double in) throws DMLRuntimeException { switch (bFunc) { case SIN: return FASTMATH ? FastMath.sin(in) : Math.sin(in); case COS: return FASTMATH ? FastMath.cos(in) : Math.cos(in); case TAN: return FASTMATH ? FastMath.tan(in) : Math.tan(in); case ASIN: return FASTMATH ? FastMath.asin(in) : Math.asin(in); case ACOS: return FASTMATH ? FastMath.acos(in) : Math.acos(in); case ATAN: return Math.atan(in); // faster in Math case CEIL: return FASTMATH ? FastMath.ceil(in) : Math.ceil(in); case FLOOR: return FASTMATH ? FastMath.floor(in) : Math.floor(in); case LOG: return FASTMATH ? FastMath.log(in) : Math.log(in); case LOG_NZ: return (in == 0) ? 0 : FASTMATH ? FastMath.log(in) : Math.log(in); case ABS: return Math.abs(in); // no need for FastMath case SIGN: return FASTMATH ? FastMath.signum(in) : Math.signum(in); case SQRT: return Math.sqrt(in); // faster in Math case EXP: return FASTMATH ? FastMath.exp(in) : Math.exp(in); case ROUND: return Math.round(in); // no need for FastMath case PLOGP: if (in == 0.0) return 0.0; else if (in < 0) return Double.NaN; else return (in * (FASTMATH ? FastMath.log(in) : Math.log(in))); case SPROP: // sample proportion: P*(1-P) return in * (1 - in); case SIGMOID: // sigmoid: 1/(1+exp(-x)) return FASTMATH ? 1 / (1 + FastMath.exp(-in)) : 1 / (1 + Math.exp(-in)); case SELP: // select positive: x*(x>0) return (in > 0) ? in : 0; default: throw new DMLRuntimeException("Builtin.execute(): Unknown operation: " + bFunc); } }
/* (non-Javadoc) * @see net.finmath.stochastic.RandomVariableInterface#log() */ public RandomVariable log() { if (isDeterministic()) { double newValueIfNonStochastic = FastMath.log(valueIfNonStochastic); return new RandomVariable(time, newValueIfNonStochastic); } else { double[] newRealizations = new double[realizations.length]; for (int i = 0; i < newRealizations.length; i++) newRealizations[i] = FastMath.log(realizations[i]); return new RandomVariable(time, newRealizations); } }
/** * Returns the regularized beta function I(x, a, b). * * <p>The implementation of this method is based on: * * <ul> * <li><a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html">Regularized Beta * Function</a>. * <li><a href="http://functions.wolfram.com/06.21.10.0001.01">Regularized Beta Function</a>. * </ul> * * @param x the value. * @param a Parameter {@code a}. * @param b Parameter {@code b}. * @param epsilon When the absolute value of the nth item in the series is less than epsilon the * approximation ceases to calculate further elements in the series. * @param maxIterations Maximum number of "iterations" to complete. * @return the regularized beta function I(x, a, b) * @throws org.apache.commons.math3.exception.MaxCountExceededException if the algorithm fails to * converge. */ public static double regularizedBeta( double x, final double a, final double b, double epsilon, int maxIterations) { double ret; if (Double.isNaN(x) || Double.isNaN(a) || Double.isNaN(b) || x < 0 || x > 1 || a <= 0.0 || b <= 0.0) { ret = Double.NaN; } else if (x > (a + 1.0) / (a + b + 2.0)) { ret = 1.0 - regularizedBeta(1.0 - x, b, a, epsilon, maxIterations); } else { ContinuedFraction fraction = new ContinuedFraction() { @Override protected double getB(int n, double x) { double ret; double m; if (n % 2 == 0) { // even m = n / 2.0; ret = (m * (b - m) * x) / ((a + (2 * m) - 1) * (a + (2 * m))); } else { m = (n - 1.0) / 2.0; ret = -((a + m) * (a + b + m) * x) / ((a + (2 * m)) * (a + (2 * m) + 1.0)); } return ret; } @Override protected double getA(int n, double x) { return 1.0; } }; ret = FastMath.exp( (a * FastMath.log(x)) + (b * FastMath.log(1.0 - x)) - FastMath.log(a) - logBeta(a, b)) * 1.0 / fraction.evaluate(x, epsilon, maxIterations); } return ret; }
/** * Returns the value of log[Γ(b) / Γ(a + b)] for a ≥ 0 and b ≥ 10. Based on the <em>NSWC Library * of Mathematics Subroutines</em> double precision implementation, {@code DLGDIV}. In {@code * BetaTest.testLogGammaMinusLogGammaSum()}, this private method is accessed through reflection. * * @param a First argument. * @param b Second argument. * @return the value of {@code log(Gamma(b) / Gamma(a + b))}. * @throws NumberIsTooSmallException if {@code a < 0.0} or {@code b < 10.0}. */ private static double logGammaMinusLogGammaSum(final double a, final double b) throws NumberIsTooSmallException { if (a < 0.0) { throw new NumberIsTooSmallException(a, 0.0, true); } if (b < 10.0) { throw new NumberIsTooSmallException(b, 10.0, true); } /* * d = a + b - 0.5 */ final double d; final double w; if (a <= b) { d = b + (a - 0.5); w = deltaMinusDeltaSum(a, b); } else { d = a + (b - 0.5); w = deltaMinusDeltaSum(b, a); } final double u = d * FastMath.log1p(a / b); final double v = a * (FastMath.log(b) - 1.0); return u <= v ? (w - u) - v : (w - v) - u; }
/** * Compute the <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top"> natural * logarithm</a> of this complex number. Implements the formula: * * <pre> * <code> * log(a + bi) = ln(|a + bi|) + arg(a + bi)i * </code> * </pre> * * where ln on the right hand side is {@link java.lang.Math#log}, {@code |a + bi|} is the modulus, * {@link Complex#abs}, and {@code arg(a + bi) = }{@link java.lang.Math#atan2}(b, a). <br> * Returns {@link Complex#NaN} if either real or imaginary part of the input argument is {@code * NaN}. <br> * Infinite (or critical) values in real or imaginary parts of the input may result in infinite or * NaN values returned in parts of the result. * * <pre> * Examples: * <code> * log(1 ± INFINITY i) = INFINITY ± (π/2)i * log(INFINITY + i) = INFINITY + 0i * log(-INFINITY + i) = INFINITY + πi * log(INFINITY ± INFINITY i) = INFINITY ± (π/4)i * log(-INFINITY ± INFINITY i) = INFINITY ± (3π/4)i * log(0 + 0i) = -INFINITY + 0i * </code> * </pre> * * @return the value <code>ln this</code>, the natural logarithm of {@code this}. * @since 1.2 */ public Complex log() { if (isNaN) { return NaN; } return createComplex(FastMath.log(abs()), FastMath.atan2(imaginary, real)); }
private double onePoint(double x0, double x1, double[] point) { final IMonteCarloModel<Double, Double> mc = factory.createModel(x0, x1, point); mc.addSamples(samples); final double value = mc.getStats().value(); return FastMath.log(value); }
@Override public IComplexNumber log() { IComplexNumber result = dup(); float real = (float) result.realComponent(); float imaginary = (float) result.imaginaryComponent(); double modulus = FastMath.sqrt(real * real + imaginary * imaginary); double arg = FastMath.atan2(imaginary, real); return result.set(FastMath.log(modulus), arg); }
public static ItemType chooseOldItemType(double logParam, List<ItemType> itemTypes, double rand) { // sum of log values for each category in itemTypesUsed // log( (x + 1) / x), log-base to be given double totalWeight = FastMath.log(logParam, itemTypes.size() + 1); // x = 2 * k ^ (y - 1), where k is the log base, y is a random number between 1 and totalWeight // basically given a random number, decides which category to reuse. double scaledRand = rand * totalWeight; int index = (int) (FastMath.pow(logParam, scaledRand)) - 1; // gives a value between 0 and itemTypesUsed.size() exclusive return itemTypes.get(index); }
/** * {@inheritDoc} * * <p>Returns {@code 0} when {@code p= = 0} and {@code Double.POSITIVE_INFINITY} when {@code p == * 1}. */ @Override public double inverseCumulativeProbability(double p) throws OutOfRangeException { double ret; if (p < 0.0 || p > 1.0) { throw new OutOfRangeException(p, 0.0, 1.0); } else if (p == 1.0) { ret = Double.POSITIVE_INFINITY; } else { ret = -mean * FastMath.log(1.0 - p); } return ret; }
/** * Returns the value of log Γ(a + b) for 1 ≤ a, b ≤ 2. Based on the <em>NSWC Library of * Mathematics Subroutines</em> double precision implementation, {@code DGSMLN}. In {@code * BetaTest.testLogGammaSum()}, this private method is accessed through reflection. * * @param a First argument. * @param b Second argument. * @return the value of {@code log(Gamma(a + b))}. * @throws OutOfRangeException if {@code a} or {@code b} is lower than {@code 1.0} or greater than * {@code 2.0}. */ private static double logGammaSum(final double a, final double b) throws OutOfRangeException { if ((a < 1.0) || (a > 2.0)) { throw new OutOfRangeException(a, 1.0, 2.0); } if ((b < 1.0) || (b > 2.0)) { throw new OutOfRangeException(b, 1.0, 2.0); } final double x = (a - 1.0) + (b - 1.0); if (x <= 0.5) { return Gamma.logGamma1p(1.0 + x); } else if (x <= 1.5) { return Gamma.logGamma1p(x) + FastMath.log1p(x); } else { return Gamma.logGamma1p(x - 1.0) + FastMath.log(x * (1.0 + x)); } }
private void calculateCoherence() { LOG.info("calculating coherence scores"); coherenceScores = new double[model.numberOfTopics()]; for (int k = 0; k < model.numberOfTopics(); k++) { for (int m = 1; m < numberOfTerms; m++) { for (int n = 0; n < m; n++) { int i = term2id.get(model.topTermIds()[k][m]); int j = term2id.get(model.topTermIds()[k][n]); if (occurrenceCounts[j] > 0) { coherenceScores[k] += FastMath.log( (double) (cooccurrenceCounts[i][j] + 1d) / (double) occurrenceCounts[j]); } } } } }
/** * A part of the deviance portion of the saddle point approximation. * * <p>References: * * <ol> * <li>Catherine Loader (2000). "Fast and Accurate Computation of Binomial Probabilities.". <a * target="_blank" href="http://www.herine.net/stat/papers/dbinom.pdf"> * http://www.herine.net/stat/papers/dbinom.pdf</a> * </ol> * * @param x the x value. * @param mu the average. * @return a part of the deviance. */ static double getDeviancePart(double x, double mu) { double ret; if (FastMath.abs(x - mu) < 0.1 * (x + mu)) { double d = x - mu; double v = d / (x + mu); double s1 = v * d; double s = Double.NaN; double ej = 2.0 * x * v; v *= v; int j = 1; while (s1 != s) { s = s1; ej *= v; s1 = s + ej / ((j * 2) + 1); ++j; } ret = s1; } else { ret = x * FastMath.log(x / mu) + mu - x; } return ret; }
/** {@inheritDoc} * */ @Override public double logDensity(double x) { recomputeZ(); if (x < 0 || x > 1) { return Double.NEGATIVE_INFINITY; } else if (x == 0) { if (alpha < 1) { throw new NumberIsTooSmallException( LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA, alpha, 1, false); } return Double.NEGATIVE_INFINITY; } else if (x == 1) { if (beta < 1) { throw new NumberIsTooSmallException( LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA, beta, 1, false); } return Double.NEGATIVE_INFINITY; } else { double logX = FastMath.log(x); double log1mX = FastMath.log1p(-x); return (alpha - 1) * logX + (beta - 1) * log1mX - z; } }
/** * Compute the error of Stirling's series at the given value. * * <p>References: * * <ol> * <li>Eric W. Weisstein. "Stirling's Series." From MathWorld--A Wolfram Web Resource. <a * target="_blank" href="http://mathworld.wolfram.com/StirlingsSeries.html"> * http://mathworld.wolfram.com/StirlingsSeries.html</a> * </ol> * * @param z the value. * @return the Striling's series error. */ static double getStirlingError(double z) { double ret; if (z < 15.0) { double z2 = 2.0 * z; if (FastMath.floor(z2) == z2) { ret = EXACT_STIRLING_ERRORS[(int) z2]; } else { ret = Gamma.logGamma(z + 1.0) - (z + 0.5) * FastMath.log(z) + z - HALF_LOG_2_PI; } } else { double z2 = z * z; ret = (0.083333333333333333333 - (0.00277777777777777777778 - (0.00079365079365079365079365 - (0.000595238095238095238095238 - 0.0008417508417508417508417508 / z2) / z2) / z2) / z2) / z; } return ret; }
/** * Utility class used by various distributions to accurately compute their respective probability * mass functions. The implementation for this class is based on the Catherine Loader's <a * target="_blank" href="http://www.herine.net/stat/software/dbinom.html">dbinom</a> routines. * * <p>This class is not intended to be called directly. * * <p>References: * * <ol> * <li>Catherine Loader (2000). "Fast and Accurate Computation of Binomial Probabilities.". <a * target="_blank" href="http://www.herine.net/stat/papers/dbinom.pdf"> * http://www.herine.net/stat/papers/dbinom.pdf</a> * </ol> * * @since 2.1 * @version $Id: SaddlePointExpansion.java 1538368 2013-11-03 13:57:37Z erans $ */ final class SaddlePointExpansion { /** 1/2 * log(2 π). */ private static final double HALF_LOG_2_PI = 0.5 * FastMath.log(MathUtils.TWO_PI); /** exact Stirling expansion error for certain values. */ private static final double[] EXACT_STIRLING_ERRORS = { 0.0, /* 0.0 */ 0.1534264097200273452913848, /* 0.5 */ 0.0810614667953272582196702, /* 1.0 */ 0.0548141210519176538961390, /* 1.5 */ 0.0413406959554092940938221, /* 2.0 */ 0.03316287351993628748511048, /* 2.5 */ 0.02767792568499833914878929, /* 3.0 */ 0.02374616365629749597132920, /* 3.5 */ 0.02079067210376509311152277, /* 4.0 */ 0.01848845053267318523077934, /* 4.5 */ 0.01664469118982119216319487, /* 5.0 */ 0.01513497322191737887351255, /* 5.5 */ 0.01387612882307074799874573, /* 6.0 */ 0.01281046524292022692424986, /* 6.5 */ 0.01189670994589177009505572, /* 7.0 */ 0.01110455975820691732662991, /* 7.5 */ 0.010411265261972096497478567, /* 8.0 */ 0.009799416126158803298389475, /* 8.5 */ 0.009255462182712732917728637, /* 9.0 */ 0.008768700134139385462952823, /* 9.5 */ 0.008330563433362871256469318, /* 10.0 */ 0.007934114564314020547248100, /* 10.5 */ 0.007573675487951840794972024, /* 11.0 */ 0.007244554301320383179543912, /* 11.5 */ 0.006942840107209529865664152, /* 12.0 */ 0.006665247032707682442354394, /* 12.5 */ 0.006408994188004207068439631, /* 13.0 */ 0.006171712263039457647532867, /* 13.5 */ 0.005951370112758847735624416, /* 14.0 */ 0.005746216513010115682023589, /* 14.5 */ 0.005554733551962801371038690 /* 15.0 */ }; /** Default constructor. */ private SaddlePointExpansion() { super(); } /** * Compute the error of Stirling's series at the given value. * * <p>References: * * <ol> * <li>Eric W. Weisstein. "Stirling's Series." From MathWorld--A Wolfram Web Resource. <a * target="_blank" href="http://mathworld.wolfram.com/StirlingsSeries.html"> * http://mathworld.wolfram.com/StirlingsSeries.html</a> * </ol> * * @param z the value. * @return the Striling's series error. */ static double getStirlingError(double z) { double ret; if (z < 15.0) { double z2 = 2.0 * z; if (FastMath.floor(z2) == z2) { ret = EXACT_STIRLING_ERRORS[(int) z2]; } else { ret = Gamma.logGamma(z + 1.0) - (z + 0.5) * FastMath.log(z) + z - HALF_LOG_2_PI; } } else { double z2 = z * z; ret = (0.083333333333333333333 - (0.00277777777777777777778 - (0.00079365079365079365079365 - (0.000595238095238095238095238 - 0.0008417508417508417508417508 / z2) / z2) / z2) / z2) / z; } return ret; } /** * A part of the deviance portion of the saddle point approximation. * * <p>References: * * <ol> * <li>Catherine Loader (2000). "Fast and Accurate Computation of Binomial Probabilities.". <a * target="_blank" href="http://www.herine.net/stat/papers/dbinom.pdf"> * http://www.herine.net/stat/papers/dbinom.pdf</a> * </ol> * * @param x the x value. * @param mu the average. * @return a part of the deviance. */ static double getDeviancePart(double x, double mu) { double ret; if (FastMath.abs(x - mu) < 0.1 * (x + mu)) { double d = x - mu; double v = d / (x + mu); double s1 = v * d; double s = Double.NaN; double ej = 2.0 * x * v; v *= v; int j = 1; while (s1 != s) { s = s1; ej *= v; s1 = s + ej / ((j * 2) + 1); ++j; } ret = s1; } else { ret = x * FastMath.log(x / mu) + mu - x; } return ret; } /** * Compute the logarithm of the PMF for a binomial distribution using the saddle point expansion. * * @param x the value at which the probability is evaluated. * @param n the number of trials. * @param p the probability of success. * @param q the probability of failure (1 - p). * @return log(p(x)). */ static double logBinomialProbability(int x, int n, double p, double q) { double ret; if (x == 0) { if (p < 0.1) { ret = -getDeviancePart(n, n * q) - n * p; } else { ret = n * FastMath.log(q); } } else if (x == n) { if (q < 0.1) { ret = -getDeviancePart(n, n * p) - n * q; } else { ret = n * FastMath.log(p); } } else { ret = getStirlingError(n) - getStirlingError(x) - getStirlingError(n - x) - getDeviancePart(x, n * p) - getDeviancePart(n - x, n * q); double f = (MathUtils.TWO_PI * x * (n - x)) / n; ret = -0.5 * FastMath.log(f) + ret; } return ret; } }
/** * Returns the value of log B(p, q) for 0 ≤ x ≤ 1 and p, q > 0. Based on the <em>NSWC Library of * Mathematics Subroutines</em> implementation, {@code DBETLN}. * * @param p First argument. * @param q Second argument. * @return the value of {@code log(Beta(p, q))}, {@code NaN} if {@code p <= 0} or {@code q <= 0}. */ public static double logBeta(final double p, final double q) { if (Double.isNaN(p) || Double.isNaN(q) || (p <= 0.0) || (q <= 0.0)) { return Double.NaN; } final double a = FastMath.min(p, q); final double b = FastMath.max(p, q); if (a >= 10.0) { final double w = sumDeltaMinusDeltaSum(a, b); final double h = a / b; final double c = h / (1.0 + h); final double u = -(a - 0.5) * FastMath.log(c); final double v = b * FastMath.log1p(h); if (u <= v) { return (((-0.5 * FastMath.log(b) + HALF_LOG_TWO_PI) + w) - u) - v; } else { return (((-0.5 * FastMath.log(b) + HALF_LOG_TWO_PI) + w) - v) - u; } } else if (a > 2.0) { if (b > 1000.0) { final int n = (int) FastMath.floor(a - 1.0); double prod = 1.0; double ared = a; for (int i = 0; i < n; i++) { ared -= 1.0; prod *= ared / (1.0 + ared / b); } return (FastMath.log(prod) - n * FastMath.log(b)) + (Gamma.logGamma(ared) + logGammaMinusLogGammaSum(ared, b)); } else { double prod1 = 1.0; double ared = a; while (ared > 2.0) { ared -= 1.0; final double h = ared / b; prod1 *= h / (1.0 + h); } if (b < 10.0) { double prod2 = 1.0; double bred = b; while (bred > 2.0) { bred -= 1.0; prod2 *= bred / (ared + bred); } return FastMath.log(prod1) + FastMath.log(prod2) + (Gamma.logGamma(ared) + (Gamma.logGamma(bred) - logGammaSum(ared, bred))); } else { return FastMath.log(prod1) + Gamma.logGamma(ared) + logGammaMinusLogGammaSum(ared, b); } } } else if (a >= 1.0) { if (b > 2.0) { if (b < 10.0) { double prod = 1.0; double bred = b; while (bred > 2.0) { bred -= 1.0; prod *= bred / (a + bred); } return FastMath.log(prod) + (Gamma.logGamma(a) + (Gamma.logGamma(bred) - logGammaSum(a, bred))); } else { return Gamma.logGamma(a) + logGammaMinusLogGammaSum(a, b); } } else { return Gamma.logGamma(a) + Gamma.logGamma(b) - logGammaSum(a, b); } } else { if (b >= 10.0) { return Gamma.logGamma(a) + logGammaMinusLogGammaSum(a, b); } else { // The following command is the original NSWC implementation. // return Gamma.logGamma(a) + // (Gamma.logGamma(b) - Gamma.logGamma(a + b)); // The following command turns out to be more accurate. return FastMath.log(Gamma.gamma(a) * Gamma.gamma(b) / Gamma.gamma(a + b)); } } }
// 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); }
/* * Builtin functions with two inputs */ public double execute(double in1, double in2) throws DMLRuntimeException { switch (bFunc) { /* * Arithmetic relational operators (==, !=, <=, >=) must be instead of * <code>Double.compare()</code> due to the inconsistencies in the way * NaN and -0.0 are handled. The behavior of methods in * <code>Double</code> class are designed mainly to make Java * collections work properly. For more details, see the help for * <code>Double.equals()</code> and <code>Double.comapreTo()</code>. */ case MAX: case CUMMAX: // return (Double.compare(in1, in2) >= 0 ? in1 : in2); return (in1 >= in2 ? in1 : in2); case MIN: case CUMMIN: // return (Double.compare(in1, in2) <= 0 ? in1 : in2); return (in1 <= in2 ? in1 : in2); // *** HACK ALERT *** HACK ALERT *** HACK ALERT *** // rowIndexMax() and its siblings require comparing four values, but // the aggregation API only allows two values. So the execute() // method receives as its argument the two cell values to be // compared and performs just the value part of the comparison. We // return an integer cast down to a double, since the aggregation // API doesn't have any way to return anything but a double. The // integer returned takes on three posssible values: // // . 0 => keep the index associated with in1 // // . 1 => use the index associated with in2 // // . 2 => use whichever index is higher (tie in value) // case MAXINDEX: if (in1 == in2) { return 2; } else if (in1 > in2) { return 1; } else { // in1 < in2 return 0; } case MININDEX: if (in1 == in2) { return 2; } else if (in1 < in2) { return 1; } else { // in1 > in2 return 0; } // *** END HACK *** case LOG: // if ( in1 <= 0 ) // throw new DMLRuntimeException("Builtin.execute(): logarithm can be computed only for // non-negative numbers."); if (FASTMATH) return (FastMath.log(in1) / FastMath.log(in2)); else return (Math.log(in1) / Math.log(in2)); case LOG_NZ: if (FASTMATH) return (in1 == 0) ? 0 : (FastMath.log(in1) / FastMath.log(in2)); else return (in1 == 0) ? 0 : (Math.log(in1) / Math.log(in2)); default: throw new DMLRuntimeException("Builtin.execute(): Unknown operation: " + bFunc); } }