sc/source/core/tool/interpr5.cxx |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

New commits:
commit e1e73a97b20af862f2fb914cb16a4f74c3ad31cb
Author: Dennis Francis <dennisfrancis...@gmail.com>
Date:   Fri Oct 23 03:28:37 2015 +0530

    tdf#32834 : improve the precision of MDETERM calculation
    
    MDETERM uses lcl_LUP_decompose() which as the name suggests does LUP 
decomposition.
    This patch allows additive cancellations to occur in a cleaner way while 
doing the *only*
    additive operation in LUP decomposition, that is while computing Shur 
complement.
    This patch does not change the high level semantics of the algorithm.
    Also note that this change makes improvement only in the case where matrix 
elements entered
    by the user are *integers*. The change allows MDETERM to evaluate to exact 
0.0 for
    singular integer matrices.
    
    The steps to calculate Shur complement are :
    
    for i = k+1 to n
      aik = aik / akk;
      for j = k+1 to n
        aij = aij - akj*aik
    
    This is now modified as :
    
    for i = k+1 to n
      for j = k+1 to n
        aij = ( aij*akk - akj*aik ) / akk
    
    Without this change MDETERM() for certain singular matrices used to 
evaluate to a tiny non zero value,
    which also caused MINVERSE() to generate a wrong output.
    An example of such a matrix is :
    1 2 3
    4 5 6
    7 8 9
    
    Change-Id: Idd4211ddceab1b758fd05bfd57f7eecd5d4fd1a0
    Reviewed-on: https://gerrit.libreoffice.org/19534
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Eike Rathke <er...@redhat.com>

diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 88cd12d..eac7cd4 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -711,11 +711,12 @@ static int lcl_LUP_decompose( ScMatrix* mA, const SCSIZE 
n,
         // Compute Schur complement.
         for (SCSIZE i = k+1; i < n; ++i)
         {
-            double fTmp = mA->GetDouble( k, i) / mA->GetDouble( k, k);
-            mA->PutDouble( fTmp, k, i);
+            double fNum = mA->GetDouble( k, i);
+            double fDen = mA->GetDouble( k, k);
+            mA->PutDouble( fNum/fDen, k, i);
             for (SCSIZE j = k+1; j < n; ++j)
-                mA->PutDouble( mA->GetDouble( j, i) - fTmp * mA->GetDouble( j,
-                            k), j, i);
+                mA->PutDouble( ( mA->GetDouble( j, i) * fDen  -
+                            fNum * mA->GetDouble( j, k) ) / fDen, j, i);
         }
     }
 #if OSL_DEBUG_LEVEL > 1
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to