测试值的采样率 远低于测试台的采样率 。这样两个波形是否一致?我们通过采取等样抽取的方式抽取出测试台的数据,计算出最小的标准误差。
#region 计算 两个 sin 正弦波 的误差
private double[] getValuable(double[] data)
{
int indexHigh = 0;int indexLow = 0; int cnt = 0; int indexS = 0;
for (int i = 0; i < data.Length; i++)
{
double max = 0;double min = 0;
if (data[i] >= max) { max = data[i]; indexHigh = i; }
if (data[i] <= min) { min = data[i]; indexLow = i; }
}
cnt = ( indexLow- indexHigh) * 2;
indexS = indexHigh - (indexLow-indexHigh) /2;
double[] buf = new double[cnt];
Array.Copy(data, indexS, buf, 0,cnt);
return buf;
} //获取有用的数据
private double[] getSample(double[] b, int len,int step=0) //取样
{
//double b 是否需要优化
double[] buf = new double[len];
List<int> indexList = sampleList(b.Length, len);
foreach (int index in indexList)
{
if (index + step >= b.Length) {
buf[index] = b[b.Length-1];
}
else
{
buf[index] = b[index + step];
}
}
return buf;
}
private List<int> sampleList(int inputLen, int sampleLen) //返回的是各取样点的索引值的List
{
// inputLen>= len
double stepSize = (double)inputLen / sampleLen;//初始步长
// 兼容inputLen< len 的情况
if (stepSize < 1)
stepSize = 1;
List<int> IndexList = new List<int>();//索引值的List
for (int i = 0, n = 0; i < inputLen || n < sampleLen; n++)//i是待处理数据的索引,n是循环次数
{
var currentStepIndex = n * stepSize;
var currentIndex = nearestInteger(currentStepIndex);
if (currentIndex >= inputLen)
{
break;
}
if (IndexList.Contains(currentIndex))
{
currentIndex++;
if (currentIndex >= inputLen)
break;
}
IndexList.Add(currentIndex);
i = currentIndex;
}
return IndexList;
}
private int nearestInteger(double data) //向下取整
{
int ret = 0;
double input = Math.Ceiling(data);//向上取整
double step = Math.Floor(data);//向下取整
if (Math.Abs(input - data) >= Math.Abs(data - step))
{
ret = (int)step;
}
else
{
ret = (int)input;
}
return ret;
}
private double RMSE(double[] a, double[] b,out double min,out double max) //根据 RMSE 标准误差公式
{
min = a.Min(); max = a.Max();
double sum = 0;
for (int i = 0; i < a.Length; i++)
{
sum += (a[i] - b[i]) * (a[i] - b[i]);
}
sum = sum / a.Length;
sum = Math.Sqrt(sum);
return sum;
}
/// <summary>
/// 计算 两个 sin 正弦波 的误差
/// </summary>
/// <param name="ECU"> 测试值 </param>
/// <param name="Tester">观察值</param>
/// <param name="min">输出最小测量值</param>
/// <param name="max">输入最大测量值</param>
public void calcRMS(double[] ECU, double[] Tester, out double min, out double max)
{
double[] a = getValuable(ECU);
double[]temp = getValuable(Tester); // 需不需要优化 平顺 信号
min = a.Min(); max = a.Max();
int step = temp.Length / a.Length; // step 最大值 是temp.Length/a.Length
step = 0; //
double minRMS = 100;
for (int i = 0; i <= step; i++)
{
double[] b = getSample(temp, a.Length, step);
double rms = RMSE(a, b, out min, out max);
if (rms < minRMS) { minRMS = rms; }
}
}
#endregion