Prev: Dhrystone
Next: Learning Ada
From: Simon Wright on
Ada novice <posts(a)gmx.us> writes:

> On Jul 24, 6:38 pm, Simon Wright <si...(a)pushface.org> wrote:
>
>> but on a Windows machine it'll be something li
>> <install-dir>\<gnat-release>\lib\gcc\<architecture>\<gcc-release>\adainclude\a-ngrear.ad[sb]
>>
>> This will lead you to System.Generic_Real_BLAS (s-gerebl.ad[sb]) and
>> System.Generic_Real_LAPACK (s-gerela.ad[sb]), which are interfaces to
>> the corresponding external libraries.
>>
>> Not sure that these will fit your 'simple' criterion, though!
>>
>> --S
>
> Thanks. I've been able to locate these files under GNAT on my Windows
> machine and read them. For eigensystems operations, only symmetric and
> hermitian (complex-symmetric) matrices are allowed. I would like
> however to be able to deal with a general non-symmetric matrix and
> this I believe is not possible right now with Ada.

No, but those files implement interfaces to those *parts of* the
external libraries BLAS and LAPACK that were necessary to implement the
Numerics annex.

It may be that the other parts of those libraries contain the features
you're looking for, in which case you have a head start on your own
implementation.

But, if not, you can at least see one approach to the job that you could
adopt for the external library of your choice.
From: Ada novice on
Many thanks for all your inputs. I'll give you an example. Say we want
to compute the eigenvalues of this 3 X 3 matrix. The code in C (using
the IMSL library)is as follows:

#include <imsl.h>

int main()
{
int n = 3;
float a[] = {8.0, -1.0, -5.0,
-4.0, 4.0, -2.0,
18.0, -5.0, -7.0};
f_complex *eval;
/* Compute eigenvalues of A */
eval = imsl_f_eig_gen (n, a, 0);
/* Print eigenvalues */
imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0);
}


and the output on the screen (with some pretty formatting from
imsl_c_write_matrix) is:

Eigenvalues
1 2 3
( 2, 4) ( 2, -4) ( 1, 0)

Here, the first eigenvalue is 2 + 4i, the second one is 2 -4i and so
on. I found that f_complex (used in the line f_complex *eval) is
defined as follows:

typedef struct{
float re;
float im;
} f_complex;

and f_complex is or single-precision complex values (d_complex exists
for double-precision).

I have never worked with structures before and after some
"cursing" :), I could access the individual elements as follows:

printf(" %g\n", eval[0].re) will give me the real part of the first
eigenvalue i.e. 2.

What would the best way to interface this with Ada? The elements of my
matrix will be formed in Ada, then the matrix will be passed to C to
calculate the eigenvalues and then the latter passed back to Ada. The
size of my matrix will be fixed say 3 x 3. As a novice in Ada, I would
like to learn good programming practice and the best way is to use
codes and learn from experts here in Ada.

Thanks for your very kind help.
YC


From: Ada novice on
Many thanks for all your inputs. I'll give you an example. Say we want
to compute the eigenvalues of this 3 X 3 matrix. The code in C (using
the IMSL library) is as follows:

#include <imsl.h>

int main()
{
int n = 3;
float a[] = {8.0, -1.0, -5.0,
-4.0, 4.0, -2.0,
18.0, -5.0, -7.0};
f_complex *eval;
/* Compute eigenvalues of A */
eval = imsl_f_eig_gen (n, a, 0);
/* Print eigenvalues */
imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0);
}


and the output on the screen (with some pretty formatting from
imsl_c_write_matrix) is:

Eigenvalues
1 2 3
( 2, 4) ( 2, -4) ( 1, 0)

Here, the first eigenvalue is 2 + 4i, the second one is 2 -4i and so
on. I found that f_complex (used in the line f_complex *eval) is
defined as follows:

typedef struct{
float re;
float im;
} f_complex;

and f_complex is for single-precision complex values (d_complex exists
for double-precision).

I have never worked with structures before and after some
"cursing" :), I could access the individual elements as follows:

printf(" %g\n", eval[0].re) will give me the real part of the first
eigenvalue i.e. 2.

What would the best way to interface this with Ada? The elements of my
matrix will be formed in Ada, then the matrix will be passed to C to
calculate the eigenvalues and then the latter passed back to Ada. The
size of my matrix will be fixed say 3 x 3. As a novice in Ada, I would
like to learn good programming practice and the best way is to use
codes and learn from experts here in Ada.

Thanks for your very kind help.
YC
From: Dmitry A. Kazakov on
On Sun, 25 Jul 2010 05:21:44 -0700 (PDT), Ada novice wrote:

