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