In [1]:
#use "topfind";;
#require "bigarray";;
open Bigarray;;
In [2]:
let len = 10
let b1 = Array1.create int c_layout len
let () = for i=0 to len-1 do b1.{i} <- (i+1)*3 done
let a1 = Array.init len (fun i -> b1.{i})
Out[2]:
Out[2]:
Out[2]:
In [3]:
let len1, len2 = 2, 3
let b2 = Array2.create float32 c_layout len1 len2
let () =
for i=0 to len1-1 do
for j=0 to len2-1 do
b2.{i,j} <- (float j *. 0.5) +. float i
done
done
let a2 = Array.init len2 (fun j -> Array.init len1 (fun i -> b2.{i,j}))
Out[3]:
Out[3]:
Out[3]:
In [4]:
let len1, len2, len3 = 2, 3, 4
let b3 = Array3.create int32 c_layout len1 len2 len3
let () =
for i=0 to len1-1 do
for j=0 to len2-1 do
for k=0 to len3-1 do
b3.{i,j,k} <- Int32.(add (mul (of_int k) 100l) (add (mul (of_int j) 10l) (of_int i)))
done
done
done
let a3 = Array.init len3 (fun k -> Array.init len2 (fun j -> Array.init len1 (fun i -> b3.{i,j,k})))
Out[4]:
Out[4]:
Out[4]:
Start off with a very basic Genarray test
In [5]:
let b = Genarray.create int c_layout [|2;2|]
let _ = Genarray.set b [|0;0|] 1, Genarray.set b [|0;1|] 2, Genarray.set b [|1;0|] 3, Genarray.set b [|1;1|] 4
let x = Genarray.get b [|0;0|], Genarray.get b [|0;1|], Genarray.get b [|1;0|], Genarray.get b [|1;1|]
Out[5]:
Out[5]:
Out[5]:
Make a Genarray with more complex dimensions. The incr function creates all the indices over the Genarray. The index is hashed, stored in the array an xor'ed together. When the array is read the hash is recomputed.
In [6]:
let dims = [| 2; 3; 4; 2; 3; 4; 2; 3; 4 |]
let incr x =
let rec f i =
if x.(i)+1 = dims.(i) then (x.(i) <- 0; f (i+1))
else (x.(i) <- x.(i)+1;)
in
f 0
let bn = Genarray.create int c_layout dims
let size = Array.fold_left ( * ) 1 dims
let hash =
let h = ref 0 in
let idx = Array.map (fun _ -> 0) dims in
for i=0 to size-1 do
let h' = Hashtbl.hash idx in
Genarray.set bn idx h';
h := !h lxor h';
(try incr idx with _ -> ());
done;
!h
let hash_get =
let h = ref 0 in
let idx = Array.map (fun _ -> 0) dims in
for i=0 to size-1 do
h := !h lxor (Genarray.get bn idx);
(try incr idx with _ -> ());
done;
!h
Out[6]:
Out[6]:
Out[6]:
Out[6]:
Out[6]:
Out[6]:
In [7]:
let exn f i = try f i |> ignore; false with x when x = Invalid_argument("index out of bounds") -> true | _ -> false
Out[7]:
In [8]:
let ok1 =
let x = exn (Array1.get b1) in
x (-100) && x (-1) && x 10 && x 100
let ok2 =
let x = exn (fun (i,j) -> Array2.get b2 i j) in
x (-1,0) && x (0,-1) && x (-10,-10) && x (0,3) && x (2,0) && x (2,3)
let ok3 =
let x = exn (fun (i,j,k) -> Array3.get b3 i j k) in
x (-1,0,0) && x (0,-1,0) && x (0,0,-1) && x (-10,-10,-10) &&
x (2,0,0) && x (0,3,0) && x (0,0,4) && x (10,20,30)
Out[8]:
Out[8]:
Out[8]:
In [9]:
let len = 10
let b1 = Array1.create int fortran_layout len
let () = for i=1 to len do b1.{i} <- i*2 done
let a1 = Array.init len (fun i -> b1.{i+1})
Out[9]:
Out[9]:
Out[9]:
In [10]:
let len1, len2 = 2, 3
let b2 = Genarray.create float32 fortran_layout [|len1; len2|]
let () =
for i=1 to len1 do
for j=1 to len2 do
Genarray.set b2 [|i; j|] ((float j *. 0.5) +. float i)
done
done
let a2 = Array.init len2 (fun j -> Array.init len1 (fun i -> Genarray.get b2 [|i+1;j+1|]))
Out[10]:
Out[10]:
Out[10]:
In [11]:
let b = Array1.create int16_unsigned c_layout 4
let () = Array1.fill b 0x1_ffff
let a = Array.init 4 (Array1.get b)
Out[11]:
Out[11]:
In [12]:
let b = Genarray.create int fortran_layout [|2;2;2|]
let () = Genarray.fill b (-2)
let a = Array.init 2 (fun k -> Array.init 2 (fun j -> Array.init 2 (fun i -> Genarray.get b [|i+1;j+1;k+1|])))
Out[12]:
Out[12]:
In [13]:
let b = Array1.create int16_unsigned c_layout 4
let () = Array1.fill b 0xbeef
let c = Array1.create int16_unsigned c_layout 4
let () = Array1.blit b c
let a = Array.init 4 (Array1.get c)
Out[13]:
Out[13]:
Out[13]:
In [14]:
(* generic arrays *)
module type B = sig
type t
type elt
val kind : (t,elt) Bigarray.kind
val rand : unit -> t
val equal : t -> t -> bool
val name : string
end
module type D = sig
val dims : int array
end
module TestGenarray(B : B)(D : D) = struct
let size = Array.fold_left ( * ) 1 D.dims
let rand_init() = Random.init 1000
let c_layout = (c_layout,0)
let fortran_layout = (fortran_layout,1)
(* multi-dimensional indices *)
let mk_idx (_,ofs) = Array.map (fun _ -> ofs) D.dims
let incr (_,ofs) x =
let rec f i =
if x.(i) = D.dims.(i)-(1-ofs) then (x.(i) <- ofs; f (i+1))
else (x.(i) <- x.(i)+1;)
in
try f 0 with _ -> ()
let test layout =
let ba = Genarray.create B.kind (fst layout) D.dims in
let ba2 = Genarray.create B.kind (fst layout) D.dims in
(* write random gunk *)
let idx,() = mk_idx layout, rand_init() in
for i=0 to size-1 do
Genarray.set ba idx (B.rand());
incr layout idx
done;
(* read back and check *)
let idx,() = mk_idx layout, rand_init() in
for i=0 to size-1 do
let r = B.rand() in
let a = Genarray.get ba idx in
assert (B.equal r a);
incr layout idx
done;
(* blit to new array *)
let () = Genarray.blit ba ba2 in
(* fill 1st array with random value *)
let x = B.rand() in
let () = Genarray.fill ba x in
(* read back and check *)
let idx = mk_idx layout in
for i=0 to size-1 do
let a = Genarray.get ba idx in
assert (B.equal x a);
incr layout idx
done;
(* read back 2nd array check *)
let idx,() = mk_idx layout, rand_init() in
for i=0 to size-1 do
let r = B.rand() in
let a = Genarray.get ba2 idx in
assert (B.equal r a);
incr layout idx
done
let run () =
(*let () = Printf.printf "%s\n" B.name in*)
let () = test c_layout in
let () = test fortran_layout in
()
end
Out[14]:
Out[14]:
Out[14]:
In [15]:
module Int = struct
type t = int
type elt = Bigarray.int_elt
let kind = Bigarray.int
let rand () = Random.int 1000
let equal a b = Pervasives.compare a b = 0
let name = "int"
end
module Int32 = struct
type t = int32
type elt = Bigarray.int32_elt
let kind = Bigarray.int32
let rand () = Random.int32 1000l
let equal a b = Pervasives.compare a b = 0
let name = "int32"
end
module Int64 = struct
type t = int64
type elt = Bigarray.int64_elt
let kind = Bigarray.int64
let rand () = Random.int64 1000L
let equal a b = Pervasives.compare a b = 0
let name = "int64"
end
module Char_ = struct
type t = char
type elt = Bigarray.int8_unsigned_elt
let kind = Bigarray.char
let rand () = Char.chr (Random.int 256)
let equal a b = Pervasives.compare a b = 0
let name = "char"
end
module Uint8 = struct
type t = int
type elt = Bigarray.int8_unsigned_elt
let kind = Bigarray.int8_unsigned
let rand () = Random.int 256
let equal a b = Pervasives.compare a b = 0
let name = "uint8"
end
module Sint8 = struct
type t = int
type elt = Bigarray.int8_signed_elt
let kind = Bigarray.int8_signed
let rand () = Random.int 128
let equal a b = Pervasives.compare a b = 0
let name = "sint8"
end
module Uint16 = struct
type t = int
type elt = Bigarray.int16_unsigned_elt
let kind = Bigarray.int16_unsigned
let rand () = Random.int 1000
let equal a b = Pervasives.compare a b = 0
let name = "uin16"
end
module Sint16 = struct
type t = int
type elt = Bigarray.int16_signed_elt
let kind = Bigarray.int16_signed
let rand () = Random.int 1000
let equal a b = Pervasives.compare a b = 0
let name = "sint16"
end
module Float32 = struct
type t = float
type elt = Bigarray.float32_elt
let kind = Bigarray.float32
let rand () = Random.float 1000.
let equal a b = abs_float (a -. b) < 0.0001
let name = "float32"
end
module Float64 = struct
type t = float
type elt = Bigarray.float64_elt
let kind = Bigarray.float64
let rand () = Random.float 1000.
let equal a b = Pervasives.compare a b = 0
let name = "float64"
end
module Complex32 = struct
type t = Complex.t
type elt = Bigarray.complex32_elt
let kind = Bigarray.complex32
let rand () = Complex.({re=Random.float 1000.;im=Random.float 1000.})
let equal a b =
let open Complex in
Float32.equal a.re b.re &&
Float32.equal a.im b.im
let name = "complex32"
end
module Complex64 = struct
type t = Complex.t
type elt = Bigarray.complex64_elt
let kind = Bigarray.complex64
let rand () = Complex.({re=Random.float 1000.;im=Random.float 1000.})
let equal a b = Pervasives.compare a b = 0
let name = "complex64"
end
let ba_types = [
(module Int : B);
(module Int32 : B);
(module Int64 : B);
(module Char_ : B);
(module Uint8 : B);
(module Sint8 : B);
(module Uint16 : B);
(module Sint16 : B);
(module Float32 : B);
(module Float64 : B);
(module Complex32 : B);
(module Complex64 : B);
]
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Out[15]:
Check generation of indices is working correctly
In [16]:
module X = TestGenarray(Int)(struct let dims = [| 2;3 |] end)
let idx = X.mk_idx X.c_layout
let c = Array.init (2*3) (fun _ -> let a = Array.copy idx in X.incr X.c_layout idx; a)
let idx = X.mk_idx X.fortran_layout
let fortran = Array.init (2*3) (fun _ -> let a = Array.copy idx in X.incr X.fortran_layout idx; a)
Out[16]:
Out[16]:
Out[16]:
Out[16]:
Out[16]:
Run tests. An exception is raised if there is an error
In [17]:
let dims = List.map (fun d -> (module (struct let dims = [| 100 |] end) : D))
[
[|1|];
[|10|];
[|10000|];
[|1;1|];
[|10;20|];
[|100;200|];
[|1;1;1|];
[|10;8;12|];
[|12;20;14;6;2;1;4|];
]
let test ba dims =
let module Test = TestGenarray((val ba : B))((val dims : D)) in
Test.run()
let _ = List.iter (fun ba -> List.iter (fun d -> test ba d) dims) ba_types
Out[17]:
Out[17]:
Out[17]:
In [18]:
let ba = Array2.of_array int c_layout [|
[| 0; 1 |];
[| 2; 3 |];
[| 4; 5 |];
[| 6; 7 |];
|]
Out[18]:
extract middle 2 rows
In [19]:
let ba2 = Array2.sub_left ba 1 2
Out[19]:
In [20]:
ba2.{0,0}, ba2.{0,1}, ba2.{1,0}, ba2.{1,1}
Out[20]:
Ensure both arrays share data
In [21]:
ba2.{0,0} <- 100
Out[21]:
In [22]:
ba.{1,0}
Out[22]:
Fortran layout
In [23]:
let ba = Array2.of_array int fortran_layout [|
[| 0; 1 |];
[| 2; 3 |];
[| 4; 5 |];
[| 6; 7 |];
|]
Out[23]:
extract right hand column
In [24]:
let ba2 = Array2.sub_right ba 2 1
Out[24]:
In [25]:
Array.init 4 (fun i -> ba2.{i+1,1})
Out[25]:
In [26]:
ba2.{3,1} <- 50
Out[26]:
In [27]:
ba.{3,2}
Out[27]:
In [28]:
let ba = Array3.of_array int c_layout [|
[| [| 0; 1 |]; [| 2; 3 |]; |];
[| [| 4; 5 |]; [| 6; 7 |]; |];
|]
Out[28]:
get the [2,3] subarray
In [29]:
let ba2 = Array3.slice_left_1 ba 0 1
Out[29]:
In [30]:
ba2.{0}, ba2.{1}
Out[30]:
get the [4,5] subarray
In [31]:
let ba2 = Array3.slice_left_1 ba 1 0
Out[31]:
In [32]:
ba2.{0}, ba2.{1}
Out[32]:
get [[4,5][6,7]]
In [33]:
let ba2 = Array3.slice_left_2 ba 1
Out[33]:
In [34]:
ba2.{0,0}, ba2.{0,1}, ba2.{1,0}, ba2.{1,1}
Out[34]:
In [35]:
let ba = Array2.of_array int c_layout [|
[| 0; 1; 2; 3 |];
[| 4; 5; 6; 7 |];
|]
Out[35]:
2d to 1d
In [36]:
let ba2 = reshape_1 (genarray_of_array2 ba) 8
Out[36]:
In [37]:
Array.init 8 (fun i -> ba2.{i})
Out[37]:
2d to 3d
In [38]:
let ba2 = array3_of_genarray (reshape (genarray_of_array2 ba) [|2;2;2|])
Out[38]:
In [39]:
ba2.{0,0,0}, ba2.{0,0,1}, ba2.{0,1,0}, ba2.{0,1,1},
ba2.{1,0,0}, ba2.{1,0,1}, ba2.{1,1,0}, ba2.{1,1,1}
Out[39]:
In [ ]: