/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.core.stat; import java.io.Serializable; import java.util.HashMap; import edu.yu.einstein.genplay.exception.ExceptionManager; import edu.yu.einstein.genplay.exception.exceptions.InvalidFactorialParameterException; import edu.yu.einstein.genplay.exception.exceptions.InvalidLambdaPoissonParameterException; /** * MyMathClass * This class gather some methods to calculate Poisson values. * These methods are developed for IslandFinder class. * @author Nicolas Fourel */ public class Poisson implements Serializable { private static final long serialVersionUID = 256395258875515443L; //Attribute to store Poisson values with parameter k as index, lambda on first double array position and the value on the second position private volatile static HashMap<Integer, HashMap<Double, Double>> poissonStorage = new HashMap<Integer, HashMap<Double, Double>>(); /** * logPoisson method * Calculate the Poisson value logarithm with Poisson parameters * * @param lambda lambda Poisson parameter * @param k k Poisson parameter * @return Poisson value * @throws InvalidLambdaPoissonParameterException * @throws InvalidFactorialParameterException */ public static double logPoisson (double lambda, int k) throws InvalidLambdaPoissonParameterException, InvalidFactorialParameterException { double result; if (lambda <= 0){ throw new InvalidLambdaPoissonParameterException(); } else { double exist = getPoissonValue(lambda, k); if (exist != -1.0){ result = exist; } else { double res1 = Math.log10(Math.exp(-lambda)); double res2 = k * Math.log10(lambda); double res3 = Factorial.logFactorial(k); result = (res1 + res2) - res3; setPoissonValue(lambda, k, result); } } return result; } /** * poisson method * Calculate the Poisson value with Poisson parameters * * @param lambda lambda Poisson parameter * @param k k Poisson parameter * @return Poisson value * @throws InvalidLambdaPoissonParameterException * @throws InvalidFactorialParameterException */ public static double poisson (double lambda, int k) throws InvalidLambdaPoissonParameterException, InvalidFactorialParameterException { return MathFunctions.unlogValue(logPoisson(lambda, k)); } /** * getPoissonValue method * This method allow to get a Poisson value if it is stored * It need to know the lambda and k Poisson parameters * * @param lambda lambda Poisson parameter * @param k k Poisson parameter * @return Poisson value if it is stored or -1.0 */ private static double getPoissonValue (double lambda, int k) { double result = -1.0; if (poissonStorage.containsKey(k)){ if (poissonStorage.get(k).containsKey(lambda)){ try { result = poissonStorage.get(k).get(lambda); } catch (Exception e) { result = -1.0; System.out.println("getPoissonValue error; lambda: " + lambda + "; k: " + k); ExceptionManager.getInstance().caughtException(e); } } } return result; } /** * setPoissonValue method * This method allow to store a Poisson value in the HashMap * * @param lambda lambda Poisson parameter * @param k k Poisson parameter * @param value the Poisson value calculated with lambda and k values */ private static void setPoissonValue (double lambda, int k, double value) { if (!poissonStorage.containsKey(k) | (poissonStorage.get(k)==null)){ poissonStorage.put(k, new HashMap<Double, Double>()); } try{ poissonStorage.get(k); poissonStorage.get(k).put(lambda , value); } catch (Exception e) { ExceptionManager.getInstance().caughtException(e); } } }