dtwParallel


NamedtwParallel JSON
Version 0.9.40 PyPI version JSON
download
home_pagehttps://github.com/oscarescuderoarnanz/dtwParallel
SummaryPython implementation of Dynamic Time Warping (DTW), which allows computing the dtw distance between one-dimensional and multidimensional time series, with the possibility of visualisation (one-dimensional case) and parallelisation (multidimensional case).
upload_time2023-10-19 09:27:38
maintainer
docs_urlNone
authoroscarescuderoarnanz
requires_python>=3.6.1
licenseBSD 2-Clause License Copyright (c) 2017, Romain Tavenard Copyright (c) 2022, Universidad Rey Juan Carlos All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
keywords dtw parallel cpu
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Dynamic Time Warping 

## Paper reference

https://www.sciencedirect.com/science/article/pii/S2352711023000602

## Summary 
This package allows to measurement of the similarity between two-time sequences, i.e., it finds the optimal alignment between two time-dependent sequences. It allows working with univariate (UTS) and multivariate (MTS) time series, regular (same time length), or irregular (different time length). 

One of the parameters available for this method is the method used to calculate the local similarity. For this case, it is possible to use any distance available in `scipy.spatial.distance` (it does not allow to work with variables of different nature, i.e., discrete, continuous, and categorical), `gower` distance (it allows to work with variables of different nature). 

At this point, using local dissimilarities such as norm1, norm2, or square euclidean distance provides optimization in terms of computational time with respect to the rest of the available local dissimilarities.

The available variants of DTW are detailed below: 
1) dependent DTW ("d").
2) Independent DTW ("i").

We can set the following global constraints:
1) Itakura parallelogram.
2) Sakoe-Chiba band.
3) None.

Extra functionality has been incorporated to transform the resulting DTW matrix into an exponential kernel, given the sigma value (default 1).

Display for 2-time series (TS):
- It incorporates the possibility of visualizing the cost matrix, the optimal path to reach the DTW distance value between two TS, and the alignment between two TS. This will allow its use in a didactic way, providing a better understanding of the method used.

Common functionalities for N (> 2) time series (TS):
- The calculation can be parallelized by the CPU by selecting the number of threads. As a result, we will obtain the distance matrix. 
- It is possible to perform distance computation and similarity computation (based on an exponential kernel).

 The input data types via API are (1) CSV; (2) array; (3) pandas (pd.DataFrame or pd.Series) and (4) npy (for tensors).

## Table of content 

