# HG changeset patch
# User Clemens Buchacher
# Date 1368966676 -7200
# Sun May 19 14:31:16 2013 +0200
# Node ID f67013b1da721c1bd72f42f87c18ddd91dd25f29
# Parent a463f6b18f7de3d79d511ddb4324b0c6a1074410
normalize multiplication result instead of operand
The operand of a multiplication with base_det is normalized to c * 2^e,
such that 0.5 <= c < 1. The mantissa is multiplied by c, and the
exponent is updated separately. After each multiplication, the mantissa
is therefore smaller by a up to a factor 2. Despite the normalization of
the operands, the mantissa can therefore become very small. Eventually,
each multiplication suffers from severe loss of precision and the
mantissa can even get rounded to 0.
Instead, normalize the mantissa after multiplication with the operand.
This makes the operation insensitive to the number of operands.
The change may degrade accuracy in case of operands close to the maximum
or minimum representable floating point numbers, but that is not a
problem base_det tries to solve.
Bug report: https://savannah.gnu.org/bugs/?39014
Reported-by: Marco Caliari
Fix-proposed-by: Stephen Montgomery-Smith
diff -r a463f6b18f7d -r f67013b1da72 libinterp/corefcn/det.cc
--- a/libinterp/corefcn/det.cc Sat May 11 11:58:47 2013 +0200
+++ b/libinterp/corefcn/det.cc Sun May 19 14:31:16 2013 +0200
@@ -247,6 +247,7 @@
/*
%!assert (det ([1, 2; 3, 4]), -2, 10*eps)
%!assert (det (single ([1, 2; 3, 4])), single (-2), 10*eps ("single"))
+%!assert (det (eye (2000)), 1)
%!error det ()
%!error det (1, 2)
%!error det ([1, 2; 3, 4; 5, 6])
diff -r a463f6b18f7d -r f67013b1da72 liboctave/numeric/DET.h
--- a/liboctave/numeric/DET.h Sat May 11 11:58:47 2013 +0200
+++ b/liboctave/numeric/DET.h Sun May 19 14:31:16 2013 +0200
@@ -71,7 +71,8 @@
void operator *= (T t)
{
int e;
- c2 *= xlog2 (t, e);
+ c2 *= t;
+ c2 = xlog2(c2, e);
e2 += e;
}