diff --git a/src/Numerics/Generate.cs b/src/Numerics/Generate.cs
index bf5b04c7..3520913e 100644
--- a/src/Numerics/Generate.cs
+++ b/src/Numerics/Generate.cs
@@ -717,6 +717,90 @@ namespace MathNet.Numerics
}
}
+ ///
+ /// Generate samples generated by the given computation.
+ ///
+ public static T[] Unfold(int length, Func> f, TState state)
+ {
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException("length");
+ }
+
+ var data = new T[length];
+ for (int i = 0; i < data.Length; i++)
+ {
+ Tuple next = f(state);
+ data[i] = next.Item1;
+ state = next.Item2;
+ }
+ return data;
+ }
+
+ ///
+ /// Generate an infinite sequence generated by the given computation.
+ ///
+ public static IEnumerable UnfoldSequence(Func> f, TState state)
+ {
+ while (true)
+ {
+ Tuple next = f(state);
+ state = next.Item2;
+ yield return next.Item1;
+ }
+ }
+
+#if !NOSYSNUMERICS
+
+ ///
+ /// Generate a Fibonacci sequence, including zero as first value.
+ ///
+ 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;
+ }
+
+ ///
+ /// Generate an infinite Fibonacci sequence, including zero as first value.
+ ///
+ public static IEnumerable 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
+
///
/// 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);
}
+
+
}
}
diff --git a/src/UnitTests/GenerateTests.cs b/src/UnitTests/GenerateTests.cs
index 522a43ef..432075b7 100644
--- a/src/UnitTests/GenerateTests.cs
+++ b/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);
+ }
}
}