public static TimeSeriesValues OperateWith(TimeSeriesValues seq, TimeSeriesValues operand, Func <decimal?, decimal?, decimal?> operation) { if (operand == null) { throw new ArgumentNullException("operand", "'operand' cannot be null"); } int count = Math.Min(seq.ColumnCount, operand.ColumnCount); TimeSeriesValues ret = new TimeSeriesValues(seq.ColumnNames.Take(count).ToArray()); using (IEnumerator <KeyValuePair <decimal, decimal?[]> > one = seq.Enumerate().GetEnumerator()) using (IEnumerator <KeyValuePair <decimal, decimal?[]> > another = operand.Enumerate().GetEnumerator()) { bool oneAlive = one.MoveNext(); bool anotherAlive = another.MoveNext(); while (oneAlive && anotherAlive) { decimal?[] values = new decimal?[count]; for (int i = 0; i < count; i++) { if (one.Current.Value[i].HasValue && another.Current.Value[i].HasValue) { values[i] = operation(one.Current.Value[i].Value, another.Current.Value[i].Value); } } // 後にある時刻のところに値を入れる // 前にある方を進める if (one.Current.Key < another.Current.Key) { ret.SetValue(another.Current.Key, values); oneAlive = one.MoveNext(); } else { ret.SetValue(one.Current.Key, values); anotherAlive = another.MoveNext(); } } } return(ret); }
public static TimeSeriesValues FrameMean(TimeSeriesValues seq, int meanLength) { using (seq.Lock.GetReadLock()) { if (meanLength <= 0) { throw new ArgumentOutOfRangeException("meanLength", "meanLength > 0"); } TimeSeriesValues ret = new TimeSeriesValues(seq.ColumnNames.Select(n => "mean " + n).ToArray()); for (int i = 0; i < seq.SequenceLength - meanLength; i++) { decimal?[] mean = new decimal?[seq.ColumnCount]; for (int j = 0; j < seq.ColumnCount; j++) { mean[j] = 0; } for (int j = 0; j < seq.ColumnCount; j++) { mean[j] = 0; for (int k = 0; k < meanLength; k++) { decimal?value = seq[i + k][j]; if (value.HasValue) { mean[j] += value.Value; } else { mean[j] = null; break; } } if (mean[j].HasValue) { mean[j] /= meanLength; } } decimal time; if (seq.TryGetTimeFromIndex(i, out time)) { ret.SetValue(time, mean); } } return(ret); } }