* Bug 16246 fixed: now isvector works for all generic types 33/21133/17
Stéphane MOTTELET [Tue, 19 Nov 2019 15:10:39 +0000 (16:10 +0100)]
http://bugzilla.scilab.org/show_bug.cgi?id=16246

Change-Id: Ied0e54ebbda3233c42a349295ca5bb15d74766de

15 files changed:
scilab/CHANGES.md
scilab/modules/ast/includes/types/arrayof.hxx
scilab/modules/ast/includes/types/list.hxx
scilab/modules/ast/includes/types/types.hxx
scilab/modules/ast/src/cpp/types/list.cpp
scilab/modules/ast/src/cpp/types/types.cpp
scilab/modules/elementary_functions/includes/elem_func_gw.hxx
scilab/modules/elementary_functions/includes/gw_elementary_functions.h
scilab/modules/elementary_functions/sci_gateway/cpp/elem_func_gw.cpp
scilab/modules/elementary_functions/sci_gateway/cpp/elem_func_gw/elem_func_gw.vcxproj
scilab/modules/elementary_functions/sci_gateway/cpp/elem_func_gw/elem_func_gw.vcxproj.filters
scilab/modules/elementary_functions/sci_gateway/cpp/sci_isvector.cpp
scilab/modules/elementary_functions/tests/nonreg_tests/bug_16246.tst [new file with mode: 0644]
scilab/modules/elementary_functions/tests/unit_tests/isvector.tst [new file with mode: 0644]
scilab/modules/overloading/macros/%r_isvector.sci [new file with mode: 0644]

