From: hreba <f_hreba@yahoo.com.br>
Subject: Re: Interfaces.C questions
Date: Sun, 19 Mar 2017 13:17:35 +0100
Date: 2017-03-19T13:17:35+01:00 [thread overview]
Message-ID: <ej7b6vF1rdnU1@mid.individual.net> (raw)
In-Reply-To: <403f77a2-992e-45b1-8f5d-a97143783130@googlegroups.com>
On 03/19/2017 12:24 AM, Leo Brewin wrote:
> Hi Frank,
>
> I'd be really interested to see a minimal working example once you've got it running.
> I'd like to be able to use GSL in my own codes.
>
> Cheers,
> Leo
>
Ok, below follows my first working example, numerical quadrature. Any
critics is welcome. Some remarks:
'void * params' in C can be a pointer to just anything, a number, an
array, a record. The best solution probably would be a generic package
where the actual type is passed as parameter (see type Element in
Interfaces.C.Pointers). The quadrature algorithm I chose makes no use of
these parameters, so in my example I translate the type to 'access all
Integer' and pass null as value.
As I am beginning to build a numerics library, I will now
- make the package generic, with 2 type parameters, one for the reals
(digits <>) and one for the parameters (private),
- write wrappers so that the client needs no Interfaces.C, and that he
can pass a function of
'type Real_Function is access function (x: Real) return Real;'
to the quadrature procedure instead of a record.
So here comes my example. The interface package is (no body):
-----------------------------------------------------------------------
with Interfaces.C;
package GSL is
package C renames Interfaces.C;
type Void_Ptr is access all Integer;
type GSL_Function_Ptr is access
function (x: C.double; params: Void_Ptr) return C.double;
type GSL_Function is record
func: GSL_Function_Ptr;
params: Void_Ptr;
end record;
function Integration_QNG
(f: access GSL_Function;
a, b, epsabs, epsrel: C.double;
result, abserr: out C.double;
neval: out C.size_t)
return C.int;
private
pragma Import (C, Integration_QNG, "gsl_integration_qng");
pragma Convention (C, Void_Ptr);
pragma Convention (C, GSL_Function_Ptr);
pragma Convention (C, GSL_Function);
end GSL;
-----------------------------------------------------------------------------
The main subprogram (client) is
-----------------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with GSL;
with Integ_Aux;
procedure Test_Integration
is
use type GSL.C.double;
a: GSL.C.double;
abserr: GSL.C.double;
neval: GSL.C.size_t;
res: GSL.C.int;
gslf: aliased GSL.GSL_Function;
begin
gslf.func:= Integ_Aux.Circle'Access;
gslf.params:= null;
res:= GSL.Integration_QNG
(gslf'Access, 0.0, 1.0, 0.001, 0.001, a, abserr, neval);
Put_Line("4*int_0^1 sqrt(1-x^2) dx = " & GSL.C.double'Image(4.0*a));
Put_Line(GSL.C.size_t'Image(neval) & " function evaluations, " &
GSL.C.double'Image(abserr) & " abs. error");
end Test_Integration;
------------------------------------------------------------------------------
Because an access is passed to the function to be integrated it has to
be in a separated package:
------------------------------------------------------------------------------
with GSL;
package Integ_Aux is
function Circle (x: GSL.C.double; pars: GSL.Void_Ptr) return
GSL.C.double;
private
pragma Convention (C, Circle);
end Integ_Aux;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
with Ada.Numerics.Generic_Elementary_Functions;
with GSL;
package body Integ_Aux is
package Functions is new
Ada.Numerics.Generic_Elementary_Functions (GSL.C.double);
function Circle (x: GSL.C.double; pars: GSL.Void_Ptr) return
GSL.C.double is
use type GSL.C.double;
begin return Functions.Sqrt(abs(1.0-x*x));
end Circle;
end Integ_Aux;
--------------------------------------------------------------------------------
The project files of the interface package are
--------------------------------------------------------------------------------
-- External library "Gnu Scientific Library"
with "gslcblas";
Project GSL is
type OS_Type is ("linux", "linux-gnu", "windows", "unknown");
act_os: OS_Type:= external ("OSTYPE");
-- act_os: OS_Type:= external ("OS_TYPE");
For externally_built use "true";
For library_dir use "/usr/lib";
case act_os is
when "linux"|"linux-gnu" => for library_dir use "/usr/lib";
when "windows" => for library_dir use "/Lib/GSL";
when "unknown" => for Source_Dirs use ("/"); -- just anything
end case;
For library_name use "gsl";
For source_dirs use (); -- no sources.
-- For library_kind use "static";
-- if it is a static lib .a
for library_kind use "dynamic";
-- if it is an so.
end GSL;
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-- External library "Gnu Scientific Library"
Project GSLCBLAS is
type OS_Type is ("linux", "linux-gnu", "windows", "unknown");
act_os: OS_Type:= external ("OSTYPE");
-- act_os: OS_Type:= external ("OS_TYPE");
For externally_built use "true";
case act_os is
when "linux"|"linux-gnu" => for library_dir use "/usr/lib";
when "windows" => for library_dir use "/Lib/GSL";
when "unknown" => for Source_Dirs use ("/"); -- just anything
end case;
For library_name use "gslcblas";
For source_dirs use (); -- no sources.
-- For library_kind use "static";
-- if it is a static lib .a
for library_kind use "dynamic";
-- if it is an so.
end GSLCBLAS;
-----------------------------------------------------------------------------
I tried to make these projects platform independent (Linux and Windows
so far); only tested on Linux so far. The environment variable OSTYPE
must exist. If you don't want to do this, just type
for library_dir use "/usr/lib";
instead of the 'case' construct (on Linux).
Finally the project file for the main program:
-----------------------------------------------------------------------------
with "../../gsl.gpr";
project Test_Integration is
for Source_Dirs use (".", "../../src"); -- test and interface sources
for Object_Dir use "../obj";
for Exec_Dir use ".";
for Main use ("test_integration.adb");
package Compiler is
for Default_Switches ("ada") use ("-g", "-gnatf", "-gnat2012");
end Compiler;
package Linker is
for Default_Switches ("ada") use ("-g");
end Linker;
package Builder is
for Default_Switches ("ada") use ("-g");
end Builder;
end Test_Integration;
------------------------------------------------------------------------------
The result is an approximation of the unit circle area, pi.
--
Frank Hrebabetzky +49 / 6355 / 989 5070
next prev parent reply other threads:[~2017-03-19 12:17 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-17 21:12 Interfaces.C questions hreba
2017-03-17 21:57 ` Niklas Holsti
2017-03-17 22:14 ` Jeffrey R. Carter
2017-03-17 22:24 ` Dmitry A. Kazakov
2017-03-21 21:08 ` Michael B.
2017-03-21 21:28 ` Dmitry A. Kazakov
2017-03-21 21:31 ` Simon Wright
2017-03-22 20:35 ` Randy Brukardt
2017-03-18 15:46 ` hreba
2017-03-18 16:26 ` Jeffrey R. Carter
2017-03-18 16:27 ` Jeffrey R. Carter
2017-03-19 7:03 ` Keith Thompson
2017-03-18 23:24 ` Leo Brewin
2017-03-19 12:17 ` hreba [this message]
2017-03-20 9:44 ` Leo Brewin
2017-03-19 7:00 ` Keith Thompson
2017-03-19 12:05 ` Per Sandberg
2017-03-19 18:39 ` hreba
2017-03-19 19:22 ` Simon Wright
2017-03-19 19:49 ` hreba
2017-03-19 23:53 ` Simon Wright
2017-03-20 11:12 ` hreba
2017-03-20 14:04 ` hreba
2017-03-22 11:21 ` hreba
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox