* Bug #12747 fixed - legendre() now accepts the -1 and 1 values for the third argument. 29/12129/2
Adeline CARNIS [Thu, 25 Jul 2013 13:11:11 +0000 (15:11 +0200)]
Change-Id: I43ac743c3ab0f31b5cda35b8c140d101a5f61b8e

scilab/CHANGES_5.5.X
scilab/modules/elementary_functions/src/fortran/slatec/dxlegf.f
scilab/modules/special_functions/help/en_US/legendre.xml
scilab/modules/special_functions/sci_gateway/c/sci_legendre.c
scilab/modules/special_functions/tests/nonreg_tests/bug_12747.dia.ref [new file with mode: 0644]
scilab/modules/special_functions/tests/nonreg_tests/bug_12747.tst [new file with mode: 0644]
scilab/modules/special_functions/tests/unit_tests/legendre.dia.ref [new file with mode: 0644]
scilab/modules/special_functions/tests/unit_tests/legendre.tst [new file with mode: 0644]

index c753da0..0cf9026 100644 (file)
@@ -498,3 +498,5 @@ Bug fixes
 * Bug #12736 fixed - In SciNotes, the Completion window appeared only in first tab.
 
 * Bug #12758 fixed - Focus issue with plot3d() fixed.
+
+* Bug #12747 fixed - legendre() now accepts the -1 and 1 values for the third argument.
\ No newline at end of file
index 11fc8d9..5ba6a02 100644 (file)
@@ -187,7 +187,7 @@ C
       IF(MU2.LT.MU1) GO TO 400
       IF(MU1.LT.0) GO TO 400
 *      IF(THETA.LE.0.D0.OR.THETA.GT.PI2) GO TO 420
-      IF(X.LT.0.D0.OR.X.GE.1.d0) GO TO 420
+      IF(X.LT.0.D0.OR.X.GT.1.d0) GO TO 420
       IF(ID.LT.1.OR.ID.GT.4) GO TO 400
       IF((MU1.NE.MU2).AND.(NUDIFF.GT.0)) GO TO 400
 C
index 8f32cd1..277340d 100644 (file)
@@ -42,8 +42,8 @@
                 <term>x</term>
                 <listitem>
                     <para>
-                        real (row) vector (elements of <literal>x</literal> must be in
-                        the <literal>(-1,1)</literal> interval)
+                        real matrix(elements of <literal>x</literal> must be in
+                        the <literal>[-1,1]</literal> interval)
                     </para>
                 </listitem>
             </varlistentry>
index d1bd529..dd006bf 100644 (file)
@@ -1,14 +1,14 @@
 /*
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) ????-2008 - Universit√© de Nancy - Bruno Pincon <Bruno.Pincon@iecn.u-nancy.fr>
- *
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
- *
- */
+* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+* Copyright (C) ????-2008 - Universit√© de Nancy - Bruno Pincon <Bruno.Pincon@iecn.u-nancy.fr>
+*
+* This file must be used under the terms of the CeCILL.
+* This source file is licensed as described in the file COPYING, which
+* you should have received as part of this distribution.  The terms
+* are also available at
+* http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+*
+*/
 
 #include <string.h>
 #include "api_scilab.h"
@@ -67,6 +67,10 @@ int sci_legendre(char *fname, unsigned long fname_len)
     double* pdblPQA = NULL;
     int* piPQA      = NULL;
 
+    int iType1 = 0;
+    int iType2 = 0;
+    int iType3 = 0;
+
     CheckInputArgument(pvApiCtx, 3, 4);
     CheckOutputArgument(pvApiCtx, 1, 1);
 
@@ -79,6 +83,19 @@ int sci_legendre(char *fname, unsigned long fname_len)
         return 1;
     }
 
