diff --git a/src/FSharp/AssemblyInfo.fs b/src/FSharp/AssemblyInfo.fs index 66beea9d..eb6ca28f 100644 --- a/src/FSharp/AssemblyInfo.fs +++ b/src/FSharp/AssemblyInfo.fs @@ -43,9 +43,14 @@ open System.Runtime.InteropServices [] [] [] -[] -[] [] [] [] + +#if PORTABLE +#else +[] +[] +#endif + () diff --git a/src/FSharp/Distributions.fs b/src/FSharp/Distributions.fs new file mode 100644 index 00000000..f7da0267 --- /dev/null +++ b/src/FSharp/Distributions.fs @@ -0,0 +1,49 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2012 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.Distributions + +open MathNet.Numerics.Random + +[] +[] +module Distributions = + + let withRandom random (dist:#IDistribution) = + dist.RandomSource <- random + dist + + let withSystemRandom dist = dist |> withRandom (Random.system()) + let withMersenneTwister dist = dist |> withRandom (Random.mersenneTwister()) + +#if PORTABLE +#else + let withCryptoRandom dist = dist |> withRandom (Random.crypto()) +#endif \ No newline at end of file diff --git a/src/FSharp/FSharp.fsproj b/src/FSharp/FSharp.fsproj index 558428a4..c8092380 100644 --- a/src/FSharp/FSharp.fsproj +++ b/src/FSharp/FSharp.fsproj @@ -51,10 +51,12 @@ + + - + diff --git a/src/FSharp/Main.fs b/src/FSharp/LinearAlgebra.Double.fs similarity index 94% rename from src/FSharp/Main.fs rename to src/FSharp/LinearAlgebra.Double.fs index b36c414d..7c734e24 100644 --- a/src/FSharp/Main.fs +++ b/src/FSharp/LinearAlgebra.Double.fs @@ -28,13 +28,13 @@ // OTHER DEALINGS IN THE SOFTWARE. // -namespace MathNet.Numerics +namespace MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Generic -open MathNet.Numerics.LinearAlgebra.Double /// A module which implements some F# utility functions. -module FSharp = +[] +module Utility = /// Construct a dense matrix from a list of floating point numbers. let inline matrix (lst: list>) = DenseMatrix.ofList lst :> Matrix diff --git a/src/FSharp/Random.fs b/src/FSharp/Random.fs new file mode 100644 index 00000000..327e9e3d --- /dev/null +++ b/src/FSharp/Random.fs @@ -0,0 +1,85 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2012 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.Random + +[] +module Random = + + /// Provides a seed based on unique GUIDs + let seed () = System.Guid.NewGuid().GetHashCode() + + /// Provides a time-dependent seed value (caution, can produce the same value on quick repeated execution) + let timeSeed () = System.Environment.TickCount + + /// Creates a default .Net system pRNG with a custom seed based on uinque GUIDs + let system () = new System.Random(seed()) + let systemWith seed = new System.Random(seed) + +#if PORTABLE +#else + /// Creates a default .Net cryptographic system pRNG + let crypto () = new SystemCryptoRandomNumberGenerator() :> System.Random + let cryptoWith (threadSafe:bool) = new SystemCryptoRandomNumberGenerator(threadSafe) :> System.Random +#endif + + /// Creates a Mersenne Twister 19937 pRNG with a custom seed based on uinque GUIDs + let mersenneTwister () = new MersenneTwister(seed()) :> System.Random + let mersenneTwisterWith seed threadSafe = new MersenneTwister(seed, threadSafe) :> System.Random + + /// Creates a multiply-with-carry Xorshift (Xn = a * Xn−3 + c mod 2^32) pRNG with a custom seed based on uinque GUIDs + let xorshift () = new Xorshift(seed()) :> System.Random + let xorshiftWith seed threadSafe = new Xorshift(seed, threadSafe) :> System.Random + let xorshiftCustom seed threadSafe a c x1 x2 = new Xorshift(seed, threadSafe, a, c, x1, x2) :> System.Random + + /// Creates a Wichmann-Hill’s 1982 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs + let wh1982 () = new WH1982(seed()) :> System.Random + let wh1982With seed threadSafe = new WH1982(seed, threadSafe) :> System.Random + + /// Creates a Wichmann-Hill’s 2006 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs + let wh2006 () = new WH2006(seed()) :> System.Random + let wh2006With seed threadSafe = new WH2006(seed, threadSafe) :> System.Random + + /// Creates a Parallel Additive Lagged Fibonacci pRNG with a custom seed based on uinque GUIDs + let palf () = new Palf(seed()) :> System.Random + let palfWith seed threadSafe = new Palf(seed, threadSafe, 418, 1279) :> System.Random + let palfCustom seed threadSafe shortLag longLag = new Palf(seed, threadSafe, shortLag, longLag) :> System.Random + + /// Creates a Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13 pRNG with a custom seed based on uinque GUIDs + let mcg59 () = new Mcg59(seed()) :> System.Random + let mcg59With seed threadSafe = new Mcg59(seed, threadSafe) :> System.Random + + /// Creates a Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760 pRNG with a custom seed based on uinque GUIDs + let mcg31m1 () = new Mcg31m1(seed()) :> System.Random + let mcg31m1With seed threadSafe = new Mcg31m1(seed, threadSafe) :> System.Random + + /// Creates a 32-bit combined multiple recursive generator with 2 components of order 3 pRNG with a custom seed based on uinque GUIDs + let mrg32k3a () = new Mrg32k3a(seed()) :> System.Random + let mrg32k3aWith seed threadSafe = new Mrg32k3a(seed, threadSafe) :> System.Random diff --git a/src/FSharpExamples/DenseVector.fs b/src/FSharpExamples/DenseVector.fs index 48f9994f..eff54d91 100644 --- a/src/FSharpExamples/DenseVector.fs +++ b/src/FSharpExamples/DenseVector.fs @@ -27,17 +27,17 @@ // module MathNet.Numerics.FSharp.Examples.DenseVector -open MathNet.Numerics.FSharp open MathNet.Numerics.LinearAlgebra +open MathNet.Numerics.LinearAlgebra.Double // Create a new 100 dimensional dense vector. -let v = Double.DenseVector.init 100 (fun i -> float i / 100.0) +let v = DenseVector.init 100 (fun i -> float i / 100.0) // Another way to create a 100 dimensional dense vector is using the vector function. let w = vector (List.init 100 (fun i -> float i ** 2.0)) // Vectors can also be constructed from sequences. -let t = Double.DenseVector.ofSeq (seq { for i in 1 .. 100 do yield float i }) +let t = DenseVector.ofSeq (seq { for i in 1 .. 100 do yield float i }) // We can now add two vectors together ... let z = v + w @@ -46,9 +46,8 @@ let z = v + w let x = v + 3.0 * t - // We can create a vector from an integer range (in this case, 5 and 10 inclusive) ... -let s = Double.DenseVector.range 5 10 +let s = DenseVector.range 5 10 // ... or we can create a vector from a double range with a particular step size. -let r = Double.DenseVector.rangef 0.0 0.1 10.0 \ No newline at end of file +let r = DenseVector.rangef 0.0 0.1 10.0 \ No newline at end of file diff --git a/src/FSharpExamples/FSharpExamples.fsproj b/src/FSharpExamples/FSharpExamples.fsproj index b9a68485..b52483c1 100644 --- a/src/FSharpExamples/FSharpExamples.fsproj +++ b/src/FSharpExamples/FSharpExamples.fsproj @@ -64,6 +64,7 @@ + 11 diff --git a/src/FSharpExamples/RandomAndDistributions.fs b/src/FSharpExamples/RandomAndDistributions.fs new file mode 100644 index 00000000..cec6a7f5 --- /dev/null +++ b/src/FSharpExamples/RandomAndDistributions.fs @@ -0,0 +1,77 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009-2012 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +module RandomAndDistributions + +open MathNet.Numerics.Random +open MathNet.Numerics.Distributions + +// generate some seeds for random values +let someGuidSeed = Random.seed () +let someTimeSeed = Random.timeSeed () + +// generate some pseudo random number generators (listing incomplete; all of them are cast to the common base type, System.Random) +let a = Random.system () +let b = Random.systemWith (Random.timeSeed()) +let c = Random.crypto () +let d = Random.mersenneTwister () +let e = Random.mersenneTwisterWith 1000 true (* thread-safe *) +let f = Random.xorshift () +let g = Random.xorshiftCustom someTimeSeed false 916905990L 13579L 362436069L 77465321L +let h = Random.wh2006 () +let i = Random.palf () + +// generate some uniform random values +let values = ( + a.Next(), + b.NextFullRangeInt32(), + c.NextFullRangeInt64(), + d.NextInt64(), + e.NextDouble(), + f.NextDecimal() + ) + +// generate some probability distributions +let normal = Normal.WithMeanVariance(3.0, 1.5) |> withRandom g +let exponential = new Exponential(2.4) +let gamma = new Gamma(2.0, 1.5) |> withCryptoRandom +let cauchy = new Cauchy() |> withRandom (Random.mrg32k3aWith 10 false) +let poisson = new Poisson(3.0) +let geometric = new Geometric(1.2) |> withSystemRandom + +// generate some random samples from these distributions +let continuous = [ + yield normal.Sample() + yield exponential.Sample() + yield! gamma.Samples() |> Seq.take 10 + ] +let discrete = [ + poisson.Sample() + poisson.Sample() + geometric.Sample() + ] \ No newline at end of file diff --git a/src/FSharpPortable/FSharpPortable.fsproj b/src/FSharpPortable/FSharpPortable.fsproj index a104d832..67038619 100644 --- a/src/FSharpPortable/FSharpPortable.fsproj +++ b/src/FSharpPortable/FSharpPortable.fsproj @@ -44,6 +44,12 @@ AssemblyInfo.fs + + Random.fs + + + Distributions.fs + LinearAlgebra.fs @@ -53,8 +59,8 @@ LinearAlgebra.Double.Vector.fs - - Main.fs + + LinearAlgebra.Double.fs diff --git a/src/FSharpUnitTests/Program.fs b/src/FSharpUnitTests/Program.fs index 04d43d03..79780a5a 100644 --- a/src/FSharpUnitTests/Program.fs +++ b/src/FSharpUnitTests/Program.fs @@ -1,7 +1,6 @@ open FsUnit -open MathNet.Numerics.FSharp -open MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Generic +open MathNet.Numerics.LinearAlgebra.Double /// Unit tests for the dense vector type. let DenseVectorTests =