Compare commits

..

10 Commits

Author SHA1 Message Date
6b968f3505 Add project related project 2023-11-30 15:58:09 +01:00
265dc44c1c rm : 2023-11-29 21:00:31 +01:00
5dfd0ea8cd more uebung 05 2023-11-29 19:40:30 +01:00
4c00a2c0b1 Uebung 05 2023-11-29 19:28:40 +01:00
9ec5cbf084 add picture 2023-11-24 19:28:47 +01:00
81ae3a34e7 uebung 03 exercise 04 2023-11-24 19:05:20 +01:00
25d77e62e0 more stuff 2023-11-23 16:02:33 +01:00
4b90be609e Add exercise 06 in uebung 04 2023-11-22 22:08:18 +01:00
d927ce5999 remove stuff 2023-11-22 20:25:39 +01:00
23076081ee stuff 2023-11-22 20:24:25 +01:00
18 changed files with 998 additions and 0 deletions

3
.gitignore vendored
View File

@ -1,2 +1,5 @@
.idea/
target/
__pycache__
*.out
*.o

0
pwr_project/src/main.py Normal file
View File

View File

@ -0,0 +1,2 @@
class Matrix:

46
pwr_project/src/vector.py Normal file
View File

@ -0,0 +1,46 @@
class Vector:
__data__ = []
def __init__(self, data):
if isinstance(data, list):
self.__data__ = data
elif isinstance(data, int):
self.__init__([0] * data)
else:
raise ValueError("data must be a list or an integer for dimension")
def get_data(self):
return self.__data__
def get_dimension(self):
return len(self.__data__)
def __iter__(self):
return iter(self.__data__)
def __eq__(self, other):
return self.__data__ == other.__data__
def __str__(self):
return f"{self.__data__}"
def __add__(self, other):
if self.get_dimension() != other.get_dimension():
raise ValueError("The vectors to be added must have the same dimension")
data = []
for (i, j) in zip(self, other):
data.append(i + j)
return Vector(data)
def __mul__(self, other):
if isinstance(other, Vector):
...
elif isinstance(other, int) or isinstance(other, float):
...
else:
raise ValueError("A vector can only be multiplied with an vector (dot product) or a scalar")
def __rmul__(self, other):
return self * other

View File

@ -0,0 +1,47 @@
from unittest import TestCase
from vector import Vector
class TestVector(TestCase):
def test_should_create_vector_dim_5(self):
dim = 5
vector = Vector(dim)
actual = vector.get_dimension()
expected = dim
self.assertEqual(expected, actual)
def test_should_create_zero_vector(self):
dim = 5
vector = Vector(dim)
actual = vector.get_data()
expected = [0, 0, 0, 0, 0]
self.assertEqual(expected, actual)
def test_should_create_vector(self):
data = list(range(5))
vector = Vector(data)
actual = vector.get_data()
expected = [0, 1, 2, 3, 4]
self.assertEqual(expected, actual)
def test_should_add_vectors(self):
v1 = Vector([1, 2])
v2 = Vector([3, 4])
expected = Vector([4, 6])
actual = v1 + v2
self.assertEqual(expected, actual)
def test_should_raise_error_while_adding_vectors(self):
v1 = Vector(1)
v2 = Vector(2)
self.assertRaises(ValueError, lambda: v1 + v2)

View File

@ -0,0 +1,11 @@
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
if rank == 0:
data = "Hello, from process 0!"
comm.send(data, dest=1)
elif rank == 1:
received_data = comm.recv(source=0)
print(f"Process 1 received: {received_data}")

View File

@ -0,0 +1,23 @@
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
send_data = f"Hello, from process {rank}!"
print(f"I am rank {rank}. I send to process {(rank+1)}")
print(f"I am rank {rank}. I receive from process {(rank-1)}")
if rank == size-1:
comm.send(send_data, dest=(0))
else:
comm.send(send_data, dest=(rank + 1))
recv_data = ""
if rank == 0:
recv_data= comm.recv(source=(size - 1))
else:
recv_data= comm.recv(source=(rank - 1))
print(f"I am rank {rank}. I have received: {recv_data}")

