I was reading this article and I trying to follow their code example but I think I am missing a library.
They have this :
First, let's create a 2D matrix with some random data. We'll use the System.Random class to generate pseudo-random numbers:
var rand = new Random();
var matrix = new double[5, 5];
for (int i = 0; i < matrix.GetLength(0); i )
{
for (int j = 0; j < matrix.GetLength(1); j )
{
matrix = rand.NextDouble() * 100;
}
}
Now that we have our data, we can calculate the mean and standard deviation:
double mean = matrix.Average();
double stdDev = Math.Sqrt(matrix.Variance());
but when I tried that in C# does, I get this compile time error:
Severity Code Description Project File Line Suppression State Error CS1061 'double[,]' does not contain a definition for 'Variance' and no accessible extension method 'Variance' accepting a first argument of type 'double[,]' could be found (are you missing a using directive or an assembly reference?)
I tried adding
using System.Numerics;
but it did not help
CodePudding user response:
In case you want to apply Linq method to 2D array T[,]
items, you can use OfType() (or Cast<T>()
) to obtain a enumeration IEnumeration<T>
.
For instance, in your case with Average()
you can put it as
using System.Linq;
...
var matrix = new double[5,5];
...
double mean = matrix
.OfType<double>()
.Average();
Since standard Linq doesn't have (at least in .Net 6) Variance
method, we should do a simple statistics. Having a sequence of x = {x_1, x_2, x_3, ..., x_N}
of N
items the variance will be
Var(x) = Sum(x * x) / N - Sum(x) * Sum(x) / N / N
In our case it can be a simple Aggregate
:
// Let's compute all required statistics
// n - number of items
// s - sum of items
// s - sum of items squared
// in one go with a help of Aggregate
var stat = matrix
.OfType<double>()
.Aggregate((n: 0, s: 0.0, ss: 0.0), (s, a) => (s.n 1, s.s a, s.ss a * a));
double stdDev = Math.Sqrt(stat.ss / stat.n - stat.s * stat.s / stat.n / stat.n);
In order not to deal with such constructions, you can implement extension methods:
public static partial class Array2dExtensions {
public static double Average(this double[,] matrix) {
if (matrix == null)
throw new ArgumentNullException(nameof(matrix));
return matrix
.OfType<double>()
.Average();
}
public static double Variance(this double[,] matrix) {
if (matrix == null)
throw new ArgumentNullException(nameof(matrix));
var stat = matrix
.OfType<double>()
.Aggregate((n: 0, s: 0.0, ss: 0.0), (s, a) =>
(s.n 1, s.s a, s.ss a * a));
return stat.ss / stat.n - stat.s * stat.s / stat.n / stat.n;
}
}
Having this implemented you can put it as if array has Average
and Variance
methods:
double mean = matrix.Average();
double stdDev = Math.Sqrt(matrix.Variance());