Так что, если я собрал это правильно ...
Эта функция возвращает массив средних.(ave)
Здесь определяется первый элемент этого массива:
do i = 1,len
v = v+x(i)
ave(1) = v/flen
Он суммирует (len) количество элементов, а затем делит на (len) - фактически (flen), чтопросто int len преобразуется в вещественное (например, float для c #).
Следующее условное выражение на самом деле производит 0 для многих дополнительных (ave) элементов.Число определяется разницей между (n) и (len).
Он добавляет каждое последующее значение к ранее вычисленной сумме, затем получает среднее значение для нового итога путем деления на (k):as (len + 1)
РЕДАКТИРОВАТЬ: я сделал ошибку в моем первоначальном понимании логики.У меня все еще есть код для того, что я описал.Но код фактически перемещает окно по входному набору, каждый раз получая среднее значение для одного и того же числа элементов, а не накапливая среднее для растущего размера ввода.Я также добавил обновленный ответ в нижней части этого поста.
Имея это в виду, попробуйте этот перевод C #:
public float[] CalcRollingAverage (float[] inputs, int beginAvg, int numInputs)
{
float[] averages = new float[(numInputs - beginAvg + 1)];
float sumUpToBeginAvg = 0;
for(int i = 0; i < beginAvg; i++)
{
sumUpToBeginAvg += inputs[i];
}
averages[0] = sumUpToBeginAvg / beginAvg;
int additionalAvgs = numInputs - beginAvg;
if(additionalAvgs > 0)
{
float currentSum = sumUpToBeginAvg;
int nextValIndex = numInputs - additionalAvgs - 1;
for(int j = 1; j <= additionalAvgs; j++)
{
currentSum += inputs[nextValIndex];
averages[j] = currentSum / (nextValIndex + 1);
}
nextValIndex++;
}
return averages;
}
Пожалуйста, дважды проверьте математику, было много настроек для0 основанный массив в C # против 1 основанного массива в Fortran.
Кроме того, версия Fortran в основном использовала параметр ref для средних значений, я вместо этого создал новый массив и возвратил его.Оба работают, но второй способ более привычен в C #. Я полагаю.
Выше был как можно более прямой перевод.Ниже приведена значительно упрощенная версия, использующая более подходящие структуры данных.
public List<float> CalcRollingAverage(List<float> inputs, int beginAvg)
{
List<float> results = new List<float>();
int index = 1;
float currentSumOfInputs = 0;
foreach(float value in inputs)
{
currentSumOfInputs += value;
if(index >= beginAvg)
{
results.Add(currentSumOfInputs / index);
}
index++;
}
return results;
}
Обновление, основанное на нашем недавнем обнаружении того, что мне не хватает какой-то оригинальной логики.Этот перемещает окно и сохраняет усредненное количество элементов одинаковым:
public List<float> CalcRollingAverage(List<float> inputs, int windowSize)
{
List<float> results = new List<float>();
int index = 1;
float currentSumOfInputs = 0;
foreach(float value in inputs)
{
currentSumOfInputs += value;
if(index == windowSize)
{
results.Add(currentSumOfInputs / windowSize);
break;
}
index++;
}
if(inputs.Count > windowSize)
{
for(int i = index - windowSize + 1; i <= inputs.Count; i++;)
{
currentSumOfInputs = currentSumOfInputs - inputs(index - windowSize);
currentSumOfInputs += inputs(index);
results.Add(currentSumOfInputs / windowSize)
index++;
}
}
}