Идеи, разыскиваемые для анализа данных о почти реальном времени, через определенные интервалы с эффективностью памяти/процессора
-
25-10-2019 - |
Вопрос
У меня есть некоторые датчики окружающей среды, и я хочу обнаружить внезапные изменения в температуре и медленные тенденции с течением времени ... однако я хотел бы сделать большую часть математики на основе того, что находится в памяти, с параметрами, которые могут выглядеть так: (При условии сдача)
(Примечание: элементы в паренах вычисляются в режиме реального времени при добавлении данных)
- 5 -минутный (производный, максимум, мин, AVG) + 36 DataPoints для большинства текущих 3 часов
- 10 -минутная (производная, максимум, мин, AVG) + 0 DataPoints, Calc основан на 5 -минутном образце
- 30 -минутная (производная, максимум, мин, AVG) + 0 DataPoints, Calc основан на 5 -минутном образце
- Почасовая (производная, максимум, мин, AVG) + 24 DataPoints для большинства текущих 1 дня
- Daily (Drevative, Max, Min, AVG) + 32 DataPoints для большинства текущего месяца
- Ежемесячный (Деривативный, Макс, Мин, AVG) + 12 данных DataPoints за прошедший год
Каждый данных - это два байтового поплавка. Таким образом, каждый датчик будет потреблять до 124 поплавок, плюс 24 рассчитанные переменные. Я хотел бы поддерживать столько датчиков, сколько позволяет устройство .NET Enceddd.
Поскольку я использую встроенное устройство для этого проекта, моя память ограничена, как и моя мощность ввода -вывода и процессора.
Как бы вы внедрили это в .net? До сих пор я создал пару структур и назвал это "TrackableFloat
«Где вставка значения заставляет старый сбросить массив, а пересчет выполняется.
Единственное, что делает это более сложным, чем было бы, - это то, что для любого датчика не сообщается о данных обратно, тогда этот DataPoint должен быть исключен/игнорирован из всех последующих калут в реальном времени.
Когда все сказано и сделано, если какое -либо из значений: (Деривативная, максимум, мин, avg) достичь предварительно определенной настройки, то событие .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;
}
}
}
}
}
}
Решение
Вы должны подумать о том, чтобы посмотреть на Прозрачный библиотека как Неспер.