* Bug 16559 fixed: size(A,'*') was 0 for A = speye(2^16,2^16) 02/21602/7
mottelet [Tue, 20 Oct 2020 12:19:02 +0000 (14:19 +0200)]
http://bugzilla.scilab.org/show_bug.cgi?id=16559

The patch also improves the speed of colon extraction A(:,...,:)
and A(:) when A is sparse.

Change-Id: If7cde827079d6d4d16fb66859f8a6aed592289f1

scilab/CHANGES.md
scilab/modules/ast/src/cpp/types/sparse.cpp
scilab/modules/elementary_functions/sci_gateway/cpp/sci_size.cpp
scilab/modules/elementary_functions/tests/nonreg_tests/bug_16559.tst [new file with mode: 0644]

index e94a97e..cdeb69f 100644 (file)
@@ -345,6 +345,7 @@ Bug Fixes
 * [#16551](https://bugzilla.scilab.org/16551): `num2cell` returned {} for any input array of empty strings.
 * [#16553](https://bugzilla.scilab.org/16553): `unique(["" ""])` returned `["" ""]`.
 * [#16557](https://bugzilla.scilab.org/16557): `macr2tree` + `tree2code` translated `e={2}` into `"e=1"` and `e={2,"ab"}` into `"e=[2,"ab"]"`.
+* [#16559](https://bugzilla.scilab.org/16553): `isempty(A)` was true for sparse matrix of dimension 2^16 or larger.
 
 
 ### Bugs fixed in 6.1.0:
index 6882f77..b57bab9 100644 (file)
@@ -2004,11 +2004,68 @@ GenericType* Sparse::extract(typed_list* _pArgs)
 {
     Sparse* pOut = NULL;
     int iDims = (int)_pArgs->size();
+    bool bAllColonIndex = true;
     typed_list pArg;
 
     int* piMaxDim = new int[iDims];
     int* piCountDim = new int[iDims];
 
+    for (int i=0; i<iDims; i++)
+    {
+        bAllColonIndex &= (*_pArgs)[i]->isColon();
+    }
+
+    if (bAllColonIndex)
+    {
+        if (iDims > 1) // a(:,...,:)
+        {
+            return this;
+        }
+        else // a(:)
+        {
+            if (isVector())
+            {
+                if (getCols() == 1)
+                {
+                    return this;
+                }
+                else
+                {
+                    this->transpose((types::InternalType *&)pOut);
+                    return pOut;
+                }
+            }
+            pOut = new types::Sparse(getRows()*getCols(), 1, isComplex());
+            if (isComplex())
+            {
+                CplxSparse_t *sp = pOut->matrixCplx;
+                sp->reserve(nonZeros());
+                int k=0;
+                for (size_t i=0; i<getRows(); ++i)
+                {
+                    for (Sparse::CplxSparse_t::InnerIterator it(*matrixCplx, i); it; ++it)
+                    {
+                        sp->insert(it.col()*getRows() + i, 0) = it.value();
+                    }
+                }
+            }
+            else
+            {
+                RealSparse_t *sp = pOut->matrixReal;
+                sp->reserve(nonZeros());
+                int k=0;
+                for (size_t i=0; i<getRows(); ++i)
+                {
+                    for (Sparse::RealSparse_t::InnerIterator it(*matrixReal, i); it; ++it)
+                    {
+                        sp->insert(it.col()*getRows() + i, 0) = it.value();
+                    }
+                }
+            }
+        }
+        return pOut;
+    }
+
     //evaluate each argument and replace by appropriate value and compute the count of combinations
     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
     if (iSeqCount == 0)
index 85cdf0b..c7e74b4 100644 (file)
@@ -135,7 +135,14 @@ types::Function::ReturnValue sci_size(types::typed_list &in, int _iRetCount, typ
                         }
                         break;
                     case 0 : //"*"
-                        pdbl[0] = in[0]->getAs<types::GenericType>()->getSize();
+                        if (in[0]->isSparse())
+                        {
+                            pdbl[0] = (double)piDims[0]*(double)piDims[1];
+                        }
+                        else
+                        {
+                            pdbl[0] = in[0]->getAs<types::GenericType>()->getSize();
+                        }
                         break;
                     default : //"r"
                         if (iMode > iDims)
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_16559.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_16559.tst
new file mode 100644 (file)
index 0000000..32ffaee
--- /dev/null
@@ -0,0 +1,22 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - St├ęphane MOTTELET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 16559 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/16559
+//
+// <-- Short Description -->
+// A(:,:) is empty for sparse matrix of dimension 2^16 or larger
+
+n = 2^16;
+A = speye(n,n);
+assert_checkequal(size(A,"*"),n*n);
+assert_checkfalse(isempty(A));
\ No newline at end of file