массивы — Расчет стандартного отклонения & amp; Дисперсия в переполнении стека

так что я написал несколько раз, и ранее мои проблемы были довольно расплывчаты

я начал C ++ на этой неделе и делал небольшой проект

поэтому я пытаюсь рассчитать стандартное отклонение & дисперсия

мой код загружает файл из 100 целых чисел и помещает их в массив, считает их, среднее значение calcs, sum, var и sd

но у меня небольшие проблемы с дисперсией

я продолжаю получать огромное количество — у меня есть ощущение, что это связано с его расчетом

мое среднее и сумма в порядке

любая помощь или советы?

NB:

SD & amp; среднее количество

Ура,

Джек

 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;

}

4

Решение

Как правильно показывает другой ответ подковы, вам придется использовать цикл для вычисления дисперсии, в противном случае утверждение

var = ((Array [n] — среднее) * (Array [n] — среднее)) / numPoints;

будет просто рассматривать один элемент из массива.

Просто улучшил предложенный код подковы:

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

Ваша сумма отлично работает даже без использования цикла, потому что вы используете скапливаться функция, которая уже имеет цикл внутри нее, но которая не очевидна в коде, взглянем на эквивалентное поведение скапливаться для четкого понимания того, что он делает.

Замечания: X ?= Y коротка для X = X ? Y где ? может быть любой оператор.
Также вы можете использовать pow(Array[n] - mean, 2) взять квадрат вместо того, чтобы умножать его самому, делая его более аккуратным.

10

Другие решения

Ваш расчет отклонения находится за пределами цикла, и поэтому он основан только на n== 100 value. Вам нужен дополнительный цикл.

Тебе нужно:

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

Два простых метода для расчета стандартного отклонения & Дисперсия в 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);
}
1

Вместо того, чтобы писать больше циклов, вы можете создать функциональный объект перейти к std::accumulate рассчитать среднее.

template <typename T>
struct normalize {
T operator()(T initial, T value) {
return initial + pow(value - mean, 2);
}
T mean;
}

Пока мы на это, мы можем использовать станд :: istream_iterator выполнить загрузку файла и станд :: вектор потому что мы не знаем, сколько значений во время компиляции. Это дает нам:

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;
}
0

Вот еще один подход с использованием 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;
}
0
По вопросам рекламы [email protected]