/// <summary> /// Calculate the root mean sqaure value of array data. Supported data type: double/float/int. /// </summary> /// <param name="data">The array data to calculate statistic value.</param> /// <typeparam name="TDataType">Supported data type: double/float/int.</typeparam> /// <returns>The root mean square value of array data.</returns> /// <exception cref="NotSupportedException">Supported data type: double/float/int.</exception> public static double RootMeanSqaure <TDataType>(TDataType[] data) { double rootMeanSqure = double.NaN; if (ReferenceEquals(typeof(TDataType), typeof(double))) { double[] doubleData = data as double[]; rootMeanSqure = ArrayStatistics.RootMeanSquare(doubleData); } else if (ReferenceEquals(typeof(TDataType), typeof(float))) { float[] floatData = data as float[]; rootMeanSqure = ArrayStatistics.RootMeanSquare(floatData); } else if (ReferenceEquals(typeof(TDataType), typeof(int))) { int[] intData = data as int[]; rootMeanSqure = ArrayStatistics.RootMeanSquare(intData); } else { throw new NotSupportedException("Unsupported data type."); } return(rootMeanSqure); }
/// <summary> /// Find the RMS value from the double array (supported platforms: MathNet) /// </summary> /// <param name="data">input data</param> /// <returns>RMS value</returns> public static double RMS(double[] data) { try { //IPP does not support RMS function yet switch (Engine.Provider) { case ProviderEngine.MathNet: return(ArrayStatistics.RootMeanSquare(data)); default: return(ArrayStatistics.RootMeanSquare(data)); } } catch (Exception ex) { throw new Exception(ex.Message); } }
private double[] ApplyAggregationFunction(AggregationMethod method, string argument, int kernelSize, double[] data, double nanLimit, ILogger logger) { var targetDatasetLength = data.Length / kernelSize; var result = new double[targetDatasetLength]; switch (method) { case AggregationMethod.Mean: Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var isHighQuality = (chunkData.Length / (double)kernelSize) >= nanLimit; if (isHighQuality) { result[x] = ArrayStatistics.Mean(chunkData); } else { result[x] = double.NaN; } }); break; case AggregationMethod.MeanPolar: double[] sin = new double[targetDatasetLength]; double[] cos = new double[targetDatasetLength]; double limit; if (argument.Contains("*PI")) { limit = Double.Parse(argument.Replace("*PI", "")) * Math.PI; } else { limit = Double.Parse(argument); } var factor = 2 * Math.PI / limit; Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var length = chunkData.Length; var isHighQuality = (length / (double)kernelSize) >= nanLimit; if (isHighQuality) { for (int i = 0; i < chunkData.Length; i++) { sin[x] += Math.Sin(chunkData[i] * factor); cos[x] += Math.Cos(chunkData[i] * factor); } result[x] = Math.Atan2(sin[x], cos[x]) / factor; if (result[x] < 0) { result[x] += limit; } } else { result[x] = double.NaN; } }); break; case AggregationMethod.Min: Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var isHighQuality = (chunkData.Length / (double)kernelSize) >= nanLimit; if (isHighQuality) { result[x] = ArrayStatistics.Minimum(chunkData); } else { result[x] = double.NaN; } }); break; case AggregationMethod.Max: Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var isHighQuality = (chunkData.Length / (double)kernelSize) >= nanLimit; if (isHighQuality) { result[x] = ArrayStatistics.Maximum(chunkData); } else { result[x] = double.NaN; } }); break; case AggregationMethod.Std: Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var isHighQuality = (chunkData.Length / (double)kernelSize) >= nanLimit; if (isHighQuality) { result[x] = ArrayStatistics.StandardDeviation(chunkData); } else { result[x] = double.NaN; } }); break; case AggregationMethod.Rms: Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var isHighQuality = (chunkData.Length / (double)kernelSize) >= nanLimit; if (isHighQuality) { result[x] = ArrayStatistics.RootMeanSquare(chunkData); } else { result[x] = double.NaN; } }); break; case AggregationMethod.SampleAndHold: Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var isHighQuality = (chunkData.Length / (double)kernelSize) >= nanLimit; if (isHighQuality) { result[x] = chunkData.First(); } else { result[x] = double.NaN; } }); break; case AggregationMethod.Sum: Parallel.For(0, targetDatasetLength, x => { var chunkData = this.GetNaNFreeData(data, x, kernelSize); var isHighQuality = (chunkData.Length / (double)kernelSize) >= nanLimit; if (isHighQuality) { result[x] = Vector <double> .Build.Dense(chunkData).Sum(); } else { result[x] = double.NaN; } }); break; default: logger.LogWarning($"The aggregation method '{method}' is not known. Skipping period."); break; } return(result); }