forked from tsai/mathnet-numerics
Browse Source
Signed-off-by: jvangael <jurgen.vangael@gmail.com> Signed-off-by: jvangael <jurgen.vangael@gmail.com>la-knuth
10 changed files with 857 additions and 7 deletions
@ -0,0 +1,278 @@ |
|||||
|
// <copyright file="Bernoulli.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 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.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.Distributions |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Properties; |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Implements the multinomial distribution. For details about this distribution, see
|
||||
|
/// <a href="http://en.wikipedia.org/wiki/Multinomial_distribution">Wikipedia - Multinomial distribution</a>.
|
||||
|
/// </summary>
|
||||
|
/// <remarks><para>The distribution is parameterized by a vector of ratios: in other words, the parameter
|
||||
|
/// does not have to be normalized and sum to 1. The reason is that some vectors can't be exactly normalized
|
||||
|
/// to sum to 1 in floating point representation.</para>
|
||||
|
/// <para>The distribution will use the <see cref="System.Random"/> by default.
|
||||
|
/// Users can set the random number generator by using the <see cref="RandomSource"/> property.</para>
|
||||
|
/// <para>The statistics classes will check all the incoming parameters whether they are in the allowed
|
||||
|
/// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters
|
||||
|
/// to false, all parameter checks can be turned off.</para></remarks>
|
||||
|
public class Multinomial |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Stores the normalized multinomial probabilities.
|
||||
|
/// </summary>
|
||||
|
private double[] _p; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The distribution's random number generator.
|
||||
|
/// </summary>
|
||||
|
private Random _random; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the Multinomial class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="p">An array of nonnegative ratios: this array does not need to be normalized
|
||||
|
/// as this is often impossible using floating point arithmetic.</param>
|
||||
|
/// <exception cref="ArgumentException">If any of the probabilities are negative or do not sum to one.</exception>
|
||||
|
public Multinomial(double[] p) |
||||
|
{ |
||||
|
SetParameters(p); |
||||
|
RandomSource = new System.Random(); |
||||
|
} |
||||
|
|
||||
|
/* TODO |
||||
|
/// <summary>
|
||||
|
/// Generate a multinomial distribution from histogram <paramref name="h"/>. The distribution will
|
||||
|
/// not be automatically updated when the histogram changes.
|
||||
|
/// </summary>
|
||||
|
public Multinomial(Histogram h) |
||||
|
{ |
||||
|
// The probability distribution vector.
|
||||
|
_p = new double[h.BinCount]; |
||||
|
|
||||
|
// Fill in the distribution vector.
|
||||
|
for (int i = 0; i < h.BinCount; i++) |
||||
|
{ |
||||
|
_p[i] = h[i]; |
||||
|
} |
||||
|
|
||||
|
RandomNumberGenerator = new System.Random(); |
||||
|
}*/ |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A string representation of the distribution.
|
||||
|
/// </summary>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return "Multinomial(Dimension = " + _p.Length + ")"; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks whether the parameters of the distribution are valid.
|
||||
|
/// </summary>
|
||||
|
/// <param name="p">An array of nonnegative ratios: this array does not need to be normalized
|
||||
|
/// as this is often impossible using floating point arithmetic.</param>
|
||||
|
/// <returns>If any of the probabilities are negative returns false, or if the sum of parameters is 0.0; otherwise true</returns>
|
||||
|
private static bool IsValidParameterSet(double[] p) |
||||
|
{ |
||||
|
double sum = 0.0; |
||||
|
for (int i = 0; i < p.Length; i++) |
||||
|
{ |
||||
|
if (p[i] < 0.0 || Double.IsNaN(p[i])) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
sum += p[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (sum == 0.0) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sets the parameters of the distribution after checking their validity.
|
||||
|
/// </summary>
|
||||
|
/// <param name="p">An array of nonnegative ratios: this array does not need to be normalized
|
||||
|
/// as this is often impossible using floating point arithmetic.</param>
|
||||
|
/// <exception cref="ArgumentOutOfRangeException">When the parameters don't pass the <see cref="IsValidParameterSet"/> function.</exception>
|
||||
|
private void SetParameters(double[] p) |
||||
|
{ |
||||
|
if (Control.CheckDistributionParameters && !IsValidParameterSet(p)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); |
||||
|
} |
||||
|
|
||||
|
_p = (double[])p.Clone(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the probability of generating a one.
|
||||
|
/// </summary>
|
||||
|
public double[] P |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return (double[]) _p.Clone(); |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
SetParameters(value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the random number generator which is used to draw random samples.
|
||||
|
/// </summary>
|
||||
|
public Random RandomSource |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return _random; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException(); |
||||
|
} |
||||
|
|
||||
|
_random = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Samples one multinomial distributed random variable; also known as the Discrete distribution.
|
||||
|
/// </summary>
|
||||
|
/// <returns>One random integer between 0 and the size of the multinomial (exclusive).</returns>
|
||||
|
public int Sample() |
||||
|
{ |
||||
|
return Sample(RandomSource, _p); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Samples a multinomially distributed random variable.
|
||||
|
/// </summary>
|
||||
|
/// <param name="n">The number of variables needed.</param>
|
||||
|
/// <returns><paramref name="n"/> random integers between 0 and the size of the multinomial (exclusive).</returns>
|
||||
|
public int[] Sample(int n) |
||||
|
{ |
||||
|
return Sample(RandomSource, n, _p); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Samples one multinomial distributed random variable; also known as the Discrete distribution.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rnd">The random number generator to use.</param>
|
||||
|
/// <param name="p">An array of nonnegative ratios: this array does not need to be normalized
|
||||
|
/// as this is often impossible using floating point arithmetic.</param>
|
||||
|
/// <returns>One random integer between 0 and the size of the multinomial (exclusive).</returns>
|
||||
|
public static int Sample(System.Random rnd, double[] p) |
||||
|
{ |
||||
|
if (Control.CheckDistributionParameters && !IsValidParameterSet(p)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); |
||||
|
} |
||||
|
|
||||
|
// The cumulative density of p.
|
||||
|
double[] cp = UnnormalizedCDF(p); |
||||
|
|
||||
|
double u = rnd.NextDouble()*cp[cp.Length - 1]; |
||||
|
int idx = 0; |
||||
|
while (u > cp[idx]) |
||||
|
{ |
||||
|
idx++; |
||||
|
} |
||||
|
return idx; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Samples a multinomially distributed random variable.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rnd">The random number generator to use.</param>
|
||||
|
/// <param name="n">The number of variables needed.</param>
|
||||
|
/// <param name="p">An array of nonnegative ratios: this array does not need to be normalized
|
||||
|
/// as this is often impossible using floating point arithmetic.</param>
|
||||
|
/// <returns><paramref name="n"/> random integers between 0 and the size of the multinomial (exclusive).</returns>
|
||||
|
public static int[] Sample(System.Random rnd, int n, double[] p) |
||||
|
{ |
||||
|
if (Control.CheckDistributionParameters && !IsValidParameterSet(p)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); |
||||
|
} |
||||
|
|
||||
|
// The cumulative density of p.
|
||||
|
double[] cp = UnnormalizedCDF(p); |
||||
|
|
||||
|
int[] arr = new int[n]; |
||||
|
for (int i = 0; i < n; i++) |
||||
|
{ |
||||
|
double u = rnd.NextDouble()*cp[cp.Length - 1]; |
||||
|
int idx = 0; |
||||
|
while (u > cp[idx]) |
||||
|
{ |
||||
|
idx++; |
||||
|
} |
||||
|
arr[i] = idx; |
||||
|
} |
||||
|
|
||||
|
return arr; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the unnormalized cumulative distribution function. This method performs no
|
||||
|
/// parameter checking.
|
||||
|
/// </summary>
|
||||
|
/// <param name="p">An array of nonnegative ratios: this array does not need to be normalized
|
||||
|
/// as this is often impossible using floating point arithmetic.</param>
|
||||
|
/// <returns>An array representing the unnormalized cumulative distribution function.</returns>
|
||||
|
private static double[] UnnormalizedCDF(double[] p) |
||||
|
{ |
||||
|
double[] cp = (double[]) p.Clone(); |
||||
|
|
||||
|
for (int i = 1; i < p.Length; i++) |
||||
|
{ |
||||
|
cp[i] += cp[i - 1]; |
||||
|
} |
||||
|
|
||||
|
return cp; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,312 @@ |
|||||
|
// <copyright file="MersenneTwister.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 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.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
/* |
||||
|
Original code's copyright and license: |
||||
|
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, |
||||
|
All rights reserved. |
||||
|
|
||||
|
Redistribution and use in source and binary forms, with or without |
||||
|
modification, are permitted provided that the following conditions |
||||
|
are met: |
||||
|
|
||||
|
1. Redistributions of source code must retain the above copyright |
||||
|
notice, this list of conditions and the following disclaimer. |
||||
|
|
||||
|
2. Redistributions in binary form must reproduce the above copyright |
||||
|
notice, this list of conditions and the following disclaimer in the |
||||
|
documentation and/or other materials provided with the distribution. |
||||
|
|
||||
|
3. The names of its contributors may not be used to endorse or promote |
||||
|
products derived from this software without specific prior written |
||||
|
permission. |
||||
|
|
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
|
||||
|
|
||||
|
Any feedback is very welcome. |
||||
|
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
|
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) |
||||
|
*/ |
||||
|
|
||||
|
namespace MathNet.Numerics.Random |
||||
|
{ |
||||
|
using System; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Random number generator using Mersenne Twister 19937 algorithm.
|
||||
|
/// </summary>
|
||||
|
public class MersenneTwister : AbstractRandomNumberGenerator, IDisposable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private const uint _lower_mask = 0x7fffffff; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private const int _m = 397; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private const uint _matrix_a = 0x9908b0df; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private const int _n = 624; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private const double _reciprocal = 1.0/4294967295.0; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private const uint _upper_mask = 0x80000000; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private static readonly uint[] _mag01 = {0x0U, _matrix_a}; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private readonly uint[] _mt = new uint[624]; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Mersenne twister constant.
|
||||
|
/// </summary>
|
||||
|
private int mti = _n + 1; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="MersenneTwister"/> class using
|
||||
|
/// the current time as the seed.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>If the seed value is zero, it is set to one. Uses the
|
||||
|
/// value of <see cref="Control.ThreadSafeRandomNumberGenerators"/> to
|
||||
|
/// set whether the instance is thread safe.</remarks>
|
||||
|
public MersenneTwister() : this((int) DateTime.Now.Ticks) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="MersenneTwister"/> class using
|
||||
|
/// the current time as the seed.
|
||||
|
/// </summary>
|
||||
|
/// <param name="threadSafe">if set to <c>true</c> , the class is thread safe.</param>
|
||||
|
public MersenneTwister(bool threadSafe) : this((int) DateTime.Now.Ticks, threadSafe) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="MersenneTwister"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="seed">The seed value.</param>
|
||||
|
/// <remarks>Uses the value of <see cref="Control.ThreadSafeRandomNumberGenerators"/> to
|
||||
|
/// set whether the instance is thread safe.</remarks>
|
||||
|
public MersenneTwister(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="MersenneTwister"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="seed">The seed value.</param>
|
||||
|
/// <param name="threadSafe">if set to <c>true</c>, the class is thread safe.</param>
|
||||
|
public MersenneTwister(int seed, bool threadSafe) : base(threadSafe) |
||||
|
{ |
||||
|
init_genrand((uint)seed); |
||||
|
} |
||||
|
|
||||
|
/*/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="MersenneTwister"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="init_key">The initialization key.</param>
|
||||
|
public MersenneTwister(int[] init_key) |
||||
|
{ |
||||
|
if (init_key == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("init_key"); |
||||
|
} |
||||
|
uint[] array = new uint[init_key.Length]; |
||||
|
for (int i = 0; i < array.Length; i++) |
||||
|
{ |
||||
|
array[i] = (uint) init_key[i]; |
||||
|
} |
||||
|
init_by_array(array); |
||||
|
} |
||||
|
*/ |
||||
|
/* initializes _mt[_n] with a seed */ |
||||
|
|
||||
|
private void init_genrand(uint s) |
||||
|
{ |
||||
|
_mt[0] = s & 0xffffffff; |
||||
|
for (mti = 1; mti < _n; mti++) |
||||
|
{ |
||||
|
_mt[mti] = (1812433253*(_mt[mti - 1] ^ (_mt[mti - 1] >> 30)) + (uint) mti); |
||||
|
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ |
||||
|
/* In the previous versions, MSBs of the seed affect */ |
||||
|
/* only MSBs of the array _mt[]. */ |
||||
|
/* 2002/01/09 modified by Makoto Matsumoto */ |
||||
|
_mt[mti] &= 0xffffffff; |
||||
|
/* for >32 bit machines */ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* initialize by an array with array-length */ |
||||
|
/* init_key is the array for initializing keys */ |
||||
|
/* slight change for C++, 2004/2/26 */ |
||||
|
|
||||
|
/* private void init_by_array(uint[] init_key) |
||||
|
{ |
||||
|
uint key_length = (uint) init_key.Length; |
||||
|
init_genrand(19650218); |
||||
|
uint i = 1; |
||||
|
uint j = 0; |
||||
|
uint k = (_n > key_length ? _n : key_length); |
||||
|
for (; k > 0; k--) |
||||
|
{ |
||||
|
_mt[i] = (_mt[i] ^ ((_mt[i - 1] ^ (_mt[i - 1] >> 30))*1664525)) + init_key[j] + j; //non linear
|
||||
|
_mt[i] &= 0xffffffff; // for WORDSIZE > 32 machines
|
||||
|
i++; |
||||
|
j++; |
||||
|
if (i >= _n) |
||||
|
{ |
||||
|
_mt[0] = _mt[_n - 1]; |
||||
|
i = 1; |
||||
|
} |
||||
|
if (j >= key_length) j = 0; |
||||
|
} |
||||
|
for (k = _n - 1; k > 0; k--) |
||||
|
{ |
||||
|
_mt[i] = (_mt[i] ^ ((_mt[i - 1] ^ (_mt[i - 1] >> 30))*1566083941)) - i; // non linear
|
||||
|
_mt[i] &= 0xffffffff; // for WORDSIZE > 32 machines
|
||||
|
i++; |
||||
|
if (i >= _n) |
||||
|
{ |
||||
|
_mt[0] = _mt[_n - 1]; |
||||
|
i = 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
_mt[0] = 0x80000000; // MSB is 1; assuring non-zero initial array
|
||||
|
}*/ |
||||
|
|
||||
|
/* generates a random number on [0,0xffffffff]-interval */ |
||||
|
|
||||
|
private uint genrand_int32() |
||||
|
{ |
||||
|
uint y; |
||||
|
|
||||
|
/* mag01[x] = x * MATRIX_A for x=0,1 */ |
||||
|
|
||||
|
if (mti >= _n) |
||||
|
{ |
||||
|
/* generate _n words at one time */ |
||||
|
int kk; |
||||
|
|
||||
|
if (mti == _n + 1) /* if init_genrand() has not been called, */ |
||||
|
init_genrand(5489); /* a default initial seed is used */ |
||||
|
|
||||
|
for (kk = 0; kk < _n - _m; kk++) |
||||
|
{ |
||||
|
y = (_mt[kk] & _upper_mask) | (_mt[kk + 1] & _lower_mask); |
||||
|
_mt[kk] = _mt[kk + _m] ^ (y >> 1) ^ _mag01[y & 0x1]; |
||||
|
} |
||||
|
for (; kk < _n - 1; kk++) |
||||
|
{ |
||||
|
y = (_mt[kk] & _upper_mask) | (_mt[kk + 1] & _lower_mask); |
||||
|
_mt[kk] = _mt[kk + (_m - _n)] ^ (y >> 1) ^ _mag01[y & 0x1]; |
||||
|
} |
||||
|
y = (_mt[_n - 1] & _upper_mask) | (_mt[0] & _lower_mask); |
||||
|
_mt[_n - 1] = _mt[_m - 1] ^ (y >> 1) ^ _mag01[y & 0x1]; |
||||
|
|
||||
|
mti = 0; |
||||
|
} |
||||
|
|
||||
|
y = _mt[mti++]; |
||||
|
|
||||
|
/* Tempering */ |
||||
|
y ^= (y >> 11); |
||||
|
y ^= (y << 7) & 0x9d2c5680; |
||||
|
y ^= (y << 15) & 0xefc60000; |
||||
|
y ^= (y >> 18); |
||||
|
|
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a random number between 0.0 and 1.0.
|
||||
|
/// </summary>
|
||||
|
/// <returns>
|
||||
|
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
|
||||
|
/// </returns>
|
||||
|
protected override double DoSample() |
||||
|
{ |
||||
|
return genrand_int32() * _reciprocal; |
||||
|
} |
||||
|
|
||||
|
/* /// <summary>
|
||||
|
/// Generates a random number on [0,1) with 53-bit resolution.
|
||||
|
/// </summary>
|
||||
|
/// <returns>A random number on [0,1) with 53-bit resolution.</returns>
|
||||
|
public double NextDoubleResolution53() |
||||
|
{ |
||||
|
ulong a = genrand_int32() >> 5, b = genrand_int32() >> 6; |
||||
|
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); |
||||
|
}*/ |
||||
|
|
||||
|
#region IDisposable Members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
|
/// </summary>
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
//do nothing in the managed version.
|
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,117 @@ |
|||||
|
// <copyright file="MultinomialTests.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 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.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.DistributionTests |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using MbUnit.Framework; |
||||
|
using MathNet.Numerics.Distributions; |
||||
|
|
||||
|
[TestFixture] |
||||
|
public class MultinomialTests |
||||
|
{ |
||||
|
double[] badP; |
||||
|
double[] badP2; |
||||
|
double[] smallP; |
||||
|
double[] largeP; |
||||
|
|
||||
|
[SetUp] |
||||
|
public void SetUp() |
||||
|
{ |
||||
|
Control.CheckDistributionParameters = true; |
||||
|
badP = new double[] { -1.0, 1.0 }; |
||||
|
badP2 = new double[] { 0.0, 0.0 }; |
||||
|
smallP = new double[] {1.0, 1.0, 1.0}; |
||||
|
largeP = new double[] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanCreateMultinomial() |
||||
|
{ |
||||
|
var m = new Multinomial(largeP); |
||||
|
AssertEx.AreEqual<double[]>(largeP, m.P); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))] |
||||
|
public void MultinomialCreateFailsWithNegativeRatios() |
||||
|
{ |
||||
|
var m = new Multinomial(badP); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))] |
||||
|
public void MultinomialCreateFailsWithAllZeroRatios() |
||||
|
{ |
||||
|
var m = new Multinomial(badP2); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void ValidateToString() |
||||
|
{ |
||||
|
var b = new Multinomial(smallP); |
||||
|
AssertEx.AreEqual<string>("Multinomial(Dimension = 3)", b.ToString()); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanSetProbability() |
||||
|
{ |
||||
|
var b = new Multinomial(largeP); |
||||
|
b.P = smallP; |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))] |
||||
|
public void SetProbabilityFails() |
||||
|
{ |
||||
|
var b = new Multinomial(largeP); |
||||
|
b.P = badP; |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanSampleStatic() |
||||
|
{ |
||||
|
var d = Multinomial.Sample(new Random(), largeP); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))] |
||||
|
public void FailSampleStatic() |
||||
|
{ |
||||
|
var d = Multinomial.Sample(new Random(), badP); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanSample() |
||||
|
{ |
||||
|
var n = new Multinomial(largeP); |
||||
|
var d = n.Sample(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
// <copyright file="SystemRandomExtensionTests.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 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.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.RandomTests |
||||
|
{ |
||||
|
using MbUnit.Framework; |
||||
|
using MathNet.Numerics.Random; |
||||
|
|
||||
|
[TestFixture] |
||||
|
public class MersenneTwisterTests : RandomTests |
||||
|
{ |
||||
|
public MersenneTwisterTests() : base(typeof(MersenneTwister)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
[Test, MultipleAsserts] |
||||
|
public void SampleKnownValues() |
||||
|
{ |
||||
|
MersenneTwister mt = new MersenneTwister(0); |
||||
|
Assert.AreEqual(mt.NextDouble(), 0.5488135024320365); |
||||
|
Assert.AreEqual(mt.NextDouble(), 0.5928446165269344); |
||||
|
Assert.AreEqual(mt.NextDouble(), 0.7151893651381110); |
||||
|
Assert.AreEqual(mt.NextDouble(), 0.8442657442866512); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,91 @@ |
|||||
|
// <copyright file="SystemRandomExtensionTests.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 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.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.RandomTests |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using MbUnit.Framework; |
||||
|
using MathNet.Numerics.Random; |
||||
|
|
||||
|
public abstract class RandomTests |
||||
|
{ |
||||
|
private const int _n = 10000; |
||||
|
private readonly Type _randomType; |
||||
|
|
||||
|
protected RandomTests(Type randomType) |
||||
|
{ |
||||
|
_randomType = randomType; |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void Sample() |
||||
|
{ |
||||
|
System.Random random = (System.Random) Activator.CreateInstance(_randomType, new object[] {false}); |
||||
|
double sum = 0; |
||||
|
for (int i = 0; i < _n; i++) |
||||
|
{ |
||||
|
double next = random.NextDouble(); |
||||
|
sum += next; |
||||
|
Assert.IsTrue(next >= 0); |
||||
|
Assert.IsTrue(next <= 1); |
||||
|
} |
||||
|
//make sure are within 10% of the expected sum.
|
||||
|
Assert.IsTrue(sum >= _n / 2.0 - .05 * _n); |
||||
|
Assert.IsTrue(sum <= _n / 2.0 + .05 * _n); |
||||
|
if (random is IDisposable) |
||||
|
{ |
||||
|
((IDisposable) random).Dispose(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void ThreadSafeSample() |
||||
|
{ |
||||
|
System.Random random = (System.Random) Activator.CreateInstance(_randomType, new object[] {true}); |
||||
|
|
||||
|
Thread t1 = new Thread(runTest); |
||||
|
Thread t2 = new Thread(runTest); |
||||
|
t1.Start(random); |
||||
|
t2.Start(random); |
||||
|
t1.Join(); |
||||
|
t2.Join(); |
||||
|
} |
||||
|
|
||||
|
public void runTest(object random) |
||||
|
{ |
||||
|
System.Random rng = (System.Random) random; |
||||
|
for (int i = 0; i < _n; i++) |
||||
|
{ |
||||
|
double next = rng.NextDouble(); |
||||
|
Assert.IsTrue(next >= 0); |
||||
|
Assert.IsTrue(next <= 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue