comp.lang.ada
 help / color / mirror / Atom feed
From: Leo Brewin <leo.brewin@internode.on.net>
Subject: Re: Interfaces.C questions
Date: Mon, 20 Mar 2017 02:44:31 -0700 (PDT)
Date: 2017-03-20T02:44:31-07:00	[thread overview]
Message-ID: <21267181-1df2-4471-a5ed-249153af5987@googlegroups.com> (raw)
In-Reply-To: <ej7b6vF1rdnU1@mid.individual.net>

Hi Frank,

Many thanks for sharing that code. I've wanted to play with GSL for a while but couldn't make sense of the C parameters and how to connect them back to Ada. Thanks again.

Cheers,
Leo

On Sunday, March 19, 2017 at 11:17:37 PM UTC+11, hreba wrote:
> 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

  reply	other threads:[~2017-03-20  9:44 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
2017-03-20  9:44     ` Leo Brewin [this message]
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