diff --git a/MathNet.Numerics.sln b/MathNet.Numerics.sln
index 1f53dab4..184df47b 100644
--- a/MathNet.Numerics.sln
+++ b/MathNet.Numerics.sln
@@ -43,6 +43,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{039229DA-A
docs\content\DescriptiveStatistics.fsx = docs\content\DescriptiveStatistics.fsx
docs\content\Distance.fsx = docs\content\Distance.fsx
docs\content\Functions.fsx = docs\content\Functions.fsx
+ docs\content\Generate.fsx = docs\content\Generate.fsx
docs\content\index.fsx = docs\content\index.fsx
docs\content\IntegralTransforms.fsx = docs\content\IntegralTransforms.fsx
docs\content\Integration.fsx = docs\content\Integration.fsx
diff --git a/docs/content/Generate.fsx b/docs/content/Generate.fsx
new file mode 100644
index 00000000..f997176a
--- /dev/null
+++ b/docs/content/Generate.fsx
@@ -0,0 +1,252 @@
+(*** hide ***)
+#I "../../out/lib/net40"
+#r "MathNet.Numerics.dll"
+#r "MathNet.Numerics.FSharp.dll"
+open System
+open MathNet.Numerics
+let a = [| 2.0; 4.0; 3.0; 6.0 |]
+
+(**
+Generating Data
+===============
+
+Numerics is all about analyzing and manipulating numeric data. But unless you can read in data from an external
+file, source or e.g. with the excellent [F# Type Providers](http://fsharp.github.io/FSharp.Data/),
+you may need to generate synthetic or random data locally, or transform existing data into a new form.
+The `Generate` class can help you in all these scenarios with a set of static functions generating either
+an array or an IEnumerable sequence.
+
+There is some overlap with LINQ, in case of F# also with some integrated language features and its fundamental types.
+This is intended for simplicity and consistency between array and sequence operations, as LINQ only supports sequences.
+
+
+Linear Range
+------------
+
+Generates a linearly spaced array within the inclusive interval between start and stop,
+and either a provided step or a step of 1.0. Linear range is equivalent to the
+single colon `:` and double colon `::` operators in MATLAB.
+
+F# has built in linear range support in array comprehensions with the colon operator:
+*)
+
+[ 10.0 .. 2.0 .. 15.0 ]
+// [fsi:val it : float list = [10.0; 12.0; 14.0] ]
+[ for x in 10.0 .. 2.0 .. 15.0 -> sin x ]
+// [fsi:val it : float list = [-0.5440211109; -0.536572918; 0.9906073557] ]
+
+(**
+In C# you can get the same result with `LinearRange`:
+
+ [lang=csharp]
+ Generate.LinearRange(10, 2, 15); // returns array { 10.0, 12.0, 14.0 }
+ Generate.LinearRangeMap(10, 2, 15, Math.Sin); // applies sin(x) to each value
+
+Most of the routines in the `Generate` class have variants with a `Map` suffix.
+Instead of returning an array with the generated numbers, these routines instead
+apply the generated numbers to a custom function and return an array with the results.
+Similarly, some routines have variants with a `Sequence` suffix that return
+lazy enumerable sequences instead of arrays.
+
+
+Linear-Spaced and Log-Spaced
+----------------------------
+
+Generates a linearly or log-spaced array within an interval, but other than linear range
+where the step is provided, here we instead provide the number of values we want.
+This is equivalent to the linspace and logspace operators in MATLAB.
+
+ [lang=csharp]
+ Generate.LinearSpaced(11, 0.0, 1.0); // returns array { 0.0, 0.1, 0.2, .., 1.0 }
+ Generate.LinearSpacedMap(15, 0.0, Math.Pi, Math.Sin); // applies sin(x) to each value
+
+In F# you can also use:
+*)
+
+Generate.linearSpacedMap 15 0.0 Math.PI sin
+// [fsi:val it : float [] = ]
+// [fsi: [|0.0; 0.222520934; 0.4338837391; 0.6234898019; 0.7818314825; 0.9009688679; ]
+// [fsi: 0.9749279122; 1.0; 0.9749279122; 0.9009688679; 0.7818314825; 0.6234898019; ]
+// [fsi: 0.4338837391; 0.222520934; 1.224606354e-16|] ]
+
+(**
+`LogSpaced` works the same way but instead of the values $10^x$ it spaces the decade exponents $x$ linearly
+between the provided two exponents.
+
+ [lang=csharp]
+ Generate.LogSpaced(4,0,3); // returns array { 1, 10, 100, 1000 }
+
+
+Kronecker Delta Impulse
+-----------------------
+
+The Kronecker delta $\delta[n]$ is a fundamental signal in time-discrete signal processing,
+often referred to as *unit impulse*. When applied to a system, the resulting output is the system's *impulse response*.
+It is closely related to the Dirac delta impulse function $\delta(x)$ in continuous signal processing.
+
+$$$
+\delta[n] = \begin{cases} 0 &\mbox{if } n \ne 0 \\ 1 & \mbox{if } n = 0\end{cases}
+
+The `Impulse` routine generates a Kronecker delta impulse, but also accepts a sample delay
+parameter $d$ and amplitude $A$ such that the resulting generated signal is
+
+$$$
+s[n] = A\cdot\delta[n-d] = \begin{cases} 0 &\mbox{if } n \ne d \\ A & \mbox{if } n = d\end{cases}
+
+There is also a periodic version in `PeriodicImpulse` which accepts an additional `period` parameter.
+*)
+
+Generate.Impulse(8, 2.0, 3)
+// [fsi:val it : float [] = [|0.0; 0.0; 0.0; 2.0; 0.0; 0.0; 0.0; 0.0|] ]
+
+Generate.PeriodicImpulse(8, 3, 10.0, 1)
+// [fsi:val it : float [] = [|0.0; 10.0; 0.0; 0.0; 10.0; 0.0; 0.0; 10.0|] ]
+
+(**
+Heaviside Step
+--------------
+
+Another fundamental signal in signal processing, the Heaviside step function $H[n]$
+is the integral of the Dirac delta impulse and represents a signal that switches on
+at a specified time and then stays on indefinitely. In discrete time:
+
+$$$
+H[n] = \begin{cases} 0 &\mbox{if } n < 0 \\ 1 & \mbox{if } n \ge 0\end{cases}
+
+The `Step` routines generates a Heaviside step, but just like the Kronecker Delta impulse
+ also accepts a sample delay parameter $d$ and amplitude $A$ such that the resulting generated signal is
+
+$$$
+s[n] = A\cdot H[n-d] = \begin{cases} 0 &\mbox{if } n < d \\ A & \mbox{if } n \ge d\end{cases}
+*)
+
+Generate.Step(8, 2.0, 3)
+// [fsi:val it : float [] = [|0.0; 0.0; 0.0; 2.0; 2.0; 2.0; 2.0; 2.0|] ]
+
+
+(**
+Periodic Sawtooth
+-----------------
+
+Generates an array of the given length with a periodic upper forward sawtooth signal,
+i.e. a line starting at zero up to some amplitude $A$, then drop back to zero instantly and start afresh.
+The sawtooth can be used to turn any arbitrary function defined over the interval $[0,A)$ into a
+periodic function by repeating it continuously.
+
+Mathematically, the sawtooth can be described using the fractional part function
+$\mathrm{frac}(x) \equiv x - \lfloor x \rfloor$, frequency $\nu$ and phase $\theta$ as
+
+$$$
+s(x) = A\cdot\mathrm{frac}\left(x\nu+\frac{\theta}{A}\right)
+
+In a trigonometric interpretation the signal represents the angular position $\alpha$ of a point moving endlessly
+around a circle with radius $\frac{A}{2\pi}$ (and thus circumference $A$) in constant speed,
+normalized to strictly $0\le\alpha < A$.
+
+`Generate.Periodic(length,samplingRate,frequency,amplitude,phase,delay)`
+
+* **Sampling Rate**: Number of samples $r$ per time unit. If the time unit is 1s, the sampling rate has unit Hz.
+* **Frequency**: Frequency $\nu$ of the signal, in sawtooth-periods per time unit. If the time unit is 1s, the frequency has unit Hz.
+ For a desired number of samples $n$ per sawtooth-period and sampling rate $r$ choose $\nu=\frac{r}{n}$.
+* **Amplitude**: The theoretical maximum value $A$, which is never reached and logically equivalent to zero.
+ The circumference of the circle. Typically $1$ or $2\pi$.
+* **Phase**: Optional initial value or phase offset. Contributes to $\theta$.
+* **Delay**: Optional initial delay, in samples. Contributes to $\theta$.
+
+The equivalent map function accepts a custom map lambda as second argument after the length:
+*)
+
+Generate.periodicMap 15 ((+) 100.0) 1000.0 100.0 10.0 0.0 0
+// [fsi:val it : float [] = ]
+// [fsi: [|100.0; 101.0; 102.0; 103.0; 104.0; 105.0; 106.0; 107.0; 108.0; 109.0; ]
+// [fsi: 100.0; 101.0; 102.0; 103.0; 104.0|] ]
+
+(**
+Sinusoidal
+----------
+
+Generates a Sine wave array of the given length. This is equivalent of applying a scaled trigonometric Sine function
+to a periodic sawtooth of amplitude $2\pi$.
+
+$$$
+s(x) = A\cdot\sin(2\pi\nu x + \theta)
+
+`Generate.Sinusoidal(length,samplingRate,frequency,amplitude,mean,phase,delay)`
+
+ [lang=csharp]
+ Generate.Sinusoidal(15, 1000.0, 100.0, 10.0);
+ // returns array { 0, 5.9, 9.5, 9.5, 5.9, 0, -5.9, ... }
+
+
+Random
+------
+
+Generate random sequences by sampling from a random distribution.
+
+
+#### Uniform Distribution
+
+Generate sample sequences distributed uniformly between 0 and 1.
+
+ [lang=csharp]
+ Generate.Uniform(100); // e.g. 0.867421787170424, 0.236744313145403, ...
+
+Uniform supports mapping to functions with not only one but also two uniform variables
+as arguments, with `UniformMap` and `UniformMap2`. As usual, lazy sequences can be
+generated using the variants with the `Sequence` suffix, e.g. `UniformMap2Sequence`.
+
+
+#### Non-Uniform Distributions
+
+Instead of uniform we can also sample from other distributions.
+
+* `Gaussian` - sample an array or sequence form a normal or standard distribution
+* `Stable` - sample from a Levy alpha-stable distribution.
+
+In addition, the `Random` functions accept a custom distribution instance to sample
+from. See the section about random numbers and probability distributions for details.
+
+
+Map
+---
+
+Generates a new array or sequence where each new values is the result of applying the provided function
+the the corresponding value in the input data.
+
+ [lang=csharp]
+ var a = new double[] { 2.0, 4.0, 3.0, 6.0 };
+ Generate.Map(a, x => x + 1.0); // returns array { 3.0, 5.0, 4.0, 7.0 }
+
+In F# you'd typically use the Array module to the same effect (and should continue to do so):
+*)
+
+Array.map ((+) 1.0) a
+// [fsi:val it : float [] = [|3.0; 5.0; 4.0; 7.0|] ]
+
+(**
+...but no equivalent operation is available in the .NET base class libraries (BCL) for C#.
+You can use LINQ, but that operates on sequences instead of arrays:
+
+ [lang=csharp]
+ a.Select(x => x + 1.0).ToArray();
+
+Similarly, with `Map2` you can also map a function accepting two inputs to two input arrays:
+*)
+
+let b = [| 1.0; -1.0; 2.0; -2.0 |]
+Generate.Map2(a, b, fun x y -> x + y)
+// [fsi:val it : float [] = [|3.0; 3.0; 5.0; 4.0|] ]
+
+(**
+Typical F# equivalent:
+*)
+
+Array.map2 (+) a b
+// [fsi:val it : float [] = [|3.0; 3.0; 5.0; 4.0|] ]
+
+(**
+And in C# with LINQ:
+
+ [lang=csharp]
+ a.Zip(b, (x, y) => x + y).ToArray();
+*)
diff --git a/docs/content/index.fsx b/docs/content/index.fsx
index ad7fd025..aa32ceca 100644
--- a/docs/content/index.fsx
+++ b/docs/content/index.fsx
@@ -12,14 +12,14 @@ Installation Instructions
The recommended way to get Math.NET Numerics is to use NuGet. The following packages are provided and maintained in the public [NuGet Gallery](https://nuget.org/profiles/mathnet/):
-- `MathNet.Numerics` - core package, including .Net 4, .Net 3.5 and portable/PCL builds
-- `MathNet.Numerics.FSharp` - optional extensions for a better F# experience
-- `MathNet.Numerics.Data.Text` - optional extensions for text-based matrix input/output
-- `MathNet.Numerics.Data.Matlab` - optional extensions for MATLAB matrix file input/output
-- `MathNet.Numerics.MKL.Win-x86` - optional Linear Algebra MKL native provider
-- `MathNet.Numerics.MKL.Win-x64` - optional Linear Algebra MKL native provider
-- `MathNet.Numerics.Signed` - strong-named version of the core package *(not recommended)*
-- `MathNet.Numerics.FSharp.Signed` - strong-named version of the F# package *(not recommended)*
+- `MathNet.Numerics` - core package, including .Net 4, .Net 3.5 and portable/PCL builds.
+- `MathNet.Numerics.FSharp` - optional extensions for a better F# experience. BigRational.
+- `MathNet.Numerics.Data.Text` - optional extensions for text-based matrix input/output.
+- `MathNet.Numerics.Data.Matlab` - optional extensions for MATLAB matrix file input/output.
+- `MathNet.Numerics.MKL.Win-x86` - optional Linear Algebra MKL native provider.
+- `MathNet.Numerics.MKL.Win-x64` - optional Linear Algebra MKL native provider.
+- `MathNet.Numerics.Signed` - strong-named version of the core package *(not recommended)*.
+- `MathNet.Numerics.FSharp.Signed` - strong-named version of the F# package *(not recommended)*.
Alternatively you can also download the binaries in Zip packages, available on [CodePlex](http://mathnetnumerics.codeplex.com/releases):
@@ -30,7 +30,7 @@ Supported Platforms:
- .Net 4.0, .Net 3.5 and Mono: Windows, Linux and Mac.
- PCL Portable Profiles 47 and 136: Silverlight 5, Windows Phone 8, .NET for Windows Store apps (Metro).
-- PCL/Xamarin: Android, iOS
+- PCL/Xamarin: Android, iOS *(not verified due to lack of license and devices)*
Building Math.NET Numerics
--------------------------
diff --git a/docs/tools/templates/template.cshtml b/docs/tools/templates/template.cshtml
index a50a3db3..8de5c355 100644
--- a/docs/tools/templates/template.cshtml
+++ b/docs/tools/templates/template.cshtml
@@ -58,7 +58,7 @@
Complex Numbers
Euclid & Number Theory
Combinatorics
- Generating Data
+ Generating Data
Random Numbers
Probability Distributions
Distance Metrics
diff --git a/src/FSharp/Generate.fs b/src/FSharp/Generate.fs
index f10ea30c..11272074 100644
--- a/src/FSharp/Generate.fs
+++ b/src/FSharp/Generate.fs
@@ -58,7 +58,7 @@ module Generate =
let inline randomMap2 length distribution map = Generate.RandomMap2(length, distribution, tobcl2 map)
let inline randomMap2Seq distribution map = Generate.RandomMap2Sequence(distribution, tobcl2 map)
- let inline randomUniformMap length map = Generate.RandomUniformMap(length, tobcl map)
- let inline randomUniformMapSeq map = Generate.RandomUniformMapSequence(tobcl map)
- let inline randomUniformMap2 length map = Generate.RandomUniformMap2(length, tobcl2 map)
- let inline randomUniformMap2Seq map = Generate.RandomUniformMap2Sequence(tobcl2 map)
+ let inline uniformMap length map = Generate.UniformMap(length, tobcl map)
+ let inline uniformMapSeq map = Generate.UniformMapSequence(tobcl map)
+ let inline uniformMap2 length map = Generate.UniformMap2(length, tobcl2 map)
+ let inline uniformMap2Seq map = Generate.UniformMap2Sequence(tobcl2 map)
diff --git a/src/Numerics/Generate.cs b/src/Numerics/Generate.cs
index 903f73b5..5ff9cfa5 100644
--- a/src/Numerics/Generate.cs
+++ b/src/Numerics/Generate.cs
@@ -196,7 +196,7 @@ namespace MathNet.Numerics
}
///
- /// Generate a linearly spaced sample vector within the inclusive interval (start, stop) and the provide step.
+ /// Generate a linearly spaced sample vector within the inclusive interval (start, stop) and the provided step.
/// The start value is aways included as first value, but stop is only included if it stop-start is a multiple of step.
/// Equivalent to MATLAB double colon operator (::).
///
@@ -457,44 +457,29 @@ namespace MathNet.Numerics
}
///
- /// Create a Dirac Delta Impulse sample vector.
+ /// Create a Kronecker Delta impulse sample vector.
///
/// The number of samples to generate.
- /// impulse sequence period. -1 for single impulse only.
/// The maximal reached peak.
/// Offset to the time axis. Zero or positive.
- public static double[] Impulse(int length, int period, double amplitude, int delay)
+ public static double[] Impulse(int length, double amplitude, int delay)
{
var data = new double[length];
- if (period <= 0)
- {
- if (delay >= 0 && delay < length)
- {
- data[delay] = amplitude;
- }
- }
- else
+ if (delay >= 0 && delay < length)
{
- delay = ((delay%period) + period)%period;
- while (delay < length)
- {
- data[delay] = amplitude;
- delay += period;
- }
+ data[delay] = amplitude;
}
return data;
}
-
///
- /// Create a Dirac Delta Impulse sample vector.
+ /// Create a Kronecker Delta impulse sample vector.
///
- /// impulse sequence period. -1 for single impulse only.
/// The maximal reached peak.
- /// Offset to the time axis. Zero or positive.
- public static IEnumerable ImpulseSequence(int period, double amplitude, int delay)
+ /// Offset to the time axis, hence the sample index of the impulse.
+ public static IEnumerable ImpulseSequence(double amplitude, int delay)
{
- if (period <= 0)
+ if (delay >= 0)
{
for (int i = 0; i < delay; i++)
{
@@ -502,87 +487,141 @@ namespace MathNet.Numerics
}
yield return amplitude;
+ }
- while (true)
- {
- yield return 0d;
- }
+ while (true)
+ {
+ yield return 0d;
}
- else
+ }
+
+ ///
+ /// Create a periodic Kronecker Delta impulse sample vector.
+ ///
+ /// The number of samples to generate.
+ /// impulse sequence period.
+ /// The maximal reached peak.
+ /// Offset to the time axis. Zero or positive.
+ public static double[] PeriodicImpulse(int length, int period, double amplitude, int delay)
+ {
+ var data = new double[length];
+ delay = Euclid.Modulus(delay, period);
+ while (delay < length)
{
- delay = ((delay%period) + period)%period;
+ data[delay] = amplitude;
+ delay += period;
+ }
+ return data;
+ }
- for (int i = 0; i < delay; i++)
- {
- yield return 0d;
- }
+ ///
+ /// Create a Kronecker Delta impulse sample vector.
+ ///
+ /// impulse sequence period.
+ /// The maximal reached peak.
+ /// Offset to the time axis. Zero or positive.
+ public static IEnumerable PeriodicImpulseSequence(int period, double amplitude, int delay)
+ {
+ delay = Euclid.Modulus(delay, period);
- while (true)
- {
- yield return amplitude;
+ for (int i = 0; i < delay; i++)
+ {
+ yield return 0d;
+ }
- for (int i = 1; i < period; i++)
- {
- yield return 0d;
- }
+ while (true)
+ {
+ yield return amplitude;
+
+ for (int i = 1; i < period; i++)
+ {
+ yield return 0d;
}
}
}
///
- /// Create random samples.
+ /// Create random samples, uniform between 0 and 1.
+ /// Faster than other methods but with reduced guarantees on randomness.
///
- public static double[] Random(int length, IContinuousDistribution distribution)
+ public static double[] Uniform(int length)
{
- return distribution.Samples().Take(length).ToArray();
+ return SystemRandomSource.Doubles(length);
}
///
- /// Create an infinite random sample sequence.
+ /// Create an infinite random sample sequence, uniform between 0 and 1.
+ /// Faster than other methods but with reduced guarantees on randomness.
///
- public static IEnumerable Random(IContinuousDistribution distribution)
+ public static IEnumerable UniformSequence()
{
- return distribution.Samples();
+ return SystemRandomSource.DoubleSequence();
}
+
///
- /// Create random samples, uniform between 0 and 1.
+ /// Generate samples by sampling a function at samples from a probability distribution, uniform between 0 and 1.
/// Faster than other methods but with reduced guarantees on randomness.
///
- public static double[] RandomUniform(int length)
+ public static T[] UniformMap(int length, Func map)
{
- return SystemRandomSource.Doubles(length);
+ var samples = SystemRandomSource.Doubles(length);
+ var data = new T[length];
+ for (int i = 0; i < data.Length; i++)
+ {
+ data[i] = map(samples[i]);
+ }
+ return data;
}
///
- /// Create an infinite random sample sequence, uniform between 0 and 1.
+ /// Generate a sample sequence by sampling a function at samples from a probability distribution, uniform between 0 and 1.
/// Faster than other methods but with reduced guarantees on randomness.
///
- public static IEnumerable RandomUniform()
+ public static IEnumerable UniformMapSequence(Func map)
{
- return SystemRandomSource.DoubleSequence();
+ return SystemRandomSource.DoubleSequence().Select(map);
}
///
- /// Create random samples.
+ /// Generate samples by sampling a function at sample pairs from a probability distribution, uniform between 0 and 1.
+ /// Faster than other methods but with reduced guarantees on randomness.
///
- public static Complex[] RandomComplex(int length, IContinuousDistribution distribution)
+ public static T[] UniformMap2(int length, Func map)
{
- return RandomMap2(length, distribution, (r, i) => new Complex(r, i));
+ var samples1 = SystemRandomSource.Doubles(length);
+ var samples2 = SystemRandomSource.Doubles(length);
+ var data = new T[length];
+ for (int i = 0; i < data.Length; i++)
+ {
+ data[i] = map(samples1[i], samples2[i]);
+ }
+ return data;
}
///
- /// Create an infinite random sample sequence.
+ /// Generate a sample sequence by sampling a function at sample pairs from a probability distribution, uniform between 0 and 1.
+ /// Faster than other methods but with reduced guarantees on randomness.
///
- public static IEnumerable RandomComplex(IContinuousDistribution distribution)
+ public static IEnumerable UniformMap2Sequence(Func map)
{
- return RandomMap2Sequence(distribution, (r, i) => new Complex(r, i));
+ var rnd1 = SystemRandomSource.Default;
+ for (int i = 0; i < 128; i++)
+ {
+ yield return map(rnd1.NextDouble(), rnd1.NextDouble());
+ }
+
+ var rnd2 = new System.Random(RandomSeed.Robust());
+ while (true)
+ {
+ yield return map(rnd2.NextDouble(), rnd2.NextDouble());
+ }
}
///
/// Create samples with independent amplitudes of normal distribution and a flat spectral density.
///
- public static double[] WhiteGaussianNoise(int length, double mean, double standardDeviation)
+ public static double[] Gaussian(int length, double mean, double standardDeviation)
{
return Normal.Samples(SystemRandomSource.Default, mean, standardDeviation).Take(length).ToArray();
}
@@ -590,7 +629,7 @@ namespace MathNet.Numerics
///
/// Create an infinite sample sequence with independent amplitudes of normal distribution and a flat spectral density.
///
- public static IEnumerable WhiteGaussianNoiseSequence(double mean, double standardDeviation)
+ public static IEnumerable GaussianSequence(double mean, double standardDeviation)
{
return Normal.Samples(SystemRandomSource.Default, mean, standardDeviation);
}
@@ -603,9 +642,9 @@ namespace MathNet.Numerics
/// Skewness beta-parameter of the stable distribution
/// Scale c-parameter of the stable distribution
/// Location mu-parameter of the stable distribution
- public static double[] StableNoise(int length, double alpha, double beta, double scale, double location)
+ public static double[] Stable(int length, double alpha, double beta, double scale, double location)
{
- return Stable.Samples(SystemRandomSource.Default, alpha, beta, scale, location).Take(length).ToArray();
+ return Distributions.Stable.Samples(SystemRandomSource.Default, alpha, beta, scale, location).Take(length).ToArray();
}
///
@@ -615,110 +654,83 @@ namespace MathNet.Numerics
/// Skewness beta-parameter of the stable distribution
/// Scale c-parameter of the stable distribution
/// Location mu-parameter of the stable distribution
- public static IEnumerable StableNoiseSequence(double alpha, double beta, double scale, double location)
+ public static IEnumerable StableSequence(double alpha, double beta, double scale, double location)
{
- return Stable.Samples(SystemRandomSource.Default, alpha, beta, scale, location);
+ return Distributions.Stable.Samples(SystemRandomSource.Default, alpha, beta, scale, location);
}
///
- /// Generate samples by sampling a function at samples from a probability distribution.
+ /// Create random samples.
///
- public static T[] RandomMap(int length, IContinuousDistribution distribution, Func map)
+ public static double[] Random(int length, IContinuousDistribution distribution)
{
- var data = new T[length];
- for (int i = 0; i < data.Length; i++)
- {
- data[i] = map(distribution.Sample());
- }
- return data;
+ return distribution.Samples().Take(length).ToArray();
}
///
- /// Generate a sample sequence by sampling a function at samples from a probability distribution.
+ /// Create an infinite random sample sequence.
///
- public static IEnumerable RandomMapSequence(IContinuousDistribution distribution, Func map)
+ public static IEnumerable Random(IContinuousDistribution distribution)
{
- return distribution.Samples().Select(map);
+ return distribution.Samples();
}
///
- /// Generate samples by sampling a function at sample pairs from a probability distribution.
+ /// Create random samples.
///
- public static T[] RandomMap2(int length, IContinuousDistribution distribution, Func map)
+ public static Complex[] RandomComplex(int length, IContinuousDistribution distribution)
{
- var data = new T[length];
- for (int i = 0; i < data.Length; i++)
- {
- data[i] = map(distribution.Sample(), distribution.Sample());
- }
- return data;
+ return RandomMap2(length, distribution, (r, i) => new Complex(r, i));
}
///
- /// Generate a sample sequence by sampling a function at sample pairs from a probability distribution.
+ /// Create an infinite random sample sequence.
///
- public static IEnumerable RandomMap2Sequence(IContinuousDistribution distribution, Func map)
+ public static IEnumerable RandomComplex(IContinuousDistribution distribution)
{
- return distribution.Samples().Zip(distribution.Samples(), map);
+ return RandomMap2Sequence(distribution, (r, i) => new Complex(r, i));
}
///
- /// Generate samples by sampling a function at samples from a probability distribution, uniform between 0 and 1.
- /// Faster than other methods but with reduced guarantees on randomness.
+ /// Generate samples by sampling a function at samples from a probability distribution.
///
- public static T[] RandomUniformMap(int length, Func map)
+ public static T[] RandomMap(int length, IContinuousDistribution distribution, Func map)
{
- var samples = SystemRandomSource.Doubles(length);
var data = new T[length];
for (int i = 0; i < data.Length; i++)
{
- data[i] = map(samples[i]);
+ data[i] = map(distribution.Sample());
}
return data;
}
///
- /// Generate a sample sequence by sampling a function at samples from a probability distribution, uniform between 0 and 1.
- /// Faster than other methods but with reduced guarantees on randomness.
+ /// Generate a sample sequence by sampling a function at samples from a probability distribution.
///
- public static IEnumerable RandomUniformMapSequence(Func map)
+ public static IEnumerable RandomMapSequence(IContinuousDistribution distribution, Func map)
{
- return SystemRandomSource.DoubleSequence().Select(map);
+ return distribution.Samples().Select(map);
}
///
- /// Generate samples by sampling a function at sample pairs from a probability distribution, uniform between 0 and 1.
- /// Faster than other methods but with reduced guarantees on randomness.
+ /// Generate samples by sampling a function at sample pairs from a probability distribution.
///
- public static T[] RandomUniformMap2(int length, Func map)
+ public static T[] RandomMap2(int length, IContinuousDistribution distribution, Func map)
{
- var samples1 = SystemRandomSource.Doubles(length);
- var samples2 = SystemRandomSource.Doubles(length);
var data = new T[length];
for (int i = 0; i < data.Length; i++)
{
- data[i] = map(samples1[i], samples2[i]);
+ data[i] = map(distribution.Sample(), distribution.Sample());
}
return data;
}
///
- /// Generate a sample sequence by sampling a function at sample pairs from a probability distribution, uniform between 0 and 1.
- /// Faster than other methods but with reduced guarantees on randomness.
+ /// Generate a sample sequence by sampling a function at sample pairs from a probability distribution.
///
- public static IEnumerable RandomUniformMap2Sequence(Func map)
+ public static IEnumerable RandomMap2Sequence(IContinuousDistribution distribution, Func map)
{
- var rnd1 = SystemRandomSource.Default;
- for (int i = 0; i < 128; i++)
- {
- yield return map(rnd1.NextDouble(), rnd1.NextDouble());
- }
-
- var rnd2 = new System.Random(RandomSeed.Robust());
- while (true)
- {
- yield return map(rnd2.NextDouble(), rnd2.NextDouble());
- }
+ return distribution.Samples().Zip(distribution.Samples(), map);
}
}
}
diff --git a/src/UnitTests/GenerateTests.cs b/src/UnitTests/GenerateTests.cs
index 30f71e16..34172a1f 100644
--- a/src/UnitTests/GenerateTests.cs
+++ b/src/UnitTests/GenerateTests.cs
@@ -188,12 +188,12 @@ namespace MathNet.Numerics.UnitTests
public void ImpulseConsistentWithSequence()
{
Assert.That(
- Generate.ImpulseSequence(0, 5, 40).Take(1000).ToArray(),
- Is.EqualTo(Generate.Impulse(1000, 0, 5, 40)).AsCollection);
+ Generate.PeriodicImpulseSequence(0, 5, 40).Take(1000).ToArray(),
+ Is.EqualTo(Generate.PeriodicImpulse(1000, 0, 5, 40)).AsCollection);
Assert.That(
- Generate.ImpulseSequence(100, 5, 40).Take(1000).ToArray(),
- Is.EqualTo(Generate.Impulse(1000, 100, 5, 40)).AsCollection);
+ Generate.PeriodicImpulseSequence(100, 5, 40).Take(1000).ToArray(),
+ Is.EqualTo(Generate.PeriodicImpulse(1000, 100, 5, 40)).AsCollection);
}
}
}