AbstractExercise.java
package net.finmath.modelling;
import java.util.Arrays;
/**
* Base class for exercise specifications.
*
* @author Alessandro Gnoatto
*/
public abstract class AbstractExercise implements Exercise {
/**
* The time tolerance.
*/
protected static final double TIME_TOLERANCE = 1E-12;
/**
* The maturity.
*/
private final double maturity;
/**
* The exercise times.
*/
private final double[] exerciseTimes;
/**
* Creates an exercise specification.
*
* @param maturity The maturity.
* @param exerciseTimes The exercise times in running time.
*/
protected AbstractExercise(final double maturity, final double[] exerciseTimes) {
if (maturity < 0.0) {
throw new IllegalArgumentException("Maturity must be non-negative.");
}
if (exerciseTimes == null || exerciseTimes.length == 0) {
throw new IllegalArgumentException("Exercise times must not be null or empty.");
}
this.maturity = maturity;
this.exerciseTimes = exerciseTimes.clone();
Arrays.sort(this.exerciseTimes);
for (final double exerciseTime : this.exerciseTimes) {
if (exerciseTime < -TIME_TOLERANCE || exerciseTime > maturity + TIME_TOLERANCE) {
throw new IllegalArgumentException("Exercise time out of range: " + exerciseTime);
}
}
}
@Override
public double getMaturity() {
return maturity;
}
@Override
public double[] getExerciseTimes() {
return exerciseTimes.clone();
}
/**
* Helper to test whether a time coincides with one of the scheduled
* exercise times.
*
* @param time The running time.
* @return True if the time matches one of the scheduled exercise times.
*/
protected boolean isScheduledExerciseTime(final double time) {
for (final double exerciseTime : exerciseTimes) {
if (Math.abs(exerciseTime - time) < TIME_TOLERANCE) {
return true;
}
}
return false;
}
}