Example #1
0
 public static TimeSeriesValues Differentiate(TimeSeriesValues seq)
 {
     using (seq.Lock.GetReadLock()) {
         TimeSeriesValues ret = new TimeSeriesValues(seq.ColumnNames.Select(n => "diff " + n).ToArray());
         for (int i = 0; i < seq.SequenceLength - 1; i++)
         {
             decimal preTime, postTime;
             if (!seq.TryGetTimeFromIndex(i, out preTime) || !seq.TryGetTimeFromIndex(i + 1, out postTime))
             {
                 continue;
             }
             decimal elapse = postTime - preTime;
             if (elapse > 0)
             {
                 decimal?[] pre  = seq[i];
                 decimal?[] post = seq[i + 1];
                 decimal?[] diff = new decimal?[seq.ColumnCount];
                 for (int j = 0; j < seq.ColumnCount; j++)
                 {
                     if (pre[j].HasValue && post[j].HasValue)
                     {
                         diff[j] = (post[j].Value - pre[j].Value) / elapse;
                     }
                 }
                 ret[preTime] = diff;
             }
         }
         return(ret);
     }
 }
Example #2
0
 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);
     }
 }
Example #3
0
        /// <summary>
        /// シーケンスの移動平均を求めます
        /// </summary>
        /// <param name="seq">シーケンス</param>
        /// <param name="smoothSpan">移動平均を取る時間範囲</param>
        /// <param name="timeOffset">出力の時間のオフセット.0で時間範囲の終了点の時間,smoothSpanの値で時間範囲の開始点の時間のところに出力される</param>
        /// <param name="limitRatioToContainEmptyValue">データの欠損があっても値を出力する限界率(0~1)</param>
        /// <returns></returns>
        public static TimeSeriesValues TimeSmooth(TimeSeriesValues seq, decimal smoothSpan, decimal timeOffset, decimal limitRatioToContainEmptyValue)
        {
            using (seq.Lock.GetReadLock()) {
                if (smoothSpan < 0)
                {
                    throw new ArgumentOutOfRangeException("time", "'time' cannot be negative");
                }
                TimeSeriesValues ret       = new TimeSeriesValues(seq.ColumnNames);
                int[]            nullCount = new int[seq.ColumnCount];
                decimal[]        sum       = new decimal[seq.ColumnCount];
                int count      = 0;
                int beginIndex = 0;
                for (int endIndex = 0; endIndex < seq.SequenceLength; endIndex++)
                {
                    decimal endTime;
                    if (!seq.TryGetTimeFromIndex(endIndex, out endTime))
                    {
                        continue;
                    }

                    for (int j = 0; j < seq.ColumnCount; j++)
                    {
                        if (seq[endIndex][j].HasValue)
                        {
                            sum[j] += seq[endIndex][j].Value;
                        }
                        else
                        {
                            nullCount[j]++;
                        }
                    }
                    count++;

                    decimal beginTime;
                    while (beginIndex < endIndex && seq.TryGetTimeFromIndex(beginIndex, out beginTime))
                    {
                        if (beginTime > endTime - smoothSpan)
                        {
                            break;
                        }
                        for (int j = 0; j < seq.ColumnCount; j++)
                        {
                            if (seq[beginIndex][j].HasValue)
                            {
                                sum[j] -= seq[beginIndex][j].Value;
                            }
                            else
                            {
                                nullCount[j]--;
                            }
                        }
                        count--;
                        beginIndex++;
                    }
                    Debug.Assert(nullCount.Max() <= count);
                    Debug.Assert(count > 0);
                    decimal?[] values = new decimal?[seq.ColumnCount];
                    for (int j = 0; j < seq.ColumnCount; j++)
                    {
                        decimal rate       = (decimal)nullCount[j] / count;
                        int     validCount = count - nullCount[j];
                        if (rate <= limitRatioToContainEmptyValue && validCount > 0)
                        {
                            values[j] = sum[j] / validCount;
                        }
                        else
                        {
                            values[j] = null;
                        }
                    }
                    ret[endTime + timeOffset] = values;
                }
                return(ret);
            }
        }