1
0

Prepare vector_mpi.py for proper implementation

This commit is contained in:
Niklas Birk 2024-02-26 00:31:48 +01:00
parent 3a4c0ed75d
commit 897fba6fb4

View File

@ -1,363 +1,365 @@
import numpy as np
from mpi4py import MPI from mpi4py import MPI
class Vector: class VectorMPI:
start_idx = 0 # Nullter Eintrag des Vektors auf dem aktuellen Rang ...
end_idx = 0 # Letzer Eintrag des Vektors auf dem aktuellen Rang
rank_size = 0 # Dimension des Vektors der auf dem aktuellen Rang gespeichert wird
kind = '' # Art des Vektors, Zeilen oder Spaltenvektor
vec = np.arange(rank_size)
vshape = np.arange(2) # Array mit Länge 2, um die Shape des Vektors zu speichern
dim = 0 # Gesamtdimension des Vektors, Länge des Vektors
comm = MPI.COMM_WORLD # class Vector:
size = comm.Get_size() # start_idx = 0 # Nullter Eintrag des Vektors auf dem aktuellen Rang
rank = comm.Get_rank() # end_idx = 0 # Letzer Eintrag des Vektors auf dem aktuellen Rang
# rank_size = 0 # Dimension des Vektors der auf dem aktuellen Rang gespeichert wird
# Konstruktor # kind = '' # Art des Vektors, Zeilen oder Spaltenvektor
def __init__(self, array): # vec = np.arange(rank_size)
# vshape = np.arange(2) # Array mit Länge 2, um die Shape des Vektors zu speichern
if isinstance(array, np.ndarray): # dim = 0 # Gesamtdimension des Vektors, Länge des Vektors
form = array.shape #
if len(array) < self.size: # comm = MPI.COMM_WORLD
raise ValueError("ERROR_3: Die Dimension des Vektors ist kleiner als die Anzahl der benutzten Ränge.") # size = comm.Get_size()
# rank = comm.Get_rank()
if len(form) > 2: #
raise ValueError("ERROR_2: Falsche Dimension, kann kein 1 x n oder n x 1 Vektor sein.") # # Konstruktor
# Array ist Zeilenvektor: # def __init__(self, array):
if len(form) == 1 or (len(form) == 2 and form[0] == 1): #
self.vshape[0] = 1 # if isinstance(array, np.ndarray):
self.vshape[1] = len(array) # Shape des Vectors # form = array.shape
self.start_idx = int(self.rank * len(array) / self.size) # if len(array) < self.size:
self.end_idx = int(len(array) / self.size + self.rank * len(array) / self.size) - 1 # raise ValueError("ERROR_3: Die Dimension des Vektors ist kleiner als die Anzahl der benutzten Ränge.")
self.rank_size = ( #
self.end_idx - self.start_idx) + 1 # Größe des Teilvektors auf dem akt. Rang: Differenz zw. Start- und Endindex + 1 # if len(form) > 2:
self.vec = array[ # raise ValueError("ERROR_2: Falsche Dimension, kann kein 1 x n oder n x 1 Vektor sein.")
self.start_idx: self.end_idx + 1] # Auf jedem Rang werden die Einträge vom Start bis zum Endindex gespeichert # # Array ist Zeilenvektor:
self.kind = 'row' # if len(form) == 1 or (len(form) == 2 and form[0] == 1):
self.dim = len(array) # self.vshape[0] = 1
# self.vshape[1] = len(array) # Shape des Vectors
# Array ist Spaltenvektor # self.start_idx = int(self.rank * len(array) / self.size)
if len(form) == 2 and form[1] == 1: # self.end_idx = int(len(array) / self.size + self.rank * len(array) / self.size) - 1
self.vshape[0] = len(array) # self.rank_size = (
self.vshape[1] = 1 # self.end_idx - self.start_idx) + 1 # Größe des Teilvektors auf dem akt. Rang: Differenz zw. Start- und Endindex + 1
self.start_idx = int(self.rank * len(array) / self.size) # self.vec = array[
self.end_idx = int(len(array) / self.size + self.rank * len(array) / self.size) - 1 # self.start_idx: self.end_idx + 1] # Auf jedem Rang werden die Einträge vom Start bis zum Endindex gespeichert
self.rank_size = ( # self.kind = 'row'
self.end_idx - self.start_idx) + 1 # Größe des Teilvektors auf dem akt. Rang: Differenz zw. Start- und Endindex + 1 # self.dim = len(array)
self.vec = array[ #
self.start_idx: self.end_idx + 1] # Auf jedem Rang werden die Einträge vom Start bis zum Endindex gespeichert # # Array ist Spaltenvektor
self.kind = 'column' # if len(form) == 2 and form[1] == 1:
self.dim = len(array) # self.vshape[0] = len(array)
# self.vshape[1] = 1
elif isinstance(array, list): # self.start_idx = int(self.rank * len(array) / self.size)
self.vshape[0] = 1 # self.end_idx = int(len(array) / self.size + self.rank * len(array) / self.size) - 1
self.vshape[1] = len(array) # self.rank_size = (
self.start_idx = int(self.rank * len(array) / self.size) # self.end_idx - self.start_idx) + 1 # Größe des Teilvektors auf dem akt. Rang: Differenz zw. Start- und Endindex + 1
self.end_idx = int(len(array) / self.size + self.rank * len(array) / self.size) - 1 # self.vec = array[
self.rank_size = (self.end_idx - self.start_idx) + 1 # self.start_idx: self.end_idx + 1] # Auf jedem Rang werden die Einträge vom Start bis zum Endindex gespeichert
self.vec = np.array(array[self.start_idx:self.end_idx + 1]) # self.kind = 'column'
self.kind = 'row' # self.dim = len(array)
self.dim = len(array) #
else: # elif isinstance(array, list):
raise ValueError( # self.vshape[0] = 1
"ERROR_1: Die übergebene Variable ist kein Numpy-Array, Keine Initialisierung der Vector-Klasse möglich.") # self.vshape[1] = len(array)
# self.start_idx = int(self.rank * len(array) / self.size)
def __add__(self, other): # Überschreibung der Addition # self.end_idx = int(len(array) / self.size + self.rank * len(array) / self.size) - 1
if isinstance(self, Vector) and isinstance(other, Vector): # self.rank_size = (self.end_idx - self.start_idx) + 1
Add_Vec = Vector(np.arange(self.dim)) # self.vec = np.array(array[self.start_idx:self.end_idx + 1])
if self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[1]: # self.kind = 'row'
for i in range(0, self.rank_size): # self.dim = len(array)
Add_Vec.vec[i] = self.vec[i] + other.vec[i] # else:
else: # raise ValueError(
raise ValueError("Die Dimensionen der Vektoren stimmen nicht überein, Addition nicht möglich.") # "ERROR_1: Die übergebene Variable ist kein Numpy-Array, Keine Initialisierung der Vector-Klasse möglich.")
elif isinstance(self, Vector) and isinstance(other, (int, float, complex)): #
Add_Vec = Vector(np.arange(self.dim)) # def __add__(self, other): # Überschreibung der Addition
for i in range(0, self.rank_size): # if isinstance(self, Vector) and isinstance(other, Vector):
Add_Vec.vec[i] = self.vec[i] + other # Add_Vec = Vector(np.arange(self.dim))
elif isinstance(self, (int, float, complex)) and isinstance(other, Vector): # if self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[1]:
Add_Vec = Vector(np.arange(other.dim)) # for i in range(0, self.rank_size):
for i in range(0, other.rank_size): # Add_Vec.vec[i] = self.vec[i] + other.vec[i]
Add_Vec.vec[i] = other.vec[i] + self # else:
else: # raise ValueError("Die Dimensionen der Vektoren stimmen nicht überein, Addition nicht möglich.")
raise ValueError("Ungeeigneter Datentyp für die Addition mit einem Vektor.") # elif isinstance(self, Vector) and isinstance(other, (int, float, complex)):
return Add_Vec # Add_Vec = Vector(np.arange(self.dim))
# for i in range(0, self.rank_size):
def __radd__(self, other): # Überschreibung der Addition eines Vektors von rechts # Add_Vec.vec[i] = self.vec[i] + other
Vector(np.arange(self.dim)) # elif isinstance(self, (int, float, complex)) and isinstance(other, Vector):
if isinstance(self, Vector) and isinstance(other, (int, float, complex)): # Add_Vec = Vector(np.arange(other.dim))
Add_Vec = Vector(np.arange(self.dim)) # for i in range(0, other.rank_size):
for i in range(0, self.rank_size): # Add_Vec.vec[i] = other.vec[i] + self
Add_Vec.vec[i] = self.vec[i] + other # else:
else: # raise ValueError("Ungeeigneter Datentyp für die Addition mit einem Vektor.")
raise ValueError("Ungeeigneter Datentyp für die Addition mit einem Vektor.") # return Add_Vec
return Add_Vec #
# def __radd__(self, other): # Überschreibung der Addition eines Vektors von rechts
def __sub__(self, other): # Überschreibung der Subtraktion # Vector(np.arange(self.dim))
if isinstance(self, Vector) and isinstance(other, Vector): # if isinstance(self, Vector) and isinstance(other, (int, float, complex)):
Sub_Vec = Vector(np.arange(self.dim)) # Add_Vec = Vector(np.arange(self.dim))
if self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[1]: # for i in range(0, self.rank_size):
for i in range(0, self.rank_size): # Add_Vec.vec[i] = self.vec[i] + other
Sub_Vec.vec[i] = self.vec[i] - other.vec[i] # else:
else: # raise ValueError("Ungeeigneter Datentyp für die Addition mit einem Vektor.")
raise ValueError("Die Dimension der Vektoren stimmen nicht überein, Subtraktion nicht möglich.") # return Add_Vec
elif isinstance(self, Vector) and isinstance(other, (int, float, complex)): #
Sub_Vec = Vector(np.arange(self.dim)) # def __sub__(self, other): # Überschreibung der Subtraktion
for i in range(0, self.rank_size): # if isinstance(self, Vector) and isinstance(other, Vector):
Sub_Vec.vec[i] = self.vec[i] - other # Sub_Vec = Vector(np.arange(self.dim))
elif isinstance(self, (int, float, complex)) and isinstance(other, Vector): # if self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[1]:
Sub_Vec = Vector(np.arange(self.dim)) # for i in range(0, self.rank_size):
for i in range(0, other.rank_size): # Sub_Vec.vec[i] = self.vec[i] - other.vec[i]
Sub_Vec.vec[i] = other.vec[i] - self # else:
else: # raise ValueError("Die Dimension der Vektoren stimmen nicht überein, Subtraktion nicht möglich.")
raise ValueError("Ungeeigneter Datentyp für die Subtraktion mit einem Vektor.") # elif isinstance(self, Vector) and isinstance(other, (int, float, complex)):
return Sub_Vec # Sub_Vec = Vector(np.arange(self.dim))
# for i in range(0, self.rank_size):
def __rsub__(self, other): # Subtraktion einer Zahl von einem Vektor # Sub_Vec.vec[i] = self.vec[i] - other
Sub_Vec = Vector(np.arange(self.dim)) # elif isinstance(self, (int, float, complex)) and isinstance(other, Vector):
if isinstance(self, Vector) and isinstance(other, (float, int, complex)): # Sub_Vec = Vector(np.arange(self.dim))
for i in range(0, self.rank_size): # for i in range(0, other.rank_size):
Sub_Vec.vec[i] = self.vec[i] - other # Sub_Vec.vec[i] = other.vec[i] - self
else: # else:
raise ValueError("Ungeeigneter Datentyp für die Subtraktion von einem Vektor.") # raise ValueError("Ungeeigneter Datentyp für die Subtraktion mit einem Vektor.")
return Sub_Vec # return Sub_Vec
#
def __mul__(self, other): # Überschreibung der Multiplikation # def __rsub__(self, other): # Subtraktion einer Zahl von einem Vektor
if isinstance(self, Vector) and isinstance(other, Vector): # Sub_Vec = Vector(np.arange(self.dim))
Mult_Vec = Vector(np.arange(self.dim)) # if isinstance(self, Vector) and isinstance(other, (float, int, complex)):
if (self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[ # for i in range(0, self.rank_size):
1]): # Elementweise Multiplikation # Sub_Vec.vec[i] = self.vec[i] - other
for i in range(0, self.rank_size): # else:
Mult_Vec.vec[i] = self.vec[i] * other.vec[i] # raise ValueError("Ungeeigneter Datentyp für die Subtraktion von einem Vektor.")
elif self.vshape[1] == other.vshape[0] and self.vshape[0] == 1: # Inneres Produkt (Skalarprodukt) # return Sub_Vec
skal_prod = 0 #
for i in range(0, self.rank_size): # def __mul__(self, other): # Überschreibung der Multiplikation
skal_prod = skal_prod + self.vec[i] * other.vec[i] # if isinstance(self, Vector) and isinstance(other, Vector):
return skal_prod # Mult_Vec = Vector(np.arange(self.dim))
elif self.vshape[0] == other.vshape[1] and self.vshape[1] == 1: # if (self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[
raise ValueError("Kann erst implementiert werden, wenn Matrix-Klasse existiert.") # 1]): # Elementweise Multiplikation
else: # for i in range(0, self.rank_size):
raise ValueError("Die Dimensionen der Vektoren stimmen nicht überein, Multiplikation nicht möglich.") # Mult_Vec.vec[i] = self.vec[i] * other.vec[i]
elif isinstance(self, Vector) and isinstance(other, (int, float, complex)): # elif self.vshape[1] == other.vshape[0] and self.vshape[0] == 1: # Inneres Produkt (Skalarprodukt)
Mult_Vec = Vector(np.arange(self.dim)) # skal_prod = 0
for i in range(0, self.rank_size): # for i in range(0, self.rank_size):
Mult_Vec.vec[i] = self.vec[i] * other # skal_prod = skal_prod + self.vec[i] * other.vec[i]
elif isinstance(self, (int, float, complex)) and isinstance(other, Vector): # return skal_prod
Mult_Vec = Vector(np.arange(self.dim)) # elif self.vshape[0] == other.vshape[1] and self.vshape[1] == 1:
for i in range(0, other.rank_size): # raise ValueError("Kann erst implementiert werden, wenn Matrix-Klasse existiert.")
Mult_Vec.vec[i] = other.vec[i] * self # else:
else: # raise ValueError("Die Dimensionen der Vektoren stimmen nicht überein, Multiplikation nicht möglich.")
raise ValueError("Ungeeigneter Datentyp für die Multiplikation mit einem Vektor.") # elif isinstance(self, Vector) and isinstance(other, (int, float, complex)):
return Mult_Vec # Mult_Vec = Vector(np.arange(self.dim))
# for i in range(0, self.rank_size):
def __rmul__(self, other): # Rechtsseitige Multiplikation von einer Zahl an einen Vektor # Mult_Vec.vec[i] = self.vec[i] * other
Mult_Vec = Vector(np.arange(self.dim)) # elif isinstance(self, (int, float, complex)) and isinstance(other, Vector):
if isinstance(self, Vector) and isinstance(other, (int, float, complex)): # Mult_Vec = Vector(np.arange(self.dim))
for i in range(0, self.rank_size): # for i in range(0, other.rank_size):
Mult_Vec.vec[i] = self.vec[i] * other # Mult_Vec.vec[i] = other.vec[i] * self
else: # else:
raise ValueError("Ungeeigneter Datentyp für die Multiplikation mit einem Vektor.") # raise ValueError("Ungeeigneter Datentyp für die Multiplikation mit einem Vektor.")
return Mult_Vec # return Mult_Vec
#
def __truediv__(self, other): # def __rmul__(self, other): # Rechtsseitige Multiplikation von einer Zahl an einen Vektor
Div_Vec = Vector(np.arange(self.dim, dtype=np.double)) # Mult_Vec = Vector(np.arange(self.dim))
if isinstance(self, Vector) and isinstance(other, Vector): # if isinstance(self, Vector) and isinstance(other, (int, float, complex)):
if self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[1]: # for i in range(0, self.rank_size):
for i in range(0, self.rank_size): # Mult_Vec.vec[i] = self.vec[i] * other
if other.vec[i] == 0: # else:
raise ValueError("Ein Eintrag des Divisor-Vektors ist 0, Divion nicht möglich.") # raise ValueError("Ungeeigneter Datentyp für die Multiplikation mit einem Vektor.")
Div_Vec.vec[i] = self.vec[i] / other.vec[i] # return Mult_Vec
else: #
raise ValueError("Die Dimensionen der Vektoren stimmen nicht überein, Division nicht möglich.") # def __truediv__(self, other):
elif isinstance(self, (int, float, complex)) and isinstance(other, Vector): # Div_Vec = Vector(np.arange(self.dim, dtype=np.double))
for i in range(0, other.rank_size): # if isinstance(self, Vector) and isinstance(other, Vector):
if other.vec[i] == 0: # if self.vshape[0] == other.vshape[0] and self.vshape[1] == other.vshape[1]:
raise ValueError("Ein Eintrag des Divisor-Vektors ist 0, Divion nicht möglich.") # for i in range(0, self.rank_size):
Div_Vec.vec[i] = self / other.vec[i] # if other.vec[i] == 0:
elif isinstance(self, Vector) and isinstance(other, (float, int, complex)): # raise ValueError("Ein Eintrag des Divisor-Vektors ist 0, Divion nicht möglich.")
if other == 0: # Div_Vec.vec[i] = self.vec[i] / other.vec[i]
raise ValueError("Division durch Null ist nicht möglich.") # else:
else: # raise ValueError("Die Dimensionen der Vektoren stimmen nicht überein, Division nicht möglich.")
for i in range(0, self.rank_size): # elif isinstance(self, (int, float, complex)) and isinstance(other, Vector):
Div_Vec.vec[i] = self.vec[i] / other # for i in range(0, other.rank_size):
else: # if other.vec[i] == 0:
raise ValueError("ERROR 11: Ungeeigneter Datentyp für die Division mit einem Vektor.") # raise ValueError("Ein Eintrag des Divisor-Vektors ist 0, Divion nicht möglich.")
return Div_Vec # Div_Vec.vec[i] = self / other.vec[i]
# elif isinstance(self, Vector) and isinstance(other, (float, int, complex)):
def __rtruediv__(self, other): # if other == 0:
Div_Vec = Vector(np.arange(self.dim, dtype=np.double)) # raise ValueError("Division durch Null ist nicht möglich.")
if isinstance(self, Vector) and isinstance(other, (float, int, complex)): # else:
if other == 0: # for i in range(0, self.rank_size):
raise ValueError("Division durch Null ist nicht möglich.") # Div_Vec.vec[i] = self.vec[i] / other
else: # else:
for i in range(0, self.rank_size): # raise ValueError("ERROR 11: Ungeeigneter Datentyp für die Division mit einem Vektor.")
Div_Vec.vec[i] = self.vec[i] / other # return Div_Vec
else: #
raise ValueError("ERROR 10: Uneignete Datentyp, um einen Vektor durch diesen zu dividieren") # def __rtruediv__(self, other):
return Div_Vec # Div_Vec = Vector(np.arange(self.dim, dtype=np.double))
# if isinstance(self, Vector) and isinstance(other, (float, int, complex)):
def __neg__(self): # if other == 0:
Neg_Vec = -1 * self # raise ValueError("Division durch Null ist nicht möglich.")
return Neg_Vec # else:
# for i in range(0, self.rank_size):
def shape(self): # Div_Vec.vec[i] = self.vec[i] / other
if self.rank == 0: # else:
return self.vshape # raise ValueError("ERROR 10: Uneignete Datentyp, um einen Vektor durch diesen zu dividieren")
# return Div_Vec
def T(self): #
Transpose = self # def __neg__(self):
if self.kind == 'row': # Neg_Vec = -1 * self
Transpose.kind = 'column' # return Neg_Vec
else: #
Transpose.kind = 'row' # def shape(self):
# if self.rank == 0:
# Tauschen der Dimensionen # return self.vshape
var_shift = self.vshape[0] #
Transpose.vshape[0] = self.vshape[1] # def T(self):
Transpose.vshape[1] = var_shift # Transpose = self
return Transpose # if self.kind == 'row':
# Transpose.kind = 'column'
def str(self): # Rückgabe des gesamten Vektors als string # else:
str_rep = '' # Transpose.kind = 'row'
#
if self.rank == 0: # # Tauschen der Dimensionen
if self.kind == 'row': # var_shift = self.vshape[0]
str_rep = '[' + ','.join(map(str, self.vec)) # Transpose.vshape[0] = self.vshape[1]
if self.kind == 'column': # Transpose.vshape[1] = var_shift
str_rep = '[' + '\n'.join(map(str, self.vec)) # return Transpose
if self.size > 1: #
self.comm.send(str_rep, dest=self.rank + 1) # def str(self): # Rückgabe des gesamten Vektors als string
# str_rep = ''
elif self.rank == self.size - 1: #
if self.kind == 'row': # if self.rank == 0:
str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(map(str, self.vec)) # if self.kind == 'row':
if self.kind == 'column': # str_rep = '[' + ','.join(map(str, self.vec))
str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(map(str, self.vec)) # if self.kind == 'column':
# str_rep = '[' + '\n'.join(map(str, self.vec))
else: # if self.size > 1:
if self.kind == 'row': # self.comm.send(str_rep, dest=self.rank + 1)
str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(map(str, self.vec)) #
if self.kind == 'column': # elif self.rank == self.size - 1:
str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(map(str, self.vec)) # if self.kind == 'row':
self.comm.send(str_rep, dest=self.rank + 1) # str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(map(str, self.vec))
# if self.kind == 'column':
str_rep = self.comm.bcast(str_rep, root=self.size - 1) # str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(map(str, self.vec))
if self.rank == 0: #
return str_rep + ']' # else:
# if self.kind == 'row':
def string(self, limit_entry): # Gibt den Vektor als String zurück bis zum Eintrag limit_entry # str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(map(str, self.vec))
str_rep = '' # if self.kind == 'column':
# str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(map(str, self.vec))
if limit_entry > self.vec_size: # self.comm.send(str_rep, dest=self.rank + 1)
raise ValueError("ERROR_4: Die eingegebene Zahl ist größer, als der größte Index des Vectors.") #
# str_rep = self.comm.bcast(str_rep, root=self.size - 1)
# Rank 0 # if self.rank == 0:
if self.rank == 0 and limit_entry <= self.end_idx: # Limit_entry befindet sich im Rang 0 # return str_rep + ']'
if self.kind == 'row': #
str_rep = '[' + ','.join(map(str, self.vec[:limit_entry])) # def string(self, limit_entry): # Gibt den Vektor als String zurück bis zum Eintrag limit_entry
if self.kind == 'column': # str_rep = ''
str_rep = '[' + '\n'.join(map(str, self.vec[:limit_entry])) #
if self.size > 1: # if limit_entry > self.vec_size:
self.comm.send(str_rep, dest=self.rank + 1) # raise ValueError("ERROR_4: Die eingegebene Zahl ist größer, als der größte Index des Vectors.")
if self.rank == 0 and limit_entry > self.end_idx: # Limit_entry befindet sich nicht im Rang 0 #
if self.kind == 'row': # # Rank 0
str_rep = '[' + ','.join(map(str, self.vec)) # if self.rank == 0 and limit_entry <= self.end_idx: # Limit_entry befindet sich im Rang 0
if self.kind == 'column': # if self.kind == 'row':
str_rep = '[' + '\n'.join(map(str, self.vec)) # str_rep = '[' + ','.join(map(str, self.vec[:limit_entry]))
if self.size > 1: # if self.kind == 'column':
self.comm.send(str_rep, dest=self.rank + 1) # str_rep = '[' + '\n'.join(map(str, self.vec[:limit_entry]))
# if self.size > 1:
# Rank im Intervall [1,size-1] # self.comm.send(str_rep, dest=self.rank + 1)
if ( # if self.rank == 0 and limit_entry > self.end_idx: # Limit_entry befindet sich nicht im Rang 0
0 < self.rank < self.size - 1 and limit_entry <= self.start_idx): # wenn lim_ent == start_idx, dann wurden bereits alle relevanten Indizes im String gespeichert, da Vector nullinitialisiert ist # if self.kind == 'row':
str_rep = self.comm.recv(source=self.rank - 1) # str_rep = '[' + ','.join(map(str, self.vec))
self.comm.send(str_rep, dest=self.rank + 1) # if self.kind == 'column':
if ( # str_rep = '[' + '\n'.join(map(str, self.vec))
0 < self.rank < self.size - 1 and self.start_idx < limit_entry <= self.end_idx): # if self.size > 1:
if self.kind == 'row': # self.comm.send(str_rep, dest=self.rank + 1)
str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join( #
map(str, self.vec[:(limit_entry - self.start_idx)])) # # Rank im Intervall [1,size-1]
if self.kind == 'column': # if (
str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join( # 0 < self.rank < self.size - 1 and limit_entry <= self.start_idx): # wenn lim_ent == start_idx, dann wurden bereits alle relevanten Indizes im String gespeichert, da Vector nullinitialisiert ist
map(str, self.vec[:(limit_entry - self.start_idx)])) + ']' # str_rep = self.comm.recv(source=self.rank - 1)
self.comm.send(str_rep, dest=self.rank + 1) # self.comm.send(str_rep, dest=self.rank + 1)
if 0 < self.rank < self.size - 1 and limit_entry > self.end_idx: # if (
if self.kind == 'row': # 0 < self.rank < self.size - 1 and self.start_idx < limit_entry <= self.end_idx):
str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(map(str, self.vec)) # if self.kind == 'row':
if self.kind == 'column': # str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(
str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(map(str, self.vec)) # map(str, self.vec[:(limit_entry - self.start_idx)]))
self.comm.send(str_rep, dest=self.rank + 1) # if self.kind == 'column':
# str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(
# Rank size-1 # map(str, self.vec[:(limit_entry - self.start_idx)])) + ']'
if self.rank == self.size - 1 and limit_entry <= self.start_idx and self.rank > 1: # self.comm.send(str_rep, dest=self.rank + 1)
str_rep = self.comm.recv(source=self.rank - 1) # if 0 < self.rank < self.size - 1 and limit_entry > self.end_idx:
# if self.kind == 'row':
if self.rank == self.size - 1 and limit_entry >= self.start_idx and self.rank > 1: # str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(map(str, self.vec))
if self.kind == 'row': # if self.kind == 'column':
str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join( # str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(map(str, self.vec))
map(str, self.vec[:(limit_entry - self.start_idx)])) # self.comm.send(str_rep, dest=self.rank + 1)
if self.kind == 'column': #
str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join( # # Rank size-1
map(str, self.vec[:(limit_entry - self.start_idx)])) # if self.rank == self.size - 1 and limit_entry <= self.start_idx and self.rank > 1:
# str_rep = self.comm.recv(source=self.rank - 1)
str_rep = self.comm.bcast(str_rep, root=self.size - 1) #
if self.rank == 0: # if self.rank == self.size - 1 and limit_entry >= self.start_idx and self.rank > 1:
return str_rep + ']' # if self.kind == 'row':
# str_rep = self.comm.recv(source=self.rank - 1) + ',' + ','.join(
def norm(self): # Berechnung der 2-Norm / euklidischen Norm # map(str, self.vec[:(limit_entry - self.start_idx)]))
0 # if self.kind == 'column':
sum_of_squares = 0 # str_rep = self.comm.recv(source=self.rank - 1) + '\n' + '\n'.join(
if self.rank == 0: # map(str, self.vec[:(limit_entry - self.start_idx)]))
for i in range(0, self.rank_size): #
sum_of_squares = sum_of_squares + self.vec[i] ** 2 # str_rep = self.comm.bcast(str_rep, root=self.size - 1)
# if self.rank == 0:
if self.size > 1: # return str_rep + ']'
self.comm.send(sum_of_squares, dest=self.rank + 1) #
# def norm(self): # Berechnung der 2-Norm / euklidischen Norm
elif self.rank == self.size - 1: # 0
sum_of_squares = self.comm.recv(source=self.rank - 1) # sum_of_squares = 0
for i in range(0, self.rank_size): # if self.rank == 0:
sum_of_squares = sum_of_squares + self.vec[i] ** 2 # for i in range(0, self.rank_size):
# sum_of_squares = sum_of_squares + self.vec[i] ** 2
else: #
sum_of_squares = self.comm.recv(source=self.rank - 1) # if self.size > 1:
for i in range(0, self.rank_size): # self.comm.send(sum_of_squares, dest=self.rank + 1)
sum_of_squares = sum_of_squares + self.vec[i] ** 2 #
self.comm.send(sum_of_squares, dest=self.rank + 1) # elif self.rank == self.size - 1:
# sum_of_squares = self.comm.recv(source=self.rank - 1)
sum_of_squares = self.comm.bcast(sum_of_squares, root=self.size - 1) # for i in range(0, self.rank_size):
norm = np.sqrt(sum_of_squares) # sum_of_squares = sum_of_squares + self.vec[i] ** 2
#
return norm # else:
# sum_of_squares = self.comm.recv(source=self.rank - 1)
def normalize(self): # Normalisierung eines Vectors # for i in range(0, self.rank_size):
norm = self.norm() # sum_of_squares = sum_of_squares + self.vec[i] ** 2
if norm == 0: # self.comm.send(sum_of_squares, dest=self.rank + 1)
return self #
normalized_vec = self / norm # sum_of_squares = self.comm.bcast(sum_of_squares, root=self.size - 1)
return normalized_vec # norm = np.sqrt(sum_of_squares)
#
# return norm
# Main-Funktion #
x = Vector(np.arange(10)) # def normalize(self): # Normalisierung eines Vectors
print(x.str(), x.shape()) # norm = self.norm()
print(x.vshape[0], x.vshape[1]) # if norm == 0:
minus = -1 * x # return self
_x = -x # normalized_vec = self / norm
print(_x.str()) # return normalized_vec
print(minus.str()) #
y = Vector(2 * np.arange(10)) #
print(y.str()) # # Main-Funktion
z = x - y # x = Vector(np.arange(10))
print(z.str()) # print(x.str(), x.shape())
ae = x + 5 # print(x.vshape[0], x.vshape[1])
print(ae.str()) # minus = -1 * x
o = x * y # _x = -x
print(o.str()) # print(_x.str())
# print(minus.str())
a = Vector(np.array([[1], [2]])) # y = Vector(2 * np.arange(10))
b = Vector(np.array([1, 2])) # print(y.str())
print(a.shape()) # z = x - y
# c = a * b # print(z.str())
# print(c.vec) # ae = x + 5
# print(ae.str())
# o = x * y
# print(o.str())
#
# a = Vector(np.array([[1], [2]]))
# b = Vector(np.array([1, 2]))
# print(a.shape())
# # c = a * b
# # print(c.vec)