• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_logsumexp_f32.c
4  * Description:  LogSumExp
5  *
6  * $Date:        23 April 2021
7  * $Revision:    V1.9.0
8  *
9  * Target Processor: Cortex-M and Cortex-A cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
16  * Licensed under the Apache License, Version 2.0 (the License); you may
17  * not use this file except in compliance with the License.
18  * You may obtain a copy of the License at
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28 
29 #include "dsp/statistics_functions.h"
30 #include <limits.h>
31 #include <math.h>
32 
33 
34 /**
35  * @addtogroup Entropy
36  * @{
37  */
38 
39 
40 /**
41  * @brief Entropy
42  *
43  * @param[in]  pSrcA        Array of input values.
44  * @param[in]  blockSize    Number of samples in the input array.
45  * @return     Entropy      -Sum(p ln p)
46  *
47  */
48 
49 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
50 
51 #include "arm_helium_utils.h"
52 #include "arm_vec_math.h"
53 
arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize)54 float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize)
55 {
56     uint32_t        blkCnt;
57     float32_t       accum=0.0f,p;
58 
59 
60     blkCnt = blockSize;
61 
62     f32x4_t         vSum = vdupq_n_f32(0.0f);
63     /* Compute 4 outputs at a time */
64     blkCnt = blockSize >> 2U;
65 
66     while (blkCnt > 0U)
67     {
68         f32x4_t         vecIn = vld1q(pSrcA);
69 
70         vSum = vaddq_f32(vSum, vmulq(vecIn, vlogq_f32(vecIn)));
71 
72         /*
73          * Decrement the blockSize loop counter
74          * Advance vector source and destination pointers
75          */
76         pSrcA += 4;
77         blkCnt --;
78     }
79 
80     accum = vecAddAcrossF32Mve(vSum);
81 
82     /* Tail */
83     blkCnt = blockSize & 0x3;
84     while(blkCnt > 0)
85     {
86        p = *pSrcA++;
87        accum += p * logf(p);
88 
89        blkCnt--;
90 
91     }
92 
93     return (-accum);
94 }
95 
96 #else
97 #if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE)
98 
99 #include "NEMath.h"
100 
arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize)101 float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize)
102 {
103     const float32_t *pIn;
104     uint32_t blkCnt;
105     float32_t accum, p;
106 
107     float32x4_t accumV;
108     float32x2_t accumV2;
109     float32x4_t tmpV, tmpV2;
110 
111     pIn = pSrcA;
112 
113     accum = 0.0f;
114     accumV = vdupq_n_f32(0.0f);
115 
116     blkCnt = blockSize >> 2;
117     while(blkCnt > 0)
118     {
119       tmpV = vld1q_f32(pIn);
120       pIn += 4;
121 
122       tmpV2 = vlogq_f32(tmpV);
123       accumV = vmlaq_f32(accumV, tmpV, tmpV2);
124 
125       blkCnt--;
126 
127     }
128 
129     accumV2 = vpadd_f32(vget_low_f32(accumV),vget_high_f32(accumV));
130     accum = vget_lane_f32(accumV2, 0) + vget_lane_f32(accumV2, 1);
131 
132 
133     blkCnt = blockSize & 3;
134     while(blkCnt > 0)
135     {
136        p = *pIn++;
137        accum += p * logf(p);
138 
139        blkCnt--;
140 
141     }
142 
143     return(-accum);
144 }
145 
146 #else
arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize)147 float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize)
148 {
149     const float32_t *pIn;
150     uint32_t blkCnt;
151     float32_t accum, p;
152 
153     pIn = pSrcA;
154     blkCnt = blockSize;
155 
156     accum = 0.0f;
157 
158     while(blkCnt > 0)
159     {
160        p = *pIn++;
161        accum += p * logf(p);
162 
163        blkCnt--;
164 
165     }
166 
167     return(-accum);
168 }
169 #endif
170 #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
171 
172 /**
173  * @} end of Entropy group
174  */
175