Skip to content

Commit 10b4c56

Browse files
ShriramShastrycujomalainey
authored andcommitted
math: Add logarithm base E and base 10
fixpoint math log() and log10() function. logarithm of a number is the power or exponent by which another value must be raised to produce an equivalent value of the given number fix point log10(x) is a derivative of log2(x)/log2(10) and loge(x) is log2(x)/log2(e) Signed-off-by: Shriram Shastry <malladi.sastry@intel.com>
1 parent 28de049 commit 10b4c56

11 files changed

Lines changed: 331 additions & 20 deletions

File tree

src/include/sof/math/base2log.h

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/include/sof/math/log.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* SPDX-License-Identifier: BSD-3-Clause
2+
*
3+
* Copyright(c) 2021 Intel Corporation. All rights reserved.
4+
*
5+
* Author: Shriram Shastry <malladi.sastry@linux.intel.com>
6+
*
7+
*/
8+
9+
#ifndef __SOF_MATH_BASE_LOGARITHM_H__
10+
#define __SOF_MATH_BASE_LOGARITHM_H__
11+
12+
#include <stdint.h>
13+
14+
#define ONE_OVER_LOG2_10 2647887844335ULL /* 1/log2(10),Q1.43 */
15+
#define ONE_OVER_LOG2_E 6096987078286ULL /* 1/log2(exp(1)), Q1.43 */
16+
/* Function Declarations */
17+
int32_t base2_logarithm(uint32_t u);
18+
uint32_t ln_int32(uint32_t numerator);
19+
uint32_t log10_int32(uint32_t numerator);
20+
21+
#endif

src/math/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ if(CONFIG_MATH_DECIBELS)
1818
add_local_sources(sof decibels.c)
1919
endif()
2020

21+
if(CONFIG_NATURAL_LOGARITHM_FIXED)
22+
add_local_sources(sof log_e.c)
23+
endif()
24+
25+
if(CONFIG_COMMON_LOGARITHM_FIXED)
26+
add_local_sources(sof log_10.c)
27+
endif()
28+
2129
if(CONFIG_POWER_FIXED)
2230
add_local_sources(sof power.c)
2331
endif()

src/math/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ config SQRT_FIXED
3838
to calculate square root.square function having positive number
3939
y as input and return the positive number x multiplied by itself (squared)
4040

41+
config NATURAL_LOGARITHM_FIXED
42+
bool "Natural Logarithm function"
43+
default n
44+
help
45+
This option builds Natural Logarithm function (loge(N)) which is the logarithm to
46+
the base e.
47+
48+
config COMMON_LOGARITHM_FIXED
49+
bool "Common Logarithm function"
50+
default n
51+
help
52+
This option builds common Logarithm function (log10(N)) which is the logarithm to
53+
the base 10.
54+
4155
config NUMBERS_GCD
4256
bool "Greatest common divisor"
4357
default n

src/math/base2log.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
//
77
//
88

9-
/* Include Files */
10-
#include <sof/math/base2log.h>
9+
#include <sof/math/log.h>
1110

1211
/* Defines Constant*/
1312
#define BASE2LOG_WRAP_SCHAR_BITS 0xFF

src/math/log_10.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: BSD-3-Clause/
2+
//
3+
// Copyright(c) 2021 Intel Corporation. All rights reserved.
4+
//
5+
// Author: Shriram Shastry <malladi.sastry@linux.intel.com>
6+
//
7+
//
8+
9+
#include <sof/math/log.h>
10+
#include <sof/audio/format.h>
11+
/**
12+
* Base-10 logarithm log10(x)
13+
*
14+
* loge = (u) computes the base-10 logarithm of
15+
* u using lookup table.
16+
* input u must be scalar/real number and positive
17+
*
18+
* +------------------+-----------------+--------+--------+
19+
* | inpfxp |log10(returntype)| inpfxp | loge |
20+
* +----+-----+-------+----+----+-------+--------+--------+
21+
* |WLen| FLen|Signbit|WLen|FLen|Signbit| Qformat| Qformat|
22+
* +----+-----+-------+----+----+-------+--------+--------+
23+
* | 32 | 0 | 0 | 32 | 28 | 0 | 32.0 | 4.28 |
24+
* +------------------+-----------------+--------+--------+
25+
* Arguments : uint32_t numerator [1 to 4294967295, Q32.0]
26+
* Return Type : uint32_t UQ4.28 [0 to 9.6329499409]
27+
*/
28+
uint32_t log10_int32(uint32_t numerator)
29+
{
30+
return((uint32_t)Q_SHIFT_RND((int64_t)base2_logarithm(numerator) *
31+
ONE_OVER_LOG2_10, 63, 32));
32+
}