View File

@ -0,0 +1,37 @@
from mpi4py import MPI
import numpy as np
import math
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
chunk = 0
if rank == 0:
N = 100000
x = np.random.uniform(0,1,(N,1))
chunksize = math.floor(N / size)
for i in range(1,size):
from_index = 0 + chunksize * i
to_index = (chunksize * (i + 1)) - 1
chunk = x[from_index:to_index]
comm.send(chunk, dest = i)
else:
chunk = comm.recv(source = 0)
chunk_sum = 0.0
for i in range(len(chunk)):
chunk_sum += chunk[i] * chunk[i]
if rank != 0:
comm.send(chunk_sum, dest = 0)
if rank == 0:
sum = chunk_sum
for i in range(1,size):
sum += comm.recv(source = i)
print(f"The squared euclidian norm of x is {sum[0]:.2f}.")

View File

@ -0,0 +1,33 @@
from mpi4py import MPI
import numpy as np
import math
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
chunk = 0
if rank == 0:
N = 100000
x = np.random.uniform(0,1,(N,1))
chunksize = math.floor(N / size)
for i in range(1,size):
from_index = 0 + chunksize * i
to_index = (chunksize * (i + 1)) - 1
chunk = x[from_index:to_index]
comm.send(chunk, dest = i)
else:
chunk = comm.recv(source = 0)
chunk_sum = 0.0
for i in range(len(chunk)):
chunk_sum += chunk[i] * chunk[i]
comm.Barrier()
sum = comm.reduce(chunk_sum, op = MPI.SUM, root = 0)
if rank == 0:
print(f"The squared euclidian norm of x is {sum[0]:.2f}.")

View File

@ -0,0 +1,41 @@
from mpi4py import MPI
import numpy as np
import math
import sys
def dot_product(a, x):
result = 0
for i in range(len(a)):
result += a[i] * x[i]
return result
def row(i):
row = []
for j in range(1, n+1):
row.append(i / j)
return row
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
n = int(sys.argv[1])
x = list(range(1, n+1))
# each rank should compute almost the same amount of matrix.row * x
# for this split the list [1,...,n+1] in sublists containing the rownumbers every rank has to compute
# if n is a multiple of size all ranks have the same amount to compute, if not, the first (n % size) ranks compute each one more
chunks = np.array_split(list(range(1,n+1)), size)
chunk = chunks[rank]
sub_b = []
for i in chunk:
sub_b.append(dot_product(row(i), x)) # every rank computes its delegated rows times x
comm.barrier()
b = comm.gather(sub_b)
if rank == 0:
b = np.concatenate(b).tolist() # b is a list of lists, np.concatenate 'flattens' the list of lists into an np.ndarray and tolist() to get an python list

View File

@ -0,0 +1,30 @@
import numpy as np
import matplotlib.pyplot as plt
import timeit
nthreads = [1, 2, 4, 8, 16]
sizes = [100, 400, 1600, 6400, 12800, 25600, 51200]
thread_timings = []
for t in nthreads:
print(f"Measure timing for {t} thread(s)")
size_timings = []
for s in sizes:
print(f"--- Measure timing for size {s}")
command = f"subprocess.run(\"mpirun --use-hwthread-cpus -n {t} python3 exercise_04.py {s}\", shell = True)"
size_timings.append(timeit.timeit(command, setup = "import subprocess", number = 1) * 1000)
thread_timings.append(size_timings)
plt.plot(sizes, thread_timings[0], "green", label=f"{nthreads[0]}")
plt.plot(sizes, thread_timings[1], "blue", label=f"{nthreads[1]}")
plt.plot(sizes, thread_timings[2], "purple", label=f"{nthreads[2]}")
plt.plot(sizes, thread_timings[3], "red", label=f"{nthreads[3]}")
plt.plot(sizes, thread_timings[4], "orange", label=f"{nthreads[4]}")
plt.title("Matrix-Vector-Multiplication time/threads comparison")
plt.xlabel("Sizes")
plt.ylabel("Time (ms)")
plt.loglog()
plt.legend(title = "# of Threads")
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

