com.meliorbis.numerics.function.primitives.DoubleRectangularGridDomain Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Numerics Show documentation
Show all versions of Numerics Show documentation
A library for working with large multi-dimensional arrays and the functions they represent
package com.meliorbis.numerics.function.primitives;
import java.util.Arrays;
import java.util.List;
import com.meliorbis.numerics.DoubleArrayFactories;
import com.meliorbis.numerics.function.grid.RectangularGridDomain;
import com.meliorbis.numerics.function.grid.RectangularGridFunction;
import com.meliorbis.numerics.generic.MultiDimensionalArray;
import com.meliorbis.numerics.generic.primitives.DoubleArray;
import com.meliorbis.numerics.generic.primitives.impl.Interpolation;
/**
* The domain of a function defined over a rectangular grid, interpolating at intermediate points
*
* @author Tobias Grasl
*/
public class DoubleRectangularGridDomain implements RectangularGridDomain>
{
private final DoubleArray>[] _gridPoints;
private final int[] _valuesSize;
private DoubleGridFunctionFactory _factory;
DoubleRectangularGridDomain(DoubleArray>[] gridPoints_, DoubleGridFunctionFactory factory_)
{
_gridPoints = gridPoints_;
_factory = factory_;
_valuesSize = initValuesSize();
}
private int[] initValuesSize()
{
// Create an array with enough elements for the input sizes plus the number of output variables
int[] _size = new int[_gridPoints.length + 1];
for (int i = 0; i < _gridPoints.length; i++)
{
_size[i] = _gridPoints[i].numberOfElements();
}
// Set the default output length to 1
_size[_gridPoints.length] = 1;
return _size;
}
public DoubleRectangularGridDomain(List extends DoubleArray>> gridPoints_, DoubleGridFunctionFactory factory_)
{
this(gridPoints_.toArray(new DoubleArray>[gridPoints_.size()]), factory_);
}
/**
* @return The axes of the rectangular grid over which this function is defined
*/
public DoubleArray>[] getGridPoints()
{
return _gridPoints;
}
@Override
public int getNumberOfDimensions()
{
return _gridPoints.length;
}
@Override
public DoubleArray> getAxis(int dimension_)
{
return _gridPoints[dimension_];
}
@Override
public DoubleArray> createValueGrid(int outputDims_)
{
int[] size;
/* Thread safety demands that we do not modify the member array willy-nilly
* Hence use that directly if it fits, else clone it and set the output size
* appropriately if not
*/
if(outputDims_ == 1)
{
size = _valuesSize;
}
else
{
size = _valuesSize.clone();
size[getNumberOfDimensions()] = outputDims_;
}
return DoubleArrayFactories.createArrayOfSize(size);
}
@Override
public DoubleArray> createValueGrid()
{
return createValueGrid(1);
}
/**
* @see com.meliorbis.numerics.function.grid.RectangularGridDomain#interpolateToGrid(int, com.meliorbis.numerics.generic.MultiDimensionalArray, com.meliorbis.numerics.generic.MultiDimensionalArray)
*/
@Override
public > RectangularGridFunction interpolateToGrid(int axis_, DoubleArray> nonRectangularDomainValues_, OA values_)
{
return interpolateToGrid(axis_, nonRectangularDomainValues_, values_, false);
}
/**
* Given a function with output values {@code values_} and input values on the grid points in this domain, except in dimension {@code axis_}, where
* the inputs are assumed non-rectangular and given by {@code nonRectangularDomainValues_}, this method will interpolate that exceptional dimension
* onto the grid and return the resulting rectangular grid function.
*
* The function can be constrained, meaning that the first y value (along each line) is considered the extreme value. Any target x values lying before the first source x will then be
* assigned that value, rather than using an extrapolated one.
*
* @param axis_ The dimension along which to perform the mapping
* @param nonRectangularDomainValues_ The input values along dimension {@code axis_} for each point orthogonal to that axis.
* @param values_ The values at the points defined by this domain's grid except in dimension {@code axis_}, where the input values are in
* {@code nonRectangularDomainValues_}
* @param constrained_ If true, the constraint mechanism is applied.
*
* @return A function on this domain that corresponds to the mapping defined by the two arrays passed
*
* @param The output value type
* @param The array type to use to hold the outputs
*/
@SuppressWarnings("unchecked")
@Override
public > RectangularGridFunction interpolateToGrid(int axis_, DoubleArray> nonRectangularDomainValues_, OA values_, boolean constrained_)
{
assert Arrays.equals(nonRectangularDomainValues_.size(), values_.size()) : "The arrays must be of equal size";
assert axis_ < nonRectangularDomainValues_.numberOfDimensions() : "Axis must be in range";
assert nonRectangularDomainValues_.numberOfDimensions() == getNumberOfDimensions() : "Number of dimensions of inputs and domain must equal";
if(!(values_ instanceof DoubleArray>))
{
throw new IllegalArgumentException("This implementation only works with IDoubleArray values arrays");
}
DoubleArray> values = (DoubleArray>) values_;
// Interpolate the function to the
DoubleArray> valuesOnGrid = Interpolation.interpolateFunction(nonRectangularDomainValues_, values, axis_, _gridPoints[axis_], new Interpolation.Params().constrained());
return (RectangularGridFunction) _factory.createFunction(this, valuesOnGrid);
}
@Override
public boolean equals(Object obj_)
{
if(!(obj_ instanceof DoubleRectangularGridDomain))
{
return false;
}
DoubleRectangularGridDomain other = (DoubleRectangularGridDomain) obj_;
return Arrays.equals(_gridPoints, other._gridPoints);
}
}