Author: [log in to unmask]
Date: Thu Dec 4 17:24:25 2014
New Revision: 1649
Log:
Add implementation of landau distribution (in my user area for now but will be moved).
Added:
java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java
java/trunk/users/src/main/java/org/hps/users/jeremym/LandauPdf.java
java/trunk/users/src/test/java/org/hps/users/jeremym/LandauTest.java
Added: java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java Thu Dec 4 17:24:25 2014
@@ -0,0 +1,50 @@
+package org.hps.users.jeremym;
+
+import hep.aida.ref.function.AbstractIFunction;
+
+public class LandauFunction extends AbstractIFunction {
+
+ LandauPdf landauPdf = new LandauPdf();
+
+ public LandauFunction() {
+ this("");
+ }
+
+ public LandauFunction(String title) {
+
+ super();
+
+ variableNames = new String[1];
+ variableNames[0] = "x0";
+
+ parameterNames = new String[2];
+ parameterNames[0] = "mean";
+ parameterNames[1] = "sigma";
+
+ init(title);
+ }
+
+ @Override
+ public double value(double[] v) {
+ return landauPdf.getValue(v[0]);
+ }
+
+ @Override
+ public void setParameter(String key, double value) throws IllegalArgumentException {
+ super.setParameter(key, value);
+ if (key.equals("mean")) {
+ System.out.println("set mean = " + value);
+ landauPdf.setMean(value);
+ } else if (key.equals("sigma")) {
+ System.out.println("set sigma = " + value);
+ landauPdf.setSigma(value);
+ }
+ }
+
+ @Override
+ public void setParameters(double[] parameters) throws IllegalArgumentException {
+ super.setParameters(parameters);
+ landauPdf.setMean(parameters[0]);
+ landauPdf.setSigma(parameters[1]);
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/jeremym/LandauPdf.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/jeremym/LandauPdf.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/jeremym/LandauPdf.java Thu Dec 4 17:24:25 2014
@@ -0,0 +1,98 @@
+package org.hps.users.jeremym;
+
+
+/**
+ * <p>
+ * Landau Probability Distribution
+ * <p>
+ * Copied from math/mathcore/src/ProbFuncMathCore.cxx::landau_pdf in ROOT (version 5.34.18).
+ */
+public class LandauPdf {
+
+ static final double[] p1 = { 0.4259894875, -0.1249762550, 0.03984243700, -0.006298287635, 0.001511162253 };
+ static final double[] q1 = { 1.0, -0.3388260629, 0.09594393323, -0.01608042283, 0.003778942063 };
+
+ static final double[] p2 = { 0.1788541609, 0.1173957403, 0.01488850518, -0.001394989411, 0.0001283617211 };
+ static final double[] q2 = { 1.0, 0.7428795082, 0.3153932961, 0.06694219548, 0.008790609714 };
+
+ static final double[] p3 = { 0.1788544503, 0.09359161662, 0.006325387654, 0.00006611667319, -0.000002031049101 };
+ static final double[] q3 = { 1.0, 0.6097809921, 0.2560616665, 0.04746722384, 0.006957301675 };
+
+ static final double[] p4 = { 0.9874054407, 118.6723273, 849.2794360, -743.7792444, 427.0262186 };
+ static final double[] q4 = { 1.0, 106.8615961, 337.6496214, 2016.712389, 1597.063511 };
+
+ static final double[] p5 = { 1.003675074, 167.5702434, 4789.711289, 21217.86767, -22324.94910 };
+ static final double[] q5 = { 1.0, 156.9424537, 3745.310488, 9834.698876, 66924.28357 };
+
+ static final double[] p6 = { 1.000827619, 664.9143136, 62972.92665, 475554.6998, -5743609.109 };
+ static final double[] q6 = { 1.0, 651.4101098, 56974.73333, 165917.4725, -2815759.939 };
+
+ static final double[] a1 = { 0.04166666667, -0.01996527778, 0.02709538966 };
+ static final double[] a2 = { -1.845568670, -4.284640743 };
+
+ protected double sigma = 0;
+ protected double mean = 0;
+
+ public LandauPdf(double mean, double sigma) {
+ this.mean = mean;
+ this.sigma = sigma;
+ }
+
+ public LandauPdf() {
+ }
+
+ public double getValue(double x) {
+ return getValue(x, mean, sigma);
+ }
+
+ public void setSigma(double sigma) {
+ this.sigma = sigma;
+ }
+
+ public void setMean(double mean) {
+ this.mean = mean;
+ }
+
+ /**
+ *
+ * @param x The free variable.
+ * @param sigma The sigma (width) of the distribution.
+ * @param mean The mean of the distribution.
+ * @return The value of the Landau distribution at x.
+ */
+ static double getValue(double x, double mean, double sigma) {
+ // LANDAU pdf : algorithm from CERNLIB G110 denlan same algorithm is used in GSL
+ if (sigma <= 0)
+ return 0;
+ double v = (x - mean) / sigma;
+ double u, ue, us, denlan;
+ if (v < -5.5) {
+ u = Math.exp(v + 1.0);
+ if (u < 1e-10)
+ return 0.0;
+ ue = Math.exp(-1 / u);
+ us = Math.sqrt(u);
+ denlan = 0.3989422803 * (ue / us) * (1 + (a1[0] + (a1[1] + a1[2] * u) * u) * u);
+ } else if (v < -1) {
+ u = Math.exp(-v - 1);
+ denlan = Math.exp(-u) * Math.sqrt(u) * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) / (q1[0] + (q1[1] + (q1[2] + (q1[3] + q1[4] * v) * v) * v) * v);
+ } else if (v < 1) {
+ denlan = (p2[0] + (p2[1] + (p2[2] + (p2[3] + p2[4] * v) * v) * v) * v) / (q2[0] + (q2[1] + (q2[2] + (q2[3] + q2[4] * v) * v) * v) * v);
+ } else if (v < 5) {
+ denlan = (p3[0] + (p3[1] + (p3[2] + (p3[3] + p3[4] * v) * v) * v) * v) / (q3[0] + (q3[1] + (q3[2] + (q3[3] + q3[4] * v) * v) * v) * v);
+ } else if (v < 12) {
+ u = 1 / v;
+ denlan = u * u * (p4[0] + (p4[1] + (p4[2] + (p4[3] + p4[4] * u) * u) * u) * u) / (q4[0] + (q4[1] + (q4[2] + (q4[3] + q4[4] * u) * u) * u) * u);
+ } else if (v < 50) {
+ u = 1 / v;
+ denlan = u * u * (p5[0] + (p5[1] + (p5[2] + (p5[3] + p5[4] * u) * u) * u) * u) / (q5[0] + (q5[1] + (q5[2] + (q5[3] + q5[4] * u) * u) * u) * u);
+ } else if (v < 300) {
+ u = 1 / v;
+ denlan = u * u * (p6[0] + (p6[1] + (p6[2] + (p6[3] + p6[4] * u) * u) * u) * u) / (q6[0] + (q6[1] + (q6[2] + (q6[3] + q6[4] * u) * u) * u) * u);
+ } else {
+ u = 1 / (v - v * Math.log(v) / (v + 1));
+ denlan = u * u * (1 + (a2[0] + a2[1] * u) * u);
+ }
+ return denlan / sigma;
+ }
+}
Added: java/trunk/users/src/test/java/org/hps/users/jeremym/LandauTest.java
=============================================================================
--- java/trunk/users/src/test/java/org/hps/users/jeremym/LandauTest.java (added)
+++ java/trunk/users/src/test/java/org/hps/users/jeremym/LandauTest.java Thu Dec 4 17:24:25 2014
@@ -0,0 +1,117 @@
+package org.hps.users.jeremym;
+
+import hep.aida.IFitFactory;
+import hep.aida.IFitResult;
+import hep.aida.IFitter;
+import hep.aida.IFunction;
+import hep.aida.IPlotter;
+import hep.aida.IProfile1D;
+import hep.aida.ref.fitter.FitResult;
+
+import java.io.IOException;
+import java.util.Random;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import junit.framework.TestCase;
+
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * <p>
+ * Test of Landau distribution functions ported from C++ and originally defined in the file
+ * <p>
+ * mathcore/src/ProbFuncMathCore.cxx
+ * <p>
+ * within ROOT (version 5.34.18).
+ */
+public class LandauTest extends TestCase {
+
+ static double[] p1 = { 0.4259894875, -0.1249762550, 0.03984243700, -0.006298287635, 0.001511162253 };
+ static double[] q1 = { 1.0, -0.3388260629, 0.09594393323, -0.01608042283, 0.003778942063 };
+
+ static double[] p2 = { 0.1788541609, 0.1173957403, 0.01488850518, -0.001394989411, 0.0001283617211 };
+ static double[] q2 = { 1.0, 0.7428795082, 0.3153932961, 0.06694219548, 0.008790609714 };
+
+ static double[] p3 = { 0.1788544503, 0.09359161662, 0.006325387654, 0.00006611667319, -0.000002031049101 };
+ static double[] q3 = { 1.0, 0.6097809921, 0.2560616665, 0.04746722384, 0.006957301675 };
+
+ static double[] p4 = { 0.9874054407, 118.6723273, 849.2794360, -743.7792444, 427.0262186 };
+ static double[] q4 = { 1.0, 106.8615961, 337.6496214, 2016.712389, 1597.063511 };
+
+ static double[] p5 = { 1.003675074, 167.5702434, 4789.711289, 21217.86767, -22324.94910 };
+ static double[] q5 = { 1.0, 156.9424537, 3745.310488, 9834.698876, 66924.28357 };
+
+ static double[] p6 = { 1.000827619, 664.9143136, 62972.92665, 475554.6998, -5743609.109 };
+ static double[] q6 = { 1.0, 651.4101098, 56974.73333, 165917.4725, -2815759.939 };
+
+ static double[] a1 = { 0.04166666667, -0.01996527778, 0.02709538966 };
+ static double[] a2 = { -1.845568670, -4.284640743 };
+
+ public void testLandauDistribution() {
+ AIDA aida = AIDA.defaultInstance();
+ double mean = 10.0;
+ double sigma = 2.0;
+
+ LandauPdf landauPdf = new LandauPdf();
+ landauPdf.setMean(mean);
+ landauPdf.setSigma(sigma);
+
+ Random random = new Random();
+
+ IProfile1D profile = aida.profile1D("Landau P1D", 50, -0.5, 49.5);
+ for (int i = 0; i < 100; i++) {
+ for (int x = 0; x < 2000; x++) {
+ double xVal = x / 10;
+ double landauVal = landauPdf.getValue(xVal);
+ double smearedLandau = landauVal * (1.0 + 0.1 * random.nextGaussian());
+ profile.fill(xVal, smearedLandau);
+ }
+ }
+
+ IPlotter plotter = aida.analysisFactory().createPlotterFactory().create();
+ plotter.createRegion();
+ plotter.region(0).plot(profile);
+
+ LandauFunction landau = new LandauFunction();
+ //IFunctionFactory functionFactory = aida.analysisFactory().createFunctionFactory(null);
+ IFitFactory fitFactory = aida.analysisFactory().createFitFactory();
+ //functionFactory.catalog().add("landau", landau);
+
+ landau.setParameter("sigma", sigma + 0.1);
+ landau.setParameter("mean", mean + 0.1);
+
+ IFitter fitter = fitFactory.createFitter();
+
+ Logger minuitLogger = Logger.getLogger("org.freehep.math.minuit");
+ minuitLogger.setLevel(Level.ALL);
+ minuitLogger.info("minuit logger test");
+
+ IFitResult fitResult = fitter.fit(profile, landau);
+
+ IFunction fittedFunction = fitResult.fittedFunction();
+
+ plotter.region(0).plot(fittedFunction);
+
+ System.out.println();
+ System.out.println("fitted parameters");
+ for (String fittedParameterName : fitResult.fittedParameterNames()) {
+ System.out.println(fittedParameterName + " = " + fitResult.fittedParameter(fittedParameterName));
+ }
+ System.out.println("fit status = " + fitResult.fitStatus());
+
+ System.out.println();
+ System.out.println("fitted function");
+ for (String parameterName : fittedFunction.parameterNames()) {
+ System.out.println(parameterName + " = " + fittedFunction.parameter(parameterName));
+ }
+
+ ((FitResult)fitResult).printResult();
+
+ try {
+ plotter.writeToFile("Landau.png");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
|