src/math/log_e.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
//
3+
// Copyright(c) 2021 Intel Corporation. All rights reserved.
4+
//
5+
// Author: Shriram Shastry <malladi.sastry@linux.intel.com>
6+
//
7+
//
8+
9+
#include <sof/math/log.h>
10+
#include <sof/audio/format.h>
11+
/**
12+
* Base-e logarithm loge(x)
13+
*
14+
* loge = (u) computes the base-e logarithm of
15+
* u using lookup table.
16+
* input u must be scalar/real number and positive
17+
*
18+
* +------------------+-----------------+--------+--------+
19+
* | inpfxp |loge (returntype)| inpfxp | loge |
20+
* +----+-----+-------+----+----+-------+--------+--------+
21+
* |WLen| FLen|Signbit|WLen|FLen|Signbit| Qformat| Qformat|
22+
* +----+-----+-------+----+----+-------+--------+--------+
23+
* | 32 | 0 | 0 | 32 | 27 | 0 | 32.0 | 5.27 |
24+
* +------------------+-----------------+--------+--------+
25+
*
26+
* Arguments : uint32_t numerator [1 to 4294967295- Q32.0]
27+
* Return Type : uint32_t UQ5.27 [ 0 to 22.1808076352]
28+
*/
29+
uint32_t ln_int32(uint32_t numerator)
30+
{
31+
return((uint32_t)Q_SHIFT_RND((int64_t)base2_logarithm(numerator) *
32+
ONE_OVER_LOG2_E, 64, 32));
33+
}

test/cmocka/src/math/arithmetic/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@ cmocka_test(square_root
1414
square_root.c
1515
${PROJECT_SOURCE_DIR}/src/math/sqrt_int16.c
1616
)
17+
18+
cmocka_test(base_10_logarithm
19+
base_10_logarithm.c
20+
${PROJECT_SOURCE_DIR}/src/math/log_10.c
21+
${PROJECT_SOURCE_DIR}/src/math/base2log.c
22+
)
23+
24+
cmocka_test(base_e_logarithm
25+
base_e_logarithm.c
26+
${PROJECT_SOURCE_DIR}/src/math/log_e.c
27+
${PROJECT_SOURCE_DIR}/src/math/base2log.c
28+
)

test/cmocka/src/math/arithmetic/base2_logarithm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <cmocka.h>
1414
#include <string.h>
1515

