aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/StableNorm.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2013-04-19 11:21:39 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2013-04-19 11:21:39 +0200
commit9cd2d14005def8e7df0b0bf5fd6eb51f8a6591e9 (patch)
treeca4df13b58e923bdebd9d5f59aecda9d1e30ca58 /Eigen/src/Core/StableNorm.h
parent4e2e615a7c2c719d2d708ab32840bad353322d8c (diff)
parent46755648ec341aa5e0283b47456108bb2897b1b3 (diff)
merge with default branch
Diffstat (limited to 'Eigen/src/Core/StableNorm.h')
-rw-r--r--Eigen/src/Core/StableNorm.h40
1 files changed, 19 insertions, 21 deletions
diff --git a/Eigen/src/Core/StableNorm.h b/Eigen/src/Core/StableNorm.h
index 1aefd91a8..ea227c535 100644
--- a/Eigen/src/Core/StableNorm.h
+++ b/Eigen/src/Core/StableNorm.h
@@ -13,6 +13,7 @@
namespace Eigen {
namespace internal {
+
template<typename ExpressionType, typename Scalar>
inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale)
{
@@ -32,7 +33,6 @@ template<typename Derived>
inline typename NumTraits<typename traits<Derived>::Scalar>::Real
blueNorm_impl(const EigenBase<Derived>& _vec)
{
- typedef typename Derived::Scalar Scalar;
typedef typename Derived::RealScalar RealScalar;
typedef typename Derived::Index Index;
using std::pow;
@@ -41,43 +41,40 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
using std::sqrt;
using std::abs;
const Derived& vec(_vec.derived());
- static Index nmax = -1;
+ static bool initialized = false;
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
- if(nmax <= 0)
+ if(!initialized)
{
- int nbig, ibeta, it, iemin, iemax, iexp;
- RealScalar abig, eps;
+ int ibeta, it, iemin, iemax, iexp;
+ RealScalar eps;
// This program calculates the machine-dependent constants
- // bl, b2, slm, s2m, relerr overfl, nmax
+ // bl, b2, slm, s2m, relerr overfl
// from the "basic" machine-dependent numbers
// nbig, ibeta, it, iemin, iemax, rbig.
// The following define the basic machine-dependent constants.
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
// are used. For any specific computer, each of the assignment
// statements can be replaced
- nbig = (std::numeric_limits<Index>::max)(); // largest integer
- ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
- it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
- iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
- iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
- rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
+ ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
+ it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
+ iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
+ iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
+ rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
iexp = -((1-iemin)/2);
- b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
+ b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
iexp = (iemax + 1 - it)/2;
- b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
+ b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
iexp = (2-iemin)/2;
- s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
+ s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
iexp = - ((iemax+it)/2);
- s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
+ s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
- overfl = rbig*s2m; // overflow boundary for abig
+ overfl = rbig*s2m; // overflow boundary for abig
eps = RealScalar(pow(double(ibeta), 1-it));
- relerr = sqrt(eps); // tolerance for neglecting asml
- abig = RealScalar(1.0/eps - 1.0);
- if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
- else nmax = nbig;
+ relerr = sqrt(eps); // tolerance for neglecting asml
+ initialized = true;
}
Index n = vec.size();
RealScalar ab2 = b2 / RealScalar(n);
@@ -125,6 +122,7 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
else
return abig * sqrt(RealScalar(1) + internal::abs2(asml/abig));
}
+
} // end namespace internal
/** \returns the \em l2 norm of \c *this avoiding underflow and overflow.