Commit fab3e662 authored by Yuncong Yu's avatar Yuncong Yu
Browse files

Replaced copyleft libraries with permissive libraries

parent 3a46bd78
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
.idea .idea
Angu:arApp/prototype/node_modules Angu:arApp/prototype/node_modules
Documents/ Documents/
EGR/ data/EGR/
data/variable_displacement/
Flaskserver/venv/* Flaskserver/venv/*
__pycache__ __pycache__
backend/cache/ backend/cache/
......
'''
/*******************************************************************************
* Copyright (C) 2018 Francois Petitjean
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
'''
from __future__ import division
import numpy as np
from functools import reduce
__author__ ="Francois Petitjean"
def performDBA(series, n_iterations=10):
n_series = len(series)
max_length = reduce(max, map(len, series))
cost_mat = np.zeros((max_length, max_length))
delta_mat = np.zeros((max_length, max_length))
path_mat = np.zeros((max_length, max_length), dtype=np.int8)
medoid_ind = approximate_medoid_index(series,cost_mat,delta_mat)
center = series[medoid_ind]
for i in range(0,n_iterations):
center = DBA_update(center, series, cost_mat, path_mat, delta_mat)
return center
def approximate_medoid_index(series,cost_mat,delta_mat):
if len(series)<=50:
indices = range(0,len(series))
else:
indices = np.random.choice(range(0,len(series)),50,replace=False)
medoid_ind = -1
best_ss = 1e20
for index_candidate in indices:
candidate = series[index_candidate]
ss = sum_of_squares(candidate,series,cost_mat,delta_mat)
if(medoid_ind==-1 or ss<best_ss):
best_ss = ss
medoid_ind = index_candidate
return medoid_ind
def sum_of_squares(s,series,cost_mat,delta_mat):
return sum(map(lambda t:squared_DTW(s,t,cost_mat,delta_mat),series))
def DTW(s,t,cost_mat,delta_mat):
return np.sqrt(squared_DTW(s,t,cost_mat,delta_mat))
def squared_DTW(s,t,cost_mat,delta_mat):
s_len = len(s)
t_len = len(t)
length = len(s)
fill_delta_mat_dtw(s, t, delta_mat)
cost_mat[0, 0] = delta_mat[0, 0]
for i in range(1, s_len):
cost_mat[i, 0] = cost_mat[i-1, 0]+delta_mat[i, 0]
for j in range(1, t_len):
cost_mat[0, j] = cost_mat[0, j-1]+delta_mat[0, j]
for i in range(1, s_len):
for j in range(1, t_len):
diag,left,top =cost_mat[i-1, j-1], cost_mat[i, j-1], cost_mat[i-1, j]
if(diag <=left):
if(diag<=top):
res = diag
else:
res = top
else:
if(left<=top):
res = left
else:
res = top
cost_mat[i, j] = res+delta_mat[i, j]
return cost_mat[s_len-1,t_len-1]
def fill_delta_mat_dtw(center, s, delta_mat):
slim = delta_mat[:len(center),:len(s)]
np.subtract.outer(center, s,out=slim)
np.square(slim, out=slim)
def DBA_update(center, series, cost_mat, path_mat, delta_mat):
options_argmin = [(-1, -1), (0, -1), (-1, 0)]
updated_center = np.zeros(center.shape)
n_elements = np.array(np.zeros(center.shape), dtype=int)
center_length = len(center)
for s in series:
s_len = len(s)
fill_delta_mat_dtw(center, s, delta_mat)
cost_mat[0, 0] = delta_mat[0, 0]
path_mat[0, 0] = -1
for i in range(1, center_length):
cost_mat[i, 0] = cost_mat[i-1, 0]+delta_mat[i, 0]
path_mat[i, 0] = 2
for j in range(1, s_len):
cost_mat[0, j] = cost_mat[0, j-1]+delta_mat[0, j]
path_mat[0, j] = 1
for i in range(1, center_length):
for j in range(1, s_len):
diag,left,top =cost_mat[i-1, j-1], cost_mat[i, j-1], cost_mat[i-1, j]
if(diag <=left):
if(diag<=top):
res = diag
path_mat[i,j] = 0
else:
res = top
path_mat[i,j] = 2
else:
if(left<=top):
res = left
path_mat[i,j] = 1
else:
res = top
path_mat[i,j] = 2
cost_mat[i, j] = res+delta_mat[i, j]
i = center_length-1
j = s_len-1
while(path_mat[i, j] != -1):
updated_center[i] += s[j]
n_elements[i] += 1
move = options_argmin[path_mat[i, j]]
i += move[0]
j += move[1]
assert(i == 0 and j == 0)
updated_center[i] += s[j]
n_elements[i] += 1
return np.divide(updated_center, n_elements)
\ No newline at end of file
'''
/*******************************************************************************
* Copyright (C) 2018 Francois Petitjean
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
'''
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
from functools import reduce
__author__ ="Francois Petitjean"
def performDBA(series, n_iterations=10):
n_series = len(series)
max_length = 0
for s in series:
max_length = max(max_length,s.shape[1])
cost_mat = np.zeros((max_length, max_length))
delta_mat = np.zeros((max_length, max_length))
tmp_delta_mat = np.zeros((max_length, max_length))
path_mat = np.zeros((max_length, max_length), dtype=np.int8)
medoid_ind = approximate_medoid_index(series,cost_mat,delta_mat,tmp_delta_mat)
center = series[medoid_ind]
for i in range(0,n_iterations):
center = DBA_update(center, series, cost_mat, path_mat, delta_mat,tmp_delta_mat)
return center
def approximate_medoid_index(series,cost_mat,delta_mat,tmp_delta_mat):
if len(series)<=50:
indices = range(0,len(series))
else:
indices = np.random.choice(range(0,len(series)),50,replace=False)
medoid_ind = -1
best_ss = 1e20
for index_candidate in indices:
candidate = series[index_candidate]
ss = sum_of_squares(candidate,series,cost_mat,delta_mat,tmp_delta_mat)
if(medoid_ind==-1 or ss<best_ss):
best_ss = ss
medoid_ind = index_candidate
return medoid_ind
def sum_of_squares(s,series,cost_mat,delta_mat,tmp_delta_mat):
return sum(map(lambda t:squared_DTW(s,t,cost_mat,delta_mat,tmp_delta_mat),series))
def DTW(s,t,cost_mat,delta_mat):
return np.sqrt(squared_DTW(s,t,cost_mat,delta_mat))
def squared_DTW(s,t,cost_mat,delta_mat,tmp_delta_mat):
s_len = s.shape[1]
t_len = t.shape[1]
fill_delta_mat_dtw(s, t, delta_mat,tmp_delta_mat)
cost_mat[0, 0] = delta_mat[0, 0]
for i in range(1, s_len):
cost_mat[i, 0] = cost_mat[i-1, 0]+delta_mat[i, 0]
for j in range(1, t_len):
cost_mat[0, j] = cost_mat[0, j-1]+delta_mat[0, j]
for i in range(1, s_len):
for j in range(1, t_len):
diag,left,top =cost_mat[i-1, j-1], cost_mat[i, j-1], cost_mat[i-1, j]
if(diag <=left):
if(diag<=top):
res = diag
else:
res = top
else:
if(left<=top):
res = left
else:
res = top
cost_mat[i, j] = res+delta_mat[i, j]
return cost_mat[s_len-1,t_len-1]
def fill_delta_mat_dtw(center, s, delta_mat, tmp_delta_mat):
n_dims = center.shape[0]
len_center = center.shape[1]
len_s= s.shape[1]
slim = delta_mat[:len_center,:len_s]
slim_tmp = tmp_delta_mat[:len_center,:len_s]
#first dimension - not in the loop to avoid initialisation of delta_mat
np.subtract.outer(center[0], s[0],out = slim)
np.square(slim, out=slim)
for d in range(1,center.shape[0]):
np.subtract.outer(center[d], s[d],out = slim_tmp)
np.square(slim_tmp, out=slim_tmp)
np.add(slim,slim_tmp,out=slim)
assert(np.abs(np.sum(np.square(center[:,0]-s[:,0]))-delta_mat[0,0])<=1e-6)
def DBA_update(center, series, cost_mat, path_mat, delta_mat, tmp_delta_mat):
options_argmin = [(-1, -1), (0, -1), (-1, 0)]
updated_center = np.zeros(center.shape)
center_length = center.shape[1]
n_elements = np.zeros(center_length, dtype=int)
for s in series:
s_len = s.shape[1]
fill_delta_mat_dtw(center, s, delta_mat, tmp_delta_mat)
cost_mat[0, 0] = delta_mat[0, 0]
path_mat[0, 0] = -1
for i in range(1, center_length):
cost_mat[i, 0] = cost_mat[i-1, 0]+delta_mat[i, 0]
path_mat[i, 0] = 2
for j in range(1, s_len):
cost_mat[0, j] = cost_mat[0, j-1]+delta_mat[0, j]
path_mat[0, j] = 1
for i in range(1, center_length):
for j in range(1, s_len):
diag,left,top =cost_mat[i-1, j-1], cost_mat[i, j-1], cost_mat[i-1, j]
if(diag <=left):
if(diag<=top):
res = diag
path_mat[i,j] = 0
else:
res = top
path_mat[i,j] = 2
else:
if(left<=top):
res = left
path_mat[i,j] = 1
else:
res = top
path_mat[i,j] = 2
cost_mat[i, j] = res+delta_mat[i, j]
i = center_length-1
j = s_len-1
while(path_mat[i, j] != -1):
updated_center[:,i] += s[:,j]
n_elements[i] += 1
move = options_argmin[path_mat[i, j]]
i += move[0]
j += move[1]
assert(i == 0 and j == 0)
updated_center[:,i] += s[:,j]
n_elements[i] += 1
return np.divide(updated_center, n_elements)
def main():
#generating synthetic data
n_series = 20
length = 200
n_dims = 201
print('Important note: the data should be structure "channels-first", ie the series should have shape (n_channels,length)')
series = list()
padding_length=30
indices = range(0, length-padding_length)
main_profile_gen = np.array([np.sin(2.0*np.pi*j/len(indices)) for j in indices])
randomizer = lambda j:np.random.normal(j,0.02)
randomizer_fun = np.vectorize(randomizer)
for i in range(0,n_series):
n_pad_left = np.random.randint(0,padding_length)
#adding zero at the start or at the end to shif the profile
b = n_pad_left
a = padding_length-n_pad_left
padded_pattern = np.pad(main_profile_gen,(a,b),mode='constant',constant_values=0)
#chop some of the end to prove it can work with multiple lengths
l = np.random.randint(length-20,length+1)
padded_pattern = padded_pattern[:l]
padded_pattern = randomizer_fun(padded_pattern)
series_i = np.zeros((n_dims,l))
for d in range(0,n_dims):
series_i[d]=padded_pattern
series.append(series_i)
#plotting the synthetic data
for s in series:
plt.plot(range(0,s.shape[1]), s[0])
plt.draw()
plt.show()
#calculating average series with DBA
average_series = performDBA(series)
#plotting the average series
plt.figure()
for d in range(0,n_dims):
plt.plot(range(0,average_series.shape[1]), average_series[d])
plt.show()
if __name__== "__main__":
main()
...@@ -9,10 +9,9 @@ from typing import Any, Dict, List, Optional, Sequence, Tuple, Union ...@@ -9,10 +9,9 @@ from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
import _lsh import _lsh
import _ucrdtw import _ucrdtw
import numpy as np import numpy as np
from tslearn.barycenters import softdtw_barycenter
from tslearn.metrics import dtw from tslearn.metrics import dtw
from libs.DBA_multivariate import performDBA
def get_lsh_parameters(data: np.ndarray, window_size: int) -> Tuple[float, float, float]: def get_lsh_parameters(data: np.ndarray, window_size: int) -> Tuple[float, float, float]:
"""Get optimal LSH parameters """Get optimal LSH parameters
...@@ -367,7 +366,7 @@ def query(data: np.ndarray, window_indices: Union[int, Dict[int, bool]]) -> List ...@@ -367,7 +366,7 @@ def query(data: np.ndarray, window_indices: Union[int, Dict[int, bool]]) -> List
else: else:
indices = [int(index) for index, value in window_indices.items() if value is True] indices = [int(index) for index, value in window_indices.items() if value is True]
indices_windows = data[indices] indices_windows = data[indices]
output = performDBA(indices_windows) output = softdtw_barycenter(np.swapaxes(indices_windows, axis1=1, axis2=2)).T
return output.tolist() return output.tolist()
......
...@@ -4,4 +4,5 @@ reload: false ...@@ -4,4 +4,5 @@ reload: false
# Specific configuration file # Specific configuration file
#path_config_yml: D:\Projects\pseudo\experiments\configs\config_egr.yml #path_config_yml: D:\Projects\pseudo\experiments\configs\config_egr.yml
path_config_yml: ..\experiments\configs\config_eeg_eye_state.yml path_config_yml: ..\experiments\configs\config_eeg_eye_state.yml
\ No newline at end of file #path_config_yml: ..\experiments\configs\config_variable_displacement.yml
\ No newline at end of file
---
dataset: variable_displacement
path_data_hdf: ..\data\variable_displacement\variable_displacement_compressed.hdf5
path_meta_json: ..\data\variable_displacement\metadata.json
channels:
- rotation speed
- derivative
dir_in_hdf: data
dir_cache: cache\
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