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.4 required=5.0 tests=AWL,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 discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id B41D0BC0A for ; Tue, 5 Jun 2007 11:56:19 +0200 (CEST) Received: from parmail02.sgcib.com (parmail02.sgcib.com [207.45.250.34]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l559uG8k030544 for ; Tue, 5 Jun 2007 11:56:19 +0200 X-IronPort-AV: i="4.16,385,1175464800"; d="scan'208"; a="197582995:sNHT36607628" Content-class: urn:content-classes:message MIME-Version: 1.0 X-MimeOLE: Produced By Microsoft Exchange V6.5.7226.0 Subject: RE: [Caml-list] nonlinear fit function binding Date: Tue, 5 Jun 2007 11:44:46 +0200 Message-ID: <33A2A7CA4E6BCB458E4F0A508A4DDDFC435687@FRDEF-EXMB03.europe.am.socgen> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: [Caml-list] nonlinear fit function binding Thread-Index: AcemfDUyWYKKlIh0SyWm/lRIcibGmAA04ZPgAAFE7vA= From: To: , X-OriginalArrivalTime: 05 Jun 2007 09:45:47.0442 (UTC) FILETIME=[4B394920:01C7A756] X-NAI-Spam-Score: -1.2 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Miltered: at discorde with ID 46653340.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 Bigarrays, in my understanding are essentially c structure, with a pointer = to data, reference 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 transf= ormed into gsl vector and matrices. To illustrate my answier, I will try to be more specific, and give some c c= ode snapshots. Let's says you have your library function called minimizer(...,array1, ...) array1 is a c double array. Your goal is to create 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 initi= al starting point, constraints, target point, ... View from caml, the minimize function have a signature like (including levm= ar definitions) (************************************ 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 type stopping=3D =A0 |Small_Grandient =A0 |Small_Dp =A0 |Stop_Itmax =A0 |Matrix_Singular =A0 |Error_Reduction_Saturated =A0 |Small_e_2 type calibrationInfo=3D =A0=A0=A0 {initial_e_2:float; =A0=A0=A0=A0 stopping_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 stopping_max_J_T_J:float; =A0=A0=A0=A0 iterations:int; =A0=A0=A0=A0 stopping_reason:stopping; =A0=A0=A0=A0 function_evaluation:int; =A0=A0=A0=A0 jacobian_evalutaion:int;} external workspace_size: ?m:int -> ?n:int -> ?analyticJacobian:bool -> int = =3D =A0 "workspace_size" (** gneral minimization *) external dlevmar_der: ?tau:float -> ?epsilon1:float -> ?epsilon2:float -> =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 -> ca= librationInfo =3D =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "dlevmar_der_bytecode" "dlevmar_der_nativ= e" external dlevmar_dif: ?tau:float -> ?epsilon1:float -> ?epsilon2:float -> =A0 ?epsilon3:float -> ?delta:float -> =A0=A0=A0 ?f:(float_vector -> float_vector -> unit) -> =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 -> c= alibrationInfo =3D =A0=A0=A0=A0=A0=A0=A0=A0=A0 "dlevmar_dif_bytecode" "dlevmar_dif_native" (************************************ wrapper.ml **************************= ******************) 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 In case we know the jacobian analytically, the jacobian function j is passe= d=2E If not, we have to use numerical jacobian computation. What you have to keep in mind is that the vector p will be modified in memo= ry by the c function. I will emphasize a bit more the c code. (************************************ wrapper.c ***************************= *****************) static double *Vdata(value =A0v) { =A0=A0=A0 return Bigarray_val(v)->data; } static value fg; /* : vector -> vector -> unit */ static double * ctempp, * 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,tempp,tempx); =A0 memcpy(hx,Vdata(tempx),n*sizeof(double)); } CAMLprim value dlevmar_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,=20 =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(temp_p,temp_x,delta); =A0 CAMLlocal1(res); =A0 int n; =A0 int m; =A0=20 =A0 double *cp; =A0 double *cfvec; =A0 double *ccovar; =A0 double *cwork; =A0 int citmax; =A0 int ret; =A0 fg =3D Field(f,0); =A0 caml_register_global_root(&fg); =A0 tempp =3D Field(temp_p,0); =A0 ctempp =3D Vdata(tempp); =A0 tempx =3D Field(temp_x,0); =A0 ctempx =3D Vdata(tempx); =A0 caml_register_global_root(&tempp); =A0 caml_register_global_root(&tempx); =A0 ... =A0 ret =3D dlevmar_dif( =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 &wrap_f_dif1,... =A0 =20 ... =A0 caml_remove_global_root(&tempp); =A0 caml_remove_global_root(&tempx);=20 =A0 caml_remove_global_root(&fg); } (************************************ wrapper.c ***************************= *****************) 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. Hope this helps. Rabih ________________________________________ De=A0: caml-list-bounces@yquem.inria.fr [mailto:caml-list-bounces@yquem.inr= ia.fr] De la part de Matthieu Dubuget Envoy=E9=A0: lundi 4 juin 2007 09:38 =C0=A0: caml-list@inria.fr Objet=A0: Re: [Caml-list] nonlinear fit function binding 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 The approach I chose is to allocate bigarrays from Caml, and pass them to t= he 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=A0 (should not be a big amount of memory). Am I wrong = in going this way?=20 In the main function, I register f and all the bigarrays as global roots, a= nd then call as many times the c sub function to compute the minimization. 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? =A0 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 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