All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jcamp.spectrum.OrderedArrayData Maven / Gradle / Ivy

package org.jcamp.spectrum;

import org.jcamp.math.DataException;
import org.jcamp.math.IOrderedArray1D;
import org.jcamp.math.OrderedArray1D;
import org.jcamp.math.Range;
import org.jcamp.math.Range1D;
import org.jcamp.units.CommonUnit;
import org.jcamp.units.Unit;
import org.jcamp.units.UnitException;
/**
 * combination of a discrete interval with a physical unit.
 * @author Thomas Weber
 */
public class OrderedArrayData implements IOrderedDataArray1D {
    private OrderedArray1D data;
    private Unit unit;
    private String label;
    private boolean ascending = true;
    /**
     * 
     */
    public OrderedArrayData(double[] data, Unit unit) {
        this.data = new OrderedArray1D(data, false, true);
        if (unit != null)
            this.unit = unit;
        else
            this.unit = CommonUnit.generic;
        if (data.length > 1)
            this.ascending = (data[0] < data[1]);
    }
    /**
     */
    public OrderedArrayData(IOrderedArray1D data) {
        this(data, CommonUnit.generic);
    }
    /**
     */
    public OrderedArrayData(IOrderedArray1D data, Unit unit) {
        this.data = new OrderedArray1D(data);
        if (unit != null)
            this.unit = unit;
        else
            this.unit = CommonUnit.generic;
    }
    /**
     * binary search for bounding indices
     * 
     * @return int left index
     * @param position double
     */
    private int binsearchIndex(double position) {
        int left = 0;
        int right = getLength() - 1;
        int mid;
        double sleft = data.pointAt(left);
        double sright = data.pointAt(right);
        if (isAscending()) {
            while (right - left > 1) {
                mid = (right + left) / 2;
                double sposition = data.pointAt(mid);
                if (position > sposition)
                    left = mid;
                else if (position < sposition)
                    right = mid;
                else {
                    left = mid;
                    break;
                }
            }
            return left;
        } else {
            while (right - left > 1) {
                mid = (right + left) / 2;
                double sposition = data.pointAt(mid);
                if (position < sposition)
                    left = mid;
                else if (position > sposition)
                    right = mid;
                else {
                    left = mid;
                    break;
                }
            }
            return left;
        }
    }
    /**
     * @see com.creon.chem.spectrum.IOrderedDataArray1D
     */
    public int[] boundIndices(double position) throws org.jcamp.math.DataException {
        Range1D.Double r = data.getRange1D();
        int max = data.getLength() - 1;
        if (!r.contains(position))
            throw new DataException("data point out of data range");
        if (isAscending()) {
            int c0 = Math.max(0, binsearchIndex(position));
            return new int[] { c0, c0 + 1 };
        } else {
            int c0 = Math.min(max, binsearchIndex(position) + 1);
            return new int[] { c0, c0 - 1 };
        }
    }
    /**
     * @see com.creon.chem.spectrum.IOrderedDataArray1D
     */
    public org.jcamp.math.Range1D.Double bounds(double position) throws org.jcamp.math.DataException {
        int[] bi = boundIndices(position);
        return new Range1D.Double(data.pointAt(bi[0]), data.pointAt(bi[1]));
    }
    /**
     * @see com.creon.chem.spectrum.IOrderedDataArray1D
     */
    public double ceil(double position) throws org.jcamp.math.DataException {
        return data.pointAt(ceilIndex(position));
    }
    /**
     * @see com.creon.chem.spectrum.IOrderedDataArray1D
     */
    public int ceilIndex(double position) throws org.jcamp.math.DataException {

        int n = data.getLength();
        // first check for degenerated data
        if (n == 0)
            throw new DataException("empty data set");
        else if (n == 1) {
            if (position < data.pointAt(0))
                return 0;
            else
                throw new DataException("no ceiling data point for position");
        }
        Range1D.Double r = data.getRange1D();
        if (position > r.getXMax())
            throw new DataException("no ceiling data point for position");
        int max = n - 1;
        if (isAscending()) {
            if (position < r.getXMin())
                return 0;
            else
                return Math.min(max, binsearchIndex(position) + 1);
        } else {
            if (position < r.getXMin())
                return max;
            else
                return Math.max(0, binsearchIndex(position));
        }
    }
    /**
     * cloning
     * 
     * @return java.lang.Object
     */
    public Object clone() {
        OrderedArrayData o = null;
        try {
            o = (OrderedArrayData) super.clone();
        } catch (CloneNotSupportedException e) {
        }
        o.data = (OrderedArray1D) this.data.clone();
        o.unit = (Unit) this.unit.clone();
        return o;
    }
    /**
     * convert data to new unit.
     * @param newUnit Unit
     * NOTE: original data is lost and new data is an expensive array.
     */
    public void convertToUnit(Unit newUnit) throws UnitException {
        double[] array = new double[data.getLength()];
        for (int i = 0; i < data.getLength(); i++)
            array[i] = newUnit.convertFrom(data.pointAt(i), unit);
        data = new OrderedArray1D(array, false);
        setUnit(newUnit);
    }
    /**
     * @see com.creon.chem.spectrum.IOrderedDataArray1D
     */
    public double floor(double position) throws org.jcamp.math.DataException {
        return data.pointAt(floorIndex(position));
    }
    /**
     * @see com.creon.chem.spectrum.IOrderedDataArray1D
     */
    public int floorIndex(double position) throws org.jcamp.math.DataException {
        int n = data.getLength();
        // first check empty or degenerated data
        if (n == 0)
            throw new DataException("empty data set");
        else if (n == 1) {
            if (position > data.pointAt(0))
                return 0;
            else
                throw new DataException("no floor data point for position");
        }

        Range1D.Double r = data.getRange1D();
        int max = n - 1;
        if (position < r.getXMin())
            throw new DataException("no floor data point for position");

        if (isAscending()) {
            if (position > r.getXMax())
                return max;
            else
                return Math.max(0, binsearchIndex(position));
        } else {
            if (position > r.getXMax())
                return 0;
            else
                return Math.min(max, binsearchIndex(position) + 1);
        }

    }
    /**
     * gets data label
     * 
     * @return java.lang.String
     */
    public java.lang.String getLabel() {
        if (label == null)
            return unit.toString();
        return label;
    }
    /**
     * gets number of data points.
     */
    public int getLength() {
        return data.getLength();
    }
    /**
     * get data range.
     * @return Range.Double
     */
    public Range.Double getRange() {
        return data.getRange();
    }
    /**
     * gets data range.
     * @return Range1D.Double
     */
    public Range1D.Double getRange1D() {
        return data.getRange1D();
    }
    /**
     * gets the data unit.
     * @return Unit
     */
    public Unit getUnit() {
        return unit;
    }
    /**
     * @see com.creon.math.IOrderedArray1D
     */
    public int indexAt(double p) {
        return data.indexAt(p);
    }
    /**
     * @see com.creon.chem.spectrum.IOrderedDataArray1D
     */
    public boolean isAscending() {
        return ascending;
    }
    /**
     * gets data point at index.
     */
    public double pointAt(int index) {
        return data.pointAt(index);
    }
    /**
     * @see com.creon.math.IArray1D
     */
    public void scale(double amount) {
        data.scale(amount);
    }
    /**
     * Insert the method's description here.
     * 
     * @param newLabel java.lang.String
     */
    public void setLabel(java.lang.String newLabel) {
        label = newLabel;
    }
    /**
     * sets the unit for the data.
     * @param newUnit Unit
     */
    public void setUnit(Unit newUnit) {
        unit = newUnit;
    }
    /**
     * toArray method comment.
     */
    public double[] toArray() {
        return data.toArray();
    }
    public void translate(double amount) {
        data.translate(amount);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy