CMSIS-DSP: Added scalar float64 entropy and kullback leibler

pull/19/head
ClaudioMartino 6 years ago committed by Christophe Favergeon
parent 3446683ed3
commit fb1f6b04a7

@ -8160,6 +8160,19 @@ float32_t arm_logsumexp_dot_prod_f32(const float32_t * pSrcA,
float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize);
/**
* @brief Entropy
*
* @param[in] pSrcA Array of input values.
* @param[in] blockSize Number of samples in the input array.
* @return Entropy -Sum(p ln p)
*
*/
float64_t arm_entropy_f64(const float64_t * pSrcA, uint32_t blockSize);
/**
* @brief Kullback-Leibler
*
@ -8174,6 +8187,20 @@ float32_t arm_kullback_leibler_f32(const float32_t * pSrcA
,uint32_t blockSize);
/**
* @brief Kullback-Leibler
*
* @param[in] pSrcA Pointer to an array of input values for probability distribution A.
* @param[in] pSrcB Pointer to an array of input values for probability distribution B.
* @param[in] blockSize Number of samples in the input array.
* @return Kullback-Leibler Divergence D(A || B)
*
*/
float64_t arm_kullback_leibler_f64(const float64_t * pSrcA,
const float64_t * pSrcB,
uint32_t blockSize);
/**
* @brief Weighted sum
*

@ -0,0 +1,71 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_logsumexp_f64.c
* Description: LogSumExp
*
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "arm_math.h"
#include <limits.h>
#include <math.h>
/**
* @addtogroup groupStats
* @{
*/
/**
* @brief Entropy
*
* @param[in] pSrcA Array of input values.
* @param[in] blockSize Number of samples in the input array.
* @return Entropy -Sum(p ln p)
*
*/
float64_t arm_entropy_f64(const float64_t * pSrcA, uint32_t blockSize)
{
const float64_t *pIn;
uint32_t blkCnt;
float64_t accum, p;
pIn = pSrcA;
blkCnt = blockSize;
accum = 0.0f;
while(blkCnt > 0)
{
p = *pIn++;
accum += p * log(p);
blkCnt--;
}
return(-accum);
}
/**
* @} end of groupStats group
*/

@ -0,0 +1,73 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_logsumexp_f64.c
* Description: LogSumExp
*
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "arm_math.h"
#include <limits.h>
#include <math.h>
/**
* @addtogroup groupStats
* @{
*/
/**
* @brief Kullback-Leibler
*
* @param[in] *pSrcA points to an array of input values for probaility distribution A.
* @param[in] *pSrcB points to an array of input values for probaility distribution B.
* @param[in] blockSize number of samples in the input array.
* @return Kullback-Leibler divergence D(A || B)
*
*/
float64_t arm_kullback_leibler_f64(const float64_t * pSrcA, const float64_t * pSrcB, uint32_t blockSize)
{
const float64_t *pInA, *pInB;
uint32_t blkCnt;
float64_t accum, pA,pB;
pInA = pSrcA;
pInB = pSrcB;
blkCnt = blockSize;
accum = 0.0f;
while(blkCnt > 0)
{
pA = *pInA++;
pB = *pInB++;
accum += pA * log(pB / pA);
blkCnt--;
}
return(-accum);
}
/**
* @} end of groupStats group
*/