+    sciErr = getVarType(pvApiCtx, piAddr1, &iType1);
+    if (sciErr.iErr)
+    {
+        printError(&sciErr, 0);
+        return 1;
+    }
+
+    if (iType1 != sci_matrix)
+    {
+        Scierror(999, _("%s: Wrong type for input argument #%d: Integer or vector of integers expected.\n"), fname, 1);
+        return 1;
+    }
+
     sciErr = getMatrixOfDouble(pvApiCtx, piAddr1, &mN, &nN, &pdblN);
     if (sciErr.iErr)
     {
@@ -88,7 +105,7 @@ int sci_legendre(char *fname, unsigned long fname_len)
 
     if (verify_cstr(pdblN, mN * nN, &n1, &n2) == 0)
     {
-        Scierror(999, _("%s: Wrong type for first input argument.\n"), fname);
+        Scierror(999, _("%s: Wrong type for input argument #%d: Integer >= %d expected.\n"), fname, 1, 0);
         return 1;
     }
 
@@ -106,6 +123,19 @@ int sci_legendre(char *fname, unsigned long fname_len)
         return 1;
     }
 
+    sciErr = getVarType(pvApiCtx, piAddr2, &iType2);
+    if (sciErr.iErr)
+    {
+        printError(&sciErr, 0);
+        return 1;
+    }
+
+    if (iType2 != sci_matrix)
+    {
+        Scierror(999, _("%s: Wrong type for input argument #%d: Integer or vector of integers expected.\n"), fname, 2);
+        return 1;
+    }
+
     sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &mM, &nM, &pdblM);
     if (sciErr.iErr)
     {
@@ -115,7 +145,7 @@ int sci_legendre(char *fname, unsigned long fname_len)
 
     if (verify_cstr(pdblM, mM * nM, &m1, &m2) == 0)
     {
-        Scierror(999, _("%s: Wrong type for input argument #%d.\n"), fname, 2);
+        Scierror(999, _("%s: Wrong type for input argument #%d: Integer >= %d expected.\n"), fname, 2, 0);
         return 1;
     }
 
@@ -139,7 +169,14 @@ int sci_legendre(char *fname, unsigned long fname_len)
         return 1;
     }
 
