Rewrite parts of Vector and Matrix (#5362)

* Rewrite parts of Vector and Matrix methods

* Refactor determinant method and add unit tests

Refactor determinant method to create separate minor and cofactor
methods.
Add respective unit tests for new methods.
Rename methods using snake case to follow Python naming conventions.

* Reorganize Vector and Matrix methods

* Update linear_algebra/README.md

Co-authored-by: John Law <johnlaw.po@gmail.com>

* Fix punctuation and wording

* Apply suggestions from code review

Co-authored-by: John Law <johnlaw.po@gmail.com>

Co-authored-by: John Law <johnlaw.po@gmail.com>
This commit is contained in:
Tianyi Zheng
2021-10-27 03:48:43 +00:00
committed by GitHub
parent 8285913e81
commit fe5c711ce6
4 changed files with 292 additions and 222 deletions

View File

@ -8,13 +8,20 @@ This file contains the test-suite for the linear algebra library.
"""
import unittest
from .lib import Matrix, Vector, axpy, squareZeroMatrix, unitBasisVector, zeroVector
from .lib import (
Matrix,
Vector,
axpy,
square_zero_matrix,
unit_basis_vector,
zero_vector,
)
class Test(unittest.TestCase):
def test_component(self) -> None:
"""
test for method component
test for method component()
"""
x = Vector([1, 2, 3])
self.assertEqual(x.component(0), 1)
@ -23,24 +30,24 @@ class Test(unittest.TestCase):
def test_str(self) -> None:
"""
test for toString() method
test for method toString()
"""
x = Vector([0, 0, 0, 0, 0, 1])
self.assertEqual(str(x), "(0,0,0,0,0,1)")
def test_size(self) -> None:
"""
test for size()-method
test for method size()
"""
x = Vector([1, 2, 3, 4])
self.assertEqual(len(x), 4)
def test_euclidLength(self) -> None:
"""
test for the eulidean length
test for method euclidean_length()
"""
x = Vector([1, 2])
self.assertAlmostEqual(x.euclidLength(), 2.236, 3)
self.assertAlmostEqual(x.euclidean_length(), 2.236, 3)
def test_add(self) -> None:
"""
@ -67,26 +74,26 @@ class Test(unittest.TestCase):
test for * operator
"""
x = Vector([1, 2, 3])
a = Vector([2, -1, 4]) # for test of dot-product
a = Vector([2, -1, 4]) # for test of dot product
b = Vector([1, -2, -1])
self.assertEqual(str(x * 3.0), "(3.0,6.0,9.0)")
self.assertEqual((a * b), 0)
def test_zeroVector(self) -> None:
"""
test for the global function zeroVector(...)
test for global function zero_vector()
"""
self.assertTrue(str(zeroVector(10)).count("0") == 10)
self.assertTrue(str(zero_vector(10)).count("0") == 10)
def test_unitBasisVector(self) -> None:
"""
test for the global function unitBasisVector(...)
test for global function unit_basis_vector()
"""
self.assertEqual(str(unitBasisVector(3, 1)), "(0,1,0)")
self.assertEqual(str(unit_basis_vector(3, 1)), "(0,1,0)")
def test_axpy(self) -> None:
"""
test for the global function axpy(...) (operation)
test for global function axpy() (operation)
"""
x = Vector([1, 2, 3])
y = Vector([1, 0, 1])
@ -94,7 +101,7 @@ class Test(unittest.TestCase):
def test_copy(self) -> None:
"""
test for the copy()-method
test for method copy()
"""
x = Vector([1, 0, 0, 0, 0, 0])
y = x.copy()
@ -102,53 +109,94 @@ class Test(unittest.TestCase):
def test_changeComponent(self) -> None:
"""
test for the changeComponent(...)-method
test for method change_component()
"""
x = Vector([1, 0, 0])
x.changeComponent(0, 0)
x.changeComponent(1, 1)
x.change_component(0, 0)
x.change_component(1, 1)
self.assertEqual(str(x), "(0,1,0)")
def test_str_matrix(self) -> None:
"""
test for Matrix method str()
"""
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
self.assertEqual("|1,2,3|\n|2,4,5|\n|6,7,8|\n", str(A))
def test_determinate(self) -> None:
def test_minor(self) -> None:
"""
test for determinate()
test for Matrix method minor()
"""
A = Matrix([[1, 1, 4, 5], [3, 3, 3, 2], [5, 1, 9, 0], [9, 7, 7, 9]], 4, 4)
self.assertEqual(-376, A.determinate())
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
minors = [[-3, -14, -10], [-5, -10, -5], [-2, -1, 0]]
for x in range(A.height()):
for y in range(A.width()):
self.assertEqual(minors[x][y], A.minor(x, y))
def test_cofactor(self) -> None:
"""
test for Matrix method cofactor()
"""
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
cofactors = [[-3, 14, -10], [5, -10, 5], [-2, 1, 0]]
for x in range(A.height()):
for y in range(A.width()):
self.assertEqual(cofactors[x][y], A.cofactor(x, y))
def test_determinant(self) -> None:
"""
test for Matrix method determinant()
"""
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
self.assertEqual(-5, A.determinant())
def test__mul__matrix(self) -> None:
"""
test for Matrix * operator
"""
A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3, 3)
x = Vector([1, 2, 3])
self.assertEqual("(14,32,50)", str(A * x))
self.assertEqual("|2,4,6|\n|8,10,12|\n|14,16,18|\n", str(A * 2))
def test_changeComponent_matrix(self) -> None:
def test_change_component_matrix(self) -> None:
"""
test for Matrix method change_component()
"""
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
A.changeComponent(0, 2, 5)
A.change_component(0, 2, 5)
self.assertEqual("|1,2,5|\n|2,4,5|\n|6,7,8|\n", str(A))
def test_component_matrix(self) -> None:
"""
test for Matrix method component()
"""
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
self.assertEqual(7, A.component(2, 1), 0.01)
def test__add__matrix(self) -> None:
"""
test for Matrix + operator
"""
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
B = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
self.assertEqual("|2,4,10|\n|4,8,10|\n|12,14,18|\n", str(A + B))
def test__sub__matrix(self) -> None:
"""
test for Matrix - operator
"""
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
B = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
self.assertEqual("|0,0,-4|\n|0,0,0|\n|0,0,-2|\n", str(A - B))
def test_squareZeroMatrix(self) -> None:
"""
test for global function square_zero_matrix()
"""
self.assertEqual(
"|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|" + "\n|0,0,0,0,0|\n",
str(squareZeroMatrix(5)),
"|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n",
str(square_zero_matrix(5)),
)