Package com.barrybecker4.common.math.cutpoints

Source Code of com.barrybecker4.common.math.cutpoints.AbstractCutPointFinder

// Copyright by Barry G. Becker, 2013. Licensed under MIT License: http://www.opensource.org/licenses/MIT
package com.barrybecker4.common.math.cutpoints;

import com.barrybecker4.common.math.Range;

import java.util.ArrayList;
import java.util.List;

/**
* Base class for cut point finders.
* @author Barry Becker
*/
abstract class AbstractCutPointFinder {

    /** The range should not get smaller than this. */
    static final double MIN_RANGE = 1.0E-10;


    /**
     * Retrieve the cut point values.
     * If its a really small range include both min and max to avoid having just one label.
     * @param range range to be divided into intervals.
     * @param maxNumTicks upper limit on number of cut points to return.
     * @return the cut points
     */
    public double[] getCutPoints(Range range, int maxNumTicks) {

        validateArguments(range);
        Range finalRange = new Range(range);
        if (range.getExtent() <= MIN_RANGE) {
            finalRange.add(range.getMin() + MIN_RANGE);
        }

        List<Double> positions = new ArrayList<Double>(10);

        if (finalRange.getExtent() < MIN_RANGE) {
            positions.add(finalRange.getMin());
        } else {
            determineCutPoints(maxNumTicks, finalRange, positions);
        }

        double[] result = new double[positions.size()];
        for (int i = 0; i < positions.size(); i++) {
            result[i] = positions.get(i);
        }

        return result;
    }

    void determineCutPoints(int maxTicks, Range finalRange, List<Double> positions) {

        double extent = Rounder.round(finalRange.getExtent(), false);
        double d = Rounder.round(extent / (maxTicks - 1), true);
        Range roundedRange =
                new Range(Math.floor(finalRange.getMin() / d) * d, Math.ceil(finalRange.getMax() / d) * d);

        addPoints(positions, roundedRange, finalRange, d);
    }

    protected abstract void addPoints(List<Double> positions, Range roundedRange, Range finalRange, double d);

     /**
     * Verify that the min and max are valid.
     * @param range range to check for NaN values.
     */
    private void validateArguments(Range range) {
        if (Double.isNaN(range.getExtent())) {
            throw new IllegalArgumentException("Min cannot be greater than max for " + range);
        }
        if (Double.isNaN(range.getMin())
                || Double.isInfinite(range.getMin())
                || Double.isNaN(range.getMax())
                || Double.isInfinite(range.getMax())) {
            throw new IllegalArgumentException("Min or max of the range [" + range + "] is not a number.");
        }
    }

    /**
     * If real small just assume it is zero.
     * @param value the value to check.
     * @return zero if value is below the smallest allowed range, else return value.
     */
    double checkSmallNumber(double value) {
        if (Math.abs(value) < MIN_RANGE) {
            return 0;
        }
        return value;
    }
}
TOP

Related Classes of com.barrybecker4.common.math.cutpoints.AbstractCutPointFinder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.