
nl.tno.bim.nmd.scaling.NmdBaseScaler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bimnmdservice Show documentation
Show all versions of bimnmdservice Show documentation
provides a REST api for retrieving nmd data from various data sources
The newest version!
package nl.tno.bim.nmd.scaling;
import java.util.Arrays;
import java.util.Collections;
public abstract class NmdBaseScaler implements NmdScaler {
protected String unit;
protected Double[] coefficients;
protected Double[] bounds;
private Double[] currentValues;
private String description;
/**
* Create a scaler by defining standard coefficients and bounds
*
* @param unit the physical unit that the input values should be in.
* @param coefficients scaling coefficients with different meaning per scaler
* implementation. shoud have maximum of 3 coefficients
* @param bounds the min and max values for 1 or 2 dimensions. in order:
* [x_min, x_max, y_min, y_max]
* @param currentValues the reference dimension of the selected product or profile
*/
public NmdBaseScaler(String unit, Double[] coefficients, Double[] bounds, Double[] currentValues) {
this.unit = unit;
this.coefficients = coefficients;
this.bounds = bounds;
this.currentValues = currentValues;
}
private Double scale(double dim1Val, double dim2Val) {
if (areDimsWithinBounds(dim1Val, dim2Val)) {
return this.getNumberOfDimensions() == 1 ? scale(dim1Val) * scale(dim2Val)
: scale(dim1Val) * getScaleFactor(dim2Val, currentValues[1]);
} else {
return Double.NaN;
}
}
private Double scale(double dim1Val) {
return getScaleFactor(dim1Val, currentValues[0]);
}
@Override
public Double scaleWithConversion(Double[] dims, double conversionFactor) {
// determine how to match input dimension on scaler dimensions
Double[] sortedDims =this.matchInputDimensionsOnCurrentDimensions(dims);
if (sortedDims.length == 1) {
return this.scale(sortedDims[0] * conversionFactor);
} else if (sortedDims.length == 2) {
return this.scale(sortedDims[0] * conversionFactor, sortedDims[1] * conversionFactor);
} else {
return Double.NaN;
}
}
private Double[] matchInputDimensionsOnCurrentDimensions(Double[] dims) {
// check if we need to order at all
if (this.currentValues.length > 1 && dims.length > 1) {
// determine how to sort the array
if (currentValues[1] <= currentValues[0]) {
Arrays.sort(dims, Collections.reverseOrder());
} else {
Arrays.sort(dims);
}
}
return dims;
}
/**
* return a flag to indicate that the desired scaling dimensions are within
* bounds
*
* @param x first dimension to check
* @param y second dimension to check
* @return Boolean that inidicates that the desired dims are within the scaling
* bounds
*/
private Boolean areDimsWithinBounds(Double x, Double y) {
// check whether to check the bounds for 1 or 2 dimensions
if (getNumberOfDimensions() == 1) {
return isWithinBounds(x, bounds[0], bounds[1]) && isWithinBounds(y, bounds[0], bounds[1]);
} else {
return isWithinBounds(x, bounds[0], bounds[1]) && isWithinBounds(y, bounds[2], bounds[3]);
}
}
@Override
public Boolean areDimsWithinBounds(Double[] dims, double conversionFactor) {
if (dims.length == 1) {
return areDimsWithinBounds(dims[0] * conversionFactor, dims[0] * conversionFactor);
} else if (dims.length == 2) {
return areDimsWithinBounds(dims[0] * conversionFactor, dims[1] * conversionFactor);
} else {
return false;
}
}
/**
* Check if a single parameter is within bounds
*
* @param x desired dimensions
* @param x_min minimum boundary value
* @param x_max maximum boundary value
* @return a flag to indicate x is within the boundary values
*/
private Boolean isWithinBounds(double x, double x_min, double x_max) {
return (x <= x_max || Double.isNaN(x_max)) && (x >= x_min || Double.isNaN(x_min));
}
/**
* Simple check to determine if scaling should be done over 1 or 2 dimensions
*
* @return Number of dimensions of the scaler
*/
@Override
public Integer getNumberOfDimensions() {
return (bounds.length == 4 && !bounds[3].isNaN() &&
currentValues.length == 2 && !currentValues[1].isNaN())
? 2
: 1;
}
/**
* Determine the correction factor for scaling from current value to desired
* value
*
* @param x_desired the desired dimension value
* @param x_current the current value with which the profileSet is defined
* @return a scaling factor
*/
protected double getScaleFactor(double x_desired, Double x_current) {
return calculate(x_desired) / calculate(x_current);
}
public String getUnit() {
return this.unit;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* abstract method to override by derived classes. will define the type of scaler
*
* @param x value to calculate the y value (y(x))
* @return y value from implemented method.
*/
protected abstract Double calculate(Double x);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy