1 /******************************************************************************
2  * @file     distance_functions.h
3  * @brief    Public header file for CMSIS DSP Library
4  * @version  V1.10.0
5  * @date     08 July 2021
6  * Target Processor: Cortex-M and Cortex-A cores
7  ******************************************************************************/
8 /*
9  * Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
10  *
11  * SPDX-License-Identifier: Apache-2.0
12  *
13  * Licensed under the Apache License, Version 2.0 (the License); you may
14  * not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
21  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  */
25 
26 
27 #ifndef _DISTANCE_FUNCTIONS_H_
28 #define _DISTANCE_FUNCTIONS_H_
29 
30 #include "arm_math_types.h"
31 #include "arm_math_memory.h"
32 
33 #include "dsp/none.h"
34 #include "dsp/utils.h"
35 
36 #include "dsp/statistics_functions.h"
37 #include "dsp/basic_math_functions.h"
38 #include "dsp/fast_math_functions.h"
39 #include "dsp/matrix_functions.h"
40 
41 #ifdef   __cplusplus
42 extern "C"
43 {
44 #endif
45 
46 
47 /**
48  * @defgroup groupDistance Distance Functions
49  *
50  * Distance functions for use with clustering algorithms.
51  * There are distance functions for float vectors and boolean vectors.
52  *
53  */
54 
55 /* 6.14 bug */
56 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) && (__ARMCC_VERSION < 6150001)
57 
58 __attribute__((weak)) float __powisf2(float a, int b);
59 
60 #endif
61 
62 /**
63  * @brief        Euclidean distance between two vectors
64  * @param[in]    pA         First vector
65  * @param[in]    pB         Second vector
66  * @param[in]    blockSize  vector length
67  * @return distance
68  *
69  */
70 
71 float32_t arm_euclidean_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
72 
73 /**
74  * @brief        Euclidean distance between two vectors
75  * @param[in]    pA         First vector
76  * @param[in]    pB         Second vector
77  * @param[in]    blockSize  vector length
78  * @return distance
79  *
80  */
81 
82 float64_t arm_euclidean_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
83 
84 /**
85  * @brief        Bray-Curtis distance between two vectors
86  * @param[in]    pA         First vector
87  * @param[in]    pB         Second vector
88  * @param[in]    blockSize  vector length
89  * @return distance
90  *
91  */
92 float32_t arm_braycurtis_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
93 
94 /**
95  * @brief        Canberra distance between two vectors
96  *
97  * This function may divide by zero when samples pA[i] and pB[i] are both zero.
98  * The result of the computation will be correct. So the division per zero may be
99  * ignored.
100  *
101  * @param[in]    pA         First vector
102  * @param[in]    pB         Second vector
103  * @param[in]    blockSize  vector length
104  * @return distance
105  *
106  */
107 float32_t arm_canberra_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
108 
109 
110 /**
111  * @brief        Chebyshev distance between two vectors
112  * @param[in]    pA         First vector
113  * @param[in]    pB         Second vector
114  * @param[in]    blockSize  vector length
115  * @return distance
116  *
117  */
118 float32_t arm_chebyshev_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
119 
120 
121 /**
122  * @brief        Chebyshev distance between two vectors
123  * @param[in]    pA         First vector
124  * @param[in]    pB         Second vector
125  * @param[in]    blockSize  vector length
126  * @return distance
127  *
128  */
129 float64_t arm_chebyshev_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
130 
131 
132 /**
133  * @brief        Cityblock (Manhattan) distance between two vectors
134  * @param[in]    pA         First vector
135  * @param[in]    pB         Second vector
136  * @param[in]    blockSize  vector length
137  * @return distance
138  *
139  */
140 float32_t arm_cityblock_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
141 
142 /**
143  * @brief        Cityblock (Manhattan) distance between two vectors
144  * @param[in]    pA         First vector
145  * @param[in]    pB         Second vector
146  * @param[in]    blockSize  vector length
147  * @return distance
148  *
149  */
150 float64_t arm_cityblock_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
151 
152 /**
153  * @brief        Correlation distance between two vectors
154  *
155  * The input vectors are modified in place !
156  *
157  * @param[in]    pA         First vector
158  * @param[in]    pB         Second vector
159  * @param[in]    blockSize  vector length
160  * @return distance
161  *
162  */
163 float32_t arm_correlation_distance_f32(float32_t *pA,float32_t *pB, uint32_t blockSize);
164 
165 /**
166  * @brief        Cosine distance between two vectors
167  *
168  * @param[in]    pA         First vector
169  * @param[in]    pB         Second vector
170  * @param[in]    blockSize  vector length
171  * @return distance
172  *
173  */
174 
175 float32_t arm_cosine_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize);
176 
177 /**
178  * @brief        Cosine distance between two vectors
179  *
180  * @param[in]    pA         First vector
181  * @param[in]    pB         Second vector
182  * @param[in]    blockSize  vector length
183  * @return distance
184  *
185  */
186 
187 float64_t arm_cosine_distance_f64(const float64_t *pA,const float64_t *pB, uint32_t blockSize);
188 
189 /**
190  * @brief        Jensen-Shannon distance between two vectors
191  *
192  * This function is assuming that elements of second vector are > 0
193  * and 0 only when the corresponding element of first vector is 0.
194  * Otherwise the result of the computation does not make sense
195  * and for speed reasons, the cases returning NaN or Infinity are not
196  * managed.
197  *
198  * When the function is computing x log (x / y) with x 0 and y 0,
199  * it will compute the right value (0) but a division per zero will occur
200  * and shoudl be ignored in client code.
201  *
202  * @param[in]    pA         First vector
203  * @param[in]    pB         Second vector
204  * @param[in]    blockSize  vector length
205  * @return distance
206  *
207  */
208 
209 float32_t arm_jensenshannon_distance_f32(const float32_t *pA,const float32_t *pB,uint32_t blockSize);
210 
211 /**
212  * @brief        Minkowski distance between two vectors
213  *
214  * @param[in]    pA         First vector
215  * @param[in]    pB         Second vector
216  * @param[in]    n          Norm order (>= 2)
217  * @param[in]    blockSize  vector length
218  * @return distance
219  *
220  */
221 
222 
223 
224 float32_t arm_minkowski_distance_f32(const float32_t *pA,const float32_t *pB, int32_t order, uint32_t blockSize);
225 
226 /**
227  * @brief        Dice distance between two vectors
228  *
229  * @param[in]    pA              First vector of packed booleans
230  * @param[in]    pB              Second vector of packed booleans
231  * @param[in]    order           Distance order
232  * @param[in]    blockSize       Number of samples
233  * @return distance
234  *
235  */
236 
237 
238 float32_t arm_dice_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
239 
240 /**
241  * @brief        Hamming distance between two vectors
242  *
243  * @param[in]    pA              First vector of packed booleans
244  * @param[in]    pB              Second vector of packed booleans
245  * @param[in]    numberOfBools   Number of booleans
246  * @return distance
247  *
248  */
249 
250 float32_t arm_hamming_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
251 
252 /**
253  * @brief        Jaccard distance between two vectors
254  *
255  * @param[in]    pA              First vector of packed booleans
256  * @param[in]    pB              Second vector of packed booleans
257  * @param[in]    numberOfBools   Number of booleans
258  * @return distance
259  *
260  */
261 
262 float32_t arm_jaccard_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
263 
264 /**
265  * @brief        Kulsinski distance between two vectors
266  *
267  * @param[in]    pA              First vector of packed booleans
268  * @param[in]    pB              Second vector of packed booleans
269  * @param[in]    numberOfBools   Number of booleans
270  * @return distance
271  *
272  */
273 
274 float32_t arm_kulsinski_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
275 
276 /**
277  * @brief        Roger Stanimoto distance between two vectors
278  *
279  * @param[in]    pA              First vector of packed booleans
280  * @param[in]    pB              Second vector of packed booleans
281  * @param[in]    numberOfBools   Number of booleans
282  * @return distance
283  *
284  */
285 
286 float32_t arm_rogerstanimoto_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
287 
288 /**
289  * @brief        Russell-Rao distance between two vectors
290  *
291  * @param[in]    pA              First vector of packed booleans
292  * @param[in]    pB              Second vector of packed booleans
293  * @param[in]    numberOfBools   Number of booleans
294  * @return distance
295  *
296  */
297 
298 float32_t arm_russellrao_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
299 
300 /**
301  * @brief        Sokal-Michener distance between two vectors
302  *
303  * @param[in]    pA              First vector of packed booleans
304  * @param[in]    pB              Second vector of packed booleans
305  * @param[in]    numberOfBools   Number of booleans
306  * @return distance
307  *
308  */
309 
310 float32_t arm_sokalmichener_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
311 
312 /**
313  * @brief        Sokal-Sneath distance between two vectors
314  *
315  * @param[in]    pA              First vector of packed booleans
316  * @param[in]    pB              Second vector of packed booleans
317  * @param[in]    numberOfBools   Number of booleans
318  * @return distance
319  *
320  */
321 
322 float32_t arm_sokalsneath_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
323 
324 /**
325  * @brief        Yule distance between two vectors
326  *
327  * @param[in]    pA              First vector of packed booleans
328  * @param[in]    pB              Second vector of packed booleans
329  * @param[in]    numberOfBools   Number of booleans
330  * @return distance
331  *
332  */
333 
334 float32_t arm_yule_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools);
335 
336 typedef enum
337   {
338     ARM_DTW_SAKOE_CHIBA_WINDOW = 1,
339     /*ARM_DTW_ITAKURA_WINDOW = 2,*/
340     ARM_DTW_SLANTED_BAND_WINDOW = 3
341   } arm_dtw_window;
342 
343 /**
344  * @brief        Window for dynamic time warping computation
345  * @param[in]    windowType  Type of window
346  * @param[in]    windowSize  Window size
347  * @param[in,out] pWindow Window
348  * @return Error if window type not recognized
349  *
350  */
351 arm_status arm_dtw_init_window_q7(const arm_dtw_window windowType,
352                                   const int32_t windowSize,
353                                   arm_matrix_instance_q7 *pWindow);
354 
355 /**
356  * @brief         Dynamic Time Warping distance
357  * @param[in]     pDistance  Distance matrix (Query rows * Template columns)
358  * @param[in]     pWindow  Windowing (can be NULL if no windowing used)
359  * @param[out]    pDTW Temporary cost buffer (same size)
360  * @param[out]    distance Distance
361  * @return Error in case no path can be found with window constraint
362  *
363  */
364 
365 arm_status arm_dtw_distance_f32(const arm_matrix_instance_f32 *pDistance,
366                                const arm_matrix_instance_q7 *pWindow,
367                                arm_matrix_instance_f32 *pDTW,
368                                float32_t *distance);
369 
370 
371 /**
372  * @brief        Mapping between query and template
373  * @param[in]    pDTW  Cost matrix (Query rows * Template columns)
374  * @param[out]   pPath Warping path in cost matrix 2*(nb rows + nb columns)
375  * @param[out]   pathLength Length of path in number of points
376  *
377  */
378 
379 void arm_dtw_path_f32(const arm_matrix_instance_f32 *pDTW,
380                       int16_t *pPath,
381                       uint32_t *pathLength);
382 #ifdef   __cplusplus
383 }
384 #endif
385 
386 #endif /* ifndef _DISTANCE_FUNCTIONS_H_ */
387