Let's bring in our code from last time:
type vec = float array;;
let vec_print =
let print_elt n =
print_float n; print_newline ()
in Array.iter print_elt;;
type vec = float array
val vec_print : float array -> unit = <fun>
Now let's add a function to add vectors!
(** [vec_add v1 v2] is the sume of the vectors [v1]
and [v2].
Precondition: [v1] and [v2] have the same length
@raise Invalid_argument if the vectors have
different lengths
Example: [vec_add [|1.; 2.|] [|3.;4.|]] is
[[|4.;6.|]]*)
let vec_add v1 v2 =
let len1, len2 = Array.length v1, Array.length v2 in
if len1 <> len2 then invalid_arg "different lengths" else
let v3 = Array.make len1 0. in
for i = 0 to len1 - 1 do
v3.(i) <- v1.(i) +. v2.(i)
done;
v3
val vec_add : float array -> float array -> float array = <fun>
Now let's test our new function!
vec_add [|1.; 2.|] [|3.; 4.|]
- : float array = [|4.; 6.|]
Yay! It seems to work well! But we can simplify this code using ideas from higher-order functions.
We can use Array.init, which gives us a way to initilize a new array with values:
let vec_add v1 v2 =
let len1, len2 = Array.length v1, Array.length v2 in
if len1 <> len2 then invalid_arg "different lengths" else
let elt i = v1.(i) +. v2.(i) in
Array.init len1 elt;;
vec_add [|1.; 2.|] [|3.; 4.|]
val vec_add : float array -> float array -> float array = <fun>
- : float array = [|4.; 6.|]
There's still some ugliness in having to deal with these lengths. We can do this in an even better way using Array.map2. It is a version of map that takes in two arrays.
let vec_add = Array.map2 ( +. );;
vec_add [|1.; 2.|] [|3.; 4.|]
val vec_add : float array -> float array -> float array = <fun>
- : float array = [|4.; 6.|]