package org.opensha2.mfd; import java.awt.geom.Point2D; /** * This class represents a Gaussian magnitude-frequency distribution (MFD). It's * standard properties are mean and standard deviation, and it may optionally be * truncated at some number of standard deviations (one or two sided). Trucation * levels are rounded to the nearest point, and given non-zero rates (zeros are * above and below these points). The mean can be any value (it doesn't have to * exactly equal one of the descrete x-axis values). <br/><br/> This MFD does * not permit independent setting of values. * * floats() always returns false. * * @author Nitin Gupta (Aug,8,2002) * @author Ned Field (Nov, 21, 2002) * @author Peter Powers */ class GaussianMfd extends IncrementalMfd { public static String NAME = "Gaussian Dist"; private double mean = Double.NaN; private double stdDev = Double.NaN; // TODO there were a billion constructors in here; really should use a // builder /** * The # of stdDev (from Mean) where truncation occurs */ private double truncLevel = Double.NaN; /** * truncType = 0 for none, = 1 for upper only, and = 2 for double sided */ private int truncType = 0; /** * todo constructors All the constructors call the function computeRates which * sets up the rate as Y-axis values based on the X-axis values provided in * the form of min,num,delta of mag. */ /** * constructor * @param min - minimum mag of distribution * @param num - number of points in distribution * @param delta - discretization interval */ // public GaussianMfd(double min,int num,double delta) { // super(min,num,delta); // // } /** * Constructor * @param min - minimum mag of distribution * @param max - maximum mag of distribution * @param num - number of points in distribution */ public GaussianMfd(double min, double max, int num, boolean floats) { super(min, max, num, floats); } /** * Constructor: This applies no trucation. * @param min - minimum mag of distribution * @param max - maximum mag of distribution * @param num - number of points in distribution * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totMoRate - the total moment rate */ // public GaussianMfd(double min,double max,int num,double mean,double // stdDev, // double totMoRate) { // super(min,max,num); // this.mean=mean; // this.stdDev=stdDev; // this.truncType = 0; // calculateRelativeRates(); // scaleToTotalMomentRate(totMoRate); // } /** * Constructor: This applies no trucation. * @param min - minimum mag of distribution * @param num - number of points in distribution * @param delta - discretization interval * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totMoRate - the total moment rate */ // public GaussianMfd(double min,int num,double delta,double mean,double // stdDev, // double totMoRate) { // super(min,num,delta); // this.mean=mean; // this.stdDev=stdDev; // this.truncType = 0; // calculateRelativeRates(); // scaleToTotalMomentRate(totMoRate); // } /** * Constructor: This applies whatever truncation is specified. * @param min - minimum mag of distribution * @param num - number of points in distribution * @param delta - discretization interval * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totMoRate - the total moment rate * @param truncLevel - in units of stdDev from the mean * @param truncType - 0 for none; 1 for upper only; and 2 for upper and lower */ // public GaussianMfd(double min,int num,double delta,double mean,double // stdDev, // double totMoRate,double truncLevel,int truncType) // { // super(min,num,delta); // this.mean=mean; // this.stdDev=stdDev; // this.truncLevel=truncLevel; // this.truncType = truncType; // calculateRelativeRates(); // scaleToTotalMomentRate(totMoRate); // } /** * Constructor: This applies whatever truncation is specified. * @param min - minimum mag of distribution * @param max - maximum mag of distribution * @param num - number of points in distribution * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totMoRate - the total moment rate * @param truncLevel - in units of stdDev from the mean * @param truncType - 0 for none; 1 for upper only; and 2 for upper and lower */ // public GaussianMfd(double min,double max,int num,double mean,double // stdDev, // double totMoRate,double truncLevel,int truncType) { // super(min,max,num); // this.mean=mean; // this.stdDev=stdDev; // this.truncLevel=truncLevel; // this.truncType = truncType; // calculateRelativeRates(); // scaleToTotalMomentRate(totMoRate); // } /** * This updates the distribution, applying no truncation (truncType set to 0) * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totMoRate - the total moment rate */ public void setAllButCumRate(double mean, double stdDev, double totMoRate) { this.mean = mean; this.stdDev = stdDev; this.truncType = 0; calculateRelativeRates(); scaleToTotalMomentRate(totMoRate); } /** * This updates the distribution, applying the truncation specified * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totMoRate - the total moment rate * @param truncLevel - in units of stdDev from the mean * @param truncType - 0 for none; 1 for upper only; and 2 for upper and lower */ public void setAllButCumRate(double mean, double stdDev, double totMoRate, double truncLevel, int truncType) { this.mean = mean; this.stdDev = stdDev; this.truncLevel = truncLevel; this.truncType = truncType; calculateRelativeRates(); scaleToTotalMomentRate(totMoRate); } /** * This updates the distribution, applying no truncation (truncType set to 0) * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totCumRate - the total cumulative rate (at the lowest magnitude) */ public void setAllButTotMoRate(double mean, double stdDev, double totCumRate) { this.mean = mean; this.stdDev = stdDev; this.truncType = 0; calculateRelativeRates(); scaleToCumRate(0, totCumRate); } /** * This updates the distribution, applying the truncation specified * @param mean - the mean maginitude of the gaussian distribution * @param stdDev - the standard deviation * @param totCumRate - the total cumulative rate (at the lowest magnitude) * @param truncLevel - in units of stdDev from the mean * @param truncType - 0 for none; 1 for upper only; and 2 for upper and lower */ public void setAllButTotMoRate(double mean, double stdDev, double totCumRate, double truncLevel, int truncType) { this.mean = mean; this.stdDev = stdDev; this.truncLevel = truncLevel; this.truncType = truncType; calculateRelativeRates(); scaleToCumRate(0, totCumRate); } /** * get the mean for this distribution */ public double getMean() { return this.mean; } /** * get the stdDev for this distribution */ public double getStdDev() { return this.stdDev; } /** * get the truncLevel which specifies the # of stdDev(from Mean) where the * dist. cuts to zero. */ public double getTruncLevel() { return this.truncLevel; } /** * get the truncType which specifies whether it is no truncation or 1 sided or * 2 sided truncation */ public int getTruncType() { return this.truncType; } /** * returns the name of the class */ @Override public String getDefaultName() { return NAME; } /** * return the info stored in the class in form of a String */ @Override public String getDefaultInfo() { return "minMag=" + minX + "; maxMag=" + maxX + "; numMag=" + num + "; mean=" + mean + "; stdDev=" + stdDev + "; totMoRate=" + (float) getTotalMomentRate() + "; totCumRate=" + (float) this.getCumRate(0) + "; truncType=" + truncType + "; truncLevel=" + truncLevel; } /** * Overriden to prevent value setting. * @throws UnsupportedOperationException */ @Override public void set(Point2D point) { throw new UnsupportedOperationException(); } /** * Overriden to prevent value setting. * @throws UnsupportedOperationException */ @Override public void set(double x, double y) { throw new UnsupportedOperationException(); } /** * Overriden to prevent value setting. * @throws UnsupportedOperationException */ @Override public void set(int index, double y) { throw new UnsupportedOperationException(); } /** * This functions call the method set(int,double) in the EvenlyDiscretized * class to set the y-axis values based on the x-axis data provided by the * user,in form of the mag,mean stdDev. it then sets up the rate as the Y-axis * values. Based on the truncType it sets the rate to be zero after setting * the truncLevel(which specifies the # of stdDev from mean where dist. cut to * zero */ private void calculateRelativeRates() { if (stdDev != 0) { for (int i = 0; i < num; ++i) { double mag = getX(i); double rate = Math.exp(-Math.pow((mag - mean), 2) / (2 * stdDev * stdDev)); super.set(i, rate); } if (truncType != 0) { double magUpper = mean + truncLevel * stdDev; int index = Math.round((float) ((magUpper - minX) / delta)); // Make this the last non-zero rate by adding one in the next // loop for (int i = index + 1; i >= 0 && i < num; i++) { super.set(i, 0); } } if (truncType == 2) { double magLower = this.mean - this.truncLevel * this.stdDev; int index = Math.round((float) ((magLower - this.minX) / this.delta)); // Make this the first non-zero rate by the <index in the next // loop for (int i = 0; i < index && i < num; i++) { super.set(i, 0); } } } else { for (int i = 0; i < num; ++i) { super.set(i, 0); } try { super.set(mean, 1.0); } catch (RuntimeException e) { throw new RuntimeException( "If sigma=0, then mean must equal one of the discrete X-axis magnitudes"); } } } }