001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.ml.timeseries.processor.interpolation;
031
032import org.openimaj.ml.timeseries.TimeSeries;
033import org.openimaj.ml.timeseries.processor.TimeSeriesProcessor;
034import org.openimaj.ml.timeseries.processor.interpolation.util.TimeSpanUtils;
035import org.openimaj.ml.timeseries.series.DoubleTimeSeries;
036
037/**
038 * Interpolate values of a time series. Useful for filling in missing values and
039 * homogonising disperate sets of {@link TimeSeries} data
040 *
041 * @author Sina Samangooei (ss@ecs.soton.ac.uk)
042 *
043 */
044public abstract class TimeSeriesInterpolation implements TimeSeriesProcessor<double[], Double, DoubleTimeSeries> {
045
046        private long[] times;
047
048        /**
049         * The processor's times are set to default, i.e. from min to max time in
050         * steps of 1 long
051         */
052        public TimeSeriesInterpolation() {
053                times = null;
054        }
055
056        /**
057         * @param begin
058         * @param end
059         * @param delta
060         */
061        public TimeSeriesInterpolation(long begin, long end, long delta) {
062                this.times = TimeSpanUtils.getTime(begin, end, delta);
063        }
064
065        /**
066         * @param begin
067         * @param steps
068         * @param delta
069         */
070        public TimeSeriesInterpolation(long begin, int steps, long delta) {
071                this.times = TimeSpanUtils.getTime(begin, steps, delta);
072        }
073
074        /**
075         * @param begin
076         *            the start of the new time series
077         * @param end
078         *            the end of the new time series
079         * @param steps
080         *            the steps between (begin = 0, end = 10, 6 steps will give 0,
081         *            2, 4, 6, 8, 10
082         */
083        public TimeSeriesInterpolation(long begin, long end, int steps) {
084                this.times = TimeSpanUtils.getTime(begin, end, steps);
085        }
086
087        /**
088         * @param times
089         *            the times used by the processor
090         */
091        public TimeSeriesInterpolation(long[] times) {
092                this.times = times;
093        }
094
095        /**
096         * Uses {@link #interpolate(DoubleTimeSeries, long[])} to return an
097         * interpolation of the construction {@link TimeSeries} between the times at
098         * the required interval
099         * 
100         * @param series
101         * @param begin
102         *            time to start
103         * @param end
104         *            time to end
105         * @param delta
106         *            the delta between time steps
107         * @return {@link DoubleTimeSeries} instance interpolated from the
108         *         construction {@link TimeSeries} instance
109         */
110        public DoubleTimeSeries interpolate(DoubleTimeSeries series, long begin, long end, long delta) {
111                final long[] times = TimeSpanUtils.getTime(begin, end, delta);
112                return interpolate(series, times);
113        }
114
115        /**
116         * Uses {@link #interpolate(DoubleTimeSeries, long[])} to return an
117         * interpolation of the construction {@link TimeSeries} from begin, for a
118         * number of steps with a given delta between steps
119         * 
120         * @param series
121         * @param begin
122         * @param steps
123         * @param delta
124         * @return {@link DoubleTimeSeries} instance interpolated from the
125         *         construction {@link TimeSeries} instance
126         */
127        public DoubleTimeSeries interpolate(DoubleTimeSeries series, long begin, int steps, long delta) {
128                final long[] times = TimeSpanUtils.getTime(begin, steps, delta);
129                return interpolate(series, times);
130        }
131
132        /**
133         * Uses {@link #interpolate(DoubleTimeSeries,long[])} to return an
134         * interpolation of the construction {@link TimeSeries} from begin, until
135         * end with a delta which means that there are splits time instances
136         * 
137         * @param series
138         * @param begin
139         * @param end
140         * @param splits
141         * @return {@link DoubleTimeSeries} instance interpolated from the
142         *         construction {@link TimeSeries} instance
143         */
144        public DoubleTimeSeries interpolate(DoubleTimeSeries series, long begin, long end, int splits) {
145                final long[] times = TimeSpanUtils.getTime(begin, end, splits);
146                return interpolate(series, times);
147        }
148
149        /**
150         * @param series
151         * @return a new {@link DoubleTimeSeries} interpolated with times provided
152         *         in the constructor
153         */
154        public DoubleTimeSeries interpolate(DoubleTimeSeries series) {
155                return interpolate(series, this.times);
156        }
157
158        /**
159         * @param series
160         * @param times
161         *            might be null, therefore some "defualt" time step should be
162         *            used
163         * @return {@link DoubleTimeSeries} instance interpolated from the
164         *         construction {@link TimeSeries} instance
165         */
166        public abstract DoubleTimeSeries interpolate(DoubleTimeSeries series, long[] times);
167
168        @Override
169        public void process(DoubleTimeSeries ts) {
170                ts.internalAssign(this.interpolate(ts, times));
171        }
172}