Chapter 5 Exercise Set 3: Vectors and Matrices

Vectors

  1. 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.

  2. 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]
        """
    
  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

  1. 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]]
        """
    
  2. 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.)

  3. 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.

  4. 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.

  5. 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.

  6. 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]]
       """
    
  7. 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.