specfunc error analysis - generated and propagated errors.
Jonathan G. Underwood
j.underwood@open.ac.uk
Wed Sep 8 17:17:00 GMT 2004
Hi Gerard,
Firstly, thanks for your considered and detailed reply, which I've been
mulling over. What I'd like to do is just make a summary of what I
believe is the current model for error analysis in the library, and then
discuss the 'bigger picture' issues you've raised.
So, if I understand what you're saying correctly, the current model for
error analysis is:
(1) Assume exact input(s). [except for a few functions where input
errors are explicitly taken into account]
(2) Assume no errors on constants used in calculations.
(3) Each "primitive" operation {+,-,/,*} between two numbers adds a
_relative_ error of 2*GSL_DBL_EPSILON to the (intermediate) result.
[This is what I meant by generated error]
(4) Errors at each step are propogated to the next step according to
normal error analysis i.e.
(i) Addition and subtraction of A and B with absolute errors a and b
respectively gives an absolute propagated error in the result of a+b
(ii) Multiplication and division of A and B with absolute errors a and b
respectively gives a relative propagated error in the result of [|a/A| +
|b/B|]
(5) Errors from (3) and (4) are added for each step.
(6) At the end, if the error calculated by this analysis means that the
computed value is not equal to the known real value within the computed
error, add a Jungman relative error factor of a few GSL_DBL_EPSILON
until it is :)
I hope I've not missrepresented what you've said here, but I thought it
would be useful to nail down the current prescription.
Regarding the more general points about the reasoning behind the error
analysis and what it achieves, that all seems reasonable. Essentially,
the model is one of forward error analysis, and your arguments about the
benefit this has had in the development of the library seem
unquestionable, as is your argument that the user needs to be given some
idea of the merit/accuracy of the results of any given function. Given
though that the current forward error analysis only really gives a worst
case scenario, and doesn't take into account non-symmetric errors, or
cancellation etc etc, I think it's worth at least considering some
alternatives. Certainly the presence of point (6) above indicates that
the current approach is somewhat subjective and inprecise in some
circumstances.
I wonder if a cleaner design might be to move to a backward error
analysis philosophy, whereby the functions are evaluated as they are
currently, but without the forward error analysis, and the test suite is
used to chacterise/establish the accuracy of the implementation by
comparing known values of the functions to computed values. For
backwards compatibility, a typical backward-analysed error could be
returned by the _e functions. It would make for a much cleaner design of
the specfun code, and also remove the runtime computational overhead of
(most-times often unused) the forward error analysis. This would of
course require further development of the test suite, and relies upon
testing over the full range of use, and of course, that the "true"
values of the functions are known for comparison and error calculation.
I'm not really questioning the value of the forward error analysis
during the design and implementation/coding of the functions, but am
questioning the worth of it to the library user, and also the cost in
terms of code complexity, maintainability, and efficiency. A backward
error analysis I think could be (a) more accurate/representative and (b)
more efficient (b) lend itself to cleaner, simpler code. Of course, the
error may vary substantially over the range/domain of the function, but
that shouldn't be too difficult to deal with.
I agree that often, if the bottle kneck in the code is the calculation
of eg. bessel functions, then perhaps that's an ill thought out piece of
code. Often times though, it's unavoidable. Specifically for the angular
momentum code I am working on, 3j/6j and sometimes 9j symbols are
calculated in often deeply nested loops, and a factor of 2 or 3 here
makes a massive difference. Given that these symbols have 6 or 9
indices, often many of which are summed over in a computation,
efficiency of coding becomes important in many applications. This is in
fact why, even though I have transplanted the code to GSL, I'll probably
still have to use my own (previous) implementation without error analysis.
Just looking through NAG and numerical recipes type equivalents, I see
they don't implement any error analysis returned to the user. Many
conclusions could be reached from that, though :)
I agree on your point of avoiding having more than a single version of
the compiled library entirely, we'll write that off as an idea based on
1 am porridge-brain.
Anyway, I'd be really interested to know what you think, and am also
keen to help with the implementation of any changes that these
discussions lead to.
Goggling around a bit on these matters is interesting. Many people seem
to favour proper interval arithmetic for this sort of thing, but that
would be a massive headache to implement. Interestingly people always
argue against forward error analysis on the basis of some statement by
von Neumann who showed that it was overly pessimistic for some matrix
problems, couldn't find the details on that, though.
>>(a) Multiplication: Looking at coupling.c, it looks like the _relative_
>>generated error for multplication (A*B) is (2 * GSL_DBL_EPSILON). [See
>>lines 73 and 74 of coupling.c]. However, I then looked at legendre_poly.c,
>>as this contains some very simple algebra. Looking at line 84, I see that
>>my assertion must be wrong. But then, comparing line 122, which is the
>>same algebraic expression as line 84, gives an entirely different
>>generated error analysis. What gives?
>>
>>
>
>Yes, these are inconsistent by a factor of 3. This is a code
>duplication problem, and I have very little idea how extensive
>it is. Rubber mallet time?
>
>
I also noticed something else about this code - although Legendre
polynomials are "hard coded" up until P_3, in the general function, only
up to P_2 is hard coded. Anyway, if you let me know which of the two
error analyses you think is more approriate, I'll happily cook up a
patch to sort it out.
>What do you mean by truncation error?
>
>
er, ignore that, not sure what I was on about there.
>By the way, lately I have been influenced by a nice
>little book by Muller called "Elementary Functions: Algorithms and
>Implementation". I wish I had seen it before I started working on
>the special functions for GSL.
>
>
>
thanks for the reference, I'll have a look at that.
Best wishes,
Jonathan
More information about the Gsl-discuss
mailing list