1
2 /* ----------------------------------------------------------------------
3 * Project: CMSIS DSP Library
4 * Title: arm_braycurtis_distance_f16.c
5 * Description: Bray-Curtis distance between two vectors
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-2021 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_f16.h"
31
32 #if defined(ARM_FLOAT16_SUPPORTED)
33
34 #include <limits.h>
35 #include <math.h>
36
37 /**
38 * @ingroup groupDistance
39 */
40
41 /**
42 * @defgroup FloatDist Float Distances
43 *
44 * Distances between two vectors of float values.
45 */
46
47 /**
48 @ingroup FloatDist
49 */
50
51 /**
52 @defgroup braycurtis Bray-Curtis distance
53
54 Bray-Curtis distance between two vectors
55 */
56
57 /**
58 @addtogroup braycurtis
59 @{
60 */
61
62
63 /**
64 * @brief Bray-Curtis distance between two vectors
65 * @param[in] pA First vector
66 * @param[in] pB Second vector
67 * @param[in] blockSize vector length
68 * @return distance
69 *
70 */
71 #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
72
73 #include "arm_helium_utils.h"
74
arm_braycurtis_distance_f16(const float16_t * pA,const float16_t * pB,uint32_t blockSize)75 float16_t arm_braycurtis_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
76 {
77 _Float16 accumDiff = 0.0f, accumSum = 0.0f;
78 uint32_t blkCnt;
79 f16x8_t a, b, c, accumDiffV, accumSumV;
80
81
82 accumDiffV = vdupq_n_f16(0.0f);
83 accumSumV = vdupq_n_f16(0.0f);
84
85 blkCnt = blockSize >> 3;
86 while (blkCnt > 0) {
87 a = vld1q(pA);
88 b = vld1q(pB);
89
90 c = vabdq(a, b);
91 accumDiffV = vaddq(accumDiffV, c);
92
93 c = vaddq_f16(a, b);
94 c = vabsq_f16(c);
95 accumSumV = vaddq(accumSumV, c);
96
97 pA += 8;
98 pB += 8;
99 blkCnt--;
100 }
101
102 blkCnt = blockSize & 7;
103 if (blkCnt > 0U) {
104 mve_pred16_t p0 = vctp16q(blkCnt);
105
106 a = vldrhq_z_f16(pA, p0);
107 b = vldrhq_z_f16(pB, p0);
108
109 c = vabdq(a, b);
110 accumDiffV = vaddq_m(accumDiffV, accumDiffV, c, p0);
111
112 c = vaddq_f16(a, b);
113 c = vabsq_f16(c);
114 accumSumV = vaddq_m(accumSumV, accumSumV, c, p0);
115 }
116
117 accumDiff = vecAddAcrossF16Mve(accumDiffV);
118 accumSum = vecAddAcrossF16Mve(accumSumV);
119
120 /*
121 It is assumed that accumSum is not zero. Since it is the sum of several absolute
122 values it would imply that all of them are zero. It is very unlikely for long vectors.
123 */
124 return (accumDiff / accumSum);
125 }
126 #else
127
arm_braycurtis_distance_f16(const float16_t * pA,const float16_t * pB,uint32_t blockSize)128 float16_t arm_braycurtis_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
129 {
130 _Float16 accumDiff=0.0f16, accumSum=0.0f16, tmpA, tmpB;
131
132 while(blockSize > 0)
133 {
134 tmpA = *pA++;
135 tmpB = *pB++;
136 accumDiff += (_Float16)fabsf(tmpA - tmpB);
137 accumSum += (_Float16)fabsf(tmpA + tmpB);
138 blockSize --;
139 }
140 /*
141
142 It is assumed that accumSum is not zero. Since it is the sum of several absolute
143 values it would imply that all of them are zero. It is very unlikely for long vectors.
144
145 */
146 return(accumDiff / accumSum);
147 }
148 #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
149
150
151 /**
152 * @} end of braycurtis group
153 */
154
155
156
157 #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
158
159