• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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