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
next prev parent 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