计算标准偏差& C ++中的差异

时间:2015-10-21 20:21:00

标签: c++ arrays average variance standard-deviation

所以我发布了几次,以前我的问题很模糊

我本周开始使用C ++并且已经做了一个小项目

所以我试图计算标准偏差&方差

我的代码加载一个100个整数的文件并将它们放入一个数组中,计算它们,计算均值,求和,var和sd

但我的方差有点麻烦

我继续得到一个巨大的数字 - 我感觉它与它的计算有关

我的意思和总和还可以

任何帮助或提示?

NB:

sd & mean calcs

干杯,

杰克

 using namespace std;
    int main()

{

int n = 0;
int Array[100];
float mean;
float var;
float sd;
string line;
float numPoints;

ifstream myfile(“numbers.txt");

if (myfile.is_open())

{
    while (!myfile.eof())

    {
        getline(myfile, line);

        stringstream convert(line);

        if (!(convert >> Array[n]))

        {
            Array[n] = 0;
        }
        cout << Array[n] << endl;

        n++;

    }

    myfile.close();

    numPoints = n;

}
else cout<< "Error loading file" <<endl;

int sum = accumulate(begin(Array), end(Array), 0, plus<int>());

cout << "The sum of all integers: " << sum << endl;

mean = sum/numPoints;

cout << "The mean of all integers: " << mean <<endl;

var = ((Array[n] - mean) * (Array[n] - mean)) / numPoints;

sd = sqrt(var);

cout << "The standard deviation is: " << sd <<endl;

return 0;

}

7 个答案:

答案 0 :(得分:12)

正如马蹄铁的另一个答案正确建议的那样,你将不得不使用一个循环来计算方差,否则就是陈述

  

var =((Array [n] - mean)*(Array [n] - mean))/ numPoints;

只考虑数组中的单个元素。

改进马蹄铁的建议代码:

var = 0;
for( n = 0; n < numPoints; n++ )
{
  var += (Array[n] - mean) * (Array[n] - mean);
}
var /= numPoints;
sd = sqrt(var);

即使不使用循环,你的总和也能正常工作,因为你正在使用 accumulate 函数,它已经在其中有一个循环,但在代码中不明显,请看看{的等效行为{3}}清楚地了解它在做什么。

注意: X ?= YX = X ? Y的缩写,其中?可以是任何运营商。 此外,您可以使用pow(Array[n] - mean, 2)取正方形,而不是将其相乘,使其更加整洁。

答案 1 :(得分:1)

你的方差计算在循环之外,因此它只基于n== 100 value.你需要一个额外的循环。

你需要:

var = 0;
n=0;
while (n<numPoints){
   var = var + ((Array[n] - mean) * (Array[n] - mean));
   n++;
}
var /= numPoints;
sd = sqrt(var);

答案 2 :(得分:1)

计算标准偏差的两种简单方法&amp; C ++中的差异。

#include <math.h>
#include <vector>

double StandardDeviation(std::vector<double>);
double Variance(std::vector<double>);

int main()
{
     std::vector<double> samples;
     samples.push_back(2.0);
     samples.push_back(3.0);
     samples.push_back(4.0);
     samples.push_back(5.0);
     samples.push_back(6.0);
     samples.push_back(7.0);

     double std = StandardDeviation(samples);
     return 0;
}

double StandardDeviation(std::vector<double> samples)
{
     return sqrt(Variance(samples));
}

double Variance(std::vector<double> samples)
{
     int size = samples.size();

     double variance = 0;
     double t = samples[0];
     for (int i = 1; i < size; i++)
     {
          t += samples[i];
          double diff = ((i + 1) * samples[i]) - t;
          variance += (diff * diff) / ((i + 1.0) *i);
     }

     return variance / (size - 1);
}

答案 3 :(得分:1)

这是使用std::accumulate但不使用pow的另一种方法。此外,我们可以使用匿名函数来定义在计算均值后如何计算方差。请注意,这会计算无偏差的样本方差。

#include <vector>
#include <algorithm>
#include <numeric>

template<typename T>
T variance(const std::vector<T> &vec)
{
    size_t sz = vec.size();
    if (sz == 1)
        return 0.0;

    // Calculate the mean
    T mean = std::accumulate(vec.begin(), vec.end(), 0.0) / sz;

    // Now calculate the variance
    auto variance_func = [&mean, &sz](T accumulator, const T& val)
    {
        return accumulator + ((val - mean)*(val - mean) / (sz - 1));
    };

    return std::accumulate(vec.begin(), vec.end(), 0.0, variance_func);
}

如何使用此功能的示例:

int main()
{
    std::vector<double> vec = {1.0, 5.0, 6.0, 3.0, 4.5};
    std::cout << variance(vec) << std::endl;
}

答案 4 :(得分:0)

您可以创建一个BigBlueButton传递给template <typename T> struct normalize { T operator()(T initial, T value) { return initial + pow(value - mean, 2); } T mean; } 来计算平均值,而不是写出更多循环。

int main()
{
    std::vector<int> values(100); // initial capacity, no contents yet

    ifstream myfile(“numbers.txt");
    if (myfile.is_open())
    {
        std::copy(std::istream_iterator<int>(myfile), std::istream_iterator<int>(), std::back_inserter(values));
        myfile.close();
    }
    else { cout<< "Error loading file" <<endl; }

    float sum = std::accumulate(values.begin(), values.end(), 0, plus<int>()); // plus is the default for accumulate, can be omitted
    std::cout << "The sum of all integers: " << sum << std::endl;
    float mean = sum / values.size();
    std::cout << "The mean of all integers: " << mean << std::endl;
    float var = std::accumulate(values.begin(), values.end(), 0, normalize<float>{ mean });
    float sd = sqrt(var);
    std::cout << "The standard deviation is: " << sd << std::endl;
    return 0;
}

虽然我们在这里,但我们可以使用function object来执行文件加载,std::istream_iterator因为我们不知道编译时有多少值。这给了我们:

{{1}}

答案 5 :(得分:0)

#include <iostream>
#include <numeric>
#include <vector>
#include <cmath>
#include <utility>
#include <array>

template <class InputIterator, class T>
void Mean(InputIterator first, InputIterator last, T& mean) {
  int n = std::distance(first, last);
  mean = std::accumulate(first, last, static_cast<T>(0)) / n;
}

template <class InputIterator, class T>
void StandardDeviation(InputIterator first, InputIterator last, T& mean, T& stardard_deviation) {
  int n = std::distance(first, last);
  mean = std::accumulate(first, last, static_cast<T>(0)) / n;
  T s = std::accumulate(first, last, static_cast<T>(0), [mean](double x, double y) {
    T denta = y - mean;
    return x + denta*denta;
  });
  stardard_deviation = s/n;
}

int main () {
  std::vector<int> v = {10, 20, 30};

  double mean = 0;
  Mean(v.begin(), v.end(), mean);
  std::cout << mean << std::endl;

  double stardard_deviation = 0;
  StandardDeviation(v.begin(), v.end(), mean, stardard_deviation);
  std::cout << mean << " " << stardard_deviation << std::endl;

  double a[3] = {10.5, 20.5, 30.5};
  Mean(a, a+3, mean);
  std::cout << mean << std::endl;
  StandardDeviation(a, a+3, mean, stardard_deviation);
  std::cout << mean << " " << stardard_deviation << std::endl;

  std::array<int, 3> m = {1, 2, 3};
  Mean(m.begin(), m.end(), mean);
  std::cout << mean << std::endl;
  StandardDeviation(m.begin(), m.end(), mean, stardard_deviation);
  std::cout << mean << " " << stardard_deviation << std::endl;
  return 0;
}

答案 6 :(得分:0)

如果你有一个包含 F(x) 值的表格

使用地图的基本方法。

映射第一个条目保存问题的值,第二个条目保存问题的 f(x)(概率)值。

注意:不要犹豫我的类名,你可以直接在你的程序中使用它而没有这个。

求平均值

找到这张地图的平均值并返回。

double Expectation::meanFinder(map<double,double> m)
{
    double sum = 0;
    for (auto it : m)
    {
        sum += it.first * it.second;
    }
    cout << "Mean: " << sum << endl;
    return sum;
}

计算方差和标准推导

计算这些值并打印。 (如果你愿意,你也可以退货)

void Expectation::varianceFinder(map<double,double> m, double mean)
{
    double sum = 0;
    for (auto it : m)
    {
        double diff_square = (it.first - mean) * (it.first - mean);
        sum += diff_square * it.second;
    }
    cout << "Variance: " << sum << endl;
    cout << "Standart Derivation: " << sqrt(sum) << endl;
}

请注意,取一个有意义的值。如果需要,您也可以在该函数中调用 meanFinder() 函数。

基本用法

cin 的基本用法

void findVarianceTest(Expectation& expect)
{
    int size = 0;
    cout << "Enter test size:";
    cin >> size;
    map<double, double> m;   
    for (int i = 0; i < size; i++)
    {
        double freq = 0;
        double f_x = 0;
        cout << "Enter " << i+1 << ". frequency and f(X) (probability) respectively" << endl;
        cin >> freq;
        cin >> f_x;
        m.insert(pair<double,double>(freq,f_x));
    }
    expect.varianceFinder(m, expect.meanFinder(m));

}

请注意,我在调用 meanFinder() 的同时调用了 varianceFinder()

Input Output