Java tutorial
/** * Copyright 2011 Cloudera Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cloudera.science.pig; import java.io.IOException; import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException; import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.integration.SimpsonIntegrator; import org.apache.commons.math.analysis.integration.UnivariateRealIntegrator; import org.apache.commons.math.analysis.solvers.BrentSolver; import org.apache.commons.math.distribution.GammaDistribution; import org.apache.commons.math.distribution.GammaDistributionImpl; import org.apache.pig.EvalFunc; import org.apache.pig.data.Tuple; import com.cloudera.science.mgps.NFunction; import com.cloudera.science.mgps.QFunction; public class EBCI extends EvalFunc<Double> { private static class PiFunction implements UnivariateRealFunction { private final double p; private final GammaDistribution g1; private final GammaDistribution g2; public PiFunction(double p, GammaDistribution g1, GammaDistribution g2) { this.p = p; this.g1 = g1; this.g2 = g2; } public double value(double lambda) throws FunctionEvaluationException { return p * g1.density(lambda) + (1.0 - p) * g2.density(lambda); } } private static class PiFunctionIntegral implements DifferentiableUnivariateRealFunction { private final PiFunction pi; private final double target; private final UnivariateRealIntegrator integrator; public PiFunctionIntegral(PiFunction pi, double target) { this.pi = pi; this.target = target; this.integrator = new SimpsonIntegrator(); } public double value(double lambda) throws FunctionEvaluationException { try { if (lambda == 0.0) { return -target; } return integrator.integrate(pi, 0.0, lambda) - target; } catch (ConvergenceException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (Exception e) { throw new RuntimeException("lambda-" + lambda, e); } return Double.POSITIVE_INFINITY; } public UnivariateRealFunction derivative() { return pi; } } private final double target; private final double alpha1; private final double beta1; private final double alpha2; private final double beta2; private final QFunction q; public EBCI(String target, String alpha1, String beta1, String alpha2, String beta2, String p) { this(Double.valueOf(target), Double.valueOf(alpha1), Double.valueOf(beta1), Double.valueOf(alpha2), Double.valueOf(beta2), Double.valueOf(p)); } public EBCI(double target, double alpha1, double beta1, double alpha2, double beta2, double p) { this.target = target; this.alpha1 = alpha1; this.beta1 = beta1; this.alpha2 = alpha2; this.beta2 = beta2; this.q = new QFunction(new NFunction(alpha1, beta1), new NFunction(alpha2, beta2), p); } public double eval(int n, double e) { GammaDistribution g1 = new GammaDistributionImpl(alpha1 + n, beta1 + e); GammaDistribution g2 = new GammaDistributionImpl(alpha2 + n, beta2 + e); PiFunction pi = new PiFunction(q.eval(n, e), g1, g2); PiFunctionIntegral ipi = new PiFunctionIntegral(pi, target); try { return (new BrentSolver()).solve(ipi, 0.0, 10.0, 0.01); } catch (ConvergenceException e1) { e1.printStackTrace(); } catch (FunctionEvaluationException e1) { e1.printStackTrace(); } catch (RuntimeException e1) { //MathRuntimeException function values at endpoints do not have different signs e1.printStackTrace(); } return -1.0; } @Override public Double exec(Tuple input) throws IOException { int n = ((Number) input.get(0)).intValue(); double e = ((Number) input.get(1)).doubleValue(); return eval(n, e); } }