-    if (isVarComplex(pvApiCtx, piAddr3))
+    sciErr = getVarType(pvApiCtx, piAddr3, &iType3);
+    if (sciErr.iErr)
+    {
+        printError(&sciErr, 0);
+        return 1;
+    }
+
+    if (iType3 != sci_matrix || isVarComplex(pvApiCtx, piAddr3))
     {
         Scierror(999, _("%s: Wrong type for input argument #%d: Real matrix expected.\n"), fname, 3);
         return 1;
@@ -156,9 +193,9 @@ int sci_legendre(char *fname, unsigned long fname_len)
 
     for ( i = 0 ; i < mnx ; i++ )
     {
-        if ((fabs(pdblX[i]) < 1.0) == 0)
+        if ((fabs(pdblX[i]) <= 1.0) == 0)
         {
-            Scierror(999, _("%s: Wrong value for input argument #%d: Matrix with elements in (%d,%d) expected.\n"), fname, 3, -1, 1);
+            Scierror(999, _("%s: Wrong value for input argument #%d: Matrix with elements in [%d,%d] expected.\n"), fname, 3, -1, 1);
             return 1;
         }
     }
@@ -216,19 +253,48 @@ int sci_legendre(char *fname, unsigned long fname_len)
 
     for ( i = 0 ; i < mnx ; i++ )
     {
-        xx = fabs(pdblX[i]); /* dxleg computes only for x in [0,1) */
-        C2F(dxlegf) (&dnu1, &nudiff, &m1, &m2, &xx, &id, pdblPQA + i * MNp1, piPQA + i * MNp1, &ierror);
-        if ( ierror != 0 )
+        xx = fabs(pdblX[i]);
+        /* manage the case where xx = 1 with n scalar*/
+        if (N_is_scalar && xx == 1)
         {
-            if ( ierror == 207 ) /* @TODO what is 207 ? */
+            if (m1 == 0)
             {
-                Scierror(999, _("%s: overflow or underflow of an extended range number\n"), fname);
+                pdblPQA[i * MNp1] = 1;
             }
             else
             {
-                Scierror(999, _("%s: error number %d\n"), fname, ierror);
+                pdblPQA[i * MNp1] = 0;
+            }
+
+            if (normalized)
+            {
+                pdblPQA[i * MNp1] = pdblPQA[i * MNp1]  * sqrt(dnu1 + 0.5);
+            }
+
+            piPQA[i * MNp1] = 0;
+
+            for (j = 1; j < MNp1; j++)
+            {
+                pdblPQA[i * MNp1 + j] = 0;
+                piPQA[i * MNp1 + j] = 0;
+            }
+        }
+        else
+        {
+            /* dxleg computes only for x in [0,1] */
+            C2F(dxlegf) (&dnu1, &nudiff, &m1, &m2, &xx, &id, pdblPQA + i * MNp1, piPQA + i * MNp1, &ierror);
+            if ( ierror != 0 )
+            {
+                if ( ierror == 207 ) /* @TODO what is 207 ? */
+                {
+                    Scierror(999, _("%s: overflow or underflow of an extended range number\n"), fname);
+                }
+                else
+                {
+                    Scierror(999, _("%s: error number %d\n"), fname, ierror);
+                }
+                return 0;
             }
-            return 0;
         }
     }
 
diff --git a/scilab/modules/special_functions/tests/nonreg_tests/bug_12747.dia.ref b/scilab/modules/special_functions/tests/nonreg_tests/bug_12747.dia.ref
new file mode 100644 (file)
index 0000000..9d5539a
--- /dev/null
@@ -0,0 +1,26 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- Non-regression test for bug 12747 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=12747
+//
+// <-- Short Description -->
+//    The legendre function did not manage the -1 and 1 values for the third 
+//    argument.
+// =============================================================================
+res = legendre(2,2,-1);
+assert_checkequal(res, 0);
+res = legendre(0, 0:2, [1 -1]);
+expected = [1 1;0 0;0 0]
+ expected  =
+    1.    1.  
+    0.    0.  
+    0.    0.  
+assert_checkequal(res, expected);
diff --git a/scilab/modules/special_functions/tests/nonreg_tests/bug_12747.tst b/scilab/modules/special_functions/tests/nonreg_tests/bug_12747.tst
new file mode 100644 (file)
index 0000000..03a1e78
--- /dev/null
@@ -0,0 +1,25 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+
+// <-- Non-regression test for bug 12747 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=12747
+//
+// <-- Short Description -->
+//    The legendre function did not manage the -1 and 1 values for the third 
+//    argument.
+// =============================================================================
+
+res = legendre(2,2,-1);
+assert_checkequal(res, 0);
+
+res = legendre(0, 0:2, [1 -1]);
+expected = [1 1;0 0;0 0]
+assert_checkequal(res, expected);
diff --git a/scilab/modules/special_functions/tests/unit_tests/legendre.dia.ref b/scilab/modules/special_functions/tests/unit_tests/legendre.dia.ref
new file mode 100644 (file)
index 0000000..c3c9510
--- /dev/null
@@ -0,0 +1,75 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// unit tests for legendre function 
+// =============================================================================
+// Interface
+assert_checkfalse(execstr("legendre()"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong number of input argument(s): %d to %d expected.\n"), "legendre", 3, 4);
+assert_checkerror("legendre()", refMsg);
+assert_checkfalse(execstr("legendre([1 2], [1 2], 1)"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Only one of arg1 and arg2 may be a vector.\n"), "legendre");
+assert_checkerror("legendre([1 2], [1 2], 1)", refMsg);
+assert_checkfalse(execstr("legendre(""r"", 1, [0.9 0.8])"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Integer or vector of integers expected.\n"), "legendre", 1);
+assert_checkerror("legendre(""r"", 1, [0.9 0.8])", refMsg);
+assert_checkfalse(execstr("legendre(1, ""r"", [0.9 0.8])"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Integer or vector of integers expected.\n"), "legendre", 2);
+assert_checkerror("legendre(1, ""r"", [0.9 0.8])", refMsg);
+assert_checkfalse(execstr("legendre(1, 1, ""r"")"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "legendre", 3);
+assert_checkerror("legendre(1, 1, ""r"")", refMsg);
+assert_checkfalse(execstr("legendre(1, 1, %i)"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "legendre", 3);
+assert_checkerror("legendre(1, 1, %i)", refMsg);
+res = legendre(0, 0, [-1 -0.5 0 0.5 1]);
+assert_checkequal(res, [1 1 1 1 1]);
+res = legendre(0:2, 0, [-1 -0.5 0 0.5 1]);
+expected = [1 1 1 1 1;
+            -1 -0.5 0 0.5 1;
+            1 -0.125 -0.5 -0.125 1];
+assert_checkequal(res, expected);
+res = legendre(2, 0:2, [-1 -0.5 0 0.5 1]);
+expected = [1 -0.125 -0.5 -0.125 1;
+            0 1.2990381 0 -1.2990381 0;
+            0 2.25 3 2.25 0];
+assert_checkalmostequal(res, expected, [], %eps);
+res = legendre(2, 0:2, [0 0.5 1 0.9]);
+expected = [-0.5 -0.125 1 0.715;
+            0 -1.2990381 0 -1.1769027;
+            3 2.25 0 0.57];
+assert_checkalmostequal(res, expected, [], %eps);
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6]);
+expected = [-0.5 1 -0.44 0.04;
+            0 0 0.58787754 1.44;
+            3 0 2.88 1.92];
+assert_checkalmostequal(res, expected, [], %eps);
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6]');
+expected = [-0.5 1 -0.44 0.04;
+            0 0 0.58787754 1.44;
+            3 0 2.88 1.92];
+assert_checkalmostequal(res, expected, [], %eps);
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6], "norm");
+expected = [-0.7905694 1.5811388 -0.6957011 0.0632456;
+            0 0 -0.3794733 -0.929516;
+            0.9682458 0 0.929516 0.6196773];
+assert_checkalmostequal(res, expected, [], 1.e-7);
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6]', "norm");
+expected = [-0.7905694 1.5811388 -0.6957011 0.0632456;
+            0 0 -0.3794733 -0.929516;
+            0.9682458 0 0.929516 0.6196773];
+assert_checkalmostequal(res, expected, [], 1.e-7);
+res = legendre(4, 2:4, [0 -0.2 0.2;1 0.7 -1]);
+expected = [-7.5 0 -5.184 9.29475 -5.184 0;
+            0 0 19.752685 -26.769644 -19.752685 0;
+            105 0 96.768 27.3105 96.768 0];
+assert_checkalmostequal(res, expected, [], 1.e-7);
+res = legendre(4, 2:4, [0 -0.2 0.2;1 0.7 -1], "norm");
+expected = [-0.8385255 0 -0.5795888 1.0391846 -0.5795888 0;
+            0 0 -0.5902244 0.7998961 0.5902244 0;
+            1.109265 0 1.0222986 0.2885198 1.0222986 0];
+assert_checkalmostequal(res, expected, [], 1.e-7);
diff --git a/scilab/modules/special_functions/tests/unit_tests/legendre.tst b/scilab/modules/special_functions/tests/unit_tests/legendre.tst
new file mode 100644 (file)
index 0000000..16a36f6
--- /dev/null
@@ -0,0 +1,93 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Adeline CARNIS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+
+// unit tests for legendre function 
+// =============================================================================
+
+// Interface
+assert_checkfalse(execstr("legendre()"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong number of input argument(s): %d to %d expected.\n"), "legendre", 3, 4);
+assert_checkerror("legendre()", refMsg);
+
+assert_checkfalse(execstr("legendre([1 2], [1 2], 1)"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Only one of arg1 and arg2 may be a vector.\n"), "legendre");
+assert_checkerror("legendre([1 2], [1 2], 1)", refMsg);
+
+assert_checkfalse(execstr("legendre(""r"", 1, [0.9 0.8])"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Integer or vector of integers expected.\n"), "legendre", 1);
+assert_checkerror("legendre(""r"", 1, [0.9 0.8])", refMsg);
+
+assert_checkfalse(execstr("legendre(1, ""r"", [0.9 0.8])"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Integer or vector of integers expected.\n"), "legendre", 2);
+assert_checkerror("legendre(1, ""r"", [0.9 0.8])", refMsg);
+
+assert_checkfalse(execstr("legendre(1, 1, ""r"")"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "legendre", 3);
+assert_checkerror("legendre(1, 1, ""r"")", refMsg);
+
+assert_checkfalse(execstr("legendre(1, 1, %i)"   ,"errcatch") == 0);
+refMsg = msprintf(_("%s: Wrong type for input argument #%d: Real matrix expected.\n"), "legendre", 3);
+assert_checkerror("legendre(1, 1, %i)", refMsg);
+
+res = legendre(0, 0, [-1 -0.5 0 0.5 1]);
+assert_checkequal(res, [1 1 1 1 1]);
+
+res = legendre(0:2, 0, [-1 -0.5 0 0.5 1]);
+expected = [1 1 1 1 1;
+            -1 -0.5 0 0.5 1;
+            1 -0.125 -0.5 -0.125 1];
+assert_checkequal(res, expected);
+
+res = legendre(2, 0:2, [-1 -0.5 0 0.5 1]);
+expected = [1 -0.125 -0.5 -0.125 1;
+            0 1.2990381 0 -1.2990381 0;
+            0 2.25 3 2.25 0];
+assert_checkalmostequal(res, expected, [], %eps);
+
+res = legendre(2, 0:2, [0 0.5 1 0.9]);
+expected = [-0.5 -0.125 1 0.715;
+            0 -1.2990381 0 -1.1769027;
+            3 2.25 0 0.57];
+assert_checkalmostequal(res, expected, [], %eps);
+
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6]);
+expected = [-0.5 1 -0.44 0.04;
+            0 0 0.58787754 1.44;
+            3 0 2.88 1.92];
+assert_checkalmostequal(res, expected, [], %eps);
+
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6]');
+expected = [-0.5 1 -0.44 0.04;
+            0 0 0.58787754 1.44;
+            3 0 2.88 1.92];
+assert_checkalmostequal(res, expected, [], %eps);
+
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6], "norm");
+expected = [-0.7905694 1.5811388 -0.6957011 0.0632456;
+            0 0 -0.3794733 -0.929516;
+            0.9682458 0 0.929516 0.6196773];
+assert_checkalmostequal(res, expected, [], 1.e-7);
+
+res = legendre(2, 0:2, [0 -1 -0.2 -0.6]', "norm");
+expected = [-0.7905694 1.5811388 -0.6957011 0.0632456;
+            0 0 -0.3794733 -0.929516;
+            0.9682458 0 0.929516 0.6196773];
+assert_checkalmostequal(res, expected, [], 1.e-7);
+
+res = legendre(4, 2:4, [0 -0.2 0.2;1 0.7 -1]);
+expected = [-7.5 0 -5.184 9.29475 -5.184 0;
+            0 0 19.752685 -26.769644 -19.752685 0;
+            105 0 96.768 27.3105 96.768 0];
+assert_checkalmostequal(res, expected, [], 1.e-7);
+
+res = legendre(4, 2:4, [0 -0.2 0.2;1 0.7 -1], "norm");
+expected = [-0.8385255 0 -0.5795888 1.0391846 -0.5795888 0;
+            0 0 -0.5902244 0.7998961 0.5902244 0;
+            1.109265 0 1.0222986 0.2885198 1.0222986 0];
+assert_checkalmostequal(res, expected, [], 1.e-7);