REVISED: Monday, October 6, 2025
1. OCAML MATRICES
(*
============================
ocaml C:\AI2025\lesson2.ml
Lesson 2: Matrices in OCaml
============================
Objective: Represent matrices and implement basic operations:
1. Matrix addition
2. Scalar multiplication
3. Matrix-vector multiplication
4. Matrix-matrix multiplication
*)
(* -----------------------------
0. Helper functions (from Lesson 1)
----------------------------- *)
(* Implemented missing helpers that the matrix functions rely on.
Each line added below includes a comment explaining its purpose. *)
(* Add two vectors (lists of floats) element-wise. *)
let rec vector_add v1 v2 =
(* If both vectors are empty, result is empty. *)
match v1, v2 with
| [], [] -> []
(* Add heads pairwise and recurse on tails. *)
| x::xs, y::ys -> (x +. y) :: vector_add xs ys
(* Different lengths -> error. *)
| _ -> failwith "vector_add: vectors must have same length"
(* End of vector_add. *)
(* Multiply a vector by a scalar (scalar * vector). *)
let rec scalar_mul scalar v =
(* Empty vector -> empty result. *)
match v with
| [] -> []
(* Multiply head by scalar and recurse on tail. *)
| x :: xs -> (scalar *. x) :: scalar_mul scalar xs
(* End of scalar_mul. *)
(* Dot product of two vectors (lists of floats). *)
let dot_product v1 v2 =
(* Use List.fold_left2 to accumulate element-wise products.
List.fold_left2 raises if lengths mismatch, which is fine here. *)
List.fold_left2 (fun acc a b -> acc +. (a *. b)) 0.0 v1 v2
(* End of dot_product. *)
(* -----------------------------
1. Matrix type
----------------------------- *)
(* We'll represent a matrix as a list of lists of floats. *)
type matrix = float list list
(* -----------------------------
2. Matrix addition
----------------------------- *)
(* Adds two matrices element-wise.
Raises an error if the matrices have different dimensions. *)
let rec matrix_add m1 m2 =
match m1, m2 with
| [], [] -> [] (* base case: both matrices empty *)
| row1::rest1, row2::rest2 ->
(* add corresponding rows using vector_add, then recurse *)
(vector_add row1 row2) :: (matrix_add rest1 rest2)
| _ -> failwith "Matrices must have the same dimensions"
(* -----------------------------
3. Scalar multiplication
----------------------------- *)
(* Multiply each element of a matrix by a scalar *)
let rec scalar_mul_matrix scalar m =
match m with
| [] -> []
| row::rows ->
(* multiply each row (vector) by scalar using scalar_mul *)
(scalar_mul scalar row) :: (scalar_mul_matrix scalar rows)
(* -----------------------------
4. Matrix-vector multiplication
----------------------------- *)
(* Multiply a matrix by a vector *)
let matrix_vector_mul m v =
(* map each row to the dot product of row and vector *)
List.map (fun row -> dot_product row v) m
(* -----------------------------
5. Matrix-matrix multiplication
----------------------------- *)
(* Multiply two matrices: m1 * m2 *)
let matrix_mul m1 m2 =
let transpose m =
(* build a transpose via accumulating columns *)
let rec aux acc = function
| [] -> acc
| row::rows ->
(* prepend each element of row to corresponding accumulator list.
List.map2 pairs each element of 'row' with a list in 'acc'. *)
let new_acc = List.map2 (fun x xs -> x :: xs) row acc in
aux new_acc rows
in
match m with
| [] -> []
| first_row::_ -> aux (List.map (fun _ -> []) first_row) m
in
let m2_t = transpose m2 in
(* for each row in m1 produce a row consisting of dot products
with each column (i.e. each row of m2_t) *)
List.map (fun row ->
List.map (fun col -> dot_product row col) m2_t
) m1
(* -----------------------------
6. Examples / Testing
----------------------------- *)
let m1 = [[1.;2.;3.]; [4.;5.;6.]]
let m2 = [[7.;8.;9.]; [10.;11.;12.]]
(* Matrix addition *)
let m_add = matrix_add m1 m2
let () =
Printf.printf "m1 + m2 = [%s]\n"
(String.concat "; " (List.map (fun row -> "[" ^ (String.concat "; " (List.map string_of_float row)) ^ "]") m_add))
(* Scalar multiplication *)
let m_scaled = scalar_mul_matrix 2.0 m1
let () =
Printf.printf "2 * m1 = [%s]\n"
(String.concat "; " (List.map (fun row -> "[" ^ (String.concat "; " (List.map string_of_float row)) ^ "]") m_scaled))
(* Matrix-vector multiplication *)
let v = [1.;2.;3.]
let mv_mul = matrix_vector_mul m1 v
let () =
Printf.printf "m1 * v = [%s]\n"
(String.concat "; " (List.map string_of_float mv_mul))
(* Matrix-matrix multiplication *)
let m3 = [[1.;2.]; [3.;4.]; [5.;6.]]
let mm_mul = matrix_mul m1 m3
let () =
Printf.printf "m1 * m3 = [%s]\n"
(String.concat "; " (List.map (fun row -> "[" ^ (String.concat "; " (List.map string_of_float row)) ^ "]") mm_mul))
2. CONCLUSION
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows
OCaml version: The OCaml toplevel, version 5.3.0
Coq-LSP version: 0.2.3
Loading personal and system profiles took 1063ms.
PS C:\Users\User> ocaml C:\AI2025\lesson2.ml
m1 + m2 = [[8.; 10.; 12.]; [14.; 16.; 18.]]
2 * m1 = [[2.; 4.; 6.]; [8.; 10.; 12.]]
m1 * v = [14.; 32.]
m1 * m3 = [[14.; 20.]; [41.; 56.]]
PS C:\Users\User>
3. REFERENCES
Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.
Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.
Goerzen, J. & O'Sullivan, B. & Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.
Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.
Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.
Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.