1
2 /* ----------------------------------------------------------------------
3 * Project: CMSIS DSP Library
4 * Title: arm_dtw_path_f32.c
5 * Description: Warping path
6 *
7 * $Date: 23 April 2021
8 * $Revision: V1.9.0
9 *
10 * Target Processor: Cortex-M and Cortex-A cores
11 * -------------------------------------------------------------------- */
12 /*
13 * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
14 *
15 * SPDX-License-Identifier: Apache-2.0
16 *
17 * Licensed under the Apache License, Version 2.0 (the License); you may
18 * not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 * www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
25 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 */
29
30 #include "dsp/distance_functions.h"
31 #include <limits.h>
32 #include <math.h>
33
34 #define E(MAT,R,C) \
35 (*((MAT)->pData + (MAT)->numCols*(R) + (C)))
36
37
38
39 /**
40 @addtogroup DTW
41 @{
42 */
43
44
45 /**
46 * @brief Mapping between query and template
47 * @param[in] pDTW Cost matrix (Query rows * Template columns)
48 * @param[out] pPath Warping path in cost matrix 2*(nb rows + nb columns)
49 * @param[out] pathLength Length of path in number of points
50 *
51 * @par Warping path
52 *
53 * The warping path has length which is at most
54 * 2*(query length + template length) in float.
55 * 2 because it is a list of coordinates :
56 * (query index, template index) coordinate.
57 *
58 * The buffer pPath must be big enough to contain
59 * the warping path.
60 *
61 * pathLength is the number of points in
62 * the returned path. The resturned path
63 * may be smaller than query + template.
64 *
65 */
arm_dtw_path_f32(const arm_matrix_instance_f32 * pDTW,int16_t * pPath,uint32_t * pathLength)66 ARM_DSP_ATTRIBUTE void arm_dtw_path_f32(const arm_matrix_instance_f32 *pDTW,
67 int16_t *pPath,
68 uint32_t *pathLength)
69 {
70 int q,t;
71 float32_t temp;
72
73 *pathLength = 0;
74 q=pDTW->numRows-1;
75 t=pDTW->numCols-1;
76 while((q>0) || (t>0))
77 {
78 int p=-1;
79 float32_t current=F32_MAX;
80
81 if (q>0)
82 {
83 temp = E(pDTW,q-1,t);
84 if (temp<current)
85 {
86 current=temp;
87 p=2;
88 }
89 }
90
91 if (t>0)
92 {
93 temp = E(pDTW,q,t-1);
94 if (temp<current)
95 {
96 current=temp;
97 p=0;
98 }
99 }
100
101 if ((q>0) && (t>0))
102 {
103 temp = E(pDTW,q-1,t-1);
104 if (temp<current)
105 {
106 current=temp;
107 p=1;
108 }
109 }
110
111
112
113
114
115
116
117 pPath[2 * (*pathLength)] = q;
118 pPath[2 * (*pathLength) + 1] = t;
119
120 *pathLength = *pathLength + 1;
121
122 switch(p)
123 {
124 case 0:
125 t = t-1;
126 break;
127 case 1:
128 t=t-1;
129 q=q-1;
130 break;
131 case 2:
132 q=q-1;
133 break;
134 }
135
136 }
137
138 pPath[2 * (*pathLength)] = 0;
139 pPath[2 * (*pathLength) + 1] = 0;
140 *pathLength = *pathLength + 1;
141
142 /* Reverse the path */
143 int16_t *fh,*sh;
144 int16_t itemp;
145 fh = pPath;
146 sh = pPath + 2* (*pathLength)-2;
147 int halfLength = (*pathLength)>>1;
148 for(int i = 0; i< halfLength; i++)
149 {
150 itemp = fh[0];
151 fh[0] = sh[0];
152 sh[0] = itemp;
153
154 itemp = fh[1];
155 fh[1] = sh[1];
156 sh[1] = itemp;
157
158 fh += 2;
159 sh -= 2;
160 }
161 }
162
163 /**
164 * @} end of DTW group
165 */
166
167