diff --git a/main/sc/source/core/tool/interpr1.cxx b/main/sc/source/core/tool/interpr1.cxx index 74ee0b8a94a..51d7277357a 100644 --- a/main/sc/source/core/tool/interpr1.cxx +++ b/main/sc/source/core/tool/interpr1.cxx @@ -72,9 +72,7 @@ #include "doubleref.hxx" #include "queryparam.hxx" -#include -#include -#include +#include #define SC_DOUBLE_MAXVALUE 1.7e307 @@ -1811,7 +1809,7 @@ void ScInterpreter::ScCotHyp() void ScInterpreter::ScArcSinHyp() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcSinHyp" ); - PushDouble( ::boost::math::asinh( GetDouble())); + PushDouble( std::asinh( GetDouble())); } void ScInterpreter::ScArcCosHyp() @@ -1821,7 +1819,7 @@ void ScInterpreter::ScArcCosHyp() if (fVal < 1.0) PushIllegalArgument(); else - PushDouble( ::boost::math::acosh( fVal)); + PushDouble( std::acosh( fVal)); } void ScInterpreter::ScArcTanHyp() @@ -1831,7 +1829,7 @@ void ScInterpreter::ScArcTanHyp() if (fabs(fVal) >= 1.0) PushIllegalArgument(); else - PushDouble( ::boost::math::atanh( fVal)); + PushDouble( std::atanh( fVal)); } diff --git a/main/sc/source/core/tool/interpr2.cxx b/main/sc/source/core/tool/interpr2.cxx index bdeebb69385..a26b2d98720 100644 --- a/main/sc/source/core/tool/interpr2.cxx +++ b/main/sc/source/core/tool/interpr2.cxx @@ -50,8 +50,7 @@ #include #include -#include -#include +#include using namespace formula; // STATIC DATA ----------------------------------------------------------- @@ -1136,11 +1135,11 @@ double ScInterpreter::ScGetRmz(double fRate, double fNper, double fPv, else { if (fPaytype > 0.0) // payment in advance - fPayment = (fFv + fPv * exp( fNper * ::boost::math::log1p(fRate) ) ) * fRate / - (::boost::math::expm1( (fNper + 1) * ::boost::math::log1p(fRate) ) - fRate); + fPayment = (fFv + fPv * exp( fNper * std::log1p(fRate) ) ) * fRate / + (std::expm1( (fNper + 1) * std::log1p(fRate) ) - fRate); else // payment in arrear - fPayment = (fFv + fPv * exp(fNper * ::boost::math::log1p(fRate) ) ) * fRate / - ::boost::math::expm1( fNper * ::boost::math::log1p(fRate) ); + fPayment = (fFv + fPv * exp(fNper * std::log1p(fRate) ) ) * fRate / + std::expm1( fNper * std::log1p(fRate) ); } return -fPayment; } diff --git a/main/sc/source/core/tool/interpr3.cxx b/main/sc/source/core/tool/interpr3.cxx index dfc05ef2c80..a1e3f3919e1 100644 --- a/main/sc/source/core/tool/interpr3.cxx +++ b/main/sc/source/core/tool/interpr3.cxx @@ -44,9 +44,7 @@ #include #include -#include -#include -#include +#include using ::std::vector; using namespace formula; @@ -857,8 +855,8 @@ double ScInterpreter::GetBeta(double fAlpha, double fBeta) fLanczos *= sqrt((fABgm/(fA+fgm))/(fB+fgm)); double fTempA = fB/(fA+fgm); // (fA+fgm)/fABgm = 1 / ( 1 + fB/(fA+fgm)) double fTempB = fA/(fB+fgm); - double fResult = exp(-fA * ::boost::math::log1p(fTempA) - -fB * ::boost::math::log1p(fTempB)-fgm); + double fResult = exp(-fA * std::log1p(fTempA) + -fB * std::log1p(fTempB)-fgm); fResult *= fLanczos; return fResult; } @@ -886,8 +884,8 @@ double ScInterpreter::GetLogBeta(double fAlpha, double fBeta) fLogLanczos += 0.5*(log(fABgm)-log(fA+fgm)-log(fB+fgm)); double fTempA = fB/(fA+fgm); // (fA+fgm)/fABgm = 1 / ( 1 + fB/(fA+fgm)) double fTempB = fA/(fB+fgm); - double fResult = -fA * ::boost::math::log1p(fTempA) - -fB * ::boost::math::log1p(fTempB)-fgm; + double fResult = -fA * std::log1p(fTempA) + -fB * std::log1p(fTempB)-fgm; fResult += fLogLanczos; return fResult; } @@ -908,7 +906,7 @@ double ScInterpreter::GetBetaDistPDF(double fX, double fA, double fB) return HUGE_VAL; } if (fX <= 0.01) - return fB + fB * ::boost::math::expm1((fB-1.0) * ::boost::math::log1p(-fX)); + return fB + fB * std::expm1((fB-1.0) * std::log1p(-fX)); else return fB * pow(0.5-fX+0.5,fB-1.0); } @@ -947,7 +945,7 @@ double ScInterpreter::GetBetaDistPDF(double fX, double fA, double fB) // normal cases; result x^(a-1)*(1-x)^(b-1)/Beta(a,b) const double fLogDblMax = log( ::std::numeric_limits::max()); const double fLogDblMin = log( ::std::numeric_limits::min()); - double fLogY = (fX < 0.1) ? ::boost::math::log1p(-fX) : log(0.5-fX+0.5); + double fLogY = (fX < 0.1) ? std::log1p(-fX) : log(0.5-fX+0.5); double fLogX = log(fX); double fAm1LogX = (fA-1.0) * fLogX; double fBm1LogY = (fB-1.0) * fLogY; @@ -1028,13 +1026,13 @@ double ScInterpreter::GetBetaDist(double fXin, double fAlpha, double fBeta) return pow(fXin, fAlpha); if (fAlpha == 1.0) // 1.0 - pow(1.0-fX,fBeta) is not accurate enough - return -::boost::math::expm1(fBeta * ::boost::math::log1p(-fXin)); + return -std::expm1(fBeta * std::log1p(-fXin)); //FIXME: need special algorithm for fX near fP for large fA,fB double fResult; // I use always continued fraction, power series are neither // faster nor more accurate. double fY = (0.5-fXin)+0.5; - double flnY = ::boost::math::log1p(-fXin); + double flnY = std::log1p(-fXin); double fX = fXin; double flnX = log(fXin); double fA = fAlpha; @@ -1145,7 +1143,7 @@ void ScInterpreter::ScFisher() if (fabs(fVal) >= 1.0) PushIllegalArgument(); else - PushDouble( ::boost::math::atanh( fVal)); + PushDouble( std::atanh( fVal)); } void ScInterpreter::ScFisherInv() diff --git a/main/scaddins/source/analysis/analysishelper.cxx b/main/scaddins/source/analysis/analysishelper.cxx index 5b56a270b4e..e6b1b153ce6 100644 --- a/main/scaddins/source/analysis/analysishelper.cxx +++ b/main/scaddins/source/analysis/analysishelper.cxx @@ -1943,10 +1943,7 @@ double Complex::Arg( void ) const THROWDEF_RTE_IAE if( Num.real() == 0.0 && Num.imag() == 0.0 ) THROW_IAE; - double phi = acos( Num.real() / Abs() ); - - if( Num.imag() < 0.0 ) - phi = -phi; + double phi = std::atan2(Num.imag(), Num.real()); return phi; } @@ -1965,68 +1962,34 @@ void Complex::Power( double fPower ) THROWDEF_RTE_IAE THROW_IAE; } - double p, phi; - - p = Abs(); - - phi = acos( Num.real() / p ); - if( Num.imag() < 0.0 ) - phi = -phi; - - p = pow( p, fPower ); - phi *= fPower; - - Num = double_complex (cos( phi ) * p, sin( phi ) * p); + Num = std::pow(Num , fPower); } void Complex::Sqrt( void ) { - static const double fMultConst = 0.7071067811865475; // ...2440084436210485 = 1/sqrt(2) - double p = Abs(); - double i_ = sqrt( p - Num.real() ) * fMultConst; - Num = double_complex (sqrt( p + Num.real() ) * fMultConst, ( Num.imag() < 0.0 )? -i_ : i_); + Num = std::sqrt(Num); } void Complex::Sin( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - - r_ = sin( r ) * cosh( i ); - i = cos( r ) * sinh( i ); - r = r_; - } - else - r = sin( r ); - Num = double_complex ( r, i ); + Num = std::sin( Num ); } void Complex::Cos( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - - r_ = cos( r ) * cosh( i ); - i = -( sin( r ) * sinh( i ) ); - r = r_; - } - else - r = cos( r ); - Num = double_complex ( r, i ); + Num = std::cos ( Num ); } @@ -2035,23 +1998,15 @@ void Complex::Div( const Complex& z ) THROWDEF_RTE_IAE if( z.Num.real() == 0 && z.Num.imag() == 0 ) THROW_IAE; - double a1 = Num.real(); - double a2 = z.Num.real(); - double b1 = Num.imag(); - double b2 = z.Num.imag(); - - double f = 1.0 / ( a2 * a2 + b2 * b2 ); - - Num = f * double_complex ( a1 * a2 + b1 * b2 , a2 * b1 - a1 * b2 ); + Num /= z.Num; - if( !c ) c = z.c; } void Complex::Exp( void ) { - double fE = exp( Num.real() ); - Num = fE * double_complex ( cos( Num.imag() ), sin( Num.imag() ) ); + + Num = std::exp( Num ); } @@ -2061,16 +2016,7 @@ void Complex::Ln( void ) THROWDEF_RTE_IAE if( r == 0.0 && i == 0.0 ) THROW_IAE; - double fAbs = Abs(); - sal_Bool bNegi = i < 0.0; - - i = acos( r / fAbs ); - - if( bNegi ) - i = -i; - - r = log( fAbs ); - Num = double_complex ( r, i ); + Num = std::log ( Num ); } @@ -2095,168 +2041,73 @@ void Complex::Tan(void) THROWDEF_RTE_IAE { if( !::rtl::math::isValidArcArg( 2.0 * r ) ) THROW_IAE; - double fScale =1.0 / ( cos( 2.0 * r ) + cosh( 2.0 * i )); - r = sin( 2.0 * r ) * fScale; - i = sinh( 2.0 * i ) * fScale; } else { if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - r = tan( r ); } - Num = double_complex ( r, i ); + Num = std::tan ( Num ); } void Complex::Sec( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if( i ) - { - if( !::rtl::math::isValidArcArg( 2 * r ) ) - THROW_IAE; - 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_IAE; - r = 1.0 / cos( r ); - } - Num = double_complex ( r, i ); + + Cos(); + Num = 1.0 / Num; } void Complex::Csc( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if( i ) - { - if( !::rtl::math::isValidArcArg( 2 * r ) ) - THROW_IAE; - 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_IAE; - r = 1.0 / sin( r ); - } - Num = double_complex ( r, i ); + + Sin(); + Num = 1.0 / Num; } void Complex::Cot(void) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if ( i ) - { - if( !::rtl::math::isValidArcArg( 2.0 * r ) ) - THROW_IAE; - 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_IAE; - r = 1.0 / tan( r ); - } - Num = double_complex ( r, i ); + + Tan(); + Num = 1.0 / Num; } void Complex::Sinh( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - r_ = sinh( r ) * cos( i ); - i = cosh( r ) * sin( i ); - r = r_; - } - else - r = sinh( r ); - Num = double_complex ( r, i ); + Num = std::sinh( Num ); } void Complex::Cosh( void ) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; + double r = Num.real(); if( !::rtl::math::isValidArcArg( r ) ) THROW_IAE; - if( i ) - { - double r_; - r_ = cosh( r ) * cos( i ); - i = sinh( r ) * sin( i ); - r = r_; - } - else - r = cosh( r ); - Num = double_complex ( r, i ); + Num = std::cosh( Num ); } void Complex::Sech(void) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if ( i ) - { - if( !::rtl::math::isValidArcArg( 2.0 * r ) ) - THROW_IAE; - 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_IAE; - r = 1.0 / cosh( r ); - } - Num = double_complex ( r, i ); + + Cosh(); + Num = 1.0 / Num; } void Complex::Csch(void) THROWDEF_RTE_IAE { - double r = Num.real(), i = Num.imag() ; - if ( i ) - { - if( !::rtl::math::isValidArcArg( 2.0 * r ) ) - THROW_IAE; - 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_IAE; - r = 1.0 / sinh( r ); - } - Num = double_complex ( r, i ); + + Sinh(); + Num = 1.0 / Num; } diff --git a/main/sccomp/source/solver/solver.cxx b/main/sccomp/source/solver/solver.cxx index 3e3d7f0f11b..985caf49370 100644 --- a/main/sccomp/source/solver/solver.cxx +++ b/main/sccomp/source/solver/solver.cxx @@ -568,6 +568,14 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException) // solve model nResult = CoinCheckProblem( hProb ); + if (nResult != SOLV_CALL_SUCCESS) + { + // report invalid model + + maStatus = lcl_GetResourceString( RID_ERROR_INVALIDMODEL ); + CoinUnloadProblem(hProb); + return; + } nResult = CoinOptimizeProblem( hProb, 0 ); mbSuccess = ( nResult == SOLV_CALL_SUCCESS ); @@ -586,8 +594,15 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException) maStatus = lcl_GetResourceString( RID_ERROR_INFEASIBLE ); else if ( nSolutionStatus == 2 ) maStatus = lcl_GetResourceString( RID_ERROR_UNBOUNDED ); - // TODO: detect timeout condition and report as RID_ERROR_TIMEOUT - // (currently reported as infeasible) + else if ( nSolutionStatus == 3 ) + maStatus = lcl_GetResourceString( RID_ERROR_ITERATIONLIMIT ); + else if ( nSolutionStatus == 4 ) + maStatus = lcl_GetResourceString( RID_ERROR_SOLVERERROR ); + else if ( nSolutionStatus == 5 ) + maStatus = lcl_GetResourceString( RID_ERROR_USERSTOP ); + else if ( nSolutionStatus >= 6 ) + maStatus = lcl_GetResourceString( RID_ERROR_UNKNOWN ); + } CoinUnloadProblem( hProb ); diff --git a/main/sccomp/source/solver/solver.hrc b/main/sccomp/source/solver/solver.hrc index 2a6965848cd..84d9169ff4c 100644 --- a/main/sccomp/source/solver/solver.hrc +++ b/main/sccomp/source/solver/solver.hrc @@ -35,7 +35,11 @@ #define RID_ERROR_NONLINEAR (SOLVER_RESOURCE_START + 7) #define RID_ERROR_EPSILONLEVEL (SOLVER_RESOURCE_START + 8) #define RID_ERROR_INFEASIBLE (SOLVER_RESOURCE_START + 9) -#define RID_ERROR_UNBOUNDED (SOLVER_RESOURCE_START + 10) -#define RID_ERROR_TIMEOUT (SOLVER_RESOURCE_START + 11) +#define RID_ERROR_UNBOUNDED (SOLVER_RESOURCE_START + 11) +#define RID_ERROR_ITERATIONLIMIT (SOLVER_RESOURCE_START + 12) +#define RID_ERROR_SOLVERERROR (SOLVER_RESOURCE_START + 13) +#define RID_ERROR_USERSTOP (SOLVER_RESOURCE_START + 14) +#define RID_ERROR_UNKNOWN (SOLVER_RESOURCE_START + 15) +#define RID_ERROR_INVALIDMODEL (SOLVER_RESOURCE_START + 16) #endif diff --git a/main/sccomp/source/solver/solver.src b/main/sccomp/source/solver/solver.src index f6cab594c15..03200029dc5 100644 --- a/main/sccomp/source/solver/solver.src +++ b/main/sccomp/source/solver/solver.src @@ -52,6 +52,7 @@ String RID_PROPERTY_NONLINEARTEST { Text [ en-US ] = "Run strict linearity checks"; }; + String RID_ERROR_NONLINEAR { Text [ en-US ] = "The model seems nonlinear (see options)."; @@ -68,7 +69,23 @@ String RID_ERROR_UNBOUNDED { Text [ en-US ] = "The model is unbounded."; }; -String RID_ERROR_TIMEOUT +String RID_ERROR_ITERATIONLIMIT +{ + Text [ en-US ] = "Iteration limit reached."; +}; +String RID_ERROR_SOLVERERROR +{ + Text [ en-US ] = "Numerical solver error."; +}; +String RID_ERROR_USERSTOP +{ + Text [ en-US ] = "User/callback cancellation."; +}; +String RID_ERROR_UNKNOWN +{ + Text [ en-US ] = "Unrecognized status."; +}; +String RID_ERROR_INVALIDMODEL { - Text [ en-US ] = "The time limit was reached."; + Text [ en-US ] = "Invalid internal generated model."; };