C# 需要使用内存/cpu效率在特定时间间隔内分析近实时数据的想法
我有一些环境传感器,我想检测温度的突然变化,以及随时间变化的缓慢趋势。。。然而,我想根据内存中的参数来做大部分的数学运算,这些参数可能是这样的:(可能会改变) (注:参数中的项目在添加数据时实时计算)C# 需要使用内存/cpu效率在特定时间间隔内分析近实时数据的想法,c#,math,real-time,.net-micro-framework,C#,Math,Real Time,.net Micro Framework,我有一些环境传感器,我想检测温度的突然变化,以及随时间变化的缓慢趋势。。。然而,我想根据内存中的参数来做大部分的数学运算,这些参数可能是这样的:(可能会改变) (注:参数中的项目在添加数据时实时计算) 5分钟(导数、最大值、最小值、平均值)+36个数据点,最新3小时 10分钟(导数、最大值、最小值、平均值)+0个数据点,计算基于5分钟样本 30分钟(导数、最大值、最小值、平均值)+0个数据点,计算基于5分钟样本 每小时(导数、最大值、最小值、平均值)+24个数据点,最新1天 每日(导数、最大值
- 5分钟(导数、最大值、最小值、平均值)+36个数据点,最新3小时
- 10分钟(导数、最大值、最小值、平均值)+0个数据点,计算基于5分钟样本
- 30分钟(导数、最大值、最小值、平均值)+0个数据点,计算基于5分钟样本
- 每小时(导数、最大值、最小值、平均值)+24个数据点,最新1天
- 每日(导数、最大值、最小值、平均值)+当前月份的32个数据点
- 过去一年每月(导数、最大值、最小值、平均值)+12个数据点
TrackableFloat
”,其中插入一个值会导致旧的值从数组中删除,并进行重新计算
唯一能让这更有趣的是
比这更复杂,是吗
对于任何传感器,都不会返回报告
数据,那么该数据点需要
从所有后续文件中排除/忽略
实时计算
当所有操作都完成后,如果任何值:(导数、最大值、最小值、平均值)达到预定义的设置,则会触发.NET事件
我认为有人会认为这是一个有趣的问题,并希望听到他们将如何实现它
enum UnitToTrackEnum
{
Minute,
FiveMinute,
TenMinute,
FifteenMinute,
Hour,
Day,
Week,
Month,
unknown
}
class TrackableFloat
{
object Gate = new object();
UnitToTrackEnum trackingMode = UnitToTrackEnum.unknown;
int ValidFloats = 0;
float[] FloatsToTrack;
public TrackableFloat(int HistoryLength, UnitToTrackEnum unitToTrack)
{
if (unitToTrack == UnitToTrackEnum.unknown)
throw new InvalidOperationException("You must not have an unknown measure of time to track.");
FloatsToTrack = new float[HistoryLength];
foreach (var i in FloatsToTrack)
{
float[i] = float.MaxValue;
}
trackingMode = unitToTrack;
Min = float.MaxValue;
Max = float.MinValue;
Sum = 0;
}
public void Add(DateTime dt, float value)
{
int RoundedDTUnit = 0;
switch (trackingMode)
{
case UnitToTrackEnum.Minute:
{
RoundedDTUnit = dt.Minute;
break;
}
case UnitToTrackEnum.FiveMinute:
{
RoundedDTUnit = System.Math.Abs(dt.Minute / 5);
break;
}
case UnitToTrackEnum.TenMinute:
{
RoundedDTUnit = System.Math.Abs(dt.Minute / 10);
break;
}
case UnitToTrackEnum.FifteenMinute:
{
RoundedDTUnit = System.Math.Abs(dt.Minute / 15);
break;
}
case UnitToTrackEnum.Hour:
{
RoundedDTUnit = dt.Hour;
break;
}
case UnitToTrackEnum.Day:
{
RoundedDTUnit = dt.Day;
break;
}
case UnitToTrackEnum.Week:
{
//RoundedDTUnit = System.Math.Abs( );
break;
}
case UnitToTrackEnum.Month:
{
RoundedDTUnit = dt.Month;
break;
}
case UnitToTrackEnum.unknown:
{
throw new InvalidOperationException("You must not have an unknown measure of time to track.");
}
default:
break;
}
bool DoRefreshMaxMin = false;
if (FloatsToTrack.Length < RoundedDTUnit)
{
if (value == float.MaxValue || value == float.MinValue)
{
// If invalid data...
lock (Gate)
{
// Get rid of old data...
var OldValue = FloatsToTrack[RoundedDTUnit];
if (OldValue != float.MaxValue || OldValue != float.MinValue)
{
Sum -= OldValue;
ValidFloats--;
if (OldValue == Max || OldValue == Min)
DoRefreshMaxMin = true;
}
// Save new data
FloatsToTrack[RoundedDTUnit] = value;
}
}
else
{
lock (Gate)
{
// Get rid of old data...
var OldValue = FloatsToTrack[RoundedDTUnit];
if (OldValue != float.MaxValue || OldValue != float.MinValue)
{
Sum -= OldValue;
ValidFloats--;
}
// Save new data
FloatsToTrack[RoundedDTUnit] = value;
Sum += value;
ValidFloats++;
if (value < Min)
Min = value;
if (value > Max)
Max = value;
if (OldValue == Max || OldValue == Min)
DoRefreshMaxMin = true;
}
}
// Function is placed here to avoid a deadlock
if (DoRefreshMaxMin == true)
RefreshMaxMin();
}
else
{
throw new IndexOutOfRangeException("Index " + RoundedDTUnit + " is out of range for tracking mode: " + trackingMode.ToString());
}
}
public float Sum { get; set; }
public float Average
{
get
{
if (ValidFloats > 0)
return Sum / ValidFloats;
else
return float.MaxValue;
}
}
public float Min { get; set; }
public float Max { get; set; }
public float Derivative { get; set; }
public void RefreshCounters()
{
lock (Gate)
{
float sum = 0;
ValidFloats = 0;
Min = float.MaxValue;
Max = float.MinValue;
foreach (var i in FloatsToTrack)
{
if (i != float.MaxValue || i != float.MinValue)
{
if (Min == float.MaxValue)
{
Min = i;
Max = i;
}
sum += i;
ValidFloats++;
if (i < Min)
Min = i;
if (i > Max)
Max = i;
}
}
Sum = sum;
}
}
public void RefreshMaxMin()
{
if (ValidFloats > 0)
{
Min = float.MaxValue;
Max = float.MinValue;
lock (Gate)
{
foreach (var i in FloatsToTrack)
{
if (i != float.MaxValue || i != float.MinValue)
{
if (i < Min)
Min = i;
if (i > Max)
Max = i;
}
}
}
}
}
}
enum unittotracknum
{
分钟,
五分钟,
十分钟,
十五分钟,
小时,
白天
周,
月,
未知的
}
类可跟踪浮点
{
对象门=新对象();
UnitToTrackNum trackingMode=UnitToTrackNum.unknown;
int ValidFloats=0;
浮动[]浮动轨道;
公共可跟踪浮点(整数历史长度,UnitToTrackNum unitToTrack)
{
if(unitToTrack==UnitToTrackNum.unknown)
抛出新的InvalidOperationException(“您不能有未知的跟踪时间度量。”);
FloatsToTrack=新浮点[HistoryLength];
foreach(FloatsToTrack中的变量i)
{
float[i]=float.MaxValue;
}
跟踪模式=unitToTrack;
Min=float.MaxValue;
Max=float.MinValue;
总和=0;
}
公共无效添加(日期时间dt,浮点值)
{
int RoundedDTUnit=0;
开关(跟踪模式)
{
案例UnitToTrackNum.分钟:
{
RoundedTunit=dt.分钟;
打破
}
案例UnitToTrackNum.5分钟:
{
RoundedTunit=系统数学绝对值(dt.Minute/5);
打破
}
案例UnitToTrackNum.TenMinute:
{
RoundedTunit=系统数学绝对值(dt.Minute/10);
打破
}
案例单元到tracknum.fiftentenminute:
{
RoundedTunit=系统数学绝对值(dt.Minute/15);
打破
}
案例UnitToTrackNum.小时:
{
RoundedTunit=dt.小时;
打破
}
案例UnitToTrackNum.天:
{
RoundedTunit=dt.天;
打破
}
案例UnitToTrackNum.周:
{
//RoundedDTUnit=System.Math.Abs();
打破
}
案例UnitToTrackNum.月份:
{
RoundedTunit=dt.月;
打破
}
案例UnitToTrackNum.unknown:
{
抛出新的InvalidOperationException(“您不能有未知的跟踪时间度量。”);
}
违约:
打破
}
bool-DoRefreshMaxMin=false;
if(FloatsToTrack.Length