Remove fastmath funktions like discussed on the list.

Add a new header with forward declarations of the SGMath stuff.
This commit is contained in:
frohlich
2006-07-30 07:48:06 +00:00
parent 397ec62180
commit 607987def5
15 changed files with 105 additions and 506 deletions

View File

@@ -247,10 +247,6 @@
RelativePath="..\..\simgear\screen\extensions.hxx"
>
</File>
<File
RelativePath="..\..\simgear\math\fastmath.hxx"
>
</File>
<File
RelativePath="..\..\simgear\timing\geocoord.h"
>
@@ -535,6 +531,14 @@
RelativePath="..\..\simgear\math\SGMath.hxx"
>
</File>
<File
RelativePath="..\..\simgear\math\SGMathFwd.hxx"
>
</File>
<File
RelativePath="..\..\simgear\math\SGCMath.hxx"
>
</File>
<File
RelativePath="..\..\simgear\math\SGMatrix.hxx"
>
@@ -821,10 +825,6 @@
RelativePath="..\..\simgear\screen\extensions.cxx"
>
</File>
<File
RelativePath="..\..\simgear\math\fastmath.cxx"
>
</File>
<File
RelativePath="..\..\simgear\nasal\gc.c"
>

View File

@@ -20,13 +20,14 @@ include_HEADERS = \
sg_random.h \
sg_types.hxx \
vector.hxx \
fastmath.hxx \
SGCMath.hxx \
SGGeoc.hxx \
SGGeod.hxx \
SGGeodesy.hxx \
SGLimits.hxx \
SGMatrix.hxx \
SGMath.hxx \
SGMathFwd.hxx \
SGMisc.hxx \
SGQuat.hxx \
SGVec4.hxx \
@@ -40,7 +41,6 @@ libsgmath_a_SOURCES = \
sg_geodesy.cxx \
sg_random.c \
vector.cxx \
fastmath.cxx \
SGGeodesy.cxx
INCLUDES = -I$(top_srcdir)

31
simgear/math/SGCMath.hxx Normal file
View File

@@ -0,0 +1,31 @@
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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.
//
#ifndef SGCMath_H
#define SGCMath_H
#include <simgear/compiler.h>
#ifdef SG_HAVE_STD_INCLUDES
// We have cmath from the standard c++ lib available
#include <cmath>
#else
// We only have math.h with the c89 double functions.
#include <math.h>
#endif
#endif

View File

@@ -18,12 +18,6 @@
#ifndef SGGeodesy_H
#define SGGeodesy_H
class SGGeoc;
class SGGeod;
template<typename T>
class SGVec3;
class SGGeodesy {
public:
// Hard numbers from the WGS84 standard.

View File

@@ -26,7 +26,4 @@
template<typename T>
class SGLimits : public std::numeric_limits<T> {};
typedef SGLimits<float> SGLimitsf;
typedef SGLimits<double> SGLimitsd;
#endif

View File

@@ -22,6 +22,9 @@
#include <iosfwd>
#include "SGMathFwd.hxx"
#include "SGCMath.hxx"
#include "SGLimits.hxx"
#include "SGMisc.hxx"
#include "SGGeodesy.hxx"

View File

@@ -0,0 +1,52 @@
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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.
//
#ifndef SGMathFwd_H
#define SGMathFwd_H
// All forward declarations in case they only need to be declared
class SGGeoc;
class SGGeod;
template<typename T>
class SGLimits;
template<typename T>
class SGMatrix;
template<typename T>
class SGMisc;
template<typename T>
class SGQuat;
template<typename T>
class SGVec3;
template<typename T>
class SGVec4;
typedef SGLimits<float> SGLimitsf;
typedef SGLimits<double> SGLimitsd;
typedef SGMatrix<float> SGMatrixf;
typedef SGMatrix<double> SGMatrixd;
typedef SGMisc<float> SGMiscf;
typedef SGMisc<double> SGMiscd;
typedef SGQuat<float> SGQuatf;
typedef SGQuat<double> SGQuatd;
typedef SGVec3<float> SGVec3f;
typedef SGVec3<double> SGVec3d;
typedef SGVec4<float> SGVec4f;
typedef SGVec4<double> SGVec4d;
#endif

View File

@@ -22,9 +22,6 @@
template<typename T>
struct TransNegRef;
template<typename T>
class SGMatrix;
/// 3D Matrix Class
template<typename T>
class SGMatrix {
@@ -571,10 +568,6 @@ operator<<(std::basic_ostream<char_type, traits_type>& s, const SGMatrix<T>& m)
return s;
}
/// Two classes doing actually the same on different types
typedef SGMatrix<float> SGMatrixf;
typedef SGMatrix<double> SGMatrixd;
inline
SGMatrixf
toMatrixf(const SGMatrixd& m)

View File

@@ -18,8 +18,6 @@
#ifndef SGMisc_H
#define SGMisc_H
#include <cmath>
template<typename T>
class SGMisc {
public:
@@ -51,6 +49,11 @@ public:
static T deg2rad(const T& val)
{ return val*pi()/180; }
static T round(const T& v)
{ return floor(v + T(0.5)); }
static int roundToInt(const T& v)
{ return int(round(v)); }
#ifndef NDEBUG
/// Returns true if v is a NaN value
/// Use with care: allways code that you do not need to use that!
@@ -71,7 +74,4 @@ public:
#endif
};
typedef SGMisc<float> SGMiscf;
typedef SGMisc<double> SGMiscd;
#endif

View File

@@ -557,10 +557,6 @@ std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGQuat<T>& v)
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << ", " << v(3) << " ]"; }
/// Two classes doing actually the same on different types
typedef SGQuat<float> SGQuatf;
typedef SGQuat<double> SGQuatd;
inline
SGQuatf
toQuatf(const SGQuatd& v)

