[seqfan] Re: Rant on Maple code
Richard Mathar
mathar at strw.leidenuniv.nl
Tue Aug 11 13:12:57 CEST 2009
In http://list.seqfan.eu/pipermail/seqfan/2009-August/002074.html
some comparisons of coding style were attempted:
pl> Just one example, out of many, which explains why I do not
pl> like most of the Maple code presented in the database:
pl>
pl> A001147 Double factorial numbers: (2n-1)!!
pl>
pl> (1) f := n->(2*n)!/(n!*2^n);
pl>
pl> (2) with(finance):seq(mul(cashflows([k, k, 1], 0), k=0..n), n=-1..22);
pl> # [From Zerinvary Lajos (zerinvarylajos(AT)yahoo.com), Dec 22 2008]
pl>
pl> (3) restart: G(x):=(1-2*x)^(-1/2): f[0]:=G(x): for n from 1 to 29 do
pl> f[n]:=diff(f[n-1], x) od: x:=0: seq(f[n], n=0..19);
pl> # [From Zerinvary Lajos (zerinvarylajos(AT)yahoo.com), Apr 03 2009]
pl>
pl> (4) A001147 := proc(n) doublefactorial(2*n-1); end:
pl> [From R. J. Mathar (mathar(AT)strw.leidenuniv.nl), Jul 04 2009]
pl>
pl> (1) is the best out of the four. It reflects the formula and
pl> is simple. Of course it is not computationally efficient.
pl>
pl> (2) A nightmare. I did not even know that Maple comes with a
pl> package 'finance'. So I looked it up in the Maple help pages
So you learned something. This is a nice point in some of the Maple
implementations.
pl> what cashflows are. It says:
pl>
pl> finance[cashflows] - present value of a list of cash flows
pl>
pl> Aha. But we are talking about the double factorial. And why
pl> does n starts at '-1'? I found no hint in the references,
pl> in the links or in the formula section which explains this
pl> implementation. Well, I stopped further investigations as I
pl> think that this formula was invented by employees of the
pl> Lehman Brothers bank. Hopefully Maple will not collapse also.
This does not get to the point. There hundreds of examples of this
kind of code (all by Zerinvary) who is trying to demonstrate that all
the polynomials (and there are many of them in the OEIS) can be written
as sums of polynomials of lesser degree (to be applied recursively)
and there seems to be a similar mission in the factorial domain.
While this seems to be trivial, superfluous (that is: worthless) to most of
us, we can look at these Maple snippets as some formulas
sprung out of some undergraduate formula book, landing for some reasons
not in the formula but in the coding section of the OEIS.
pl>
pl> (3) Well, there are many ways to do it... The 'restart'
pl> command is a good general advice -- in a Maple beginners
pl> book. What why put it here?
pl>
pl> (4) Not really helpful. 'doublefactorial' is not implemented
pl> in the older versions of Maple. And there are many Maple V
pl> still out there just because they are not so buggy as the
pl> newer versions.
Clearly, (4) is the best out of the four. The reasons are :
(i) It is the most obvious in terms of the interface. You want to get
a double factorial, as the definition says, and, voila, there is a name
in the language which looks like it is doing the job, and you call it by
the name. Don't be surprised if the sin() returns the sine function, log the
logarithm etc.
(ii) It definitely is the most efficient way, because we know for sure that
instead of one multiplication, one division and two factorials involved
in (1), whoever implemented the double factorial was aware of the
cases where an odd integer is the argument, and he/she did it in the
machine language of your computer.
(iii) It is clearly superior to any type of Pochhammer or other
hypergeometric or factorial obfuscation because it stays entirely
in the integer domain. It does not rewrite the code in terms of
fractions (rational functions), and it does not accumulate larger
intermediate numbers to chop them down to smaller final results.
(iv) It is the best one could do in a tutorial style. For those who
did not know the function: read those fine manuals. For those who are
still not finding it into the package it sends the message: progress
is inevitable. Even packages like Maple (or language like Fortran) are
upgraded from time to time to implement new functionality.
(v) There is a very important additional point of view: don't re-invent
the wheel. You can write this by calling some of your most favorite
machine coded, native, highly-optimized private programs with
some system() call. If you are not in the business of optimizing
specialized functions: be pleased to find it is already there.
pl>
pl> Maple can of course compute the double factorial numbers
pl> since the early days in an efficient manner. Moreover,
pl> this way also reflects the way the double factorial numbers
pl> are used in the world of hypergeometric summation where
pl> they occur frequently. And reflects the mathematical
pl> meaning of these numbers better than (1).
pl>
pl> A001147 := n -> 2^n*pochhammer(1/2, n);
A very doubtful attempt, and already a giant step forward
to obfuscation. One can rewrite the double factorial as gamma-functions,
and rewrite these as integrals etc, obtaining more and more complicated
formulas with an ever increasing level of inefficiency, unreadability etc.
Note that the mathematical meaning of the double factorial in the integer
domain is: skip each second number while multiplying; it does not get much
simpler than that. The Pochhammer symbol has a much wider range of
applicability, and in turn it is forced to hide this fact.
Richard Mathar
More information about the SeqFan
mailing list