1
0

Finalize matrix_mpi.py; Add more vector_mpi.py

This commit is contained in:
2024-04-16 23:21:56 +02:00
parent 987de6acf7
commit 6848bc7b26
8 changed files with 291 additions and 502 deletions

View File

@ -230,6 +230,51 @@ class TestMatrix(TestCase):
self.assertEqual(expected, actual)
def test_should_mul_matrices_4(self):
m1 = Matrix([1] * 6, (2, 3))
m2 = Matrix([1] * 15, (3, 5))
actual = m1 * m2
expected = Matrix([3] * 10, (2, 5))
self.assertEqual(expected, actual)
def test_should_mul_matrices_5(self):
m1 = Matrix([1] * 15, (3, 5))
m2 = Matrix([1] * 20, (5, 4))
actual = m1 * m2
expected = Matrix([5] * 12, (3, 4))
self.assertEqual(expected, actual)
def test_should_mul_matrices_6(self):
m1 = Matrix([1] * 15, (5, 3))
m2 = Matrix([1] * 12, (3, 4))
actual = m1 * m2
expected = Matrix([3] * 20, (5, 4))
self.assertEqual(expected, actual)
def test_should_mul_matrices_7(self):
m1 = Matrix(list(range(1, 21)), (4, 5))
m2 = Matrix(list(range(1, 16)), (5, 3))
actual = m1 * m2
expected = Matrix([135, 150, 165, 310, 350, 390, 485, 550, 615, 660, 750, 840], (4, 3))
self.assertEqual(expected, actual)
def test_should_mul_vector_matrix(self):
m1 = Matrix([1, 2, 3], (1, 3))
m2 = Matrix([6, 5, 4, 3, 2, 1], (3, 2))
actual = m1 * m2
expected = Matrix([20, 14], (1, 2))
self.assertEqual(expected, actual)
def test_should_raise_shape_missmatch_error_while_multiplying_matrices(self):
m1 = Matrix([1, 2], (2, 1))
m2 = Matrix([3, 4], (2, 1))

View File

