linmdtw package¶
Submodules¶
linmdtw.dtw module¶
- linmdtw.dtw.check_euclidean_inputs(X, Y)[source]¶
Check the input of two time series in Euclidean spaces, which are to be warped to each other. They must satisfy: 1. They are in the same dimension space 2. They are 32-bit 3. They are in C-contiguous order
If #2 or #3 are not satisfied, automatically fix them and warn the user. Furthermore, warn the user if X or Y has more columns than rows, since the convention is that points are along rows and dimensions are along columns
- Parameters
X (ndarray(M, d)) – The first time series
Y (ndarray(N, d)) – The second time series
- Returns
X (ndarray(M, d)) – The first time series, possibly copied in memory to be 32-bit, C-contiguous
Y (ndarray(N, d)) – The second time series, possibly copied in memory to be 32-bit, C-contiguous
- linmdtw.dtw.dtw_brute(X, Y, debug=False)[source]¶
Compute brute force dynamic time warping between two time-ordered point clouds in Euclidean space, using cython on the backend
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
Y (ndarray(N, d)) – A d-dimensional Euclidean point cloud with N points
debug (boolean) – Whether to keep track of debugging information
- Returns
{ –
- ‘cost’: float
The optimal cost of the alignment (if computation didn’t stop prematurely),
- ’U’/’L’/’UL’: ndarray(M, N)
The choice matrices (if debugging),
- ’S’: ndarray(M, N)
The accumulated cost matrix (if debugging)
}
- linmdtw.dtw.dtw_brute_backtrace(X, Y, debug=False)[source]¶
Compute dynamic time warping between two time-ordered point clouds in Euclidean space, using cython on the backend. Then, trace back through the matrix of backpointers to extract an alignment path
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
Y (ndarray(N, d)) – A d-dimensional Euclidean point cloud with N points
debug (boolean) – Whether to keep track of debugging information
- Returns
If not debugging – (float: cost, ndarray(K, 2): The warping path)
If debugging
{ –
- ‘cost’: float
The optimal cost of the alignment (if computation didn’t stop prematurely),
- ’U’/’L’/’UL’: ndarray(M, N)
The choice matrices (if debugging),
- ’S’: ndarray(M, N)
The accumulated cost matrix (if debugging)
- ’path’: ndarray(K, 2)
The warping path
}
- linmdtw.dtw.dtw_diag(X, Y, k_save=- 1, k_stop=- 1, box=None, reverse=False, debug=False, metadata=None)[source]¶
A CPU version of linear memory diagonal DTW
- Parameters
X (ndarray(M, d)) – An M-dimensional Euclidean point cloud
Y (ndarray(N, d)) – An N-dimensional Euclidean point cloud
k_save (int) – Index of the diagonal d2 at which to save d0, d1, and d2
k_stop (int) – Index of the diagonal d2 at which to stop computation
box (list) – A list of [startx, endx, starty, endy]
reverse (boolean) – Whether we’re going in reverse
debug (boolean) – Whether to save the accumulated cost matrix
metadata (dictionary) – A dictionary for storing information about the computation
- Returns
{ –
- ‘cost’: float
The optimal cost of the alignment (if computation didn’t stop prematurely),
- ’U’/’L’/’UL’: ndarray(M, N)
The choice matrices (if debugging),
- ’d0’/’d1’/’d2’:ndarray(min(M, N))
The saved rows if a save index was chosen,
- ’csm0’/’csm1’/’csm2’:ndarray(min(M, N))
The saved cross-similarity distances if a save index was chosen
}
- linmdtw.dtw.linmdtw(X, Y, box=None, min_dim=500, do_gpu=True, metadata=None)[source]¶
Linear memory exact, parallelizable DTW
- Parameters
X (ndarray(N1, d)) – An N1-dimensional Euclidean point cloud
Y (ndarray(N2, d)) – An N2-dimensional Euclidean point cloud
min_dim (int) – If one of the dimensions of the rectangular region to the left or to the right is less than this number, then switch to brute force CPU
do_gpu (boolean) – If true, use the GPU diagonal DTW function as a subroutine. Otherwise, use the CPU version. Both are linear memory, but the GPU will go faster for larger synchronization problems
metadata (dictionary) – A dictionary for storing information about the computation
- Returns
(float (cost, ndarray(K, 2): The optimal warping path))
linmdtw.dtwapprox module¶
- linmdtw.dtwapprox.cdtw(X, Y, radius, debug=False, do_plot=False)[source]¶
Dynamic time warping with constraints, as per the Sakoe-Chiba band
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
Y (ndarray(N, d)) – A d-dimensional Euclidean point cloud with N points
radius (int) – How far away a warping path is allowed to stray from the identity map in either direction
debug (boolean) – Whether to keep track of debugging information
do_plot (boolean) – Whether to plot the warping path at each level and save to image files
- Returns
(float (cost, ndarray(K, 2): The warping path))
- linmdtw.dtwapprox.fastdtw(X, Y, radius, debug=False, level=0, do_plot=False)[source]¶
An implementation of [1] [1] FastDTW: Toward Accurate Dynamic Time Warping in Linear Time and Space. Stan Salvador and Philip Chan
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
Y (ndarray(N, d)) – A d-dimensional Euclidean point cloud with N points
radius (int) – Radius of the l-infinity box that determines sparsity structure at each level
debug (boolean) – Whether to keep track of debugging information
level (int) – An int for keeping track of the level of recursion
do_plot (boolean) – Whether to plot the warping path at each level and save to image files
- Returns
(float (cost, ndarray(K, 2): The warping path))
- linmdtw.dtwapprox.fill_block(A, p, radius, val)[source]¶
Fill a square block with values
- Parameters
A (ndarray(M, N) or sparse(M, N)) – The array to fill
p (list of [i, j]) – The coordinates of the center of the box
radius (int) – Half the width of the box
val (float) – Value to fill in
- linmdtw.dtwapprox.get_box_area(a1, a2)[source]¶
Get the area of a box specified by two anchors
- Parameters
a1 (list(2)) – Row/column of first anchor
a2 (list(2)) – Row/column of second anchor
- Returns
Area of box determined by these two anchors
- linmdtw.dtwapprox.mrmsdtw(X, Y, tau, debug=False, refine=True)[source]¶
An implementation of the approximate, memory-restricted multiscale DTW technique from [2] [2] “Memory-Restricted Multiscale Dynamic Time Warping” Thomas Praetzlich, Jonathan Driedger and Meinard Mueller
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
Y (ndarray(N, d)) – A d-dimensional Euclidean point cloud with N points
tau (int) – The max amount of cells to be in memory at any given time
debug (boolean) – Whether to keep track of debugging information
refine (boolean) – Whether to do refinement with the “white anchors”
- Returns
path (ndarray(K, 2)) – The warping path
linmdtw.alignmenttools module¶
- linmdtw.alignmenttools.get_alignment_area_dist(P1, P2, do_plot=False)[source]¶
Compute area-based alignment error between two warping paths.
- Parameters
ndarray(M (P1) – First warping path
2) (P2) – First warping path
ndarray(N (P2) – Second warping path
2) – Second warping path
do_plot (boolean) – Whether to draw a plot showing the enclosed area
- Returns
score (float) – The area score
- linmdtw.alignmenttools.get_alignment_row_col_dists(P1, P2)[source]¶
A measurement of errors between two warping paths. For each point in the first path, record the distance of the closest point in the same row on the second path, and vice versa. Then repeat this along the columns
- Parameters
P1 (ndarray(M, 2)) – Ground truth warping path
P2 (ndarray(N, 2)) – Test warping path
- Returns
dists (ndarray(2M+2N)) – The errors
- linmdtw.alignmenttools.get_alignment_row_dists(P1, P2)[source]¶
A measurement of errors between two warping paths. For each point in the first path, record the distance of the closest point in the same row on the second path
- Parameters
P1 (ndarray(M, 2)) – Ground truth warping path
P2 (ndarray(N, 2)) – Test warping path
- Returns
dists (ndarray(M)) – The errors at each point on the first warping path
- linmdtw.alignmenttools.get_csm(X, Y)[source]¶
Return the Euclidean cross-similarity matrix between X and Y
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
Y (ndarray(N, d)) – A d-dimensional Euclidean point cloud with N points
- Returns
D (ndarray(M, N)) – The cross-similarity matrix
- linmdtw.alignmenttools.get_diag_indices(MTotal, NTotal, k, box=None, reverse=False)[source]¶
Compute the indices on a diagonal into indices on an accumulated distance matrix
- Parameters
MTotal (int) – Total number of samples in X
NTotal (int) – Total number of samples in Y
k (int) – Index of the diagonal
box (list [XStart, XEnd, YStart, YEnd]) – The coordinates of the box in which to search
- Returns
i (ndarray(dim)) – Row indices
j (ndarray(dim)) – Column indices
- linmdtw.alignmenttools.get_diag_len(box, k)[source]¶
Return the number of elements in this particular diagonal
- Parameters
MTotal (int) – Total number of samples in X
NTotal (int) – Total number of samples in Y
k (int) – Index of the diagonal
- Returns
Number of elements
- linmdtw.alignmenttools.get_interpolated_euclidean_timeseries(X, t, kind='linear')[source]¶
Resample a time series in Euclidean space using interp2d
- Parameters
X (ndarray(M, d)) – The Euclidean time series with n points
t (ndarray(N)) – A re-parameterization function on the unit interval [0, 1]
kind (string) – The kind of interpolation to do
- Returns
Y (ndarray(N, d)) – The interpolated time series
- linmdtw.alignmenttools.get_inverse_fn_equally_sampled(t, x)[source]¶
Compute the inverse of a 1D function and equally sample it.
- Parameters
t (ndarray(N)) – The domain samples of the original function
x (ndarray(N)) – The range samples of the original function
- Returns
y (ndarray(N)) – The inverse function samples
- linmdtw.alignmenttools.get_parameterization_dict(N, do_plot=False)[source]¶
Construct a dictionary of different types of parameterizations on the unit interval
- Parameters
N (int) – Number of samples on the unit interval
do_plot (boolean) – Whether to plot all of the parameterizations
- Returns
D (ndarray(N, K)) – The dictionary of parameterizations, with each warping path down a different column
- linmdtw.alignmenttools.get_path_cost(X, Y, path)[source]¶
Return the cost of a warping path that matches two Euclidean point clouds
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
Y (ndarray(N, d)) – A d-dimensional Euclidean point cloud with N points
P1 (ndarray(K, 2)) – Warping path
- Returns
cost (float) – The sum of the Euclidean distances along the warping path between X and Y
- linmdtw.alignmenttools.get_ssm(X)[source]¶
Return the SSM between all rows of a time-ordered Euclidean point cloud X
- Parameters
X (ndarray(M, d)) – A d-dimensional Euclidean point cloud with M points
- Returns
D (ndarray(M, M)) – The self-similarity matrix
- linmdtw.alignmenttools.make_path_strictly_increase(path)[source]¶
Given a warping path, remove all rows that do not strictly increase from the row before
- linmdtw.alignmenttools.param_to_warppath(t, M)[source]¶
Convert a parameterization function into a valid warping path
- Parameters
t (ndarray(N)) – Samples along the parameterization function on the unit interval
M (int) – The number of samples in the original time series
- Returns
P (ndarray(K, 2)) – A warping path that best matches the parameterization
- linmdtw.alignmenttools.refine_warping_path(path)[source]¶
An implementation of the technique in section 4 of “Refinement Strategies for Music Synchronization” by Ewert and Müller
- Parameters
path (ndarray(K, 2)) – A warping path
- Returns
path_refined (ndarray(N >= K, 2)) – A refined set of correspondences
- linmdtw.alignmenttools.sample_parameterization_dict(D, k, do_plot=False)[source]¶
Return a warping path made up of k random elements drawn from dictionary D
- Parameters
D (ndarray(N, K)) – The dictionary of warping paths, with each warping path down a different column
k (int) – The number of warping paths to take in a combination
- linmdtw.alignmenttools.update_alignment_metadata(metadata=None, newcells=0)[source]¶
Add new amount of cells to the total cells processed, and print out a percentage point if there’s been progress
- Parameters
newcells (int) – The number of new cells that are being processed
metadata (dictionary) – Dictionary with ‘M’, ‘N’, ‘totalCells’, all ints and ‘timeStart’
linmdtw.audiotools module¶
- linmdtw.audiotools.get_DLNC0(x, sr, hop_length, lag=10, do_plot=False)[source]¶
Compute decaying locally adaptive normalize C0 (DLNC0) features
- Parameters
x (ndarray(N)) – Audio samples
sr (int) – Sample rate
hop_length (int) – Hop size between windows
lag (int) – Number of lags to include
- Returns
X (ndarray(n_win, 12)) – The DLNC0 features
- linmdtw.audiotools.get_mfcc_mod(x, sr, hop_length, n_mfcc=120, drop=20, n_fft=2048)[source]¶
Compute the mfcc_mod features, as described in Gadermaier 2019
- Parameters
x (ndarray(N)) – Audio samples
sr (int) – Sample rate
hop_length (int) – Hop size between windows
n_mfcc (int) – Number of mfcc coefficients to compute
drop (int) – Index under which to ignore coefficients
n_fft (int) – Number of fft points to use in each window
- Returns
X (ndarray(n_win, n_mfcc-drop)) – The mfcc-mod features
- linmdtw.audiotools.get_mixed_DLNC0_CENS(x, sr, hop_length, lam=0.1)[source]¶
Concatenate DLNC0 to CENS
- Parameters
x (ndarray(N)) – Audio samples
sr (int) – Sample rate
hop_length (int) – Hop size between windows
lam (float) – The coefficient in front of the CENS features
- Returns
X (ndarray(n_win, 24)) – DLNC0 features along the first 12 columns, weighted CENS along the next 12 columns
- linmdtw.audiotools.load_audio(filename, sr=44100)[source]¶
Load an audio waveform from a file. Try to use ffmpeg to convert it to a .wav file so scipy’s fast wavfile loader can work. Otherwise, fall back to the slower librosa
- Parameters
filename (string) – Path to audio file to load
sr (int) – Sample rate to use
- Returns
y (ndarray(N)) – Audio samples
sr (int) – The sample rate that was actually used
- linmdtw.audiotools.save_audio(x, sr, outprefix)[source]¶
Save audio to a file
- Parameters
x (ndarray(N, 2)) – Stereo audio to save
sr (int) – Sample rate of audio to save
outprefix (string) – Use this as the prefix of the file to which to save audio
- linmdtw.audiotools.stretch_audio(x1, x2, sr, path, hop_length, refine=True)[source]¶
Wrap around pyrubberband to warp one audio stream to another, according to some warping path
- Parameters
x1 (ndarray(M)) – First audio stream
x2 (ndarray(N)) – Second audio stream
sr (int) – Sample rate
path (ndarray(P, 2)) – Warping path, in units of windows
hop_length (int) – The hop length between windows
refine (boolean) – Whether to refine the warping path before alignment
- Returns
x3 (ndarray(N, 2)) – The synchronized audio. x2 is in the right channel, and x1 stretched to x2 is in the left channel