ch-ch-update: series, closed-form series, and strides
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Tue Feb 3 12:25:43 PST 2009
Denis Koroskin wrote:
> On Tue, 03 Feb 2009 21:25:21 +0300, Sean Kelly <sean at invisibleduck.org>
> wrote:
>
>> Andrei Alexandrescu wrote:
>>> Ary Borenszweig wrote:
>>>> Andrei Alexandrescu escribió:
>>>>> I've updated my code and documentation to include series (as in
>>>>> math) in the form of infinite ranges. Also series in closed form
>>>>> (given n can compute the nth value without iterating) are supported
>>>>> as random-access ranges.
>>>>>
>>>>> Also Stride is provided. The Matrix container (speaking of
>>>>> scientific computing with D!) will support various representational
>>>>> choices, most importantly the ones endorsed by high-performance
>>>>> libraries. For Matrix, Stride is an important component as I'm sure
>>>>> anyone who's ever written a matrix knows.
>>>>>
>>>>> http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_range.html
>>>>> http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_algorithm.html
>>>>>
>>>>>
>>>>> Back to series. Finally my dream has come true: I can define a
>>>>> decent Fibonacci series clearly and efficiently in one line of
>>>>> code. No more idiotic recursive function that takes exponential
>>>>> time to finish!
>>>>>
>>>>> auto fib = series!("a[n-1] + a[n]")(1, 1);
>>>>> // write 10 Fibonacci numbers
>>>>> foreach (e; take(10, fib)) writeln(e);
>>>>
>>>> That is *SO* awesome!!
>>> Thanks! Constant-space factorial is just a line away:
>>> auto fact = series!("a[n] * (n + 1)")(1);
>>> foreach (e; take(10, fact)) writeln(e);
>>
>> Awesome :-) I think that proves the efficacy of the approach all by
>> itself.
>>
>>
>> Sean
>
> I wonder how efficent it is? Does it store last few sequence elements or
> re-compute then again and again?
> I wouldn't use it in the latter case.
I wouldn't use it either, in fact I have a dim view of all books,
articles, and courses that promote exponential-time Fibonacci and
linear-space factorial. It just promotes sloppy algorithmic thinking
under the pretense that recursion is cool. (I also have a dim view of
the FP proponents who promote the quicksort that actually doesn't sort
in place and returns new arrays by value every iteration, consuming O(n
log n) extra memory. But I digress.)
The size of the state held by a series is equal to the number of initial
arguments passed when it is constructed. The arguments are stored in a
fixed-size array sitting in the series object. So:
auto fib = series!("a[n-1] + a[n]")(1, 1);
holds an int[2], initialized with [1, 1]. The current index in the
series (a size_t initialized to 0) completes the state size.
When fib.next is called, the ((n+1) % 2)th element in the array is
overwritten with the result of a[(n-1)%2] + a[n%2]. Then n is
incremented. fib.head returns a[n%2].
In the factorial case it's simpler because the state size is 1. Since
the state size is used as a compile-time constant, the compiler has the
opportunity to optimize away calculations like n%1.
Andrei
More information about the Digitalmars-d
mailing list