std.range.recurrence
- multiple declarations
- Function recurrence
- Struct Recurrence
Function recurrence
Creates a mathematical sequence
given the initial
values and a
recurrence
function that computes the next value from the existing
values. The sequence
comes in the form of an infinite forward
range. The type
itself is seldom used directly; most
often, recurrences are obtained by calling the function Recurrence
.
recurrence
When calling
, the function that computes the next
value is specified as a template argument, and the recurrence
initial
values in
the recurrence
are passed as regular arguments. For example, in a
Fibonacci sequence
, there are two initial
values (and therefore a
state size of 2) because computing the next Fibonacci value needs the
past two values.
The signature of this function should be:
auto fun(R)(R state, size_t n)
where n
will be the index of the current value, and state
will be an
opaque state vector that can be indexed
with array-indexing notation
state[i]
, where valid values of i
range from (n - 1)
to
(n - State.length)
.
If the function is passed in string form, the state has name "a"
and the zero-based index in the recurrence
has name "n"
. The
given string must return the desired value for a[n]
given a[n
- 1]
, a[n - 2]
, a[n - 3]
,..., a[n - stateSize]
. The
state size is dictated by the number of arguments passed to the call
to
. The recurrence
struct itself takes care of
managing the Recurrence
recurrence
's state and shifting it appropriately.
Prototype
Recurrence!(fun,CommonType!State,State.length) recurrence(alias fun, State...)( Fiber.State initial );
Example
import std.algorithm : equal; // The Fibonacci numbers, using function in string form: // a[0] = 1, a[1] = 1, and compute a[n+1] = a[n-1] + a[n] auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1); assert(fib.take(10).equal([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])); // The factorials, using function in lambda form: auto fac = recurrence!((a,n) => a[n-1] * n)(1); assert(take(fac, 10).equal([ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 ])); // The triangular numbers, using function in explicit form: static size_t genTriangular(R)(R state, size_t n) { return state[n-1] + n; } auto tri = recurrence!genTriangular(0); assert(take(tri, 10).equal([0, 1, 3, 6, 10, 15, 21, 28, 36, 45]));
Struct Recurrence
Creates a mathematical sequence
given the initial values and a
recurrence
function that computes the next value from the existing
values. The sequence
comes in the form of an infinite forward
range. The type
itself is seldom used directly; most
often, recurrences are obtained by calling the function Recurrence
.
recurrence
When calling
, the function that computes the next
value is specified as a template argument, and the initial values in
the recurrence
recurrence
are passed as regular arguments. For example, in a
Fibonacci sequence
, there are two initial values (and therefore a
state size of 2) because computing the next Fibonacci value needs the
past two values.
The signature of this function should be:
auto fun(R)(R state, size_t n)
where n
will be the index of the current value, and state
will be an
opaque state vector that can be indexed
with array-indexing notation
state[i]
, where valid values of i
range from (n - 1)
to
(n - State.length)
.
If the function is passed in string form, the state has name "a"
and the zero-based index in the recurrence
has name "n"
. The
given string must return the desired value for a[n]
given a[n
- 1]
, a[n - 2]
, a[n - 3]
,..., a[n - stateSize]
. The
state size is dictated by the number of arguments passed to the call
to
. The recurrence
struct itself takes care of
managing the Recurrence
recurrence
's state and shifting it appropriately.
Example
import std.algorithm : equal; // The Fibonacci numbers, using function in string form: // a[0] = 1, a[1] = 1, and compute a[n+1] = a[n-1] + a[n] auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1); assert(fib.take(10).equal([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])); // The factorials, using function in lambda form: auto fac = recurrence!((a,n) => a[n-1] * n)(1); assert(take(fac, 10).equal([ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 ])); // The triangular numbers, using function in explicit form: static size_t genTriangular(R)(R state, size_t n) { return state[n-1] + n; } auto tri = recurrence!genTriangular(0); assert(take(tri, 10).equal([0, 1, 3, 6, 10, 15, 21, 28, 36, 45]));
Authors
Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.