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

org.tensorics.core.function.interpolation.LinearInterpolationStrategy Maven / Gradle / Ivy

Go to download

Tensorics is a java framework which uses a tensor as a central object. A tensor represents a set of values placed in an N-dimensional space. Wherever you are tempted to use maps of maps, a tensor might be a good choice ;-) Tensorics provides methods to create, transform and performing calculations with those tensors.

There is a newer version: 0.0.81
Show newest version
package org.tensorics.core.function.interpolation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.tensorics.core.commons.operations.Conversion;
import org.tensorics.core.function.DiscreteFunction;
import org.tensorics.core.math.ExtendedField;
import org.tensorics.core.scalar.lang.ScalarSupport;

import com.google.common.base.Preconditions;

/**
 * An {@link InterpolationStrategy} for interpolating linearly {@link DiscreteFunction}s.
 * 
 * @see InterpolationStrategy
 * @author agorzaws, caguiler
 */
public class LinearInterpolationStrategy extends ScalarSupport implements InterpolationStrategy {

    private static final long serialVersionUID = 1L;

    public LinearInterpolationStrategy(ExtendedField field) {
        super(field);
    }

    @Override
    public  Y interpolate(X x, DiscreteFunction function, Conversion conversion,
            Comparator comparator) {
        Preconditions.checkNotNull(x, "x cannot be null!");
        Preconditions.checkNotNull(function, "function cannot be null!");
        Preconditions.checkNotNull(conversion, "conversion cannot be null!");

        int size = function.definedXValues().size();

        if (size < 2) {
            throw new IllegalStateException("Cannot interpolate function with less than 2 -values defined!");
        }

        List xValues = new ArrayList<>(function.definedXValues());

        Collections.sort(xValues, comparator);

        X firstX = xValues.get(0);
        X lastX = xValues.get(size - 1);

        boolean lessOrEqualThanFirstX = comparator.compare(x, firstX) <= 0;
        boolean greaterOrEqualThanLastX = comparator.compare(x, lastX) >= 0;

        X x1 = null;
        X x2 = null;

        if (lessOrEqualThanFirstX) {
            x1 = firstX;
            x2 = xValues.get(1);
        } else if (greaterOrEqualThanLastX) {
            x1 = xValues.get(size - 2);
            x2 = lastX;
        } else {
            int index = 0;

            do {
                x2 = xValues.get(index);
                ++index;
            } while (comparator.compare(x2, x) < 0);

            x1 = xValues.get(index - 2);
        }

        Y xInYDomain = conversion.apply(x);
        Y x1InyDomain = conversion.apply(x1);
        Y x2InYDomain = conversion.apply(x2);

        Y y1 = function.apply(x1);
        Y y2 = function.apply(x2);

        return calculateInterpolation(xInYDomain, x1InyDomain, x2InYDomain, y1, y2);
    }

    private Y calculateInterpolation(Y x, Y x1, Y x2, Y y1, Y y2) {
        Y xMinusX1 = calculate(x).minus(x1);

        Y x2MinusX1 = calculate(x2).minus(x1);

        Y division = calculate(xMinusX1).dividedBy(x2MinusX1);

        Y y2MinusY1 = calculate(y2).minus(y1);

        Y partialResult = calculate(division).times(y2MinusY1);

        return calculate(partialResult).plus(y1);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy