org.opensha.sha.magdist.IncrementalMagFreqDist.java Source code

Java tutorial

Introduction

Here is the source code for org.opensha.sha.magdist.IncrementalMagFreqDist.java

Source

/*******************************************************************************
 * Copyright 2009 OpenSHA.org in partnership with
 * the Southern California Earthquake Center (SCEC, http://www.scec.org)
 * at the University of Southern California and the UnitedStates Geological
 * Survey (USGS; http://www.usgs.gov)
 * 
 * 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 org.opensha.sha.magdist;

import org.apache.commons.math3.stat.regression.SimpleRegression;
import org.opensha.commons.data.function.EvenlyDiscretizedFunc;
import org.opensha.commons.eq.MagUtils;
import org.opensha.commons.exceptions.InvalidRangeException;

/**
 * <p>Title:IncrementalMagFreqDist </p>
 * <p>Description:This class give the rate of earthquakes (number per year) in succesion</p>
 *
 * @author : Nitin Gupta Date:July 26,2002
 * @version 1.0
 */

public class IncrementalMagFreqDist extends EvenlyDiscretizedFunc
        implements IncrementalMagFreqDistAPI, java.io.Serializable {

    //for Debug purposes
    private boolean D = false;

    protected String defaultInfo;
    protected String defaultName;

    /**
     * todo constructors
     * @param min
     * @param num
     * @param delta
     * using the parameters we call the parent class constructors to initialise the parent class variables
     */
    public IncrementalMagFreqDist(double min, int num, double delta) throws InvalidRangeException {
        super(min, num, delta);
        setTolerance(delta / 1000000);
    }

    /**
     * todo constructors
     * @param min
     * @param max
     * @param num
     * using the min, max and num we calculate the delta
     */
    public IncrementalMagFreqDist(double min, double max, int num) throws InvalidRangeException {
        super(min, max, num);
        setTolerance(delta / 1000000);
    }

    /**
     * This function finds IncrRate for the given magnitude
     * @param mag
     * @return
     */
    public double getIncrRate(double mag) {
        int xIndex = getXIndex(mag);
        return getIncrRate(xIndex);
    }

    /**
     * This function finds the IncrRate at the given index
     * @param index
     * @return
     */
    public double getIncrRate(int index) {
        return getY(index);
    }

    /**
     * This function finds the cumulative Rate at a specified magnitude (the rate greater than
    * and equal to that mag)
     * @param mag
     * @return
     */
    public double getCumRate(double mag) {
        return getCumRate(getXIndex(mag));
    }

    /**
     * This function finds the cumulative Rate at a specified index  (the rate greater than
     * and equal to that index)
     * @param index
     * @return
     */

    public double getCumRate(int index) {
        double sum = 0.0;
        for (int i = index; i < num; ++i)
            sum += getIncrRate(i);
        return sum;
    }

    /**
     * This function finds the moment Rate at a specified magnitude
     * @param mag
     * @return
     */

    public double getMomentRate(double mag) {
        return getIncrRate(mag) * MagUtils.magToMoment(mag);
    }

    /**
     * This function finds the moment Rate at a specified index
     * @param index
     * @return
     */

    public double getMomentRate(int index) {
        return getIncrRate(index) * MagUtils.magToMoment(getX(index));
    }

    /**
     * This function return the sum of all the moment rates as a double variable
     * @return
     */

    public double getTotalMomentRate() {
        double sum = 0.0;
        for (int i = 0; i < num; ++i)
            sum += getMomentRate(i);
        return sum;
    }

    /**
     * This function returns the sum of all the incremental rate as the double varibale
     * @return
     */

    public double getTotalIncrRate() {
        double sum = 0.0;
        for (int i = 0; i < num; ++i)
            sum += getIncrRate(i);
        return sum;
    }

    /**
     * This function normalises the values of all the Incremental rate at each point, by dividing each one
     * by the totalIncrRate, so that after normalization the sum addition of all incremental rate at each point
     * comes to be 1.
     */

    public void normalizeByTotalRate() {
        double totalIncrRate = getTotalIncrRate();
        for (int i = 0; i < num; ++i) {
            double newRate = getIncrRate(i) / totalIncrRate;
            super.set(i, newRate);
        }
    }

    /**
     * This returns the object of the class EvenlyDiscretizedFunc which contains all the points
     * with Cum Rate Distribution (the rate greater than and equal to each magnitude)
     * @return
     */

    public EvenlyDiscretizedFunc getCumRateDist() {
        EvenlyDiscretizedFunc cumRateDist = new EvenlyDiscretizedFunc(minX, num, delta);
        double sum = 0.0;
        for (int i = num - 1; i >= 0; --i) {
            sum += getIncrRate(i);
            cumRateDist.set(i, sum);
        }
        cumRateDist.setInfo(this.getInfo());
        cumRateDist.setName(this.getName());
        return cumRateDist;
    }

    /**
     * This returns the object of the class EvenlyDiscretizedFunc which contains all the points
     * with Cum Rate Distribution (the rate greater than and equal to each magnitude).
     * It differs from getCumRateDist() in the X Values because the values are offset
     * by delta/2 in the CumDist returned by this method.
     * 
     * @return
     */

    public EvenlyDiscretizedFunc getCumRateDistWithOffset() {
        EvenlyDiscretizedFunc cumRateDist = new EvenlyDiscretizedFunc(minX - delta / 2, num, delta);
        double sum = 0.0;
        for (int i = num - 1; i >= 0; --i) {
            sum += getIncrRate(i);
            cumRateDist.set(i, sum);
        }
        cumRateDist.setInfo(this.getInfo());
        cumRateDist.setName(this.getName());
        return cumRateDist;
    }

    /**
     * This returns the object of the class EvenlyDiscretizedFunc which contains all the points
     * with Moment Rate Distribution
     * @return
     */

    public EvenlyDiscretizedFunc getMomentRateDist() {
        EvenlyDiscretizedFunc momentRateDist = new EvenlyDiscretizedFunc(minX, num, delta);
        for (int i = num - 1; i >= 0; --i) {
            momentRateDist.set(i, getMomentRate(i));
        }
        momentRateDist.setInfo(this.getInfo());
        momentRateDist.setName(this.getName());
        return momentRateDist;
    }

    /**
     * This returns the object of the class EvenlyDiscretizedFunc which contains cumulative
     * Moment Rate (the total moment rate for all points greater than and equal to each mag)
     * @return
     */
    public EvenlyDiscretizedFunc getCumMomentRateDist() {
        EvenlyDiscretizedFunc momentRateDist = new EvenlyDiscretizedFunc(minX, num, delta);
        double totMoRate = 0;
        for (int i = num - 1; i >= 0; --i) {
            totMoRate += getMomentRate(i);
            momentRateDist.set(i, totMoRate);
        }
        momentRateDist.setInfo(this.getInfo());
        momentRateDist.setName(this.getName());
        return momentRateDist;
    }

    /**
     * Using this function each data point is scaled to ratio of specified newTotalMomentRate
     * and oldTotalMomentRate.
     * @param newTotMoRate
     */

    public void scaleToTotalMomentRate(double newTotMoRate) {
        double oldTotMoRate = getTotalMomentRate();
        if (D)
            System.out.println("old Mo. Rate = " + oldTotMoRate);
        if (D)
            System.out.println("target Mo. Rate = " + newTotMoRate);
        double scaleRate = newTotMoRate / oldTotMoRate;
        for (int i = 0; i < num; ++i) {
            super.set(i, scaleRate * getIncrRate(i));
        }
        if (D)
            System.out.println("actual Mo. Rate = " + getTotalMomentRate());

    }

    /**
     * Using this function each data point is scaled to the ratio of the CumRate at a given
     * magnitude and the specified rate.
     * @param mag
     * @param rate
     */

    public void scaleToCumRate(double mag, double rate) {
        int index = getXIndex(mag);
        scaleToCumRate(index, rate);
    }

    /**
     * Using this function each data point is scaled to the ratio of the CumRate at a given
     * index and the specified rate
     * @param index
     * @param rate
     */

    public void scaleToCumRate(int index, double rate) {
        double temp = getCumRate(index);
        double scaleCumRate = rate / temp;
        for (int i = 0; i < num; ++i)
            super.set(i, scaleCumRate * getIncrRate(i));
    }

    /**
     * Using this function each data point is scaled to the ratio of the IncrRate at a given
     * magnitude and the specified newRate
     * @param mag
     * @param newRate
     */

    public void scaleToIncrRate(double mag, double newRate) {
        int index = getXIndex(mag);
        scaleToIncrRate(index, newRate);
    }

    /**
     * Using this function each data point is scaled to the ratio of the IncrRate at a given
     * index and the specified newRate
     * @param index
     * @param newRate
     */

    public void scaleToIncrRate(int index, double newRate) {
        double temp = getIncrRate(index);
        double scaleIncrRate = newRate / temp;
        for (int i = 0; i < num; ++i)
            super.set(i, scaleIncrRate * getIncrRate(i));
    }

    /**
     * Returns the default Info String for the Distribution
     * @return String
     */
    public String getDefaultInfo() {
        return defaultInfo;
    }

    /**
     * Returns the default Name for the Distribution
     * @return String
     */
    public String getDefaultName() {
        defaultName = "Incremental Mag Freq Dist";
        return defaultName;
    }

    /**
     * Returns the Name of the Distribution that user has set from outside,
     * if it is null then it returns the default Name from the distribution.
     * Makes the call to the parent "getName()" method to get the metadata
     * set outside the application.
     * @return String
     */
    public String getName() {
        if (name != null && !(name.trim().equals("")))
            return super.getName();
        return getDefaultName();
    }

    /**
     * Returns the info of the distribution that user has set from outside,
     * if it is null then it returns the default info from the distribution.
     * Makes the call to the parent "getInfo()" method to get the metadata
     * set outside the application.
     * @return String
     */
    public String getInfo() {
        if (info != null && !(info.equals("")))
            return super.getInfo();
        return getDefaultInfo();
    }

    /** Returns a copy of this and all points in this DiscretizedFunction */
    public IncrementalMagFreqDist deepClone() {

        IncrementalMagFreqDist f = new IncrementalMagFreqDist(minX, num, delta);

        f.tolerance = tolerance;
        f.setInfo(this.getInfo());
        f.setName(this.getName());
        for (int i = 0; i < num; i++)
            f.set(i, points[i]);

        return f;
    }

    /**
     * This returns the maximum magnitude with a non-zero rate
     * @return
     */
    public double getMinMagWithNonZeroRate() {
        for (int i = 0; i < num; i++) {
            if (getY(i) > 0)
                return getX(i);
        }
        return Double.NaN;
    }

    /**
     * This returns the maximum magnitude with a non-zero rate
     * @return
     */
    public double getMaxMagWithNonZeroRate() {
        for (int i = num - 1; i >= 0; i--) {
            if (getY(i) > 0)
                return getX(i);
        }
        return Double.NaN;
    }

    /**
    * This computes the b-value (the slope of the line of a linear-log plot, meaning
     * after computing log10 of all y-axis values) between the the given x-axis values.
     * If Double.NaN is passed in, then the first (or last) non-zero rate is used for
     * min_bValMag (or max_bValMag).
     * @param min_bValMag
     * @param max_bValMag
     * @return
     */
    public double compute_bValue(double min_bValMag, double max_bValMag) {
        int firstIndex, lastIndex;

        if (Double.isNaN(min_bValMag))
            firstIndex = getClosestXIndex(getMinMagWithNonZeroRate());
        else
            firstIndex = getClosestXIndex(min_bValMag);

        if (Double.isNaN(max_bValMag))
            lastIndex = getClosestXIndex(getMaxMagWithNonZeroRate());
        else
            lastIndex = getClosestXIndex(max_bValMag);

        SimpleRegression regression = new SimpleRegression();
        for (int i = firstIndex; i <= lastIndex; i++) {
            if (getY(i) > 0.0) // avoid taking log of zero
                regression.addData(getX(i), Math.log10(getY(i)));
        }

        //      if(getX(lastIndex)-getX(firstIndex) <1.0)
        //         return Double.NaN;

        return regression.getSlope();
    }

    /**
     * This sets all y-axis values above the given total moment rate to zero.
     * The final total moment rate will be something less than the value passed in.
     * @param moRate
     */
    public void setValuesAboveMomentRateToZero(double moRate) {
        double mag = findMagJustAboveMomentRate(moRate);
        if (Double.isNaN(mag))
            return;
        zeroAboveMag(mag);
    }

    /**
     * This finds the smallest magnitude such that all those less than and equal
     * to this have a cumulative moment rate less than that passed in.
     * @param moRate - in Nm/yr
     */
    public double findMagJustAboveMomentRate(double moRate) {
        double cumMoRate = 0;
        int targetIndex = -1;
        for (int i = 0; i < size(); i++) {
            cumMoRate += getMomentRate(i);
            if (cumMoRate > moRate) {
                targetIndex = i - 1;
                break;
            }
        }
        if (targetIndex == -1)
            return Double.NaN;
        else
            return getX(targetIndex);

    }

    /**
     * Sets the rate of all magnitudes above the supplied magnitude to 0.
     * @param mag 
     */
    public void zeroAboveMag(double mag) {
        for (int i = getXIndex(mag) + 1; i < size(); i++) {
            set(i, 0);
        }
    }

    /**
     * Sets the rate of all magnitudes above the supplied magnitude to 0.
     * @param mag 
     */
    public void zeroAtAndAboveMag(double mag) {
        for (int i = getXIndex(mag); i < size(); i++) {
            set(i, 0);
        }
    }

    /**
     * This computes the b-value (the slope of the line of a linear-log plot, meaning
     * after computing log10 of all y-axis values) between the smallest and largest 
     * mags with non-zero rates (zeros at the beginning and end of the distribution 
     * are ignored).
     * @return
     */
    public double compute_bValue() {
        return compute_bValue(Double.NaN, Double.NaN);
    }

}