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

net.finmath.time.TimeDiscretizationFromArray Maven / Gradle / Ivy

/*
 * (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
 *
 * Created on 20.04.2008
 */
package net.finmath.time;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import java.util.function.DoublePredicate;
import java.util.function.IntToDoubleFunction;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * This class represents a set of discrete points in time.
 * 
* It handles the mapping from time indices to time points and back. * It uses a time tick size ("quantum"). This is to make comparison of times safe. * The default tick size is 1.0 / (365.0 * 24.0) (which corresponds to one hour if 1.0 is a non-leap-year): * Times are rounded to the nearest multiple of 1.0 / (365.0 * 24.0). * * This property can be configured via a System.setProperty("net.finmath.functions.TimeDiscretization.timeTickSize"). * * Objects of this class are immutable. * * @author Christian Fries * @version 1.6 */ public class TimeDiscretizationFromArray implements Serializable, TimeDiscretization { private static final long serialVersionUID = 6880668325019167781L; private static final double timeTickSizeDefault = Double.parseDouble(System.getProperty("net.finmath.functions.TimeDiscretization.timeTickSize", Double.toString(1.0 / (365.0 * 24.0)))); private final double[] timeDiscretization; private final double timeTickSize; public enum ShortPeriodLocation { SHORT_PERIOD_AT_START, SHORT_PERIOD_AT_END } /** * Constructs a time discretization using the given tick size. * The time discretization will be sorted. Duplicate entries are allowed if allowDuplicates is true, otherwise duplicate entries are removed. * * @param times A non closed and not necessarily sorted stream containing the time points. * @param tickSize A non-negative double representing the smallest time span distinguishable. * @param allowDuplicates If true, the time discretization allows duplicate entries. */ public TimeDiscretizationFromArray(DoubleStream times, final double tickSize, final boolean allowDuplicates) { timeTickSize = tickSize; times = times.map(this::roundToTimeTickSize); if(!allowDuplicates) { times = times.distinct(); } timeDiscretization = times.sorted().toArray(); } /** * Constructs a time discretization using the given tick size. * * @param times A non closed and not necessarily sorted stream containing the time points. * @param tickSize A non-negative double representing the smallest time span distinguishable. */ public TimeDiscretizationFromArray(final DoubleStream times, final double tickSize) { this(times, tickSize, false); } /** * Constructs a time discretization from a (non closed and not necessarily sorted) stream of doubles. * The time discretization will be sorted. Duplicate entries are allowed if allowDuplicates is true, otherwise duplicate entries are removed. * * @param times A double stream of time points for the time discretization. * @param allowDuplicates If true, the time discretization allows duplicate entries. */ public TimeDiscretizationFromArray(final DoubleStream times, final boolean allowDuplicates) { this(times, timeTickSizeDefault, allowDuplicates); } /** * Constructs a time discretization from a (non closed and not necessarily sorted) stream of doubles. * * @param times A double stream of time points for the time discretization. */ public TimeDiscretizationFromArray(final DoubleStream times) { this(times, timeTickSizeDefault, false); } /** * Constructs a time discretization using the given tick size. * * @param times A non closed and not necessarily sorted stream containing the time points. * @param tickSize A non-negative double representing the smallest time span distinguishable. * @param allowDuplicates If true, the time discretization allows duplicate entries. */ public TimeDiscretizationFromArray(final Stream times, final double tickSize, final boolean allowDuplicates) { this(times.mapToDouble(Double::doubleValue), tickSize, allowDuplicates); } /** * Constructs a time discretization using the given tick size. * The time discretization will be sorted. Duplicate entries are allowed if allowDuplicates is true, otherwise duplicate entries are removed. * * @param times A non closed and not necessarily sorted stream containing the time points. * @param tickSize A non-negative double representing the smallest time span distinguishable. */ public TimeDiscretizationFromArray(final Stream times, final double tickSize) { this(times.mapToDouble(Double::doubleValue), tickSize, false); } /** * Constructs a time discretization from a (non closed and not necessarily sorted) stream of boxed doubles. * * @param times A double stream of time points for the time discretization. */ public TimeDiscretizationFromArray(final Stream times) { this(times.mapToDouble(Double::doubleValue), timeTickSizeDefault, false); } /** * Constructs a time discretization using the given tick size. * The iteration of the iterable does not have to happen in order. * * @param times The time to constitute the time discretization. * @param tickSize A non-negative double representing the smallest time span distinguishable. * @param allowDuplicates If true, the time discretization allows duplicate entries. */ public TimeDiscretizationFromArray(final Iterable times, final double tickSize, final boolean allowDuplicates) { this(StreamSupport.stream(times.spliterator(), false), tickSize, allowDuplicates); } /** * Constructs a time discretization using the given tick size. * The iteration of the iterable does not have to happen in order. * * @param times The time to constitute the time discretization. * @param tickSize A non-negative double representing the smallest time span distinguishable. */ public TimeDiscretizationFromArray(final Iterable times, final double tickSize) { this(times, tickSize, false); } /** * Constructs a time discretization from an iterable of doubles. * The iteration does not have to happen in order. * * @param times The time to constitute the time discretization. * @param allowDuplicates If true, the time discretization allows duplicate entries. */ public TimeDiscretizationFromArray(final Iterable times, final boolean allowDuplicates) { this(times,timeTickSizeDefault, allowDuplicates); } /** * Constructs a time discretization from an iterable of doubles. * The iteration does not have to happen in order. * * @param times The time to constitute the time discretization. */ public TimeDiscretizationFromArray(final Iterable times) { this(times, false); } /** * Constructs a time discretization from a given set of doubles. * The given array does not need to be sorted. * * @param times Given array or arguments list of discretization points. */ public TimeDiscretizationFromArray(final double... times) { this(Arrays.stream(times)); } /** * Constructs a time discretization from a given set of Doubles. * The given array does not need to be sorted. * * @param times Given boxed array of discretization points. */ public TimeDiscretizationFromArray(final Double[] times) { this(Arrays.stream(times)); } /** * Constructs a time discretization using the given tick size. * The given array does not need to be sorted. * * @param times Given boxed array of discretization points. * @param tickSize A non-negative double representing the smallest time span distinguishable. */ public TimeDiscretizationFromArray(final Double[] times, final double tickSize) { this(Arrays.stream(times), tickSize); } /** * Constructs an equi-distant time discretization with points timeDiscretizationFromArray[i] being * for(i=0; i ≤ timeSteps; i++) timeDiscretizationFromArray[i] = initial + i * deltaT; * * @param initial First discretization point. * @param numberOfTimeSteps Number of time steps. * @param deltaT Time step size. */ public TimeDiscretizationFromArray(final double initial, final int numberOfTimeSteps, final double deltaT) { this(IntStream.range(0, numberOfTimeSteps + 1).mapToDouble(new IntToDoubleFunction() { @Override public double applyAsDouble(final int n) { return initial + n * deltaT; } })); } /** * Constructs an equi-distant time discretization with stub periods at start or end. * * @param initial First discretization point. * @param last Last time steps. * @param deltaT Time step size. * @param shortPeriodLocation Placement of the stub period. */ public TimeDiscretizationFromArray(final double initial, final double last, final double deltaT, final ShortPeriodLocation shortPeriodLocation) { this(getEquidistantStreamWithStub(initial, last, deltaT, shortPeriodLocation)); } private static DoubleStream getEquidistantStreamWithStub(final double initial, final double last, final double deltaT, final ShortPeriodLocation shortPeriodLocation) { final int numberOfTimeStepsPlusOne = (int) Math.ceil((last - initial) / deltaT) + 1; if (shortPeriodLocation == ShortPeriodLocation.SHORT_PERIOD_AT_END) { return IntStream.range(0, numberOfTimeStepsPlusOne).mapToDouble(new IntToDoubleFunction() { @Override public double applyAsDouble(final int n) { return Math.min(last, initial + n * deltaT); } }); } return IntStream.range(0, numberOfTimeStepsPlusOne).mapToDouble(new IntToDoubleFunction() { @Override public double applyAsDouble(final int n) { return Math.max(initial, last - n * deltaT); } }); } @Override public int getNumberOfTimes() { return timeDiscretization.length; } @Override public int getNumberOfTimeSteps() { return timeDiscretization.length-1; } @Override public double getTime(final int timeIndex) { return timeDiscretization[timeIndex]; } @Override public double getTimeStep(final int timeIndex) { return timeDiscretization[timeIndex + 1] - timeDiscretization[timeIndex]; } @Override public int getTimeIndex(final double time) { return Arrays.binarySearch(timeDiscretization, roundToTimeTickSize(time)); } @Override public int getTimeIndexNearestLessOrEqual(final double time) { int index = java.util.Arrays.binarySearch(timeDiscretization,roundToTimeTickSize(time)); if(index < 0) { index = -index-2; } return index; } @Override public int getTimeIndexNearestGreaterOrEqual(final double time) { int index = java.util.Arrays.binarySearch(timeDiscretization,time); if(index < 0) { index = -index-1; } return index; } @Override public double[] getAsDoubleArray() { // Note: This is a deep copy return timeDiscretization.clone(); } @Override public ArrayList getAsArrayList() { final ArrayList times = new ArrayList<>(timeDiscretization.length); for (final double aTimeDiscretization : timeDiscretization) { times.add(aTimeDiscretization); } return times; } @Override public TimeDiscretization getTimeShiftedTimeDiscretization(final double timeShift) { final double[] newTimeDiscretization = new double[timeDiscretization.length]; for (int timeIndex = 0; timeIndex < timeDiscretization.length; timeIndex++) { newTimeDiscretization[timeIndex] = roundToTimeTickSize(timeDiscretization[timeIndex] + timeShift); } return new TimeDiscretizationFromArray(newTimeDiscretization); } @Override public TimeDiscretization filter(DoublePredicate timesToKeep) { return new TimeDiscretizationFromArray(Arrays.stream(timeDiscretization).filter(timesToKeep), getTickSize()); } /** * @param that Another time discretization containing points to add to the time discretization. * @return A new time discretization containing both the time points of this and the other discretization. */ @Override public TimeDiscretization union(final TimeDiscretization that) { return new TimeDiscretizationFromArray( Stream.concat(Arrays.stream(timeDiscretization).boxed(), Arrays.stream(that.getAsDoubleArray()).boxed()), Math.min(timeTickSize, that.getTickSize())); } @Override public TimeDiscretization intersect(final TimeDiscretization that) { final Set intersectionSet = Arrays.stream(timeDiscretization).boxed().collect(Collectors.toSet()); intersectionSet.retainAll(that.getAsArrayList()); return new TimeDiscretizationFromArray(intersectionSet, Math.max(timeTickSize, that.getTickSize())); } @Override public double getTickSize() { return timeTickSize; } @Override public Iterator iterator() { return this.getAsArrayList().iterator(); } @Override public String toString() { return "TimeDiscretizationFromArray [timeDiscretizationFromArray=" + Arrays.toString(timeDiscretization) + ", timeTickSize=" + timeTickSize + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(timeDiscretization); long temp; temp = Double.doubleToLongBits(timeTickSize); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final TimeDiscretizationFromArray other = (TimeDiscretizationFromArray) obj; if (!Arrays.equals(timeDiscretization, other.timeDiscretization)) { return false; } return Double.doubleToLongBits(timeTickSize) == Double.doubleToLongBits(other.timeTickSize); } private double roundToTimeTickSize(final double time) { return Math.rint(time/timeTickSize)*timeTickSize; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy