forked from jhjourdan/SIMD-math-prims
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathicsilog.h
73 lines (65 loc) · 4.18 KB
/
icsilog.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#ifndef __ICSI_LOG__
#define __ICSI_LOG__
////////////////////////////////////////////////////////////////////////////////////
// ICSIlog Copyright taken from ICSIlog source //
// Copyright (C) 2007 International Computer Science Institute //
// 1947 Center Street, Suite 600 //
// Berkeley, CA 94704 //
// //
// Contact information: //
// Oriol Vinyals [email protected] //
// Gerald Friedland [email protected] //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License along //
// with this program; if not, write to the Free Software Foundation, Inc., //
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. //
// //
// Authors //
// ------- //
// //
// Oriol Vinyals [email protected] //
// Gerald Friedland [email protected] //
// //
// Acknowledgements //
// ---------------- //
// //
// Thanks to Harrison Ainsworth ([email protected]) for his idea that //
// doubled the accuracy. //
////////////////////////////////////////////////////////////////////////////////////
// ICSIlog V 2.0
const std::vector<float> fill_icsi_log_table2(const unsigned int precision) {
std::vector<float> pTable(static_cast<size_t>(pow(2,precision)));
// step along table elements and x-axis positions
// (start with extra half increment, so the steps intersect at their midpoints.)
float oneToTwo = 1.0f + (1.0f / (float)( 1 <<(precision + 1) ));
for(int i = 0; i < (1 << precision); ++i ) {
// make y-axis value for table element
pTable[i] = logf(oneToTwo) / 0.69314718055995f;
oneToTwo += 1.0f / (float)( 1 << precision );
}
return pTable;
}
// ICSIlog v2.0
inline float icsi_log(const float val) {
const unsigned int precision(10);
static std::vector<float> pTable = fill_icsi_log_table2(precision);
// get access to float bits
static_assert(sizeof(int)==sizeof(float),"int and float are not the same size.");
const int* const pVal = reinterpret_cast<const int*>(&val);
// extract exponent and mantissa (quantized)
const int exp = ((*pVal >> 23) & 255) - 127;
const int man = (*pVal & 0x7FFFFF) >> (23 - precision);
// exponent plus lookup refinement
return ((float)(exp) + pTable[man]) * 0.69314718055995f;
}
#endif