**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.

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 );

**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.

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 );

- 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)