495
uebung_04/exercise_06/Cargo.lock generated Normal file
View File

@ -0,0 +1,495 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "bindgen"
version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn",
"which",
]
[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "build-probe-mpi"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6606c78346df2f2e1f39ac51d0a7752060a08a5de7805f0ad1b3bbefa93be8cc"
dependencies = [
"pkg-config",
"shell-words",
]
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "conv"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
dependencies = [
"custom_derive",
]
[[package]]
name = "custom_derive"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "errno"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "exercise_06"
version = "0.1.0"
dependencies = [
"mpi",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "home"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
dependencies = [
"windows-sys",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "libffi"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2"
dependencies = [
"libc",
"libffi-sys",
]
[[package]]
name = "libffi-sys"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c"
dependencies = [
"cc",
]
[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "mpi"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feff046b021e89291acbb509336cd0a9fec3c0ccb54d996401bcb35b8bbf267a"
dependencies = [
"build-probe-mpi",
"conv",
"libffi",
"mpi-sys",
"once_cell",
"smallvec",
"thiserror",
]
[[package]]
name = "mpi-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cb5d935a63f2c1c7b4f41dcf897869efb1b5ce8e48019b982a43fff2c34b916"
dependencies = [
"bindgen",
"build-probe-mpi",
"cc",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pkg-config"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "prettyplease"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.38.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "shell-words"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "shlex"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
[[package]]
name = "smallvec"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

View File

@ -0,0 +1,9 @@
[package]
name = "exercise_06"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
mpi = "0.7.0"

View File

@ -0,0 +1,76 @@
use std::f64::consts::PI;
use mpi::collective::SystemOperation;
use mpi::traits::*;
fn main() {
let universe = mpi::initialize().unwrap();
let world = universe.world();
let size = world.size();
let rank = world.rank();
let support_points = 100;
let a = 0.0;
let b = 1.0;
let N = (b - a) / size as f64;
let f = |x: f64| 1.0 / (1.0 + x.powi(2)) as f64; // function
let n = (support_points / size) as u32; // fewer ranks should also use an appropriate amount of support points; the support points are distributed among the ranks
let partial_integral = trapezoidal_rule(f, a + rank as f64 * N, a + (rank + 1) as f64 * N, n);
println!("Rank {}: Partial integral is {} on [{},{}]", rank, partial_integral, (a + rank as f64 * N), (a + (rank + 1) as f64 * N));
world.barrier();
let mut integral = 0.0;
world.all_reduce_into(&partial_integral, &mut integral, SystemOperation::sum());
if rank == 0 {
println!("The approximated integral is {}", integral);
println!("The error is |{:.7} - {:.7}| = {}", (PI / 4.0), integral, (integral - (PI / 4.0)).abs());
}
}
fn trapezoidal_rule(f: fn(f64) -> f64, a: f64, b: f64, n: u32) -> f64 {
let h = (b - a) / n as f64;
let mut result = 0.5 * (f(a) + f(b));
for i in 1..n {
let x_i = a + i as f64 * h;
result += f(x_i);
}
h * result
}
#[cfg(test)]
mod tests {
use std::f64::consts::PI;
use crate::trapezoidal_rule;
#[test]
fn should_return_0_trapezoid_rule() {
let expected = 0.0;
let actual = trapezoidal_rule(|_x| 0.0, 0.0, 10.0, 1);
assert_eq!(expected, actual, "Integral is {} but should be {}", actual, expected);
}
#[test]
fn should_return_1_trapezoid_rule() {
let expected = 1.0;
let actual = trapezoidal_rule(|_x| 1.0, 0.0, 1.0, 1);
assert_eq!(expected, actual, "Integral is {} but should be {}", actual, expected);
}
#[test]
fn should_return_pi_trapezoid_rule() {
let expected = PI / 4.0;
let actual = trapezoidal_rule(|x| 1.0 / (1.0 + x.powi(2)), 0.0, 1.0, 10);
let tolerance = 1e-3;
assert!((expected - actual).abs() < tolerance, "Integral is {} but should be {}", actual, expected);
}
}

View File

@ -0,0 +1,20 @@
class Ball:
__diameter__ = 0.0
## Methods
# Constructor
def __init__(self, diameter = 1.0):
self.__diameter__ = diameter
pass
# a simple method
def introduction(self):
print(f"My diameter is {self.__diameter__:.3f}.")
pass
# main code
a = Ball()
b = Ball(2.0)
a.introduction()
b.introduction()

View File

@ -0,0 +1,51 @@
import numpy as np
class Ball:
__diameter__ = 0.0
## Methods
# Constructor
def __init__(self, diameter = 1.0):
self.__diameter__ = diameter
pass
# a simple method
def introduction(self):
print(f"My diameter is {self.__diameter__:.3f}.")
pass
# Getter
def get_diameter(self):
return self.__diameter__
# overload __add_ (+)
def __add__(self, other):
d1 = self.get_diameter()
if(isinstance(other, Ball)):
d2 = other.get_diameter()
combined_volume = 1/6 * np.pi * (d1**3 + d2**3)
elif(isinstance(other, int) or isinstance(other, float)):
combined_volume = 1/6 * np.pi*d1**3 + other
else:
raise ValueError("Invalid summand.")
d_combined = np.power(6 * combined_volume / np.pi, 1/3)
return Ball(d_combined)
# overload __radd__ (number + Ball)
def __radd__(self, other):
return self + other
# main code
a = Ball()
b = Ball(2.0)
c = a + b
d = a + 5
e = 5 + a
a.introduction()
b.introduction()
c.introduction()
d.introduction()

View File

@ -0,0 +1,74 @@
import math
import matplotlib.pyplot as plt
class Point:
__x__ = 0.0
__y__ = 0.0
def __init__(self, x = 0.0, y = 0.0):
self.__x__ = x
self.__y__ = y
def __str__(self):
return f"({self.__x__:.3f},{self.__y__:.3f})"
def __neg__(self):
return Point(-self.__x__, -self.__y__)
def __add__(self, other):
if isinstance(other, Point):
return Point(self.__x__ + other.__x__, self.__y__ + other.__y__)
elif isinstance(other, int) or isinstance(other, float):
return Point(self.__x__ + other, self.__y__ + other)
else:
raise ValueError("Operand must be Point, int or float.")
def __radd__(self, other):
return self + other
def __sub__(self, other):
return self + (-other)
def __rsub__(self, other):
return self - other
def __mul__(self, other):
if isinstance(other, Point):
return Point(self.__x__ * other.__x__, self.__x__ * other.__y__)
elif isinstance(other, int) or isinstance(other, float):
return Point(self.__x__ * other, self.__x__ * other)
else:
raise ValueError("Operand must be Point, int or float.")
def __rmul__(self, other):
return self * other
def rot(self, degree):
x = math.cos(degree) * self.__x__ + math.sin(degree) * self.__y__
y = -math.sin(degree) * self.__x__ + math.cos(degree) * self.__y__
return Point(x, y)
def get_x(self):
return self.__x__
def get_y(self):
return self.__y__
p1 = Point()
p2 = Point(1, 1)
p3 = Point (3, 2)
p4 = 2 * p2 + p3 - 1
p5 = p4.rot(math.pi / 2)
plt.plot(p1.get_x(), p1.get_y(), "orange", marker = "o", label = p1)
plt.plot(p2.get_x(), p2.get_y(), "green", marker = "o", label = p2)
plt.plot(p3.get_x(), p3.get_y(), "yellow", marker = "o", label = p3)
plt.plot(p4.get_x(), p4.get_y(), "purple", marker = "o", label = 2 * p2 + p3 - 1)
plt.plot(p5.get_x(), p5.get_y(), "purple", marker = "o", label = f"{p4} rotated 90°")
plt.title("Points")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.show()