tdf#157794 refactor Complex to use std::complex where possible
Change-Id: Ie583399977caf266e3cc0a3cb78462be4cd63151 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160394 Tested-by: Jenkins Reviewed-by: Eike Rathke <erack@redhat.com>
This commit is contained in:
parent
0a7b9ba8a4
commit
418a55e0dc
5 changed files with 8355 additions and 9024 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -27,6 +27,7 @@
|
||||||
#include <rtl/math.hxx>
|
#include <rtl/math.hxx>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <complex>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "analysisdefs.hxx"
|
#include "analysisdefs.hxx"
|
||||||
|
@ -1591,9 +1592,8 @@ bool Complex::ParseString( const OUString& rStr, Complex& rCompl )
|
||||||
|
|
||||||
if( IsImagUnit( *pStr ) && rStr.getLength() == 1)
|
if( IsImagUnit( *pStr ) && rStr.getLength() == 1)
|
||||||
{
|
{
|
||||||
rCompl.r = 0.0;
|
|
||||||
rCompl.i = 1.0;
|
|
||||||
rCompl.c = *pStr;
|
rCompl.c = *pStr;
|
||||||
|
rCompl.num = std::complex(0.0, 1.0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1613,8 +1613,7 @@ bool Complex::ParseString( const OUString& rStr, Complex& rCompl )
|
||||||
rCompl.c = pStr[ 1 ];
|
rCompl.c = pStr[ 1 ];
|
||||||
if( pStr[ 2 ] == 0 )
|
if( pStr[ 2 ] == 0 )
|
||||||
{
|
{
|
||||||
rCompl.r = f;
|
rCompl.num = std::complex(f, ( *pStr == '+' )? 1.0 : -1.0);
|
||||||
rCompl.i = ( *pStr == '+' )? 1.0 : -1.0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1624,8 +1623,7 @@ bool Complex::ParseString( const OUString& rStr, Complex& rCompl )
|
||||||
pStr++;
|
pStr++;
|
||||||
if( *pStr == 0 )
|
if( *pStr == 0 )
|
||||||
{
|
{
|
||||||
rCompl.r = r;
|
rCompl.num = std::complex(r, f);
|
||||||
rCompl.i = f;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1637,43 +1635,40 @@ bool Complex::ParseString( const OUString& rStr, Complex& rCompl )
|
||||||
pStr++;
|
pStr++;
|
||||||
if( *pStr == 0 )
|
if( *pStr == 0 )
|
||||||
{
|
{
|
||||||
rCompl.i = f;
|
rCompl.num = std::complex(0.0, f);
|
||||||
rCompl.r = 0.0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0: // only real-part
|
case 0: // only real-part
|
||||||
rCompl.r = f;
|
rCompl.num = std::complex(f, 0.0);
|
||||||
rCompl.i = 0.0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OUString Complex::GetString() const
|
OUString Complex::GetString() const
|
||||||
{
|
{
|
||||||
finiteOrThrow(r);
|
finiteOrThrow(num.real());
|
||||||
finiteOrThrow(i);
|
finiteOrThrow(num.imag());
|
||||||
OUStringBuffer aRet;
|
OUStringBuffer aRet;
|
||||||
|
|
||||||
bool bHasImag = i != 0.0;
|
bool bHasImag = num.imag() != 0.0;
|
||||||
bool bHasReal = !bHasImag || (r != 0.0);
|
bool bHasReal = !bHasImag || (num.real() != 0.0);
|
||||||
|
|
||||||
if( bHasReal )
|
if( bHasReal )
|
||||||
aRet.append(::GetString( r, false ));
|
aRet.append(::GetString( num.real(), false ));
|
||||||
if( bHasImag )
|
if( bHasImag )
|
||||||
{
|
{
|
||||||
if( i == 1.0 )
|
if( num.imag() == 1.0 )
|
||||||
{
|
{
|
||||||
if( bHasReal )
|
if( bHasReal )
|
||||||
aRet.append('+');
|
aRet.append('+');
|
||||||
}
|
}
|
||||||
else if( i == -1.0 )
|
else if( num.imag() == -1.0 )
|
||||||
aRet.append('-');
|
aRet.append('-');
|
||||||
else
|
else
|
||||||
aRet.append(::GetString( i, bHasReal ));
|
aRet.append(::GetString( num.imag(), bHasReal ));
|
||||||
aRet.append((c != 'j') ? 'i' : 'j');
|
aRet.append((c != 'j') ? 'i' : 'j');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1683,139 +1678,65 @@ OUString Complex::GetString() const
|
||||||
|
|
||||||
double Complex::Arg() const
|
double Complex::Arg() const
|
||||||
{
|
{
|
||||||
if( r == 0.0 && i == 0.0 )
|
// Note: there are differing opinions on whether arg(0) should be 0 or undefined, we are treating it as undefined
|
||||||
|
if( num.real() == 0.0 && num.imag() == 0.0 )
|
||||||
throw lang::IllegalArgumentException();
|
throw lang::IllegalArgumentException();
|
||||||
|
return std::arg(num);
|
||||||
double phi = acos( r / Abs() );
|
|
||||||
|
|
||||||
if( i < 0.0 )
|
|
||||||
phi = -phi;
|
|
||||||
|
|
||||||
return phi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Power( double fPower )
|
void Complex::Power( double fPower )
|
||||||
{
|
{
|
||||||
if( r == 0.0 && i == 0.0 )
|
if( num.real() == 0.0 && num.imag() == 0.0 && fPower <= 0 )
|
||||||
{
|
throw lang::IllegalArgumentException();
|
||||||
if( fPower <= 0 )
|
num = std::pow(num, fPower);
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
r = i = 0.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double p, phi;
|
|
||||||
|
|
||||||
p = Abs();
|
|
||||||
|
|
||||||
phi = acos( r / p );
|
|
||||||
if( i < 0.0 )
|
|
||||||
phi = -phi;
|
|
||||||
|
|
||||||
p = pow( p, fPower );
|
|
||||||
phi *= fPower;
|
|
||||||
|
|
||||||
r = cos( phi ) * p;
|
|
||||||
i = sin( phi ) * p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Sqrt()
|
void Complex::Sqrt()
|
||||||
{
|
{
|
||||||
static const double fMultConst = M_SQRT1_2;
|
num = std::sqrt(num);
|
||||||
double p = Abs();
|
|
||||||
double i_ = sqrt( p - r ) * fMultConst;
|
|
||||||
|
|
||||||
r = sqrt( p + r ) * fMultConst;
|
|
||||||
i = ( i < 0.0 )? -i_ : i_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Sin()
|
void Complex::Sin()
|
||||||
{
|
{
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
if( !::rtl::math::isValidArcArg( num.real() ) )
|
||||||
throw lang::IllegalArgumentException();
|
throw lang::IllegalArgumentException();
|
||||||
|
num = std::sin(num);
|
||||||
if( i )
|
|
||||||
{
|
|
||||||
double r_;
|
|
||||||
|
|
||||||
r_ = sin( r ) * cosh( i );
|
|
||||||
i = cos( r ) * sinh( i );
|
|
||||||
r = r_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r = sin( r );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Cos()
|
void Complex::Cos()
|
||||||
{
|
{
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
if( !::rtl::math::isValidArcArg( num.real() ) )
|
||||||
throw lang::IllegalArgumentException();
|
throw lang::IllegalArgumentException();
|
||||||
|
num = std::cos(num);
|
||||||
if( i )
|
|
||||||
{
|
|
||||||
double r_;
|
|
||||||
|
|
||||||
r_ = cos( r ) * cosh( i );
|
|
||||||
i = -( sin( r ) * sinh( i ) );
|
|
||||||
r = r_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r = cos( r );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Div( const Complex& z )
|
void Complex::Div( const Complex& z )
|
||||||
{
|
{
|
||||||
if( z.r == 0 && z.i == 0 )
|
if( z.num.real() == 0 && z.num.imag() == 0 )
|
||||||
throw lang::IllegalArgumentException();
|
throw lang::IllegalArgumentException();
|
||||||
|
num = num / z.num;
|
||||||
double a1 = r;
|
|
||||||
double a2 = z.r;
|
|
||||||
double b1 = i;
|
|
||||||
double b2 = z.i;
|
|
||||||
|
|
||||||
double f = 1.0 / ( a2 * a2 + b2 * b2 );
|
|
||||||
|
|
||||||
r = ( a1 * a2 + b1 * b2 ) * f;
|
|
||||||
i = ( a2 * b1 - a1 * b2 ) * f;
|
|
||||||
|
|
||||||
if( !c ) c = z.c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Exp()
|
void Complex::Exp()
|
||||||
{
|
{
|
||||||
double fE = exp( r );
|
num = std::exp(num);
|
||||||
r = fE * cos( i );
|
|
||||||
i = fE * sin( i );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Ln()
|
void Complex::Ln()
|
||||||
{
|
{
|
||||||
if( r == 0.0 && i == 0.0 )
|
num = std::log(num);
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
|
|
||||||
double fAbs = Abs();
|
|
||||||
bool bNegi = i < 0.0;
|
|
||||||
|
|
||||||
i = acos( r / fAbs );
|
|
||||||
|
|
||||||
if( bNegi )
|
|
||||||
i = -i;
|
|
||||||
|
|
||||||
r = log( fAbs );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Log10()
|
void Complex::Log10()
|
||||||
{
|
{
|
||||||
Ln();
|
num = std::log10(num);
|
||||||
Mult( M_LOG10E );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1828,157 +1749,64 @@ void Complex::Log2()
|
||||||
|
|
||||||
void Complex::Tan()
|
void Complex::Tan()
|
||||||
{
|
{
|
||||||
if ( i )
|
// using 2.0 * num.real/imag as a precaution because a) this is what our previous implementation did and
|
||||||
{
|
// b) the std::complex implementation may use cos(2x) etc, see the comment in isValidArcArg for details
|
||||||
if( !::rtl::math::isValidArcArg( 2.0 * r ) )
|
if ( ( num.imag() && !::rtl::math::isValidArcArg( 2.0 * num.real() ) )
|
||||||
throw lang::IllegalArgumentException();
|
|| ( !num.imag() && !::rtl::math::isValidArcArg( num.real() ) ) )
|
||||||
double fScale =1.0 / ( cos( 2.0 * r ) + cosh( 2.0 * i ));
|
throw lang::IllegalArgumentException();
|
||||||
r = sin( 2.0 * r ) * fScale;
|
num = std::tan(num);
|
||||||
i = sinh( 2.0 * i ) * fScale;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
r = tan( r );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Sec()
|
void Complex::Sec()
|
||||||
{
|
{
|
||||||
if( i )
|
Cos();
|
||||||
{
|
num = 1.0 / num;
|
||||||
if( !::rtl::math::isValidArcArg( 2 * r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
double fScale = 1.0 / (cosh( 2.0 * i) + cos ( 2.0 * r));
|
|
||||||
double r_;
|
|
||||||
r_ = 2.0 * cos( r ) * cosh( i ) * fScale;
|
|
||||||
i = 2.0 * sin( r ) * sinh( i ) * fScale;
|
|
||||||
r = r_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
r = 1.0 / cos( r );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Csc()
|
void Complex::Csc()
|
||||||
{
|
{
|
||||||
if( i )
|
Sin();
|
||||||
{
|
num = 1.0 / num;
|
||||||
if( !::rtl::math::isValidArcArg( 2 * r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
double fScale = 1.0 / (cosh( 2.0 * i) - cos ( 2.0 * r));
|
|
||||||
double r_;
|
|
||||||
r_ = 2.0 * sin( r ) * cosh( i ) * fScale;
|
|
||||||
i = -2.0 * cos( r ) * sinh( i ) * fScale;
|
|
||||||
r = r_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
r = 1.0 / sin( r );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Cot()
|
void Complex::Cot()
|
||||||
{
|
{
|
||||||
if ( i )
|
|
||||||
{
|
Tan();
|
||||||
if( !::rtl::math::isValidArcArg( 2.0 * r ) )
|
num = 1.0 / num;
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
double fScale =1.0 / ( cosh( 2.0 * i ) - cos( 2.0 * r ) );
|
|
||||||
r = sin( 2.0 * r ) * fScale;
|
|
||||||
i = - ( sinh( 2.0 * i ) * fScale );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
r = 1.0 / tan( r );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Sinh()
|
void Complex::Sinh()
|
||||||
{
|
{
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
if( !::rtl::math::isValidArcArg( num.imag() ) )
|
||||||
throw lang::IllegalArgumentException();
|
throw lang::IllegalArgumentException();
|
||||||
|
num = std::sinh(num);
|
||||||
if( i )
|
|
||||||
{
|
|
||||||
double r_;
|
|
||||||
r_ = sinh( r ) * cos( i );
|
|
||||||
i = cosh( r ) * sin( i );
|
|
||||||
r = r_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r = sinh( r );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Cosh()
|
void Complex::Cosh()
|
||||||
{
|
{
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
if( !::rtl::math::isValidArcArg( num.imag() ) )
|
||||||
throw lang::IllegalArgumentException();
|
throw lang::IllegalArgumentException();
|
||||||
|
num = std::cosh(num);
|
||||||
if( i )
|
|
||||||
{
|
|
||||||
double r_;
|
|
||||||
r_ = cosh( r ) * cos( i );
|
|
||||||
i = sinh( r ) * sin( i );
|
|
||||||
r = r_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r = cosh( r );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Sech()
|
void Complex::Sech()
|
||||||
{
|
{
|
||||||
if ( i )
|
Cosh();
|
||||||
{
|
num = 1.0 / num;
|
||||||
if( !::rtl::math::isValidArcArg( 2.0 * r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
double fScale =1.0 / ( cosh( 2.0 * r ) + cos( 2.0 * i ));
|
|
||||||
double r_;
|
|
||||||
r_ = 2.0 * cosh( r ) * cos( i ) * fScale;
|
|
||||||
i = - (2.0 * sinh( r ) * sin( i ) * fScale );
|
|
||||||
r = r_ ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
r = 1.0 / cosh( r );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Csch()
|
void Complex::Csch()
|
||||||
{
|
{
|
||||||
if ( i )
|
Sinh();
|
||||||
{
|
num = 1.0 / num;
|
||||||
if( !::rtl::math::isValidArcArg( 2.0 * r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
double fScale =1.0 / ( cosh( 2.0 * r ) - cos( 2.0 * i ));
|
|
||||||
double r_;
|
|
||||||
r_ = 2.0 * sinh( r ) * cos( i ) * fScale;
|
|
||||||
i = - ( 2.0 * cosh( r ) * sin( i ) * fScale );
|
|
||||||
r = r_ ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !::rtl::math::isValidArcArg( r ) )
|
|
||||||
throw lang::IllegalArgumentException();
|
|
||||||
r = 1.0 / sinh( r );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <unotools/resmgr.hxx>
|
#include <unotools/resmgr.hxx>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <complex>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -380,8 +381,7 @@ public:
|
||||||
|
|
||||||
class Complex
|
class Complex
|
||||||
{
|
{
|
||||||
double r;
|
std::complex<double> num;
|
||||||
double i;
|
|
||||||
sal_Unicode c;
|
sal_Unicode c;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -629,66 +629,59 @@ inline FDCategory FuncData::GetCategory() const
|
||||||
|
|
||||||
|
|
||||||
inline Complex::Complex( double fReal, double fImag, sal_Unicode cC ) :
|
inline Complex::Complex( double fReal, double fImag, sal_Unicode cC ) :
|
||||||
r( fReal ), i( fImag ), c( cC )
|
c( cC )
|
||||||
{
|
{
|
||||||
|
num = std::complex(fReal, fImag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline double Complex::Real() const
|
inline double Complex::Real() const
|
||||||
{
|
{
|
||||||
return r;
|
return num.real();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline double Complex::Imag() const
|
inline double Complex::Imag() const
|
||||||
{
|
{
|
||||||
return i;
|
return num.imag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline double Complex::Abs() const
|
inline double Complex::Abs() const
|
||||||
{
|
{
|
||||||
return std::hypot(r, i);
|
return std::abs(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Complex::Conjugate()
|
void Complex::Conjugate()
|
||||||
{
|
{
|
||||||
i = -i;
|
num = std::conj(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Complex::Mult( double f )
|
inline void Complex::Mult( double f )
|
||||||
{
|
{
|
||||||
i *= f;
|
num = num * f;
|
||||||
r *= f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Complex::Mult( const Complex& rM )
|
inline void Complex::Mult( const Complex& rM )
|
||||||
{
|
{
|
||||||
double r_ = r;
|
num = num * rM.num;
|
||||||
double i_ = i;
|
|
||||||
|
|
||||||
r = r_ * rM.r - i_ * rM.i;
|
|
||||||
i = r_ * rM.i + i_ * rM.r;
|
|
||||||
|
|
||||||
if( !c ) c = rM.c;
|
if( !c ) c = rM.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Complex::Sub( const Complex& rC )
|
inline void Complex::Sub( const Complex& rC )
|
||||||
{
|
{
|
||||||
r -= rC.r;
|
num = num - rC.num;
|
||||||
i -= rC.i;
|
|
||||||
if( !c ) c = rC.c;
|
if( !c ) c = rC.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Complex::Add( const Complex& rAdd )
|
inline void Complex::Add( const Complex& rAdd )
|
||||||
{
|
{
|
||||||
r += rAdd.r;
|
num = num + rAdd.num;
|
||||||
i += rAdd.i;
|
|
||||||
if( !c ) c = rAdd.c;
|
if( !c ) c = rAdd.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue