From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.3 required=5.0 tests=AWL,HTML_MESSAGE,NO_REAL_NAME, SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 32CBABC0A for ; Tue, 5 Jun 2007 11:33:36 +0200 (CEST) Received: from parmail02.sgcib.com (parmail02.sgcib.com [207.45.250.34]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l559XYRH007934 for ; Tue, 5 Jun 2007 11:33:35 +0200 X-IronPort-AV: i="4.16,385,1175464800"; d="scan'208,217"; a="197575200:sNHT113732844" Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C7A754.9160D6C3" X-MimeOLE: Produced By Microsoft Exchange V6.5.7226.0 Subject: RE: [Caml-list] nonlinear fit function binding Date: Tue, 5 Jun 2007 11:33:26 +0200 Message-ID: <33A2A7CA4E6BCB458E4F0A508A4DDDFC435686@FRDEF-EXMB03.europe.am.socgen> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: [Caml-list] nonlinear fit function binding Thread-Index: AcemfDUyWYKKlIh0SyWm/lRIcibGmAA04ZPg From: To: , X-OriginalArrivalTime: 05 Jun 2007 09:33:30.0198 (UTC) FILETIME=[93CAC760:01C7A754] X-NAI-Spam-Score: -0.3 X-j-chkmail-Score: MSGID : 46652DEE.001 on concorde : j-chkmail score : X : 0/20 1 0.000 -> 1 X-Miltered: at concorde with ID 46652DEE.001 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; bigarrays:01 pointer:01 gsl:01 bigarrays:01 gsl:01 matrices:01 bigarray:01 elt:01 elt:01 bool:01 bytecode:01 bytecode:01 computes:01 bigarray:01 val:01 This is a multi-part message in MIME format. ------_=_NextPart_001_01C7A754.9160D6C3 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Bigarrays, in my understanding are essentially c structure, with a pointer = to date, reference of usages, ... It is very similar to the gsl vector matrix structure. =20 You can look at the ocamlgsl binding to see how easily bigarrays are transf= ormed into gsl vector and matrices. =20 To illustrate my answier, I will try to be more specific, and give some c c= ode snapshots. =20 Let's says you have your library function called minimizer(...,array1, ...) =20 array1 is a c double array. =20 Your goal is to create a c function called caml_wrap_minimizer, which will = be called from CAML. =20 This function will take into argument the function f to minimize, the initi= al starting point, constraints, target point, ... =20 View from caml, the minimize function have a signature like (including levm= ar definitions) =20 =20 =20 (************************************ wrapper.ml **************************= ******************) open Bigarray type float_vector =3D (float, float64_elt, c_layout) Array1.t=20 type float_matrix =3D (float, float64_elt, c_layout) Array2.t=20 =20 type stopping=3D |Small_Grandient |Small_Dp |Stop_Itmax |Matrix_Singular |Error_Reduction_Saturated |Small_e_2 =20 type calibrationInfo=3D {initial_e_2:float; stopping_e_2:float; stopping_J_T_e_inf:float; stopping_Dp_2:float; stopping_max_J_T_J:float; iterations:int; stopping_reason:stopping; function_evaluation:int; jacobian_evalutaion:int;} =20 external workspace_size: ?m:int -> ?n:int -> ?analyticJacobian:bool -> int = =3D "workspace_size" =20 (** gneral minimization *) external dlevmar_der: ?tau:float -> ?epsilon1:float -> ?epsilon2:float -> ?epsilon3:float -> ?f:(float_vector -> float_vector -> unit) -> ?j:(float_vector -> float_matrix ->unit) -> ?p:float_vector -> ?x:float_vector -> ?itmax:int -> ?work:float_vector -> ?covar:float_matrix -> calibrationInfo =3D "dlevmar_der_bytecode" "dlevmar_der_native" =20 =20 external dlevmar_dif: ?tau:float -> ?epsilon1:float -> ?epsilon2:float -> ?epsilon3:float -> ?delta:float -> ?f:(float_vector -> float_vector -> unit) -> ?p:float_vector -> ?x:float_vector -> ?itmax:int -> ?work:float_vector -> ?covar:float_matrix -> ?tempp:float_vector -> ?tempx:float_vector -> calibrationInfo =3D "dlevmar_dif_bytecode" "dlevmar_dif_native" =20 (************************************ wrapper.ml **************************= ******************) =20 f is the function that computes x =3D f(p) and our goal is starting from p, find the point p* verifying f(p*)=3Dx =20 In case we know the jacobian analytically, the jacobian function j is passe= d=2E If not, we have to use numerical jacobian computation. =20 What you have to keep in mind is that the vector p will be modified in memo= ry by the c function. =20 I will emphasize a bit more the c code. =20 =20 (************************************ wrapper.c ***************************= *****************) =20 static double *Vdata(value v) { return Bigarray_val(v)->data; } =20 static value fg; /* : vector -> vector -> unit */ static double * ctempp, * ctempx; static value tempp; static value tempx; =20 =20 static void wrap_f_dif1(double *p, double *hx, int m, int n, void *adata) { memcpy(Vdata(tempp),p,m*sizeof(double)); callback2(fg,tempp,tempx); memcpy(hx,Vdata(tempx),n*sizeof(double)); =20 } =20 CAMLprim value dlevmar_dif_native(value tau, value epsilon1, value epsilon2= , value epsilon3, value delta, value f, value p, value x, value itmax,=20 value work, value covar, value temp_p, va= lue temp_x) { double info[LM_INFO_SZ]; double opts[LM_OPTS_SZ]; CAMLparam5(tau,epsilon1,epsilon2,epsilon3,f); CAMLxparam5(p,x,itmax,covar,work); CAMLxparam3(temp_p,temp_x,delta); CAMLlocal1(res); int n; int m; =20 double *cp; double *cfvec; double *ccovar; double *cwork; int citmax; int ret; =20 =20 fg =3D Field(f,0); caml_register_global_root(&fg); =20 tempp =3D Field(temp_p,0); ctempp =3D Vdata(tempp); =20 tempx =3D Field(temp_x,0); ctempx =3D Vdata(tempx); =20 =20 caml_register_global_root(&tempp); caml_register_global_root(&tempx); =20 =20 =20 ret =3D dlevmar_dif( &wrap_f_dif1,... =20 caml_remove_global_root(&tempp); caml_remove_global_root(&tempx);=20 caml_remove_global_root(&fg); =20 } (************************************ wrapper.c ***************************= *****************) =20 =20 When you look thoroughly to the wrap_f_dif1 function, you get a clear under= standing of what I am trying to do. After having registered f, temp and tempw passed from caml as global_roots,= when I have to call my caml function for minimization, i copy the c pointe= rs of my c function to the bigarray structure behind temp and tempx, and do= a callback2 to have the function computed in the caml world. =20 Hope this helps. =20 Rabih ________________________________ De : caml-list-bounces@yquem.inria.fr [mailto:caml-list-bounces@yquem.inria= .fr] De la part de Matthieu Dubuget Envoy=E9 : lundi 4 juin 2007 09:38 =C0 : caml-list@inria.fr Objet : Re: [Caml-list] nonlinear fit function binding =20 Thanks for your reply, Rabih. 2007/5/31, RABIH.ELCHAAR@sgam.com :=20 I did a wrapping of the levmar library. Unfortunately, since I am to use this in a commercial product, and I was no= t able (yet ?) to convince my boss to release the sources, I can't use with= levmar, wich is GPLed... I may switch to cminpack. But i think this is not= related to my current question.=20 =20 The approach I chose is to allocate bigarrays from Caml, and pass them to = the main C function, along with the function f. Does it mean that each time f function is called by the minimization, the C= wrappers has to copy the params C array into your Bigarray pre-allocated s= torage place? That's why I choosed to leave the C array untouched and wrap = a Bigarray around it (should not be a big amount of memory). Am I wrong in= going this way?=20 =20 In the main function, I register f and all the bigarrays as global roots, = and then call as many times the c sub function to compute the minimization. =20 I do not understand this part. f is passed to the main (C) function from OC= aml: why do you need to register it as a global root? Same question for the= Bigarrays? Does it mean that else, nothing in OCaml world would point to t= hem? =20 Feel free to ask for more precisions if needed Hope this helps. Surely. I really need to acquire a better understanding of GC and C interfa= ce in OCaml.=20 Really, I do not understand what happens to those C allocated Bigarrays... Salutations Matthieu =20 Ce message et toutes les pieces jointes (ci-apres le "message") sont confid= entiels et etablis a l'intention exclusive de ses destinataires.=20 Toute utilisation ou diffusion non autorisee est interdite.=20 Tout message electronique est susceptible d'alteration.=20 Societe Generale Asset Management et ses filiales declinent toute responsab= ilite au titre de ce message s'il a ete altere, deforme ou falsifie.=20 =20 Decouvrez l'offre et les services de Societe Generale Asset Management sur = le site www.sgam.fr=20 =20 ********=20 =20 This message and any attachments (the "message") are confidential and inten= ded solely for the addressees.=20 Any unauthorised use or dissemination is prohibited.=20 E-mails are susceptible to alteration.=20 Neither Societe Generale Asset Management nor any of its subsidiaries or af= filiates shall be liable for the message if altered, changed or falsified.=20 =20 Find out more about Societe Generale Asset Management's proposal on www.sga= m=2Ecom ------_=_NextPart_001_01C7A754.9160D6C3 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable

Bigarrays, in my understanding are essentially c structure, with a pointer to date, referenc= e of usages, …

It is very similar = to the gsl vector matrix structure.

 

You can look at the ocamlgsl binding to see how easily bigarrays are transformed into gsl vector and matrices.

 

To illustrate my an= swier, I will try to be more specific, and give some c code snapshots.<= /span>

 

Let’s says yo= u have your library function called minimizer(…,array1, …)<= /span>

 

array1 is a c double array.

 

Your goal is to cre= ate a c function called caml_wrap_minimizer, which will be called from CAML.=

 

This function will = take into argument the function f to minimize, the initial starting point, constraints, target point, …

 

View from caml, the minimize function have a signature like (including levmar definitions)=

 

 

 

(******************= ****************** wrapper.ml ********************************************)<= /font>

open Bigarray<= /o:p>

type float_vector = =3D (float, float64_elt, c_layout) Array1.t

type float_matrix = =3D (float, float64_elt, c_layout) Array2.t

 

type stopping=3D

=A0 |Small_Grandien= t

=A0 |Small_Dp<= /o:p>

=A0 |Stop_Itmax

=A0 |Matrix_Singula= r

=A0 |Error_Reductio= n_Saturated

=A0 |Small_e_2=

 

type calibrationInf= o=3D

=A0=A0=A0 {initial_= e_2:float;

=A0=A0=A0=A0 stoppi= ng_e_2:float;

=A0=A0=A0=A0 stopping_J_T_e_inf:float;

=A0=A0=A0=A0 stopping_Dp_2:float;=

=A0=A0=A0=A0 stoppi= ng_max_J_T_J:float;

=A0=A0=A0=A0 iterat= ions:int;

=A0=A0=A0=A0 stoppi= ng_reason:stopping;

=A0=A0=A0=A0 functi= on_evaluation:int;

=A0=A0=A0=A0 jacobi= an_evalutaion:int;}

 

external workspace_= size: ?m:int -> ?n:int -> ?analyticJacobian:bool -> int =3D

=A0 "workspace= _size"

 

(** gneral minimiza= tion *)

external dlevmar_de= r: ?tau:float -> ?epsilon1:float -> ?epsilon2:float -><= /p>

=A0 ?epsilon3:float= ->

=A0=A0=A0 ?f:(float= _vector -> float_vector -> unit) ->

=A0=A0=A0=A0=A0 ?j:= (float_vector -> float_matrix ->unit) ->

=A0=A0=A0=A0=A0=A0= =A0 ?p:float_vector -> ?x:float_vector -> ?itmax:int ->

=A0=A0=A0=A0=A0=A0= =A0=A0=A0 ?work:float_vector -> ?covar:float_matrix -> calibrationInfo =3D

=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 "dlevmar_der_bytecode" "dlevmar_der_native= "

 

 

external dlevmar_di= f: ?tau:float -> ?epsilon1:float -> ?epsilon2:float -><= /p>

=A0 ?epsilon3:float= -> ?delta:float ->

=A0=A0=A0 ?f:(float_vector -> float_vector -> uni= t) ->

=A0=A0=A0=A0=A0 ?p:= float_vector -> ?x:float_vector -> ?itmax:int ->

=A0=A0=A0=A0=A0=A0= =A0 ?work:float_vector -> ?covar:float_matrix ->

=A0=A0=A0=A0=A0=A0= =A0=A0=A0 ?tempp:float_vector -> ?tempx:float_vector -> calibrationInfo =3D

=A0=A0=A0=A0=A0=A0= =A0=A0=A0 "dlevmar_dif_bytecode" "dlevmar_dif_native= "

 

(******************= ****************** wrapper.ml ********************************************)<= /font>

 

f is the function that computes x =3D f(p) and ou= r goal is

starting from p, find the point p* verifying=

f(p*)=3Dx

 

In case we know the jacobian analytically, the jacobian function j is passed.

If not, we have to use numerical jacobian computa= tion.

 

What you have to keep in mind is that the vector p will be modified in memory by the c function.

 

I will emphasize a bit more the c code.

 

 

(******************= ****************** wrapper.c ********************************************)

 

static double *Vdat= a(value =A0v)

{=

=A0=A0=A0 return Bi= garray_val(v)->data;

}=

 

static value fg; /*= : vector -> vector -> unit */

static double * cte= mpp, * ctempx;

static value tempp;=

static value tempx;=

 

 

static void wrap_f_= dif1(double *p, double *hx, int m, int n, void *adata)

{=

=A0=A0memcpy(Vdata(= tempp),p,m*sizeof(double));

=A0 callback2(fg,te= mpp,tempx);

=A0 memcpy(hx,Vdata= (tempx),n*sizeof(double));

=A0

}=

 

CAMLprim value dlev= mar_dif_native(value tau, value epsilon1, value epsilon2, value epsilon3, value delta,

=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 value f, value p, value x, value itmax,

=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 value work, value covar, value temp_p, value temp_x)

{=

=A0 double info[LM_= INFO_SZ];

=A0 double opts[LM_= OPTS_SZ];

=A0 CAMLparam5(tau,= epsilon1,epsilon2,epsilon3,f);

=A0 CAMLxparam5(p,x= ,itmax,covar,work);

=A0 CAMLxparam3(tem= p_p,temp_x,delta);

=A0 CAMLlocal1(res)= ;

=A0 <= font size=3D2 color=3Dnavy face=3DArial>int n;

=A0 int m;

=A0

=A0 double *cp;

=A0 double *cfvec;

=A0 double *ccovar;<= /font>

=A0 double *cwork;

=A0 int citmax;

=A0 int ret;

 

 

=A0 fg =3D Field(f,= 0);

=A0 caml_register_g= lobal_root(&fg);

 

=A0 tempp =3D Field= (temp_p,0);

=A0 ctempp =3D Vdat= a(tempp);

 

=A0 tempx =3D Field= (temp_x,0);

=A0 ctempx =3D Vdat= a(tempx);

 

 

=A0 caml_register_g= lobal_root(&tempp);

=A0 caml_register_g= lobal_root(&tempx);

 

=A0

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'> =

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'>=A0 ret =3D dlevmar_dif(=

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'>=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 &wrap_f_dif1,…

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'>=A0

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'>=A0 caml_remove_global_r= oot(&tempp);

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'>=A0 caml_remove_global_r= oot(&tempx);

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'>=A0 caml_remove_global_r= oot(&fg);

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'> =

<= span lang=3DEN-GB style=3D'font-size:12.0pt;color:navy'>}

(******************= ****************** wrapper.c ********************************************)

 

 

When you look thoroughly to the wrap_f_dif1 func= tion, you get a clear understanding of what I am trying to do.

After having registered f, temp and tempw passed= from caml as global_roots, when I have to call my caml function for minimization= , i copy the c pointers of my c function to the bigarray structure behind temp = and tempx, and do a callback2 to have the function computed in the caml world.<= o:p>

 

Hope this helps.

 

Rabih


De : caml-list-bounces@yquem.inria.fr [mailto:caml-list-bounces@yquem.inria.fr] = De la part de Matthieu Dubuget
Envoy=E9 : lundi 4 juin= 2007 09:38
=C0 : caml-list@inria.f= r
Objet : Re: [Caml-list] nonlinear fit function binding

 

Thanks for your r= eply, Rabih.

2007/5/31, RABIH.ELCHAAR@sgam.com <RABIH.ELCHAAR@sgam.com>= ;:

I did a wrapping of the levmar library.


Unfortunately, since I am to use this in a commercial product, and I was not able (yet ?) to convince my boss to release the sources, I can't use with levmar, wich is GPLed... I may switch to cminpack. But i think this is not related to my current question.

 

The approach I chose is to allocate bigarrays from Caml, and pass them to the main C function, along with the function f.=

Does it mean that each time f function is called by the minimizatio= n, the C wrappers has to copy the params C array into your Bigarray pre-alloca= ted storage place? That's why I choosed to leave the C array untouched and wrap= a Bigarray around it  (should not be a big amount of memory). Am I wrong= in going this way?

 

In the main functio= n, I register f and all the bigarrays as global roots, and then call as many tim= es the c sub function to compute the minimization.

 

I do not understand this part. f is passed to the main (C) function from OCaml: why do you need to register it as a global root? Same question = for the Bigarrays? Does it mean that else, nothing in OCaml world would point to them?  

Feel free to ask for more precisions if neede= d

Hope this helps.

Surely. I really need to acquire a better understanding of GC and C interface in OCaml.
Really, I do not understand what happens to those C allocated Bigarrays...<= br>
Salutations

Matthieu

 

Ce message et toutes les pieces jointes (ci-apres le "message") sont c=
onfidentiels et etablis a l'intention exclusive de ses destinataires.=20
Toute utilisation ou diffusion non autorisee est interdite.=20
Tout message electronique est susceptible d'alteration.=20
Societe Generale Asset Management et ses filiales declinent toute responsab=
ilite au titre de ce message s'il a ete altere, deforme ou falsifie.=20
 =20
Decouvrez l'offre et les services de Societe Generale Asset Management sur =
le site www.sgam.fr=20
 =20
                                ********=20
 =20
This message and any attachments (the "message") are confidential and inten=
ded solely for the addressees.=20
Any unauthorised use or dissemination is prohibited.=20
E-mails are susceptible to alteration.=20
Neither Societe Generale Asset Management nor any of its subsidiaries or af=
filiates shall be liable for the message if altered, changed or falsified.=20
=20
Find out more about Societe Generale Asset Management's proposal on www.sga=
m=2Ecom
------_=_NextPart_001_01C7A754.9160D6C3--