index fb04c62..5c1299b 100644 (file)
@@ -305,6 +305,7 @@ Bug Fixes
 * [#16230](http://bugzilla.scilab.org/show_bug.cgi?id=16230): `MSWin>scilab --help` missed displaying some options like `-args..`, `-noatomsautoload`, etc.
 * [#16242](http://bugzilla.scilab.org/show_bug.cgi?id=16242): `loadmatfile()` could not read Octave native text data files.
 * [#16245](http://bugzilla.scilab.org/show_bug.cgi?id=16245): `gsort` could not sort booleans.
+* [#16246](http://bugzilla.scilab.org/show_bug.cgi?id=16246): `isvector` was broken for sparse matrices.
 * [#16257](http://bugzilla.scilab.org/show_bug.cgi?id=16257): `blockdiag()` implemented to replace `sysdiag()`, improved and extended to strings.
 * [#16259](http://bugzilla.scilab.org/show_bug.cgi?id=16259): * and .* multiplications involving a sparse boolean and a double, or involving 2 booleans, were not implemented.
 * [#16260](http://bugzilla.scilab.org/show_bug.cgi?id=16260): overloading `nnz` was not possible (regression).
index 726880d..1d686c9 100644 (file)
@@ -187,28 +187,6 @@ public :
     // The function is not write here because we needs to create a Bool which inherits from ArrayOf<int>
     // so it will create a cyclic dependency... so the body of the function is in bool.hxx after the Bool definition.
     virtual bool neg(InternalType *& out) override;
-
-    virtual bool isVector() //only one dim must be != 1
-    {
-        bool bFirstChance = false;
-
-        for (int i = 0 ; i < m_iDims ; i++)
-        {
-            if (m_piDims[i] != 1)
-            {
-                if (bFirstChance == true)
-                {
-                    return false;
-                }
-                else
-                {
-                    bFirstChance = true;
-                }
-            }
-        }
-        return true;
-    }
-
     virtual bool isComplex() override
     {
         return m_pImgData != NULL;
index cd91f29..7fad5fd 100644 (file)
@@ -32,6 +32,7 @@ protected :
     List(List *_oListCopyMe);
 public :
     int                             getSize() const override;
+    bool                            isVector() override;
 
     void                            whoAmI(void) override
     {
index eb5e175..ea8d415 100644 (file)
@@ -61,6 +61,7 @@ public :
     }
 
     bool                        isScalar();
+    virtual bool                isVector();
 
     /*commun functions*/
     virtual int                  getCols()
index 51a7c04..d6fcb39 100644 (file)
@@ -113,6 +113,11 @@ int List::getSize() const
     return static_cast<int>(m_plData->size());
 }
 
+bool List::isVector()
+{
+    return false;
+}
+
 /**
 ** append(InternalType *_typedValue)
 ** Append the given value to the end of the List
index 4eb5286..15d2661 100644 (file)
@@ -59,6 +59,20 @@ bool GenericType::isScalar() //2 dims and each dim == 1
     return false;
 }
 
+bool GenericType::isVector()
+{
+    int iCount = 0;
+    for (int i = 0; i < m_iDims && iCount < 2; ++i)
+    {
+        if (m_piDims[i] != 1)
+        {
+            iCount++;
+        }
+    }
+
+    return iCount < 2; // a Scalar is a Vector
+}
+
 bool GenericType::isIdentity(void)
 {
     for (int i = 0; i < getDims(); i++)
index 86c5326..4eb2a01 100644 (file)
@@ -70,6 +70,7 @@ CPP_GATEWAY_PROTOTYPE(sci_imult);
 CPP_GATEWAY_PROTOTYPE(sci_int);
 CPP_GATEWAY_PROTOTYPE(sci_isequal);
 CPP_GATEWAY_PROTOTYPE(sci_isreal);
+CPP_GATEWAY_PROTOTYPE(sci_isvector);
 CPP_GATEWAY_PROTOTYPE(sci_kron);
 CPP_GATEWAY_PROTOTYPE(sci_linspace);
 CPP_GATEWAY_PROTOTYPE(sci_log);
index 4c0d693..62fef97 100644 (file)
@@ -69,7 +69,7 @@ STACK_GATEWAY_PROTOTYPE(sci_testmatrix);
 //STACK_GATEWAY_PROTOTYPE(sci_base2dec);
 STACK_GATEWAY_PROTOTYPE(sci_dec2base);
 //STACK_GATEWAY_PROTOTYPE(sci_log10);
-C_GATEWAY_PROTOTYPE(sci_isvector);
+//C_GATEWAY_PROTOTYPE(sci_isvector);
 C_GATEWAY_PROTOTYPE(sci_issquare);
 
 #endif /*  __GW_ELEMENTARIES_FUNCTIONS__ */
index f6243ab..f8f7946 100644 (file)
@@ -64,6 +64,7 @@ int ElemFuncModule::Load()
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"int", &sci_int, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isreal", &sci_isreal, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isequal", &sci_isequal, MODULE_NAME));
+    symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isvector", &sci_isvector, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"kron", &sci_kron, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"linspace", &sci_linspace, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log", &sci_log, MODULE_NAME));
index b4c1730..f0ca972 100644 (file)
@@ -272,6 +272,7 @@ lib /DEF:"$(ProjectDir)elementary_functions_Import.def" /SUBSYSTEM:WINDOWS /MACH
   <ItemGroup>
     <ClInclude Include="..\..\..\includes\dynlib_elementary_functions_gw.h" />
     <ClInclude Include="..\..\..\includes\elem_func_gw.hxx" />
+    <ClInclude Include="..\..\..\includes\gw_elementary_functions.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="elementary_functions_f_Import.def" />
index c0c34ae..34b5d4c 100644 (file)
     <ClInclude Include="..\..\..\includes\dynlib_elementary_functions_gw.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\includes\gw_elementary_functions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="elementary_functions_f_Import.def">
index 9eeaa6c..21057f1 100644 (file)
@@ -1,6 +1,7 @@
 /*
 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
+* Copyright (C) 2019 - Stéphane Mottelet
 *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
 *
 */
 /*--------------------------------------------------------------------------*/
+#include "function.hxx"
+#include "arrayof.hxx"
+#include "overload.hxx"
+#include "bool.hxx"
+
 extern "C"
 {
-#include "api_scilab.h"
 #include "Scierror.h"
 #include "localization.h"
-#include "gw_elementary_functions.h"
 }
 
-static const char fname[] = "isvector";
 /*--------------------------------------------------------------------------*/
-int sci_isvector(scilabEnv env, int nin, scilabVar* in, int nopt, scilabOpt opt, int nout, scilabVar* out)
+
+types::Function::ReturnValue sci_isvector(types::typed_list &in, int _iRetCount, types::typed_list &out)
 {
-    if (nin != 1)
+    if (in.size() != 1)
     {
-        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), fname, 1);
-        return 1;
+        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "isvector", 1);
+        return types::Function::Error;
     }
 
-    if (nout > 1)
+    if (out.size() >  1)
     {
-        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), fname, 1);
-        return 1;
+        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "isvector", 1);
+        return types::Function::Error;
     }
 
