/// <summary>Generate random numbers following a normal distribution N(a,\sigma^2). /// </summary> /// <param name="n">The number of random values to generate.</param> /// <param name="data">The <paramref name="n" /> random numbers following a normal distribution (output).</param> /// <param name="a">The mean.</param> /// <param name="sigma">The standard deviation.</param> /// <param name="generationMethod">The optional generation mode.</param> public void Gaussian(int n, double[] data, double a, double sigma, RandomNumberSequence.GaussianGenerationMode generationMethod = null) { int errorCode; if (generationMethod != null) { if (generationMethod is MklRandomNumberSequence.GaussianGenerationMode) { var vslGaussianGenerationMode = (MklRandomNumberSequence.GaussianGenerationMode)generationMethod; errorCode = vdRngGaussian(vslGaussianGenerationMode.MagicNumber, m_Stream.m_Handle, n, data, a, sigma); } else { throw new ArgumentException("Generation mode is not a valid argument", "generationMode"); } } else { errorCode = vdRngGaussian(MklRandomNumberSequence.GaussianGenerationMode.InverseCumulativeDistributionFunction.MagicNumber, m_Stream.m_Handle, n, data, a, sigma); } if (errorCode != 0) // execution is not successful { throw new InvalidOperationException("MKL: Return value " + errorCode + " in vdRngGaussian."); } }
/// <summary>Generate random numbers following a normal distribution N(a,\sigma^2). /// </summary> /// <param name="n">The number of random values to generate.</param> /// <param name="data">The <paramref name="n" /> random numbers following a normal distribution (output).</param> /// <param name="a">The mean.</param> /// <param name="sigma">The standard deviation.</param> /// <param name="generationMethod">The optional generation mode.</param> public void Gaussian(int n, double[] data, double a, double sigma, RandomNumberSequence.GaussianGenerationMode generationMethod = null) { int errorCode = 0; double variance = sigma * sigma; _acml_GaussianNumbers(ref n, ref a, ref variance, m_RandomNumberStream.m_State, data, ref errorCode); if (errorCode != 0) // execution is not successful { throw new InvalidOperationException("ACML: Return value " + errorCode + " in DRANDGAUSSIAN."); } }
/// <summary>Generates random numbers following a multivariate normal distribution N_d(\mu, \Sigma), i.e. d-dimensional vectors, where \Sigma = Q * Q' represents the variance-covariance matrix. /// </summary> /// <param name="n">The number of random values to generate.</param> /// <param name="data">The <paramref name="n"/> random numbers following a multivariate normal distribution, i.e. random vectors of size at least <paramref name="dimension"/> * <paramref name="n"/>. The return value /// as well as <see cref="GaussianMultivariateDataRepresentation"/> indicates the representation of the data (output).</param> /// <param name="dimension">The dimension of the output vectors.</param> /// <param name="matrixStorage">The matrix storage schema of <paramref name="pseudoRootOfVarianceCovarianceMatrix" />.</param> /// <param name="mu">The mean vector of dimension <paramref name="dimension" />.</param> /// <param name="pseudoRootOfVarianceCovarianceMatrix">The elements of the upper triangular matrix Q' passed according to the matrix storage scheme <paramref name="matrixStorage" />, where \Sigma = Q * Q' represents the variance-covariance matrix.</param> /// <param name="workspace">A workspace array, perhaps <c>null</c>.</param> /// <param name="generationMethod">The optional generation mode.</param> /// <returns>The representation of the <paramref name="data"/>; the random vectors (of dimension <paramref name="dimension"/>) are stored column-by-column if <see cref="BLAS.MatrixTransposeState.NoTranspose"/>; otherwise each column contains all realisation of the j'th component (i.e. transposed matrix).</returns> public BLAS.MatrixTransposeState GaussianMultivariate(int n, double[] data, int dimension, RandomNumberSequence.MultivariateMatrixStorageType matrixStorage, double[] mu, double[] pseudoRootOfVarianceCovarianceMatrix, double[] workspace = null, RandomNumberSequence.GaussianGenerationMode generationMethod = null) { int method; if (generationMethod != null) { if (generationMethod is MklRandomNumberSequence.GaussianGenerationMode) { var vslGaussianGenerationMode = (MklRandomNumberSequence.GaussianGenerationMode)generationMethod; method = vslGaussianGenerationMode.MagicNumber; } else { throw new ArgumentException("Generation mode is not a valid argument", "generationMode"); } } else { method = GaussianGenerationMode.InverseCumulativeDistributionFunction.MagicNumber; } int errorCode; int storage = (int)matrixStorage; unsafe { fixed(double *dataPtr = data, muPtr = mu, pseudoRootPtr = pseudoRootOfVarianceCovarianceMatrix) { errorCode = vdRngGaussianMV(ref method, ref m_Stream.m_Handle, ref n, (IntPtr)dataPtr, ref dimension, ref storage, (IntPtr)muPtr, (IntPtr)pseudoRootPtr); } } if (errorCode != 0) // execution is not successful { throw new InvalidOperationException("MKL: Return value " + errorCode + " in vdRngGaussianmv."); } return(BLAS.MatrixTransposeState.NoTranspose); }
/// <summary>Gets the length of the workspace array required for optimal performance of <see cref="GaussianMultivariate(int, double[], int, RandomNumberSequence.MultivariateMatrixStorageType, double[], double[], double[], RandomNumberSequence.GaussianGenerationMode)" />. /// </summary> /// <param name="n">The number of random values to generate.</param> /// <param name="dimension">The dimension of the output vectors.</param> /// <param name="matrixStorage">The matrix storage schema.</param> /// <param name="generationMethod">The optional generation mode.</param> /// <returns>The length of the workspace array required for the generation of random numbers following a multivariate normal distribution, perhaps <c>0</c>.</returns> public int GaussianMultivariateWorkspaceQuery(int n, int dimension, RandomNumberSequence.MultivariateMatrixStorageType matrixStorage, RandomNumberSequence.GaussianGenerationMode generationMethod = null) { return(0); }
public void NextNumberSequenceGaussianMultivariate_EstimatedVariance_ConvidenceInterval(int dimension, int sampleSize, double[] mu, double[] pseudoRootOfVarianceCovarianceMatrix, RandomNumberSequence.MultivariateMatrixStorageType matrixStorageType, double lowerCriticalValueOfChiSquaredDistribution, double upperCriticalValueOfChiSquaredDistribution, RandomNumberSequence.GaussianGenerationMode generatorMode) { IRandomNumberStream randomStream = GetRandomStream(); /* do not apply BoxMuller to Pseudo-Random Number Generator: */ Assume.That(randomStream.Generator is IPseudoRandomNumberGenerator || (string)generatorMode.Name != "BoxMuller", "Box-Muller approach is for Pseudo-Random Number Generators not adequate."); var sample = new double[sampleSize * dimension]; int workspaceLength = randomStream.NextNumberSequence.GaussianMultivariateWorkspaceQuery(sampleSize, dimension, matrixStorageType, generatorMode); double[] workspace = null; if (workspaceLength > 0) { workspace = new double[workspaceLength]; } var outputRepresentation = randomStream.NextNumberSequence.GaussianMultivariate(sampleSize, sample, dimension, matrixStorageType, mu, pseudoRootOfVarianceCovarianceMatrix, workspace, generatorMode); int triangularPackagedMatrixStartIndex = 0; for (int j = 0; j < dimension; j++) { // check the variance of the j'te component double[] projectedSample = null; switch (outputRepresentation) { case Basics.BLAS.MatrixTransposeState.NoTranspose: projectedSample = sample.Skip(j).Where((x, k) => k % dimension == 0).ToArray(); // the relevant sample, i.e. realisations of a normal-distributed random number break; case Basics.BLAS.MatrixTransposeState.Transpose: case Basics.BLAS.MatrixTransposeState.Hermite: projectedSample = sample.Skip(j * sampleSize).Where((x, k) => k < sampleSize).ToArray(); break; default: throw new NotImplementedException(); } Assert.That(projectedSample.Length >= sampleSize, String.Format("Length : {0}", projectedSample.Length)); double expectedMean = mu[j]; double estimatedMean = projectedSample.Average(); double estimatedVariance = GetEstimatedVariance(projectedSample, sampleSize, estimatedMean); double expectedVariance = 0.0; switch (matrixStorageType) { case RandomNumberSequence.MultivariateMatrixStorageType.Diagonal: expectedVariance = pseudoRootOfVarianceCovarianceMatrix[j] * pseudoRootOfVarianceCovarianceMatrix[j]; break; case RandomNumberSequence.MultivariateMatrixStorageType.Full: // compute [Q * Q']_{j,j], where Q' is one of the arguments for (int k = 0; k < dimension; k++) { double temp = pseudoRootOfVarianceCovarianceMatrix[k + dimension * j]; expectedVariance += temp * temp; } break; case RandomNumberSequence.MultivariateMatrixStorageType.TriangularPackaged: for (int k = 0; k <= j; k++) { double temp = pseudoRootOfVarianceCovarianceMatrix[triangularPackagedMatrixStartIndex + k]; expectedVariance += temp * temp; } triangularPackagedMatrixStartIndex += j + 1; break; default: throw new NotImplementedException(); } /* check whether the (theoretical) variance is inside * * [ (n-1) * S^2 / \chi^2_{\alpha/2, n-1}, (n-1)*S^2 / \chi^2_{1.0 - \alpha/2, n-1} ], * * where \chi^2_{\alpha, n} is the quantile of the chi-square distribution with degree n and parameter \alpha. */ Assert.That(estimatedVariance * (sampleSize - 1) / upperCriticalValueOfChiSquaredDistribution, Is.GreaterThanOrEqualTo(expectedVariance), String.Format("Component: {0}; sampleSize: {1}, theor. Variance: {2}, estimated mean: {3}, estimated Variance: {4}, upper-Chi Squared quantile: {5}", j, sampleSize, expectedVariance, estimatedMean, estimatedVariance, upperCriticalValueOfChiSquaredDistribution)); Assert.That(estimatedVariance * (sampleSize - 1) / lowerCriticalValueOfChiSquaredDistribution, Is.LessThanOrEqualTo(expectedVariance), String.Format("Component: {0}; sampleSize: {1}, theor. Variance: {2}, estimated mean: {3}, estimated Variance: {4}, upper-Chi Squared quantile: {5}", j, sampleSize, expectedVariance, estimatedMean, estimatedVariance, upperCriticalValueOfChiSquaredDistribution)); } }
public void NextNumberSequenceGaussianMultivariate_EstimatedMean_ConvidenceInterval(int dimension, int sampleSize, double[] mu, double[] pseudoRootOfVarianceCovarianceMatrix, RandomNumberSequence.MultivariateMatrixStorageType matrixStorageType, RandomNumberSequence.GaussianGenerationMode generatorMode) { IRandomNumberStream randomStream = GetRandomStream(); /* do not apply BoxMuller to Pseudo-Random Number Generator: */ Assume.That(randomStream.Generator is IPseudoRandomNumberGenerator || (string)generatorMode.Name != "BoxMuller", "Box-Muller approach is for Pseudo-Random Number Generators not adequate."); var sample = new double[sampleSize * dimension]; int workspaceLength = randomStream.NextNumberSequence.GaussianMultivariateWorkspaceQuery(sampleSize, dimension, matrixStorageType, generatorMode); double[] workspace = null; if (workspaceLength > 0) { workspace = new double[workspaceLength]; } var outputRepresentation = randomStream.NextNumberSequence.GaussianMultivariate(sampleSize, sample, dimension, matrixStorageType, mu, pseudoRootOfVarianceCovarianceMatrix, workspace, generatorMode); for (int j = 0; j < dimension; j++) { // check the mean of the j'te component etc.: double[] projectedSample = null; switch (outputRepresentation) { case Basics.BLAS.MatrixTransposeState.NoTranspose: projectedSample = sample.Skip(j).Where((x, k) => k % dimension == 0).ToArray(); // the relevant sample, i.e. realisations of a normal-distributed random number break; case Basics.BLAS.MatrixTransposeState.Transpose: case Basics.BLAS.MatrixTransposeState.Hermite: projectedSample = sample.Skip(j * sampleSize).Where((x, k) => k < sampleSize).ToArray(); break; default: throw new NotImplementedException(); } Assert.That(projectedSample.Length >= sampleSize, String.Format("Length : {0}", projectedSample.Length)); double expectedMean = mu[j]; double estimatedMean = projectedSample.Average(); double estimatedStandardDeviation = GetEstimatedStandardDeviation(projectedSample, sampleSize, estimatedMean); double epsilon = 2.0 * estimatedStandardDeviation / Math.Sqrt(sampleSize); // size of the confidence interval w.r.t. normal distribution N{-1}(0.975) \approx 1.96 \approx 2.0 /* test whether E(X) \in [ estimatedMean - \epsilon, estimatedMean + \epsilon], where \epsilon = \sigma/\sqrt(n} */ Assert.That(estimatedMean + epsilon, Is.GreaterThanOrEqualTo(expectedMean), String.Format("Component: {0}; expected Mean: {1}; estimated Mean: {2}; lower Confidence Interval bound: {3}; upper Confidence Interval bound: {4}.", j, expectedMean, estimatedMean, estimatedMean - epsilon, estimatedMean + epsilon)); Assert.That(estimatedMean - epsilon, Is.LessThanOrEqualTo(expectedMean), String.Format("Component: {0}; expected Mean: {1}; estimated Mean: {2}; lower Confidence Interval bound: {3}; upper Confidence Interval bound: {4}.", j, expectedMean, estimatedMean, estimatedMean - epsilon, estimatedMean + epsilon)); } }
public void NextNumberSequenceGaussian_EstimateVariance_ConvidenceInterval(int sampleSize, double a, double sigma, double lowerCriticalValueOfChiSquaredDistribution, double upperCriticalValueOfChiSquaredDistribution, RandomNumberSequence.GaussianGenerationMode generatorMode) { var sample = new double[sampleSize]; IRandomNumberStream randomStream = GetRandomStream(); randomStream.NextNumberSequence.Gaussian(sampleSize, sample, a, sigma, generatorMode); double estimatedMean = sample.Average(); double estimatedVariance = GetEstimatedVariance(sample, sampleSize, estimatedMean); /* check whether the (theoretical) variance is inside * * [ (n-1) * S^2 / \chi^2_{\alpha/2, n-1}, (n-1)*S^2 / \chi^2_{1.0 - \alpha/2, n-1} ], * * where \chi^2_{\alpha, n} is the quantile of the chi-square distribution with degree n and parameter \alpha. */ double expectedVariance = sigma * sigma; Assert.That((sampleSize - 1) * estimatedVariance / upperCriticalValueOfChiSquaredDistribution, Is.GreaterThanOrEqualTo(expectedVariance), String.Format("a: {0}, sigma: {1}, sampleSize: {2}, theor. Variance: {3}, estimated mean: {4}, estimated Variance: {5}, upper-Chi Squared quantile: {6}", a, sigma, sampleSize, expectedVariance, estimatedMean, estimatedVariance, upperCriticalValueOfChiSquaredDistribution)); Assert.That((sampleSize - 1) * estimatedVariance / lowerCriticalValueOfChiSquaredDistribution, Is.LessThanOrEqualTo(expectedVariance), String.Format("a: {0}, sigma: {1}, sampleSize: {2}, theor. Variance: {3}, estimated mean: {4}, estimated Variance: {5}, lower-Chi Squared quantile: {6}", a, sigma, sampleSize, expectedVariance, estimatedMean, estimatedVariance, lowerCriticalValueOfChiSquaredDistribution)); }
public void NextNumberSequenceGaussian_EstimatedSecondMoment_ConvidenceInterval(int sampleSize, double a, double sigma, RandomNumberSequence.GaussianGenerationMode generatorMode) { double expectedSecondMoment = sigma * sigma + a * a; var sample = new double[sampleSize]; IRandomNumberStream randomStream = GetRandomStream(); randomStream.NextNumberSequence.Gaussian(sampleSize, sample, a, sigma, generatorMode); sample = sample.Select(x => x * x).ToArray(); double estimatedSecondMoment = sample.Average(); double estimatedStandardDeviation = GetEstimatedStandardDeviation(sample, sampleSize, estimatedSecondMoment); double epsilon = 2.0 * estimatedStandardDeviation / Math.Sqrt(sampleSize); // size of the confidence interval w.r.t. normal distribution N{-1}(0.975) \approx 1.96 \approx 2.00 /* test whether E(X^2) \in [ estimatedMoment - \epsilon, estimatedMoment + \epsilon], where \epsilon = \sigma/\sqrt(n} */ Assert.That(estimatedSecondMoment - epsilon, Is.LessThanOrEqualTo(expectedSecondMoment), String.Format("a: {0}; sigma: {1}; 2nd Moment: {2}; estimated 2nd Moment: {3}; estimated Standard Deviation: {4}; epsilon: {5}", a, sigma, sigma * sigma + a * a, estimatedSecondMoment, estimatedStandardDeviation, epsilon)); Assert.That(estimatedSecondMoment + epsilon, Is.GreaterThanOrEqualTo(expectedSecondMoment), String.Format("a: {0}; sigma: {1}; 2nd Moment: {2}; estimated 2nd Moment: {3}; estimated Standard Deviation: {4}; epsilon: {5}", a, sigma, sigma * sigma + a * a, estimatedSecondMoment, estimatedStandardDeviation, epsilon)); }
public void NextNumberSequenceGaussian_EstimatedMean_ConvidenceInterval(int sampleSize, double a, double sigma, RandomNumberSequence.GaussianGenerationMode generatorMode) { double expectedMean = a; var sample = new double[sampleSize]; IRandomNumberStream randomStream = GetRandomStream(); randomStream.NextNumberSequence.Gaussian(sampleSize, sample, a, sigma, generatorMode); double estimatedMean = sample.Average(); double estimatedStandardDeviation = GetEstimatedStandardDeviation(sample, sampleSize, estimatedMean); double epsilon = 2.0 * estimatedStandardDeviation / Math.Sqrt(sampleSize); // size of the confidence interval w.r.t. normal distribution N{-1}(0.975) \approx 1.96 \approx 2.0 /* test whether E(X) \in [ estimatedMean - \epsilon, estimatedMean + \epsilon], where \epsilon = \sigma/\sqrt(n} */ Assert.That(estimatedMean - epsilon, Is.LessThanOrEqualTo(expectedMean), String.Format("a: {0}, sigma: {1}, estimated mean: {2}, estimated Standard Deviation: {3}, epsilon: {4}", a, sigma, estimatedMean, estimatedStandardDeviation, epsilon)); Assert.That(estimatedMean + epsilon, Is.GreaterThanOrEqualTo(expectedMean), String.Format("a: {0}, sigma: {1}, estimated mean: {2}, estimated Standard Deviation: {3}, epsilon: {4}", a, sigma, estimatedMean, estimatedStandardDeviation, epsilon)); }
/// <summary>Generates random numbers following a multivariate normal distribution N_d(\mu, \Sigma), i.e. d-dimensional vectors, where \Sigma = Q * Q' represents the variance-covariance matrix. /// </summary> /// <param name="n">The number of random values to generate.</param> /// <param name="data">The <paramref name="n"/> random numbers following a multivariate normal distribution, i.e. random vectors of size at least <paramref name="dimension"/> * <paramref name="n"/>, /// where the i-th block of <paramref name="n"/> elements contains the realisations of the i-th component of the random vector (output).</param> /// <param name="dimension">The dimension of the output vectors.</param> /// <param name="mu">The mean vector of dimension <paramref name="dimension" />.</param> /// <param name="varianceCovarianceMatrix">The variance covariance matrix supplied column-by-column.</param> /// <param name="generationMethod">The optional generation mode.</param> public void GaussianMultivariate(int n, double[] data, int dimension, double[] mu, double[] varianceCovarianceMatrix, RandomNumberSequence.GaussianGenerationMode generationMethod = null) { int errorCode = 0; _acml_MultiNormalNumbers(ref n, ref dimension, mu, varianceCovarianceMatrix, ref dimension, m_RandomNumberStream.m_State, data, ref n, ref errorCode); if (errorCode != 0) // execution is not successful { throw new InvalidOperationException("ACML: Return value " + errorCode + " in DRANDMULTINORMAL."); } }
/// <summary>Generates random numbers following a multivariate normal distribution N_d(\mu, \Sigma), i.e. d-dimensional vectors, where \Sigma = Q * Q' represents the variance-covariance matrix. /// </summary> /// <param name="n">The number of random values to generate.</param> /// <param name="data">The <paramref name="n"/> random numbers following a multivariate normal distribution, i.e. random vectors of size at least <paramref name="dimension"/> * <paramref name="n"/>. The return value /// as well as <see cref="GaussianMultivariateDataRepresentation"/> indicates the representation of the data (output).</param> /// <param name="dimension">The dimension of the output vectors.</param> /// <param name="matrixStorage">The matrix storage schema of <paramref name="pseudoRootOfVarianceCovarianceMatrix" />.</param> /// <param name="mu">The mean vector of dimension <paramref name="dimension" />.</param> /// <param name="pseudoRootOfVarianceCovarianceMatrix">The elements of the upper triangular matrix Q' passed according to the matrix storage scheme <paramref name="matrixStorage" />, where \Sigma = Q * Q' represents the variance-covariance matrix.</param> /// <param name="workspace">A workspace array, perhaps <c>null</c>.</param> /// <param name="generationMethod">The optional generation mode.</param> /// <returns>The representation of the <paramref name="data"/>; the random vectors (of dimension <paramref name="dimension"/>) are stored column-by-column if <see cref="BLAS.MatrixTransposeState.NoTranspose"/>; otherwise each column contains all realisation of the j'th component (i.e. transposed matrix).</returns> public BLAS.MatrixTransposeState GaussianMultivariate(int n, double[] data, int dimension, RandomNumberSequence.MultivariateMatrixStorageType matrixStorage, double[] mu, double[] pseudoRootOfVarianceCovarianceMatrix, double[] workspace = null, RandomNumberSequence.GaussianGenerationMode generationMethod = null) { // for this implementation one has to calculate the covariance matrix: if ((workspace == null) || (workspace.Length < dimension * dimension)) { workspace = new double[dimension * dimension]; } switch (matrixStorage) { case RandomNumberSequence.MultivariateMatrixStorageType.Full: BLAS.Level3.dgemm(dimension, dimension, dimension, 1.0, pseudoRootOfVarianceCovarianceMatrix, pseudoRootOfVarianceCovarianceMatrix, 0.0, workspace, BLAS.MatrixTransposeState.Transpose); break; case RandomNumberSequence.MultivariateMatrixStorageType.Diagonal: BLAS.Level1.dscal(dimension * dimension, 0.0, workspace); // set coVarianceMatrix = 0 for (int j = 0; j < dimension; j++) // the input is just the diagonal matrix (column-by-column representation) { workspace[j * dimension + j] = pseudoRootOfVarianceCovarianceMatrix[j] * pseudoRootOfVarianceCovarianceMatrix[j]; } break; case RandomNumberSequence.MultivariateMatrixStorageType.TriangularPackaged: int startIndexMatrixQ = 0; // the null-based index of the first index [in packaged representation] of matrix Q w.r.t. to the (i,j)-component of Q*Q' for (int i = 0; i < dimension; i++) { startIndexMatrixQ += i; for (int j = 0; j <= i; j++) { /* j is the start index of Matrix Q' and one has to calculate j + 1 multiplications: */ double value = 0.0; for (int k = 0; k < j + 1; k++) { value += pseudoRootOfVarianceCovarianceMatrix[startIndexMatrixQ + k] * pseudoRootOfVarianceCovarianceMatrix[j + k]; } workspace[i + j * dimension] = workspace[j + i * dimension] = value; } } break; default: throw new ArgumentException(matrixStorage.ToFormatString()); } int errorCode = 0; _acml_MultiNormalNumbers(ref n, ref dimension, mu, workspace, ref dimension, m_RandomNumberStream.m_State, data, ref n, ref errorCode); if (errorCode != 0) // execution is not successful { throw new InvalidOperationException("ACML: Return value " + errorCode + " in DRANDMULTINORMAL."); } return(BLAS.MatrixTransposeState.Transpose); }