Commit a024c012 authored by Franck Thollard's avatar Franck Thollard
Browse files

adding missing files for fortran wrapping in mpi snippets

parent c376ea6f
all:
python3 -m numpy.f2py -c "dtw_cort.f90" -m distances_fort
clean:
rm -f distances_fort.*.so
#!/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(_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()
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, sum_square_x, sum_square_y
len_s1 = size(s1)
num = 0
sum_square_x = 0
sum_square_y = 0
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_y))
end function cort
end module dtw_cort
\ No newline at end of file
Markdown is supported
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