CMSIS-DSP: log f16 update

pull/19/head
Christophe Favergeon 4 years ago
parent 8fb55a90b7
commit 9674e00294

@ -121,6 +121,64 @@ void arm_barycenter_f16(const float16_t *in
, uint32_t nbVectors
, uint32_t vecDim);
/**
@ingroup groupSupport
*/
/**
* @defgroup typecast Typecasting
*/
/**
@addtogroup typecast
@{
*/
/**
* @brief Interpret a f16 as an s16 value
* @param[in] x input value.
* @return return value.
*
* @par Description
* It is a typecast. No conversion of the float to int is done.
* The memcpy will be optimized out by the compiler.
* memcpy is used to prevent type punning issues.
* With gcc, -fno-builtins MUST not be used or the
* memcpy will not be optimized out.
*/
__STATIC_INLINE int16_t arm_typecast_s16_f16(float16_t x)
{
int16_t res;
res=*(int16_t*)memcpy((char*)&res,(char*)&x,sizeof(float16_t));
return(res);
}
/**
* @brief Interpret an s16 as an f16 value
* @param[in] x input value.
* @return return value.
*
* @par Description
* It is a typecast. No conversion of the int to float is done.
* The memcpy will be optimized out by the compiler.
* memcpy is used to prevent type punning issues.
* With gcc, -fno-builtins MUST not be used or the
* memcpy will not be optimized out.
*/
__STATIC_INLINE float16_t arm_typecast_f16_s16(int16_t x)
{
float16_t res;
res=*(float16_t*)memcpy((char*)&res,(char*)&x,sizeof(int16_t));
return(res);
}
/**
@} end of typecast group
*/
#endif /*defined(ARM_FLOAT16_SUPPORTED)*/
#ifdef __cplusplus
}

