# Chapter 5 Exercise Set 3: Vectors and Matrices¶

## Vectors¶

Lists can be used to represent mathematical

*vectors*. In this exercise and several that follow you will write functions to perform standard operations on vectors. Create a file named`vectors.py`

and write Python code to make the doctests for each function pass.Write a function

`add_vectors(u, v)`

that takes two lists of numbers of the same length, and returns a new list containing the sums of the corresponding elements of each.def add_vectors(u, v): """ >>> add_vectors([1, 0], [1, 1]) [2, 1] >>> add_vectors([1, 2], [1, 4]) [2, 6] >>> add_vectors([1, 2, 1], [1, 4, 3]) [2, 6, 4] >>> add_vectors([11, 0, -4, 5], [2, -4, 17, 0]) [13, -4, 13, 5] >>> a = [1, 2, 3] >>> b = [1, 1, 1] >>> add_vectors(a, b) [2, 3, 4] >>> a [1, 2, 3] >>> b [1, 1, 1] """

`add_vectors`

should pass the doctests above.Write a function

`scalar_mult(s, v)`

that takes a number,`s`

, and a list,`v`

and returns the scalar multiple of`v`

by`s`

.def scalar_mult(s, v): """ >>> scalar_mult(5, [1, 2]) [5, 10] >>> scalar_mult(3, [1, 0, -1]) [3, 0, -3] >>> scalar_mult(7, [3, 0, 5, 11, 2]) [21, 0, 35, 77, 14] >>> a = [1, 2, 3] >>> scalar_mult(4, a) [4, 8, 12] >>> a [1, 2, 3] """

Write a function

`dot_product(u, v)`

that takes two lists of numbers of the same length, and returns the sum of the products of the corresponding elements of each (the dot_product).def dot_product(u, v): """ >>> dot_product([1, 1], [1, 1]) 2 >>> dot_product([1, 2], [1, 4]) 9 >>> dot_product([1, 2, 1], [1, 4, 3]) 12 >>> dot_product([2, 0, -1, 1], [1, 5, 2, 0]) 0 """

Verify that

`dot_product`

passes the doctests above.

## Matrices¶

Create a new module named

`matrices.py`

and add the following function, which returns a*copy*of nested lists of numbers such that the lists are not*aliases*:def copy_matrix(matrix): """ >>> copy_matrix([[1, 2], [3, 4]]) [[1, 2], [3, 4]] >>> copy_matrix([[1, 2, 3], [4, 5, 6]]) [[1, 2, 3], [4, 5, 6]] >>> copy_matrix([[1, 2], [3, 4], [5, 6], [7, 8]]) [[1, 2], [3, 4], [5, 6], [7, 8]] >>> m = [[1, 0, 0], [0, 2, 0], [0, 0, 3]] >>> copyofm = copy_matrix(m) >>> copyofm [[1, 0, 0], [0, 2, 0], [0, 0, 3]] >>> for row_num, row in enumerate(copyofm): ... for col_num, col_val in enumerate(row): ... copyofm[row_num][col_num] = 42 ... >>> copyofm [[42, 42, 42], [42, 42, 42], [42, 42, 42]] >>> m [[1, 0, 0], [0, 2, 0], [0, 0, 3]] """

Then add each of the following functions to the

`matrices.py`

module, one at a time, making sure the doctests pass for each one before adding the next.def add_row(matrix): """ >>> m = [[0, 0], [0, 0]] >>> add_row(m) [[0, 0], [0, 0], [0, 0]] >>> n = [[3, 2, 5], [1, 4, 7]] >>> add_row(n) [[3, 2, 5], [1, 4, 7], [0, 0, 0]] >>> n [[3, 2, 5], [1, 4, 7]] """

def add_column(matrix): """ >>> m = [[0, 0], [0, 0]] >>> add_column(m) [[0, 0, 0], [0, 0, 0]] >>> n = [[3, 2], [5, 1], [4, 7]] >>> add_column(n) [[3, 2, 0], [5, 1, 0], [4, 7, 0]] >>> n [[3, 2], [5, 1], [4, 7]] """

Your new functions should pass the doctests. Note that the last doctest in each function assures that

`add_row`

and`add_column`

are pure functions. (*note:*Python has a`copy`

module with a function named`deepcopy`

that could make the task easier here, or you could use your own`copy_matrix`

function.)Write a function

`add_matrices(m1, m2)`

that adds`m1`

and`m2`

and returns a new matrix containing their sum. You can assume that`m1`

and`m2`

are the same size. You add two matrices by adding their corresponding values.def add_matrices(m1, m2): """ >>> a = [[1, 2], [3, 4]] >>> b = [[2, 2], [2, 2]] >>> add_matrices(a, b) [[3, 4], [5, 6]] >>> c = [[8, 2], [3, 4], [5, 7]] >>> d = [[3, 2], [9, 2], [10, 12]] >>> add_matrices(c, d) [[11, 4], [12, 6], [15, 19]] >>> c [[8, 2], [3, 4], [5, 7]] >>> d [[3, 2], [9, 2], [10, 12]] """

Add your new function to

`matrices.py`

and be sure it passes the doctests above. The last two doctests confirm that`add_matrices`

is a pure function.Write a function

`scalar_mult(s, m)`

that multiplies a matrix,`m`

, by a scalar,`s`

.def scalar_mult(s, m): """ >>> a = [[1, 2], [3, 4]] >>> scalar_mult(3, a) [[3, 6], [9, 12]] >>> b = [[3, 5, 7], [1, 1, 1], [0, 2, 0], [2, 2, 3]] >>> scalar_mult(10, b) [[30, 50, 70], [10, 10, 10], [0, 20, 0], [20, 20, 30]] >>> b [[3, 5, 7], [1, 1, 1], [0, 2, 0], [2, 2, 3]] """

Add your new function to

`matrices.py`

and be sure it passes the doctests above.Write functions

`row_times_column`

and`matrix_mult`

:def row_times_column(m1, row, m2, column): """ >>> row_times_column([[1, 2], [3, 4]], 0, [[5, 6], [7, 8]], 0) 19 >>> row_times_column([[1, 2], [3, 4]], 0, [[5, 6], [7, 8]], 1) 22 >>> row_times_column([[1, 2], [3, 4]], 1, [[5, 6], [7, 8]], 0) 43 >>> row_times_column([[1, 2], [3, 4]], 1, [[5, 6], [7, 8]], 1) 50 """

def matrix_mult(m1, m2): """ >>> matrix_mult([[1, 2], [3, 4]], [[5, 6], [7, 8]]) [[19, 22], [43, 50]] >>> matrix_mult([[1, 2, 3], [4, 5, 6]], [[7, 8], [9, 1], [2, 3]]) [[31, 19], [85, 55]] >>> matrix_mult([[7, 8], [9, 1], [2, 3]], [[1, 2, 3], [4, 5, 6]]) [[39, 54, 69], [13, 23, 33], [14, 19, 24]] """

Add your new functions to

`matrices.py`

and be sure it passes the doctests above.Write a function

`transpose`

that takes a matrix as an argument and returns is transpose:def transpose(m): """ >>> m = [[3, 4, 6]] >>> transpose(m) [[3], [4], [6]] >>> m [3, 4, 6] >>> m = [[3, 4, 6], [1, 5, 9]] >>> transpose(m) [[3, 1], [4, 5], [6, 9]] """

*Extra challenge for the mathematically inclined*: Add a function`cross_product(u, v)`

to your`vectors.py`

module that takes two lists of numbers of length 3 and returns their cross product. You should write your own doctests and use the test driven development process described in the chapter.