Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2913_MatlabScriptProblemInstanceProvider/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/Matlab/Api/Types/MLTimeseries.cs @ 15919

Last change on this file since 15919 was 15919, checked in by rhanghof, 6 years ago

#2913: The import does now work with Matlab timeseries datatypes.

File size: 5.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6
7namespace HeuristicLab.Problems.Instances.DataAnalysis.Regression.Matlab.Api.Types {
8  using TMLTimeseriesValueDT = IMLValueVariable<IList<KeyValuePair<double, double[]>>>;
9  public class MLTimeseries : IMLValueVariable<IList<KeyValuePair<double, double[]>>>, IMLTimeseries {
10    private readonly object _locker = new object();
11
12    private string[] _dataHeaders;
13
14    #region Constructors
15
16    protected MLTimeseries() {
17      Data = new List<KeyValuePair<double, double[]>>();
18      Name = string.Empty;
19    }
20
21    /// <summary>
22    /// Creates a new timeseries from the given collection of timeseries.
23    /// All values will be merged into one time series.
24    /// </summary>
25    /// <param name="timeseries"></param>
26    public MLTimeseries(IEnumerable<MLTimeseries> timeseries) : this() {
27      var dataHeaders = new List<string>();
28      var times = new SortedSet<double>(); // The time values have to be unique and sorted.
29
30      foreach (var item in timeseries) {
31        foreach (var dataHeader in item.DataHeader) {
32          dataHeaders.Add(dataHeader);
33        }
34
35        foreach (var time in item.Times) {
36          times.Add(time);
37        }
38      }
39     
40
41      IList<MLTimeseries> tsCollection;
42      if (!(timeseries is IList<MLTimeseries>)) {
43        tsCollection = timeseries.ToList();
44      } else {
45        tsCollection = timeseries as IList<MLTimeseries>;
46      }
47
48      int[] indices = new int[tsCollection.Count];
49      var numberOfElements = dataHeaders.Count;
50      foreach (var time in times) {
51        var values = new double[numberOfElements];
52        int idx = 0;
53        for (int i = 0; i < tsCollection.Count; i++) {
54          var item = tsCollection[i];
55          double[] vs;
56          if (indices[i] == 0 && item.Data[indices[i]].Key > time) {
57            vs = new double[item.Data[0].Value.Length];
58          } else {
59            if (indices[i] < item.Count - 1 && item.Data[indices[i] + 1].Key == time) {
60              indices[i]++;
61            }
62            vs = item.Data[indices[i]].Value;
63          }         
64
65          foreach (var v in vs) {
66            values[idx++] = v;
67          }
68        }
69
70        lock (_locker) {
71          Data.Add(new KeyValuePair<double, double[]>(time, values));
72        }
73      }
74      _dataHeaders = dataHeaders.ToArray();
75    }
76
77    public MLTimeseries(string name, object times, object data) : this() {
78      Name = name;
79
80      if (!(times is double[,]) || !(data is double[,])) {
81        throw new ArgumentException(string.Format("Invalid datatype: times={0}, data={1}", times.GetType(), data.GetType()));
82      }
83
84      var t = times as double[,];
85      var d = data as double[,];
86
87      if (t.GetLength(0) != d.GetLength(0)) {
88        throw new ArgumentException(string.Format("Number of elements are not equal: times={0}, data={1}", t.GetLength(0), d.GetLength(0)));
89      }
90
91      var valueColumns = d.GetLength(1);
92      _dataHeaders = new string[valueColumns];
93
94      for (int i = 0; i < valueColumns; i++) {
95        _dataHeaders[i] = string.Format("{0}:{1}", Name, i);
96      }
97
98      for (int i = 0; i < t.GetLength(0); i++) {
99        var time = t[i, 0];
100        var vals = new double[valueColumns];
101        for (int j = 0; j < valueColumns; j++) {
102          vals[j] = d[i, j];
103        }
104        Data.Add(new KeyValuePair<double, double[]>(time, vals));
105      }
106    }
107
108    private MLTimeseries(IMLTimeseries original) : this() {
109      Name = ((TMLTimeseriesValueDT)original).Name;
110
111      _dataHeaders = (string[])original.DataHeader.Clone();
112
113      foreach (var entry in ((TMLTimeseriesValueDT)original).Data) {
114        Data.Add(new KeyValuePair<double, double[]>(entry.Key, entry.Value));
115      }
116    }
117    #endregion
118
119    public string Name { get; set; }
120
121    public IList<KeyValuePair<double, double[]>> Data { get; set; }
122
123    public MLDatatype Datatype {
124      get { return MLDatatype.Timeseries; }
125    }
126
127    public string[] DataHeader {
128      get { return _dataHeaders; }
129    }
130
131    public double[] this[int idx] {
132      get {
133        var entry = Data[idx];
134        var values = new double[entry.Value.Length + 1];
135        values[0] = Data[idx].Key;
136        for (int i = 1; i < values.Length; i++) {
137          values[i] = entry.Value[i - 1];
138        }
139        return values;
140      }
141    }
142
143    public double[] Times {
144      get {
145        return Data.Select(x => x.Key).ToArray();
146      }
147    }
148
149    public double GetTimeAt(int idx) {
150      if (idx < Data.Count) {
151        return Data[idx].Key;
152      }
153
154      return double.MaxValue;
155    }
156
157    public int Count {
158      get {
159        return Data.Count;
160      }
161    }
162
163    public double[] GetValuesByTime(double time) {
164      double[] value;
165      if (Data.Count < 0) {
166        value = new double[] { 0.0 };
167      }
168      value = Data.Where(x => x.Key <= time).LastOrDefault().Value;
169      if (value == null) {
170        return new double[Data[0].Value.Length];
171      }
172      return value;
173    }
174
175    public IMLTimeseries ToTimeseries() {
176      return new MLTimeseries(this);
177    }
178  }
179}
Note: See TracBrowser for help on using the repository browser.