arm_entropy_f32.c
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 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 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 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 */