178 lines
4.9 KiB
C#
178 lines
4.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace IOB_UT_NEXT.Objects
|
|
{
|
|
/// <summary>
|
|
/// Classe gestione valori campionati su periodo
|
|
/// </summary>
|
|
public class sampleVect
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Inizializzo l'oggetto
|
|
/// </summary>
|
|
public sampleVect()
|
|
{
|
|
// init valori default...
|
|
windSize = baseUtils.CRI("countWindSize") > 0 ? baseUtils.CRI("countWindSize") : 60;
|
|
lTime = new List<DateTime>();
|
|
lVal = new List<int>();
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// Calcola il valore mediano...
|
|
/// </summary>
|
|
public double vcMedian
|
|
{
|
|
get
|
|
{
|
|
double answ = 0;
|
|
// restituisce la mediana SE valida, altrimenti null...
|
|
if (numElem > 2 && flWindSize > windSize)
|
|
{
|
|
try
|
|
{
|
|
// calcolo mediana!
|
|
//answ = Statistics.Median(lVal.ToArray());
|
|
|
|
// rif: https://blogs.msmvps.com/deborahk/linq-mean-median-and-mode/
|
|
var sortedNumbers = lVal.OrderBy(n => n);
|
|
int numCount = lVal.Count;
|
|
int indice50 = lVal.Count / 2;
|
|
if ((numCount % 2) == 0)
|
|
{
|
|
answ = ((sortedNumbers.ElementAt(indice50) + sortedNumbers.ElementAt(indice50 - 1)) / 2);
|
|
}
|
|
else
|
|
{
|
|
answ = sortedNumbers.ElementAt(indice50);
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica se la vc sia valida (ovvero almeno 2 valori e intervallo > window richiesta)
|
|
/// </summary>
|
|
public bool vcValid
|
|
{
|
|
get
|
|
{
|
|
return (flWindSize > windSize && numElem > 1);
|
|
}
|
|
}
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Aggiunge un valore alla serie ed eventualmente elimina i valori superflui a garantirne
|
|
/// una finestra temporale valida
|
|
/// </summary>
|
|
/// <param name="tempo"></param>
|
|
/// <param name="valore"></param>
|
|
public void addValue(DateTime tempo, int valore)
|
|
{
|
|
lTime.Add(tempo);
|
|
lVal.Add(valore);
|
|
// verifico se siano da accorciare le serie... ovvero i 2 intervalli ENTRAMBI sono
|
|
// superiori al periodo minimo (in tal caso riduco..
|
|
while (flWindSize > windSize && slWindSize > windSize)
|
|
{
|
|
// elimino i 2 valori + vecchi
|
|
lTime.RemoveAt(0);
|
|
lVal.RemoveAt(0);
|
|
// ora ricontrollo...
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// vettore valori temporali della serie
|
|
/// </summary>
|
|
protected List<DateTime> lTime;
|
|
|
|
/// <summary>
|
|
/// vettore valori puntuali della serie
|
|
/// </summary>
|
|
protected List<int> lVal;
|
|
|
|
/// <summary>
|
|
/// Dimensione finestra di campionamento (secondi)
|
|
/// </summary>
|
|
protected int windSize;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Properties
|
|
|
|
/// <summary>
|
|
/// Verifica ampiezza finestra valori First-Last
|
|
/// </summary>
|
|
protected double flWindSize
|
|
{
|
|
get
|
|
{
|
|
double answ = 0;
|
|
if (numElem > 1)
|
|
{
|
|
answ = lTime.Last().Subtract(lTime[0]).TotalSeconds;
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Conteggio elementi
|
|
/// </summary>
|
|
protected int numElem
|
|
{
|
|
get
|
|
{
|
|
int answ = 0;
|
|
try
|
|
{
|
|
answ = lTime.Count;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica ampiezza finestra valori Second-Last
|
|
/// </summary>
|
|
protected double slWindSize
|
|
{
|
|
get
|
|
{
|
|
double answ = 0;
|
|
if (numElem > 2) // altrimenti SE non ne ho almeno 3 NON posso avere secondo/ultimo...
|
|
{
|
|
answ = lTime.Last().Subtract(lTime[1]).TotalSeconds;
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
#endregion Protected Properties
|
|
}
|
|
|
|
}
|