| Section | Description |
|-|-|
| [Installation](#installation) | Installing the dependencies and dtwParallel |
| [Getting started](#requirements) | Packages necessary to work with dtwParallel |
| [Available parameters](#parameters) | Modifiable parameters in terminal and API with their possible values |
| [Usage](#usage) | Different examples for terminal and API |
| [Configuration](#configuration) | Composition of configuration.ini file |
| [Examples with public data](#realexamples) | Examples with real financial data |
| [References](#reference) | References to cite |
| [License](#license) | Package license |
 

## Package structure 

<p align="center"> <img src="./Images/schema.png"> </p>

 <!-- <p align="center"> <img src="./Images/fileSchema.png"> </p> -->


## Installation

dtwParallel can be installed using [pip](https://pip.pypa.io/en/stable/), a tool
for installing Python packages. To do it, run the following command:
```
pip install dtwParallel
```

**Current version:** 0.9.39


## Requirements

dtwParallel requires Python >= 3.6.1 or later to run. For other Python
dependencies, please check the `pyproject.toml` file included
on this repository.


Note that you should have also the following packages installed in your system:
- numpy
- pandas
- matplotlib
- seaborn
- gower
- setuptools
- scipy
- joblib
- numba

## Available parameters

The different parameters available with their possible values are listed below:

| Parameter description | Terminal usage | API usage | Possible values |
|-|-|-|-|
| Check errors | -ce or --check_errors | check_errors | True or False |
| Type of DTW variant | -t or --type_dtw| type_dtw | "d" or "i" |
| Global constraint | -c or --constrained_path_search | constrained_path_search | "itakura", "sakoe_chiba" or None |
| Local dissimilarity value | -d or --local_dissimilarity | local_dissimilarity | any distance available in `scipy.spatial.distance`, "norm1", "norm2", "gower" or "square_euclidean_distance" |
| Time series introduced: univariate or multivariate | MTS | MTS | True or False |
| Value used to complete irregular MTS. This value is removed transparently to the user | -rf or --regular_flag | regular_flag | int |
| Number of threads used for multiple MTS parallelization | -n or --n_threads| n_threads | int |
| Visualization | -vis or --visualization | get_visualization | True or False |
| Obtain the result in a file | -of or --output_file | not possible | True or False |
| Name for the output file | -nf or --name_file| not possible | string |
| Transformation of the DTW distance matrix to an exponential kernel | -k or --dtw_to_kernel | dtw_to_kernel | True or False |
| Sigma value for kernel transformation | -s or --sigma_kernel | sigma_kernel | float |
| Maximum slope for the Itakura parallelogram | -imx or --itakura_max_slope | itakura_max_slope | float or None |
| Radius to be used for Sakoe-Chiba band | -scr or --sakoe_chiba_radius | sakoe_chiba_radius | int or None |


## Usage

Based on the previous scheme, this package can be used in three different contexts: 

### 1) Calculation of the DTW distance with input from the terminal.
   
   The generic example is shown below:
      
      dtwParallel -x <floats> -y <floats> -d <str> -ce <bool> -of <bool>
      
   Note that only the x and y values need to be set. If not indicated, the rest of the values will be selected from the file containing the default values, ``configuration.ini``.

   Next, different uses are shown by modifying the parameters of the function:
   
   **a) Example 1.** Considers the Euclidean distance, activates the option -ce to check for errors, and uses as input two UTS (denoted as x and y) with the same length (T=10). 
   Firstly, the input TS and distance are checked as valid entries. Secondly, the dtwParallel package computes the DTW distance. Thirdly, the output is shown in the terminal (while in most cases, the outputs are forwarded to a file, we selected this option to facilitate exposition).
   
   ```
   dtwParallel -x 2 4 6 8 5 3 6 8 9 15 -y 12 0 0 3 5 6 30 1 2 4 -ce True

   ```
   ```
   [out]: 65.0
   ```

   **b) Example 2.** Considering the CityBlock distance.
   
   ```
   dtwParallel -x 2.5 4.3 6.6 8.0 1 0 0 1 5.5 15.2  -y 12.1 0 0 1 1 6.4 3.5 1 0 0  -d cityblock
   ```
   ```
   [out]: 45.4
   ```

   **c) Example 3.** This examples are, respectively, counterparts to **Example 1** and **Example 2**.
   
   ```
   dtwParallel -x 2 4 6 8 5 3 -y 12 0 0 3 5 6 30 1 2 4
   ```
   ```
   [out]: 44.0
   ```   
   ```
   dtwParallel -x 2.5 4.3 6.6 8.0 1 0 0 1 5.5 15.2 -y 1 0 0 1 -d cityblock
   ```
   ```
   [out]: 36.09
   ```   

   **d) Example 4.** **Novelty**: It has been included the possibility to calculate the Itakura parallelogram and the Sakoe-Chiba band.
   
   ```
   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 -c "sakoe_chiba" -d "square_euclidean_distance"
   ```
   ```
   [out]: 296.0
   ```   
   ```
   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 2 4 7 1 9 10 -c "itakura" -d "square_euclidean_distance"
   ```
   ```
   [out]: 169.0
   ```   

   **e) Example e.** **Novelty**: A straightforward and optimal way to calculate norm 1, norm 2 and square euclidean distance is included.

   ```
   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 5 6 1 0 9 11 -d "norm1"
   ```
   ```
   [out]: 12.24
   ```   
   ```
   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 5 6 1 0 9 11 -d "norm2"
   ```
   ```
   [out]: 18.0
   ```   
   ```
   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 5 6 1 0 9 11 -d "square_euclidean_distance"
   ```
   ```
   [out]: 48.0
   ```   
   **We include another example with differents lengths of the time series:**
   ```
   dtwParallel -x 2 4 6 8 1 0 0 -y 1 0 0 1 5 6 1 0 9 11 -d "norm1"
   ```
   ```
   [out]: 13.55
   ```   
   ```
   dtwParallel -x 2 4 6 8 1 0 0 -y 1 0 0 1 5 6 1 0 9 11 -d "norm2"
   ```
   ```
   [out]: 29.0
   ```   
   ```
   dtwParallel -x 2 4 6 8 1 0 0 -y 1 0 0 1 5 6 1 0 -d "square_euclidean_distance"
   ```
   ```
   [out]: 15.0
   ```   


   **Remarks:**
   The calculation of the DTW distance from the command line is limited to simple examples that allow a quick understanding due to the complexity of the terminal handling:
   - Univariate time series.
   - We can set the following restrictions to the calculation of dependent (d) or independent (i) DTW:  Itakura parallelogram, Sakoe-Chiba band or None.
   - Include a straightforward and optimal way to calculate norm 1 (l1), norm 2 (l2) and square euclidean distance.
   - To visualize the cost matrix, routing and the alignment between a pair of series, it will be necessary to use an integrated development environment.

### 2) Calculation of the DTW distance with input from a file, haciendo uso de terminal.


   #### The generic example of univariate time series entered by means of ``csv files`` is shown below:
   ```
   dtwParallel <file_X> -d <str> -ce <bool> -of <bool>
   ```
   If you want to modify any of the possible values, it is necessary to modify the configuration.ini file. The possible values are those shown in [Configuration](#item1).
   
   **a) Example 1.** Calculation of univariate time series taking as input a csv file containing x and y. 

   ```
   dtwParallel exampleData/Data/E1_SyntheticData/example_1.csv
   ```
   ```      
   [out]: 40.6
   ```

   ```
   dtwParallel exampleData/Data/E1_SyntheticData/example_1.csv -d "gower"
   ```
   ```      
   [out]: 10.00
   ```
   ```
   dtwParallel exampleData/Data/E1_SyntheticData/example_1.csv -d "norm1"
   ```
   ```      
   [out]: 18.46
   ```
      
   #### The generic example of multivariate time series entered by means of ``csv files`` is shown below:

   ```
   dtwParallel <file_X> -d <str> -t <str> -ce <bool> -of <bool> -n <int> -k <bool> -s <float>
   ```

   **b) Example 2.** Multivariate time series computation using a csv file containing x and y as input.
   ```
   dtwParallel exampleData/Data/E1_SyntheticData/example_2.csv
   ```
   ```         
   [out]: 81.99
   ```   

   ```
   dtwParallel exampleData/Data/E1_SyntheticData/example_2.csv -d gower -t i 
   ```
   ```              
   [out]: 28.99
   ``` 

   #### The generic example for ``npy files`` is shown below:

   ```
   dtwParallel <file_X> <file_Y> -d <str> -t <str> -ce <bool> -of <bool> -n <int> -k <bool> -s <float>
   ```

   **c) Example 3.** It computes the distance to itself. With differents types of DTW, distances and constraints.
   ```
   dtwParallel exampleData/Data/E0/X_train.npy 
   ```
   ```
   [out]: [[0.00000000e+00 6.36756028e+17 2.94977907e+16 9.96457616e+17]
          [6.36756028e+17 0.00000000e+00 6.07258237e+17 1.63321364e+18]
          [2.94977907e+16 6.07258237e+17 0.00000000e+00 1.02595541e+18]
          [9.96457616e+17 1.63321364e+18 1.02595541e+18 0.00000000e+00]]
   ```
   
   ```
   dtwParallel exampleData/Data/E0/X_train.npy -t "i"
   ```
   ```
   [out]: [[0.00000000e+00 1.68469810e+18 7.80438184e+16 2.63637904e+18]
           [1.68469810e+18 0.00000000e+00 1.60665428e+18 4.32107714e+18]
           [7.80438184e+16 1.60665428e+18 0.00000000e+00 2.71442286e+18]
           [2.63637904e+18 4.32107714e+18 2.71442286e+18 0.00000000e+00]]
   ```

   ```
   dtwParallel exampleData/Data/E0/X_train.npy -c "itakura" -d "square_euclidean_distance"
   ```
   ```
   [out]: [[0.00000000e+00 5.79226055e+34 1.24302808e+32 1.41846826e+35]
           [5.79226055e+34 0.00000000e+00 5.26803666e+34 3.81055258e+35]
           [1.24302808e+32 5.26803666e+34 0.00000000e+00 1.50369214e+35]
           [1.41846826e+35 3.81055258e+35 1.50369214e+35 0.00000000e+00]]
   ```


   **d) Example 4.** We compute the distance matrix DTW between X and Y.

   ```
   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy
   ```
   ```
   [out]: [[2.47396197e+16 9.07388652e+17 2.23522660e+17 1.68210525e+18]
          [6.12016408e+17 1.54414468e+18 8.60278687e+17 2.31886127e+18]
          [4.75817098e+15 9.36886443e+17 2.53020450e+17 1.71160304e+18]
          [1.02119724e+18 8.90689643e+16 7.72934957e+17 6.85647630e+17]]
   ```

   **e) Example 5.** We select two types of distance: gower distance and norm 1. We obtain the distance matrix DTW between X and Y. 

   ```
   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d "gower"
   ```
   ```
   [out]: [[1.7200027  2.16000016 1.92000033 2.53999992]
          [1.59999973 1.79999978 1.83999987 2.27999987]
          [0.5399895  1.52000002 1.04000024 1.66      ]
          [0.70000006 1.57999993 1.10000018 1.69999999]]
   ```

   ```
   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d "norm1"
   ```
   ```
   [out]: [[4.16145813e+08 2.52026200e+09 1.25086315e+09 3.43143363e+09]
           [2.06981034e+09 3.28770631e+09 2.45396634e+09 4.02889922e+09]
           [1.82502594e+08 2.56089928e+09 1.33084302e+09 3.46139008e+09]
           [2.67364557e+09 7.89609239e+08 2.32605776e+09 2.19078374e+09]]
   ```

   **f) Example 6.** Compute the gower distance between X and Y, and we select the number of threads.

   ```
   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d "gower" -n 12
   ```
   ```
   [out]: [[1.7200027  2.16000016 1.92000033 2.53999992]
          [1.59999973 1.79999978 1.83999987 2.27999987]
          [0.5399895  1.52000002 1.04000024 1.66      ]
          [0.70000006 1.57999993 1.10000018 1.69999999]]
   ```

   **g) Example 7.** Compute the gower distance between X and Y, then we obtain the output per file.

   ```
   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d "gower" -n 12 -of True
   ```
   ```
   [out]: output.csv
   ```


   **h) Example 8.** We calculate the distance between X and Y, and transform to Gaussian kernel with sigma_kernel=0.5. We return the distance matrix and the kernel.  
   ```
   dtwParallel exampleData/Data/E0/X_train.npy -k True -s 1000000000
   ```
   ```
   [out]: (array([[0.00000000e+00, 6.36756028e+17, 2.94977907e+16, 9.96457616e+17],
                  [6.36756028e+17, 0.00000000e+00, 6.07258237e+17, 1.63321364e+18],
                  [2.94977907e+16, 6.07258237e+17, 0.00000000e+00, 1.02595541e+18],
                  [9.96457616e+17, 1.63321364e+18, 1.02595541e+18, 0.00000000e+00]]),
           array([[1.        , 0.7273278 , 0.98535934, 0.60760589],
                  [0.7273278 , 1.        , 0.73813458, 0.44192866],
                  [0.98535934, 0.73813458, 1.        , 0.59871014],
                  [0.60760589, 0.44192866, 0.59871014, 1.        ]]))
   ```

   **Remarks:**
   - You can run from any repository, but be careful! The .npy file must be found. 


