StableNorm.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_STABLENORM_H
11 #define EIGEN_STABLENORM_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 template<typename ExpressionType, typename Scalar>
18 inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale)
19 {
20  Scalar maxCoeff = bl.cwiseAbs().maxCoeff();
21 
22  if(maxCoeff>scale)
23  {
24  ssq = ssq * numext::abs2(scale/maxCoeff);
25  Scalar tmp = Scalar(1)/maxCoeff;
26  if(tmp > NumTraits<Scalar>::highest())
27  {
28  invScale = NumTraits<Scalar>::highest();
29  scale = Scalar(1)/invScale;
30  }
31  else if(maxCoeff>NumTraits<Scalar>::highest()) // we got a INF
32  {
33  invScale = Scalar(1);
34  scale = maxCoeff;
35  }
36  else
37  {
38  scale = maxCoeff;
39  invScale = tmp;
40  }
41  }
42  else if(maxCoeff!=maxCoeff) // we got a NaN
43  {
44  scale = maxCoeff;
45  }
46 
47  // TODO if the maxCoeff is much much smaller than the current scale,
48  // then we can neglect this sub vector
49  if(scale>Scalar(0)) // if scale==0, then bl is 0
50  ssq += (bl*invScale).squaredNorm();
51 }
52 
53 template<typename Derived>
56 {
57  typedef typename Derived::RealScalar RealScalar;
58  using std::pow;
59  using std::sqrt;
60  using std::abs;
61  const Derived& vec(_vec.derived());
62  static bool initialized = false;
63  static RealScalar b1, b2, s1m, s2m, rbig, relerr;
64  if(!initialized)
65  {
66  int ibeta, it, iemin, iemax, iexp;
67  RealScalar eps;
68  // This program calculates the machine-dependent constants
69  // bl, b2, slm, s2m, relerr overfl
70  // from the "basic" machine-dependent numbers
71  // nbig, ibeta, it, iemin, iemax, rbig.
72  // The following define the basic machine-dependent constants.
73  // For portability, the PORT subprograms "ilmaeh" and "rlmach"
74  // are used. For any specific computer, each of the assignment
75  // statements can be replaced
76  ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
77  it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
78  iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
79  iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
80  rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
81 
82  iexp = -((1-iemin)/2);
83  b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
84  iexp = (iemax + 1 - it)/2;
85  b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
86 
87  iexp = (2-iemin)/2;
88  s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
89  iexp = - ((iemax+it)/2);
90  s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
91 
92  eps = RealScalar(pow(double(ibeta), 1-it));
93  relerr = sqrt(eps); // tolerance for neglecting asml
94  initialized = true;
95  }
96  Index n = vec.size();
97  RealScalar ab2 = b2 / RealScalar(n);
98  RealScalar asml = RealScalar(0);
99  RealScalar amed = RealScalar(0);
100  RealScalar abig = RealScalar(0);
101  for(typename Derived::InnerIterator it(vec, 0); it; ++it)
102  {
103  RealScalar ax = abs(it.value());
104  if(ax > ab2) abig += numext::abs2(ax*s2m);
105  else if(ax < b1) asml += numext::abs2(ax*s1m);
106  else amed += numext::abs2(ax);
107  }
108  if(amed!=amed)
109  return amed; // we got a NaN
110  if(abig > RealScalar(0))
111  {
112  abig = sqrt(abig);
113  if(abig > rbig) // overflow, or *this contains INF values
114  return abig; // return INF
115  if(amed > RealScalar(0))
116  {
117  abig = abig/s2m;
118  amed = sqrt(amed);
119  }
120  else
121  return abig/s2m;
122  }
123  else if(asml > RealScalar(0))
124  {
125  if (amed > RealScalar(0))
126  {
127  abig = sqrt(amed);
128  amed = sqrt(asml) / s1m;
129  }
130  else
131  return sqrt(asml)/s1m;
132  }
133  else
134  return sqrt(amed);
135  asml = numext::mini(abig, amed);
136  abig = numext::maxi(abig, amed);
137  if(asml <= abig*relerr)
138  return abig;
139  else
140  return abig * sqrt(RealScalar(1) + numext::abs2(asml/abig));
141 }
142 
143 } // end namespace internal
144 
155 template<typename Derived>
158 {
159  using std::sqrt;
160  using std::abs;
161  const Index blockSize = 4096;
162  RealScalar scale(0);
163  RealScalar invScale(1);
164  RealScalar ssq(0); // sum of square
165 
166  typedef typename internal::nested_eval<Derived,2>::type DerivedCopy;
167  typedef typename internal::remove_all<DerivedCopy>::type DerivedCopyClean;
168  const DerivedCopy copy(derived());
169 
170  enum {
171  CanAlign = ( (int(DerivedCopyClean::Flags)&DirectAccessBit)
172  || (int(internal::evaluator<DerivedCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
173  ) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
174  && (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
175  };
177  typename DerivedCopyClean::ConstSegmentReturnType>::type SegmentWrapper;
178  Index n = size();
179 
180  if(n==1)
181  return abs(this->coeff(0));
182 
184  if (bi>0)
185  internal::stable_norm_kernel(copy.head(bi), ssq, scale, invScale);
186  for (; bi<n; bi+=blockSize)
187  internal::stable_norm_kernel(SegmentWrapper(copy.segment(bi,numext::mini(blockSize, n - bi))), ssq, scale, invScale);
188  return scale * sqrt(ssq);
189 }
190 
200 template<typename Derived>
203 {
204  return internal::blueNorm_impl(*this);
205 }
206 
212 template<typename Derived>
215 {
216  return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>());
217 }
218 
219 } // end namespace Eigen
220 
221 #endif // EIGEN_STABLENORM_H
SCALAR Scalar
Definition: bench_gemm.cpp:33
#define max(a, b)
Definition: datatypes.h:20
return int(ret)+1
const unsigned int DirectAccessBit
Definition: Constants.h:150
int n
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
void stable_norm_kernel(const ExpressionType &bl, Scalar &ssq, Scalar &scale, Scalar &invScale)
Definition: StableNorm.h:18
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:150
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
Derived::RealScalar relerr(const MatrixBase< Derived > &A, const MatrixBase< OtherDerived > &B)
static Index first_default_aligned(const DenseBase< Derived > &m)
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
NumTraits< typename traits< Derived >::Scalar >::Real blueNorm_impl(const EigenBase< Derived > &_vec)
Definition: StableNorm.h:55
RealScalar blueNorm() const
Definition: StableNorm.h:202
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseAbsReturnType cwiseAbs() const
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
Vector2 b2(4,-5)
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:34
RealScalar stableNorm() const
Definition: StableNorm.h:157
const VectorBlock< const Derived > ConstSegmentReturnType
Definition: BlockMethods.h:39
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T mini(const T &x, const T &y)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Abs2ReturnType abs2() const
Vector2 b1(2,-1)
mp::number< mp::cpp_dec_float< 100 >, mp::et_on > Real
NumTraits< Scalar >::Real RealScalar
Definition: DenseBase.h:73
#define EIGEN_MAX_STATIC_ALIGN_BYTES
Definition: Macros.h:728
RealScalar hypotNorm() const
Definition: StableNorm.h:214
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics scale
#define EIGEN_STACK_ALLOCATION_LIMIT
Definition: Macros.h:801
int EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:29
Jet< T, N > pow(const Jet< T, N > &f, double g)
Definition: jet.h:570
#define abs(x)
Definition: datatypes.h:17
EIGEN_DEVICE_FUNC Derived & derived()
Definition: EigenBase.h:45
Definition: pytypes.h:897


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:44:49