pythoncdtw

Dynamic time warping in C


So I can find alot of guides on DTW for python, and they work as they should. But I need the code translatet into C, but it's over a year since I've written C code.

So in C code I have these two arrays

static int codeLock[6][2] = {
{1, 0},
{2, 671},
{3, 1400},
{4, 2000},
{5, 2800},
        };;

static int code[6][2] = {
{1, 0},
{2, 600},
{3, 1360},
{4, 1990},
{5, 2800},
        };;

And I'm gonna use DTW to compare the right side of the array codeLock(n)(1) / code(m)(1), so 1..5 should not be looked at.

But yeah..

In python I have two functions one for euclidean distance which is:

def compute_euclidean_distance_matrix(x, y) -> np.array:
    """Calculate distance matrix
    This method calcualtes the pairwise Euclidean distance between two sequences.
    The sequences can have different lengths.
    """
    dist = np.zeros((len(y), len(x)))
    for i in range(len(y)):
        for j in range(len(x)):
            dist[i,j] = (x[j]-y[i])**2
    return dist

and the other for accumulated cost:

def compute_accumulated_cost_matrix(x, y) -> np.array:
    """Compute accumulated cost matrix for warp path using Euclidean distance
    """
    distances = compute_euclidean_distance_matrix(x, y)
    # Initialization
    cost = np.zeros((len(y), len(x)))
    cost[0,0] = distances[0,0]

    for i in range(1, len(y)):
        cost[i, 0] = distances[i, 0] + cost[i-1, 0]  
        
    for j in range(1, len(x)):
        cost[0, j] = distances[0, j] + cost[0, j-1]  

    # Accumulated warp path cost
    for i in range(1, len(y)):
        for j in range(1, len(x)):
            cost[i, j] = min(
                cost[i-1, j],    # insertion
                cost[i, j-1],    # deletion
                cost[i-1, j-1]   # match
            ) + distances[i, j] 
            
    return cost

This code is from a guide I followed to get an understanding on how DTW worked, but it's in python and i need it in C.

This can easily be testet in python like this:

x = [0, 671, 1400, 2000, 2800]
y = [0, 600, 1360, 1990, 2800]

compute_euclidean       = compute_euclidean_distance_matrix(x, y)
compute_accumulated     = compute_accumulated_cost_matrix(x, y)


print("\ncompute_euclidean_distance_matrix")
print(compute_euclidean)
print("\ncompute_accumulated_cost_matrix")
print(compute_accumulated)
print("\nflipud")
print(np.flipud(compute_accumulated))

and this is my output

Console output

I've also looked into fastdtw, and my test then looked like this

x = [0, 671, 1400, 2000, 2800]
y = [0, 600, 1360, 1990, 2800]

dtw_distance, warp_path = fastdtw(x, y, dist=euclidean)

print("\ndtw_distance")
print(dtw_distance)

This is my output

Console output

Do any of you know where there might be a GitHub/guide on how to do all this in C? Because that would help me a lot. I would of course appreciate if you are willing to help me translate this code.


Solution

  • A C implementation of dynamic time warping is in https://github.com/wannesm/dtaidistance/tree/master/dtaidistance/lib/DTAIDistanceC/DTAIDistanceC

    You can always translate python to C using Cython https://people.duke.edu/~ccc14/sta-663/FromPythonToC.html however the generated code sometimes does not work, complete rewriting is better