Description of the issue
Many operations on polynomials are defined as "monomial-wise" operations, meaning that the same operation is carried out on each monomial, and summation of the resulting monomials (or polynomials) gives the resulting polynomial.
In other words, using the terminology of jscience, let us consider a org.jscience.mathematics.function.Polynomial<R> p which shall be written symbolically
p = c0*t0 + c1*t1 + ...
where c0, c1, ... are coefficients (of type R), and t0, t1, ... are of type org.jscience.mathematics.function.Term.
Let us now consider a function f taking as an input a monomial c*t (c : R, t : org.jscience.mathematics.function.Term), and returns a new monomial f(c*t). I would like to be able to compute in an efficient way the following polynomial
q = f(c0*t0) + f(c1*t1) + ...
Using a loop for (Term t: p.getTerms()) is of course possible, but incredibly slow, while a direct traversal of p._termToCoef is much, much faster.
First define a GeneralFunction<X, Y>, with only one method
Y evaluate(X x)
Then, in org.jscience.mathematics.function.Polynomial<R>, define a method
Polynomial<R> map(GeneralFunction<Map.Entry<Term, R>, Map.Entry<Term, R>> f)
which carries out the operation above.
I propose to define a GeneralFunction (or any other name), because the function f we want to map on the polynomial is not really a org.jscience.mathematics.function.Function.
Improvements on this side might be
- find a better name,
- make org.jscience.mathematics.function.Function inherit from GeneralFunction.
I didn't define a type Monomial<R>, but used Map.Entry<Term, R> instead. This makes implementation of the requested feature easier, but might lead to confusing code.
Examples of use
I'm using org.jscience.mathematics.function.Polynomial to carry out series expansions in many (9) variable, so the polynomials are quite big. Each time I carry out a multiplication, I need to do truncation. If I loop over the terms of the polynomial to be truncated, it's incredibly slow. Using the solution described above results in a significantly faster execution. Silly measurements on a specific case showed that the new implementation was 200x faster !
Attached is the source for GeneralFunction, as well as a patch for Polynomial.
This patch actually also includes modifications from issue JSCIENCE-155.