Lisp - Matrix Multiplication



Matrix Multiplication

Matrix multiplication is one of the fundamental operation in linear algebra. It is practically used in many fields like computer graphics, physics and machine learning. Following are the key points to be noted before understanding a matrix multiplication.

  • Dimensions− Two matrices, A and B can be multiplied only if columns of matrix A are same as rows in matrix B.

  • Resulted Matrix Dimensions− Consider a matrix A of dimension m x n and a matrix B of dimension n x p, the result of multiplication of A and B matrices, C will be of m x p.

  • Process of Multiplication− Each element of Resulted Matrix C[i][j] is calculated as product of ith row of matrix A with jth column of matrix B.

Example of Matrix Multiplication

Let's have Matrix A of 2 x 3 as shown below

Matrix A

[
[1, 2, 3],
[4, 5, 6]
]

Let's have Matrix B of 3 x 2 as shown below

Matrix B

[
[7, 8],
[9, 10],
[11, 12]
]

Result of Matrix Multiplication will be computed using following way −

C[0][0]  = A[0][0] * B[0][0]  + A[0][1] * B[1][0] + A[0][2] + B[2][0]
         = (1 * 7) + (2 * 9) + (3 * 11)
         = 7 + 18 + 33
         = 58		 

Resulted Matrix C

[
[58, 64],
[139, 154]
]

Let's write a LISP Funtion to implement matrix manipulation.

main.lisp

(defun multiply-matrix (matrixA matrixB)(
   ; initialize rows and columns of matrices
   let(
      (rowsA (length matrixA))
      (colsA (length (first matrixA))) 
      (rowsB (length matrixB))
      (colsB (length (first matrixB)))
   )
   ; if columns of A is not same as rows of B        
   (if (/= colsA rowsB)
      (error "Incompatible Dimensions for matrix multiplication.")
      (loop for i from 0 below rowsA
         collect (
            loop for j from 0 below colsB
               collect (
                  loop for k from 0 below colsA
                     sum (* (elt (elt matrixA i) k)
                                                 (elt (elt matrixB k) j))))))))

;; Multiply two matrices
(let ((matrixA '((1 2 3) (4 5 6)))
      (matrixB '((7 8) (9 10) (11 12))))
  (let ((result (multiply-matrix matrixA matrixB)))
    (loop for row in result do (format t "~a~%" row))))

Output

When you execute the code, it returns the following result −

(58 64)
(139 154)

Explanation

  • defun matrix-multiply − Define a function matrix-multiply

  • let − Dimensions of matrices are stored in local variables. first returns the first row. We're assuming here that each row have same number of element.

  • Dimension Check − If columns of matrix A is not same as rows as matrix B then error is thrown.

  • Nested Loop − We're using loop construct for iteration.

    • Outer loop iterates over rows of matrix A using i.

    • middle loop iterates over columns of matrix B using j.

    • inner loop iterates over columns of matrix A using k.

  • elt − elt is used to access element of the list. elt (elt matrixA i) k refers to A[i][k].

  • sum − using sum function, we're computing each element of resultant matrix.

  • collect − using collect, we're building the result. Innermost collect creates the rows of resulted matrix and middle collect builds the complete matrix

Advertisements