NMath User's Guide

TOC | Previous | Next | Index

40.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# correlated 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 );

Code Example – VB correlated random inputs

Dim NumSamples As Integer = 500
Dim Str As String = "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]"
Dim DesiredCorrelations As New DoubleMatrix(Str)



Dim Correlator As 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# correlated 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 );

Code Example – VB correlated random inputs

Dim BetaRng As New RandGenBeta()
Dim UniformRng As New RandGenUniform()
Dim PoissonRng As New RandGenPoisson()
Dim NormalRng As New RandGenNormal()



Dim Inputs As 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)



Dim CorrelatedInputs As DoubleMatrix = 
  Correlator.GetCorrelatedInputs(Inputs)

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

Code Example – C# correlated random inputs

DoubleMatrix actualCorrelations =
  StatsFunctions.Spearmans( correlatedInputs );



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

Code Example – VB correlated random inputs

Dim ActualCorrelations As DoubleMatrix = 
  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# correlated random inputs

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

Code Example – VB correlated random inputs

Dim CorrelatedInputs As DoubleMatrix = 
  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# correlated 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 );

Code Example – VB correlated random inputs

Dim Mean1 As Double = 43.2
Dim Var1 As Double = 1.2
Dim NormalRng1 As New RandGenNormal(Mean1, Var1)



Dim Mean2 As Double = 102.45
Dim Var2 As Double = 8.098
Dim NormalRng2 As New RandGenNormal(Mean2, Var2)



Dim DesiredRankCorrelation As Double = 0.8



Dim NumSamples As Integer = 100



Dim CorrelatedInputs As DoubleMatrix =
  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)  

Top

Top