> What would the best way to interface this with Ada? The elements of my
> matrix will be formed in Ada, then the matrix will be passed to C to
> calculate the eigenvalues and then the latter passed back to Ada. The
> size of my matrix will be fixed say 3 x 3. As a novice in Ada, I would
> like to learn good programming practice and the best way is to use
> codes and learn from experts here in Ada.

Something like (not tested):

with Interfaces.C; use Interfaces.C;
package IMSL is
type Float_Matrix is -- Row-wise, packed/aligned
array (Positive range <>, Positive range <>) of C_Float;
pragma Convention (C, Float_Matrix);
type F_Complex is record
Re : C_Float;
Im : C_Float;
end record;
pragma Convention (C, F_Complex);
type Complex_Array is array (Positive range <>) of F_Complex;
pragma Convention (C, Complex_Array);

function F_Eig_Gen (Matrix : Float_Matrix) return Complex_Array;
end IMSL;

package body IMSL is
procedure Free (Ptr : System.Address);
pragma Import (C, Free, "free");

function F_Eig_Gen (Matrix : Float_Matrix) return Complex_Array is
begin
if Matrix'Length (1) /= Matrix'Length (2) then
raise Constraint_Error;
end if;
declare -- No idea, how they report convergence/accuracy errors
function Internal (N : Int; A : Address; Terminator : Address :=
Null_Address) return Address;
pragma Import (C, Internal, "imsl_f_eig_gen");
Ptr : Address := Internal
( Matrix'Length (1),
Matrix ( Matrix'First (1),
Matrix'First (2)
)' Address
);
Data : Complex_Array (1..Matrix'Length (1));
for Data'Address use Ptr;
pragma Import (Ada, Data);
Result : Complex_Array := Data; -- Copy, we don't own that memory
begin
Free (Ptr);
return Result;
end;
end F_Eig_Gen;
end IMSL;

Used as:

Values : Complex_Array :=
F_Eig_Gen
( ( ( 8.0,-1.0,-5.0),
(-4.0, 4.0,-2.0),
(18.0,-5.0,-7.0) )
);

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Ada novice on
Thanks a lot. On compilation I get:


1. package body IMSL is
2. procedure Free (
3. Ptr : System.Address);
|
>>> "System" is not visible
>>> non-visible declaration at system.ads:40

4. pragma Import (C, Free, "free");
5.
6. function F_Eig_Gen (
7. Matrix : Float_Matrix)
8. return Complex_Array is
9. begin
10. if Matrix'Length (1) /= Matrix'Length (2) then
11. raise Constraint_Error;
12. end if;
13. declare -- No idea, how they report convergence/accuracy
errors
14. function Internal (
|
>>> missing body for "Internal"

15. N : Int;
16. A : Address;
|
>>> "Address" is not visible (more references follow)
>>> non-visible declaration at system.ads:67

17. Terminator : Address := Null_Address)
|
>>> "Null_Address" is not visible
>>> non-visible declaration at system.ads:69

18. return Address;
19. pragma Import (C, Internal, "imsl_f_eig_gen");
20. Ptr : Address :=
Internal (Matrix'Length
21. (1), Matrix (Matrix'First (1), Matrix'First
(2))'Address);
22. Data : Complex_Array (1 .. Matrix'Length (1));
23. for Data'Address use Ptr;
24. pragma Import (Ada, Data);
25. Result : Complex_Array := Data; -- Copy, we
don't own that memory
26. begin
27. Free (Ptr);
28. return Result;
29. end;
30. end F_Eig_Gen;
31. end IMSL;

Compiling: c:/docume~1/testing/imsl.ads (source file time stamp:
2010-07-25 14:00:52)

1. with Interfaces.C;
2. use Interfaces.C;
3. package IMSL is
4. type Float_Matrix is -- Row-wise, packed/aligned
5. array (Positive range <>, Positive range <>) of C_Float;
6. pragma Convention (C, Float_Matrix);
7. type F_Complex is
8. record
9. Re : C_Float;
10. Im : C_Float;
11. end record;
12. pragma Convention (C, F_Complex);
13. type Complex_Array is array (Positive range <>) of
F_Complex;
14. pragma Convention (C, Complex_Array);
15.
16. function F_Eig_Gen (
17. Matrix : Float_Matrix)
18. return Complex_Array;
19. end IMSL;

31 lines: 7 errors


And what do I need on the C side?

Thanks
YC



First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13
Prev: Dhrystone
Next: Learning Ada