How to get a multivariate normal distribution


(Brian McBrayer) #1

Hello,

I really like Math.NET and am hoping to use it in an upcoming project (and maybe start contributing if I can–I’m not the best at math but I do know code).

Can somebody please help me figure out how to obtain the multivariate normal distribution? I see the Matrix-valued Normal Distribution, but I’m not sure if that can translate to a straight multivariate normal distribution. My end-goal is a two-dimensional array filled with a multivariate normal distribution given a mean and a correlation matrix, similar to MATLAB’s mvnrnd (https://www.mathworks.com/help/stats/mvnrnd.html).

It’s also possible that I’m so ignorant on the subject that I don’t know what I don’t know, so please feel free to correct my question if it’s stupid.

Thanks so much!

-Brian


(Peter Vanderwaart) #2

Caution: I’ve never worked with this before.

The Matrix Normal is, supposedly, a generalization of the multivariate normal that you are interested in, so you can use the MatrixNormal using nominal inputs for the features you don’t want. My sample program produced plausible results. I did not get the IsValidParameterSet feature to work.

private void MatrixNormal_Click(object sender, EventArgs e)
{
//required header
//using MathNet.Numerics.Distributions;

        // dimension = 2
        int d = 2;
        // # of samples = n
        int n = 100;
        // row covariance
        double r = 2.0;

        // Matrix of means
        var m = Matrix<double>.Build.Dense(d,n);  // zero-filled
        // fill with same means for all observations
        for (int i = 0; i< n; i++)
        {
            m[0,i] = 50.0;
            m[1,i] = 100.0;
        }

        // Matrix of row covariance, i.e. between dimensions for one observation
        // variance on the diagonal, otherwise covariance
        var v = Matrix<double>.Build.Dense(2,2); // zero-filled
        v[0, 0] = 5.0;
        v[0, 1] = r;
        v[1,0] = r;
        v[1, 1] = 10.0;

        // Matrix of column covariance, i.e. between different observations. 
        // successive observations are independent. Use Identity matrix.
        var k = Matrix<double>.Build.Dense(n,n); //zero-filled
        for (int i = 0; i < n; i++) k[i, i] = 1.0;
        
        //build object
        MatrixNormal MatNorm = new MatrixNormal(m, v, k);

        // construct sample
        var Result = MatNorm.Sample();

        // write result
        Console.WriteLine(Result);
        
    }

I’m not really sure what k should be filled with. The Wikipedia article on the Matrix Normal might be helpful.


(Peter Vanderwaart) #3

I’m not at all sure I have this right. It could be that what I thought about v should have applied to k and vice versa. Search under Example at Wikipedia entry on Matrix Normal. Unfortunately, most of terms of the notation are not defined.