Browse Source

Generate: Unfold, Fibonacci

cuda
Christoph Ruegg 12 years ago
parent
commit
44ea89a983
  1. 86
      src/Numerics/Generate.cs
  2. 29
      src/UnitTests/GenerateTests.cs

86
src/Numerics/Generate.cs

@ -717,6 +717,90 @@ namespace MathNet.Numerics
}
}
/// <summary>
/// Generate samples generated by the given computation.
/// </summary>
public static T[] Unfold<T, TState>(int length, Func<TState, Tuple<T, TState>> f, TState state)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException("length");
}
var data = new T[length];
for (int i = 0; i < data.Length; i++)
{
Tuple<T, TState> next = f(state);
data[i] = next.Item1;
state = next.Item2;
}
return data;
}
/// <summary>
/// Generate an infinite sequence generated by the given computation.
/// </summary>
public static IEnumerable<T> UnfoldSequence<T, TState>(Func<TState, Tuple<T, TState>> f, TState state)
{
while (true)
{
Tuple<T, TState> next = f(state);
state = next.Item2;
yield return next.Item1;
}
}
#if !NOSYSNUMERICS
/// <summary>
/// Generate a Fibonacci sequence, including zero as first value.
/// </summary>
public static BigInteger[] Fibonacci(int length)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException("length");
}
var data = new BigInteger[length];
if (data.Length > 0)
{
data[0] = BigInteger.Zero;
}
if (data.Length > 1)
{
data[1] = BigInteger.One;
}
for (int i = 2; i < data.Length; i++)
{
data[i] = data[i - 1] + data[i - 2];
}
return data;
}
/// <summary>
/// Generate an infinite Fibonacci sequence, including zero as first value.
/// </summary>
public static IEnumerable<BigInteger> FibonacciSequence()
{
BigInteger a = BigInteger.Zero;
yield return a;
BigInteger b = BigInteger.One;
yield return b;
while (true)
{
a = a + b;
yield return a;
b = a + b;
yield return b;
}
}
#endif
/// <summary>
/// Create random samples, uniform between 0 and 1.
/// Faster than other methods but with reduced guarantees on randomness.
@ -1016,5 +1100,7 @@ namespace MathNet.Numerics
{
return distribution.Samples().Zip(distribution.Samples(), map);
}
}
}

29
src/UnitTests/GenerateTests.cs

@ -30,6 +30,7 @@
using System;
using System.Linq;
using System.Numerics;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests
@ -217,5 +218,33 @@ namespace MathNet.Numerics.UnitTests
Generate.PeriodicImpulseSequence(100, 5, 40).Take(1000).ToArray(),
Is.EqualTo(Generate.PeriodicImpulse(1000, 100, 5, 40)).AsCollection);
}
[Test]
public void UnfoldConsistentWithSequence()
{
Assert.That(
Generate.UnfoldSequence((s => Tuple.Create(s + 1, s + 1)), 0).Take(250).ToArray(),
Is.EqualTo(Generate.Unfold(250, (s => Tuple.Create(s + 1, s + 1)), 0)).AsCollection);
}
[Test]
public void FibonacciConsistentWithSequence()
{
Assert.That(
Generate.FibonacciSequence().Take(250).ToArray(),
Is.EqualTo(Generate.Fibonacci(250)).AsCollection);
}
[Test]
public void FibonacciConsistentWithUnfold()
{
Assert.That(
Generate.FibonacciSequence().Take(250).ToArray(),
Is.EqualTo(new[] { BigInteger.Zero, BigInteger.One }.Concat(Generate.Unfold(248, (s =>
{
var z = s.Item1 + s.Item2;
return Tuple.Create(z, Tuple.Create(s.Item2, z));
}), Tuple.Create(BigInteger.Zero, BigInteger.One)))).AsCollection);
}
}
}

Loading…
Cancel
Save