com.enterprisemath.math.fa.StraightLineSegmentFunction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of em-math Show documentation
Show all versions of em-math Show documentation
Advanced mathematical algorithms.
The newest version!
package com.enterprisemath.math.fa;
import com.enterprisemath.math.algebra.Vector;
import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* Real to real function which is created by straight line segments.
* These segments are interpolated / extrapolated between the defined points.
* Extrapolation is linear using two first / last points.
*
* @author radek.hecl
*/
public class StraightLineSegmentFunction implements Function {
/**
* Builder object.
*/
public static class Builder {
/**
* Pivot points.
*/
private SortedMap pivotPoints = new TreeMap();
/**
* Sets pivot points.
*
* @param pivotPoints pivot points
* @return this instance
*/
public Builder setPivotPoints(SortedMap pivotPoints) {
this.pivotPoints = DomainUtils.softCopySortedMap(pivotPoints);
return this;
}
/**
* Adds pivot point.
*
* @param x value x
* @param y value y
* @return this instance
*/
public Builder addPivotPoint(double x, double y) {
this.pivotPoints.put(x, y);
return this;
}
/**
* Builds the result object.
*
* @return created object
*/
public StraightLineSegmentFunction build() {
return new StraightLineSegmentFunction(this);
}
}
/**
* Pivot points.
*/
private SortedMap pivotPoints;
/**
* List of pivot points in the x axis.
*/
private List pivotXList;
/**
* Creates new instance.
*
* @param builder builder object
*/
public StraightLineSegmentFunction(Builder builder) {
this.pivotPoints = DomainUtils.softCopyUnmodifiableSortedMap(builder.pivotPoints);
guardInvariants();
pivotXList = DomainUtils.softCopyUnmodifiableList(pivotPoints.keySet());
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
ValidationUtils.guardNotNullMap(pivotPoints, "pivot points cannot contain null");
ValidationUtils.guardTrue(pivotPoints.size() >= 2, "at least 2 pivot points are required");
}
@Override
public Double getValue(Double x) {
if (pivotPoints.containsKey(x)) {
return pivotPoints.get(x);
}
double x1 = 0;
double x2 = 0;
if (x < pivotXList.get(0)) {
x1 = pivotXList.get(0);
x2 = pivotXList.get(1);
}
else if (x > pivotXList.get(pivotXList.size() - 1)) {
x1 = pivotXList.get(pivotXList.size() - 2);
x2 = pivotXList.get(pivotXList.size() - 1);
}
else {
for (double px : pivotXList) {
if (px < x) {
x1 = px;
}
else {
x2 = px;
break;
}
}
}
double t = (x - x1) / (x2 - x1);
return (1 - t) * pivotPoints.get(x1) + t * pivotPoints.get(x2);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
/**
* Creates new instance.
*
* @param p1 first pivot point
* @param p2 second pivot point
* @param others other pivot points
* @return created instance
*/
public static StraightLineSegmentFunction create(Vector p1, Vector p2, Vector... others) {
StraightLineSegmentFunction.Builder res = new StraightLineSegmentFunction.Builder();
ValidationUtils.guardEquals(2, p1.getDimension(), "dimension of all pivot points must be 2");
res.addPivotPoint(p1.getComponent(0), p1.getComponent(1));
ValidationUtils.guardEquals(2, p2.getDimension(), "dimension of all pivot points must be 2");
res.addPivotPoint(p2.getComponent(0), p2.getComponent(1));
if (others != null) {
for (Vector p : others) {
ValidationUtils.guardEquals(2, p.getDimension(), "dimension of all pivot points must be 2");
res.addPivotPoint(p.getComponent(0), p.getComponent(1));
}
}
return res.build();
}
}