我有一个样本数组,假设它的长度是 10。现在我想给它们加权,这样我就可以得到一个平均值,其中最旧的样本比新鲜的样本重一点。
例如,位置 1 = 100%,位置 10 = 10% 称重。
这是怎么调用的,如何正确编写这样的函数?
我有一个样本数组,假设它的长度是 10。现在我想给它们加权,这样我就可以得到一个平均值,其中最旧的样本比新鲜的样本重一点。
例如,位置 1 = 100%,位置 10 = 10% 称重。
这是怎么调用的,如何正确编写这样的函数?
这可能不完全符合您的要求,但指数移动平均线 (EMA)通常是这样写的:
double exp_avg(double avg, double sample, double sample_weight)
{
return sample * sample_weight + avg * (1 - sample_weight);
// return avg + (sample - avg) * sample_weight; // equivalent alternative
}
首次建立 EMA 时,应将平均值设置为等于第一个样本。
这是您所要求的简单实现。
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
int normalize_weights(double *weights, size_t num_weights)
{
double sum = 0;
for (size_t i = 0; i < num_weights; ++i)
{
if (weights[i] < 0)
return -1;
sum += weights[i];
}
if (sum == 0)
return -1;
for (size_t i = 0; i < num_weights; ++i)
weights[i] /= sum;
return 0;
}
int weighted_avg(double *avg_ptr, const double *samples, size_t num_samples, const double *weights, size_t num_weights)
{
if (num_samples != num_weights)
return -1;
double avg = 0;
for (size_t i = 0; i < num_weights; ++i)
avg += samples[i] * weights[i];
*avg_ptr = avg;
return 0;
}
int main(int argc, char **argv)
{
double weights[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
double samples[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
double avg;
if (normalize_weights(weights, sizeof(weights) / sizeof(weights[0])))
abort();
for (size_t i = 0; i < sizeof(weights) / sizeof(weights[0]); ++i)
printf("Normalized weight[%u] = %lf\n", (unsigned) i, weights[i]);
if (weighted_avg(&avg, samples, sizeof(samples) / sizeof(samples[0]), weights, sizeof(weights) / sizeof(weights[0])))
abort();
printf("\nWeighted average is %lf\n", avg);
return 0;
}