COMMON: Cos/Sin Table switch internal structure so at() is faster
A new internal table has been added so that no if checks need to be performed for the at() lookup. The old table can still be accessed using getTable or atLegacy(). at() and atLegacy() return the same values, but at() is faster.
This commit is contained in:
parent
cf99bb0a5e
commit
51c11efbbc
4 changed files with 55 additions and 20 deletions
|
@ -34,35 +34,45 @@ CosineTable::CosineTable(int nPoints) {
|
||||||
_nPoints = nPoints;
|
_nPoints = nPoints;
|
||||||
_radResolution = 2.0 * M_PI / _nPoints;
|
_radResolution = 2.0 * M_PI / _nPoints;
|
||||||
_refSize = _nPoints / 4;
|
_refSize = _nPoints / 4;
|
||||||
_table = new float[_nPoints / 2];
|
_tableEOS = new float[_nPoints / 2];
|
||||||
|
_table = new float[_nPoints];
|
||||||
|
|
||||||
|
for (int i = 0; i < _nPoints; i++)
|
||||||
|
_table[i] = cos(i * _radResolution);
|
||||||
|
|
||||||
// Table contains cos(2*pi*i/_nPoints) for 0<=i<=_nPoints/4,
|
// Table contains cos(2*pi*i/_nPoints) for 0<=i<=_nPoints/4,
|
||||||
// followed by 3_nPoints/4<=i<_nPoints
|
// followed by 3_nPoints/4<=i<_nPoints
|
||||||
for (int i = 0; i <= _nPoints / 4; i++)
|
for (int i = 0; i <= _nPoints / 4; i++)
|
||||||
_table[i] = cos(i * _radResolution);
|
_tableEOS[i] = cos(i * _radResolution);
|
||||||
|
|
||||||
for (int i = 1; i < _nPoints / 4; i++)
|
for (int i = 1; i < _nPoints / 4; i++)
|
||||||
_table[_nPoints / 2 - i] = _table[i];
|
_tableEOS[_nPoints / 2 - i] = _tableEOS[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
float CosineTable::at(int index) const {
|
float CosineTable::at(int index) const {
|
||||||
|
assert((index >= 0) && (index < _nPoints));
|
||||||
|
return _table[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
float CosineTable::atLegacy(int index) const {
|
||||||
assert((index >= 0) && (index < _nPoints));
|
assert((index >= 0) && (index < _nPoints));
|
||||||
if (index < _refSize)
|
if (index < _refSize)
|
||||||
// [0,pi/2)
|
// [0,pi/2)
|
||||||
return _table[index];
|
return _tableEOS[index];
|
||||||
if ((index > _refSize) && (index < 2 * _refSize))
|
if ((index > _refSize) && (index < 2 * _refSize))
|
||||||
// (pi/2,pi)
|
// (pi/2,pi)
|
||||||
return -_table[2 * _refSize - index];
|
return -_tableEOS[2 * _refSize - index];
|
||||||
if ((index >= 2 * _refSize) && (index < 3 * _refSize))
|
if ((index >= 2 * _refSize) && (index < 3 * _refSize))
|
||||||
// [pi,3/2pi)
|
// [pi,3/2pi)
|
||||||
return -_table[index - 2 * _refSize];
|
return -_tableEOS[index - 2 * _refSize];
|
||||||
if ((index > 3 * _refSize) && (index < _nPoints))
|
if ((index > 3 * _refSize) && (index < _nPoints))
|
||||||
// (3/2pi,2pi)
|
// (3/2pi,2pi)
|
||||||
return _table[_nPoints - index];
|
return _tableEOS[_nPoints - index];
|
||||||
return 0.0f; // cos(pi/2) and cos(3pi/2) = 0
|
return 0.0f; // cos(pi/2) and cos(3pi/2) = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
CosineTable::~CosineTable() {
|
CosineTable::~CosineTable() {
|
||||||
|
delete[] _tableEOS;
|
||||||
delete[] _table;
|
delete[] _table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,15 +46,23 @@ public:
|
||||||
* - Entries (excluding) nPoints/4 up to nPoints/2:
|
* - Entries (excluding) nPoints/4 up to nPoints/2:
|
||||||
* (excluding) cos(3/2*pi) till (excluding) cos(2*pi)
|
* (excluding) cos(3/2*pi) till (excluding) cos(2*pi)
|
||||||
*/
|
*/
|
||||||
const float *getTable() { return _table; }
|
const float *getTable() { return _tableEOS; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns cos(2*pi * index / nPoints )
|
||||||
|
* Index must be in range [0, nPoints - 1]
|
||||||
|
* Faster than atLegacy
|
||||||
|
*/
|
||||||
|
float at(int index) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns cos(2*pi * index / nPoints )
|
* Returns cos(2*pi * index / nPoints )
|
||||||
* Index must be in range [0, nPoints - 1]
|
* Index must be in range [0, nPoints - 1]
|
||||||
*/
|
*/
|
||||||
float at(int index) const;
|
float atLegacy(int index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
float *_tableEOS;
|
||||||
float *_table;
|
float *_table;
|
||||||
double _radResolution; // Smallest radian increment
|
double _radResolution; // Smallest radian increment
|
||||||
int _refSize; // _nPoints / 4
|
int _refSize; // _nPoints / 4
|
||||||
|
|
|
@ -34,39 +34,48 @@ SineTable::SineTable(int nPoints) {
|
||||||
_nPoints = nPoints;
|
_nPoints = nPoints;
|
||||||
_radResolution = 2.0 * M_PI / _nPoints;
|
_radResolution = 2.0 * M_PI / _nPoints;
|
||||||
_refSize = _nPoints / 4;
|
_refSize = _nPoints / 4;
|
||||||
_table = new float[_nPoints / 2];
|
_tableEOS = new float[_nPoints / 2];
|
||||||
|
_table = new float[_nPoints];
|
||||||
|
|
||||||
|
for (int i = 0; i < _nPoints; i++)
|
||||||
|
_table[i] = sin(i * _radResolution);
|
||||||
|
|
||||||
// Table contains sin(2*pi*i/_nPoints) for 0<=i<_nPoints/4,
|
// Table contains sin(2*pi*i/_nPoints) for 0<=i<_nPoints/4,
|
||||||
// followed by _nPoints/2<=i<3_nPoints/4
|
// followed by _nPoints/2<=i<3_nPoints/4
|
||||||
for (int i = 0; i < _nPoints / 4; i++)
|
for (int i = 0; i < _nPoints / 4; i++)
|
||||||
_table[i] = sin(i * _radResolution);
|
_tableEOS[i] = sin(i * _radResolution);
|
||||||
|
|
||||||
for (int i = 0; i < _nPoints / 4; i++)
|
for (int i = 0; i < _nPoints / 4; i++)
|
||||||
_table[_nPoints / 4 + i] = -_table[i];
|
_tableEOS[_nPoints / 4 + i] = -_tableEOS[i];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float SineTable::at(int index) const {
|
float SineTable::at(int index) const {
|
||||||
|
assert((index >= 0) && (index < _nPoints));
|
||||||
|
return _table[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
float SineTable::atLegacy(int index) const {
|
||||||
assert((index >= 0) && (index < _nPoints));
|
assert((index >= 0) && (index < _nPoints));
|
||||||
if (index < _refSize)
|
if (index < _refSize)
|
||||||
// [0,pi/2)
|
// [0,pi/2)
|
||||||
return _table[index];
|
return _tableEOS[index];
|
||||||
if (index == _refSize)
|
if (index == _refSize)
|
||||||
// pi/2
|
// pi/2
|
||||||
return 1.0f; // sin(pi/2) = 1.0
|
return 1.0f; // sin(pi/2) = 1.0
|
||||||
if ((index > _refSize) && (index < 2 * _refSize))
|
if ((index > _refSize) && (index < 2 * _refSize))
|
||||||
// (pi/2,pi)
|
// (pi/2,pi)
|
||||||
return _table[2 * _refSize - index];
|
return _tableEOS[2 * _refSize - index];
|
||||||
if ((index >= 2 * _refSize) && (index < 3 * _refSize))
|
if ((index >= 2 * _refSize) && (index < 3 * _refSize))
|
||||||
// [pi,3/2pi)
|
// [pi,3/2pi)
|
||||||
return -_table[index - 2 * _refSize];
|
return -_tableEOS[index - 2 * _refSize];
|
||||||
if ((index > 3 * _refSize) && (index < _nPoints))
|
if ((index > 3 * _refSize) && (index < _nPoints))
|
||||||
// (3/2pi,2pi)
|
// (3/2pi,2pi)
|
||||||
return -_table[_nPoints - index];
|
return -_tableEOS[_nPoints - index];
|
||||||
return -1.0f; // sin(3pi/2) = -1.0
|
return -1.0f; // sin(3pi/2) = -1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
SineTable::~SineTable() {
|
SineTable::~SineTable() {
|
||||||
|
delete[] _tableEOS;
|
||||||
delete[] _table;
|
delete[] _table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,15 +46,23 @@ public:
|
||||||
* - Entries 2_nPoints/4 up to nPoints/2:
|
* - Entries 2_nPoints/4 up to nPoints/2:
|
||||||
* sin(pi) till (excluding) sin(3/2*pi)
|
* sin(pi) till (excluding) sin(3/2*pi)
|
||||||
*/
|
*/
|
||||||
const float *getTable() { return _table; }
|
const float *getTable() { return _tableEOS; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns sin(2*pi * index / nPoints )
|
||||||
|
* Index must be in range [0, nPoints - 1]
|
||||||
|
* Faster than atLegacy
|
||||||
|
*/
|
||||||
|
float at(int index) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns sin(2*pi * index / nPoints )
|
* Returns sin(2*pi * index / nPoints )
|
||||||
* Index must be in range [0, nPoints - 1]
|
* Index must be in range [0, nPoints - 1]
|
||||||
*/
|
*/
|
||||||
float at(int index) const;
|
float atLegacy(int index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
float *_tableEOS;
|
||||||
float *_table;
|
float *_table;
|
||||||
double _radResolution; // Smallest radian increment
|
double _radResolution; // Smallest radian increment
|
||||||
int _refSize; // _nPoints / 4
|
int _refSize; // _nPoints / 4
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue