Mar 27, 2015

Special Purpose Iterators

This package is for the mathematically inclined only.It contains four types of methods: 

Generating iterators of Integer: There are faculty, fibonacci and hamming. While the first two are well-known, Hamming is rather particular. It is based on an exercise attributed to R. W. Hamming and reported by Dijkstra in "A discipline of programming", p. 129. The problem is this: Let p1, p2, .. pn be n integers, often but not necessarily primes. Create an iterator yielding 1 and all multiples of p1, p2, .. pn in ascending order. So, hamming(2,3,5) returns 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, ...

Generating iterators of Double: exp(), cos(), sin() generate the respective series. random(), arithmeticSeries(start, delta), geometricSeries(start, factor) behave as expected. 

Finite and Infinite Polynoms: An Iterator of Double such as (1.0, 1.0, 1.0) can be considered the finite polynom 1 + x + x^2 and hence be evaluated for any Double. The same is true for series such as exp(). The method polynom(Iterator<Double>) returns an UnaryOperator which unwinds the iterator completely or up to a given degree and stores the result in an internal list. It thus consumes the iterator but the polynom itself is reusable.
UnaryOperator<Double> p;
p = polynom(of(1.0, 2.0, 3.0));  // p(x) = 1 + 2x + 3x^2                                                                         
p.apply(0.0);                    // returns 1.0
p.apply(1.0);                    // returns 6.0
p.apply(-1.0);                   // returns 2.0
p.apply(2.0);                    // returns 17.0

p = polynom(exp());              // p(x) = exp(x)
p.apply(0.0);                    // returns 1.0
p.apply(1.0);                    // returns e
p.apply(-1.0);                   // returns 1/e
p.apply(2.0);                    // returns e^2


Operators on Polynoms Two polynoms of finite or infinite length can be added, multiplied, divided and composed, yielding in each case a new polynom. Note that the divisor's first coefficient must not be zero. compose(s, t) returns the coefficients of polynom(t) o polynom(s). It thus holds that

polynom(compose(t, s)) = compose(polynom(t), polynom(s))

Square and inverse of a polynom p are defined by
square(p) = multiply(p, p)
inverse(p) = divide(1, p)

 Everybody knows that sin^2 + cos^2 = 1. With our library, this reads as follows:
Iterator<Double> r;
r = add(square(sin()), square(cos()));
r.next();                    // first element is 1.0, all others are 0.0
reduce(limit(r, 10), (a, b) -> abs(a) + abs(b), 0.0);  // returns 0.0
An iterator can also be augmented by a scalar and multiplied with a factor:
Iterator<Double> r;
r = add(random(), 5.0);
r = multiply(random(), 5.0);

No comments:

Post a Comment