123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617(*
* BatBigarray - additional and modified functions for big arrays.
* Copyright (C) 2000 Michel Serrano
* 2000 Xavier Leroy
* 2009 David Teller, LIFO, Universite d'Orleans
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version,
* with the special exception on linking described in 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)moduleA=structincludeBatArrayincludeBatArray.Labelsend(* The V>=4.2 lines are not necessary for typing,
but they are necessary for the compatibility test in batteries_compattest.ml
which are of the form:
module _ = (BatBigarray : module type of Bigarray)
because of the somewhat strange interpretation of strengthening in (module type of),
we need to explicitly equate each type with its constructor *)##V>=5.2##typefloat16_elt=Bigarray.float16_elt=Float16_elttypefloat32_elt=Bigarray.float32_elt##V>=4.2##=Float32_elttypefloat64_elt=Bigarray.float64_elt##V>=4.2##=Float64_elttypecomplex32_elt=Bigarray.complex32_elt##V>=4.2##=Complex32_elttypecomplex64_elt=Bigarray.complex64_elt##V>=4.2##=Complex64_elttypeint8_signed_elt=Bigarray.int8_signed_elt##V>=4.2##=Int8_signed_elttypeint8_unsigned_elt=Bigarray.int8_unsigned_elt##V>=4.2##=Int8_unsigned_elttypeint16_signed_elt=Bigarray.int16_signed_elt##V>=4.2##=Int16_signed_elttypeint16_unsigned_elt=Bigarray.int16_unsigned_elt##V>=4.2##=Int16_unsigned_elttypeint_elt=Bigarray.int_elt##V>=4.2##=Int_elttypeint32_elt =Bigarray.int32_elt##V>=4.2##=Int32_elttypeint64_elt =Bigarray.int64_elt##V>=4.2##=Int64_elttypenativeint_elt =Bigarray.nativeint_elt##V>=4.2##=Nativeint_elttype('a,'b)kind =('a,'b)Bigarray.kind##V>=4.2##=Float32 :(float,float32_elt)kind##V>=4.2##|Float64:(float,float64_elt)kind##V>=4.2##|Int8_signed:(int,int8_signed_elt)kind##V>=4.2##|Int8_unsigned :(int,int8_unsigned_elt)kind##V>=4.2##|Int16_signed:(int,int16_signed_elt)kind##V>=4.2##|Int16_unsigned :(int,int16_unsigned_elt)kind##V>=4.2##|Int32:(int32,int32_elt)kind##V>=4.2##|Int64:(int64,int64_elt)kind##V>=4.2##|Int :(int,int_elt)kind##V>=4.2##|Nativeint:(nativeint,nativeint_elt)kind##V>=4.2##|Complex32:(Complex.t,complex32_elt)kind##V>=4.2##|Complex64:(Complex.t,complex64_elt)kind##V>=4.2##|Char:(char,int8_unsigned_elt)kind##V>=5.2##|Float16:(float,float16_elt)kind(* this type is local to Batteries,
it is meant to make it easier to port code
written against (>= 4.2) GADT style
into older versions: we know that a kind value
(on < 4.2) can be directly converted to one of those by
just the identity *)##V<4.2##typeuntyped_kind=##V<4.2##|Float32##V<4.2##|Float64##V<4.2##|Int8_signed##V<4.2##|Int8_unsigned##V<4.2##|Int16_signed##V<4.2##|Int16_unsigned##V<4.2##|Int32##V<4.2##|Int64##V<4.2##|Int##V<4.2##|Nativeint##V<4.2##|Complex32##V<4.2##|Complex64##V<4.2##|Char##V<4.2##externaluntyped_kind_of_kind :(_,_)kind-> untyped_kind="%identity"typec_layout=Bigarray.c_layout##V>=4.2##=C_layout_typtypefortran_layout=Bigarray.fortran_layout##V>=4.2##=Fortran_layout_typtype'alayout='aBigarray.layout##V>=4.2##=C_layout:c_layoutlayout##V>=4.2##|Fortran_layout :fortran_layoutlayoutletfloat32=Bigarray.float32letfloat64=Bigarray.float64letcomplex32=Bigarray.complex32letcomplex64=Bigarray.complex64letint8_signed=Bigarray.int8_signedletint8_unsigned=Bigarray.int8_unsignedletint16_signed=Bigarray.int16_signedletint16_unsigned=Bigarray.int16_unsignedletint=Bigarray.intletint32=Bigarray.int32letint64=Bigarray.int64letnativeint=Bigarray.nativeintletchar=Bigarray.char(* kind_size_in_bytes was introduced upstream in 4.03 *)##V>=4.3##letkind_size_in_bytes=Bigarray.kind_size_in_bytes##V=4.2##letkind_size_in_bytes:typeab.(a,b)kind->int=function##V<4.2##letkind_size_in_bytes(kind:(_,_)kind):int=##V<4.2##matchuntyped_kind_of_kindkindwith##V<=4.2##(* the clauses below are shared before 4.02 and at 4.02 *)##V<=4.2##|Float32 ->4##V<=4.2##|Float64->8##V<=4.2##|Int8_signed->1##V<=4.2##|Int8_unsigned->1##V<=4.2##|Int16_signed->2##V<=4.2##|Int16_unsigned ->2##V<=4.2##|Int32->4##V<=4.2##|Int64->8##V<=4.2##|Int->Sys.word_size/8##V<=4.2##|Nativeint->Sys.word_size/8##V<=4.2##|Complex32->8##V<=4.2##|Complex64->16##V<=4.2##|Char->1letc_layout=Bigarray.c_layoutletfortran_layout=Bigarray.fortran_layout##V<4.2##letofs_of_layout(layout:_Bigarray.layout)=##V<4.2##match(Obj.magiclayout:int)with##V<4.2##|0->0##V<4.2##|0x100->1(* constants to be found in caml_ba_layout in bigarray.h *)##V<4.2##|_->failwith"Unknown layout"##V>=4.2##letofs_of_layout:typea.aBigarray.layout->int=function##V>=4.2##|Bigarray.C_layout->0##V>=4.2##|Bigarray.Fortran_layout->1moduleGenarray=structincludeBigarray.Genarray##V>=4.8##letmap_file=Unix.map_fileletofse=ofs_of_layout(layoute)##V<4.3##letsize_in_bytesarr=##V<4.3##(kind_size_in_bytes(kindarr))*(Array.fold_left(*)1(dimsarr))(**
Emulate multi-dimensional coordinates.
@param index The index of the element.
@param dims The dimensions of the array.
@param coor A buffer in which to write the various coordinates *)(* let index_to_coor index ~dims ~coor =
(*
[| a; b; c; d |]0 -> 0 0 0 0
1 -> 0 0 0 1
2 -> 0 0 0 2
3 -> 0 0 0 3
d -> 0 0 1 0 d+1->0 0 1 1
d+2->0 0 1 2
2*d->0 0 1 0
c*d->0 1 0 0 -> d' = index mod a * b * c * d
c' = indexmod a * b * c *)
let product = ref 1 in
for i = 0 to Array.length dims - 1 do
indices.(i) <-done*)(**
Determine the coordinates of the item following thisone.
@param coor Coordinates to increment.
@param dims The set of coordinates of the array.
@return [true] if everything happened correctly,[false] if
we've passedthe last element.
*)letinplace_next~ofs~dims~coor=letrecauxi=ifi<0then falseelseletnew_value=coor.(i)+1inifnew_value=dims.(i)+ofsthen(*Propagate carry*)begincoor.(i)<-ofs;aux(i-1)endelsebegincoor.(i)<-new_value;trueendin aux(Array.lengthdims-1)letiterfe=letdims=dimseinletoffset=ofseinlet coor=A.create(num_dimse)~init:offsetinf(getecoor);whileinplace_next~ofs:offset~dims~coordof(getecoor)doneletiterife=letdims=dimseinletoffset=ofseinletcoor=A.create(num_dimse)~init:offsetinf(A.Cap.of_arraycoor)(getecoor);whileinplace_next~ofs:offset~dims~coordof(A.Cap.of_arraycoor)(getecoor)doneletmodifyfe=letdims =dimseinletoffset=ofseinletchangec=setec(f(getec))inletcoor=A.create (num_dimse)~init:offsetinchange coor;whileinplace_next~ofs:offset~dims~coordochangecoordoneletmodifyi fe=letdims=dimseinletoffset=ofseinletchangec=setec(f(A.Cap.of_array c)(getec))inletcoor=A.create(num_dimse)~init:offsetinchangecoor;while inplace_next~ofs:offset~dims~coordochange coordoneletenume=letdims=dimseandoffset=ofseinletcoor=A.create(num_dimse)~init:offsetandstatus=ref`ongoinginBatEnum.from(fun()->match!statuswith|`ongoing->begintryletresult=getecoorinletupdate=inplace_next~ofs:offset~dims~coorinifnotupdatethenstatus:=`dry;resultwith_->status:=`dry;raise BatEnum.No_more_elementsend|`dry ->raiseBatEnum.No_more_elements)let mapfb_kinda=letd=dimsainletb=createb_kind(layout a)diniteri(funix->setb(A.Cap.to_array i)(fx))a;bletmapifb_kind a=letd=dimsainletb=createb_kind(layouta)diniteri(funix->setb(A.Cap.to_array i)(f(A.Cap.read_onlyi)x))a;bend##V>=4.5##externalgenarray_of_array0:('a,'b,'c)Bigarray.Array0.t->('a,'b,'c)Genarray.t##V>=4.5##="%identity"externalgenarray_of_array1:('a,'b,'c)Bigarray.Array1.t->('a,'b,'c)Genarray.t="%identity"externalgenarray_of_array2:('a,'b,'c)Bigarray.Array2.t->('a,'b,'c)Genarray.t="%identity"externalgenarray_of_array3:('a,'b,'c)Bigarray.Array3.t->('a,'b,'c)Genarray.t="%identity"externalreshape:('a,'b,'c)Genarray.t->intarray ->('a,'b,'c)Genarray.t="caml_ba_reshape"letreshape_3=Bigarray.reshape_3letreshape_2=Bigarray.reshape_2letreshape_1=Bigarray.reshape_1##V>=4.5##letreshape_0=Bigarray.reshape_0letarray3_of_genarray=Bigarray.array3_of_genarrayletarray2_of_genarray=Bigarray.array2_of_genarrayletarray1_of_genarray=Bigarray.array1_of_genarray##V>=4.5##letarray0_of_genarray=Bigarray.array0_of_genarray##V>=4.5##moduleArray0=struct##V>=4.5##includeBigarray.Array0##V>=4.5##endmoduleArray1=structincludeBigarray.Array1##V>=4.8##letmap_filefd?poskindlayoutshareddim=##V>=4.8##Bigarray.array1_of_genarray##V>=4.8##(Unix.map_filefd?poskindlayoutshared[|dim|])letofse=ofs_of_layout(layoute)##V<4.3##letsize_in_bytesarr=##V<4.3##(kind_size_in_bytes(kindarr))*(dimarr)letenumt=letoffset=ofstinBatEnum.init(dimt)(funi->t.{offset+i})letof_enumkindlayoutenum=letb_dim=BatEnum.countenuminletb=createkindlayoutb_diminfori=ofsbtoofsb+b_dim-1dob.{i}<-BatEnum.get_exnenumdone;b(*$QQ.string (fun s ->s = String.of_enum (Array1.enum \
(Array1.of_enum char c_layout (String.enums))))
Q.string (fun s -> s = String.of_enum (Array1.enum \
(Array1.of_enum char fortran_layout (String.enum s))))
(Q.list Q.int) (fun li -> li = List.of_enum (Array1.enum \
(Array1.of_enum int c_layout (List.enum li))))
*)letmapfb_kinda=letb_dim =dimainletb=createb_kind(layouta)b_diminfori=ofsatoofs a+b_dim-1dob.{i}<-fa.{i}done;bletmapifb_kinda=letb_dim=dimainletb=createb_kind(layouta)b_diminfori=ofsatoofsa+b_dim-1dob.{i}<-fia.{i}done;blet modifyfa=fori=ofsatoofs a+dima-1dounsafe_setai(f(unsafe_getai))doneletmodifyifa=fori=ofsatoofsa+dima-1dounsafe_setai(fi(unsafe_getai))doneletto_arraya=Array.init(dima)(funi->a.{i+(ofsa)})endmoduleArray2=structincludeBigarray.Array2##V>=4.8##letmap_filefd?poskindlayoutshareddim1dim2=##V>=4.8##Bigarray.array2_of_genarray##V>=4.8##(Unix.map_filefd?poskindlayoutshared[|dim1;dim2|])letofse=ofs_of_layout(layoute)##V<4.3##letsize_in_bytesarr=##V<4.3##(kind_size_in_bytes(kindarr))*(dim1arr)*(dim2arr)letenumt=Genarray.enum(genarray_of_array2t)letmapfb_kinda=letb_dim1=dim1ainletb_dim2 =dim2ainlet b=createb_kind(layout a)b_dim1 b_dim2infori=ofsatoofsa+b_dim1-1doforj=ofsatoofsa+b_dim2 -1dob.{i,j}<-fa.{i,j}donedone;bletmapijfb_kinda=letb_dim1=dim1ainletb_dim2=dim2ainletb=createb_kind(layouta)b_dim1b_dim2infori=ofsatoofsa+b_dim1-1doforj=ofsatoofsa+b_dim2-1dob.{i,j}<-fija.{i,j}donedone;bletmodifyfa=fori=ofsatoofsa+dim1a-1doforj=ofsatoofsa+dim2a-1dounsafe_setaij(f(unsafe_getaij))donedoneletmodifyijfa=fori=ofsatoofsa+dim1a-1doforj=ofsatoofsa+dim2a-1dounsafe_set aij(fij(unsafe_getaij))donedoneletto_arraya=Array.init(dim1a)(funi->Array.init(dim2a)(funj->a.{i+ofsa,j+ofsa}))endmodule Array3=structincludeBigarray.Array3##V>=4.8##letmap_filefd?poskindlayoutshareddim1dim2dim3=##V>=4.8##Bigarray.array3_of_genarray##V>=4.8##(Unix.map_filefd?poskindlayoutshared[|dim1;dim2;dim3|])letofse=ofs_of_layout(layoute)##V<4.3##letsize_in_bytesarr=##V<4.3##(kind_size_in_bytes(kindarr))*(dim1arr)*(dim2arr)*(dim3arr)letenumt=Genarray.enum(genarray_of_array3t)letmapfb_kinda=letb_dim1=dim1ainletb_dim2=dim2ainletb_dim3=dim3ainletb=createb_kind(layouta)b_dim1b_dim2b_dim3infori=0tob_dim1-1doforj=0tob_dim2-1dofork=0tob_dim3-1dob.{i,j,k}<-fa.{i,j,k}donedonedone;bletmapijkfb_kinda=letb_dim1=dim1ainletb_dim2=dim2ainletb_dim3=dim3ainletb=createb_kind(layouta)b_dim1b_dim2b_dim3infori=0tob_dim1-1doforj=0tob_dim2-1dofork=0tob_dim3-1dob.{i,j,k}<-fijka.{i,j,k}donedonedone;bletmodifyfa=fori=ofsatoofsa+dim1a-1doforj=ofsatoofsa+dim2a-1dofork=ofsatoofsa+dim3a-1dounsafe_setaijk(f(unsafe_getaijk))donedonedoneletmodifyijkfa=fori=ofsatoofsa+dim1a-1doforj=ofsatoofsa+dim2a-1dofork=ofsatoofsa+dim3a-1dounsafe_setaijk(fijk(unsafe_getaijk))donedonedoneletto_arraya=Array.init(dim1a)(funi->Array.init(dim2a)(funj->Array.init(dim3a)(funk->a.{i,j,k})))end(*$R
let a = Genarray.create int c_layout [|2;3;4;5;6|] in
let n_elt = 2 * 3 * 4 * 5 * 6 in
let value_index = function
| [|i1; i2; i3; i4; i5|] -> i1+2*(i2+3*(i3+4*(i4+5*i5)))
| _ -> assert false in
let value_index2 : (int, [`Read]) BatArray.Cap.t -> int =
fun a -> value_index (Obj.magic a) in
for i1 = 0 to 2 - 1 do
for i2 = 0 to 3 - 1 do
for i3 = 0 to 4 - 1 do
for i4 = 0 to 5 - 1 do
for i5 = 0 to 6 - 1 do
let index = [|i1;i2;i3;i4;i5|] in
Genarray.set a index (value_index index)
done
done
done
done
done;
let total = n_elt * (n_elt - 1) / 2 in
let sum = ref 0 in
Genarray.iter (fun i -> sum := !sum + i) a;
assert_equal !sum total;
sum := 0;
Genarray.iteri (fun index i ->
assert_equal i (value_index2 index);
sum := !sum + i
) a;
assert_equal !sum total;
Genarray.modify (fun i -> i + 1) a;
Genarray.iteri (fun index i -> assert_equal (value_index2 index + 1) i) a;
Genarray.modifyi (fun index i -> i - 1 + value_index2 index) a;
Genarray.iteri (fun index i -> assert_equal (2 * value_index2 index) i) a;
let a2 = Genarray.map (fun i -> i / 2) int a in
Genarray.iteri (fun index i -> assert_equal (2 * value_index2 index) i) a;
Genarray.iteri (fun index i -> assert_equal (value_index2 index) i) a2;
let a3 = Genarray.mapi (fun index i -> value_index2 index - i) int a2 in
Genarray.iteri (fun index i -> assert_equal (value_index2 index) i) a2;
Genarray.iter (fun i -> assert_equal 0 i) a3
*)(*$R
let a = Array1.create int c_layout 6 in
let n_elt = 6 in
let value_index n = n + 1 in
for i1 = 0 to 6 - 1 do
Array1.set a i1 (value_index i1)
done;
let iteri f a =
for i = 0 to n_elt - 1 do f i a.{i}
done in
Array1.modify (fun i -> i + 1) a;
iteri (fun index i -> assert_equal (value_index index + 1) i) a;
Array1.modifyi (fun index i -> i - 1 + value_index index) a;
iteri (fun index i -> assert_equal (2 * value_index index) i) a;
let a2 = Array1.map (fun i -> i / 2) int a in
iteri (fun index i -> assert_equal (2 * value_index index) i) a;
iteri (fun index i -> assert_equal (value_index index) i) a2;
let a3 = Array1.mapi (fun index i -> value_index index - i) int a2 in
iteri (fun index i -> assert_equal (value_index index) i) a2;
iteri (fun _ i -> assert_equal 0 i) a3
*)(*$R
let a = Array2.create int c_layout 5 6 in
let value_index i j = i * 5 + j in
let iterij f a =
for i = 0 to 5 - 1 do
for j = 0 to 6 - 1 do
f i j a.{i,j}
done
done in
iterij (fun i j _undef -> a.{i,j} <- value_index i j) a;
Array2.modify (fun i -> i + 1) a;
iterij (fun i j elt -> assert_equal (value_index i j + 1) elt) a;
Array2.modifyij (fun i j elt -> elt - 1 + value_index i j) a;
iterij (fun i j elt -> assert_equal (2 * value_index i j) elt) a;
let a2 = Array2.map (fun elt -> elt / 2) int a in
iterij (fun i j elt -> assert_equal (2 * value_index i j) elt) a;
iterij (fun i j elt -> assert_equal (value_index i j) elt) a2;
let a3 = Array2.mapij (fun i j elt -> value_index i j - elt) int a2 in
iterij (fun i j elt -> assert_equal (value_index i j) elt) a2;
iterij (fun _ _ elt -> assert_equal 0 elt) a3
*)(*$R
let a = Array3.create int c_layout 4 5 6 in
let value_index i j k = i + 4 * (j + 5 * k) in
let iterijk f a =
for i = 0 to 4 - 1 do
for j = 0 to 5 - 1 do
for k = 0 to 6 - 1 do
f i j k a.{i,j,k}
done
done
done in
iterijk (fun i j k _undef -> a.{i,j,k} <- value_index i j k) a;
Array3.modify (fun i -> i + 1) a;
iterijk (fun i j k elt -> assert_equal (value_index i j k + 1) elt) a;
Array3.modifyijk (fun i j k elt -> elt - 1 + value_index i j k) a;
iterijk (fun i j k elt -> assert_equal (2 * value_index i j k) elt) a;
let a2 = Array3.map (fun elt -> elt / 2) int a in
iterijk (fun i j k elt -> assert_equal (2 * value_index i j k) elt) a;
iterijk (fun i j k elt -> assert_equal (value_index i j k) elt) a2;
let a3 = Array3.mapijk (fun i j k elt -> value_index i j k - elt) int a2 in
iterijk (fun i j k elt -> assert_equal (value_index i j k) elt) a2;
iterijk (fun _ _ _ elt -> assert_equal 0 elt) a3
*)