/* Copyright (C) 2001 Kyle Siegrist, Dawn Duehring 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package distributions; /**This class creates the n-fold convolution of a given distribution*/ public class Convolution extends Distribution{ private Distribution distribution; private int power; private double[][] pdf; /**This general constructor: creates a new convolution distribution corresponding to a specified distribution and convolution power*/ public Convolution(Distribution d, int n){ setParameters(d, n); } /**This defalut constructor creates a new convolution distribution corrrepsonding to the uniform distribution on (0,1), with convolution power 5.*/ public Convolution(){ this(new ContinuousUniformDistribution(0, 1), 5); } /**This method sets the parameters: the distribution and convolution power. The method computes and store pdf values*/ public void setParameters(Distribution d, int n){ //Correct for invalid parameters if (n < 1) n = 1; distribution = d; power = n; Domain domain = distribution.getDomain(); double l = domain.getLowerValue(), u = domain.getUpperValue(), w = domain.getWidth(), p, dx; int t = distribution.getType(); if (t == DISCRETE) dx = 1; else dx = w; super.setParameters(power * l, power * u, w, t); int m = domain.getSize(); pdf = new double[power][]; for (int k = 0; k < n; k++) pdf[k] = new double[(k + 1) * m - k]; for (int j = 0; j < m; j++) pdf[0][j] = distribution.getDensity(domain.getValue(j)); for (int k = 1; k < n; k++){ for (int j = 0; j < (k + 1) * m - k; j++){ p = 0; for (int i = Math.max(0, j - m + 1); i < Math.min(j+1, k * m - k + 1); i++){ p = p + pdf[k - 1][i] * pdf[0][j - i]; } pdf[k][j] = p; } } } /**Density function*/ public double getDensity(double x){ return pdf[power - 1][getDomain().getIndex(x)]; } /**Mean*/ public double getMean(){ return power * distribution.getMean(); } /**Variance*/ public double getVariance(){ return power * distribution.getVariance(); } /**Simulate a value from the distribution*/ public double simulate(){ double sum = 0; for (int i = 0; i < power; i++) sum = sum + distribution.simulate(); return sum; } /**This method sets the convolution power.*/ public void setPower(int n){ setParameters(distribution, n); } /**This method returns the convolution power.*/ public int getPower(){ return power; } /**This method sets the distribution.*/ public void setDistribution(Distribution d){ setParameters(d, power); } /**This method returns the distribution.*/ public Distribution getDistribution(){ return distribution; } }