Matrix Division on the 28C/S (and later)
|
03-04-2020, 01:41 PM
Post: #21
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
(03-04-2020 09:23 AM)Werner Wrote: Slightly changing the test to DOT( [ a -1 1 ] , [ 1 1 1] ), I noticed this difference between the 71B and the 28S/42S (and later RPL machines I guess): Using a=1E-20 (or any values <5E-16): 71B: result is 1E-15 ! 28S/42S: result is correctly rounded to 0. Something I will investigate for the HP71 Math ROM 2 :-) J-F |
|||
03-04-2020, 04:39 PM
(This post was last modified: 03-04-2020 07:00 PM by Albert Chan.)
Post: #22
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
(03-04-2020 12:29 PM)Thomas Okken Wrote: I'll write the new version of DOT next week, I think. I'll have to add FMA to the "phloat" functions, using bid128_fma() in the decimal version, and (I think) std::fma() in the binary version, and then implement the functions from your citations. DotFMA probably will not gain much accuracy. Example, if we fuse for every step, with tiny a, such that a+1=1 DotFMA([a 1 -1], [1 1 1]) = (a+1) - 1 = 1-1 = 0 However, fusing result at the end help (essentially "double" precision until final sum) see CompDot, CompDotFMA, http://rnc7.loria.fr/louvet_poster.pdf (03-04-2020 01:41 PM)J-F Garnier Wrote: Slightly changing the test to DOT( [ a -1 1 ] , [ 1 1 1] ), I noticed this difference between the 71B and the 28S/42S It seems 71B internal 15-digits precision is using Round-to-zero (chopping excess digits) Say, a = 1.00000000001e-15 DOT([a 1 -1], [1 1 1]) = (1.0000 00000 00000 10000 00000 01) - 1 ≈ (1.0000 00000 00000) - 1 = 0 DOT([a -1 1], [1 1 1]) = (-0.99999 99999 99998 99999 999999) + 1 ≈ (-0.99999 99999 99998) + 1 = 2E-15 |
|||
03-05-2020, 06:41 AM
Post: #23
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
(03-04-2020 04:39 PM)Albert Chan Wrote: DotFMA probably will not gain much accuracy. Well, yes, that's the idea: don't use the FMA for the dot product itself, but for the correction term, a bit like Kahan summation, but for dot products. Cheers, Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
03-06-2020, 05:48 AM
(This post was last modified: 03-06-2020 06:12 AM by Thomas Okken.)
Post: #24
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
First stab at compensated DOT, real-real case only:
Code: - for (i = 0; i < size; i++) I guess Werner's test case is a bit too easy, since it's returning a for arbitrarily low values, not just down to 1e-67. But maybe my implementation is wrong! I uploaded a test version for Windows here. Decimal only, since VC++ 2008 doesn't appear to support FMA in <math.h>; I guess I'll have to switch to a newer version if I'm going through with this. The code does build without complaint for MacOS and Linux; I haven't tried Android or iOS yet. I optimistically pushed this initial code to my master branch. |
|||
03-06-2020, 12:05 PM
Post: #25
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
Hello Thomas, no that is correct, the FMA 'compensated dot' algorithm is actually not the same as just using 68 digits ;-) As long as we're just performing a DOT product with one argument being a vector with all 1's, we're performing additions only, and we can actually do the same in RPN:
(based on Dekker's double precision algorithms, but modified a bit to work for decimal floating point arithmetic): Code: extended precision summation I can probably do the same for the full-fledged DOT.. I have the 'multiply two numbers and obtain a double-precision result' routines as well. The only thing I don't have for now is time ;-) Cheers, Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
03-06-2020, 05:20 PM
Post: #26
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
(03-06-2020 05:48 AM)Thomas Okken Wrote: I uploaded a test version for Windows here. Decimal only, since VC++ 2008 doesn't appear to support FMA in <math.h>; For machines that does not have hardware FMA, we can implement it in software. see Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates, page 18 to 20 lua> function split(x) -- assume IEEE double : local hi = (2^27+1) * x : hi = hi - (hi - x) : return hi, x - hi : end lua> function product(a, b) : local x = a*b : local a1, a2 = split(a) : local b1, b2 = split(b) : return x, -x + a1*b1 + a2*b1 + a1*b2 + a2*b2 : end lua> product(1.1, 1.2) 1.32 -4.44089209850063e-018 |
|||
03-07-2020, 04:08 PM
Post: #27
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
I implemented the real-complex and complex-complex cases, and moved all three cases to separate functions, so they can be easily reused later in other functions. Those other functions have yet to be done, but the improved DOT is now complete.
I uploaded test versions for Android, Windows, Mac, and Linux to https://thomasokken.com/free42/download/test/ and the source code is in the master branch in GitHub. For the Windows build, I switched from Visual C++ 2008 to 2019, so I was able to build the Binary version again. |
|||
03-08-2020, 06:11 PM
(This post was last modified: 03-08-2020 06:18 PM by J-F Garnier.)
Post: #28
|
|||
|
|||
RE: Matrix Division on the 28C/S (and later)
(03-04-2020 04:39 PM)Albert Chan Wrote:(03-04-2020 01:41 PM)J-F Garnier Wrote: Slightly changing the test to DOT( [ a -1 1 ] , [ 1 1 1] ), I noticed this difference between the 71B and the 28S/42S There is another similar truncating effect, instead of proper rounding with complex numbers: >(1+1E-10,1)*(1-1E-10,1) (-1.E-15,2) Contrary to the previous case, it is still present in the 42S, 28S, 48 series up to the 49G+. So I will not attempt to fix this effect (I don't call it bug...). J-F |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 1 Guest(s)