Solución:
Como sugiere correctamente la otra respuesta por herradura, tendrá que usar un bucle para calcular la varianza, de lo contrario, la declaración
var = ((Matriz[n] – media) * (Matriz[n] – media)) / numPoints;
solo considerará un solo elemento de la matriz.
Acabo de mejorar el código sugerido de herradura:
var = 0;
for( n = 0; n < numPoints; n++ )
{
var += (Array[n] - mean) * (Array[n] - mean);
}
var /= numPoints;
sd = sqrt(var);
Su suma funciona bien incluso sin usar el bucle porque está usando acumular función que ya tiene un bucle dentro, pero que no es evidente en el código, eche un vistazo al comportamiento equivalente de acumular para una comprensión clara de lo que está haciendo.
Nota: X ?= Y
es la abreviatura de X = X ? Y
dónde ?
puede ser cualquier operador. También puedes usar pow(Array[n] - mean, 2)
tomar el cuadrado en lugar de multiplicarlo por sí mismo haciéndolo más ordenado.
Aquí hay otro enfoque que usa std::accumulate
pero sin usar pow
. Además, podemos usar una función anónima para definir cómo calcular la varianza después de calcular la media. Tenga en cuenta que esto calcula la varianza muestral insesgada.
#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);
}
Una muestra de cómo utilizar esta función:
#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;
}