Prev: Dhrystone
Next: Learning Ada
From: Ada novice on 5 Aug 2010 05:14 I have made some simple tests on some special matrices which can pose some problems. I limited myself to matrices with real values. I have tested: 1. non-symmetric real matrices with repeated values. No problem here 2. a real orthogonal matrix. Such a matrix gives all eigenvalues of unit modulus. I tested the case from http://en.wikipedia.org/wiki/Orthogonal_matrix. In Matlab, eig([0, -0.8, -0.6; 0.8, -0.36, 0.48; 0.6, 0.48, -0.64]) gives the eigenvalues as 0 + 1i, 0 - 1i and -1. Using your Ada code gives: -1.78814E-08 1.00000E+00 -8.72890E-09 -1.00000E+00 -1.00000E+00 0.00000E+00 Does the Blas code work with Fortran double-precision? In the above, Matlab with double (15 digits precision). I don't see you using the type Long_Float in the Ada code. I don't know how many digits are being passed from the Fortran result to Ada. Maybe this is causing the discrepancy between the expected results (all eigenvalues of modulus one) and the output in Ada. 3. a real skew-symmetric matrix. This is also interesting as all eigenvalues are imaginary. I tested the case from http://en.wikipedia.org/wiki/Skew-symmetric_matrix. In Matlab, eig([0, 2, -1; -2, 0, -4; 1, 4, 0]) gives the eigenvalues as 0 ; 0 + 4.582575694955841i and 0 - 4.582575694955841i Using the Ada code gives: 9.12635E-08 4.58258E+00 -5.31220E-08 1.92730E-07 3.95880E-08 -4.58258E+00 Here also exist some slight discrepancies. I believe as mentioned above that if we change use more precision digits, then we'll get "better" answers. Thanks. YC
From: John B. Matthews on 5 Aug 2010 09:23 In article <b7f5edce-124d-4b91-82f2-e9793d39a3cf(a)x25g2000yqj.googlegroups.com>, Ada novice <posts(a)gmx.us> wrote: > 2. a real orthogonal matrix. Such a matrix gives all eigenvalues of > unit modulus. I tested the case from > http://en.wikipedia.org/wiki/Orthogonal_matrix. > In Matlab, > > eig([0, -0.8, -0.6; 0.8, -0.36, 0.48; 0.6, 0.48, -0.64]) > > gives the eigenvalues as 0 + 1i, 0 - 1i and -1. > > Using your Ada code gives: > > -1.78814E-08 1.00000E+00 > -8.72890E-09 -1.00000E+00 > -1.00000E+00 0.00000E+00 > > > Does the Blas code work with Fortran double-precision? In the above, > Matlab with double (15 digits precision). I don't see you using the > type Long_Float in the Ada code. I don't know how many digits are > being passed from the Fortran result to Ada. Maybe this is causing the > discrepancy between the expected results (all eigenvalues of modulus > one) and the output in Ada. Using these declarations in test_extensions.adb: subtype My_Float is Long_Float; Input : constant Complex_Matrix := (((0.0, 0.0), (-0.8, 0.0), -0.6, 0.0)), ((0.8, 0.0), (-0.36, 0.0), (0.48, 0.0)), ((0.6, 0.0), (0.48, 0.0), (-0.64, 0.0))); I get this result: ../test_extensions 0.00000000000000E+00 1.00000000000000E+00 -2.77555756156289E-17 -1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 [...] -- John B. Matthews trashgod at gmail dot com <http://sites.google.com/site/drjohnbmatthews>
From: sjw on 5 Aug 2010 09:57 On Aug 5, 2:23 pm, "John B. Matthews" <nos...(a)nospam.invalid> wrote: > In article > <b7f5edce-124d-4b91-82f2-e9793d39a...(a)x25g2000yqj.googlegroups.com>, > Ada novice <po...(a)gmx.us> wrote: > > > > > 2. a real orthogonal matrix. Such a matrix gives all eigenvalues of > > unit modulus. I tested the case from > >http://en.wikipedia.org/wiki/Orthogonal_matrix. > > In Matlab, > > > eig([0, -0.8, -0.6; 0.8, -0.36, 0.48; 0.6, 0.48, -0.64]) > > > gives the eigenvalues as 0 + 1i, 0 - 1i and -1. > > > Using your Ada code gives: > > > -1.78814E-08 1.00000E+00 > > -8.72890E-09 -1.00000E+00 > > -1.00000E+00 0.00000E+00 > > > Does the Blas code work with Fortran double-precision? In the above, > > Matlab with double (15 digits precision). I don't see you using the > > type Long_Float in the Ada code. I don't know how many digits are > > being passed from the Fortran result to Ada. Maybe this is causing the > > discrepancy between the expected results (all eigenvalues of modulus > > one) and the output in Ada. > > Using these declarations in test_extensions.adb: > > subtype My_Float is Long_Float; > > Input : constant Complex_Matrix > := (((0.0, 0.0), (-0.8, 0.0), -0.6, 0.0)), > ((0.8, 0.0), (-0.36, 0.0), (0.48, 0.0)), > ((0.6, 0.0), (0.48, 0.0), (-0.64, 0.0))); > > I get this result: > > ./test_extensions > 0.00000000000000E+00 1.00000000000000E+00 > -2.77555756156289E-17 -1.00000000000000E+00 > -1.00000000000000E+00 0.00000000000000E+00 The reason for the 'subtype My_Float is Float;' is to make it easy to change the type in use, for experimentation. You can certainly use Fortran double precision, equivalent to the GNAT Ada Long_Float. Although LAPACK/BLAS (at 3.2.2 anyway) allow you to build with extended precision (80-bit floats, GNAT Long_Long_Float if on x86 hardware) GNAT's implementation of Generic * Arrays assumes the worst case, ie BLAS/LAPACK only available in single & double precision; and if the type in use (My_Float in my test case) doesn't match Fortran single or double precision it converts to double precision, makes the call, then converts back. I think this deserves a warning at the least if the precision of the result doesn't match the precision of the base type. The Extensions code makes the same transformations as GNAT's.
From: Ada novice on 5 Aug 2010 13:24 Thanks sjw and trashgod. It's good that changing the subtype to Long_Float fixes the "problem" easily. First my apologies for supplying the test matrices in Matlab form and in Ada form in my earlier post. I should have of course supplied them in Ada's form as trashgod did to make things easier for you. I tried again case 2 and case 3 from my earlier post: 2. case 2 Input : constant Complex_Matrix := (((0.0, 0.0), (-0.8, 0.0), (-0.6, 0.0)), ((0.8, 0.0), (-0.36, 0.0), (0.48, 0.0)), ((0.6, 0.0), (0.48, 0.0), (-0.64, 0.0))); and the eigenvalues are: -9.97465998686664E-18 1.00000000000000E+00 -2.07489190759413E-17 -1.00000000000000E+00 -1.00000000000000E+00 0.00000000000000E+00 3. Case 3 Input : constant Complex_Matrix := (((0.0, 0.0), (2.0, 0.0), (-1.0, 0.0)), ((-2.0, 0.0), (0.0, 0.0), (-4.0, 0.0)), ((1.0, 0.0), (4.0, 0.0), (0.0, 0.0))); and the eigenvalues are: -3.16587034365767E-17 4.58257569495584E+00 3.52062239626920E-17 -1.38867432149415E-16 2.99876030370094E-16 -4.58257569495584E+00 They are much more accurate and better results of course. I wonder why Matlab tends to be give very "accurate" answers. Normally 15 digits of precision is also used there. On Aug 5, 3:57 pm, sjw <simon.j.wri...(a)mac.com> wrote: > Although LAPACK/BLAS (at 3.2.2 anyway) allow you to build with > extended precision (80-bit floats, GNAT Long_Long_Float if on x86 > hardware) GNAT's implementation of Generic * Arrays assumes the worst > case, ie BLAS/LAPACK only available in single & double precision; and > if the type in use (My_Float in my test case) doesn't match Fortran > single or double precision it converts to double precision, makes the > call, then converts back. Can we change the subtype to Long_Long_Float? This will be of 18 precision digits and "more" precise than Fortran's double precision. It would be like asking for more precision that can be offered. Did I understand you correctly? Thanks YC
From: Jeffrey Carter on 5 Aug 2010 13:59
On 08/05/2010 10:24 AM, Ada novice wrote: > > They are much more accurate and better results of course. I wonder why > Matlab tends to be give very "accurate" answers. Normally 15 digits of > precision is also used there. You requested 15 decimal digits; your results are zero to 15 decimal places. If you output in non-scientific notation you'd get zero; presumably that's what Matlab is doing. -- Jeff Carter "I was in love with a beautiful blonde once, dear. She drove me to drink. That's the one thing I'm indebted to her for." Never Give a Sucker an Even Break 109 --- news://freenews.netfront.net/ - complaints: news(a)netfront.net --- |