### 3) Making use of the API  
   
   The generic example is shown below:

   ```
   from dtwParallel import dtw_functions
    
   # For Univariate Time Series
   dtw_functions.dtw(x, y, type_dtw, local_dissimilarity, MTS, get_visualization, check_errors)
   
   # For Multivariate Time Series
   dtw_functions.dtw_tensor_3d(X_1, X_2, object)
   ```

   The examples shown below are executed in jupyter-notebook. Code available in exampleData/CodeExamples/E1_SyntheticData (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E1_SyntheticData). These examples can be executed in any Integrated Development Environment.

   **Example 1.** For univariate time series.
   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [1,2,3]
   y = [0,0,1]
   
   dtw_functions.dtw(x,y,local_dissimilarity=d.euclidean)
   ```
   ```
   [out]: 5.0
   ```

   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [1,2,3,3,4,5,6,7]
   y = [0,1,5,7,1,8,1,4]
   
   dtw_functions.dtw(x,y,local_dissimilarity=d.euclidean)
   ```
   ```
   [out]: 22.0
   ```

   ```
   from dtwParallel import dtw_functions
   
   # For Univariate Time Series
   x = [1,2,3,3,4,5,6,7]
   y = [0,1,5,7,1,8,1,4]
   
   dtw_functions.dtw(x,y,local_dissimilarity="norm1")
   ```
   ```
   [out]: 12.84
   ```

   ```
   import pandas as pd
   import numpy as np
   from dtwParallel import dtw_functions 

   # Use of dataframes with 1D (UTS) as entry data
   x = pd.DataFrame(np.random.randint(0,10, size=(1,8)))
   y = pd.DataFrame(np.random.randint(0,10, size=(1,8)))
   dtw_functions.dtw(x, y, n_threads=8)
   ```
   ```
   [out]: Result with random dependency.
   ```
   ```
   import pandas as pd
   import numpy as np
   from dtwParallel import dtw_functions 

   # Use of dataframes with 2D (MTS) as entry data
   x = pd.DataFrame([np.random.randn(10), np.random.randn(10)])
   y = pd.DataFrame([np.random.randn(10), np.random.randn(10)])
   dtw_functions.dtw(x, y, MTS=True, n_threads=8)
   ```
   ```
   [out]: Result with random dependency.
   ```

   ```
   import pandas as pd 
   import numpy as np
   from dtwParallel import dtw_functions 

   # Use of dataframes with 1D (UTS) as entry data
   x = pd.DataFrame(np.random.randn(10)).T
   y = pd.DataFrame(np.random.randn(10)).T

   dtw_functions.dtw(x,y,n_threads=8)
   ```
   ```
   [out]: Result with random dependency.
   ```

   ```
   import pandas as pd
   import numpy as np
   from dtwParallel import dtw_functions 

   # Use of pd.Series as entry data
   x = pd.Series(np.random.randn(10))
   y = pd.Series(np.random.randn(10))

   dtw_functions.dtw(x,y,local_dissimilarity="norm2")
   ```
   ```
   [out]: Result with random dependency.
   ```


   **Example 2.** For univariate time series with different lengths.
   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [1,2,3,5,8,9,5,4,2]
   y = [1,0,1,0,1,1]
   
   dtw_functions.dtw(x, y, local_dissimilarity=d.euclidean)
   ```
   ```
   [out]: 32.0
   ```

   **Example 3.** For univariate time series with visualization (cost matrix, path and alignment between a pair of time series).
   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [4,2,8,4,5]
   y = [0,1,0,8,9]
   
   dtw_functions.dtw(x, y, local_dissimilarity=d.euclidean, get_visualization=True)
   ```
   ```
   [out]: 15.0
   ```

   ![Example_3_1.png](./Images/Example_3_1.png)
   ![Example_3_1_2.png](./Images/Example_3_1_2.png)

   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]
   y = [0,1,0,8,9,1,3,2,4,3,5,6,7,8,5,6]

   dtw_functions.dtw(x, y, constrained_path_search=None,local_dissimilarity=d.euclidean, get_visualization=True)
   ```
   ```
   [out]: 20.0
   ```

   ![Example_3_1.png](./Images/Example_3_2_0.png)
   ![Example_3_1_2.png](./Images/Example_3_2_2_0.png)

   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]
   y = [0,1,0,8,9,1,3,2,4,3,5,6,7,8,5,6]

   dtw_functions.dtw(x, y, constrained_path_search="itakura",local_dissimilarity=d.euclidean, get_visualization=True)
   ```
   ```
   [out]: 24.0
   ```

   ![Example_3_1.png](./Images/Example_3_2.png)
   ![Example_3_1_2.png](./Images/Example_3_2_2.png)

   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]
   y = [0,1,0,8,9,1,3,2,4,3,5,6,7,8,5,6]

   dtw_functions.dtw(x, y, constrained_path_search="sakoe_chiba",local_dissimilarity=d.euclidean, get_visualization=True)
   ```
   ```
   [out]: 25.0
   ```

   ![Example_3_1.png](./Images/Example_3_3.png)
   ![Example_3_1_2.png](./Images/Example_3_3_2.png)

   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   
   # For Univariate Time Series
   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]
   y = [0,1,0,8,9,1,3,2,4,3,5]
   
   dtw_functions.dtw(x, y, local_dissimilarity=d.euclidean, get_visualization=True)
   ```
   ```
   [out]: 26.0
   ```

   ![Example_3_1.png](./Images/Example_3_4.png)
   ![Example_3_1_2.png](./Images/Example_3_4_2.png)

   **Example 4.** For multivariate time series.
   
   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   import numpy as np
   
   X = np.array([[3,5,8], 
                [5, 1,9]])
   
   Y = np.array([[2, 0,8],
                [4, 3,8]])
               
   dtw_functions.dtw(X, Y, type_dtw="d", local_dissimilarity=d.euclidean, MTS=True)
   ```
   ```
   [out]: 7.548509256375962
   ```

   **Example 5.** For multivariate time series with different lengths.
   
   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   import numpy as np

   X = np.array([[3, 5, 8], 
                 [5, 1, 9],
                 [0, 1, 1], 
                 [1, 4, 2]])

   Y = np.array([[2, 0,8],
                 [4, 3,8]])

   dtw_functions.dtw(X, Y, type_dtw="d", local_dissimilarity=d.euclidean, MTS=True)
   ```
   ```
   [out]: 22.546443515422986
   ```

   **Example 6.** For multivariate time series with visualization.
   
   ```
   from dtwParallel import dtw_functions
   from scipy.spatial import distance as d
   import numpy as np

   X = np.array([[3, 5, 8], 
                 [0, 1, 3],
                 [1, 2, 3]])

   Y = np.array([[2, 0, 8],
                 [1, 3, 8],
                 [4, 8, 12]])

   dtw_functions.dtw(X, Y, type_dtw="d", local_dissimilarity=d.euclidean, MTS=True, get_visualization=True)
   ```
   ![Example_26png](./Images/Example_6.png)

   **Remark**: In the case of MTS, it is not possible to display the alignment between the time series. 

   ```
   [out]: 21.801217248966267
   ```

   **Example 7.** For a tensor formed by N x T x F, where N is the number of observations, T the time instants and F the characteristics.
    
   ```
   import numpy as np
   from dtwParallel import dtw_functions as dtw

   x = np.load('../../Data/E0/X_train.npy')
   y = np.load('../../Data/E0/X_test.npy')

   class Input:
       def __init__(self):
           self.check_errors = False 
           self.type_dtw = "d"
           self.constrained_path_search = None
           self.MTS = True
           self.regular_flag = False
           self.n_threads = -1
           self.local_dissimilarity = "gower"
           self.visualization = False
           self.output_file = True
           self.dtw_to_kernel = False
           self.sigma_kernel = 1
           self.itakura_max_slope = None
           self.sakoe_chiba_radius = None

   input_obj = Input()
   # API call. 
   dtw.dtw_tensor_3d(x, y, input_obj)
   ```
   ```
   [out]: 
   array([[1.7200027 , 2.16000016, 1.92000033, 2.53999992],
       [1.59999973, 1.79999978, 1.83999987, 2.27999987],
       [0.5399895 , 1.52000002, 1.04000024, 1.66      ],
       [0.70000006, 1.57999993, 1.10000018, 1.69999999]])
   ```

   ```
   import numpy as np
   from dtwParallel import dtw_functions as dtw

   x = np.load('../../Data/E0/X_train.npy')
   y = np.load('../../Data/E0/X_test.npy')

   class Input:
       def __init__(self):
           self.check_errors = False 
           self.type_dtw = "i"
           self.constrained_path_search = None
           self.MTS = True
           self.regular_flag = False
           self.n_threads = -1
           self.local_dissimilarity = "gower"
           self.visualization = False
           self.output_file = True
           self.dtw_to_kernel = False
           self.sigma_kernel = 1
           self.itakura_max_slope = None
           self.sakoe_chiba_radius = None

   input_obj = Input()
   # API call. 
   dtw.dtw_tensor_3d(x, y, input_obj)
   ```
   ```
   [out]: 
   array([[ 86.0001335 , 108.00000931,  96.00001545, 126.99999504],
       [ 79.99998522,  89.99999088,  91.99999337, 113.9999931 ],
       [ 26.99947403,  76.0000011 ,  52.00001171,  82.99999923],
       [ 35.00000282,  78.99999571,  55.00000872,  84.99999817]]))
   ```


   ```
   import numpy as np
   from dtwParallel import dtw_functions as dtw

   x = np.load('../../Data/E0/X_train.npy')
   y = np.load('../../Data/E0/X_test.npy')

   class Input:
       def __init__(self):
           self.check_errors = False 
           self.type_dtw = "d"
           self.constrained_path_search = None
           self.MTS = True
           self.regular_flag = False
           self.n_threads = -1
           self.local_dissimilarity = "norm2"
           self.visualization = False
           self.output_file = True
           self.dtw_to_kernel = False
           self.sigma_kernel = 1
           self.itakura_max_slope = None
           self.sakoe_chiba_radius = None

   input_obj = Input()
   # API call. 
   dtw.dtw_tensor_3d(x, y, input_obj)
   ```
   ```
   [out]: 
   array([[2.47396197e+16, 9.07388652e+17, 2.23522660e+17, 1.68210525e+18],
       [6.12016408e+17, 1.54414468e+18, 8.60278687e+17, 2.31886127e+18],
       [4.75817098e+15, 9.36886443e+17, 2.53020450e+17, 1.71160304e+18],
       [1.02119724e+18, 8.90689643e+16, 7.72934957e+17, 6.85647630e+17]])
   ```


   ```
   import numpy as np
   from dtwParallel import dtw_functions as dtw

   x = np.load('../../Data/E0/X_train.npy')
   y = np.load('../../Data/E0/X_test.npy')

   class Input:
       def __init__(self):
           self.check_errors = False 
           self.type_dtw = "d"
           self.constrained_path_search = "itakura"
           self.MTS = True
           self.regular_flag = False
           self.n_threads = -1
           self.local_dissimilarity = "square_euclidean_distance"
           self.visualization = False
           self.output_file = True
           self.dtw_to_kernel = False
           self.sigma_kernel = 1
           self.itakura_max_slope = None
           self.sakoe_chiba_radius = None

   input_obj = Input()
   # API call. 
   dtw.dtw_tensor_3d(x, y, input_obj)
   ```
   ```
   [out]: 
   array([[8.74355404e+31, 1.17622024e+35, 7.13748276e+33, 4.04211152e+35],
       [5.35091548e+34, 3.40626113e+35, 1.05725631e+35, 7.68159658e+35],
       [3.23431302e+30, 1.25393744e+35, 9.14562117e+33, 4.18512137e+35],
       [1.48977685e+35, 1.13332577e+33, 8.53469211e+34, 6.71589533e+34]])
   ```


