renaming exercises

This commit is contained in:
Jenni Rinker 2024-08-29 18:23:32 +03:00
parent b9988fdda9
commit 55cccc5f4f
6 changed files with 2 additions and 2 deletions

View file

@ -0,0 +1,27 @@
# Exercise B: multiprocessing and map
Objective: introduce `map` and `Pool.map`.
In the `numerical_integration.py` file, we give Python code that calculates
the integral of a function in two different ways: numerically and analytically.
The given functions are `integrate` (numerical integration), `f` (the function
to integrate), and `F` (the analytical integral).
We want to check the precision of the numerical integration as a function of
the number of steps in the domain. To do this, we calculate and print the
relative differences between the analytic result and the numerical result
for different values of the number of steps.
**TASKS**:
0. Read `numerical_integration.py` and familiarize yourselves with the code.
1. Update the `main` function so that it calculates the numerical error without
any parallelization. You can use a for loop or `map`.
2. Note the execution time for this serial implementation.
3. Implement the parallel version using `multiprocessing.Pool`.
4. Compare the timing for the parallel version with the serial time.
What speed-up did you get?
**BONUS TASKS (very optional)**:
5. Implement a parallel version with threads (using `multiprocessing.pool.ThreadPool`).
6. Time this version, and hypothetize about the result.

View file

@ -0,0 +1,38 @@
"""Exercise 2b: multiprocessing
"""
def integrate(f, a, b, n):
"Perform numerical integration of f in range [a, b], with n steps"
s = []
for i in range(n):
dx = (b - a) / n
x = a + (i + 0.5) * dx
y = f(x)
s = s + [y * dx]
return sum(s)
def f(x):
"A polynomial that we'll integrate"
return x ** 4 - 3 * x
def F(x):
"The analatic integral of f. (F' = f)"
return 1 / 5 * x ** 5 - 3 / 2 * x ** 2
def compute_error(n):
"Calculate the difference between the numerical and analytical integration results"
a = -1.0
b = +2.0
F_analytical = F(b) - F(a)
F_numerical = integrate(f, a, b, n)
return abs((F_numerical - F_analytical) / F_analytical)
def main():
ns = [10_000, 25_000, 50_000, 75_000]
errors = ... # TODO: write a for loop, serial map, and parallel map here
for n, e in zip(ns, errors):
print(f'{n} {e:.8%}')
if __name__ == '__main__':
main()

View file

@ -0,0 +1,30 @@
import sys
from numerical_integration import compute_error
def main(arg):
ns = [10_000, 25_000, 50_000, 75_000]
match arg:
case 'for':
errors = []
for n in ns:
errors += [compute_error(n)]
case 'lc':
errors = [compute_error(n) for n in ns]
case 'map':
errors = list(map(compute_error, ns))
case 'mp':
from multiprocessing import Pool as ProcessPool
with ProcessPool() as pool:
errors = pool.map(compute_error, ns)
case 'mt':
from multiprocessing.pool import ThreadPool
with ThreadPool(10) as pool:
errors = pool.map(compute_error, ns)
for n, e in zip(ns, errors):
print(f'{n} {e:.8%}')
if __name__ == '__main__':
arg = (sys.argv[1:] + ['for'])[0]
main(arg)