/// <summary> /// Samples a matrix normal distributed random variable. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="m">The mean of the matrix normal.</param> /// <param name="v">The covariance matrix for the rows.</param> /// <param name="k">The covariance matrix for the columns.</param> /// <exception cref="ArgumentOutOfRangeException">If the dimensions of the mean and two covariance matrices don't match.</exception> /// <returns>a sequence of samples from the distribution.</returns> public static Matrix<double> Sample(System.Random rnd, Matrix<double> m, Matrix<double> v, Matrix<double> k) { if (Control.CheckDistributionParameters && !IsValidParameterSet(m, v, k)) { throw new ArgumentException(Resources.InvalidDistributionParameters); } var n = m.RowCount; var p = m.ColumnCount; // Compute the Kronecker product of V and K, this is the covariance matrix for the stacked matrix. var vki = v.KroneckerProduct(k.Inverse()); // Sample a vector valued random variable with VKi as the covariance. var vector = SampleVectorNormal(rnd, new DenseVector(n*p), vki); // Unstack the vector v and add the mean. var r = m.Clone(); for (var i = 0; i < n; i++) { for (var j = 0; j < p; j++) { r.At(i, j, r.At(i, j) + vector[(j*n) + i]); } } return r; }