@ -27,13 +27,131 @@
*/
#include "dsp/fast_math_functions_f16.h"
#include "dsp/support_functions_f16.h"
#if defined(ARM_FLOAT16_SUPPORTED)
/* Degree of the polynomial approximation */
#define NB_DEG_LOGF16 3
/*
Related to the Log2 of the number of approximations.
For instance, with 3 there are 1 + 2^3 polynomials
*/
#define NB_DIV_LOGF16 3
/* Length of the LUT table */
#define NB_LUT_LOGF16 (NB_DEG_LOGF16+1)*(1 + (1<<NB_DIV_LOGF16))
/*
LUT of polynomial approximations.
Could be generated with:
ClearAll[lut, coefs, nb, deg];
nb = 3;
deg = 3;
lut = Table[
MiniMaxApproximation[
Log[x/2^nb + i], {x, {10^-6, 1.0/2^nb}, deg, 0},
MaxIterations -> 1000][[2, 1]], {i, 1, 2, (1.0/2^nb)}];
coefs = Chop@Flatten[CoefficientList[lut, x]];
*/
static float16_t lut_logf16[NB_LUT_LOGF16]={
0,0.125,-0.00781197,0.00063974,0.117783,
0.111111,-0.00617212,0.000447935,0.223144,
0.1,-0.00499952,0.000327193,0.318454,0.0909091,
-0.00413191,0.000246234,0.405465,0.0833333,
-0.00347199,0.000189928,0.485508,0.0769231,
-0.00295841,0.00014956,0.559616,0.0714286,
-0.0025509,0.000119868,0.628609,0.0666667,
-0.00222213,0.0000975436,0.693147,
0.0625,-0.00195305,0.0000804357};
float16_t logf16_scalar(float16_t x)
{
int16_t i = arm_typecast_s16_f16(x);
int32_t vecExpUnBiased = (i >> 10) - 15;
i = i - (vecExpUnBiased << 10);
float16_t vecTmpFlt1 = arm_typecast_f16_s16(i);
float16_t *lut;
int n;
float16_t tmp,v;
tmp = ((_Float16)vecTmpFlt1 - 1.0f16) * (1 << NB_DIV_LOGF16);
n = floor((double)tmp);
v = (_Float16)tmp - (_Float16)n;
lut = lut_logf16 + n * (1+NB_DEG_LOGF16);
float16_t res = lut[NB_DEG_LOGF16-1];
for(int j=NB_DEG_LOGF16-2; j >=0 ; j--)
{
res = (_Float16)lut[j] + (_Float16)v * (_Float16)res;
}
res = (_Float16)res + 0.693147f16 * (_Float16)vecExpUnBiased;
return(res);
}
#if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
#include "arm_common_tables.h"
#include "arm_vec_math_f16.h"
float16x8_t vlogq_lut_f16(float16x8_t vecIn)
{
int16x8_t i = vreinterpretq_s16_f16(vecIn);
int16x8_t vecExpUnBiased = vsubq_n_s16(vshrq_n_s16(i,10), 15);
i = vsubq_s16(i,vshlq_n_s16(vecExpUnBiased,10));
float16x8_t vecTmpFlt1 = vreinterpretq_f16_s16(i);
float16x8_t lutV;
int16x8_t n;
int16x8_t offset;
float16x8_t tmp,v,res;
tmp = vmulq_n_f16(vsubq_n_f16(vecTmpFlt1,1.0f16),(_Float16)(1 << NB_DIV_LOGF16));
n = vcvtq_s16_f16(tmp);
v = vsubq_f16(tmp,vcvtq_f16_s16(n));
offset = vmulq_n_s16(n,(1+NB_DEG_LOGF16));
offset = vaddq_n_s16(offset,NB_DEG_LOGF16-1);
res = vldrhq_gather_shifted_offset_f16(lut_logf16,offset);
offset = vsubq_n_s16(offset,1);
for(int j=NB_DEG_LOGF16-2; j >=0 ; j--)
{
lutV = vldrhq_gather_shifted_offset_f16(lut_logf16,offset);
res = vfmaq_f16(lutV,v,res);
offset = vsubq_n_s16(offset,1);
}
res = vfmaq_n_f16(res,vcvtq_f16_s16(vecExpUnBiased),0.693147f16);
return(res);
}
#endif
/**
@ingroup groupFastMath
*/
@ -42,6 +160,16 @@
@addtogroup vlog
@{
*/
/**
@brief Floating-point vector of log values.
@param[in] pSrc points to the input vector
@param[out] pDst points to the output vector
@param[in] blockSize number of samples in each vector
@return none
*/
void arm_vlog_f16(
const float16_t * pSrc,
float16_t * pDst,
@ -49,8 +177,7 @@ void arm_vlog_f16(
{
uint32_t blkCnt;
#if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
#if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
f16x8_t src;
f16x8_t dst;
@ -59,7 +186,7 @@ void arm_vlog_f16(
while (blkCnt > 0U)
{
src = vld1q(pSrc);
dst = vlogq_f16(src);
dst = vlogq_lut_f16(src);
vst1q(pDst, dst);
pSrc += 8;
@ -78,17 +205,18 @@ void arm_vlog_f16(
/* C = log(A) */
/* Calculate log and store result in destination buffer. */
*pDst++ = (_Float16)logf((float32_t)*pSrc++);
*pDst++ = logf16_scalar(*pSrc++);
/* Decrement loop counter */
blkCnt--;
}
}
/**
@} end of vlog group
*/
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */

@ -49,6 +49,8 @@ def divide(f,r):
def initLogValues(format):
if format == Tools.Q15:
exps = -np.linspace(0,15,num=125)
elif format == Tools.F16:
exps = -np.linspace(0,10,num=125)
else:
exps = -np.linspace(0,31,num=125)
basis=2.0*np.ones(exps.size)

@ -2,251 +2,251 @@ H
125
// 0.000000
0x0
// -0.173287
0xb18c
// -0.346574
0xb58c
// -0.519860
0xb829
// -0.693147
0xb98c
// -0.866434
0xbaee
// -1.039721
0xbc29
// -1.213008
0xbcda
// -1.386294
0xbd8c
// -1.559581
0xbe3d
// -0.055899
0xab28
// -0.111798
0xaf28
// -0.167697
0xb15e
// -0.223596
0xb328
// -0.279495
0xb479
// -0.335394
0xb55e
// -0.391293
0xb643
// -0.447192
0xb728
// -0.503091
0xb806
// -0.558990
0xb879
// -0.614889
0xb8eb
// -0.670788
0xb95e
// -0.726687
0xb9d0
// -0.782586
0xba43
// -0.838484
0xbab5
// -0.894383
0xbb28
// -0.950282
0xbb9a
// -1.006181
0xbc06
// -1.062080
0xbc40
// -1.117979
0xbc79
// -1.173878
0xbcb2
// -1.229777
0xbceb
// -1.285676
0xbd25
// -1.341575
0xbd5e
// -1.397474
0xbd97
// -1.453373
0xbdd0
// -1.509272
0xbe09
// -1.565171
0xbe43
// -1.621070
0xbe7c
// -1.676969
0xbeb5
// -1.732868
0xbeee
// -1.906155
0xbfa0
// -2.079442
0xc029
// -2.252728
0xc081
// -2.426015
0xc0da
// -2.599302
0xc133
// -2.772589
0xc18c
// -2.945876
0xc1e4
// -3.119162
0xc23d
// -3.292449
0xc296
// -1.788767
0xbf28
// -1.844666
0xbf61
// -1.900565
0xbf9a
// -1.956464
0xbfd3
// -2.012363
0xc006
// -2.068262
0xc023
// -2.124161
0xc040
// -2.180060
0xc05c
// -2.235959
0xc079
// -2.291858
0xc095
// -2.347757
0xc0b2
// -2.403656
0xc0cf
// -2.459555
0xc0eb
// -2.515453
0xc108
// -2.571352
0xc125
// -2.627251
0xc141
// -2.683150
0xc15e
// -2.739049
0xc17a
// -2.794948
0xc197
// -2.850847
0xc1b4
// -2.906746
0xc1d0
// -2.962645
0xc1ed
// -3.018544
0xc209
// -3.074443
0xc226
// -3.130342
0xc243
// -3.186241
0xc25f
// -3.242140
0xc27c
// -3.298039
0xc299
// -3.353938
0xc2b5
// -3.409837
0xc2d2
// -3.465736
0xc2ee
// -3.639023
0xc347
// -3.812309
0xc3a0
// -3.985596
0xc3f9
// -4.158883
0xc429
// -4.332170
0xc455
// -4.505457
0xc481
// -4.678743
0xc4ae
// -4.852030
0xc4da
// -5.025317
0xc506
// -3.521635
0xc30b
// -3.577534
0xc328
// -3.633433
0xc344
// -3.689332
0xc361
// -3.745231
0xc37e
// -3.801130
0xc39a
// -3.857029
0xc3b7
// -3.912928
0xc3d3
// -3.968827
0xc3f0
// -4.024726
0xc406
// -4.080625
0xc415
// -4.136523
0xc423
// -4.192422
0xc431
// -4.248321
0xc440
// -4.304220
0xc44e
// -4.360119
0xc45c
// -4.416018
0xc46b
// -4.471917
0xc479
// -4.527816
0xc487
// -4.583715
0xc495
// -4.639614
0xc4a4
// -4.695513
0xc4b2
// -4.751412
0xc4c0
// -4.807311
0xc4cf
// -4.863210
0xc4dd
// -4.919109
0xc4eb
// -4.975008
0xc4fa
// -5.030907
0xc508
// -5.086806
0xc516
// -5.142705
0xc525
// -5.198604
0xc533
// -5.371891
0xc55f
// -5.545177
0xc58c
// -5.718464
0xc5b8
// -5.891751
0xc5e4
// -6.065038
0xc611
// -6.238325
0xc63d
// -6.411611
0xc669
// -6.584898
0xc696
// -6.758185
0xc6c2
// -5.254503
0xc541
// -5.310402
0xc54f
// -5.366301
0xc55e
// -5.422200
0xc56c
// -5.478099
0xc57a
// -5.533998
0xc589
// -5.589897
0xc597
// -5.645796
0xc5a5
// -5.701695
0xc5b4
// -5.757594
0xc5c2
// -5.813492
0xc5d0
// -5.869391
0xc5df
// -5.925290
0xc5ed
// -5.981189
0xc5fb
// -6.037088
0xc609
// -6.092987
0xc618
// -6.148886
0xc626
// -6.204785
0xc634
// -6.260684
0xc643
// -6.316583
0xc651
// -6.372482
0xc65f
// -6.428381
0xc66e
// -6.484280
0xc67c
// -6.540179
0xc68a
// -6.596078
0xc699
// -6.651977
0xc6a7
// -6.707876
0xc6b5
// -6.763775
0xc6c4
// -6.819674
0xc6d2
// -6.875573
0xc6e0
// -6.931472
0xc6ee
// -7.104759
0xc71b
// -7.278045
0xc747
// -7.451332
0xc774
// -7.624619
0xc7a0
// -7.797906
0xc7cc
// -7.971193
0xc7f9
// -8.144479
0xc812
// -8.317766
0xc829
// -8.491053
0xc83f
// -8.664340
0xc855
// -8.837627
0xc86b
// -9.010913
0xc881
// -9.184200
0xc898
// -9.357487
0xc8ae
// -9.530774
0xc8c4
// -9.704061
0xc8da
// -9.877347
0xc8f0
// -10.050634
0xc906
// -10.223921
0xc91d
// -10.397208
0xc933
// -10.570495
0xc949
// -10.743781
0xc95f
// -10.917068
0xc975
// -11.090355
0xc98c
// -11.263642
0xc9a2
// -11.436928
0xc9b8
// -11.610215
0xc9ce
// -11.783502
0xc9e4
// -11.956789
0xc9fa
// -12.130076
0xca11
// -12.303362
0xca27
// -12.476649
0xca3d
// -12.649936
0xca53
// -12.823223
0xca69
// -12.996510
0xca80
// -13.169796
0xca96
// -13.343083
0xcaac
// -13.516370
0xcac2
// -13.689657
0xcad8
// -13.862944
0xcaee
// -14.036230
0xcb05
// -14.209517
0xcb1b
// -14.382804
0xcb31
// -14.556091
0xcb47
// -14.729378
0xcb5d
// -14.902664
0xcb74
// -15.075951
0xcb8a
// -15.249238
0xcba0
// -15.422525
0xcbb6
// -15.595812
0xcbcc
// -15.769098
0xcbe2
// -15.942385
0xcbf9
// -16.115672
0xcc07
// -16.288959
0xcc12
// -16.462246
0xcc1e
// -16.635532
0xcc29
// -16.808819
0xcc34
// -16.982106
0xcc3f
// -17.155393
0xcc4a
// -17.328680
0xcc55
// -17.501966
0xcc60
// -17.675253
0xcc6b
// -17.848540
0xcc76
// -18.021827
0xcc81
// -18.195113
0xcc8c
// -18.368400
0xcc98
// -18.541687
0xcca3
// -18.714974
0xccae
// -18.888261
0xccb9
// -19.061547
0xccc4
// -19.234834
0xcccf
// -19.408121
0xccda
// -19.581408
0xcce5
// -19.754695
0xccf0
// -19.927981
0xccfb
// -20.101268
0xcd06
// -20.274555
0xcd12
// -20.447842
0xcd1d
// -20.621129
0xcd28
// -20.794415
0xcd33
// -20.967702
0xcd3e
// -21.140989
0xcd49
// -21.314276
0xcd54
// -21.487563
0xcd5f

@ -2,251 +2,251 @@ H
125
// 1.000000
0x3c00
// 0.840896
0x3aba
// 0.707107
0x39a8
// 0.594604
0x38c2
// 0.500000
0x3800
// 0.420448
0x36ba
// 0.353553
0x35a8
// 0.297302
0x34c2
// 0.250000
0x3400
// 0.210224
0x32ba
// 0.945635
0x3b91
// 0.894225
0x3b27
// 0.845610
0x3ac4
// 0.799638
0x3a66
// 0.756166
0x3a0d
// 0.715056
0x39b8
// 0.676182
0x3969
// 0.639421
0x391e
// 0.604659
0x38d6
// 0.571786
0x3893
// 0.540701
0x3853
// 0.511306
0x3817
// 0.483508
0x37bc
// 0.457222
0x3751
// 0.432365
0x36eb
// 0.408860
0x368b
// 0.386632
0x3630
// 0.365612
0x35da
// 0.345736
0x3588
// 0.326940
0x353b
// 0.309166
0x34f2
// 0.292358
0x34ad
// 0.276464
0x346c
// 0.261434
0x342f
// 0.247221
0x33e9
// 0.233780
0x337b
// 0.221071
0x3313
// 0.209052
0x32b1
// 0.197687
0x3253
// 0.186940
0x31fb
// 0.176777
0x31a8
// 0.148651
0x30c2
// 0.125000
0x3000
// 0.105112
0x2eba
// 0.088388
0x2da8
// 0.074325
0x2cc2
// 0.062500
0x2c00
// 0.052556
0x2aba
// 0.044194
0x29a8
// 0.037163
0x28c2
// 0.167166
0x3159
// 0.158078
0x310f
// 0.149484
0x30c9
// 0.141357
0x3086
// 0.133672
0x3047
// 0.126405
0x300c
// 0.119533
0x2fa6
// 0.113035
0x2f3c
// 0.106890
0x2ed7
// 0.101079
0x2e78
// 0.095583
0x2e1e
// 0.090387
0x2dc9
// 0.085473
0x2d78
// 0.080826
0x2d2c
// 0.076432
0x2ce4
// 0.072277
0x2ca0
// 0.068347
0x2c60
// 0.064632
0x2c23
// 0.061118
0x2bd3
// 0.057795
0x2b66
// 0.054653
0x2aff
// 0.051682
0x2a9e
// 0.048872
0x2a41
// 0.046215
0x29ea
// 0.043703
0x2998
// 0.041327
0x294a
// 0.039080
0x2901
// 0.036956
0x28bb
// 0.034946
0x2879
// 0.033047
0x283b
// 0.031250
0x2800
// 0.026278
0x26ba
// 0.022097
0x25a8
// 0.018581
0x24c2
// 0.015625
0x2400
// 0.013139
0x22ba
// 0.011049
0x21a8
// 0.009291
0x20c2
// 0.007812
0x2000
// 0.006570
0x1eba
// 0.029551
0x2791
// 0.027945
0x2727
// 0.026425
0x26c4
// 0.024989
0x2666
// 0.023630
0x260d
// 0.022346
0x25b8
// 0.021131
0x2569
// 0.019982
0x251e
// 0.018896
0x24d6
// 0.017868
0x2493
// 0.016897
0x2453
// 0.015978
0x2417
// 0.015110
0x23bc
// 0.014288
0x2351
// 0.013511
0x22eb
// 0.012777
0x228b
// 0.012082
0x2230
// 0.011425
0x21da
// 0.010804
0x2188
// 0.010217
0x213b
// 0.009661
0x20f2
// 0.009136
0x20ad
// 0.008639
0x206c
// 0.008170
0x202f
// 0.007726
0x1fe9
// 0.007306
0x1f7b
// 0.006908
0x1f13
// 0.006533
0x1eb1
// 0.006178
0x1e53
// 0.005842
0x1dfb
// 0.005524
0x1da8
// 0.004645
0x1cc2
// 0.003906
0x1c00
// 0.003285
0x1aba
// 0.002762
0x19a8
// 0.002323
0x18c2
// 0.001953
0x1800
// 0.001642
0x16ba
// 0.001381
0x15a8
// 0.001161
0x14c2
// 0.005224
0x1d59
// 0.004940
0x1d0f
// 0.004671
0x1cc9
// 0.004417
0x1c86
// 0.004177
0x1c47
// 0.003950
0x1c0c
// 0.003735
0x1ba6
// 0.003532
0x1b3c
// 0.003340
0x1ad7
// 0.003159
0x1a78
// 0.002987
0x1a1e
// 0.002825
0x19c9
// 0.002671
0x1978
// 0.002526
0x192c
// 0.002389
0x18e4
// 0.002259
0x18a0
// 0.002136
0x1860
// 0.002020
0x1823
// 0.001910
0x17d3
// 0.001806
0x1766
// 0.001708
0x16ff
// 0.001615
0x169e
// 0.001527
0x1641
// 0.001444
0x15ea
// 0.001366
0x1598
// 0.001291
0x154a
// 0.001221
0x1501
// 0.001155
0x14bb
// 0.001092
0x1479
// 0.001033
0x143b
// 0.000977
0x1400
// 0.000821
0x12ba
// 0.000691
0x11a8
// 0.000581
0x10c2
// 0.000488
0x1000
// 0.000411
0xeba
// 0.000345
0xda8
// 0.000290
0xcc2
// 0.000244
0xc00
// 0.000205
0xaba
// 0.000173
0x9a8
// 0.000145
0x8c2
// 0.000122
0x800
// 0.000103
0x6ba
// 0.000086
0x5a8
// 0.000073
0x4c2
// 0.000061
0x400
// 0.000051
0x35d
// 0.000043
0x2d4
// 0.000036
0x261
// 0.000031
0x200
// 0.000026
0x1af
// 0.000022
0x16a
// 0.000018
0x130
// 0.000015
0x100
// 0.000013
0xd7
// 0.000011
0xb5
// 0.000009
0x98
// 0.000008
0x80
// 0.000006
0x6c
// 0.000005
0x5b
// 0.000005
0x4c
// 0.000004
0x40
// 0.000003
0x36
// 0.000003
0x2d
// 0.000002
0x26
// 0.000002
0x20
// 0.000002
0x1b
// 0.000001
0x17
// 0.000001
0x13
// 0.000001
0x10
// 0.000001
0xd
// 0.000001
0xb
// 0.000001
0xa
// 0.000000
0x8
// 0.000000
0x7
// 0.000000
0x6
// 0.000000
0x5
// 0.000000
0x4
// 0.000000
0x3
// 0.000000
0x3
// 0.000000
0x2
// 0.000000
0x2
// 0.000000
0x2
// 0.000000
0x1
// 0.000000
0x1
// 0.000000
0x1
// 0.000000
0x1
// 0.000000
0x1
// 0.000000
0x1
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

@ -5,7 +5,6 @@
#define SNR_THRESHOLD 60
#define SNR_LOG_THRESHOLD 40
/*
@ -16,8 +15,6 @@ a double precision computation.
#define REL_ERROR (1.0e-3)
#define ABS_ERROR (1.0e-3)
#define REL_LOG_ERROR (3.0e-2)
#define ABS_LOG_ERROR (3.0e-2)
#if 0
void FastMathF16::test_cos_f16()
@ -74,15 +71,16 @@ a double precision computation.
}
void FastMathF16::test_vlog_f16()
{
const float16_t *inp = input.ptr();
float16_t *outp = output.ptr();
arm_vlog_f16(inp,outp,ref.nbSamples());
ASSERT_SNR(ref,output,(float16_t)SNR_LOG_THRESHOLD);
ASSERT_CLOSE_ERROR(ref,output,ABS_LOG_ERROR,REL_LOG_ERROR);
//ASSERT_SNR(ref,output,(float16_t)SNR_THRESHOLD);
ASSERT_CLOSE_ERROR(ref,output,ABS_ERROR,REL_ERROR);
ASSERT_EMPTY_TAIL(output);
}

@ -4,7 +4,7 @@
#include "mfccdata_f16.h"
#define SNR_THRESHOLD 50
#define SNR_THRESHOLD 60
/*
@ -12,8 +12,8 @@ Reference patterns are generated with
a double precision computation.
*/
#define REL_ERROR (2.0e-2)
#define ABS_ERROR (2.0e-2)
#define REL_ERROR (4.0e-3)
#define ABS_ERROR (4.0e-3)
void MFCCF16::test_mfcc_f16()

Loading…
Cancel
Save