RE: Haskell 98 - Standard Prelude - Floating Class
Simon PJ wrote:
Fpr the Revised Haskell 98 report, Russell O'Connor suggests: =20 | Also, I understand you are reluctant to make library changes,=20 | but sinh and cosh can easily be defined in terms of exp |=20 | sinh x =3D (exp(x) - exp(-x))/2 | cosh x =3D (exp(x) + exp(-x))/2 |=20 | (source: Calculus Third Edition by Michael Spivak, page 349,=20 | or any decent calculus book) |=20 | I suggest removing sinh and cosh from the minimal complete=20 | definition, and add the above defaults.
This looks pretty reasonable to me. We should have default methods for anything we can.
Comments? No. As has been pointed out, this is a bad idea numerically because it will give the wrong answer for sinh x for very small values of x. As a matter of fact, you will also get the wrong answer for very large values of x, where exp(x) can overflow even though sinh x and cosh x don't, meaning you get an incorrect answer of positive infinity.
I suggest saying as little about the transcendental functions as possible, rather than forcing incorrect rules on the implementor. I imagine most Haskell implementors do not want to waste time writing their own transcendental function routines, but simply call out to one of the various high-quality C implementations. (Netlib has a good free one, for example.) This will probably produce better results than suggesting buggy code to the implementor. Technically, you would probably be able to define all the functions sinh/cosh/tanh/exp functions with reasonable precision in terms of expm1, defined mathematically as expm1(x) = exp(x) - 1. But please don't . . .
On Mon, Oct 15, 2001 at 06:27:52PM +0200, George Russell wrote:
Simon PJ wrote:
Fpr the Revised Haskell 98 report, Russell O'Connor suggests: =20 | Also, I understand you are reluctant to make library changes,=20 | but sinh and cosh can easily be defined in terms of exp |=20 | sinh x =3D (exp(x) - exp(-x))/2 | cosh x =3D (exp(x) + exp(-x))/2 |=20 | (source: Calculus Third Edition by Michael Spivak, page 349,=20 | or any decent calculus book) |=20 | I suggest removing sinh and cosh from the minimal complete=20 | definition, and add the above defaults.
This looks pretty reasonable to me. We should have default methods for anything we can.
Comments? No. As has been pointed out, this is a bad idea numerically because it will give the wrong answer for sinh x for very small values of x. As a matter of fact, you will also get the wrong answer for very large values of x, where exp(x) can overflow even though sinh x and cosh x don't, meaning you get an incorrect answer of positive infinity.
Err, what? Surely sinh x is at least 1/2 of exp x, leaving only a very narrow range for this to happen. Behaviour of sinh x near 0 is more important, unless I'm missing something?
I suggest saying as little about the transcendental functions as possible, rather than forcing incorrect rules on the implementor.
The suggestions are for default methods, which force nothing on anybody. They would be suggestions, in case anyone writes their own instances of these classes; the question should be whether they are useful suggestions. For instance, if you have a class of computable reals (increasingly good approximations), the default definitions of sinh and cosh are excellent. I don't think it's worth worrying about much. (They don't work for floating point numbers because of the special behaviour near 0.) Best, Dylan Thurston
Dylan Thurston wrote: [snip]
No. As has been pointed out, this is a bad idea numerically because it will give the wrong answer for sinh x for very small values of x. As a matter of fact, you will also get the wrong answer for very large values of x, where exp(x) can overflow even though sinh x and cosh x don't, meaning you get an incorrect answer of positive infinity.
Err, what? Surely sinh x is at least 1/2 of exp x, leaving only a very narrow range for this to happen. Behaviour of sinh x near 0 is more important, unless I'm missing something? If we are planning to introduce bugs into the Haskell standard, I am not going to argue about which bug is more important than which other bug. Personally I think we should avoid all bugs.
I suggest saying as little about the transcendental functions as possible, rather than forcing incorrect rules on the implementor.
The suggestions are for default methods, which force nothing on anybody. They would be suggestions, in case anyone writes their own instances of these classes; the question should be whether they are useful suggestions. For instance, if you have a class of computable reals (increasingly good approximations), the default definitions of sinh and cosh are excellent. I would like to see such an implementation. The definition of sinh/cosh requires the number to be an instance of Floating, which requires Fractional, which requires Num, which requires Eq. Testing equality for computable reals is equivalent to solving the Turing Halting Problem, which would have wide-ranging applications for computer science . . .
I'm afraid that I have very little faith in the numerical analysis expertise of the typical Haskell implementor, so I think it is dangerous to give them an incorrect "default" implementation. I am reminded of the notorious ASCII C (very)-pseudo-random number generator . . .
I don't think it's worth worrying about much.
This is a good argument for leaving things as they are. [snip]
George Russell wants to terminate the discussion with Dylan Thurston who corrects some inadequacies of his previous posting :
... Surely sinh x is at least 1/2 of exp x, leaving only a very narrow range for this to happen. Behaviour of sinh x near 0 is more important, unless I'm missing something?
If we are planning to introduce bugs into the Haskell standard, I am not going to argue about which bug is more important than which other bug. Personally I think we should avoid all bugs.
There IS a big difference between "bugs in standard" and numerically unstable or incomplete algorithms. I go to Canossa now, I agree of course that the def. sinh = (exp - recip.exp)/2 is disgraceful, although as a math. proper default is OK. Yes, in this sense - as Lennart pointed out - the complex sinh which uses the real sinh is numerically better near zero, (provided that the real sinh is properly implemented!! Did Joe Fasel include this consciously? If yes, my respect - already almost infinite, is even bigger now). But the defaults should find a reasonable compromise between accuracy and ease. The passage below is methodologically dangerous.
I'm afraid that I have very little faith in the numerical analysis expertise of the typical Haskell implementor, so I think it is dangerous to give them an incorrect "default" implementation. I am reminded of the notorious ASCII C (very)-pseudo-random number generator . . .
I don't think it's worth worrying about much.
This is a good argument for leaving things as they are.
Absolutely NO. Unless you don't care at all about the potential scientific users of the language. Leaving the details which are of utmost importance for professional applications is killing the language. Most readers of this forum are very far away from numerics, and this is normal. But languages live through their libraries. At least 4 times a year somebody on this list complains about lack of such a support even if the actual libraries are already quite impressive. So, I would encourage to organize one day a group - not necessarily a "task force" like the GUI people - of people who would test all the numerics, and at least give to the freshmen some implementation prototypes, e.g. Padés for small arguments of sinh, etc. And what is this: "typical Haskell implementor"? Do you know many of them? Do you think really that some fellow totally inconscious in the domain of STANDARD numeric maths, somebody who never heard about IEEE etc. will NOW engage in implementing Haskell? What is the rationale behind your little faith, Man of Little Faith? Jerzy Karczmarczuk =========================================== PS. One more thing. HARMFUL SPAMMERS ARE AMONG US. May I humbly suggest that people who send postings to haskell@ avoid sending copies to all individuals who ever took part in the discussion?
Jerzy Karczmarczuk wrote:
Did Joe Fasel include this consciously? If yes, my respect - already almost infinite, is even bigger now).
I'm pretty sure he did, but he can speak for himself. I know he discussed these things with his numerical collegues when designing the prelude. Look at this definition (from Complex, by Joe) for instance instance (RealFloat a) => Fractional (Complex a) where (x:+y) / (x':+y') = (x*x''+y*y'') / d :+ (y*x''-x*y'') / d where x'' = scaleFloat k x' y'' = scaleFloat k y' k = - max (exponent x') (exponent y') d = x'*x'' + y'*y'' The scaleFloat calls are there for numeric reasons. -- Lennart
participants (4)
-
Dylan Thurston -
George Russell -
Jerzy Karczmarczuk -
Lennart Augustsson