1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Copyright (C) 2009-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "main.h"
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> EIGEN_DONT_INLINE T copy(const T& x)
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return x;
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> void stable_norm(const MatrixType& m)
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  /* this test covers the following files:
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath     StableNorm.h
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  using std::sqrt;
237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  using std::abs;
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename MatrixType::Index Index;
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename MatrixType::Scalar Scalar;
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NumTraits<Scalar>::Real RealScalar;
272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  bool complex_real_product_ok = true;
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // Check the basic machine-dependent constants.
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int ibeta, it, iemin, iemax;
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ibeta = std::numeric_limits<RealScalar>::radix;         // base for floating-point numbers
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    it    = std::numeric_limits<RealScalar>::digits;        // number of base-beta digits in mantissa
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    iemin = std::numeric_limits<RealScalar>::min_exponent;  // minimum exponent
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    iemax = std::numeric_limits<RealScalar>::max_exponent;  // maximum exponent
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY( (!(iemin > 1 - 2*it || 1+it>iemax || (it==2 && ibeta<5) || (it<=4 && ibeta <= 3 ) || it<2))
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           && "the stable norm algorithm cannot be guaranteed on this computer");
412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Scalar inf = std::numeric_limits<RealScalar>::infinity();
432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    if(NumTraits<Scalar>::IsComplex && (numext::isnan)(inf*RealScalar(1)) )
442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    {
452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      complex_real_product_ok = false;
462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      static bool first = true;
472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      if(first)
482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        std::cerr << "WARNING: compiler mess up complex*real product, " << inf << " * " << 1.0 << " = " << inf*RealScalar(1) << std::endl;
492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      first = false;
502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Index rows = m.rows();
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Index cols = m.cols();
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // get a non-zero random factor
587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Scalar factor = internal::random<Scalar>();
597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  while(numext::abs2(factor)<RealScalar(1e-4))
607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    factor = internal::random<Scalar>();
617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Scalar big = factor * ((std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4));
627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  factor = internal::random<Scalar>();
647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  while(numext::abs2(factor)<RealScalar(1e-4))
657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    factor = internal::random<Scalar>();
667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  Scalar small = factor * ((std::numeric_limits<RealScalar>::min)() * RealScalar(1e4));
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType  vzero = MatrixType::Zero(rows, cols),
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              vrand = MatrixType::Random(rows, cols),
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              vbig(rows, cols),
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              vsmall(rows,cols);
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  vbig.fill(big);
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  vsmall.fill(small);
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1));
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.stableNorm(),      vrand.norm());
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.blueNorm(),        vrand.norm());
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.hypotNorm(),       vrand.norm());
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  RealScalar size = static_cast<RealScalar>(m.size());
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // test numext::isfinite
842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY(!(numext::isfinite)( std::numeric_limits<RealScalar>::infinity()));
852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY(!(numext::isfinite)(sqrt(-abs(big))));
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test overflow
882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((numext::isfinite)(sqrt(size)*abs(big)));
897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_NOT_APPROX(sqrt(copy(vbig.squaredNorm())), abs(sqrt(size)*big)); // here the default norm must fail
907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_APPROX(vbig.stableNorm(), sqrt(size)*abs(big));
917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_APPROX(vbig.blueNorm(),   sqrt(size)*abs(big));
927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_APPROX(vbig.hypotNorm(),  sqrt(size)*abs(big));
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test underflow
952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  VERIFY((numext::isfinite)(sqrt(size)*abs(small)));
967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_NOT_APPROX(sqrt(copy(vsmall.squaredNorm())),   abs(sqrt(size)*small)); // here the default norm must fail
977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_APPROX(vsmall.stableNorm(), sqrt(size)*abs(small));
987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_APPROX(vsmall.blueNorm(),   sqrt(size)*abs(small));
997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  VERIFY_IS_APPROX(vsmall.hypotNorm(),  sqrt(size)*abs(small));
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // Test compilation of cwise() version
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.colwise().stableNorm(),      vrand.colwise().norm());
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.colwise().blueNorm(),        vrand.colwise().norm());
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.colwise().hypotNorm(),       vrand.colwise().norm());
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.rowwise().stableNorm(),      vrand.rowwise().norm());
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.rowwise().blueNorm(),        vrand.rowwise().norm());
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(),       vrand.rowwise().norm());
1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // test NaN, +inf, -inf
1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  MatrixType v;
1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Index i = internal::random<Index>(0,rows-1);
1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  Index j = internal::random<Index>(0,cols-1);
1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // NaN
1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v = vrand;
1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v(i,j) = std::numeric_limits<RealScalar>::quiet_NaN();
1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.squaredNorm()));   VERIFY((numext::isnan)(v.squaredNorm()));
1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.norm()));          VERIFY((numext::isnan)(v.norm()));
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.stableNorm()));    VERIFY((numext::isnan)(v.stableNorm()));
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.blueNorm()));      VERIFY((numext::isnan)(v.blueNorm()));
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.hypotNorm()));     VERIFY((numext::isnan)(v.hypotNorm()));
1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // +inf
1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v = vrand;
1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v(i,j) = std::numeric_limits<RealScalar>::infinity();
1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.squaredNorm()));   VERIFY(isPlusInf(v.squaredNorm()));
1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.norm()));          VERIFY(isPlusInf(v.norm()));
1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.stableNorm()));
1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    if(complex_real_product_ok){
1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      VERIFY(isPlusInf(v.stableNorm()));
1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.blueNorm()));      VERIFY(isPlusInf(v.blueNorm()));
1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.hypotNorm()));     VERIFY(isPlusInf(v.hypotNorm()));
1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // -inf
1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v = vrand;
1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v(i,j) = -std::numeric_limits<RealScalar>::infinity();
1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.squaredNorm()));   VERIFY(isPlusInf(v.squaredNorm()));
1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.norm()));          VERIFY(isPlusInf(v.norm()));
1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.stableNorm()));
1462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    if(complex_real_product_ok) {
1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      VERIFY(isPlusInf(v.stableNorm()));
1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
1492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.blueNorm()));      VERIFY(isPlusInf(v.blueNorm()));
1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.hypotNorm()));     VERIFY(isPlusInf(v.hypotNorm()));
1512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // mix
1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Index i2 = internal::random<Index>(0,rows-1);
1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Index j2 = internal::random<Index>(0,cols-1);
1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v = vrand;
1582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v(i,j) = -std::numeric_limits<RealScalar>::infinity();
1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    v(i2,j2) = std::numeric_limits<RealScalar>::quiet_NaN();
1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.squaredNorm()));   VERIFY((numext::isnan)(v.squaredNorm()));
1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.norm()));          VERIFY((numext::isnan)(v.norm()));
1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.stableNorm()));    VERIFY((numext::isnan)(v.stableNorm()));
1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.blueNorm()));      VERIFY((numext::isnan)(v.blueNorm()));
1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY(!(numext::isfinite)(v.hypotNorm()));     VERIFY((numext::isnan)(v.hypotNorm()));
1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // stableNormalize[d]
1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX(vrand.stableNormalized(), vrand.normalized());
1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    MatrixType vcopy(vrand);
1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    vcopy.stableNormalize();
1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX(vcopy, vrand.normalized());
1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX((vrand.stableNormalized()).norm(), RealScalar(1));
1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX(vcopy.norm(), RealScalar(1));
1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX((vbig.stableNormalized()).norm(), RealScalar(1));
1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX((vsmall.stableNormalized()).norm(), RealScalar(1));
1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    RealScalar big_scaling = ((std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4));
1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX(vbig/big_scaling, (vbig.stableNorm() * vbig.stableNormalized()).eval()/big_scaling);
1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    VERIFY_IS_APPROX(vsmall, vsmall.stableNorm() * vsmall.stableNormalized());
1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_stable_norm()
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i = 0; i < g_repeat; i++) {
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_1( stable_norm(Matrix<float, 1, 1>()) );
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_2( stable_norm(Vector4d()) );
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_3( stable_norm(VectorXd(internal::random<int>(10,2000))) );
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_4( stable_norm(VectorXf(internal::random<int>(10,2000))) );
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_5( stable_norm(VectorXcd(internal::random<int>(10,2000))) );
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
193