Math.NET Numerics
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

346 lines
30 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Pseudo-Random Numbers
</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="author" content="Christoph Ruegg, Marcus Cuda, Jurgen Van Gael">
<link rel="stylesheet" id="theme_link" href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/4.6.0/materia/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"></script>
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
<link type="text/css" rel="stylesheet" href="https://numerics.mathdotnet.com/content/navbar-fixed-left.css" />
<link type="text/css" rel="stylesheet" href="https://numerics.mathdotnet.com/content/fsdocs-default.css" />
<link type="text/css" rel="stylesheet" href="https://numerics.mathdotnet.com/content/fsdocs-custom.css" />
<script type="text/javascript" src="https://numerics.mathdotnet.com/content/fsdocs-tips.js"></script>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- BEGIN SEARCH BOX: this adds support for the search box -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/JavaScript-autoComplete/1.0.4/auto-complete.css" />
<!-- END SEARCH BOX: this adds support for the search box -->
</head>
<body>
<nav class="navbar navbar-expand-md navbar-light bg-secondary fixed-left" id="fsdocs-nav">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse navbar-nav-scroll" id="navbarsExampleDefault">
<a href="https://numerics.mathdotnet.com/"><img id="fsdocs-logo" src="/logo.png" /></a>
<!-- BEGIN SEARCH BOX: this adds support for the search box -->
<div id="header">
<div class="searchbox" id="fsdocs-searchbox">
<label for="search-by">
<i class="fas fa-search"></i>
</label>
<input data-search-input="" id="search-by" type="search" placeholder="Search..." />
<span data-search-clear="">
<i class="fas fa-times"></i>
</span>
</div>
</div>
<!-- END SEARCH BOX: this adds support for the search box -->
<ul class="navbar-nav">
<li class="nav-header">Math.NET Numerics</li>
<li class="nav-item"><a class="nav-link" href="Packages.html">NuGet & Binaries</a></li>
<li class="nav-item"><a class="nav-link" href="ReleaseNotes.html">Release Notes</a></li>
<li class="nav-item"><a class="nav-link" href="https://github.com/mathnet/mathnet-numerics/blob/master/LICENSE.md">MIT License</a></li>
<li class="nav-item"><a class="nav-link" href="Compatibility.html">Platform Support</a></li>
<li class="nav-item"><a class="nav-link" href="https://numerics.mathdotnet.com/api/">Class Reference</a></li>
<li class="nav-item"><a class="nav-link" href="https://github.com/mathnet/mathnet-numerics/issues">Issues & Bugs</a></li>
<li class="nav-item"><a class="nav-link" href="Users.html">Who is using Math.NET?</a></li>
<li class="nav-header">Contributing</li>
<li class="nav-item"><a class="nav-link" href="Contributors.html">Contributors</a></li>
<li class="nav-item"><a class="nav-link" href="Contributing.html">Contributing</a></li>
<li class="nav-item"><a class="nav-link" href="Build.html">Build & Tools</a></li>
<li class="nav-item"><a class="nav-link" href="https://github.com/mathnet/mathnet-numerics/discussions/categories/ideas">Your Ideas</a></li>
<li class="nav-header">Getting Help</li>
<li class="nav-item"><a class="nav-link" href="https://discuss.mathdotnet.com/c/numerics">Discuss</a></li>
<li class="nav-item"><a class="nav-link" href="https://stackoverflow.com/questions/tagged/mathdotnet">Stack Overflow</a></li>
<li class="nav-header">Getting Started</li>
<l class="nav-item"i><a class="nav-link" href="/">Getting started</a></li>
<li class="nav-item"><a class="nav-link" href="Constants.html">Constants</a></li>
<li class="nav-item"><a class="nav-link" href="Matrix.html">Matrices and Vectors</a></li>
<li class="nav-item"><a class="nav-link" href="Euclid.html">Euclid & Number Theory</a></li>
<li class="nav-item">Combinatorics</li>
<li class="nav-header">Evaluation</li>
<li class="nav-item"><a class="nav-link" href="Functions.html">Special Functions</a></li>
<li class="nav-item"><a class="nav-link" href="Integration.html">Integration</a></li>
<li class="nav-header">Statistics/Probability</li>
<li class="nav-item"><a class="nav-link" href="DescriptiveStatistics.html">Descriptive Statistics</a></li>
<li class="nav-item"><a class="nav-link" href="Probability.html">Probability Distributions</a></li>
<li class="nav-header">Generation</li>
<li class="nav-item"><a class="nav-link" href="Generate.html">Generating Data</a></li>
<li class="nav-item"><a class="nav-link" href="Random.html">Random Numbers</a></li>
<li class="nav-header">Solving Equations</li>
<li class="nav-item"><a class="nav-link" href="LinearEquations.html">Linear Equation Systems</a></li>
<li class="nav-header">Optimization</li>
<li class="nav-item"><a class="nav-link" href="Distance.html">Distance Metrics</a></li>
<li class="nav-header">Curve Fitting</li>
<li class="nav-item"><a class="nav-link" href="Regression.html">Regression</a></li>
<li class="nav-header">Native Providers</li>
<li class="nav-item"><a class="nav-link" href="MKL.html">Intel MKL</a></li>
<li class="nav-header">Working Together</li>
<li class="nav-item"><a class="nav-link" href="CSV.html">Delimited Text Files (CSV)</a></li>
<li class="nav-item"><a class="nav-link" href="MatrixMarket.html">NIST MatrixMarket</a></li>
<li class="nav-item"><a class="nav-link" href="MatlabFiles.html">MATLAB</a></li>
<li class="nav-item"><a class="nav-link" href="IFSharpNotebook.html">IF# Notebook</a></li>
</ul>
</div>
</nav>
<div class="container">
<div class="masthead">
<h3 class="muted">
<a href="https://numerics.mathdotnet.com">Math.NET Numerics</a> |
<a href="https://www.mathdotnet.com">Math.NET Project</a> |
<a href="https://github.com/mathnet/mathnet-numerics">GitHub</a>
</h3>
</div>
<hr />
<div class="container" id="fsdocs-content">
<h1><a name="Pseudo-Random-Numbers" class="anchor" href="#Pseudo-Random-Numbers">Pseudo-Random Numbers</a></h1>
<p>The .Net Framework base class library (BCL) includes a pseudo-random number generator
for non-cryptography use in the form of the <code>System.Random</code> class.
Math.NET Numerics provides a few alternatives with different characteristics
in randomness, bias, sequence length, performance and thread-safety. All these classes
inherit from <code>System.Random</code> so you can use them as a drop-in replacement
even in third-party code.</p>
<p>All random number generators (RNG) generate numbers in a uniform
distribution. In practice you often need to sample random numbers with a different
distribution, like a Gaussian or Poisson. You can do that with one of our probability
distribution classes, or in F# also using the <code>Sample</code> module. Once parametrized,
the distribution classes also provide a variety of other functionality around probability
distributions, like evaluating statistical distribution properties or functions.</p>
<h2><a name="Initialization" class="anchor" href="#Initialization">Initialization</a></h2>
<p>We need to reference Math.NET Numerics and open the namespaces for
random numbers and probability distributions:</p>
<table class="pre"><tr><td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">using</span> MathNet.Numerics.Random;
<span class="k">using</span> MathNet.Numerics.Distributions;
</code></pre></td></tr></table>
<h2><a name="Generating-Random-Numbers" class="anchor" href="#Generating-Random-Numbers">Generating Random Numbers</a></h2>
<p>Let's sample a few random values from a uniform distributed variable
<span class="math">\(X\sim\mathcal{U}(0,1)\)</span>, such that <span class="math">\(0 \le x &lt; 1\)</span>:</p>
<table class="pre"><tr><td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="c">// create an array with 1000 random values</span>
<span class="k">double</span>[] samples <span class="o">=</span> SystemRandomSource.Doubles(<span class="n">1000</span>);
<span class="c">// now overwrite the existing array with new random values</span>
SystemRandomSource.Doubles(samples);
<span class="c">// we can also create an infinite sequence of random values:</span>
IEnumerable&lt;<span class="k">double</span>&gt; sampleSeq <span class="o">=</span> SystemRandomSource.DoubleSequence();
<span class="c">// take a single random value</span>
System.Random rng <span class="o">=</span> SystemRandomSource.Default;
<span class="k">double</span> sample <span class="o">=</span> rng.NextDouble();
<span class="k">decimal</span> sampled <span class="o">=</span> rng.NextDecimal();
</code></pre></td></tr></table>
<p>In F# we can do exactly the same, or alternatively use the <code>Random</code> module:</p>
<pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs1', 1)" onmouseover="showTip(event, 'fs1', 1)" class="id">samples</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">doubles</span> <span class="n">1000</span>
<span class="c">// overwrite the whole array with new random values</span>
<span class="id">Random</span><span class="pn">.</span><span class="id">doubleFill</span> <span onmouseout="hideTip(event, 'fs1', 2)" onmouseover="showTip(event, 'fs1', 2)" class="id">samples</span>
<span class="c">// create an infinite sequence:</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 3)" onmouseover="showTip(event, 'fs2', 3)" class="id">sampleSeq</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">doubleSeq</span> <span class="pn">(</span><span class="pn">)</span>
<span class="c">// take a single random value</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs3', 4)" onmouseover="showTip(event, 'fs3', 4)" class="id">rng</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">shared</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs4', 5)" onmouseover="showTip(event, 'fs4', 5)" class="id">sample</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 6)" onmouseover="showTip(event, 'fs3', 6)" class="id">rng</span><span class="pn">.</span><span class="id">NextDouble</span><span class="pn">(</span><span class="pn">)</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 7)" onmouseover="showTip(event, 'fs5', 7)" class="id">sampled</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 8)" onmouseover="showTip(event, 'fs3', 8)" class="id">rng</span><span class="pn">.</span><span class="id">NextDecimal</span><span class="pn">(</span><span class="pn">)</span>
</code></pre>
<p>If you have used the .Net BCL random number generators before, you have likely
noticed a few differences: we used special routines to create a full array or
sequence in one go, we were able to sample a decimal number, an we used static functions
and a shared default instance instead of creating our own instance.</p>
<p>Math.NET Numerics provides a few alternative random number generators in their own types.
For example, <code>MersenneTwister</code> implements the very popular mersenne twister algorithm. All these types
inherit from <code>System.Random</code>, are fully compatible to it and can also be used exactly the same way:</p>
<table class="pre"><tr><td class="snippet"><pre class="fssnip highlighted"><code lang="csharp">System.Random random <span class="o">=</span> <span class="k">new</span> SystemRandomSource();
<span class="k">var</span> sample <span class="o">=</span> random.NextDouble();
</code></pre></td></tr></table>
<p>However, unlike System.Random they can be made thread safe, use much more reasonable
default seeds and have some convenient extra routines. The <code>SystemRandomSource</code> class that
was used above uses System.Random to generate random numbers internally - but with all the extras.</p>
<h2><a name="Full-Range-Integers-and-Decimal" class="anchor" href="#Full-Range-Integers-and-Decimal">Full Range Integers and Decimal</a></h2>
<p>Out of the box, <code>System.Random</code> only provides <code>Next</code> methods to sample integers
in the [0, Int.MaxValue) range and <code>NextDouble</code> for floating point numbers in the [0,1) interval.
Did you ever have a need to generate numbers of the full integer range including negative numbers,
or a <code>System.Decimal</code>? Extending discrete random numbers to different ranges or types is non-trivial
if the distribution should still be uniform over the chosen range. That's why we've added a few extensions
methods which are available on all RNGs (including System.Random itself):</p>
<ul>
<li><strong>NextInt64</strong> generates a 64 bit integer, uniform in the range [0, Long.MaxValue)</li>
<li><strong>NextDecimal</strong> generates a <code>System.Decimal</code>, uniform in the range [0.0, 1.0)</li>
<li><strong>NextFullRangeInt32</strong> generates a 32 bit integer, uniform in the range [Int.MinValue, Int.MaxValue]</li>
<li><strong>NextFullRangeInt64</strong> generates a 64 bit integer, uniform in the range [Long.MinValue, Long.MaxValue]</li>
</ul>
<h2><a name="Seeds" class="anchor" href="#Seeds">Seeds</a></h2>
<p>All RNGs can be initialized with a custom seed number. The same seed causes
the same number sequence to be generated, which can be very useful if you need results
to be reproducible, e.g. in testing/verification. The exception is cryptography,
where reproducible random number sequences would be a fatal security flaw,
so our crypto random source does not accept a seed.</p>
<p>In the code samples above we did not provide a seed, so a default seed was used.
If no seed is provided, <code>System.Random</code> uses a time based seed equivalent to the
one below. This means that all instances created within a short time-frame
(which typically spans about a thousand CPU clock cycles) will generate
exactly the same sequence. This can happen easily e.g. in parallel computing
and is often unwanted. That's why all Math.NET Numerics RNGs are by default
initialized with a robust seed taken from the <code>CryptoRandomSource</code> if available,
or else a combination of a random number from a shared RNG, the time and a Guid
(which are supposed to be generated uniquely, worldwide).</p>
<pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs6', 9)" onmouseover="showTip(event, 'fs6', 9)" class="id">someTimeSeed</span> <span class="o">=</span> <span class="id">RandomSeed</span><span class="pn">.</span><span class="id">Time</span><span class="pn">(</span><span class="pn">)</span> <span class="c">// not recommended</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs7', 10)" onmouseover="showTip(event, 'fs7', 10)" class="id">someGuidSeed</span> <span class="o">=</span> <span class="id">RandomSeed</span><span class="pn">.</span><span class="id">Guid</span><span class="pn">(</span><span class="pn">)</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs8', 11)" onmouseover="showTip(event, 'fs8', 11)" class="id">someRobustSeed</span> <span class="o">=</span> <span class="id">RandomSeed</span><span class="pn">.</span><span class="id">Robust</span><span class="pn">(</span><span class="pn">)</span> <span class="c">// recommended, used by default</span>
</code></pre>
<p>Let's generate random numbers like before, but this time with custom seed 42:</p>
<pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs9', 12)" onmouseover="showTip(event, 'fs9', 12)" class="id">samplesSeeded</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">doublesSeed</span> <span class="n">42</span> <span class="n">1000</span>
<span class="id">Random</span><span class="pn">.</span><span class="id">doubleFillSeed</span> <span class="n">42</span> <span onmouseout="hideTip(event, 'fs9', 13)" onmouseover="showTip(event, 'fs9', 13)" class="id">samplesSeeded</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs10', 14)" onmouseover="showTip(event, 'fs10', 14)" class="id">samplesSeqSeeded</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">doubleSeqSeed</span> <span class="n">42</span>
</code></pre>
<p>Or without the F# Random module, e.g. in C#:</p>
<table class="pre"><tr><td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">double</span>[] samplesSeeded <span class="o">=</span> SystemRandomSource.Doubles(<span class="n">1000</span>, <span class="n">42</span>);
SystemRandomSource.Doubles(samplesSeeded, <span class="n">42</span>);
IEnumerable&lt;<span class="k">double</span>&gt; sampleSeqSeeded <span class="o">=</span> SystemRandomSource.DoubleSequence(<span class="n">42</span>);
</code></pre></td></tr></table>
<h2><a name="Uniform-Random-Number-Generators" class="anchor" href="#Uniform-Random-Number-Generators">Uniform Random Number Generators</a></h2>
<p>Up to now we've used only <code>SystemRandomSource</code>, but there's much more:</p>
<ul>
<li><strong>SystemRandomSource</strong>: Wraps the .NET System.Random to provide thread-safety</li>
<li><strong>CryptoRandomSource</strong>: Wraps the .NET RNGCryptoServiceProvider. <em>Not available in portable builds.</em></li>
<li><strong>MersenneTwister</strong>: Mersenne Twister 19937 generator</li>
<li><strong>Xorshift</strong>: Multiply-with-carry XOR-shift generator</li>
<li><strong>Mcg31m1</strong>: Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760</li>
<li><strong>Mcg59</strong>: Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13</li>
<li><strong>WH1982</strong>: Wichmann-Hill's 1982 combined multiplicative congruential generator</li>
<li><strong>WH2006</strong>: Wichmann-Hill's 2006 combined multiplicative congruential generator</li>
<li><strong>Mrg32k3a</strong>: 32-bit combined multiple recursive generator with 2 components of order 3</li>
<li><strong>Palf</strong>: Parallel Additive Lagged Fibonacci generator</li>
</ul>
<p>Let's sample a few uniform random values using Mersenne Twister in C#:</p>
<table class="pre"><tr><td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="c">// Typical way with an instance:</span>
<span class="k">var</span> random <span class="o">=</span> <span class="k">new</span> MersenneTwister(<span class="n">42</span>); <span class="c">// seed 42</span>
<span class="k">int</span> sampleInt <span class="o">=</span> random.Next();
<span class="k">double</span> sampleDouble <span class="o">=</span> random.NextDouble();
<span class="k">decimal</span> sampleDecimal <span class="o">=</span> random.NextDecimal();
<span class="k">double</span>[] samples <span class="o">=</span> random.NextDoubles(<span class="n">1000</span>);
IEnumerable&lt;<span class="k">double</span>&gt; sampleSeq <span class="o">=</span> random.NextDoubleSequence();
<span class="c">// Simpler and faster if you need a large sequence, only once:</span>
<span class="k">double</span>[] samples <span class="o">=</span> MersenneTwister.Doubles(<span class="n">1000</span>, <span class="n">42</span>) <span class="c">// 1000 numbers, seed 42</span>
IEnumerable&lt;<span class="k">double</span>&gt; sampleSeq <span class="o">=</span> MersenneTwister.DoubleSequence(<span class="n">42</span>); <span class="c">// seed 42</span>
</code></pre></td></tr></table>
<p>In F# you can use the constructor as well, or alternatively use the <code>Random</code> module.
In case of the latter, all objects will be cast to their common base type <code>System.Random</code>:</p>
<pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// By using the normal constructor (random1 has type MersenneTwister) </span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 15)" onmouseover="showTip(event, 'fs11', 15)" class="id">random1</span> <span class="o">=</span> <span class="id">MersenneTwister</span><span class="pn">(</span><span class="pn">)</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 16)" onmouseover="showTip(event, 'fs12', 16)" class="id">random1b</span> <span class="o">=</span> <span class="id">MersenneTwister</span><span class="pn">(</span><span class="n">42</span><span class="pn">)</span> <span class="c">// with seed</span>
<span class="c">// By using the Random module (random2 has type System.Random)</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs13', 17)" onmouseover="showTip(event, 'fs13', 17)" class="id">random2</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">mersenneTwister</span> <span class="pn">(</span><span class="pn">)</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs14', 18)" onmouseover="showTip(event, 'fs14', 18)" class="id">random2b</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">mersenneTwisterSeed</span> <span class="n">42</span> <span class="c">// with seed</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs15', 19)" onmouseover="showTip(event, 'fs15', 19)" class="id">random2c</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">mersenneTwisterWith</span> <span class="n">42</span> <span class="k">false</span> <span class="c">// opt-out of thread-safety</span>
<span class="c">// Using some other algorithms:</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs16', 20)" onmouseover="showTip(event, 'fs16', 20)" class="id">random3</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">crypto</span> <span class="pn">(</span><span class="pn">)</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs17', 21)" onmouseover="showTip(event, 'fs17', 21)" class="id">random4</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">xorshift</span> <span class="pn">(</span><span class="pn">)</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs18', 22)" onmouseover="showTip(event, 'fs18', 22)" class="id">random5</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">wh2006</span> <span class="pn">(</span><span class="pn">)</span>
</code></pre>
<h2><a name="Shared-Instances-and-Thread-Safety" class="anchor" href="#Shared-Instances-and-Thread-Safety">Shared Instances and Thread Safety</a></h2>
<p>Generators make certain claims about how many random numbers they can generate
until the whole sequence repeats itself. However, this only applies if you
continue to sample from the same instance and its internal state.
The generator instances should therefore be reused within an application if long
random sequences are needed. If you'd create a new instance each time, the numbers
it generates would be exactly as random as your seed - and thus not very random at all.</p>
<p>Another reason to share instances: most generators run an initialization routine before
they can start generating numbers which can be expensive. Some of them also maintain
their internal state in large memory blocks, which can quickly add up when creating multiple
instances.</p>
<p>Unfortunately the two generators provided by .NET are not thread-safe and thus cannot be
shared between threads without manual locking. But all the RNGs provided by Math.NET Numerics,
including the <code>SystemRandomSource</code> and <code>CryptoRandomSource</code> wrappers, <em>are</em> thread-safe by default,
unless explicitly disabled by a constructor argument or by setting <code>Control.ThreadSafeRandomNumberGenerators</code>
(which is used if the constructor argument is omitted).</p>
<p>For convenience a few generators provide a thread-safe shared instance</p>
<table class="pre"><tr><td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> a <span class="o">=</span> SystemRandomSource.Default;
<span class="k">var</span> b <span class="o">=</span> MersenneTwister.Default;
</code></pre></td></tr></table>
<p>Or with the F# module:</p>
<pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs19', 23)" onmouseover="showTip(event, 'fs19', 23)" class="id">a</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">systemShared</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs20', 24)" onmouseover="showTip(event, 'fs20', 24)" class="id">b</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">mersenneTwisterShared</span>
<span class="c">// or if you don&#39;t care, simply</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs21', 25)" onmouseover="showTip(event, 'fs21', 25)" class="id">c</span> <span class="o">=</span> <span class="id">Random</span><span class="pn">.</span><span class="id">shared</span><span class="pn">;</span>
</code></pre>
<h2><a name="Non-Uniform-Random-Numbers" class="anchor" href="#Non-Uniform-Random-Numbers">Non-Uniform Random Numbers</a></h2>
<p>For non-uniform random number generation you can use the wide range of probability
distributions in the <code>MathNet.Numerics.Distributions</code> namespace.</p>
<table class="pre"><tr><td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">using</span> MathNet.Numerics.Distributions;
<span class="c">// sample a single value from a standard distribution</span>
<span class="k">double</span> a <span class="o">=</span> Normal.Sample(<span class="n">0.0</span>, <span class="n">1.0</span>);
<span class="c">// sample using a custom random number generator</span>
<span class="k">double</span> b <span class="o">=</span> Normal.Sample(<span class="k">new</span> MersenneTwister(), <span class="n">0.0</span>, <span class="n">1.0</span>);
<span class="c">// sample a large number of values in one go</span>
<span class="k">double</span>[] c <span class="o">=</span> <span class="k">new</span> <span class="k">double</span>[<span class="n">100000</span>];
Normal.Samples(c, <span class="n">0.0</span>, <span class="n">1.0</span>);
</code></pre></td></tr></table>
<p>See <a href="Probability.html">Probability Distributions</a> for details.</p>
<div class="fsdocs-tip" id="fs1">val samples : obj</div>
<div class="fsdocs-tip" id="fs2">val sampleSeq : obj</div>
<div class="fsdocs-tip" id="fs3">val rng : obj</div>
<div class="fsdocs-tip" id="fs4">val sample : obj</div>
<div class="fsdocs-tip" id="fs5">val sampled : obj</div>
<div class="fsdocs-tip" id="fs6">val someTimeSeed : obj</div>
<div class="fsdocs-tip" id="fs7">val someGuidSeed : obj</div>
<div class="fsdocs-tip" id="fs8">val someRobustSeed : obj</div>
<div class="fsdocs-tip" id="fs9">val samplesSeeded : obj</div>
<div class="fsdocs-tip" id="fs10">val samplesSeqSeeded : obj</div>
<div class="fsdocs-tip" id="fs11">val random1 : obj</div>
<div class="fsdocs-tip" id="fs12">val random1b : obj</div>
<div class="fsdocs-tip" id="fs13">val random2 : obj</div>
<div class="fsdocs-tip" id="fs14">val random2b : obj</div>
<div class="fsdocs-tip" id="fs15">val random2c : obj</div>
<div class="fsdocs-tip" id="fs16">val random3 : obj</div>
<div class="fsdocs-tip" id="fs17">val random4 : obj</div>
<div class="fsdocs-tip" id="fs18">val random5 : obj</div>
<div class="fsdocs-tip" id="fs19">val a : obj</div>
<div class="fsdocs-tip" id="fs20">val b : obj</div>
<div class="fsdocs-tip" id="fs21">val c : obj</div>
</div>
<!-- BEGIN SEARCH BOX: this adds support for the search box -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/JavaScript-autoComplete/1.0.4/auto-complete.css" />
<script type="text/javascript">var fsdocs_search_baseurl = 'https://numerics.mathdotnet.com/';</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.8/lunr.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/JavaScript-autoComplete/1.0.4/auto-complete.min.js"></script>
<script type="text/javascript" src="https://numerics.mathdotnet.com/content/fsdocs-search.js"></script>
<!-- END SEARCH BOX: this adds support for the search box -->
</div>
</body>
</html>