Prev: Dhrystone
Next: Learning Ada
From: Ada novice on
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
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
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
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
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 ---
First  |  Prev  |  Next  |  Last
Pages: 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Prev: Dhrystone
Next: Learning Ada