Commit 88240f88 authored by Jonas Stienen's avatar Jonas Stienen

Substituting minus infinity with numeric_limits infinity() for float and double

parent 4510d825
......@@ -51,15 +51,6 @@ namespace ITAConstants
// Epsilon (distance quantization)
static float EPS_F_L = 1.0e-5f; // 10 micro meter
static double EPS_D_L = 1.0e-5f; // 10 micro meter
// Symbolische Konstante für den Verstärkungsfaktor -oo dB
/* TODO: Dies ist hardgecodet eine verdammt große Double-Zahl.
Laut Internet ist die größte negative Zahl -1.79769313486231570 x 10^308.
Am besten wäre hier eine symbolische Minus-Unendlich.
Da muss noch geprüft werden, ob sich so etwas mit double
realisieren lässt [fwe]. */
const double DECIBEL_MINUS_INFINITY = -1.5E-308;
};
#endif // INCLUDE_WATCHER_ITA_CONSTANTS
......@@ -36,19 +36,19 @@
* Existiert keine solche, d.h. ist x keine Zweierpotenz, so
* gibt die Funktion -1 zurück.
*/
ITA_BASE_API int getExp2(unsigned int x);
ITA_BASE_API int getExp2( unsigned int x );
//! Test auf Zweierpotenz
ITA_BASE_API bool isPow2(unsigned int x);
ITA_BASE_API bool isPow2( unsigned int x );
//! Nächstgrößeres Zweierpotenz zurückgeben
ITA_BASE_API unsigned int nextPow2(unsigned int x);
ITA_BASE_API unsigned int nextPow2( unsigned int x );
// Rundung auf Compilern definieren die dies nicht standardmäßig mitliefern
#ifndef HAVE_ROUND
ITA_BASE_API inline double round(double x) { return (x<0 ? ceil((x)-0.5) : floor((x)+0.5)); }
ITA_BASE_API inline float roundf(float x) { return (x<0 ? ceil((x)-0.5f) : floor((x)+0.5f)); }
ITA_BASE_API inline double round( double x ) { return ( x < 0 ? ceil( ( x ) -0.5 ) : floor( ( x ) +0.5 ) ); }
ITA_BASE_API inline float roundf( float x ) { return ( x < 0 ? ceil( ( x ) -0.5f ) : floor( ( x ) +0.5f ) ); }
#endif
//! Nächstkleineres Vielfaches von mul zu einer Zahl x zurückgeben
......@@ -60,7 +60,7 @@ ITA_BASE_API inline float roundf(float x) { return (x<0 ? ceil((x)-0.5f) : floor
* lwrmul(-10, 6) = -12
* lwrmul(10, -6) = 12
*/
ITA_BASE_API int lwrmul(int x, int mul);
ITA_BASE_API int lwrmul( int x, int mul );
//! Nächstgrößeres Vielfaches von mul zu einer Zahl x zurückgeben
/**
......@@ -71,21 +71,21 @@ ITA_BASE_API int lwrmul(int x, int mul);
* uprmul(-10, 6) = -6
* uprmul(10, -6) = 12
*/
ITA_BASE_API int uprmul(int x, int mul);
ITA_BASE_API int uprmul( int x, int mul );
//! Nächstkleineres Vielfaches von mul zu einer Zahl x zurückgeben
/**
* Beispiele: lwrmulu(10, 5) = 10
* lwrmulu(10, 6) = 6
*/
ITA_BASE_API unsigned int lwrmulu(unsigned int x, unsigned int mul);
ITA_BASE_API unsigned int lwrmulu( unsigned int x, unsigned int mul );
//! Nächstgrößeres Vielfaches von mul zu einer Zahl x zurückgeben
/**
* Beispiele: uprmulu(10, 5) = 10
* uprmulu(10, 6) = 12
*/
ITA_BASE_API unsigned int uprmulu(unsigned int x, unsigned int mul);
ITA_BASE_API unsigned int uprmulu( unsigned int x, unsigned int mul );
//! Aufrundende Ganzzahl-Division
/**
......@@ -93,16 +93,16 @@ ITA_BASE_API unsigned int uprmulu(unsigned int x, unsigned int mul);
* (d.h. es bleibt ein Rest a mod b != 0 übrig), so wird c um
* eins inkrementiert. Danach gibt die Funktion c zurück
*
* Anwendungen: Wieviele Blöcke der Länge b sind erforderlich
* Anwendungen: Wieviele Blöcke der Länge b sind erforderlich
* um ein Signal der Länge l zu beschreiben: uprdiv(l, b)
*/
ITA_BASE_API int uprdiv(int a, int b);
ITA_BASE_API int uprdiv( int a, int b );
//! Aufrundende Ganzzahl-Division
/**
* Variante von uprdiv für vorzeichenlose Ganzzahlen.
*/
ITA_BASE_API unsigned int uprdivu(unsigned int a, unsigned int b);
ITA_BASE_API unsigned int uprdivu( unsigned int a, unsigned int b );
//! Einen (beliebigen) Winkel ins Interval (-180,180] abbilden
/**
......@@ -110,13 +110,13 @@ ITA_BASE_API unsigned int uprdivu(unsigned int a, unsigned int b);
* \note Der exakte Wert -180 wird durch die Funktion erhalten
* und nicht auf +180 abgebildet (Ästethik :-))
*/
ITA_BASE_API float correctAngle180(float phi);
ITA_BASE_API float correctAngle180( float phi );
//! Einen (beliebigen) Winkel ins Interval [0,360) abbilden
/**
* Beispiel: correctAngle(380°) = 20°
*/
ITA_BASE_API float correctAngle360(float phi);
ITA_BASE_API float correctAngle360( float phi );
//! Verhältnis in Dezibel (Energie) (im 10er-Logarithmus) umrechnen
/**
......@@ -126,7 +126,7 @@ ITA_BASE_API float correctAngle360(float phi);
* \note Für die symbolische Konstante DECIBEL_MINUS_INFINITY gibt die
* Funktion den Wert 0 zurück.
*/
ITA_BASE_API double db10_to_ratio(double db);
ITA_BASE_API double db10_to_ratio( const double db );
//! Dezibel (Energie) (im 10er-Logarithmus) in Verhältnis umrechnen
/**
......@@ -139,7 +139,7 @@ ITA_BASE_API double db10_to_ratio(double db);
* \important Negative Verhältnisse sind nicht erlaubt. In diesem
* Falle wird eine ITAException (INVALID_PARAMETER) ausgelöst!
*/
ITA_BASE_API double ratio_to_db10(double r);
ITA_BASE_API double ratio_to_db10( const double r );
//! Verhältnis in Dezibel (Spannung) (im 10er-Logarithmus) umrechnen
......@@ -150,7 +150,7 @@ ITA_BASE_API double ratio_to_db10(double r);
* \note Für die symbolische Konstante DECIBEL_MINUS_INFINITY gibt die
* Funktion den Wert 0 zurück.
*/
ITA_BASE_API double db20_to_ratio(double db);
ITA_BASE_API double db20_to_ratio( const double db );
//! Dezibel (Spannung) (im 10er-Logarithmus) in Verhältnis umrechnen
/**
......@@ -163,7 +163,7 @@ ITA_BASE_API double db20_to_ratio(double db);
* \important Negative Verhältnisse sind nicht erlaubt. In diesem
* Falle wird eine ITAException (INVALID_PARAMETER) ausgelöst!
*/
ITA_BASE_API double ratio_to_db20(double r);
ITA_BASE_API double ratio_to_db20( const double r );
/* +------------------------------------+
| |
......@@ -175,13 +175,13 @@ ITA_BASE_API double ratio_to_db20(double r);
ITA_BASE_API float cabsf( float re, float im );
//! Phase einer komplexen Zahl berechnen
ITA_BASE_API float canglef(float re, float im);
ITA_BASE_API float canglef( float re, float im );
//! Betrag einer komplexen Zahl setzen, deren Phase aber erhalten (auch in-place)
ITA_BASE_API void csabsparg(const float& in_re, const float& in_im, const float& dest_abs, float& out_re, float& out_im);
ITA_BASE_API void csabsparg( const float& in_re, const float& in_im, const float& dest_abs, float& out_re, float& out_im );
//! Winkel einer komplexen Zahl setzen, deren Betrag aber erhalten (auch in-place)
ITA_BASE_API void csargpabs(const float& in_re, const float& in_im, const float& dest_arg, float& out_re, float& out_im);
ITA_BASE_API void csargpabs( const float& in_re, const float& in_im, const float& dest_arg, float& out_re, float& out_im );
/* +---------------------------+
| |
......@@ -190,16 +190,16 @@ ITA_BASE_API void csargpabs(const float& in_re, const float& in_im, const float&
+---------------------------+ */
//! Winkel im Bogenmaß in Grad [°] umrechnen
ITA_BASE_API float rad2gradf(float phi);
ITA_BASE_API float rad2gradf( float phi );
//! Winkel im Bogenmaß in Grad [°] umrechnen
ITA_BASE_API double rad2grad(double phi);
ITA_BASE_API double rad2grad( double phi );
//! Winkel in Grad [°] ins Bogenmaß umrechnen
ITA_BASE_API float grad2radf(float phi);
ITA_BASE_API float grad2radf( float phi );
//! Winkel im Bogenmaß in Grad [°] umrechnen
ITA_BASE_API double grad2rad(double phi);
ITA_BASE_API double grad2rad( double phi );
/* ---------- RAD ----------- */
......@@ -207,12 +207,12 @@ ITA_BASE_API double grad2rad(double phi);
//! Einen Winkel (rad) in das Intervall [0, 2PI) projezieren
/**
* Projeziert einen Winkel in Rad [rad] (nicht Grad) in das Intervall [0,2*PI) und
* setzt somit negative Winkel (gegen den UZS) in positive (im UZS) um und entfernt
* setzt somit negative Winkel (gegen den UZS) in positive (im UZS) um und entfernt
* Mehrfachumdrehungen.
*
* Beispiele: 0->0, 2*PI->0, (-2*PI)->0, (2*PI+0.1)->0.1, (-0.1)->(2*PI-0.1)
*/
ITA_BASE_API float anglef_proj_0_2PI(float alpha);
ITA_BASE_API float anglef_proj_0_2PI( float alpha );
//! Einen Winkel (rad) in das Intervall (-PI, PI] projezieren
/**
......@@ -223,7 +223,7 @@ ITA_BASE_API float anglef_proj_0_2PI(float alpha);
*
* Beispiele: 0->0, 2*PI->0, (-2*PI)->0, (PI+0.1)->(-PI+0.1), (-PI-0.1)->(PI-0.1)
*/
ITA_BASE_API float anglef_proj_NPI_PI(float alpha);
ITA_BASE_API float anglef_proj_NPI_PI( float alpha );
//! (Gerichtete) minimale Winkeldifferenz für zwei Winkel [rad] (nicht Grad) im Intervall [0,2PI)
/**
......@@ -244,7 +244,7 @@ ITA_BASE_API float anglef_proj_NPI_PI(float alpha);
*
* Beispiele: (0,PI/2) -> PI/2, (PI/5,PI/4) -> PI/20, (PI/3,PI/4) -> -PI/12, (0,2*PI-0.1) -> -0.1
*/
ITA_BASE_API float anglef_mindiff_0_2PI(float alpha, float beta);
ITA_BASE_API float anglef_mindiff_0_2PI( float alpha, float beta );
//! Absolute minimale Winkeldifferenz für zwei Winkel [rad] im Intervall [0,2PI)
/**
......@@ -258,19 +258,19 @@ ITA_BASE_API float anglef_mindiff_0_2PI(float alpha, float beta);
*
* Beispiele: (0,PI/2) -> PI/2, (PI/2,PI/3) -> PI/6, (PI/3,PI/2) -> PI/6, (0,2*PI-0.1) -> 0.1
*/
ITA_BASE_API float anglef_mindiff_abs_0_2PI(float alpha, float beta);
ITA_BASE_API float anglef_mindiff_abs_0_2PI( float alpha, float beta );
/* ---------- GRAD ---------- */
//! Einen Winkel [°] in das Intervall [0°,360°) projezieren
/**
* Projeziert einen Winkel in Grad [°] (nicht Bogenmaß) in das Intervall [0°,360°) und
* setzt somit negative Winkel (gegen den UZS) in positive (im UZS) um und entfernt
* setzt somit negative Winkel (gegen den UZS) in positive (im UZS) um und entfernt
* Mehrfachumdrehungen.
*
* Beispiele: 0°->0°, 360°->0°, -360°->0°, 361°->1°, -1°->359°
*/
ITA_BASE_API float anglef_proj_0_360_DEG(float alpha);
ITA_BASE_API float anglef_proj_0_360_DEG( float alpha );
//! Einen Winkel (°) in das Intervall (-180°, 180°] projezieren
/**
......@@ -281,7 +281,7 @@ ITA_BASE_API float anglef_proj_0_360_DEG(float alpha);
*
* Beispiele: 0°->0°, 360°->0°, -360°->0°, 181°->-179°, -181°->179°
*/
ITA_BASE_API float anglef_proj_N180_180_DEG(float alpha);
ITA_BASE_API float anglef_proj_N180_180_DEG( float alpha );
//! (Gerichtete) minimale Winkeldifferenz für zwei Winkel [°] im Intervall [0°,360°)
/**
......@@ -302,7 +302,7 @@ ITA_BASE_API float anglef_proj_N180_180_DEG(float alpha);
*
* Beispiele: (0°,90°) -> 90°, (45°,70°) -> 25°, (70°,45°) -> -25°, (0°,359°) -> -1°
*/
ITA_BASE_API float anglef_mindiff_0_360_DEG(float alpha, float beta);
ITA_BASE_API float anglef_mindiff_0_360_DEG( float alpha, float beta );
//! Absolute minimale Winkeldifferenz für zwei Winkel [°] im Intervall [0°,360°)
/**
......@@ -316,28 +316,28 @@ ITA_BASE_API float anglef_mindiff_0_360_DEG(float alpha, float beta);
*
* Beispiele: (0°,90°) -> 90°, (45°,70°) -> 25°, (70°,45°) -> 25°, (0°,359°) -> 1°
*/
ITA_BASE_API float anglef_mindiff_abs_0_360_DEG(float alpha, float beta);
ITA_BASE_API float anglef_mindiff_abs_0_360_DEG( float alpha, float beta );
// Orientierung in Yaw-Pitch-Roll Winkeln in View-Up-Vektor umrechnen (Alle Winkel in Bogenmaß)
ITA_BASE_API void convertYPR2VU(const double yaw, const double pitch, const double roll,
double& vx, double& vy, double& vz,
double& ux, double& uy, double& uz);
ITA_BASE_API void convertYPR2VU( const double yaw, const double pitch, const double roll,
double& vx, double& vy, double& vz,
double& ux, double& uy, double& uz );
// Orientierung in Yaw-Pitch-Roll Winkeln in View-Up-Vektor umrechnen (Alle Winkel in Bogenmaß)
ITA_BASE_API void convertYPR2VU(const float yaw, const float pitch, const float roll,
float& vx, float& vy, float& vz,
float& ux, float& uy, float& uz);
ITA_BASE_API void convertYPR2VU( const float yaw, const float pitch, const float roll,
float& vx, float& vy, float& vz,
float& ux, float& uy, float& uz );
// Orientierung in View-Up-Vektor in Yaw-Pitch-Roll Winkeln umrechnen (Alle Winkel in Bogenmaß)
ITA_BASE_API void convertVU2YPR(const double vx, const double vy, const double vz,
ITA_BASE_API void convertVU2YPR( const double vx, const double vy, const double vz,
const double ux, const double uy, const double uz,
double& yaw, double& pitch, double& roll);
double& yaw, double& pitch, double& roll );
// Orientierung in View-Up-Vektor in Yaw-Pitch-Roll Winkeln umrechnen (Alle Winkel in Bogenmaß)
ITA_BASE_API void convertVU2YPR(const float vx, const float vy, const float vz,
ITA_BASE_API void convertVU2YPR( const float vx, const float vy, const float vz,
const float ux, const float uy, const float uz,
float& yaw, float& pitch, float& roll);
float& yaw, float& pitch, float& roll );
// Datenklasse für Fehlerwerte
template <typename T>
......@@ -349,24 +349,24 @@ public:
int indexMaxAbsError; // Index of element where max abs error
ErrorValues() : minAbsError(0), avgAbsError(0), maxAbsError(0), indexMaxAbsError(0) {}
ErrorValues() : minAbsError( 0 ), avgAbsError( 0 ), maxAbsError( 0 ), indexMaxAbsError( 0 ) {}
};
// Fehler zwischen zwei Vektoren berechnen
template <typename Tc, typename Ta, typename Tb>
ErrorValues<Tc> computeErrorValues(const Ta* A, const Tb* B, int size)
ErrorValues<Tc> computeErrorValues( const Ta* A, const Tb* B, int size )
{
ErrorValues<Tc> v;
if (size == 0) return v;
if( size == 0 ) return v;
Tb absErr = std::abs( (Tc) A[0] - (Tc) B[0] );
Tb absErr = std::abs( ( Tc ) A[ 0 ] - ( Tc ) B[ 0 ] );
v.minAbsError = v.avgAbsError = v.maxAbsError = absErr;
for (int i=1; i<size; ++i) {
absErr = std::abs( (Tc) A[i] - (Tc) B[i] );
v.minAbsError = std::min(v.minAbsError, absErr);
if (absErr > v.maxAbsError) {
for( int i = 1; i < size; ++i ) {
absErr = std::abs( ( Tc ) A[ i ] - ( Tc ) B[ i ] );
v.minAbsError = std::min( v.minAbsError, absErr );
if( absErr > v.maxAbsError ) {
v.maxAbsError = absErr;
v.indexMaxAbsError = i;
}
......@@ -385,44 +385,45 @@ ErrorValues<Tc> computeErrorValues(const Ta* A, const Tb* B, int size)
+-----------------------+ */
// Fills a vector with numbers dest = { a+n*s < b | n in N }
template <typename T> void linspace(std::vector<T>& dest, T a, T b, T s=1) {
template <typename T> void linspace( std::vector<T>& dest, T a, T b, T s = 1 ) {
dest.clear();
if (s==0) {
dest.push_back(a);
if( s == 0 ) {
dest.push_back( a );
return;
}
if (s<0) {
if (a<b) return; // No elements contained
dest.reserve( (a-b)/s + 1 );
for (T x=a; x>=b; x+=s) dest.push_back(x);
} else {
if (a>b) return; // No elements contained
dest.reserve( (b-a)/s + 1 );
for (T x=a; x<=b; x+=s) dest.push_back(x);
if( s < 0 ) {
if( a < b ) return; // No elements contained
dest.reserve( ( a - b ) / s + 1 );
for( T x = a; x >= b; x += s ) dest.push_back( x );
}
else {
if( a > b ) return; // No elements contained
dest.reserve( ( b - a ) / s + 1 );
for( T x = a; x <= b; x += s ) dest.push_back( x );
}
};
// Fills a vector with powers of two in the range a=2^i <= 2^j <= 2^k=b
// (Note a and b must be powers of two, otherwise an exception is thrown)
ITA_BASE_API void pow2space(std::vector<int>& dest, int a, int b);
ITA_BASE_API void pow2space( std::vector<int>& dest, int a, int b );
// Calculates the factorial of an positive integer m
ITA_BASE_API int factorial(int m);
ITA_BASE_API int factorial( int m );
//Calculates the normalizing constant for SHRealvaluedBasefunctions
ITA_BASE_API double SHNormalizeConst(int m, int n);
ITA_BASE_API double SHNormalizeConst( int m, int n );
//Calculates the Kronecker delta
ITA_BASE_API int SHKronecker(int m);
ITA_BASE_API int SHKronecker( int m );
// Returns the index of a basefunction with degree m and order n
ITA_BASE_API int SHDegreeOrder2Linear(int m, int n);
ITA_BASE_API int SHDegreeOrder2Linear( int m, int n );
//Calculates the realvalued Basefunctions of SH for e.g. Ambisonics
ITA_BASE_API std::vector<double> SHRealvaluedBasefunctions(double elevation, double azimuth, int maxOrder);
ITA_BASE_API std::vector<double> SHRealvaluedBasefunctions( double elevation, double azimuth, int maxOrder );
//Calculates the associated legendre polynomials
ITA_BASE_API std::vector<double> SHAssociatedLegendre(int N, double mu);
ITA_BASE_API std::vector<double> SHAssociatedLegendre( int N, double mu );
#endif // INCLUDE_WATCHER_ITA_NUMERIC_UTILS
......@@ -3,6 +3,8 @@
#include <ITAConstants.h>
#include <ITAException.h>
#include <numeric>
using namespace ITAConstants;
int getExp2(unsigned int x) {
......@@ -117,26 +119,34 @@ float correctAngle360(float phi) {
return fmodf(phi, 360.0f);
}
double db10_to_ratio(double db) {
return (db == DECIBEL_MINUS_INFINITY ? 0 : pow(10, db/10.0));
double db10_to_ratio( const double db )
{
return ( db == -std::numeric_limits< double >::infinity() ? 0.0f : pow( 10.0f, db / 10.0f ) );
}
double ratio_to_db10(double r) {
if (r < 0) ITA_EXCEPT0(INVALID_PARAMETER);
return (r == 0 ? DECIBEL_MINUS_INFINITY : 10*log10(r));
double db20_to_ratio( const double db )
{
return ( db == -std::numeric_limits< double >::infinity() ? 0.0f : pow( 10.0f, db / 20.0f ) );
}
double db20_to_ratio(double db) {
return (db == DECIBEL_MINUS_INFINITY ? 0 : pow(10, db/20.0));
double ratio_to_db10( const double r )
{
if( r < 0.0f )
ITA_EXCEPT1( INVALID_PARAMETER, "Conversion to decibel not possible for negative values" );
if( r == 0.0f )
return -std::numeric_limits< double >::infinity();
else
return 10.0f * log10( r );
}
double ratio_to_db20( double r )
double ratio_to_db20( const double r )
{
if( r < 0.0f )
ITA_EXCEPT1( INVALID_PARAMETER, "Conversion to decibel not possible for negative values" );
if( r == 0.0f )
return DECIBEL_MINUS_INFINITY;
return -std::numeric_limits< double >::infinity();
else
return 20.0f * log10( r );
}
......
This diff is collapsed.
......@@ -50,10 +50,20 @@ void test_ratio_to_db()
CITAThirdOctaveMagnitudeSpectrum oTOSpectrumConvertToRatio;
oTOSpectrumConvertToRatio.SetName( "Test unit gain spectrum to db" );
oTOSpectrumConvertToRatio.SetValueUnit( "(gain)" );
oTOSpectrumConvertToRatio.SetZero();
oTOSpectrumConvertToRatio.SetIdentity(); // db -> all zeros
for( int n = 0; n < oTOSpectrumConvertToRatio.GetNumBands(); n++ )
oTOSpectrumConvertToRatio[ n ] = ratio_to_db10( oTOSpectrumConvertToRatio[ n ] ); // zero to db -> -inf
oTOSpectrumConvertToRatio.SetValueUnit( "dB" );
cout << oTOSpectrumConvertToRatio << endl;
// Convert gains "1"
oTOSpectrumConvertToRatio.SetIdentity(); // db -> all zeros
oTOSpectrumConvertToRatio.Add( 1.0f ); // gains now all 1.0
for( int n = 0; n < oTOSpectrumConvertToRatio.GetNumBands(); n++ )
oTOSpectrumConvertToRatio[ n ] = ratio_to_db10( oTOSpectrumConvertToRatio[ n ] );
oTOSpectrumConvertToRatio[ n ] = ratio_to_db10( oTOSpectrumConvertToRatio[ n ] ); // ratio 1 to db -> 0
oTOSpectrumConvertToRatio.SetValueUnit( "dB" );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment