123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506(* AUTOMATICALLY GENERATED from "fftw3SD.ml". *)#1 "fftw3SD.ml"(* File: fftw3SD.ml
Copyright (C) 2006-
Christophe Troestler <Christophe.Troestler@umons.ac.be>
WWW: https://math.umons.ac.be/anum/software/
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.1 or
later as published by the Free Software Foundation, with the special
exception on linking described in the file LICENSE.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
LICENSE for more details. *)(* FFTW3 interface for Single/Double precision *)openBigarrayopenFftw3_utilstypefloat_elt=Bigarray.float64_elttypecomplex_elt=Bigarray.complex64_eltletfloat=Bigarray.float64letcomplex=Bigarray.complex64type'afftw_plan(* single and double precision plans are different *)(* Types of plans *)typec2ctyper2ctypec2rtyper2rtypedir=Forward|Backwardtypemeasure=Estimate|Measure|Patient|Exhaustivetyper2r_kind=(* Keep the order in sync with fftw3.h and the test in
configure.ac (affects code in fftw3SD_stubs.c). *)|R2HC|HC2R|DHT|REDFT00|REDFT01|REDFT10|REDFT11|RODFT00|RODFT01|RODFT10|RODFT11exceptionFailureofstring(* Localizing the Failure exn *)letis_c_layoutm=(Genarray.layoutm=(Obj.magicc_layout:'alayout))(** External declarations
***********************************************************************)(* The types for Array1,... can be converted to this at no cost. *)type'lcomplex_array=(Complex.t,Bigarray.complex64_elt,'l)Genarray.ttype'lfloat_array=(float,Bigarray.float64_elt,'l)Genarray.t(* Execution of plans
***********************************************************************)externalfftw_exec:'afftw_plan->unit="fftw_ocaml_execute"[@@noalloc]externalexec_dft:c2cfftw_plan->'lcomplex_array->'lcomplex_array->unit="fftw_ocaml_execute_dft"[@@noalloc]externalexec_split_dft:c2cfftw_plan->'lfloat_array->'lfloat_array->'lfloat_array->'lfloat_array->unit="fftw_ocaml_execute_split_dft"[@@noalloc]externalexec_dft_r2c:r2cfftw_plan->'lfloat_array->'lcomplex_array->unit="fftw_ocaml_execute_dft_r2c"[@@noalloc]externalexec_split_dft_r2c:r2cfftw_plan->'lfloat_array->'lfloat_array->'lfloat_array->unit="fftw_ocaml_execute_split_dft_r2c"[@@noalloc]externalexec_dft_c2r:c2rfftw_plan->'lcomplex_array->'lfloat_array->unit="fftw_ocaml_execute_dft_c2r"[@@noalloc]externalexec_split_dft_c2r:c2rfftw_plan->'lfloat_array->'lfloat_array->'lfloat_array->unit="fftw_ocaml_execute_split_dft_c2r"[@@noalloc]externalexec_r2r:r2rfftw_plan->'lfloat_array->'lfloat_array->unit="fftw_ocaml_execute_r2r"[@@noalloc](* Creating plans
***********************************************************************)(* BEWARE: wrapper functions are just thin wrappers around their C
counterpart. In particular, their arguments must be thought for
the C layout. *)externalguru_dft:(* in *)'lcomplex_array->(* out *)'lcomplex_array->(* sign (forward/backward) *)int->(* flags (GOOD: they do not use the 32th bit) *)int->(* input offset ([in] as 1D array, C layout) *)int->(* output offset ([out] as 1D array, C layout) *)int->(* n (transform dimensions; its length = transform rank) *)intarray->(* istride (same length as [n]) *)intarray->(* ostride (same length as [n]) *)intarray->(* howmany (multiplicity dimensions; its length=howmany_rank) *)intarray->(* howmany input strides (same length as [howmany]) *)intarray->(* howmany output strides (same length as [howmany]) *)intarray->c2cfftw_plan="fftw_ocaml_guru_dft_bc""fftw_ocaml_guru_dft"(* Wrapper of fftw_plan_guru_dft. No coherence check is done in the
C code. @raise Failure if the plan cannot be created.
The [istride] and [ostride] parameters can be longer than [n]
without harm (but only the [Array.length n] first entries will be
used). The same applies for the "howmany" parameters. *)externalguru_r2c:(* in *)'lfloat_array->(* out *)'lcomplex_array->(* flags *)int->(* input offset *)int->(* output offset *)int->(* n (transform dimensions) *)intarray->(* istride (same length as [n]) *)intarray->(* ostride (same length as [n]) *)intarray->(* howmany (multiplicity dimensions) *)intarray->(* howmany input strides (same length as [howmany]) *)intarray->(* howmany output strides (same length as [howmany]) *)intarray->r2cfftw_plan="fftw_ocaml_guru_r2c_bc""fftw_ocaml_guru_r2c"externalguru_c2r:(* in *)'lcomplex_array->(* out *)'lfloat_array->(* flags *)int->(* input offset *)int->(* output offset *)int->(* n (transform LOGICAL dimensions) *)intarray->(* istride (same length as [n]) *)intarray->(* ostride (same length as [n]) *)intarray->(* howmany (multiplicity dimensions) *)intarray->(* howmany input strides (same length as [howmany]) *)intarray->(* howmany output strides (same length as [howmany]) *)intarray->c2rfftw_plan="fftw_ocaml_guru_c2r_bc""fftw_ocaml_guru_c2r"externalguru_r2r:(* in *)'lfloat_array->(* out *)'lfloat_array->(* kind (same length as [n]) *)r2r_kindarray->(* flags *)int->(* input offset *)int->(* output offset *)int->(* n (transform dimensions) *)intarray->(* istride (same length as [n]) *)intarray->(* ostride (same length as [n]) *)intarray->(* howmany (multiplicity dimensions) *)intarray->(* howmany input strides (same length as [howmany]) *)intarray->(* howmany output strides (same length as [howmany]) *)intarray->r2rfftw_plan="fftw_ocaml_guru_r2r_bc""fftw_ocaml_guru_r2r"(** Plans on the OCaml side
***********************************************************************)typegenarrayexternalgenarray:(_,_,_)Genarray.t->genarray="%identity"(* Since we want the FFT functions to be polymorphic in the layout of
the arrays, some black magic is unavoidable. This one way
conversion is actually safe, it is the use of [genarray] by C
functions that must be taken care of. *)type'aplan={plan:'afftw_plan;i:genarray;(* hold input array => not freed by GC before the plan *)offseto:int;(* output offset; C-stubs *)strideo:intarray;(* strides; C-stubs *)no:intarray;(* dimensions *)o:genarray;(* output array *)}letsign_of_dir=function|Forward->-1|Backward->1(* WARNING: keep in sync with fftw3.h *)letflagsmeasunaligned~destroy_input:int=letf=matchmeaswith|Measure->0(* 0U *)|Exhaustive->8(* 1U lsl 3 *)|Patient->32(* 1U lsl 5 *)|Estimate->64(* 1U lsl 6 *)inletf=ifunalignedthenflor2(* 1U lsl 1 *)elsefinifdestroy_inputthenflor1(* 1U lsl 0 *)elseflor16(* 1U lsl 4 *)(** {2 Execution of plans}
***********************************************************************)letexecp=fftw_execp.planmoduleGuru=structletdftplanio=(* how to check that the arrays conform to the plan specification? *)exec_dftplanioletsplit_dftplanriiiroio=(* again, how to check conformance with the plan? *)exec_split_dftplanriiiroioend(** {2 Creating plans}
***********************************************************************)moduleGenarray=structexternalcreate:('a,'b)Bigarray.kind->'cBigarray.layout->intarray->('a,'b,'c)Bigarray.Genarray.t="fftw3_ocaml_ba_create"type'lcomplex_array=(Complex.t,Bigarray.complex64_elt,'l)Genarray.ttype'lfloat_array=(float,Bigarray.float64_elt,'l)Genarray.ttypecoord=intarray(* Layout independent function *)letapplynamemk_planhm_nhmi?niofsiinciihmo?noofsoincoo~logical_dims=letmakeoffsetioffsetonstrideistrideohm_nihm_strideihm_strideo=letp=(mk_planoffsetioffsetonstrideistrideohm_nihm_strideihm_strideo)in{plan=p;i=genarrayi;offseto=offseto;strideo=strideo;no=n;(* LOGICAL dims FIXME: what we want? *)o=genarrayo;}in(ifis_c_layoutithenFftw3_geomC.applyelseFftw3_geomF.apply)namemakehm_nhmi?niofsiinciihmo?noofsoincoo~logical_dimsletdft_name="Fftw3.D.Genarray.dft"letdftdir?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?inci(i:'lcomplex_array)?(howmanyo=[])?no?ofso?inco(o:'lcomplex_array)=applydft_name~logical_dims:Geom.logical_c2c(guru_dftio(sign_of_dirdir)(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiinciihowmanyo?noofsoincoo(* At the moment, in place transforms are not possible but they may
be if OCaml bug 0004333 is resolved. *)letr2c_name="Fftw3.D.Genarray.r2c"letr2c?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?inci(i:'lfloat_array)?(howmanyo=[])?no?ofso?inco(o:'lcomplex_array)=applyr2c_name~logical_dims:Geom.logical_r2c(guru_r2cio(flagsmeasunaligned~destroy_input))howmany_nhowmanyiofsi?niinciihowmanyo?noofsoincooletc2r_name="Fftw3.D.Genarray.c2r"letc2r?(meas=Measure)?(destroy_input=true)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?inci(i:'lcomplex_array)?(howmanyo=[])?no?ofso?inco(o:'lfloat_array)=applyc2r_name~logical_dims:Geom.logical_c2r(guru_c2rio(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiinciihowmanyo?noofsoincooletr2r_name="Fftw3.D.Genarray.r2r"letr2rkind?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?inci(i:'lfloat_array)?(howmanyo=[])?no?ofso?inco(o:'lfloat_array)=(* FIXME: must check [kind] has the right length/order?? *)applyr2r_name~logical_dims:Geom.logical_r2r(guru_r2riokind(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiinciihowmanyo?noofsoincooendmoduleArray1=structexternalarray1_of_ba:('a,'b,'c)Bigarray.Genarray.t->('a,'b,'c)Array1.t="%identity"(* We know that the bigarray will have only 1D, convert without check *)letcreatekindlayoutdim=array1_of_ba(Genarray.createkindlayout[|dim|])letof_arraykindlayoutdata=letba=createkindlayout(Array.lengthdata)inletofs=iflayout=(Obj.magicc_layout:'alayout)then0else1infori=0toArray.lengthdata-1doba.{i+ofs}<-data.(i)done;batype'lcomplex_array=(Complex.t,Bigarray.complex64_elt,'l)Array1.ttype'lfloat_array=(float,Bigarray.float64_elt,'l)Array1.tletapplynamemake_planhm_nhmi?niofsiinciihmo?noofsoincoo~logical_dims=lethmi=List.map(funv->[|v|])hmiinletni=option_map(funn->[|n|])niinletofsi=option_map(funn->[|n|])ofsiinletinci=Some[|inci|]inlethmo=List.map(funv->[|v|])hmoinletno=option_map(funn->[|n|])noinletofso=option_map(funn->[|n|])ofsoinletinco=Some[|inco|]inGenarray.applynamemake_planhm_nhmi?niofsiinciihmo?noofsoincoo~logical_dimsletdft_name="Fftw3.D.Array1.dft"letdftdir?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=1)(i:'lcomplex_array)?(howmanyo=[])?no?ofso?(inco=1)(o:'lcomplex_array)=letgi=genarray_of_array1iandgo=genarray_of_array1oinapplydft_name~logical_dims:Geom.logical_c2c(guru_dftgigo(sign_of_dirdir)(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletr2c_name="Fftw3.D.Array1.r2c"letr2c?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=1)(i:'lfloat_array)?(howmanyo=[])?no?ofso?(inco=1)(o:'lcomplex_array)=letgi=genarray_of_array1iandgo=genarray_of_array1oinapplyr2c_name~logical_dims:Geom.logical_r2c(guru_r2cgigo(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletc2r_name="Fftw3.D.Array1.c2r"letc2r?(meas=Measure)?(destroy_input=true)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=1)(i:'lcomplex_array)?(howmanyo=[])?no?ofso?(inco=1)(o:'lfloat_array)=letgi=genarray_of_array1iandgo=genarray_of_array1oinapplyc2r_name~logical_dims:Geom.logical_c2r(guru_c2rgigo(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletr2r_name="Fftw3.D.Array1.r2r"letr2rkind?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=1)(i:'lfloat_array)?(howmanyo=[])?no?ofso?(inco=1)(o:'lfloat_array)=letgi=genarray_of_array1iandgo=genarray_of_array1oinletkind=[|kind|]inapplyr2r_name~logical_dims:Geom.logical_r2r(guru_r2rgigokind(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoendmoduleArray2=structexternalarray2_of_ba:('a,'b,'c)Bigarray.Genarray.t->('a,'b,'c)Array2.t="%identity"(* BEWARE: only for bigarray with 2D, convert without check *)letcreatekindlayoutdim1dim2=array2_of_ba(Genarray.createkindlayout[|dim1;dim2|])type'lcomplex_array=(Complex.t,Bigarray.complex64_elt,'l)Array2.ttype'lfloat_array=(float,Bigarray.float64_elt,'l)Array2.ttypecoord=int*intletapplynamemake_planhm_nhmi?niofsi(inci1,inci2)ihmo?noofso(inco1,inco2)o~logical_dims=lethmi=List.map(fun(d1,d2)->[|d1;d2|])hmiinletni=option_map(fun(n1,n2)->[|n1;n2|])niinletofsi=option_map(fun(n1,n2)->[|n1;n2|])ofsiinletinci=Some[|inci1;inci2|]inlethmo=List.map(fun(d1,d2)->[|d1;d2|])hmoinletno=option_map(fun(n1,n2)->[|n1;n2|])noinletofso=option_map(fun(n1,n2)->[|n1;n2|])ofsoinletinco=Some[|inco1;inco2|]inGenarray.applynamemake_planhm_nhmi?niofsiinciihmo?noofsoincoo~logical_dimsletdft_name="Fftw3.D.Array2.dft"letdftdir?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1))(i:'lcomplex_array)?(howmanyo=[])?no?ofso?(inco=(1,1))(o:'lcomplex_array)=letgi=genarray_of_array2iandgo=genarray_of_array2oinapplydft_name~logical_dims:Geom.logical_c2c(guru_dftgigo(sign_of_dirdir)(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletr2c_name="Fftw3.D.Array2.r2c"letr2c?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1))(i:'lfloat_array)?(howmanyo=[])?no?ofso?(inco=(1,1))(o:'lcomplex_array)=letgi=genarray_of_array2iandgo=genarray_of_array2oinapplyr2c_name~logical_dims:Geom.logical_r2c(guru_r2cgigo(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletc2r_name="Fftw3.D.Array2.c2r"letc2r?(meas=Measure)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1))(i:'lcomplex_array)?(howmanyo=[])?no?ofso?(inco=(1,1))(o:'lfloat_array)=letgi=genarray_of_array2iandgo=genarray_of_array2oinapplyc2r_name~logical_dims:Geom.logical_c2r(guru_c2rgigo(flagsmeasunaligned~destroy_input:true))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletr2r_name="Fftw3.D.Array2.r2r"letr2r(kind1,kind2)?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1))(i:'lfloat_array)?(howmanyo=[])?no?ofso?(inco=(1,1))(o:'lfloat_array)=letgi=genarray_of_array2iandgo=genarray_of_array2oinletkind=[|kind1;kind2|]inapplyr2r_name~logical_dims:Geom.logical_r2r(guru_r2rgigokind(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoendmoduleArray3=structexternalarray3_of_ba:('a,'b,'c)Bigarray.Genarray.t->('a,'b,'c)Array3.t="%identity"(* BEWARE: only for bigarray with 3D, convert without check *)letcreatekindlayoutdim1dim2dim3=array3_of_ba(Genarray.createkindlayout[|dim1;dim2;dim3|])type'lcomplex_array=(Complex.t,Bigarray.complex64_elt,'l)Array3.ttype'lfloat_array=(float,Bigarray.float64_elt,'l)Array3.ttypecoord=int*int*intletapplynamemake_planhm_nhmi?niofsi(inci1,inci2,inci3)ihmo?noofso(inco1,inco2,inco3)o~logical_dims=lethmi=List.map(fun(d1,d2,d3)->[|d1;d2;d3|])hmiinletni=option_map(fun(n1,n2,n3)->[|n1;n2;n3|])niinletofsi=option_map(fun(n1,n2,n3)->[|n1;n2;n3|])ofsiinletinci=Some[|inci1;inci2;inci3|]inlethmo=List.map(fun(d1,d2,d3)->[|d1;d2;d3|])hmoinletno=option_map(fun(n1,n2,n3)->[|n1;n2;n3|])noinletofso=option_map(fun(n1,n2,n3)->[|n1;n2;n3|])ofsoinletinco=Some[|inco1;inco2;inco3|]inGenarray.applynamemake_planhm_nhmi?niofsiinciihmo?noofsoincoo~logical_dimsletdft_name="Fftw3.D.Array3.dft"letdftdir?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1,1))(i:'lcomplex_array)?(howmanyo=[])?no?ofso?(inco=(1,1,1))(o:'lcomplex_array)=letgi=genarray_of_array3iandgo=genarray_of_array3oinapplydft_name~logical_dims:Geom.logical_c2c(guru_dftgigo(sign_of_dirdir)(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletr2c_name="Fftw3.D.Array3.r2c"letr2c?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1,1))(i:'lfloat_array)?(howmanyo=[])?no?ofso?(inco=(1,1,1))(o:'lcomplex_array)=letgi=genarray_of_array3iandgo=genarray_of_array3oinapplyr2c_name~logical_dims:Geom.logical_r2c(guru_r2cgigo(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletc2r_name="Fftw3.D.Array3.c2r"letc2r?(meas=Measure)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1,1))(i:'lcomplex_array)?(howmanyo=[])?no?ofso?(inco=(1,1,1))(o:'lfloat_array)=letgi=genarray_of_array3iandgo=genarray_of_array3oinapplyc2r_name~logical_dims:Geom.logical_c2r(guru_c2rgigo(flagsmeasunaligned~destroy_input:true))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoletr2r_name="Fftw3.D.Array3.r2r"letr2r(kind1,kind2,kind3)?(meas=Measure)?(destroy_input=false)?(unaligned=false)?(howmany_n=[||])?(howmanyi=[])?ni?ofsi?(inci=(1,1,1))(i:'lfloat_array)?(howmanyo=[])?no?ofso?(inco=(1,1,1))(o:'lfloat_array)=letgi=genarray_of_array3iandgo=genarray_of_array3oinletkind=[|kind1;kind2;kind3|]inapplyr2r_name~logical_dims:Geom.logical_r2r(guru_r2rgigokind(flagsmeasunaligned~destroy_input))howmany_nhowmanyi?niofsiincigihowmanyo?noofsoincogoend