Commit 05f546db authored by Cyrille Bonamy's avatar Cyrille Bonamy
Browse files

add VM link + first very bad mpi4py version

parent b8c3653d
......@@ -129,6 +129,9 @@ during this training with a (real or
[virtual](https://www.virtualbox.org/wiki/Downloads)) Linux machine. Of course,
if you can't or don't want to use Linux, come with your computer on Windows or
macOS.
We offer a linux virtual machine ready to use (via virtualbox 6.X) for training.
It can be downloaded [here](https://filesender.renater.fr/?s=download&token=62c5f530-7def-8c32-4e3c-d205299a5201)
#### Install Python and utilities
......
#!/usr/bin/env python3
from functools import partial
from runpy import run_path
from pathlib import Path
import numpy as np
from mpi4py import MPI
util = run_path(Path(__file__).absolute().parent.parent / "util.py")
def serie_pair_index_generator(number, rank, size):
""" generator for pair index (i, j) such that i < j < number
:param number: the upper bound
:returns: pairs (lower, greater)
:rtype: a generator
"""
start = rank*number//size
end = min(number, (rank+1)*number//size)
return (
(_idx_greater, _idx_lower)
for _idx_greater in range(start, end)
for _idx_lower in range(_idx_greater)
if _idx_lower < _idx_greater
)
def DTWDistance(s1, s2):
""" Computes the dtw between s1 and s2 with distance the absolute distance
:param s1: the first serie (ie an iterable over floats64)
:param s2: the second serie (ie an iterable over floats64)
:returns: the dtw distance
:rtype: float64
"""
len_s1 = len(s1)
len_s2 = len(s2)
_dtw_mat = np.empty([len_s1, len_s2])
_dtw_mat[0, 0] = abs(s1[0] - s2[0])
# two special cases : filling first row and columns
for j in range(1, len_s2):
dist = abs(s1[0] - s2[j])
_dtw_mat[0, j] = dist + _dtw_mat[0, j - 1]
for i in range(1, len_s1):
dist = abs(s1[i] - s2[0])
_dtw_mat[i, 0] = dist + _dtw_mat[i - 1, 0]
#  filling the matrix
for i in range(1, len_s1):
for j in range(1, len_s2):
dist = abs(s1[i] - s2[j])
_dtw_mat[(i, j)] = dist + min(
_dtw_mat[i - 1, j], _dtw_mat[i, j - 1], _dtw_mat[i - 1, j - 1]
)
return _dtw_mat[len_s1 - 1, len_s2 - 1]
def cort(s1, s2):
""" Computes the cort between serie one and two (assuming they have the same length)
:param s1: the first serie (or any iterable over floats64)
:param s2: the second serie (or any iterable over floats64)
:returns: the cort distance
:rtype: float64
"""
num = 0.0
sum_square_x = 0.0
sum_square_y = 0.0
for t in range(len(s1) - 1):
slope_1 = s1[t + 1] - s1[t]
slope_2 = s2[t + 1] - s2[t]
num += slope_1 * slope_2
sum_square_x += slope_1 * slope_1
sum_square_y += slope_2 * slope_2
return num / (np.sqrt(sum_square_x * sum_square_y))
def compute(series, nb_series):
comm = MPI.COMM_WORLD
gen = serie_pair_index_generator(nb_series, comm.rank, comm.size)
_dist_mat_dtw = np.zeros((nb_series, nb_series), dtype=np.float64)
_dist_mat_cort = np.zeros((nb_series, nb_series), dtype=np.float64)
_dist_mat_dtw_global = np.zeros((nb_series, nb_series), dtype=np.float64)
_dist_mat_cort_global = np.zeros((nb_series, nb_series), dtype=np.float64)
for t1, t2 in gen:
dist_dtw = DTWDistance(series[t1], series[t2])
_dist_mat_dtw[t1, t2] = dist_dtw
_dist_mat_dtw[t2, t1] = dist_dtw
dist_cort = 0.5 * (1 - cort(series[t1], series[t2]))
_dist_mat_cort[t1, t2] = dist_cort
_dist_mat_cort[t2, t1] = dist_cort
comm.Reduce(
[_dist_mat_cort, MPI.DOUBLE],
[_dist_mat_cort_global, MPI.DOUBLE],
op = MPI.SUM,
root = 0
)
comm.Reduce(
[_dist_mat_dtw, MPI.DOUBLE],
[_dist_mat_dtw_global, MPI.DOUBLE],
op = MPI.SUM,
root = 0
)
return _dist_mat_dtw_global, _dist_mat_cort_global
main = partial(util["main"], compute)
if __name__ == "__main__":
main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment