Imports System Imports CenterSpace.NMath.Core Imports CenterSpace.NMath.Matrix Namespace CenterSpace.NMath.Core.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