Prev: Dhrystone
Next: Learning Ada
From: Simon Wright on 25 Jul 2010 04:29 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 25 Jul 2010 08:20 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 25 Jul 2010 08:21 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 25 Jul 2010 09:50 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 25 Jul 2010 10:12
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 |