• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        arm_naive_gaussian_bayes_predict_f16
4  * Description:  Naive Gaussian Bayesian Estimator
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/bayes_functions_f16.h"
30 
31 #if defined(ARM_FLOAT16_SUPPORTED)
32 
33 #include <limits.h>
34 #include <math.h>
35 
36 #define PI_F 3.1415926535897932384626433832795f16
37 
38 /**
39  * @addtogroup groupBayes
40  * @{
41  */
42 
43 /**
44  * @brief Naive Gaussian Bayesian Estimator
45  *
46  * @param[in]  *S                       points to a naive bayes instance structure
47  * @param[in]  *in                      points to the elements of the input vector.
48  * @param[out] *pOutputProbabilities    points to a buffer of length numberOfClasses containing estimated probabilities
49  * @param[out] *pBufferB                points to a temporary buffer of length numberOfClasses
50  * @return The predicted class
51  *
52  *
53  */
54 
55 #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
56 
57 #include "arm_helium_utils.h"
58 #include "arm_vec_math_f16.h"
59 
arm_gaussian_naive_bayes_predict_f16(const arm_gaussian_naive_bayes_instance_f16 * S,const float16_t * in,float16_t * pOutputProbabilities,float16_t * pBufferB)60 uint32_t arm_gaussian_naive_bayes_predict_f16(const arm_gaussian_naive_bayes_instance_f16 *S,
61    const float16_t * in,
62    float16_t *pOutputProbabilities,
63    float16_t *pBufferB
64    )
65 {
66     uint32_t         nbClass;
67     const float16_t *pTheta = S->theta;
68     const float16_t *pSigma = S->sigma;
69     float16_t      *buffer = pOutputProbabilities;
70     const float16_t *pIn = in;
71     float16_t       result;
72     f16x8_t         vsigma;
73     _Float16       tmp;
74     f16x8_t         vacc1, vacc2;
75     uint32_t        index;
76     float16_t       *logclassPriors=pBufferB;
77     float16_t      *pLogPrior = logclassPriors;
78 
79     arm_vlog_f16((float16_t *) S->classPriors, logclassPriors, S->numberOfClasses);
80 
81     pTheta = S->theta;
82     pSigma = S->sigma;
83 
84     for (nbClass = 0; nbClass < S->numberOfClasses; nbClass++) {
85         pIn = in;
86 
87         vacc1 = vdupq_n_f16(0.0f16);
88         vacc2 = vdupq_n_f16(0.0f16);
89 
90         uint32_t         blkCnt =S->vectorDimension >> 3;
91         while (blkCnt > 0U) {
92             f16x8_t         vinvSigma, vtmp;
93 
94             vsigma = vaddq_n_f16(vld1q(pSigma), S->epsilon);
95             vacc1 = vaddq(vacc1, vlogq_f16(vmulq_n_f16(vsigma, 2.0f16 * (_Float16)PI)));
96 
97             vinvSigma = vrecip_medprec_f16(vsigma);
98 
99             vtmp = vsubq(vld1q(pIn), vld1q(pTheta));
100             /* squaring */
101             vtmp = vmulq(vtmp, vtmp);
102 
103             vacc2 = vfmaq(vacc2, vtmp, vinvSigma);
104 
105             pIn += 8;
106             pTheta += 8;
107             pSigma += 8;
108             blkCnt--;
109         }
110 
111         blkCnt = S->vectorDimension & 7;
112         if (blkCnt > 0U) {
113             mve_pred16_t    p0 = vctp16q(blkCnt);
114             f16x8_t         vinvSigma, vtmp;
115 
116             vsigma = vaddq_n_f16(vld1q(pSigma), S->epsilon);
117             vacc1 =
118                 vaddq_m_f16(vacc1, vacc1, vlogq_f16(vmulq_n_f16(vsigma, 2.0f16 * (_Float16)PI)), p0);
119 
120             vinvSigma = vrecip_medprec_f16(vsigma);
121 
122             vtmp = vsubq(vld1q(pIn), vld1q(pTheta));
123             /* squaring */
124             vtmp = vmulq(vtmp, vtmp);
125 
126             vacc2 = vfmaq_m_f16(vacc2, vtmp, vinvSigma, p0);
127 
128             pTheta += blkCnt;
129             pSigma += blkCnt;
130         }
131 
132         tmp = -0.5f16 * (_Float16)vecAddAcrossF16Mve(vacc1);
133         tmp -= 0.5f16 * (_Float16)vecAddAcrossF16Mve(vacc2);
134 
135         *buffer = tmp + *pLogPrior++;
136         buffer++;
137     }
138 
139     arm_max_f16(pOutputProbabilities, S->numberOfClasses, &result, &index);
140 
141     return (index);
142 }
143 
144 #else
145 
arm_gaussian_naive_bayes_predict_f16(const arm_gaussian_naive_bayes_instance_f16 * S,const float16_t * in,float16_t * pOutputProbabilities,float16_t * pBufferB)146 uint32_t arm_gaussian_naive_bayes_predict_f16(const arm_gaussian_naive_bayes_instance_f16 *S,
147    const float16_t * in,
148    float16_t *pOutputProbabilities,
149    float16_t *pBufferB)
150 {
151     uint32_t nbClass;
152     uint32_t nbDim;
153     const float16_t *pPrior = S->classPriors;
154     const float16_t *pTheta = S->theta;
155     const float16_t *pSigma = S->sigma;
156     float16_t *buffer = pOutputProbabilities;
157     const float16_t *pIn=in;
158     float16_t result;
159     _Float16 sigma;
160     _Float16 tmp;
161     _Float16 acc1,acc2;
162     uint32_t index;
163     (void)pBufferB;
164 
165     pTheta=S->theta;
166     pSigma=S->sigma;
167 
168     for(nbClass = 0; nbClass < S->numberOfClasses; nbClass++)
169     {
170 
171 
172         pIn = in;
173 
174         tmp = 0.0f16;
175         acc1 = 0.0f16;
176         acc2 = 0.0f16;
177         for(nbDim = 0; nbDim < S->vectorDimension; nbDim++)
178         {
179            sigma = *pSigma + S->epsilon;
180            acc1 += logf(2.0f16 * (_Float16)PI_F * sigma);
181            acc2 += (*pIn - *pTheta) * (*pIn - *pTheta) / sigma;
182 
183            pIn++;
184            pTheta++;
185            pSigma++;
186         }
187 
188         tmp = -0.5f16 * acc1;
189         tmp -= 0.5f16 * acc2;
190 
191 
192         *buffer = tmp + logf(*pPrior++);
193         buffer++;
194     }
195 
196     arm_max_f16(pOutputProbabilities,S->numberOfClasses,&result,&index);
197 
198     return(index);
199 }
200 
201 #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
202 
203 /**
204  * @} end of groupBayes group
205  */
206 
207 #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
208 
209