C++ 计算标准差&;C+的方差+;

C++ 计算标准差&;C+的方差+;,c++,arrays,average,variance,standard-deviation,C++,Arrays,Average,Variance,Standard Deviation,所以,我发了几次帖子,之前我的问题都很模糊。我本周开始C++,一直在做一个小项目。 我试图计算标准差和方差。我的代码加载一个包含100个整数的文件,并将它们放入一个数组中,对它们进行计数,计算平均值、总和、方差和SD。但我在方差方面有点问题 #include <vector> #include <algorithm> #include <numeric> template<typename T> T variance(const std::vec

所以,我发了几次帖子,之前我的问题都很模糊。我本周开始C++,一直在做一个小项目。 我试图计算标准差和方差。我的代码加载一个包含100个整数的文件,并将它们放入一个数组中,对它们进行计数,计算平均值、总和、方差和SD。但我在方差方面有点问题

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

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

    // Calculate the mean
    const 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);
}
我不断得到一个巨大的数字——我感觉这与它的计算有关

我的平均数和总和都可以

注意:

使用名称空间std;
int main()
{
int n=0;
整数数组[100];
浮动平均值;
浮动风险价值;
浮动sd;
弦线;
浮点数;
ifstream myfile(“numbers.txt”);
如果(myfile.is_open())
{
而(!myfile.eof())
{
getline(myfile,line);
字符串流转换(行);
if(!(转换>>数组[n]))
{
数组[n]=0;
}

cout您的方差计算在循环之外,因此它仅基于
n==100值。
您需要一个额外的循环

你需要:

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

而(n正如马蹄铁的另一个答案正确地建议的那样,您必须使用循环来计算方差,否则会导致语句错误

var=((数组[n]-平均值)*(数组[n]-平均值))/numPoints

将只考虑数组中的一个元素。

刚刚改进了马蹄铁的建议代码:

var = 0;
for( n = 0; n < numPoints; n++ )
{
  var += (Array[n] - mean) * (Array[n] - mean);
}
var /= numPoints;
sd = sqrt(var);
var=0;
对于(n=0;n
即使不使用循环,您的求和也可以正常工作,因为您使用的是累计函数,该函数内部已经有一个循环,但在代码中并不明显,请查看的等效行为,以清楚地了解它在做什么

注意:
X?=Y
X=X?Y
的缩写,其中
可以是任何运算符。
也可以使用<代码> PoW(数组[n]平均,2)< /COD>取平方而不是乘法,使其更整洁。

< P>计算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);
}
#包括
#包括
双标准差(标准差::向量);
双方差(标准:向量);
int main()
{
std::载体样本;
样品。推回(2.0);
样品。推回(3.0);
样品。推回(4.0);
样品。推回(5.0);
样品。推回(6.0);
样品。推回(7.0);
双标准=标准偏差(样本);
返回0;
}
双标准偏差(标准::矢量样本)
{
返回sqrt(差异(样本));
}
双方差(标准::向量样本)
{
int size=samples.size();
双方差=0;
双t=样本[0];
对于(int i=1;i
您可以创建一个传递到
std::acculate
来计算平均值,而不是写出更多的循环

template <typename T>
struct normalize {
    T operator()(T initial, T value) {
        return initial + pow(value - mean, 2);
    }
    T mean;
}
模板
结构规范化{
T运算符()(T初始值,T值){
返回初始值+功率(值-平均值,2);
}
不是指;
}
当我们使用它时,我们可以使用来进行文件加载,因为我们不知道在编译时有多少个值。这给了我们:

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

    ifstream myfile(“numbers.txt");
    if (myfile)
    {
        values.assign(std::istream_iterator<int>(myfile), {});
    }
    else { std::cout << "Error loading file" << std::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 }) / values.size();
    float sd = sqrt(var);
    std::cout << "The standard deviation is: " << sd << std::endl;
    return 0;
}
intmain()
{
std::vector values;//初始容量,还没有内容
ifstream myfile(“numbers.txt”);
如果(我的文件)
{
赋值(std::istream_迭代器(myfile),{});
}

否则{std::cout这里有另一种方法使用
std::acculate
,但不使用
pow
。此外,我们可以使用匿名函数定义在计算平均值后如何计算方差。请注意,这会计算无偏样本方差

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

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

    // Calculate the mean
    const 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);
}
#包括
#包括
#包括
模板
T方差(常数标准::向量和向量){
const size_t sz=vec.size();
如果(sz==1){
返回0.0;
}
//计算平均数
const T mean=std::累加(向量开始(),向量结束(),0.0)/sz;
//现在计算方差
自动方差_func=[&平均值,&sz](T累加器,常数T&val){
收益累加器+((val-平均值)*(val-平均值)/(sz-1));
};
返回标准::累计(向量开始(),向量结束(),0.0,方差函数);
}
如何使用此功能的示例:

#include <iostream>
int main() {
    const std::vector<double> vec = {1.0, 5.0, 6.0, 3.0, 4.5};
    std::cout << variance(vec) << std::endl;
}
#包括
int main(){
const std::vector vec={1.0,5.0,6.0,3.0,4.5};
std::cout
#包括
#包括
#包括
#包括
#包括
#包括
模板
无效平均值(输入者第一,输入者最后,T&平均值){
int n=标准::距离(第一个,最后一个);
平均值=标准::累积(第一次、最后一次、静态(0))/n;
}
模板
无效标准偏差(输入者第一,输入者最后,T和平均值,T和标准偏差){
int n=标准::距离(第一个,最后一个);
平均值=标准::累积(第一次、最后一次、静态(0))/n;
TS=std::累加(第一次、最后一次、静态(0),[平均值](双x,双y){
T denta=y-平均值;
返回x+denta*denta;
});
标准偏差=序列号;
}
int main(){
向量v={10,20,30};
双平均值=0;
平均值(v.开始(),v.结束(),平均值);

std::cout In
(数组[n]-平均值)
n
不是比你读过的元素数多了一个吗?另外,你应该用double而不是float。我想你在最后一行有一个拼写错误。@Jason:是的,没错,但是Ahmeds solutions现在很好地解决了这个问题。对于其他读代码的人来说,纠正你的拼写错误仍然很好。@horseshoe循环应该从
n=0开始
以满足数组的第一个索引。“为阅读代码的其他人修复键入错误仍然很好。-Jason“感谢您的“注释”,它很有用。将您的代码与horseshoe进行比较为什么for语句比while语句更好?或者是否有n