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

org.ojalgo.series.BasicSeries Maven / Gradle / Ivy

Go to download

oj! Algorithms - ojAlgo - is Open Source Java code that has to do with mathematics, linear algebra and optimisation.

There is a newer version: 55.0.1
Show newest version
/*
 * Copyright 1997-2021 Optimatika
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.ojalgo.series;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;

import org.ojalgo.ProgrammingError;
import org.ojalgo.array.DenseArray;
import org.ojalgo.function.BinaryFunction;
import org.ojalgo.series.primitive.CoordinatedSet;
import org.ojalgo.series.primitive.PrimitiveSeries;
import org.ojalgo.structure.Access1D;
import org.ojalgo.structure.Structure1D;
import org.ojalgo.type.CalendarDate;
import org.ojalgo.type.ColourData;
import org.ojalgo.type.TimeIndex;
import org.ojalgo.type.keyvalue.KeyValue;

/**
 * A BasicSeries is a {@linkplain SortedMap} with:
 * 
    *
  • Keys restricted to {@linkplain Comparable} (the keys have a natural order)
  • *
  • Values restricted to {@linkplain Number} (you can do maths on the values)
  • *
  • The option to associate a name and colour with the data
  • *
  • The option to define an accumlator function to be used with multilple/subsequent put operations on the * same key
  • *
  • Some additional methods to work with primitive keys and values more efficiently
  • *
  • A few additional methods to help access and modify series entries
  • *
* The extension {@link NaturallySequenced} is typically used with time series data. * * @author apete */ public interface BasicSeries, V extends Comparable> extends SortedMap { /** * A series with naturally sequenced keys - given any key there is a natural "next" key, e.g. with a * series of daily values the natural next key is the next day. Further, natural sequencing implies a * bidirectional mapping between the keys and long indices. * * @author apete */ interface NaturallySequenced, V extends Comparable> extends BasicSeries, Access1D { default PrimitiveSeries asPrimitive() { return PrimitiveSeries.wrap(this); } /** * Will fill in missing values, inbetween the first and last keys. */ default void complete() { K tmpKey = this.firstKey(); V tmpVal = null; V patchVal = this.firstValue(); final K lastKey = this.lastKey(); while (tmpKey.compareTo(lastKey) <= 0) { tmpVal = this.get(tmpKey); if (tmpVal != null) { patchVal = tmpVal; } else { this.put(tmpKey, patchVal); } tmpKey = this.step(tmpKey); } } /** * A natural sequence implies a bidirectional mapping between the keys and long indices. This * {@link org.ojalgo.structure.Structure1D.IndexMapper} specifies that mapping. Please note that * multiple instaces of the key type could correspnd to the same index, and not all long values are * valid indices. The conversions key -> index -> key may not return the original key. */ IndexMapper mapper(); /** * @return The next, after the {@link #lastKey()}, key. */ default K nextKey() { return this.step(this.lastKey()); } double put(long index, double value); V put(long index, V value); default int size() { return Access1D.super.size(); } K step(K key); } public static final class TimeSeriesBuilder> { private K myReference = null; private CalendarDate.Resolution myResolution = null; private final TimeIndex myTimeIndex; TimeSeriesBuilder(final TimeIndex timeIndex) { super(); myTimeIndex = timeIndex; } public > BasicSeries.NaturallySequenced build(final DenseArray.Factory denseArrayFactory) { ProgrammingError.throwIfNull(denseArrayFactory); return this.doBuild(denseArrayFactory, null); } public > BasicSeries.NaturallySequenced build(final DenseArray.Factory denseArrayFactory, final BinaryFunction accumularor) { ProgrammingError.throwIfNull(denseArrayFactory, accumularor); return this.doBuild(denseArrayFactory, accumularor); } public TimeSeriesBuilder reference(final K reference) { myReference = reference; return this; } public TimeSeriesBuilder resolution(final CalendarDate.Resolution resolution) { myResolution = resolution; return this; } private > BasicSeries.NaturallySequenced doBuild(final DenseArray.Factory arrayFactory, final BinaryFunction accumularor) { if (myReference != null) { if (myResolution != null) { return new MappedIndexSeries<>(arrayFactory, myTimeIndex.from(myReference, myResolution), accumularor); } else { return new MappedIndexSeries<>(arrayFactory, myTimeIndex.from(myReference), accumularor); } } else { if (myResolution != null) { return new MappedIndexSeries<>(arrayFactory, myTimeIndex.plain(myResolution), accumularor); } else { return new MappedIndexSeries<>(arrayFactory, myTimeIndex.plain(), accumularor); } } } } BasicSeries.TimeSeriesBuilder CALENDAR = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.CALENDAR); BasicSeries.TimeSeriesBuilder CALENDAR_DATE = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.CALENDAR_DATE); BasicSeries.TimeSeriesBuilder DATE = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.DATE); BasicSeries.TimeSeriesBuilder INSTANT = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.INSTANT); BasicSeries.TimeSeriesBuilder LOCAL_DATE = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.LOCAL_DATE); BasicSeries.TimeSeriesBuilder LOCAL_DATE_TIME = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.LOCAL_DATE_TIME); BasicSeries.TimeSeriesBuilder LOCAL_TIME = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.LOCAL_TIME); BasicSeries.TimeSeriesBuilder OFFSET_DATE_TIME = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.OFFSET_DATE_TIME); BasicSeries.TimeSeriesBuilder ZONED_DATE_TIME = new BasicSeries.TimeSeriesBuilder<>(TimeIndex.ZONED_DATE_TIME); static > CoordinatedSet coordinate(final List> uncoordinated) { return CoordinatedSet.from(uncoordinated); } static > K findEarliestFirstKey(final Collection> collection) { K retVal = null, tmpVal = null; for (final BasicSeries individual : collection) { tmpVal = individual.firstKey(); if ((retVal == null) || (tmpVal.compareTo(retVal) < 0)) { retVal = tmpVal; } } return retVal; } static > K findEarliestLastKey(final Collection> collection) { K retVal = null, tmpVal = null; for (final BasicSeries individual : collection) { tmpVal = individual.lastKey(); if ((retVal == null) || (tmpVal.compareTo(retVal) < 0)) { retVal = tmpVal; } } return retVal; } static > K findLatestFirstKey(final Collection> collection) { K retVal = null, tmpVal = null; for (final BasicSeries individual : collection) { tmpVal = individual.firstKey(); if ((retVal == null) || (tmpVal.compareTo(retVal) > 0)) { retVal = tmpVal; } } return retVal; } static > K findLatestLastKey(final Collection> collection) { K retVal = null, tmpVal = null; for (final BasicSeries individual : collection) { tmpVal = individual.lastKey(); if ((retVal == null) || (tmpVal.compareTo(retVal) > 0)) { retVal = tmpVal; } } return retVal; } static BasicSeries make(final DenseArray.Factory arrayFactory) { return new MappedIndexSeries<>(arrayFactory, MappedIndexSeries.MAPPER, null); } static BasicSeries make(final DenseArray.Factory arrayFactory, final BinaryFunction accumulator) { return new MappedIndexSeries<>(arrayFactory, MappedIndexSeries.MAPPER, accumulator); } static > BasicSeries make(final DenseArray.Factory arrayFactory, final Structure1D.IndexMapper indexMapper) { return new MappedIndexSeries<>(arrayFactory, indexMapper, null); } static > BasicSeries make(final DenseArray.Factory arrayFactory, final Structure1D.IndexMapper indexMapper, final BinaryFunction accumulator) { return new MappedIndexSeries<>(arrayFactory, indexMapper, accumulator); } PrimitiveSeries asPrimitive(); BasicSeries colour(ColourData colour); double doubleValue(final K key); V firstValue(); V get(final K key); ColourData getColour(); String getName(); V lastValue(); BasicSeries name(String name); /** * @see #put(Comparable, Number) */ double put(final K key, final double value); /** * Some implementations may specify an accumulator function to be used with subsequent put operation with * the same key. If such an accumulator is present it should be used here, and in that case the method * returns the new/accumulated/mixed value. With out an accumulator this method should behave exactly as * with any other {@link Map}. * * @see java.util.Map#put(java.lang.Object, java.lang.Object) */ V put(final K key, final V value); default void putAll(final Collection> data) { for (final KeyValue tmpKeyValue : data) { this.put(tmpKeyValue.getKey(), tmpKeyValue.getValue()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy