← All NMath Code Examples
Imports System
Imports CenterSpace.NMath.Core
Namespace CenterSpace.NMath.Examples.VisualBasic
A .NET example in Visual Basic showing how to create streams of independent random numbers.
Module IndependentStreamsExample
Sub Main()
NMath provides classes for generating several independent streams of random
numbers using the leapfrog and skip-ahead (blocksplitting) methods.
IMPORTANT NOTE:
Skip-ahead and leapfrog streams are only supported for basic random number
generator types which provide a more efficient algorithm than generation
of that full sequence to pick out a required subsequence. The static variable
SkipAheadStream.SupportedGeneratorTypes contains a list of the supported
types for SkipAheadStream.
Dim Seed As Integer = &H124
Dim GenType As RandomNumberStream.BasicRandGenType = RandomNumberStream.BasicRandGenType.MultiplicativeCongruent31
Create a SkipAheadRandomStreams object for generating 10 independent random number streams,
each of length 100, using the Skip Ahead method.
Dim NumberOfStreams As Integer = 5
Dim StreamLength As Integer = 1000
Dim IndStreams As New SkipAheadRandomStreams(Seed, GenType, NumberOfStreams, StreamLength)
Create a streamLength x numberOfStreams matrix A and use the SkipAheadRandomStreams object
created above to fill it with random numbers. Each of the numberOfStreams columns
in the resulting matrix will contain streamLength random deviates distributed
uniformly in the interval (0, 1). Each column of random numbers will
be independent from the others.
Dim Dist As New DoubleRandomUniformDistribution()
Dim A As New DoubleMatrix(StreamLength, NumberOfStreams)
IndStreams.Fill(Dist, A)
Console.WriteLine()
Print out the correlation matrix for the sample to test
independence. Correlations should be near zero for independent
samples.
Dim CorrelationMatrix As DoubleSymmetricMatrix = RankCorrelation(A, True)
Console.WriteLine("Spearmans Rank Correlation for independent random samples:")
Dim I, J As Integer
For I = 0 To CorrelationMatrix.Rows - 1
For J = 0 To I - 1
Console.WriteLine("Correlation between column {0} and row {1} is {2}", I, J, CorrelationMatrix(I, J).ToString("G6"))
Next
Next
You can also generate independent streams from different probability
distributions. Here we generate 3 streams each with a different
distribution using the leapfrog technique.
NumberOfStreams = 3
Dim LeapfrogIndStreams As New LeapfrogRandomStreams(Seed, GenType, NumberOfStreams, StreamLength)
Dim Distributions(NumberOfStreams) As IRandomNumberDistribution(Of Double)
Distributions(0) = New DoubleRandomBetaDistribution()
Distributions(1) = New DoubleRandomExponentialDistribution()
Distributions(2) = New DoubleRandomLogNormalDistribution()
Dim C As DoubleMatrix = LeapfrogIndStreams.Next(Distributions)
Print out the rank correlation matrix for the sample to test
independence. Correlations should be near zero for independent
samples.
CorrelationMatrix = RankCorrelation(C, True)
Console.WriteLine()
Console.WriteLine("Spearmans Rank Correlation for samples from different distributions:")
For I = 0 To CorrelationMatrix.Rows - 1
For J = 0 To I - 1
Console.WriteLine("Correlation between column {0} and row {1} is {2}", I, J, CorrelationMatrix(I, J).ToString("G6"))
Next
Next
Independent streams from discrete distributions are also supported.
StreamLength = 5
GenType = RandomNumberStream.BasicRandGenType.WinchannHillCombined
LeapfrogIndStreams = New LeapfrogRandomStreams(GenType, NumberOfStreams, StreamLength)
Dim DiscreteDistributions(NumberOfStreams) As IRandomNumberDistribution(Of Integer)
DiscreteDistributions(0) = New IntRandomBernoulliDistribution(0.6)
DiscreteDistributions(1) = New IntRandomGeometricDistribution(0.2)
DiscreteDistributions(2) = New IntRandomPoissonDistribution(0.8)
Dim DiscreteRandomSamples()() As Integer = LeapfrogIndStreams.Next(Of Integer)(DiscreteDistributions)
The ith independent stream is in the array discreteRandomSamples[i].
For I = 0 To NumberOfStreams - 1
Console.WriteLine()
Console.WriteLine("Distribution: {0}", DiscreteDistributions(I).GetType())
For J = 0 To DiscreteRandomSamples(I).Length - 1
Console.Write("{0}{1}", DiscreteRandomSamples(I)(J), If(J = DiscreteRandomSamples(I).Length, "\n", ", "))
Next
Next
Console.WriteLine()
Console.WriteLine()
Console.WriteLine("Press Enter Key")
Console.Read()
End Sub
<summary>
Computes the Spearman rank correlation matrix for a set of random inputs. The random
inputs are taken to be the columns of the input matrix. The symmetric,
positive definite matrix whose i,j entry is the Spearman correlation coefficient
between the inputs in column i and column j is computed and returned.
</summary>
<param name="A">Matrix whose columns are the inputs whose Spearman rank correlation
coefficient is computed.</param>
<param name="useMidRankForTies">If true mid ranks are used for ranking ties.
</param>
<returns>The symmetric, positive definite matrix whose row i, column j
entry is the correlation coefficient between the inputs in column i and column j
</returns>
Function RankCorrelation(ByVal A As DoubleMatrix, ByVal useMidRankForTies As Boolean) As DoubleSymmetricMatrix
Console.WriteLine("A.Rows " & A.Rows)
Console.WriteLine("A.Cols " & A.Cols)
Dim N As Integer = A.Rows
Console.WriteLine(N)
Dim SortedData(N - 1) As Double
Console.WriteLine(SortedData.Length)
Dim Indices(N - 1) As Integer
Console.WriteLine(Indices.Length)
Dim XRanks As New DoubleVector(N)
Dim YRanks As New DoubleVector(N)
Dim R As New DoubleSymmetricMatrix(A.Cols)
For I = 0 To A.Cols - 1
For J = 0 To A.Cols - 1
If (I = J) Then
R(I, J) = 1.0
Else
RankData(A.Col(I), SortedData, Indices, XRanks, useMidRankForTies)
RankData(A.Col(J), SortedData, Indices, YRanks, useMidRankForTies)
R(I, J) = RankCorrelationFromRanks(XRanks, YRanks)
End If
Next
Next
Return R
End Function
Sub RankData(ByVal Data As DoubleVector, ByVal SortedData() As Double, ByVal Indices() As Integer, ByVal Ranks As DoubleVector, ByVal useMidRankForTies As Boolean)
Console.WriteLine("data: " & Data.Length & " sorted " & SortedData.Length)
If (Data.Length <> SortedData.Length) Then
Throw New InvalidArgumentException("data and sortedData arrays do not have the same length in RankData")
End If
If (Data.Length <> Indices.Length) Then
Throw New InvalidArgumentException("data and indices arrays do not have the same length in RankData")
End If
For I = 0 To Indices.Length - 1
SortedData(I) = Data(I)
Indices(I) = I
Next
Array.Sort(Of Double, Integer)(SortedData, Indices)
For I = 0 To SortedData.Length - 1
Ranks(I) = Array.IndexOf(Of Integer)(Indices, I) + 1
Next
If (useMidRankForTies) Then
ApplyMidranks(SortedData, Ranks)
End If
End Sub
Sub ApplyMidranks(ByRef Data() As Double, ByRef Ranks As DoubleVector)
For I = 1 To Data.Length - 1
If (Data(I) = Data(I - 1)) Then
Dim Start As Integer = I - 1
Dim Count As Integer = 0
Dim Ranksum As Double = 0
While (Start + Count < Data.Length & Data(Start) = Data(Start + Count))
Ranksum += Ranks(Start + Count)
Count = Count + 1
End While
Dim MidRanks As Double = Ranksum / CType(Count, Double)
For S = 0 To Count - 1
Ranks(Start + S) = MidRanks
Next
I = Start + Count
End If
Next
End Sub
Function RankCorrelationFromRanks(ByRef xRanks As DoubleVector, ByRef yRanks As DoubleVector) As Double
Dim N As Integer = xRanks.Length
If (yRanks.Length <> N) Then
Throw New InvalidArgumentException("All arrays must have same length in RankCorreleation")
End If
Dim Sum As Double = 0
For I = 0 To N - 1
Dim D As Double = xRanks(I) - yRanks(I)
Sum += (D * D)
Next
Return (1.0 - ((6 * Sum) / (N * (N * N - 1))))
End Function
End Module
End Namespace
← All NMath Code Examples