16-
#include <sof/math/base2log.h>
16+
#include <sof/math/log.h>
1717
#include <sof/audio/format.h>
1818
#include <sof/string.h>
1919
#include <sof/common.h>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
//
3+
// Copyright(c) 2021 Intel Corporation. All rights reserved.
4+
//
5+
// Author: Shriram Shastry <malladi.sastry@linux.intel.com>
6+
//
7+
//
8+
9+
#include <stdio.h>
10+
#include <stdint.h>
11+
#include <stdarg.h>
12+
#include <stddef.h>
13+
#include <setjmp.h>
14+
#include <math.h>
15+
#include <cmocka.h>
16+
#include <string.h>
17+
18+
#include <sof/math/log.h>
19+
#include <sof/audio/format.h>
20+
#include <sof/string.h>
21+
#include <sof/common.h>
22+
#include "log2_tables.h"
23+
/* 'Error[max] = 0.0000071279028671,THD = -102.9407645424143993 ' */
24+
/* 'Error[max] = rms(log10() - double(log10_int32()))' */
25+
/* 'THD = 20*log10(Error[max])' */
26+
#define CMP_TOLERANCE 0.0000071279028671
27+
/* Natural logarithm log10(X) reference table generated by matlab/Octave */
28+
/* UQ4.28 */
29+
static const double common_log10_ref_table[] = {
30+
0.0000000000000000, 7.6373246662453802, 7.9383546619093615, 8.1144459209650428,
31+
8.2393846575733427, 8.3362946705813989, 8.4154759166290241, 8.4824227062596371,
32+
8.5404146532373240, 8.5915671756847054, 8.6373246662453802, 8.6787173514036056,
33+
8.7165059122930053, 8.7512680193222625, 8.7834527026386606, 8.8134159259684335,
34+
8.8414446495269665, 8.8677735882125130, 8.8925971719048302, 8.9160782677250818,
35+
8.9383546624098908, 8.9595439614559940, 8.9797473475226131, 8.9990525026982162,
36+
9.0175359083740947, 9.0352646753178405, 9.0522980146012202, 9.0686884307751292,
37+
9.0844826979451199, 9.0997226644895282, 9.1144459212987297, 9.1286863604025754,
38+
9.1424746448781171, 9.1558386064266184, 9.1688035835820649, 9.1813927108816724,
39+
9.1936271672907388, 9.2055263908534872, 9.2171082633890631, 9.2283892737852433,
40+
9.2393846580738721, 9.2501085234534361, 9.2605739571199752, 9.2707931222905753,
41+
9.2807773431865943, 9.2905371804656394, 9.3000824983621975, 9.3094225246070792,
42+
9.3185659040380759, 9.3275207466824899, 9.3362946709818218, 9.3448948427358882,
43+
9.3533280102652014, 9.3616005362239267, 9.3697184264391105, 9.3776873561036460,
44+
9.3855126936091011, 9.3931995222691196, 9.4007526601535094, 9.4081766782268659,
45+
9.4154759169627091, 9.4226545015843630, 9.4297163562280168, 9.4366652161756566,
46+
9.4435046406985137, 9.4502380233502628, 9.4568686022422757, 9.4633994693944423,
47+
9.4698335793932600, 9.4761737574178788, 9.4824227066886628, 9.4885830153874373,
48+
9.4946571630937573, 9.5006475267772306, 9.5065563863821918, 9.5123859300375031,
49+
9.5181382589213257, 9.5238153918078847, 9.5294192693208828, 9.5349517579159713,
50+
9.5404146536127215, 9.5458096854947918, 9.5511385189953373, 9.5564027589832818,
51+
9.5616039526647825, 9.5667435923129869, 9.5718231178381536, 9.5768439193242560,
52+
9.5818073388505756, 9.5867146733402073, 9.5915671761296206, 9.5963660590064990,
53+
9.6011124940261787, 9.6058076152298781, 9.6104525202710605, 9.6150482719557271,
54+
9.6195958997020572, 9.6240964009244330, 9.6285507423464711, 9.6329598611462810};
55+
56+
/* testvector in Q32.0 */
57+
static const uint32_t uv[100] = {
58+
1ULL, 43383509ULL, 86767017ULL, 130150525ULL, 173534033ULL, 216917541ULL,
59+
260301049ULL, 303684557ULL, 347068065ULL, 390451573ULL, 433835081ULL, 477218589ULL,
60+
520602097ULL, 563985605ULL, 607369113ULL, 650752621ULL, 694136129ULL, 737519638ULL,
61+
780903146ULL, 824286654ULL, 867670162ULL, 911053670ULL, 954437178ULL, 997820686ULL,
62+
1041204194ULL, 1084587702ULL, 1127971210ULL, 1171354718ULL, 1214738226ULL, 1258121734ULL,
63+
1301505242ULL, 1344888750ULL, 1388272258ULL, 1431655766ULL, 1475039274ULL, 1518422782ULL,
64+
1561806290ULL, 1605189798ULL, 1648573306ULL, 1691956814ULL, 1735340322ULL, 1778723830ULL,
65+
1822107338ULL, 1865490846ULL, 1908874354ULL, 1952257862ULL, 1995641370ULL, 2039024878ULL,
66+
2082408386ULL, 2125791894ULL, 2169175403ULL, 2212558911ULL, 2255942419ULL, 2299325927ULL,
67+
2342709435ULL, 2386092943ULL, 2429476451ULL, 2472859959ULL, 2516243467ULL, 2559626975ULL,
68+
2603010483ULL, 2646393991ULL, 2689777499ULL, 2733161007ULL, 2776544515ULL, 2819928023ULL,
69+
2863311531ULL, 2906695039ULL, 2950078547ULL, 2993462055ULL, 3036845563ULL, 3080229071ULL,
70+
3123612579ULL, 3166996087ULL, 3210379595ULL, 3253763103ULL, 3297146611ULL, 3340530119ULL,
71+
3383913627ULL, 3427297135ULL, 3470680643ULL, 3514064151ULL, 3557447659ULL, 3600831168ULL,
72+
3644214676ULL, 3687598184ULL, 3730981692ULL, 3774365200ULL, 3817748708ULL, 3861132216ULL,
73+
3904515724ULL, 3947899232ULL, 3991282740ULL, 4034666248ULL, 4078049756ULL, 4121433264ULL,
74+
4164816772ULL, 4208200280ULL, 4251583788ULL, 4294967295ULL};
75+
76+
static void test_math_arithmetic_base10log_fixed(void **state)
77+
{
78+
(void)state;
79+
80+
double clogfxp;
81+
double diff;
82+
int i;
83+
84+
for (i = 0; i < ARRAY_SIZE(common_log10_ref_table); i++) {
85+
clogfxp = log10_int32(uv[i]);
86+
diff = fabs(common_log10_ref_table[i] - (double)clogfxp / (1 << 28));
87+
88+
if (diff > CMP_TOLERANCE) {
89+
printf("%s: diff for %.16f: val = %16d, log10() = %.16f\n", __func__, diff,
90+
uv[i], clogfxp / (1 << 28));
91+
assert_true(diff <= CMP_TOLERANCE);
92+
}
93+
}
94+
}
95+
96+
int main(void)
97+
{
98+
const struct CMUnitTest tests[] = {
99+
cmocka_unit_test(test_math_arithmetic_base10log_fixed)
100+
};
101+
102+
cmocka_set_message_output(CM_OUTPUT_TAP);
103+
104+
return cmocka_run_group_tests(tests, NULL, NULL);
105+
}

0 commit comments

Comments
 (0)