@ -1,8 +1,8 @@
import numpy as np
from mpi4py import MPI
from matrix import Matrix
from vector import Vector
from matrix_mpi import MatrixMPI
from vector_mpi import VectorMPI
np.random.seed(0)
###############
@ -27,13 +27,11 @@ if rank == 0:
n_x1 = 10
x1_list = [i0 for i0 in
range(n_x1)] # must work for 4 ranks, too, so even if entries are not evenly distributable between ranks
#vec_x1 = Vector(comm, x1_list)
vec_x1 = Vector(x1_list)
vec_x1 = VectorMPI(x1_list)
# from numpy array
n_x2 = 10000
x2_list = np.random.uniform(0, 1, n_x2)
#vec_x2 = Vector(comm, x2_list)
vec_x2 = Vector(x2_list)
vec_x2 = VectorMPI(x2_list)
if rank == 0:
print("End 1a\n")
comm.Barrier()
@ -64,25 +62,21 @@ if rank == 0:
print("End 1c\n")
comm.Barrier()
### 1d addition and substraction
### 1d addition and subtraction
if rank == 0:
print("Start 1d addition and substraction")
# intitialization
print("Start 1d addition and subtraction ")
# initialization
n_a = 10
n_b = 10
a_list = [i0 for i0 in range(n_a)]
b_list = [1 / (i0 + 1) for i0 in range(n_b)]
#a = Vector(comm, a_list)
a = Vector(a_list)
#b = Vector(comm, b_list)
b = Vector(b_list)
a = VectorMPI(a_list)
b = VectorMPI(b_list)
# computation
x = a + b
y = a - b
#numpy_x_compare_norm = (x - Vector(comm, np.array(a_list) + np.array(b_list))).norm()
numpy_x_compare_norm = (x - Vector(np.array(a_list) + np.array(b_list))).norm()
#numpy_y_compare_norm = (y - Vector(comm, np.array(a_list) - np.array(b_list))).norm()
numpy_y_compare_norm = (y - Vector(np.array(a_list) - np.array(b_list))).norm()
numpy_x_compare_norm = (x - VectorMPI(np.array(a_list) + np.array(b_list))).norm()
numpy_y_compare_norm = (y - VectorMPI(np.array(a_list) - np.array(b_list))).norm()
if rank == 0:
print(f"norm(a + b - numpy) = {numpy_x_compare_norm} | must be < 1e-8")
print(f"norm(a - b - numpy) = {numpy_x_compare_norm} | must be < 1e-8")
@ -109,23 +103,19 @@ comm.Barrier()
### 1e multiplication
if rank == 0:
print("Start 1e multiplication")
# intitialization
# initialization
n_a = 10
n_b = 10
a_list = [i0 for i0 in range(n_a)]
b_list = [1 / (i0 + 1) for i0 in range(n_b)]
#a = Vector(comm, a_list)
a = Vector(a_list)
#b = Vector(comm, b_list)
b = Vector(b_list)
a = VectorMPI(a_list)
b = VectorMPI(b_list)
# computation with vectors
x = a.T() * b # scalar
y = a * b # vector
# z = b * a.T() # matrix
numpy_x_compare_norm = np.linalg.norm(x - np.sum(np.array(a_list) * np.array(b_list)))
#numpy_y_compare_norm = (y - Vector(comm, np.array(a_list) * np.array(b_list))).norm()
numpy_y_compare_norm = (y - Vector(np.array(a_list) * np.array(b_list))).norm()
# numpy_z_compare_norm = (z - Matrix(comm,np.outer(np.array(a_list),np.array(b_list)))).norm()
numpy_y_compare_norm = (y - VectorMPI(np.array(a_list) * np.array(b_list))).norm()
# numpy_z_compare_norm = (z - MatrixMPI(comm,np.outer(np.array(a_list),np.array(b_list)))).norm()
if rank == 0:
print(f"norm(a.T() * b - numpy) = {numpy_x_compare_norm} | must be < 1e-8")
print(f"norm(a * b - numpy) = {numpy_y_compare_norm} | must be < 1e-8")
@ -133,35 +123,29 @@ if rank == 0:
# computation with scalars
x = a * 5
y = 0.1 * b.T()
#numpy_x_compare_norm = (x - Vector(comm, np.array(a_list) * 5)).norm()
numpy_x_compare_norm = (x - Vector(np.array(a_list) * 5)).norm()
#numpy_y_compare_norm = (y - Vector(comm, np.array(b_list) * 0.1, transpose=True)).norm()
numpy_y_compare_norm = (y - Vector(np.array(b_list) * 0.1).T()).norm()
numpy_x_compare_norm = (x - VectorMPI(np.array(a_list) * 5)).norm()
numpy_y_compare_norm = (y - VectorMPI(np.array(b_list) * 0.1).T()).norm()
if rank == 0:
print(f"norm(a * 5 - numpy) = {numpy_x_compare_norm} | must be < 1e-8")
print(f"norm(0.1 * b.T() - numpy) = {numpy_y_compare_norm} | must be < 1e-8")
print("End 1e\n")
comm.Barrier()
### 1f divison
### 1f division
if rank == 0:
print("Start 1f divison")
# intitialization
print("Start 1f division")
# initialization
n_a = 10
n_b = 10
a_list = [i0 for i0 in range(n_a)]
b_list = [1 / (i0 + 1) for i0 in range(n_b)]
#a = Vector(comm, a_list)
a = Vector(a_list)
#b = Vector(comm, b_list)
b = Vector(b_list)
a = VectorMPI(a_list)
b = VectorMPI(b_list)
# computation with vectors
x = a / b
y = a / 5
#numpy_x_compare_norm = (x - Vector(comm, np.array(a_list) / np.array(b_list))).norm()
numpy_x_compare_norm = (x - Vector(np.array(a_list) / np.array(b_list))).norm()
#numpy_y_compare_norm = (y - Vector(comm, np.array(a_list) / 5)).norm()
numpy_y_compare_norm = (y - Vector(np.array(a_list) / 5)).norm()
numpy_x_compare_norm = (x - VectorMPI(np.array(a_list) / np.array(b_list))).norm()
numpy_y_compare_norm = (y - VectorMPI(np.array(a_list) / 5)).norm()
if rank == 0:
print(f"norm(a / b - numpy) = {numpy_x_compare_norm} | must be < 1e-8")
print(f"norm(a / 5 - numpy) = {numpy_y_compare_norm} | must be < 1e-8")
@ -171,16 +155,14 @@ comm.Barrier()
### 1g norm
if rank == 0:
print("Start 1g norm")
# intitialization
# initialization
a_list = [1 / (i0 + 1) for i0 in range(10)]
#a = Vector(comm, a_list)
a = Vector(a_list)
a = VectorMPI(a_list)
# computation
a_norm = a.norm()
a_normalized = a.normalize()
a_normalized_str = str(a_normalized)
#numpy_comparison_norm = (a_normalized - Vector(comm, np.array(a_list) / np.linalg.norm(a_list))).norm()
numpy_comparison_norm = (a_normalized - Vector(np.array(a_list) / np.linalg.norm(a_list))).norm()
numpy_comparison_norm = (a_normalized - VectorMPI(np.array(a_list) / np.linalg.norm(a_list))).norm()
if rank == 0:
print(f"a_norm = {a_norm} | must be {np.linalg.norm(a_list)}")
print(f"norm(a_normalize-np.a_normalize) = {numpy_comparison_norm} | must be < 1e-8")
@ -190,10 +172,9 @@ comm.Barrier()
### 1h negation
if rank == 0:
print("Start 1h negation")
# intitialization
# initialization
a_list = [1 / (i0 + 1) for i0 in range(10)]
#a = Vector(comm, a_list)
a = Vector(a_list)
a = VectorMPI(a_list)
# computation
x = -a
x_str = str(x)
@ -205,11 +186,10 @@ comm.Barrier()
### 1i manipulation
if rank == 0:
print("Start 1i manipulation")
# intitialization
# initialization
n_a = 10
a_list = [1 / (i0 + 1) for i0 in range(n_a)]
#a = Vector(comm, a_list)
a = Vector(a_list)
a = VectorMPI(a_list)
a_idx = [1, 2, 9, 7, 8]
a_values = a[a_idx]
if rank == 0:
@ -224,7 +204,6 @@ if rank == 0:
print("End 1i\n")
comm.Barrier()
"""
###############
# Testing the matrix class
comm.Barrier()
@ -232,18 +211,18 @@ if rank == 0:
print("\n\nTesting the matrix class -----------------------------------\n\n")
###############
### 2a Initialization
if rank == 0:
print("Start 2a initialization")
n_a1 = 10
n_a2 = 5
a_list = np.array([[(i0 + 1) * (i1 + 1) for i0 in range(n_a1)] for i1 in range(n_a2)])
A = Matrix(comm, a_list)
B = Matrix(comm, structure="tridiagonal", size=12)
A = MatrixMPI(a_list)
B = MatrixMPI(structure="tridiagonal", data=[-1, 2, -1], n=12)
c_list = [i0 for i0 in range(n_a1 * n_a1)]
C = Matrix(comm, c_list, shape=(n_a1, n_a1))
D = Matrix(comm, model="sheet1ex1", size=50)
C = MatrixMPI(c_list, shape=(n_a1, n_a1))
D = MatrixMPI(structure="tridiagonal", data=[-1, 2, -1], n=50)
# D = MatrixMPI(model="sheet1ex1", n=50)
if rank == 0:
print("End 2a\n")
comm.Barrier()
@ -284,29 +263,29 @@ comm.Barrier()
# if rank == 0:
# print(f"Matrix\n{str(mat)}\nlocal max each row {str(local_max_each_row)}")
# # frobenius norm
# A = Matrix(comm,mat)
# A = MatrixMPI(comm,mat)
# a_norm_fro = A.norm("frobenius")
# if rank == 0:
# print(f"A.norm('frobenius') = {a_norm_fro} | must be {np.linalg.norm(np.array([[(i0+1)*(i1+1) for i0 in range(10)] for i1 in range(5)]),'fro')}")
# # row sum norm
# a_norm_row = A.norm("row sum")
# if rank == 0:
# print(f"A.norm('row sum') = {a_norm_row} | must be {np.max(local_max_each_row)}")
# print(f"A.norm('row sum') = {a_norm_row} | must be {np.max(local_max_each_row)}")
# # col sum norm
### 2d addition and substraction
### 2d addition and subtraction
if rank == 0:
print("Start 2d addition and substraction")
print("Start 2d addition and subtraction ")
# Initialization
n = 10
A = Matrix(comm, structure="diagonal", diag_values=[3], offset=0, size=n)
A21 = Matrix(comm, structure="diagonal", diag_values=[-1], offset=-1, size=n)
A12 = Matrix(comm, structure="diagonal", diag_values=[-1], offset=+1, size=n)
B = Matrix(comm, structure="diagonal", diag_values=[1], offset=0, size=n)
A = MatrixMPI(structure="diagonal", data=[3], offset=0, n=n)
A21 = MatrixMPI(structure="diagonal", data=[-1], offset=-1, n=n)
A12 = MatrixMPI(structure="diagonal", data=[-1], offset=+1, n=n)
B = MatrixMPI(structure="diagonal", data=[1], offset=0, n=n)
# computation
C = A + A21 + A12 - B
D = C - Matrix(comm, structure='tridiagonal', diag_values=[-1, 2, -1], size=n)
D = C - MatrixMPI(structure='tridiagonal', data=[-1, 2, -1], n=n)
d_norm = D.norm()
A_str = str(5 + A - 3)
if rank == 0:
@ -324,19 +303,19 @@ a_mat = np.array([[(i0 + 1) / (i1 + 1) for i1 in range(8)] for i0 in range(n)])
b_mat = np.array([[(i0 + 1) / (i1 + 1) for i1 in range(n)] for i0 in range(8)])
c_mat = np.array([[(i0 + 1) / (i1 + 1) for i1 in range(n)] for i0 in range(n)])
d_mat = np.array([[(i0 + 1) / (i1 + 1) for i1 in range(17)] for i0 in range(n)])
A = Matrix(comm, a_mat)
B = Matrix(comm, b_mat)
C = Matrix(comm, c_mat)
D = Matrix(comm, d_mat)
A = MatrixMPI(a_mat)
B = MatrixMPI(b_mat)
C = MatrixMPI(c_mat)
D = MatrixMPI(d_mat)
x_vec = np.array([i0 + 1 for i0 in range(n)])
y_vec = np.array([n * (i0 + 1) for i0 in range(n)])
x = Vector(comm, x_vec)
y = Vector(comm, y_vec)
x = VectorMPI(x_vec)
y = VectorMPI(y_vec)
# computation matrix scalar
norm5 = (5 * A - Matrix(comm, 5 * np.array(a_mat))).norm()
norm5 = (5 * A - MatrixMPI(5 * np.array(a_mat))).norm()
# computation matrix vector
norm6 = (C * x - Vector(comm, np.array(c_mat) @ np.array(x_vec))).norm()
norm7 = (D.T() * x - Vector(comm, np.array(d_mat).T @ np.array(x_vec))).norm()
norm6 = (C * x - VectorMPI(np.array(c_mat) @ np.array(x_vec))).norm()
norm7 = (D.T() * x - VectorMPI(np.array(d_mat).T @ np.array(x_vec))).norm()
y_shape = (D.T() * x).shape()
if rank == 0:
print(f"Norm of (5*A - np.(5*A)) is {norm5} | must be < 1e-8")
@ -347,10 +326,10 @@ A_str = str(A)
B_str = str(B)
if rank == 0:
print(f"DEBUG: A\n{A_str}\nDEBUG: B\n{B_str}")
norm1 = (A * B - Matrix(comm, np.array(a_mat) @ np.array(b_mat))).norm()
norm2 = (A.T() * A - Matrix(np.array(a_mat).T @ np.array(a_mat))).norm()
norm3 = (A * A.T() - Matrix(np.array(a_mat) @ np.array(a_mat).T)).norm()
norm4 = (B.T() * A.T() - Matrix(np.array(b_mat).T @ np.array(a_mat).T)).norm()
norm1 = (A * B - MatrixMPI(np.array(a_mat) @ np.array(b_mat))).norm()
norm2 = (A.T() * A - MatrixMPI(np.array(a_mat).T @ np.array(a_mat))).norm()
norm3 = (A * A.T() - MatrixMPI(np.array(a_mat) @ np.array(a_mat).T)).norm()
norm4 = (B.T() * A.T() - MatrixMPI(np.array(b_mat).T @ np.array(a_mat).T)).norm()
if rank == 0:
print(f"Norm of (A*B - np.(A*B)) is {norm1} | must be < 1e-8")
print(f"Norm of (A.T()*A - np(A.T()*A)) is {norm2} | must be < 1e-8")
@ -359,48 +338,44 @@ if rank == 0:
print("End 2e\n")
comm.Barrier()
'''
### 2f divison
### 2f division
if rank == 0:
print("Start 2f divison")
print("Start 2f division")
# initialization
A = Matrix(a_mat)
A = MatrixMPI(a_mat)
# computation
print(f"Norm of (A/5 - np.(A/5)) is {(A/5 - Matrix(np.array(a_mat) / 5)).norm()} | must be < 1e-8")
print(f"Norm of (A/5 - np.(A/5)) is {(A / 5 - MatrixMPI(np.array(a_mat) / 5)).norm()} | must be < 1e-8")
if rank == 0:
print("End 2f\n")
print("End 2f\n")
comm.Barrier()
### 2g norm
if rank == 0:
print("Start 2g norm")
A = Matrix(structure="tridiagonal",given_size=50,given_values=[-1,2,-1])
print("Start 2g norm")
A = MatrixMPI(structure="tridiagonal", n=50, data=[-1, 2, -1])
print(f"Frobenius norm of tridiagonal matrix: {A.norm('frobenius')} | must be 17.263")
print(f"Row sum norm of tridiagonal matrix: {A.norm('row sum')} | must be 2")
print(f"Col sum norm of tridiagonal matrix: {A.norm('col sum')} | must be 2")
print(f"Row sum norm of tridiagonal matrix: {A.norm('row sum')} | must be 4")
print(f"Col sum norm of tridiagonal matrix: {A.norm('col sum')} | must be 4")
if rank == 0:
print("End 2g\n")
print("End 2g\n")
comm.Barrier()
### 2h negation
if rank == 0:
print("Start 2h negation")
A = Matrix(structure="tridiagonal", given_size=50, given_values=[-1,2,1])
print("Start 2h negation")
A = MatrixMPI(structure="tridiagonal", n=50, data=[-1, 2, 1])
print(f"Norm of (A + (-A)) is {(A + (-A)).norm('frobenius')} | must be < 1e-8")
if rank == 0:
print("End 2h\n")
print("End 2h\n")
comm.Barrier()
### 2i manipulation
if rank == 0:
print("Start 2i manipulation")
A = Matrix(structure="tridiagonal", given_size=10, given_values=[-1,2,1])
A[1,1] = 4
A[[1,2,3],2] = [-5,-10,100]
print("Start 2i manipulation")
A = MatrixMPI(structure="tridiagonal", n=10, data=[-1, 2, 1])
A[1, 1] = 4
A[[1, 2, 3], 2] = [-5, -10, 100]
print(str(A))
if rank == 0:
print("End 2i\n")
print("End 2i\n")
comm.Barrier()
'''
"""

View File

@ -1,5 +1,6 @@
from unittest import TestCase
from matrix import Matrix
from vector import Vector
@ -169,6 +170,24 @@ class TestVector(TestCase):
self.assertEqual(expected, actual)
def test_should_mul_matrix_vector(self):
m = Matrix([1, 2, 3, 4, 5, 6], (2, 3))
v = Vector([1, 2, 3])
expected = Vector([14, 32])
actual = m * v
self.assertEqual(expected, actual)
def test_should_mul_matrix_vector_2(self):
m = Matrix([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], (3, 4))
v = Vector([1, 2, 3, 4])
expected = Vector([30, 30, 30])
actual = m * v
self.assertEqual(expected, actual)
def test_should_raise_value_missmatch_error_while_mul_vectors(self):
v1 = Vector([1, 2])
v2 = '0'