-4

我有一个样本数组,假设它的长度是 10。现在我想给它们加权,这样我就可以得到一个平均值,其中最旧的样本比新鲜的样本重一点。

例如,位置 1 = 100%,位置 10 = 10% 称重。

这是怎么调用的,如何正确编写这样的函数?

4

2 回答 2

2

这可能不完全符合您的要求,但指数移动平均线 (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 时,应将平均值设置为等于第一个样本。

于 2015-03-19T17:06:32.767 回答
0

这是您所要求的简单实现。

#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;
}
于 2015-03-19T17:37:58.650 回答