diff --git a/src/FSharp/Random.fs b/src/FSharp/Random.fs index 24ee548e..7303bc3c 100644 --- a/src/FSharp/Random.fs +++ b/src/FSharp/Random.fs @@ -55,7 +55,7 @@ module Random = /// Creates a default .Net cryptographic system pRNG let inline crypto () = new CryptoRandomSource() :> System.Random let inline cryptoWith (threadSafe:bool) = new CryptoRandomSource(threadSafe) :> System.Random - let inline cryptoDoubles length = CryptoRandomSource.Doubles(length) + let inline cryptoDoubles (length:int) = CryptoRandomSource.Doubles(length) let inline cryptoDoubleSeq () = CryptoRandomSource.DoubleSequence() #endif diff --git a/src/Numerics/Random/CryptoRandomSource.cs b/src/Numerics/Random/CryptoRandomSource.cs index 86389ee8..871f672f 100644 --- a/src/Numerics/Random/CryptoRandomSource.cs +++ b/src/Numerics/Random/CryptoRandomSource.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,11 +28,11 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System.Collections.Generic; - #if !PORTABLE using System; +using System.Collections.Generic; +using System.Runtime; using System.Security.Cryptography; namespace MathNet.Numerics.Random @@ -48,7 +48,7 @@ namespace MathNet.Numerics.Random /// /// Construct a new random number generator with a random seed. /// - /// Uses and uses the value of + /// Uses and uses the value of /// to set whether the instance is thread safe. public CryptoRandomSource() { @@ -107,24 +107,36 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// - public static double[] Doubles(int length) + /// Supports being called in parallel from multiple threads. + public static void Doubles(double[] values) { var rnd = new RNGCryptoServiceProvider(); - var bytes = new byte[length*4]; + var bytes = new byte[values.Length*4]; rnd.GetBytes(bytes); - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { - data[i] = BitConverter.ToUInt32(bytes, i*4)*Reciprocal; + values[i] = BitConverter.ToUInt32(bytes, i*4)*Reciprocal; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length) + { + var data = new double[length]; + Doubles(data); return data; } /// /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// + /// Supports being called in parallel from multiple threads. public static IEnumerable DoubleSequence() { var rnd = new RNGCryptoServiceProvider(); diff --git a/src/Numerics/Random/Mcg31m1.cs b/src/Numerics/Random/Mcg31m1.cs index b363a74e..8d5e1585 100644 --- a/src/Numerics/Random/Mcg31m1.cs +++ b/src/Numerics/Random/Mcg31m1.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -30,6 +30,10 @@ using System.Collections.Generic; +#if !PORTABLE +using System.Runtime; +#endif + namespace MathNet.Numerics.Random { /// @@ -103,10 +107,10 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// /// Supports being called in parallel from multiple threads. - public static double[] Doubles(int length, int seed) + public static void Doubles(double[] values, int seed) { if (seed == 0) { @@ -114,12 +118,22 @@ namespace MathNet.Numerics.Random } ulong xn = (uint)seed%Modulus; - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { - data[i] = xn*Reciprocal; + values[i] = xn*Reciprocal; xn = (xn*Multiplier)%Modulus; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed) + { + var data = new double[length]; + Doubles(data, seed); return data; } diff --git a/src/Numerics/Random/Mcg59.cs b/src/Numerics/Random/Mcg59.cs index f78eff5f..993b1ae2 100644 --- a/src/Numerics/Random/Mcg59.cs +++ b/src/Numerics/Random/Mcg59.cs @@ -30,6 +30,10 @@ using System.Collections.Generic; +#if !PORTABLE +using System.Runtime; +#endif + namespace MathNet.Numerics.Random { /// @@ -105,10 +109,10 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// /// Supports being called in parallel from multiple threads. - public static double[] Doubles(int length, int seed) + public static void Doubles(double[] values, int seed) { if (seed == 0) { @@ -116,12 +120,22 @@ namespace MathNet.Numerics.Random } ulong xn = (uint)seed%Modulus; - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { - data[i] = xn*Reciprocal; + values[i] = xn*Reciprocal; xn = (xn*Multiplier)%Modulus; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed) + { + var data = new double[length]; + Doubles(data, seed); return data; } diff --git a/src/Numerics/Random/Mrg32k3a.cs b/src/Numerics/Random/Mrg32k3a.cs index fa80cf77..8a2afab4 100644 --- a/src/Numerics/Random/Mrg32k3a.cs +++ b/src/Numerics/Random/Mrg32k3a.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -30,6 +30,10 @@ using System.Collections.Generic; +#if !PORTABLE +using System.Runtime; +#endif + namespace MathNet.Numerics.Random { /// @@ -142,10 +146,10 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// /// Supports being called in parallel from multiple threads. - public static double[] Doubles(int length, int seed) + public static void Doubles(double[] values, int seed) { double x1 = 1; double x2 = 1; @@ -154,8 +158,7 @@ namespace MathNet.Numerics.Random double y2 = 1; double y3 = 1; - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { double xn = A12*x2 - A13*x3; double k = (long)(xn/Modulus1); @@ -179,8 +182,19 @@ namespace MathNet.Numerics.Random y2 = y1; y1 = yn; - data[i] = xn <= yn ? (xn - yn + Modulus1)*Reciprocal : (xn - yn)*Reciprocal; + values[i] = xn <= yn ? (xn - yn + Modulus1)*Reciprocal : (xn - yn)*Reciprocal; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed) + { + var data = new double[length]; + Doubles(data, seed); return data; } diff --git a/src/Numerics/Random/Palf.cs b/src/Numerics/Random/Palf.cs index aa5c4d77..08495bc9 100644 --- a/src/Numerics/Random/Palf.cs +++ b/src/Numerics/Random/Palf.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -32,6 +32,10 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +#if !PORTABLE +using System.Runtime; +#endif + namespace MathNet.Numerics.Random { /// @@ -224,10 +228,10 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// /// Supports being called in parallel from multiple threads. - public static double[] Doubles(int length, int seed) + public static void Doubles(double[] values, int seed) { if (seed == 0) { @@ -247,8 +251,7 @@ namespace MathNet.Numerics.Random var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform*uint.MaxValue)); var k = longLag; - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { if (k >= longLag) { @@ -268,8 +271,19 @@ namespace MathNet.Numerics.Random k = 0; } - data[i] = (int)(x[k++] >> 1)*IntToDoubleMultiplier; + values[i] = (int)(x[k++] >> 1)*IntToDoubleMultiplier; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed) + { + var data = new double[length]; + Doubles(data, seed); return data; } diff --git a/src/Numerics/Random/SystemRandomSource.cs b/src/Numerics/Random/SystemRandomSource.cs index e86b915d..620868b5 100644 --- a/src/Numerics/Random/SystemRandomSource.cs +++ b/src/Numerics/Random/SystemRandomSource.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation diff --git a/src/Numerics/Random/WH1982.cs b/src/Numerics/Random/WH1982.cs index d35bc3b8..1bc04d89 100644 --- a/src/Numerics/Random/WH1982.cs +++ b/src/Numerics/Random/WH1982.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -30,6 +30,10 @@ using System.Collections.Generic; +#if !PORTABLE +using System.Runtime; +#endif + namespace MathNet.Numerics.Random { /// @@ -117,10 +121,10 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// /// Supports being called in parallel from multiple threads. - public static double[] Doubles(int length, int seed) + public static void Doubles(double[] values, int seed) { if (seed == 0) { @@ -130,16 +134,26 @@ namespace MathNet.Numerics.Random uint yn = 1; uint zn = 1; - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { xn = (171*xn)%Modx; yn = (172*yn)%Mody; zn = (170*zn)%Modz; double w = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip; - data[i] = w - (int)w; + values[i] = w - (int)w; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed) + { + var data = new double[length]; + Doubles(data, seed); return data; } diff --git a/src/Numerics/Random/WH2006.cs b/src/Numerics/Random/WH2006.cs index 6cd0ad70..7f5b2df3 100644 --- a/src/Numerics/Random/WH2006.cs +++ b/src/Numerics/Random/WH2006.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -30,6 +30,10 @@ using System.Collections.Generic; +#if !PORTABLE +using System.Runtime; +#endif + namespace MathNet.Numerics.Random { /// @@ -120,10 +124,10 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// /// Supports being called in parallel from multiple threads. - public static double[] Doubles(int length, int seed) + public static void Doubles(double[] values, int seed) { if (seed == 0) { @@ -134,8 +138,7 @@ namespace MathNet.Numerics.Random ulong yn = 1; ulong zn = 1; - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { xn = 11600*xn%Modx; yn = 47003*yn%Mody; @@ -143,8 +146,19 @@ namespace MathNet.Numerics.Random wn = 33000*wn%Modw; double u = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip + wn*ModwRecip; - data[i] = u - (int)u; + values[i] = u - (int)u; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed) + { + var data = new double[length]; + Doubles(data, seed); return data; } diff --git a/src/Numerics/Random/Xorshift.cs b/src/Numerics/Random/Xorshift.cs index 46133ca0..8d585108 100644 --- a/src/Numerics/Random/Xorshift.cs +++ b/src/Numerics/Random/Xorshift.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2013 Math.NET +// Copyright (c) 2009-2014 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -32,6 +32,10 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +#if !PORTABLE +using System.Runtime; +#endif + namespace MathNet.Numerics.Random { /// @@ -264,11 +268,11 @@ namespace MathNet.Numerics.Random } /// - /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. /// /// Supports being called in parallel from multiple threads. [CLSCompliant(false)] - public static double[] Doubles(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed) + public static void Doubles(double[] values, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed) { if (a <= c) { @@ -281,16 +285,27 @@ namespace MathNet.Numerics.Random } ulong x = (uint)seed; - var data = new double[length]; - for (int i = 0; i < data.Length; i++) + for (int i = 0; i < values.Length; i++) { var t = (a*x) + c; x = x1; x1 = x2; c = t >> 32; x2 = t & 0xffffffff; - data[i] = x2*UlongToDoubleMultiplier; + values[i] = x2*UlongToDoubleMultiplier; } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [CLSCompliant(false)] + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed) + { + var data = new double[length]; + Doubles(data, seed, a, c, x1, x2); return data; }