NMath Stats User's Guide

TOC | Previous | Next | Index

4.2 Correlated Random Inputs (.NET, C#, CSharp, VB, Visual Basic, F#)

NMath Stats provides classes InputVariableCorrelator and ReducedVarianceInputCorrelator to induce a desired rank correlation among a set of random input variables. The correlated inputs retain the same marginal distributions as the original inputs but have a Spearman's rank correlation matrix approximately equal to that specified by the user. The method used is that of Iman and Conover (1982).1

ReducedVarianceInputCorrelator performs the same function as InputVariableCorrelator class, but uses an algorithm that produces more accurate results, at some cost in performance.

Constructing Correlator Instances

Instances of InputVariableCorrelator and ReducedVarianceInputCorrelator are constructed from the number of samples and the desired correlation matrix. This code assume 500 samples of 6 input variables:

Code Example – C# correlation random inputs

int numSamples = 500;
string str = "6x6 [1 0 0 0 0 0 " +
                  "0 1 0 0 0 0 " +
                  "0 0 1 0 0 0 " +
                  "0 0 0 1 .75 -.70 " +
                  "0 0 0 .75 1 -.95 " +
                  "0 0 0 -.7 -.95 1]";
var desiredCorrelations = new DoubleMatrix( str );

var correlator = new
  InputVariableCorrelator( numSamples, desiredCorrelations );

Most of the work done by the correlation algorithm involves setting up a score matrix which has been transformed so that it's Spearman's rank correlation matrix is equal to the desired correlation matrix. The computation of this score matrix requires only the number of samples and the desired correlation matrix, and is performed at construction time. Once you have constructed an InputVariableCorrelator or ReducedVarianceInputCorrelator instance, you can correlate batches of random inputs relatively quickly.

Correlating Random Inputs

The GetCorrelatedInputs() method on InputVariableCorrelator and ReducedVarianceInputCorrelator returns a matrix containing a given set of input variables values re-ordered so as to have the desired correlations.

For instance, this code creates a set of samples drawn from 4 different distributions (each row of the inputs matrix is a random sample of the 6 input variables), and induces the desired correlation:

Code Example – C# correlation random inputs

var betaRng = new RandGenBeta();
var uniformRng = new RandGenUniform();
var poissonRng = new RandGenPoisson();
var normalRng = new RandGenNormal();

var inputs = new DoubleMatrix( numSamples, 6 );
betaRng.Fill( inputs.Col( 0 ).DataBlock.Data );
uniformRng.Fill( inputs.Col( 1 ).DataBlock.Data );
poissonRng.Fill( inputs.Col( 2 ).DataBlock.Data );
normalRng.Fill( inputs.Col( 3 ).DataBlock.Data );
betaRng.Fill( inputs.Col( 4 ).DataBlock.Data );
uniformRng.Fill( inputs.Col( 5 ).DataBlock.Data );

DoubleMatrix correlatedInputs =
  correlator.GetCorrelatedInputs( inputs );

You can compare the actual Spearman's rank correlation matrix with the desired correlation matrix, like so:

Code Example – C# correlation random inputs

DoubleMatrix actualCorrelations =
  StatsFunctions.Spearmans( correlatedInputs );

Console.WriteLine( "Desired: " + desiredCorrelations );
Console.WriteLine( "Actual: " + actualCorrelations );

Correlator Properties

InputVariableCorrelator and ReducedVarianceInputCorrelator provide the following read-only properties:

Rstar gets the permuted score matrix which has been transformed to have the desired correlation matrix.

NumInputVariables gets the number of input variables.

SampleSize gets the sample size of the input variables.

Convenience Method

The static CorrelatedRandomInputs() convenience method is provided on class StatsFunctions for cases where you need only one set of correlated inputs. For example:

Code Example – C# correlation random inputs

DoubleMatrix correlatedInputs =   
  StatsFunctions.CorrelatedRandomInputs( inputs, 
    desiredCorrelations );

In the special case of two input variables, an additional overload obviates the need for setting up the original input sample matrix. For instance, this code creates two sequences of 100 normally distributed random numbers which have, approximately, the specified rank correlation coefficient 0.8:

Code Example – C# correlation random inputs

double mean1 = 43.2;
double var1 = 1.2;
var normalRng1 = new RandGenNormal( mean1, var1 );

double mean2 = 102.45;
double var2 = 8.098;
var normalRng2 = new RandGenNormal( mean2, var2 );

double desiredRankCorrelation = .8;

int numSamples = 100;

DoubleMatrix correlatedInputs = 
  StatsFunctions.CorrelatedRandomInputs( numSamples,
    desiredRankCorrelation, normalRng1, normalRng2 );

  1. Iman, Ronald L. and W. J. Conover, "A Distribution-Free Approach to Inducing Rank Correlation Amoung Input Variables", Commun. Statist.-Simula. Computation 11(3), pp. 311-334 (1982)