View File

@@ -328,10 +328,6 @@ std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec3<T>& v)
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << " ]"; }
/// Two classes doing actually the same on different types
typedef SGVec3<float> SGVec3f;
typedef SGVec3<double> SGVec3d;
inline
SGVec3f
toVec3f(const SGVec3d& v)

View File

@@ -280,10 +280,6 @@ std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec4<T>& v)
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << ", " << v(3) << " ]"; }
/// Two classes doing actually the same on different types
typedef SGVec4<float> SGVec4f;
typedef SGVec4<double> SGVec4d;
inline
SGVec4f
toVec4f(const SGVec4d& v)

View File

@@ -1,291 +0,0 @@
/*
* \file fastmath.cxx
* fast mathematics routines.
*
* References:
*
* A Fast, Compact Approximation of the Exponential Function
* Nicol N. Schraudolph
* IDSIA, Lugano, Switzerland
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
*
* Base-2 exp, Laurent de Soras
* http://www.musicdsp.org/archive.php?classid=5#106
*
* Fast log() Function, by Laurent de Soras:
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
*
* Sin, Cos, Tan approximation
* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=115
*
* fast floating point power computation:
* http://playstation2-linux.com/download/adam/power.c
*/
/*
* $Id$
*/
#include <simgear/constants.h>
#include "fastmath.hxx"
/**
* This function is on avarage 9 times faster than the system exp() function
* and has an error of about 1.5%
*/
static union {
double d;
struct {
#if BYTE_ORDER == BIG_ENDIAN
int i, j;
#else
int j, i;
#endif
} n;
} _eco;
double fast_exp(double val) {
const double a = 1048576/M_LN2;
const double b_c = 1072632447; /* 1072693248 - 60801 */
_eco.n.i = (int)(a*val + b_c);
return _eco.d;
}
/*
* Linear approx. between 2 integer values of val. Uses 32-bit integers.
* Not very efficient but faster than exp()
*/
double fast_exp2( const double val )
{
int e;
double ret;
if (val >= 0) {
e = int (val);
ret = val - (e - 1);
#if BYTE_ORDER == BIG_ENDIAN
((*((int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
#else
((*(1 + (int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
#endif
} else {
e = int (val + 1023);
ret = val - (e - 1024);
#if BYTE_ORDER == BIG_ENDIAN
((*((int *) &ret)) &= ~(2047 << 20)) += e << 20;
#else
((*(1 + (int *) &ret)) &= ~(2047 << 20)) += e << 20;
#endif
}
return ret;
}
/*
*
*/
float _fast_log2(const float val)
{
float result, tmp;
float mp = 0.346607f;
result = *(int*)&val;
result *= 1.0/(1<<23);
result = result - 127;
tmp = result - floor(result);
tmp = (tmp - tmp*tmp) * mp;
return tmp + result;
}
float _fast_pow2(const float val)
{
float result;
float mp = 0.33971f;
float tmp = val - floor(val);
tmp = (tmp - tmp*tmp) * mp;
result = val + 127 - tmp;
result *= (1<<23);
*(int*)&result = (int)result;
return result;
}
/**
* While we're on the subject, someone might have use for these as well?
* Float Shift Left and Float Shift Right. Do what you want with this.
*/
void fast_BSL(float &x, register unsigned long shiftAmount) {
*(unsigned long*)&x+=shiftAmount<<23;
}
void fast_BSR(float &x, register unsigned long shiftAmount) {
*(unsigned long*)&x-=shiftAmount<<23;
}
/*
* fastpow(f,n) gives a rather *rough* estimate of a float number f to the
* power of an integer number n (y=f^n). It is fast but result can be quite a
* bit off, since we directly mess with the floating point exponent.
*
* Use it only for getting rough estimates of the values and where precision
* is not that important.
*/
float fast_pow(const float f, const int n)
{
long *lp,l;
lp=(long*)(&f);
l=*lp;l-=0x3F800000l;l<<=(n-1);l+=0x3F800000l;
*lp=l;
return f;
}
float fast_root(const float f, const int n)
{
long *lp,l;
lp=(long*)(&f);
l=*lp;l-=0x3F800000l;l>>=(n-1);l+=0x3F800000l;
*lp=l;
return f;
}
/*
* Code for approximation of cos, sin, tan and inv sin, etc.
* Surprisingly accurate and very usable.
*
* Domain:
* Sin/Cos [0, pi/2]
* Tan [0,pi/4]
* InvSin/Cos [0, 1]
* InvTan [-1, 1]
*/
float fast_sin(const float val)
{
float fASqr = val*val;
float fResult = -2.39e-08f;
fResult *= fASqr;
fResult += 2.7526e-06f;
fResult *= fASqr;
fResult -= 1.98409e-04f;
fResult *= fASqr;
fResult += 8.3333315e-03f;
fResult *= fASqr;
fResult -= 1.666666664e-01f;
fResult *= fASqr;
fResult += 1.0f;
fResult *= val;
return fResult;
}
float fast_cos(const float val)
{
float fASqr = val*val;
float fResult = -2.605e-07f;
fResult *= fASqr;
fResult += 2.47609e-05f;
fResult *= fASqr;
fResult -= 1.3888397e-03f;
fResult *= fASqr;
fResult += 4.16666418e-02f;
fResult *= fASqr;
fResult -= 4.999999963e-01f;
fResult *= fASqr;
fResult += 1.0f;
return fResult;
}
float fast_tan(const float val)
{
float fASqr = val*val;
float fResult = 9.5168091e-03f;
fResult *= fASqr;
fResult += 2.900525e-03f;
fResult *= fASqr;
fResult += 2.45650893e-02f;
fResult *= fASqr;
fResult += 5.33740603e-02f;
fResult *= fASqr;
fResult += 1.333923995e-01f;
fResult *= fASqr;
fResult += 3.333314036e-01f;
fResult *= fASqr;
fResult += 1.0f;
fResult *= val;
return fResult;
}
float fast_asin(float val)
{
float fRoot = sqrt(1.0f-val);
float fResult = -0.0187293f;
fResult *= val;
fResult += 0.0742610f;
fResult *= val;
fResult -= 0.2121144f;
fResult *= val;
fResult += 1.5707288f;
fResult = SGD_PI_2 - fRoot*fResult;
return fResult;
}
float fast_acos(float val)
{
float fRoot = sqrt(1.0f-val);
float fResult = -0.0187293f;
fResult *= val;
fResult += 0.0742610f;
fResult *= val;
fResult -= 0.2121144f;
fResult *= val;
fResult += 1.5707288f;
fResult *= fRoot;
return fResult;
}
float fast_atan(float val)
{
float fVSqr = val*val;
float fResult = 0.0028662257f;
fResult *= fVSqr;
fResult -= 0.0161657367f;
fResult *= fVSqr;
fResult += 0.0429096138f;
fResult *= fVSqr;
fResult -= 0.0752896400f;
fResult *= fVSqr;
fResult += 0.1065626393f;
fResult *= fVSqr;
fResult -= 0.1420889944f;
fResult *= fVSqr;
fResult += 0.1999355085f;
fResult *= fVSqr;
fResult -= 0.3333314528f;
fResult *= fVSqr;
fResult += 1.0f;
fResult *= val;
return fResult;
}

View File

@@ -1,162 +0,0 @@
/*
* \file fastmath.hxx
* fast mathematics routines.
*
* References:
*
* A Fast, Compact Approximation of the Exponential Function
* Nicol N. Schraudolph
* IDSIA, Lugano, Switzerland
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
*
* Fast log() Function, by Laurent de Soras:
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
*
*/
/*
* $Id$
*/
#ifndef _SG_FMATH_HXX
#define _SG_FMATH_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#include <math.h>
double fast_exp(double val);
double fast_exp2(const double val);
float fast_pow(const float val1, const float val2);
float fast_log2(const float cal);
float fast_root(const float f, const int n);
float _fast_pow2(const float cal);
float _fast_log2(const float val);
float fast_sin(const float val);
float fast_cos(const float val);
float fast_tan(const float val);
float fast_asin(const float val);
float fast_acos(const float val);
float fast_atan(const float val);
void fast_BSL(float &x, register unsigned long shiftAmount);
void fast_BSR(float &x, register unsigned long shiftAmount);
inline float fast_log2 (float val)
{
union {
float f;
int i;
} v;
v.f = val;
const int log_2 = ((v.i >> 23) & 255) - 128;
v.i &= ~(255 << 23);
v.i += 127 << 23;
v.f = ((-1.0f/3) * v.f + 2) * v.f - 2.0f/3; // (1)
return (v.f + log_2);
}
/**
* This function is about 3 times faster than the system log() function
* and has an error of about 0.01%
*/
inline float fast_log (const float &val)
{
return (fast_log2 (val) * 0.69314718f);
}
inline float fast_log10 (const float &val)
{
return (fast_log2(val) / 3.321928095f);
}
/**
* This function is about twice as fast as the system pow(x,y) function
*/
inline float fast_pow(const float val1, const float val2)
{
return _fast_pow2(val2 * _fast_log2(val1));
}
/*
* Haven't seen this elsewhere, probably because it is too obvious?
* Anyway, these functions are intended for 32-bit floating point numbers
* only and should work a bit faster than the regular ones.
*/
inline float fast_abs(float f)
{
union {
float f;
int i;
} v;
v.f = f;
v.i = v.i&0x7fffffff;
return v.f;
}
inline float fast_neg(float f)
{
union {
float f;
int i;
} v;
v.f = f;
v.i = v.i^0x80000000;
return v.f;
}
inline int fast_sgn(float f)
{
union {
float f;
int i;
} v;
v.f = f;
return 1+((v.i>>31)<<1);
}
/**
* Quick rounding function.
*/
#if defined(i386)
#define USE_X86_ASM
#endif
#if defined(USE_X86_ASM)
static __inline__ int float_to_int(float f)
{
int r;
__asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
return r;
}
#elif defined(__MSC__) && defined(__WIN32__)
static __inline int float_to_int(float f)
{
int r;
_asm {
fld f
fistp r
}
return r;
}
#else
#define float_to_int(F) ((int) ((F) < 0.0f ? (F)-0.5f : (F)+0.5f))
#endif
#endif // !_SG_FMATH_HXX

View File

@@ -23,28 +23,22 @@
#include <simgear/compiler.h>
#ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
#else
# include <math.h>
#endif
#include <string.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/props/condition.hxx>
#include <simgear/math/fastmath.hxx>
#include <simgear/math/SGMath.hxx>
#include "xmlsound.hxx"
#define LOG_ABS(x) (((x) > 1) ? (x) : (((x) < -1) ? -(x) : 0))
// static double _snd_lin(double v) { return v; }
static double _snd_inv(double v) { return (v == 0) ? 1e99 : 1/v; }
static double _snd_abs(double v) { return (v >= 0) ? v : -v; }
static double _snd_sqrt(double v) { return (v < 0) ? sqrt(-v) : sqrt(v); }
static double _snd_log10(double v) { return fast_log10( LOG_ABS(v) ); }
static double _snd_log(double v) { return fast_log( LOG_ABS(v) ); }
static double _snd_sqrt(double v) { return sqrt(fabs(v)); }
static double _snd_log10(double v) { return log10(fabs(v)); }
static double _snd_log(double v) { return log(fabs(v)); }
// static double _snd_sqr(double v) { return v*v; }
// static double _snd_pow3(double v) { return v*v*v; }