From ac673bda27883d4bb4085fa326380aaed29b1a70 Mon Sep 17 00:00:00 2001 From: Tor Myklebust Date: Sun, 20 Apr 2014 15:29:10 -0400 Subject: [PATCH] More safeguards against numerical ridiculousness. --- .../apache/spark/mllib/optimization/NNLSbyPCG.scala | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mllib/src/main/scala/org/apache/spark/mllib/optimization/NNLSbyPCG.scala b/mllib/src/main/scala/org/apache/spark/mllib/optimization/NNLSbyPCG.scala index 9572ef7f8f2a2..779f374158c3b 100644 --- a/mllib/src/main/scala/org/apache/spark/mllib/optimization/NNLSbyPCG.scala +++ b/mllib/src/main/scala/org/apache/spark/mllib/optimization/NNLSbyPCG.scala @@ -39,14 +39,18 @@ object NNLSbyPCG { def steplen(dir: DoubleMatrix, resid: DoubleMatrix): Double = { val top = SimpleBlas.dot(dir, resid) SimpleBlas.gemv(1.0, ata, dir, 0.0, scratch) - top / SimpleBlas.dot(scratch, dir) + // Push the denominator upward very slightly to avoid infinities and silliness + top / (SimpleBlas.dot(scratch, dir) + 1e-20) } // stopping condition def stop(step: Double, ndir: Double, nx: Double): Boolean = { - ((step != step) - || (step < 1e-6) - || (ndir < 1e-12 * nx)) + ((step != step) // NaN + || (step < 1e-6) // too small or negative + || (step > 1e40) // too small; almost certainly numerical problems + || (ndir < 1e-12 * nx) // gradient relatively too small + || (ndir < 1e-32) // gradient absolutely too small; numerical issues may lurk + ) } val grad = new DoubleMatrix(n, 1) @@ -134,5 +138,4 @@ object NNLSbyPCG { } x.data } - }