<a name="item1"></a>
## Configuration
For any modification of the default parameters, the ``configuration.ini`` file can be edited.

The default values are:

```
[DEFAULT]
check_errors = False
type_dtw = d
constrained_path_search = None
mts = False
regular_flag = 0
local_dissimilarity = euclidean
n_threads = -1
visualization = False
output_file = False
name_file = output
dtw_to_kernel = False
sigma_kernel = 1
itakura_max_slope = None
sakoe_chiba_radius = None
``` 

## Examples with public data

I have used data from yahoo finance (https://finance.yahoo.com/) of 505 companies, available in a .zip file. The folder where the data is located is exampleData/Data/E2_FinanceData (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/Data/E2_FinanceData). The code needed to process the information of each of the 505 companies, obtaining the tensor input to the package is located in exampleData/CodeExamples/E2_FinanceData/tensorGenerator (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E2_FinanceData).

### Experiment 1. Computational time as a function of the number of threads. 
The computation of the distance matrix has been carried out using dependent and independent DTW varying the number of threads. Code of this example is available at exampleData/Code/E2_FinanceData (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E2_FinanceData).

**DTW dependent**
![dtwParallel_dtw_D.png](./exampleData/CodeExamples/Figures/dtwParallel_dtw_D.png)

**DTW independent**
![dtwParallel_dtw_I.png](./exampleData/CodeExamples/Figures/dtwParallel_dtw_I.png)

### Experiment 2. Comparison of computational time with other packages to calculate dependent DTW. 
Code available for this example at exampleData/CodeExamples_new/plot_timeExamples_V2.ipynb (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E2_FinanceData).

![schema.png.png](./exampleData/CodeExamples/Figures/comparativeTime.png)


### Experiment 3. We performed a computational time comparison by increasing the length of the time series. 
Note that the distances used in dtwParallel and tslearn are the same. 

![schema.png.png](./exampleData/CodeExamples/Figures/comparativeTime_difflengths.png)

## Reference 

If you use `dtwParallel` in your research papers, please refer to it using following reference:
```bibtex
@article{escudero2023dtwparallel,
  title={dtwParallel: A Python package to efficiently compute dynamic time warping between time series},
  author={Escudero-Arnanz, {\'O}scar and Marques, Antonio G and Soguero-Ruiz, Cristina and Mora-Jim{\'e}nez, Inmaculada and Robles, Gregorio},
  journal={SoftwareX},
  volume={22},
  pages={101364},
  year={2023},
  publisher={Elsevier}
}
```

In case of using the `itakura parrallelogram` or `sakoe_chiba band` variants, we ask you to cite as well the following work, as we have taken this functionality granted from [tslearn](https://github.com/tslearn-team/tslearn):
```bibtex
@article{JMLR:v21:20-091,
  author  = {Romain Tavenard and Johann Faouzi and Gilles Vandewiele and 
             Felix Divo and Guillaume Androz and Chester Holtz and 
             Marie Payne and Roman Yurchak and Marc Ru{\ss}wurm and 
             Kushal Kolar and Eli Woods},
  title   = {Tslearn, A Machine Learning Toolkit for Time Series Data},
  journal = {Journal of Machine Learning Research},
  year    = {2020},
  volume  = {21},
  number  = {118},
  pages   = {1-6},
  url     = {http://jmlr.org/papers/v21/20-091.html}
}
```

## License

`dtwParallel` is released under the terms of the BSD 2-Clause license.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/oscarescuderoarnanz/dtwParallel",
    "name": "dtwParallel",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6.1",
    "maintainer_email": "",
    "keywords": "dtw,parallel,CPU",
    "author": "oscarescuderoarnanz",
    "author_email": "\u00d3scar <escuderoarnanzoscar@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/f4/7d/2ffb4f4934bef806ea61dbb0346d8c1bde8f85898b3f4c32d60739de54f2/dtwParallel-0.9.40.tar.gz",
    "platform": null,
    "description": "# Dynamic Time Warping \r\n\r\n## Paper reference\r\n\r\nhttps://www.sciencedirect.com/science/article/pii/S2352711023000602\r\n\r\n## Summary \r\nThis package allows to measurement of the similarity between two-time sequences, i.e., it finds the optimal alignment between two time-dependent sequences. It allows working with univariate (UTS) and multivariate (MTS) time series, regular (same time length), or irregular (different time length). \r\n\r\nOne of the parameters available for this method is the method used to calculate the local similarity. For this case, it is possible to use any distance available in `scipy.spatial.distance` (it does not allow to work with variables of different nature, i.e., discrete, continuous, and categorical), `gower` distance (it allows to work with variables of different nature). \r\n\r\nAt this point, using local dissimilarities such as norm1, norm2, or square euclidean distance provides optimization in terms of computational time with respect to the rest of the available local dissimilarities.\r\n\r\nThe available variants of DTW are detailed below: \r\n1) dependent DTW (\"d\").\r\n2) Independent DTW (\"i\").\r\n\r\nWe can set the following global constraints:\r\n1) Itakura parallelogram.\r\n2) Sakoe-Chiba band.\r\n3) None.\r\n\r\nExtra functionality has been incorporated to transform the resulting DTW matrix into an exponential kernel, given the sigma value (default 1).\r\n\r\nDisplay for 2-time series (TS):\r\n- It incorporates the possibility of visualizing the cost matrix, the optimal path to reach the DTW distance value between two TS, and the alignment between two TS. This will allow its use in a didactic way, providing a better understanding of the method used.\r\n\r\nCommon functionalities for N (> 2) time series (TS):\r\n- The calculation can be parallelized by the CPU by selecting the number of threads. As a result, we will obtain the distance matrix. \r\n- It is possible to perform distance computation and similarity computation (based on an exponential kernel).\r\n\r\n The input data types via API are (1) CSV; (2) array; (3) pandas (pd.DataFrame or pd.Series) and (4) npy (for tensors).\r\n\r\n## Table of content \r\n\r\n| Section | Description |\r\n|-|-|\r\n| [Installation](#installation) | Installing the dependencies and dtwParallel |\r\n| [Getting started](#requirements) | Packages necessary to work with dtwParallel |\r\n| [Available parameters](#parameters) | Modifiable parameters in terminal and API with their possible values |\r\n| [Usage](#usage) | Different examples for terminal and API |\r\n| [Configuration](#configuration) | Composition of configuration.ini file |\r\n| [Examples with public data](#realexamples) | Examples with real financial data |\r\n| [References](#reference) | References to cite |\r\n| [License](#license) | Package license |\r\n \r\n\r\n## Package structure \r\n\r\n<p align=\"center\"> <img src=\"./Images/schema.png\"> </p>\r\n\r\n <!-- <p align=\"center\"> <img src=\"./Images/fileSchema.png\"> </p> -->\r\n\r\n\r\n## Installation\r\n\r\ndtwParallel can be installed using [pip](https://pip.pypa.io/en/stable/), a tool\r\nfor installing Python packages. To do it, run the following command:\r\n```\r\npip install dtwParallel\r\n```\r\n\r\n**Current version:** 0.9.39\r\n\r\n\r\n## Requirements\r\n\r\ndtwParallel requires Python >= 3.6.1 or later to run. For other Python\r\ndependencies, please check the `pyproject.toml` file included\r\non this repository.\r\n\r\n\r\nNote that you should have also the following packages installed in your system:\r\n- numpy\r\n- pandas\r\n- matplotlib\r\n- seaborn\r\n- gower\r\n- setuptools\r\n- scipy\r\n- joblib\r\n- numba\r\n\r\n## Available parameters\r\n\r\nThe different parameters available with their possible values are listed below:\r\n\r\n| Parameter description | Terminal usage | API usage | Possible values |\r\n|-|-|-|-|\r\n| Check errors | -ce or --check_errors | check_errors | True or False |\r\n| Type of DTW variant | -t or --type_dtw| type_dtw | \"d\" or \"i\" |\r\n| Global constraint | -c or --constrained_path_search | constrained_path_search | \"itakura\", \"sakoe_chiba\" or None |\r\n| Local dissimilarity value | -d or --local_dissimilarity | local_dissimilarity | any distance available in `scipy.spatial.distance`, \"norm1\", \"norm2\", \"gower\" or \"square_euclidean_distance\" |\r\n| Time series introduced: univariate or multivariate | MTS | MTS | True or False |\r\n| Value used to complete irregular MTS. This value is removed transparently to the user | -rf or --regular_flag | regular_flag | int |\r\n| Number of threads used for multiple MTS parallelization | -n or --n_threads| n_threads | int |\r\n| Visualization | -vis or --visualization | get_visualization | True or False |\r\n| Obtain the result in a file | -of or --output_file | not possible | True or False |\r\n| Name for the output file | -nf or --name_file| not possible | string |\r\n| Transformation of the DTW distance matrix to an exponential kernel | -k or --dtw_to_kernel | dtw_to_kernel | True or False |\r\n| Sigma value for kernel transformation | -s or --sigma_kernel | sigma_kernel | float |\r\n| Maximum slope for the Itakura parallelogram | -imx or --itakura_max_slope | itakura_max_slope | float or None |\r\n| Radius to be used for Sakoe-Chiba band | -scr or --sakoe_chiba_radius | sakoe_chiba_radius | int or None |\r\n\r\n\r\n## Usage\r\n\r\nBased on the previous scheme, this package can be used in three different contexts: \r\n\r\n### 1) Calculation of the DTW distance with input from the terminal.\r\n   \r\n   The generic example is shown below:\r\n      \r\n      dtwParallel -x <floats> -y <floats> -d <str> -ce <bool> -of <bool>\r\n      \r\n   Note that only the x and y values need to be set. If not indicated, the rest of the values will be selected from the file containing the default values, ``configuration.ini``.\r\n\r\n   Next, different uses are shown by modifying the parameters of the function:\r\n   \r\n   **a) Example 1.** Considers the Euclidean distance, activates the option -ce to check for errors, and uses as input two UTS (denoted as x and y) with the same length (T=10). \r\n   Firstly, the input TS and distance are checked as valid entries. Secondly, the dtwParallel package computes the DTW distance. Thirdly, the output is shown in the terminal (while in most cases, the outputs are forwarded to a file, we selected this option to facilitate exposition).\r\n   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 5 3 6 8 9 15 -y 12 0 0 3 5 6 30 1 2 4 -ce True\r\n\r\n   ```\r\n   ```\r\n   [out]: 65.0\r\n   ```\r\n\r\n   **b) Example 2.** Considering the CityBlock distance.\r\n   \r\n   ```\r\n   dtwParallel -x 2.5 4.3 6.6 8.0 1 0 0 1 5.5 15.2  -y 12.1 0 0 1 1 6.4 3.5 1 0 0  -d cityblock\r\n   ```\r\n   ```\r\n   [out]: 45.4\r\n   ```\r\n\r\n   **c) Example 3.** This examples are, respectively, counterparts to **Example 1** and **Example 2**.\r\n   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 5 3 -y 12 0 0 3 5 6 30 1 2 4\r\n   ```\r\n   ```\r\n   [out]: 44.0\r\n   ```   \r\n   ```\r\n   dtwParallel -x 2.5 4.3 6.6 8.0 1 0 0 1 5.5 15.2 -y 1 0 0 1 -d cityblock\r\n   ```\r\n   ```\r\n   [out]: 36.09\r\n   ```   \r\n\r\n   **d) Example 4.** **Novelty**: It has been included the possibility to calculate the Itakura parallelogram and the Sakoe-Chiba band.\r\n   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 -c \"sakoe_chiba\" -d \"square_euclidean_distance\"\r\n   ```\r\n   ```\r\n   [out]: 296.0\r\n   ```   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 2 4 7 1 9 10 -c \"itakura\" -d \"square_euclidean_distance\"\r\n   ```\r\n   ```\r\n   [out]: 169.0\r\n   ```   \r\n\r\n   **e) Example e.** **Novelty**: A straightforward and optimal way to calculate norm 1, norm 2 and square euclidean distance is included.\r\n\r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 5 6 1 0 9 11 -d \"norm1\"\r\n   ```\r\n   ```\r\n   [out]: 12.24\r\n   ```   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 5 6 1 0 9 11 -d \"norm2\"\r\n   ```\r\n   ```\r\n   [out]: 18.0\r\n   ```   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 1 5 15 -y 1 0 0 1 5 6 1 0 9 11 -d \"square_euclidean_distance\"\r\n   ```\r\n   ```\r\n   [out]: 48.0\r\n   ```   \r\n   **We include another example with differents lengths of the time series:**\r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 -y 1 0 0 1 5 6 1 0 9 11 -d \"norm1\"\r\n   ```\r\n   ```\r\n   [out]: 13.55\r\n   ```   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 -y 1 0 0 1 5 6 1 0 9 11 -d \"norm2\"\r\n   ```\r\n   ```\r\n   [out]: 29.0\r\n   ```   \r\n   ```\r\n   dtwParallel -x 2 4 6 8 1 0 0 -y 1 0 0 1 5 6 1 0 -d \"square_euclidean_distance\"\r\n   ```\r\n   ```\r\n   [out]: 15.0\r\n   ```   \r\n\r\n\r\n   **Remarks:**\r\n   The calculation of the DTW distance from the command line is limited to simple examples that allow a quick understanding due to the complexity of the terminal handling:\r\n   - Univariate time series.\r\n   - We can set the following restrictions to the calculation of dependent (d) or independent (i) DTW:  Itakura parallelogram, Sakoe-Chiba band or None.\r\n   - Include a straightforward and optimal way to calculate norm 1 (l1), norm 2 (l2) and square euclidean distance.\r\n   - To visualize the cost matrix, routing and the alignment between a pair of series, it will be necessary to use an integrated development environment.\r\n\r\n### 2) Calculation of the DTW distance with input from a file, haciendo uso de terminal.\r\n\r\n\r\n   #### The generic example of univariate time series entered by means of ``csv files`` is shown below:\r\n   ```\r\n   dtwParallel <file_X> -d <str> -ce <bool> -of <bool>\r\n   ```\r\n   If you want to modify any of the possible values, it is necessary to modify the configuration.ini file. The possible values are those shown in [Configuration](#item1).\r\n   \r\n   **a) Example 1.** Calculation of univariate time series taking as input a csv file containing x and y. \r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E1_SyntheticData/example_1.csv\r\n   ```\r\n   ```      \r\n   [out]: 40.6\r\n   ```\r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E1_SyntheticData/example_1.csv -d \"gower\"\r\n   ```\r\n   ```      \r\n   [out]: 10.00\r\n   ```\r\n   ```\r\n   dtwParallel exampleData/Data/E1_SyntheticData/example_1.csv -d \"norm1\"\r\n   ```\r\n   ```      \r\n   [out]: 18.46\r\n   ```\r\n      \r\n   #### The generic example of multivariate time series entered by means of ``csv files`` is shown below:\r\n\r\n   ```\r\n   dtwParallel <file_X> -d <str> -t <str> -ce <bool> -of <bool> -n <int> -k <bool> -s <float>\r\n   ```\r\n\r\n   **b) Example 2.** Multivariate time series computation using a csv file containing x and y as input.\r\n   ```\r\n   dtwParallel exampleData/Data/E1_SyntheticData/example_2.csv\r\n   ```\r\n   ```         \r\n   [out]: 81.99\r\n   ```   \r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E1_SyntheticData/example_2.csv -d gower -t i \r\n   ```\r\n   ```              \r\n   [out]: 28.99\r\n   ``` \r\n\r\n   #### The generic example for ``npy files`` is shown below:\r\n\r\n   ```\r\n   dtwParallel <file_X> <file_Y> -d <str> -t <str> -ce <bool> -of <bool> -n <int> -k <bool> -s <float>\r\n   ```\r\n\r\n   **c) Example 3.** It computes the distance to itself. With differents types of DTW, distances and constraints.\r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy \r\n   ```\r\n   ```\r\n   [out]: [[0.00000000e+00 6.36756028e+17 2.94977907e+16 9.96457616e+17]\r\n          [6.36756028e+17 0.00000000e+00 6.07258237e+17 1.63321364e+18]\r\n          [2.94977907e+16 6.07258237e+17 0.00000000e+00 1.02595541e+18]\r\n          [9.96457616e+17 1.63321364e+18 1.02595541e+18 0.00000000e+00]]\r\n   ```\r\n   \r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy -t \"i\"\r\n   ```\r\n   ```\r\n   [out]: [[0.00000000e+00 1.68469810e+18 7.80438184e+16 2.63637904e+18]\r\n           [1.68469810e+18 0.00000000e+00 1.60665428e+18 4.32107714e+18]\r\n           [7.80438184e+16 1.60665428e+18 0.00000000e+00 2.71442286e+18]\r\n           [2.63637904e+18 4.32107714e+18 2.71442286e+18 0.00000000e+00]]\r\n   ```\r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy -c \"itakura\" -d \"square_euclidean_distance\"\r\n   ```\r\n   ```\r\n   [out]: [[0.00000000e+00 5.79226055e+34 1.24302808e+32 1.41846826e+35]\r\n           [5.79226055e+34 0.00000000e+00 5.26803666e+34 3.81055258e+35]\r\n           [1.24302808e+32 5.26803666e+34 0.00000000e+00 1.50369214e+35]\r\n           [1.41846826e+35 3.81055258e+35 1.50369214e+35 0.00000000e+00]]\r\n   ```\r\n\r\n\r\n   **d) Example 4.** We compute the distance matrix DTW between X and Y.\r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy\r\n   ```\r\n   ```\r\n   [out]: [[2.47396197e+16 9.07388652e+17 2.23522660e+17 1.68210525e+18]\r\n          [6.12016408e+17 1.54414468e+18 8.60278687e+17 2.31886127e+18]\r\n          [4.75817098e+15 9.36886443e+17 2.53020450e+17 1.71160304e+18]\r\n          [1.02119724e+18 8.90689643e+16 7.72934957e+17 6.85647630e+17]]\r\n   ```\r\n\r\n   **e) Example 5.** We select two types of distance: gower distance and norm 1. We obtain the distance matrix DTW between X and Y. \r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d \"gower\"\r\n   ```\r\n   ```\r\n   [out]: [[1.7200027  2.16000016 1.92000033 2.53999992]\r\n          [1.59999973 1.79999978 1.83999987 2.27999987]\r\n          [0.5399895  1.52000002 1.04000024 1.66      ]\r\n          [0.70000006 1.57999993 1.10000018 1.69999999]]\r\n   ```\r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d \"norm1\"\r\n   ```\r\n   ```\r\n   [out]: [[4.16145813e+08 2.52026200e+09 1.25086315e+09 3.43143363e+09]\r\n           [2.06981034e+09 3.28770631e+09 2.45396634e+09 4.02889922e+09]\r\n           [1.82502594e+08 2.56089928e+09 1.33084302e+09 3.46139008e+09]\r\n           [2.67364557e+09 7.89609239e+08 2.32605776e+09 2.19078374e+09]]\r\n   ```\r\n\r\n   **f) Example 6.** Compute the gower distance between X and Y, and we select the number of threads.\r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d \"gower\" -n 12\r\n   ```\r\n   ```\r\n   [out]: [[1.7200027  2.16000016 1.92000033 2.53999992]\r\n          [1.59999973 1.79999978 1.83999987 2.27999987]\r\n          [0.5399895  1.52000002 1.04000024 1.66      ]\r\n          [0.70000006 1.57999993 1.10000018 1.69999999]]\r\n   ```\r\n\r\n   **g) Example 7.** Compute the gower distance between X and Y, then we obtain the output per file.\r\n\r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy exampleData/Data/E0/X_test.npy -d \"gower\" -n 12 -of True\r\n   ```\r\n   ```\r\n   [out]: output.csv\r\n   ```\r\n\r\n\r\n   **h) Example 8.** We calculate the distance between X and Y, and transform to Gaussian kernel with sigma_kernel=0.5. We return the distance matrix and the kernel.  \r\n   ```\r\n   dtwParallel exampleData/Data/E0/X_train.npy -k True -s 1000000000\r\n   ```\r\n   ```\r\n   [out]: (array([[0.00000000e+00, 6.36756028e+17, 2.94977907e+16, 9.96457616e+17],\r\n                  [6.36756028e+17, 0.00000000e+00, 6.07258237e+17, 1.63321364e+18],\r\n                  [2.94977907e+16, 6.07258237e+17, 0.00000000e+00, 1.02595541e+18],\r\n                  [9.96457616e+17, 1.63321364e+18, 1.02595541e+18, 0.00000000e+00]]),\r\n           array([[1.        , 0.7273278 , 0.98535934, 0.60760589],\r\n                  [0.7273278 , 1.        , 0.73813458, 0.44192866],\r\n                  [0.98535934, 0.73813458, 1.        , 0.59871014],\r\n                  [0.60760589, 0.44192866, 0.59871014, 1.        ]]))\r\n   ```\r\n\r\n   **Remarks:**\r\n   - You can run from any repository, but be careful! The .npy file must be found. \r\n\r\n\r\n### 3) Making use of the API  \r\n   \r\n   The generic example is shown below:\r\n\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n    \r\n   # For Univariate Time Series\r\n   dtw_functions.dtw(x, y, type_dtw, local_dissimilarity, MTS, get_visualization, check_errors)\r\n   \r\n   # For Multivariate Time Series\r\n   dtw_functions.dtw_tensor_3d(X_1, X_2, object)\r\n   ```\r\n\r\n   The examples shown below are executed in jupyter-notebook. Code available in exampleData/CodeExamples/E1_SyntheticData (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E1_SyntheticData). These examples can be executed in any Integrated Development Environment.\r\n\r\n   **Example 1.** For univariate time series.\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [1,2,3]\r\n   y = [0,0,1]\r\n   \r\n   dtw_functions.dtw(x,y,local_dissimilarity=d.euclidean)\r\n   ```\r\n   ```\r\n   [out]: 5.0\r\n   ```\r\n\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [1,2,3,3,4,5,6,7]\r\n   y = [0,1,5,7,1,8,1,4]\r\n   \r\n   dtw_functions.dtw(x,y,local_dissimilarity=d.euclidean)\r\n   ```\r\n   ```\r\n   [out]: 22.0\r\n   ```\r\n\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   \r\n   # For Univariate Time Series\r\n   x = [1,2,3,3,4,5,6,7]\r\n   y = [0,1,5,7,1,8,1,4]\r\n   \r\n   dtw_functions.dtw(x,y,local_dissimilarity=\"norm1\")\r\n   ```\r\n   ```\r\n   [out]: 12.84\r\n   ```\r\n\r\n   ```\r\n   import pandas as pd\r\n   import numpy as np\r\n   from dtwParallel import dtw_functions \r\n\r\n   # Use of dataframes with 1D (UTS) as entry data\r\n   x = pd.DataFrame(np.random.randint(0,10, size=(1,8)))\r\n   y = pd.DataFrame(np.random.randint(0,10, size=(1,8)))\r\n   dtw_functions.dtw(x, y, n_threads=8)\r\n   ```\r\n   ```\r\n   [out]: Result with random dependency.\r\n   ```\r\n   ```\r\n   import pandas as pd\r\n   import numpy as np\r\n   from dtwParallel import dtw_functions \r\n\r\n   # Use of dataframes with 2D (MTS) as entry data\r\n   x = pd.DataFrame([np.random.randn(10), np.random.randn(10)])\r\n   y = pd.DataFrame([np.random.randn(10), np.random.randn(10)])\r\n   dtw_functions.dtw(x, y, MTS=True, n_threads=8)\r\n   ```\r\n   ```\r\n   [out]: Result with random dependency.\r\n   ```\r\n\r\n   ```\r\n   import pandas as pd \r\n   import numpy as np\r\n   from dtwParallel import dtw_functions \r\n\r\n   # Use of dataframes with 1D (UTS) as entry data\r\n   x = pd.DataFrame(np.random.randn(10)).T\r\n   y = pd.DataFrame(np.random.randn(10)).T\r\n\r\n   dtw_functions.dtw(x,y,n_threads=8)\r\n   ```\r\n   ```\r\n   [out]: Result with random dependency.\r\n   ```\r\n\r\n   ```\r\n   import pandas as pd\r\n   import numpy as np\r\n   from dtwParallel import dtw_functions \r\n\r\n   # Use of pd.Series as entry data\r\n   x = pd.Series(np.random.randn(10))\r\n   y = pd.Series(np.random.randn(10))\r\n\r\n   dtw_functions.dtw(x,y,local_dissimilarity=\"norm2\")\r\n   ```\r\n   ```\r\n   [out]: Result with random dependency.\r\n   ```\r\n\r\n\r\n   **Example 2.** For univariate time series with different lengths.\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [1,2,3,5,8,9,5,4,2]\r\n   y = [1,0,1,0,1,1]\r\n   \r\n   dtw_functions.dtw(x, y, local_dissimilarity=d.euclidean)\r\n   ```\r\n   ```\r\n   [out]: 32.0\r\n   ```\r\n\r\n   **Example 3.** For univariate time series with visualization (cost matrix, path and alignment between a pair of time series).\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [4,2,8,4,5]\r\n   y = [0,1,0,8,9]\r\n   \r\n   dtw_functions.dtw(x, y, local_dissimilarity=d.euclidean, get_visualization=True)\r\n   ```\r\n   ```\r\n   [out]: 15.0\r\n   ```\r\n\r\n   ![Example_3_1.png](./Images/Example_3_1.png)\r\n   ![Example_3_1_2.png](./Images/Example_3_1_2.png)\r\n\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]\r\n   y = [0,1,0,8,9,1,3,2,4,3,5,6,7,8,5,6]\r\n\r\n   dtw_functions.dtw(x, y, constrained_path_search=None,local_dissimilarity=d.euclidean, get_visualization=True)\r\n   ```\r\n   ```\r\n   [out]: 20.0\r\n   ```\r\n\r\n   ![Example_3_1.png](./Images/Example_3_2_0.png)\r\n   ![Example_3_1_2.png](./Images/Example_3_2_2_0.png)\r\n\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]\r\n   y = [0,1,0,8,9,1,3,2,4,3,5,6,7,8,5,6]\r\n\r\n   dtw_functions.dtw(x, y, constrained_path_search=\"itakura\",local_dissimilarity=d.euclidean, get_visualization=True)\r\n   ```\r\n   ```\r\n   [out]: 24.0\r\n   ```\r\n\r\n   ![Example_3_1.png](./Images/Example_3_2.png)\r\n   ![Example_3_1_2.png](./Images/Example_3_2_2.png)\r\n\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]\r\n   y = [0,1,0,8,9,1,3,2,4,3,5,6,7,8,5,6]\r\n\r\n   dtw_functions.dtw(x, y, constrained_path_search=\"sakoe_chiba\",local_dissimilarity=d.euclidean, get_visualization=True)\r\n   ```\r\n   ```\r\n   [out]: 25.0\r\n   ```\r\n\r\n   ![Example_3_1.png](./Images/Example_3_3.png)\r\n   ![Example_3_1_2.png](./Images/Example_3_3_2.png)\r\n\r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   \r\n   # For Univariate Time Series\r\n   x = [4,2,8,4,5,1,3,5,2,5,7,8,4,5,6,7]\r\n   y = [0,1,0,8,9,1,3,2,4,3,5]\r\n   \r\n   dtw_functions.dtw(x, y, local_dissimilarity=d.euclidean, get_visualization=True)\r\n   ```\r\n   ```\r\n   [out]: 26.0\r\n   ```\r\n\r\n   ![Example_3_1.png](./Images/Example_3_4.png)\r\n   ![Example_3_1_2.png](./Images/Example_3_4_2.png)\r\n\r\n   **Example 4.** For multivariate time series.\r\n   \r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   import numpy as np\r\n   \r\n   X = np.array([[3,5,8], \r\n                [5, 1,9]])\r\n   \r\n   Y = np.array([[2, 0,8],\r\n                [4, 3,8]])\r\n               \r\n   dtw_functions.dtw(X, Y, type_dtw=\"d\", local_dissimilarity=d.euclidean, MTS=True)\r\n   ```\r\n   ```\r\n   [out]: 7.548509256375962\r\n   ```\r\n\r\n   **Example 5.** For multivariate time series with different lengths.\r\n   \r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   import numpy as np\r\n\r\n   X = np.array([[3, 5, 8], \r\n                 [5, 1, 9],\r\n                 [0, 1, 1], \r\n                 [1, 4, 2]])\r\n\r\n   Y = np.array([[2, 0,8],\r\n                 [4, 3,8]])\r\n\r\n   dtw_functions.dtw(X, Y, type_dtw=\"d\", local_dissimilarity=d.euclidean, MTS=True)\r\n   ```\r\n   ```\r\n   [out]: 22.546443515422986\r\n   ```\r\n\r\n   **Example 6.** For multivariate time series with visualization.\r\n   \r\n   ```\r\n   from dtwParallel import dtw_functions\r\n   from scipy.spatial import distance as d\r\n   import numpy as np\r\n\r\n   X = np.array([[3, 5, 8], \r\n                 [0, 1, 3],\r\n                 [1, 2, 3]])\r\n\r\n   Y = np.array([[2, 0, 8],\r\n                 [1, 3, 8],\r\n                 [4, 8, 12]])\r\n\r\n   dtw_functions.dtw(X, Y, type_dtw=\"d\", local_dissimilarity=d.euclidean, MTS=True, get_visualization=True)\r\n   ```\r\n   ![Example_26png](./Images/Example_6.png)\r\n\r\n   **Remark**: In the case of MTS, it is not possible to display the alignment between the time series. \r\n\r\n   ```\r\n   [out]: 21.801217248966267\r\n   ```\r\n\r\n   **Example 7.** For a tensor formed by N x T x F, where N is the number of observations, T the time instants and F the characteristics.\r\n    \r\n   ```\r\n   import numpy as np\r\n   from dtwParallel import dtw_functions as dtw\r\n\r\n   x = np.load('../../Data/E0/X_train.npy')\r\n   y = np.load('../../Data/E0/X_test.npy')\r\n\r\n   class Input:\r\n       def __init__(self):\r\n           self.check_errors = False \r\n           self.type_dtw = \"d\"\r\n           self.constrained_path_search = None\r\n           self.MTS = True\r\n           self.regular_flag = False\r\n           self.n_threads = -1\r\n           self.local_dissimilarity = \"gower\"\r\n           self.visualization = False\r\n           self.output_file = True\r\n           self.dtw_to_kernel = False\r\n           self.sigma_kernel = 1\r\n           self.itakura_max_slope = None\r\n           self.sakoe_chiba_radius = None\r\n\r\n   input_obj = Input()\r\n   # API call. \r\n   dtw.dtw_tensor_3d(x, y, input_obj)\r\n   ```\r\n   ```\r\n   [out]: \r\n   array([[1.7200027 , 2.16000016, 1.92000033, 2.53999992],\r\n       [1.59999973, 1.79999978, 1.83999987, 2.27999987],\r\n       [0.5399895 , 1.52000002, 1.04000024, 1.66      ],\r\n       [0.70000006, 1.57999993, 1.10000018, 1.69999999]])\r\n   ```\r\n\r\n   ```\r\n   import numpy as np\r\n   from dtwParallel import dtw_functions as dtw\r\n\r\n   x = np.load('../../Data/E0/X_train.npy')\r\n   y = np.load('../../Data/E0/X_test.npy')\r\n\r\n   class Input:\r\n       def __init__(self):\r\n           self.check_errors = False \r\n           self.type_dtw = \"i\"\r\n           self.constrained_path_search = None\r\n           self.MTS = True\r\n           self.regular_flag = False\r\n           self.n_threads = -1\r\n           self.local_dissimilarity = \"gower\"\r\n           self.visualization = False\r\n           self.output_file = True\r\n           self.dtw_to_kernel = False\r\n           self.sigma_kernel = 1\r\n           self.itakura_max_slope = None\r\n           self.sakoe_chiba_radius = None\r\n\r\n   input_obj = Input()\r\n   # API call. \r\n   dtw.dtw_tensor_3d(x, y, input_obj)\r\n   ```\r\n   ```\r\n   [out]: \r\n   array([[ 86.0001335 , 108.00000931,  96.00001545, 126.99999504],\r\n       [ 79.99998522,  89.99999088,  91.99999337, 113.9999931 ],\r\n       [ 26.99947403,  76.0000011 ,  52.00001171,  82.99999923],\r\n       [ 35.00000282,  78.99999571,  55.00000872,  84.99999817]]))\r\n   ```\r\n\r\n\r\n   ```\r\n   import numpy as np\r\n   from dtwParallel import dtw_functions as dtw\r\n\r\n   x = np.load('../../Data/E0/X_train.npy')\r\n   y = np.load('../../Data/E0/X_test.npy')\r\n\r\n   class Input:\r\n       def __init__(self):\r\n           self.check_errors = False \r\n           self.type_dtw = \"d\"\r\n           self.constrained_path_search = None\r\n           self.MTS = True\r\n           self.regular_flag = False\r\n           self.n_threads = -1\r\n           self.local_dissimilarity = \"norm2\"\r\n           self.visualization = False\r\n           self.output_file = True\r\n           self.dtw_to_kernel = False\r\n           self.sigma_kernel = 1\r\n           self.itakura_max_slope = None\r\n           self.sakoe_chiba_radius = None\r\n\r\n   input_obj = Input()\r\n   # API call. \r\n   dtw.dtw_tensor_3d(x, y, input_obj)\r\n   ```\r\n   ```\r\n   [out]: \r\n   array([[2.47396197e+16, 9.07388652e+17, 2.23522660e+17, 1.68210525e+18],\r\n       [6.12016408e+17, 1.54414468e+18, 8.60278687e+17, 2.31886127e+18],\r\n       [4.75817098e+15, 9.36886443e+17, 2.53020450e+17, 1.71160304e+18],\r\n       [1.02119724e+18, 8.90689643e+16, 7.72934957e+17, 6.85647630e+17]])\r\n   ```\r\n\r\n\r\n   ```\r\n   import numpy as np\r\n   from dtwParallel import dtw_functions as dtw\r\n\r\n   x = np.load('../../Data/E0/X_train.npy')\r\n   y = np.load('../../Data/E0/X_test.npy')\r\n\r\n   class Input:\r\n       def __init__(self):\r\n           self.check_errors = False \r\n           self.type_dtw = \"d\"\r\n           self.constrained_path_search = \"itakura\"\r\n           self.MTS = True\r\n           self.regular_flag = False\r\n           self.n_threads = -1\r\n           self.local_dissimilarity = \"square_euclidean_distance\"\r\n           self.visualization = False\r\n           self.output_file = True\r\n           self.dtw_to_kernel = False\r\n           self.sigma_kernel = 1\r\n           self.itakura_max_slope = None\r\n           self.sakoe_chiba_radius = None\r\n\r\n   input_obj = Input()\r\n   # API call. \r\n   dtw.dtw_tensor_3d(x, y, input_obj)\r\n   ```\r\n   ```\r\n   [out]: \r\n   array([[8.74355404e+31, 1.17622024e+35, 7.13748276e+33, 4.04211152e+35],\r\n       [5.35091548e+34, 3.40626113e+35, 1.05725631e+35, 7.68159658e+35],\r\n       [3.23431302e+30, 1.25393744e+35, 9.14562117e+33, 4.18512137e+35],\r\n       [1.48977685e+35, 1.13332577e+33, 8.53469211e+34, 6.71589533e+34]])\r\n   ```\r\n\r\n\r\n<a name=\"item1\"></a>\r\n## Configuration\r\nFor any modification of the default parameters, the ``configuration.ini`` file can be edited.\r\n\r\nThe default values are:\r\n\r\n```\r\n[DEFAULT]\r\ncheck_errors = False\r\ntype_dtw = d\r\nconstrained_path_search = None\r\nmts = False\r\nregular_flag = 0\r\nlocal_dissimilarity = euclidean\r\nn_threads = -1\r\nvisualization = False\r\noutput_file = False\r\nname_file = output\r\ndtw_to_kernel = False\r\nsigma_kernel = 1\r\nitakura_max_slope = None\r\nsakoe_chiba_radius = None\r\n``` \r\n\r\n## Examples with public data\r\n\r\nI have used data from yahoo finance (https://finance.yahoo.com/) of 505 companies, available in a .zip file. The folder where the data is located is exampleData/Data/E2_FinanceData (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/Data/E2_FinanceData). The code needed to process the information of each of the 505 companies, obtaining the tensor input to the package is located in exampleData/CodeExamples/E2_FinanceData/tensorGenerator (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E2_FinanceData).\r\n\r\n### Experiment 1. Computational time as a function of the number of threads. \r\nThe computation of the distance matrix has been carried out using dependent and independent DTW varying the number of threads. Code of this example is available at exampleData/Code/E2_FinanceData (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E2_FinanceData).\r\n\r\n**DTW dependent**\r\n![dtwParallel_dtw_D.png](./exampleData/CodeExamples/Figures/dtwParallel_dtw_D.png)\r\n\r\n**DTW independent**\r\n![dtwParallel_dtw_I.png](./exampleData/CodeExamples/Figures/dtwParallel_dtw_I.png)\r\n\r\n### Experiment 2. Comparison of computational time with other packages to calculate dependent DTW. \r\nCode available for this example at exampleData/CodeExamples_new/plot_timeExamples_V2.ipynb (https://github.com/oscarescuderoarnanz/dtwParallel/tree/main/exampleData/CodeExamples_new/E2_FinanceData).\r\n\r\n![schema.png.png](./exampleData/CodeExamples/Figures/comparativeTime.png)\r\n\r\n\r\n### Experiment 3. We performed a computational time comparison by increasing the length of the time series. \r\nNote that the distances used in dtwParallel and tslearn are the same. \r\n\r\n![schema.png.png](./exampleData/CodeExamples/Figures/comparativeTime_difflengths.png)\r\n\r\n## Reference \r\n\r\nIf you use `dtwParallel` in your research papers, please refer to it using following reference:\r\n```bibtex\r\n@article{escudero2023dtwparallel,\r\n  title={dtwParallel: A Python package to efficiently compute dynamic time warping between time series},\r\n  author={Escudero-Arnanz, {\\'O}scar and Marques, Antonio G and Soguero-Ruiz, Cristina and Mora-Jim{\\'e}nez, Inmaculada and Robles, Gregorio},\r\n  journal={SoftwareX},\r\n  volume={22},\r\n  pages={101364},\r\n  year={2023},\r\n  publisher={Elsevier}\r\n}\r\n```\r\n\r\nIn case of using the `itakura parrallelogram` or `sakoe_chiba band` variants, we ask you to cite as well the following work, as we have taken this functionality granted from [tslearn](https://github.com/tslearn-team/tslearn):\r\n```bibtex\r\n@article{JMLR:v21:20-091,\r\n  author  = {Romain Tavenard and Johann Faouzi and Gilles Vandewiele and \r\n             Felix Divo and Guillaume Androz and Chester Holtz and \r\n             Marie Payne and Roman Yurchak and Marc Ru{\\ss}wurm and \r\n             Kushal Kolar and Eli Woods},\r\n  title   = {Tslearn, A Machine Learning Toolkit for Time Series Data},\r\n  journal = {Journal of Machine Learning Research},\r\n  year    = {2020},\r\n  volume  = {21},\r\n  number  = {118},\r\n  pages   = {1-6},\r\n  url     = {http://jmlr.org/papers/v21/20-091.html}\r\n}\r\n```\r\n\r\n## License\r\n\r\n`dtwParallel` is released under the terms of the BSD 2-Clause license.\r\n",
    "bugtrack_url": null,
    "license": "BSD 2-Clause License  Copyright (c) 2017, Romain Tavenard Copyright (c) 2022, Universidad Rey Juan Carlos All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ",
    "summary": "Python implementation of Dynamic Time Warping (DTW), which allows computing the dtw distance between one-dimensional and multidimensional time series, with the possibility of visualisation (one-dimensional case) and parallelisation (multidimensional case).",
    "version": "0.9.40",
    "project_urls": {
        "Homepage": "https://github.com/oscarescuderoarnanz/dtwParallel"
    },
    "split_keywords": [
        "dtw",
        "parallel",
        "cpu"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0108182ea247ce488ef1f8b164d1e31f38e59e1c5ee75b017c31b9a5f92036fd",
                "md5": "a8a3d1536493ec12f9249775e1edf71b",
                "sha256": "a910a80b16cc1bf19715b7e3e2befc0635021ea90433fc4280d814fe958bf4f4"
            },
            "downloads": -1,
            "filename": "dtwParallel-0.9.40-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a8a3d1536493ec12f9249775e1edf71b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6.1",
            "size": 24115,
            "upload_time": "2023-10-19T09:27:37",
            "upload_time_iso_8601": "2023-10-19T09:27:37.685745Z",
            "url": "https://files.pythonhosted.org/packages/01/08/182ea247ce488ef1f8b164d1e31f38e59e1c5ee75b017c31b9a5f92036fd/dtwParallel-0.9.40-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f47d2ffb4f4934bef806ea61dbb0346d8c1bde8f85898b3f4c32d60739de54f2",
                "md5": "8356a301bb76c2af48593e0df88b796e",
                "sha256": "23b98ee52d2e8d6ba7a63eb32e19089b281f7a59eb5b3f06fbeee3b7bd3fd6a1"
            },
            "downloads": -1,
            "filename": "dtwParallel-0.9.40.tar.gz",
            "has_sig": false,
            "md5_digest": "8356a301bb76c2af48593e0df88b796e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6.1",
            "size": 35208,
            "upload_time": "2023-10-19T09:27:38",
            "upload_time_iso_8601": "2023-10-19T09:27:38.933094Z",
            "url": "https://files.pythonhosted.org/packages/f4/7d/2ffb4f4934bef806ea61dbb0346d8c1bde8f85898b3f4c32d60739de54f2/dtwParallel-0.9.40.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-19 09:27:38",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "oscarescuderoarnanz",
    "github_project": "dtwParallel",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "dtwparallel"
}
        
Elapsed time: 0.13630s