@ -156,6 +156,7 @@ set(TESTSRC
Source/Tests/TransformCQ15.cpp
Source/Tests/TransformRQ15.cpp
Source/Tests/StatsTestsF32.cpp
Source/Tests/StatsTestsF64.cpp
Source/Tests/StatsTestsQ31.cpp
Source/Tests/StatsTestsQ15.cpp
Source/Tests/StatsTestsQ7.cpp

@ -0,0 +1,32 @@
#include "Test.h"
#include "Pattern.h"
class StatsTestsF64:public Client::Suite
{
public:
StatsTestsF64(Testing::testID_t id);
virtual void setUp(Testing::testID_t,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr);
virtual void tearDown(Testing::testID_t,Client::PatternMgr *mgr);
private:
#include "StatsTestsF64_decl.h"
Client::Pattern<float64_t> inputA;
Client::Pattern<float64_t> inputB;
Client::Pattern<int16_t> dims;
Client::LocalPattern<float64_t> output;
Client::LocalPattern<int16_t> index;
Client::LocalPattern<float64_t> tmp;
// Reference patterns are not loaded when we are in dump mode
Client::RefPattern<float64_t> ref;
Client::Pattern<int16_t> maxIndexes;
Client::Pattern<int16_t> minIndexes;
int nbPatterns;
int vecDim;
int refOffset;
};

@ -123,6 +123,11 @@ def writeF32OnlyTests(config,nb):
logSumExpDotTest(config,nb+3)
return(nb+4)
def writeF64OnlyTests(config,nb):
entropyTest(config,nb)
klTest(config,nb+2)
return(nb+4)
# For index in min and max we need to ensure that the difference between values
# of the input is big enough to be representable on q31, q15 or q7.
# Otherwise python will compute an index different from the one
@ -338,16 +343,17 @@ def generatePatterns():
PARAMDIR = os.path.join("Parameters","DSP","Stats","Stats")
configf32=Tools.Config(PATTERNDIR,PARAMDIR,"f32")
configf64=Tools.Config(PATTERNDIR,PARAMDIR,"f64")
configq31=Tools.Config(PATTERNDIR,PARAMDIR,"q31")
configq15=Tools.Config(PATTERNDIR,PARAMDIR,"q15")
configq7 =Tools.Config(PATTERNDIR,PARAMDIR,"q7")
nb=writeTests(configf32,1,0)
nb=writeF32OnlyTests(configf32,22)
writeF64OnlyTests(configf64,22)
writeTests(configq31,1,31)
writeTests(configq15,1,15)
writeTests(configq7,1,7)
if __name__ == '__main__':
generatePatterns()
generatePatterns()

@ -0,0 +1,24 @@
H
11
// 10
0x000A
// 3
0x0003
// 8
0x0008
// 9
0x0009
// 12
0x000C
// 3
0x0003
// 8
0x0008
// 9
0x0009
// 12
0x000C
// 3
0x0003
// 8
0x0008

@ -0,0 +1,24 @@
H
11
// 10
0x000A
// 3
0x0003
// 8
0x0008
// 9
0x0009
// 12
0x000C
// 3
0x0003
// 8
0x0008
// 9
0x0009
// 12
0x000C
// 3
0x0003
// 8
0x0008

@ -0,0 +1,152 @@
D
75
// 0.505280
0x3fe02b417ebce314
// 0.454144
0x3fdd10b048f98340
// 0.040576
0x3fa4c665cc65b4da
// 0.228813
0x3fcd49bc24996ead
// 0.111427
0x3fbc8677ddbcf163
// 0.184665
0x3fc7a31bcac2bf14
// 0.102689
0x3fba49d5259ee3fc
// 0.061293
0x3faf61d601affcb1
// 0.149838
0x3fc32de527c03dd6
// 0.068132
0x3fb1711893b7b7bb
// 0.093143
0x3fb7d83539db9d64
// 0.183439
0x3fc77af068192567
// 0.135121
0x3fc14ba61cff9e4a
// 0.254422
0x3fd04874bc8b246c
// 0.083904
0x3fb57ab816eaf2d4
// 0.019128
0x3f93965f819fb27d
// 0.133743
0x3fc11e7adb462d9e
// 0.031570
0x3fa029f293959c58
// 0.155015
0x3fc3d78a1d28ff68
// 0.003657
0x3f6df59a34bbe7fc
// 0.098729
0x3fb94647dfe164c2
// 0.188947
0x3fc82f6c20029e4c
// 0.047608
0x3fa8600f36933cc7
// 0.141847
0x3fc22808a330e919
// 0.120154
0x3fbec26dff4e4a07
// 0.090980
0x3fb74a7dd8ae1dc6
// 0.160669
0x3fc490cda4dc1fba
// 0.044310
0x3fa6afdd8f890bed
// 0.014223
0x3f8d212b593bb5d5
// 0.017826
0x3f9240db8931faf8
// 0.046638
0x3fa7e0dfc0893a18
// 0.028069
0x3f9cbe139cf0b961
// 0.034885
0x3fa1dc81ecf1e55c
// 0.555134
0x3fe1c3a8c3665c97
// 0.409980
0x3fda3d1e3b950a27
// 0.147303
0x3fc2dad28b75bdbb
// 0.064279
0x3fb0749b57b09f6c
// 0.090849
0x3fb741e98925ac09
// 0.096415
0x3fb8aea8dd2d9f60
// 0.229429
0x3fcd5ded0f16ce39
// 0.278635
0x3fd1d5267e1ff701
// 0.078974
0x3fb437a2f99783fc
// 0.014116
0x3f8ce8b0d65cea1e
// 0.136180
0x3fc16e5c2448f017
// 0.113739
0x3fbd1dfee47d7526
// 0.014262
0x3f8d35807b52bb38
// 0.164832
0x3fc519385dec9eb0
// 0.173764
0x3fc63de6d7b944c8
// 0.092918
0x3fb7c97fa6cbdd79
// 0.163854
0x3fc4f929fe4ebe2d
// 0.118066
0x3fbe398bbcfdf520
// 0.022384
0x3f96ebebdf4cf5b5
// 0.008318
0x3f8108debf1c188a
// 0.135012
0x3fc148117697674d
// 0.106476
0x3fbb420b2755099e
// 0.135063
0x3fc149bd2923d7a6
// 0.108069
0x3fbbaa6936142c3f
// 0.038218
0x3fa391498e2c8ec4
// 0.017892
0x3f9252517f6a400e
// 0.050650
0x3fa9eec84ae68d1c
// 0.066123
0x3fb0ed6f2034becb
// 0.154318
0x3fc3c0af2f83b20f
// 0.005330
0x3f75d54fb82e5b5e
// 0.174531
0x3fc65709620cd149
// 0.434164
0x3fdbc9575a8675f6
// 0.062753
0x3fb0108e60bada3e
// 0.503083
0x3fe0194286a569be
// 0.132317
0x3fc0efc111f57b42
// 0.154534
0x3fc3c7c715d99fde
// 0.156671
0x3fc40dcdb6423723
// 0.061359
0x3faf6a634a4b379e
// 0.100333
0x3fb9af6f5c11a434
// 0.107005
0x3fbb64aa0e48ab7f
// 0.122395
0x3fbf554c29cc943a
// 0.165386
0x3fc52b5e85486ddc

@ -0,0 +1,152 @@
D
75
// 0.501853
0x3fe00f2ee978b047
// 0.177515
0x3fc6b8d10fd5ee4b
// 0.320631
0x3fd48539a523a84e
// 0.047192
0x3fa829850436d98b
// 0.158713
0x3fc450b4c623ec7d
// 0.104308
0x3fbab3f2f656a749
// 0.205971
0x3fca5d3e6b075a10
// 0.218328
0x3fcbf22b6b1086a3
// 0.118650
0x3fbe5fdba7cfa8b1
// 0.030952
0x3f9fb1e9d483be94
// 0.115886
0x3fbdaab73225b93e
// 0.113465
0x3fbd0c04fff053b4
// 0.148880
0x3fc30e817da1d640
// 0.128425
0x3fc0703748090597
// 0.122130
0x3fbf43e6098ab895
// 0.035091
0x3fa1f7623e67a84b
// 0.120082
0x3fbebdb6179e919d
// 0.145733
0x3fc2a762a0f0bacb
// 0.124931
0x3fbffb79bbbeee35
// 0.061264
0x3faf5dfa6d78e4fd
// 0.064801
0x3fb096cf187042e3
// 0.092918
0x3fb7c97320f2a3ae
// 0.118482
0x3fbe54ceb43c30bc
// 0.062414
0x3faff4accb8bd8b0
// 0.060437
0x3faef1a8ccd0e611
// 0.039589
0x3fa444f8c3c66199
// 0.105396
0x3fbafb3f60731313
// 0.102100
0x3fba2340353bff17
// 0.110738
0x3fbc594c098a19bf
// 0.080640
0x3fb4a4cb1be519ee
// 0.046774
0x3fa7f2b354bd88a3
// 0.115713
0x3fbd9f577ed24e53
// 0.439571
0x3fdc21ed1f2ea6d7
// 0.282044
0x3fd20d041644dc92
// 0.278385
0x3fd1d10eca8c7c97
// 0.182100
0x3fc74f10e76157a5
// 0.043353
0x3fa63261dc70867f
// 0.042056
0x3fa58869987c34b4
// 0.128218
0x3fc0697018a334b3
// 0.136056
0x3fc16a4920e0b468
// 0.169850
0x3fc5bda40485792a
// 0.136761
0x3fc181623e3a0bb2
// 0.161605
0x3fc4af7cbf200b96
// 0.080238
0x3fb48a8204653a41
// 0.038292
0x3fa39b0380dedfa9
// 0.194841
0x3fc8f08c8462dcd7
// 0.129271
0x3fc08bf2ca4780be
// 0.016048
0x3f906ec52d80a287
// 0.228960
0x3fcd4e8c8faab1fe
// 0.219449
0x3fcc16e7c60ce05b
// 0.062672
0x3fb00b4bbec4cc77
// 0.030229
0x3f9ef45fa10a03d4
// 0.008741
0x3f81e6917c79950e
// 0.121629
0x3fbf230d5cdc3e8a
// 0.065855
0x3fb0dbdfe66a59de
// 0.141689
0x3fc222db8d1db5ce
// 0.137891
0x3fc1a667b1cd01b9
// 0.142990
0x3fc24d8303bfe315
// 0.079355
0x3fb450a30d958f82
// 0.093264
0x3fb7e027cf1d49b7
// 0.058599
0x3fae00a190b6bd75
// 0.096343
0x3fb8a9ec7a0837a1
// 0.020144
0x3f94a0841a8a6bf2
// 0.033501
0x3fa12715c437ea4d
// 0.347819
0x3fd642a9e74cc4eb
// 0.305751
0x3fd3916ca11c18f1
// 0.346430
0x3fd62be977972226
// 0.115685
0x3fbd9d8931dc83cd
// 0.128242
0x3fc06a3d21eb0ba8
// 0.013092
0x3f8acfc715554a30
// 0.146638
0x3fc2c505ae582974
// 0.153318
0x3fc39feddba73197
// 0.197917
0x3fc955581b9af273
// 0.079896
0x3fb47410ece8debb
// 0.165212
0x3fc525adb7c2a0ef

@ -0,0 +1,152 @@
D
75
// 0.263522
0x3fd0dd8afff76385
// 0.289325
0x3fd2844bcd035f61
// 0.447153
0x3fdc9e2933053d19
// 0.000025
0x3efa6f4e7228bd15
// 0.040059
0x3fa4829304814b70
// 0.053628
0x3fab7524ae359534
// 0.199652
0x3fc98e32f2965e45
// 0.205763
0x3fca56733f1a01f7
// 0.171010
0x3fc5e3a89f0d1329
// 0.134326
0x3fc131988682ed56
// 0.195537
0x3fc90757419e55d9
// 0.182694
0x3fc7628782f84ace
// 0.103593
0x3fba850baa401081
// 0.073549
0x3fb2d41fc7af6949
// 0.083657
0x3fb56a8d4ff5c4ce
// 0.109701
0x3fbc15655565f88a
// 0.177554
0x3fc6ba14992cfb13
// 0.143951
0x3fc26cff04aaadfd
// 0.081353
0x3fb4d38ee714820e
// 0.043947
0x3fa680398000be22
// 0.083992
0x3fb58078d86368d7
// 0.199730
0x3fc990bdeb084e53
// 0.062036
0x3fafc3360baac4e8
// 0.158378
0x3fc445bb623c4b7f
// 0.036417
0x3fa2a53693e22a16
// 0.018402
0x3f92d7febc6e387b
// 0.118342
0x3fbe4ba21ce4600c
// 0.002168
0x3f61c378ef5efebb
// 0.058332
0x3fadddbafac042e0
// 0.048660
0x3fa8e9f397ef93b3
// 0.067851
0x3fb15ea6b21d3082
// 0.145693
0x3fc2a611572e750e
// 0.048427
0x3fa8cb76f97dc0ef
// 0.295198
0x3fd2e48464ca679e
// 0.656375
0x3fe501065e02f021
// 0.088473
0x3fb6a628682a7e83
// 0.087547
0x3fb6698255fbb263
// 0.157099
0x3fc41bd5965c12f9
// 0.047299
0x3fa83789c29247a8
// 0.237495
0x3fce663ac81f0c6c
// 0.055216
0x3fac454f2e4c27cd
// 0.250528
0x3fd008a5bf2917e8
// 0.076343
0x3fb38b310fcff8fd
// 0.021593
0x3f961c645b41c08a
// 0.262684
0x3fd0cfceb390413d
// 0.112116
0x3fbcb3a7b22f6ea7
// 0.156858
0x3fc413edec26286a
// 0.044288
0x3fa6ace2e1806ead
// 0.230852
0x3fcd8c91bb460a8c
// 0.028178
0x3f9cdacdb11e83ac
// 0.001985
0x3f6043dcf2bc61d6
// 0.141445
0x3fc21ae0aaa47d82
// 0.219547
0x3fcc1a19934b1be0
// 0.009410
0x3f83459cd302a689
// 0.096667
0x3fb8bf26175eeef3
// 0.031591
0x3fa02cb3fab03e31
// 0.053311
0x3fab4b880d02a953
// 0.158655
0x3fc44ecf8e8c9f7d
// 0.004074
0x3f70afd3e9975d43
// 0.060421
0x3faeef83359c9e67
// 0.150100
0x3fc336781ccb2f6b
// 0.033587
0x3fa132555bab6b42
// 0.111738
0x3fbc9ae433badb47
// 0.070899
0x3fb2267812291cf3
// 0.094328
0x3fb825da8e1fce34
// 0.465077
0x3fddc3d0b5d6209e
// 0.440596
0x3fdc32b8a6a1ebd4
// 0.116737
0x3fbde27eae730478
// 0.145569
0x3fc2a204aea21edf
// 0.139047
0x3fc1cc47a26356f2
// 0.052558
0x3faae8e3995a3677
// 0.203339
0x3fca07013a914739
// 0.083542
0x3fb5630a011891fd
// 0.113459
0x3fbd0bad4b66be46
// 0.145748
0x3fc2a7de90998afd

@ -0,0 +1,22 @@
D
10
// 0.833429
0x3feaab74254fab33
// 1.987310
0x3fffcc05dcd7cd66
// 1.901057
0x3ffe6abb2f676934
// 2.245504
0x4001f6cae58c45f0
// 0.809344
0x3fe9e624b250b86c
// 1.856407
0x3ffdb3d806503032
// 2.035090
0x400047dd80fc17ed
// 2.207907
0x4001a9caffce45d4
// 0.881589
0x3fec35fae331ee22
// 2.042380
0x400056cb168cbab7

@ -0,0 +1,22 @@
D
10
// 0.129920
0x3fc0a13512307c18
// 0.513409
0x3fe06dd851efeff6
// 0.106515
0x3fbb4490892ca6fc
// 0.440309
0x3fdc2e04ff890360
// 0.717942
0x3fe6f961d81600b0
// 0.326888
0x3fd4ebba22a3aa24
// 0.716218
0x3fe6eb41f5a1e15a
// 0.849533
0x3feb2f5f66c7e669
// 0.242332
0x3fcf04bcf8c08388
// 0.222324
0x3fcc751ae4b0f2e7

@ -0,0 +1,96 @@
#include "StatsTestsF64.h"
#include <stdio.h>
#include "Error.h"
#include "arm_math.h"
#include "Test.h"
#define SNR_THRESHOLD 300
/*
Reference patterns are generated with
a double precision computation.
*/
#define REL_ERROR (1.0e-14)
void StatsTestsF64::test_entropy_f64()
{
const float64_t *inp = inputA.ptr();
const int16_t *dimsp = dims.ptr();
float64_t *refp = ref.ptr();
float64_t *outp = output.ptr();
for(int i=0;i < this->nbPatterns; i++)
{
*outp = arm_entropy_f64(inp,dimsp[i+1]);
outp++;
inp += dimsp[i+1];
}
ASSERT_SNR(ref,output,(float64_t)SNR_THRESHOLD);
ASSERT_REL_ERROR(ref,output,REL_ERROR);
}
void StatsTestsF64::test_kullback_leibler_f64()
{
const float64_t *inpA = inputA.ptr();
const float64_t *inpB = inputB.ptr();
const int16_t *dimsp = dims.ptr();
float64_t *refp = ref.ptr();
float64_t *outp = output.ptr();
for(int i=0;i < this->nbPatterns; i++)
{
*outp = arm_kullback_leibler_f64(inpA,inpB,dimsp[i+1]);
outp++;
inpA += dimsp[i+1];
inpB += dimsp[i+1];
}
ASSERT_SNR(ref,output,(float64_t)SNR_THRESHOLD);
ASSERT_REL_ERROR(ref,output,REL_ERROR);
}
void StatsTestsF64::setUp(Testing::testID_t id,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr)
{
switch(id)
{
case StatsTestsF64::TEST_ENTROPY_F64_1:
{
inputA.reload(StatsTestsF64::INPUT22_F64_ID,mgr);
dims.reload(StatsTestsF64::DIM22_S16_ID,mgr);
ref.reload(StatsTestsF64::REF22_ENTROPY_F64_ID,mgr);
output.create(ref.nbSamples(),StatsTestsF64::OUT_F64_ID,mgr);
const int16_t *dimsp = dims.ptr();
this->nbPatterns=dimsp[0];
}
break;
case StatsTestsF64::TEST_KULLBACK_LEIBLER_F64_2:
{
inputA.reload(StatsTestsF64::INPUTA24_F64_ID,mgr);
inputB.reload(StatsTestsF64::INPUTB24_F64_ID,mgr);
dims.reload(StatsTestsF64::DIM24_S16_ID,mgr);
ref.reload(StatsTestsF64::REF24_KL_F64_ID,mgr);
output.create(ref.nbSamples(),StatsTestsF64::OUT_F64_ID,mgr);
const int16_t *dimsp = dims.ptr();
this->nbPatterns=dimsp[0];
}
break;
}
}
void StatsTestsF64::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
{
output.dump(mgr);
}

@ -95,6 +95,30 @@ group Root {
}
suite Statistics Tests F64 {
class = StatsTestsF64
folder = StatsF64
Pattern INPUT22_F64_ID : Input22_f64.txt
Pattern DIM22_S16_ID : Dims22_s16.txt
Pattern REF22_ENTROPY_F64_ID : RefEntropy22_f64.txt
Pattern INPUTA24_F64_ID : InputA24_f64.txt
Pattern INPUTB24_F64_ID : InputB24_f64.txt
Pattern DIM24_S16_ID : Dims24_s16.txt
Pattern REF24_KL_F64_ID : RefKL24_f64.txt
Output OUT_F64_ID : Output
Output OUT_S16_ID : Index
Output TMP_F64_ID : Temp
Functions {
arm_entropy_f64:test_entropy_f64
arm_kullback_leibler_f64:test_kullback_leibler_f64
}
}
suite Statistics Tests Q31 {
class = StatsTestsQ31
folder = StatsQ31

Loading…
Cancel
Save