Commit 0a916490 authored by Eric Maldonado's avatar Eric Maldonado
Browse files
parents 157bfa53 f2d6dcfc
## Timing:
We use [invoke](https://www.pyinvoke.org/) (`pip install invoke`) to build and run the benchmarks.
We use [invoke](https://www.pyinvoke.org/) (`pip install invoke`) to build and run the benchmarks. The full requirements can be installed with `pip install -r requirements.txt`.
See [how to get autocompletion with invoke](http://docs.pyinvoke.org/en/1.2/invoke.html?highlight=completion#cmdoption-print-completion-script).
......
all:
python3 -m numpy.f2py -c "dtw_cort.f90" -m distances_fort
clean:
rm -f distances_fort.*.so
module dtw_cort
implicit none
contains
subroutine dtwdistance(s1, s2, dtw_result)
! Computes the dtw between s1 and s2 with distance the absolute distance
doubleprecision, intent(in) :: s1(:), s2(:)
doubleprecision, intent(out) :: dtw_result
integer :: i, j
integer :: len_s1, len_s2
doubleprecision :: dist
doubleprecision, allocatable :: dtw_mat(:, :)
len_s1 = size(s1)
len_s2 = size(s1)
allocate(dtw_mat(len_s1, len_s2))
dtw_mat(1, 1) = dabs(s1(1) - s2(1))
do j = 2, len_s2
dist = dabs(s1(1) - s2(j))
dtw_mat(1, j) = dist + dtw_mat(1, j-1)
end do
do i = 2, len_s1
dist = dabs(s1(i) - s2(1))
dtw_mat(i, 1) = dist + dtw_mat(i-1, 1)
end do
! Fill the dtw_matrix
do i = 2, len_s1
do j = 2, len_s2
dist = dabs(s1(i) - s2(j))
dtw_mat(i, j) = dist + dmin1(dtw_mat(i - 1, j), &
dtw_mat(i, j - 1), &
dtw_mat(i - 1, j - 1))
end do
end do
dtw_result = dtw_mat(len_s1, len_s2)
end subroutine dtwdistance
doubleprecision function cort(s1, s2)
! Computes the cort between s1 and s2 (assuming they have the same length)
doubleprecision, intent(in) :: s1(:), s2(:)
integer :: len_s1, t
doubleprecision :: slope_1, slope_2
doubleprecision :: num=0, sum_square_x=0, sum_square_y=0
len_s1 = size(s1)
do t=1, len_s1 - 1
slope_1 = s1(t + 1) - s1(t)
slope_2 = s2(t + 1) - s2(t)
num = num + slope_1 * slope_2
sum_square_x = sum_square_x + slope_1 * slope_1
sum_square_y = sum_square_y + slope_2 * slope_2
end do
cort = num / dsqrt(sum_square_x*sum_square_x)
end function cort
end module dtw_cort
\ No newline at end of file
#!/usr/bin/env python3
from functools import partial
from runpy import run_path
from pathlib import Path
from distances_fort import dtw_cort
import numpy as np
util = run_path(Path(__file__).absolute().parent.parent / "util.py")
def serie_pair_index_generator(number):
""" generator for pair index (i, j) such that i < j < number
:param number: the upper bound
:returns: pairs (lower, greater)
:rtype: a generator
"""
return (
(_idx_greater, _idx_lower)
for _idx_greater in range(number)
for _idx_lower in range(number)
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
"""
dtw_result = dtw_cort.dtwdistance(s1, s2)
return dtw_result
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
"""
cort_result = dtw_cort.cort(s1, s2)
return cort_result
def compute(series, nb_series):
gen = serie_pair_index_generator(nb_series)
_dist_mat_dtw = np.zeros((nb_series, nb_series), dtype=np.float64)
_dist_mat_cort = 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
return _dist_mat_dtw, _dist_mat_cort
main = partial(util["main"], compute)
if __name__ == "__main__":
main()
astunparse==1.6.2
beniget==0.1.0
cffi==1.12.3
Cython==0.29.10
decorator==4.4.0
docutils-stubs==0.0.10
-e git+https://gricad-gitlab.univ-grenoble-alpes.fr/python-uga/training-hpc.git@fa9d7e7c22b54d54cd17890c58f01821e9b3d321#egg=dtw_cort_dist_mat&subdirectory=pyfiles/dtw_cort_dist/V2_c_dtw
gast==0.2.2
invoke==1.2.0
llvmlite==0.29.0
mpi4py==3.0.1
networkx==2.3
numba==0.44.0
numpy==1.16.4
parsimonious==0.7.0
pkg-resources==0.0.0
ply==3.11
pycparser==2.19
pythran==0.9.2
six==1.12.0
transonic==0.2.2
#!/usr/bin/env python3
from functools import partial
from runpy import run_path
from pathlib import Path
import numpy as np
import math
util = run_path(Path(__file__).absolute().parent.parent / "util.py")
def serie_pair_index_generator(number):
""" generator for pair index (i, j) such that i < j < number
:param number: the upper bound
:returns: pairs (lower, greater)
:rtype: a generator
"""
return (
(_idx_greater, _idx_lower)
for _idx_greater in range(number)
for _idx_lower in range(number)
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 series 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
"""
slope_1 = s1[1:] - s1[:-1]
slope_2 = s2[1:] - s2[:-1]
num = np.sum(slope_1 * slope_2)
sum_square_x = np.sum(slope_1 * slope_1)
sum_square_y = np.sum(slope_2 * slope_2)
return num / (math.sqrt(sum_square_x * sum_square_y))
def compute(series, nb_series):
gen = serie_pair_index_generator(nb_series)
_dist_mat_dtw = np.zeros((nb_series, nb_series), dtype=np.float64)
_dist_mat_cort = 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
return _dist_mat_dtw, _dist_mat_cort
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