-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdpcore.c
140 lines (122 loc) · 3.52 KB
/
dpcore.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* dpcore.c
* Core of dynamic programming/DTW calculation
* 2003-04-02 dpwe@ee.columbia.edu
* $Header: /Users/dpwe/projects/dtw/RCS/dpcore.c,v 1.5 2014/06/20 21:08:53 dpwe Exp dpwe $
% Copyright (c) 2003-05 Dan Ellis <dpwe@ee.columbia.edu>
% released under GPL - see file COPYRIGHT
*/
#include <stdio.h>
#include <float.h> /* per Vigi Katlowitz for windows 2014-06-20 */
#include <math.h>
#include <ctype.h>
/* these two lines are to make it compile on Xcode 5.1 2014-06-20 */
#include <stdint.h>
typedef uint16_t char16_t;
#include "mex.h"
/* #define DEBUG */
/* #define INF HUGE_VAL */
#define INF DBL_MAX
void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int i,j;
long pvl, pvb[16];
#ifdef DEBUG
mexPrintf("dpcore: Got %d lhs args and %d rhs args.\n",
nlhs, nrhs);
for (i=0;i<nrhs;i++) {
mexPrintf("RHArg #%d is size %d x %d\n",
(long)i, mxGetM(prhs[i]), mxGetN(prhs[i]));
}
for (i=0;i<nlhs;i++)
if (plhs[i]) {
mexPrintf("LHArg #%d is size %d x %d\n",
(long)i, mxGetM(plhs[i]), mxGetN(plhs[i]));
}
#endif /* DEBUG */
if (nrhs < 1){
mexPrintf("dpcore [D,P] = dpcore(S[,C]) dynamic programming core\n");
mexPrintf(" Calculate the best cost to every point in score\n");
mexPrintf(" cost matrix S; return it in D along with traceback\n");
mexPrintf(" indices in P. Optional C defines allowable steps\n");
mexPrintf(" and costs; default [1 1 1.0;1 0 1.0;0 1 1.0]\n");
return;
}
if (nlhs > 0){
mxArray *DMatrix, *PMatrix;
int rows, cols, i, j, k, tb;
double *pM, *pD, *pP, *pC;
double d1, d2, d3, v;
double *costs;
int *steps;
int ncosts;
rows = mxGetM(prhs[0]);
cols = mxGetN(prhs[0]);
pM = mxGetPr(prhs[0]);
DMatrix = mxCreateDoubleMatrix(rows, cols, mxREAL);
pD = mxGetPr(DMatrix);
PMatrix = mxCreateDoubleMatrix(rows, cols, mxREAL);
pP = mxGetPr(PMatrix);
plhs[0] = DMatrix;
if (nlhs > 1) {
plhs[1] = PMatrix;
}
/* setup costs */
if (nrhs == 1) {
/* default C matrix */
int ii;
ncosts = 3;
costs = (double *)malloc(ncosts*sizeof(double));
for (ii = 0; ii<ncosts; ++ii) costs[ii] = 1.0;
steps = (int *)malloc(ncosts*2*sizeof(int));
steps[0] = 1; steps[1] = 1;
steps[2] = 1; steps[3] = 0;
steps[4] = 0; steps[5] = 1;
} else {
int ii, crows, ccols;
crows = mxGetM(prhs[1]);
ccols = mxGetN(prhs[1]);
pC = mxGetPr(prhs[1]);
/* mexPrintf("C has %d rows and %d cols\n", crows, ccols); */
if (ccols != 3) {
mexPrintf("Cost matrix must have 3 cols (i step, j step, cost factor)\n");
return;
}
ncosts = crows;
costs = (double *)malloc(ncosts*sizeof(double));
steps = (int *)malloc(ncosts*2*sizeof(int));
for (ii = 0; ii < ncosts; ++ii) {
steps[2*ii] = (int)(pC[ii]);
steps[2*ii+1] = (int)(pC[ii+crows]);
costs[ii] = pC[ii+2*crows];
/* mexPrintf("step=%d,%d cost=%f\n", steps[2*ii],steps[2*ii+1],costs[ii]); */
}
}
/* do dp */
v = 0;
tb = 1; /* value to use for 0,0 */
for (j = 0; j < cols; ++j) {
for (i = 0; i < rows; ++i) {
d1 = pM[i + j*rows];
for (k = 0; k < ncosts; ++k) {
if ( i >= steps[2*k] && j >= steps[2*k+1] ) {
d2 = costs[k]*d1 + pD[(i-steps[2*k]) + (j-steps[2*k+1])*rows];
if (d2 < v) {
v = d2;
tb = k+1;
}
}
}
pD[i + j*rows] = v;
pP[i + j*rows] = (double)tb;
v = INF;
}
}
free((void *)costs);
free((void *)steps);
}
#ifdef DEBUG
mexPrintf("dpcore: returning...\n");
#endif /* DEBUG */
}