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 @ 15926

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

#2913:

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