-    out[0] = scilab_createBoolean(env, scilab_isVector(env, in[0]));
-    return 0;
+    if (in[0]->isTList() || in[0]->isMList() || in[0]->isGenericType() == false)
+    {
+        std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_isvector";
+        return Overload::call(wstFuncName, in, _iRetCount, out);
+    }
+    else
+    {
+        types::GenericType *pIn = in[0]->getAs<types::GenericType>();
+        out.push_back(new types::Bool(pIn->isVector() && pIn->isScalar() == false));
+        return types::Function::OK;
+    }
 }
diff --git a/scilab/modules/elementary_functions/tests/nonreg_tests/bug_16246.tst b/scilab/modules/elementary_functions/tests/nonreg_tests/bug_16246.tst
new file mode 100644 (file)
index 0000000..b2a277e
--- /dev/null
@@ -0,0 +1,21 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2019 - 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 16246 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/16246
+//
+// <-- Short Description -->
+// isvector(sparse([1 2])) returns %F  (6.0 Regression)
+
+assert_checktrue(isvector(sparse([1 2])));
+assert_checktrue(isvector(sparse([1 2]')));
+assert_checkfalse(isvector(sparse([1 2;3 4])));
diff --git a/scilab/modules/elementary_functions/tests/unit_tests/isvector.tst b/scilab/modules/elementary_functions/tests/unit_tests/isvector.tst
new file mode 100644 (file)
index 0000000..3e392e2
--- /dev/null
@@ -0,0 +1,47 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// unit tests for isvector() function
+// =============================================================================
+
+assert_checkfalse(isvector(eye()));
+assert_checkfalse(isvector([]));
+assert_checkfalse(isvector(1));         // questionnable
+assert_checktrue(isvector(1:3));
+assert_checktrue(isvector((1:3)'));
+assert_checktrue(isvector(cat(3,1,2,3)));
+assert_checktrue(isvector(cat(5,1,2,3)));
+
+// Sparse
+assert_checkfalse(isvector(sparse(eye())));
+assert_checkfalse(isvector(sparse([])));
+assert_checkfalse(isvector(sparse(1)));  // questionnable
+assert_checktrue(isvector(sparse(1:3)));
+assert_checktrue(isvector(sparse((1:3)')));
+
+// Cell
+assert_checkfalse(isvector({}));
+assert_checkfalse(isvector({1}));       // questionnable
+assert_checktrue(isvector({1 2 3}));
+assert_checktrue(isvector({1 ; 2 ; 3}));
+assert_checktrue(isvector(cat(3,{1},{2},{3})));
+
+// Struct
+clear s
+s.r = %pi;   assert_checkfalse(isvector(s));  // questionnable
+s(2).r = %e; assert_checktrue(isvector(s));
+clear
+s(1,1,2).r = %e; assert_checktrue(isvector(s));
+
+// Rationals : isvector always crashes
+//assert_checkfalse(isvector(1/%s));         // questionnable
+//assert_checktrue(isvector((1:3)./%s));
+//assert_checktrue(isvector((1:3)'./%s));
+//assert_checktrue(isvector(cat(3,1,2,3)./%s));
diff --git a/scilab/modules/overloading/macros/%r_isvector.sci b/scilab/modules/overloading/macros/%r_isvector.sci
new file mode 100644 (file)
index 0000000..263ca0f
--- /dev/null
@@ -0,0 +1,11 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+//
+// Copyright (C) 2020 - Stéphane MOTTELET
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// For more information, see the COPYING file which you should have received
+// along with this program.
+
+function b = %r_isvector(r)
+    b = isvector(r.num)
+endfunction