@Override public LocalDateDoubleTimeSeries mapDates(Function<? super LocalDate, ? extends LocalDate> mapper) { ArgChecker.notNull(mapper, "mapper"); LocalDate[] dates = Arrays.stream(this.dates).map(mapper).toArray(size -> new LocalDate[size]); // Check the dates are still in ascending order after the mapping Arrays.stream(dates).reduce(this::checkAscending); return createUnsafe(dates, values); }
@Override public LocalDateDoubleTimeSeries headSeries(int numPoints) { ArgChecker.notNegative(numPoints, "numPoints"); if (numPoints == 0) { return EMPTY; } else if (numPoints >= size()) { return this; } LocalDate[] datesArray = Arrays.copyOfRange(dates, 0, numPoints); double[] valuesArray = Arrays.copyOfRange(values, 0, numPoints); return createUnsafe(datesArray, valuesArray); }
@Override public LocalDateDoubleTimeSeries subSeries(LocalDate startInclusive, LocalDate endExclusive) { ArgChecker.notNull(startInclusive, "startInclusive"); ArgChecker.notNull(endExclusive, "endExclusive"); if (endExclusive.isBefore(startInclusive)) { throw new IllegalArgumentException( "Invalid sub series, end before start: " + startInclusive + " to " + endExclusive); } // special case when this is empty or when the dates are the same if (isEmpty() || startInclusive.equals(endExclusive)) { return EMPTY; } // where in the array would start/end be (whether or not it's actually in the series) int startPos = Arrays.binarySearch(dates, startInclusive); startPos = startPos >= 0 ? startPos : -startPos - 1; int endPos = Arrays.binarySearch(dates, endExclusive); endPos = endPos >= 0 ? endPos : -endPos - 1; // create sub-series LocalDate[] timesArray = Arrays.copyOfRange(dates, startPos, endPos); double[] valuesArray = Arrays.copyOfRange(values, startPos, endPos); return createUnsafe(timesArray, valuesArray); }
/** * Obtains a time-series from matching arrays of dates and values. * <p> * The two arrays must be the same size and must be sorted from earliest to latest. * * @param dates the date list * @param values the value list * @return the time-series */ static SparseLocalDateDoubleTimeSeries of(Collection<LocalDate> dates, Collection<Double> values) { ArgChecker.noNulls(dates, "dates"); ArgChecker.noNulls(values, "values"); LocalDate[] datesArray = dates.toArray(new LocalDate[dates.size()]); double[] valuesArray = Doubles.toArray(values); validate(datesArray, valuesArray); return createUnsafe(datesArray, valuesArray); }
@Override public LocalDateDoubleTimeSeries filter(ObjDoublePredicate<LocalDate> predicate) { ArgChecker.notNull(predicate, "predicate"); // build up result in arrays keeping track of count of retained dates LocalDate[] resDates = new LocalDate[size()]; double[] resValues = new double[size()]; int resCount = 0; for (int i = 0; i < size(); i++) { if (predicate.test(dates[i], values[i])) { resDates[resCount] = dates[i]; resValues[resCount] = values[i]; resCount++; } } return createUnsafe(Arrays.copyOf(resDates, resCount), Arrays.copyOf(resValues, resCount)); }
@Override public LocalDateDoubleTimeSeries tailSeries(int numPoints) { ArgChecker.notNegative(numPoints, "numPoints"); if (numPoints == 0) { return EMPTY; } else if (numPoints >= size()) { return this; } LocalDate[] datesArray = Arrays.copyOfRange(dates, size() - numPoints, size()); double[] valuesArray = Arrays.copyOfRange(values, size() - numPoints, size()); return createUnsafe(datesArray, valuesArray); }
@Override public LocalDateDoubleTimeSeries mapValues(DoubleUnaryOperator mapper) { ArgChecker.notNull(mapper, "mapper"); return createUnsafe(dates, DoubleStream.of(values).map(mapper).toArray()); }