* Bug 16620 fixed: polyint() introduced 59/21659/4
Samuel GOUGEON [Thu, 24 Dec 2020 00:05:16 +0000 (01:05 +0100)]
  http://bugzilla.scilab.org/16620

  polyint page (en_US PDF): http://bugzilla.scilab.org/attachment.cgi?id=5204

Change-Id: I4d8c0e7d754886bf2900796ee2113f44311725c8

scilab/CHANGES.md
scilab/modules/helptools/data/configuration/scilab_macros.txt
scilab/modules/polynomials/help/en_US/polyint.xml [new file with mode: 0644]
scilab/modules/polynomials/macros/polyint.sci [new file with mode: 0644]
scilab/modules/polynomials/tests/unit_tests/polyint.tst [new file with mode: 0644]

index 7349040..6b4e6cc 100644 (file)
@@ -223,6 +223,7 @@ Feature changes and additions on 6.1.1
 * `kron` and `.*.` are extended to boolean arrays.
 * `gamma` is extended to incomplete gamma integrals.
 * `close` is extended to close the help browser, xcos, or the variables browser or editor GUIs.
+* `polyint` is introduced to compute polynomial antiderivatives.
 
 
 Help pages:
@@ -416,6 +417,7 @@ Bug Fixes
 * [#16613](https://bugzilla.scilab.org/16613): Neither `.*.` nor `kron()` worked with boolean or sparse boolean matrices.
 * [#16617](https://bugzilla.scilab.org/16617): `gamma` did not support incomplete gamma integrals.
 * [#16618](https://bugzilla.scilab.org/16618): `close` could not close the help browser, xcos, nor the variable editor or browser.
+* [#16620](https://bugzilla.scilab.org/16620): `derivat` had no reciprocal `polyint` polynomial integration function.
 * [#16622](https://bugzilla.scilab.org/16622): `inv` could no longer be overloaded for hypermatrices of decimal or complex numbers.
 * [#16623](https://bugzilla.scilab.org/16623): `rand(2,2,2)^2` yielded a wrong result instead of trying to call the `%s_p_s` overload for input hypermatrices.
 * [#16629](https://bugzilla.scilab.org/16629): `interp1`'s documentation did not tell the spline edges conditions ; extrapolation modes were poorly explained. ; the description of the result's size was completely wrong ; x as an option was not documented. A wrong extrapolation value could silently return a wrong result. There was some dead code like `if varargin(5)==%nan`. A bugged error message yielded its own error. When x is implicit, the argument index in error messages could be wrong. `periodic` and `edgevalue` extrapolation modes were not available. `linear` extrapolation was not available for splines. When `xp` is an hypermatrix with `size(xp,1)==1`, the size of the result was irregular/wrong.
diff --git a/scilab/modules/polynomials/help/en_US/polyint.xml b/scilab/modules/polynomials/help/en_US/polyint.xml
new file mode 100644 (file)
index 0000000..8125081
--- /dev/null
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2020 - Samuel GOUGEON - Le Mans Université
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ -->
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+          xmlns:svg="http://www.w3.org/2000/svg" xmlns:db="http://docbook.org/ns/docbook"
+          xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="polyint">
+    <refnamediv>
+        <refname>polyint</refname>
+        <refpurpose>
+            Polynomial integration
+        </refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Syntax</title>
+        <synopsis>
+            polyint  // example
+            Q = polyint(P)
+            Q = polyint(P, Const)
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Arguments</title>
+        <variablelist>
+            <varlistentry>
+                <term>P, Q</term>
+                <listitem>
+                    arrays (from scalars to hypermatrices) of polynomials with real or complex
+                    coefficients, of same size.
+                    <para/>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>Const</term>
+                <listitem>
+                    Set of real or complex constants of integration.
+                    <literal>length(Const)</literal> sets the number of consecutive integrations
+                    to perform. By default, 0 is used.
+                    <varname>Const</varname> can be one of the following:
+                    <itemizedlist>
+                        <listitem>
+                            a scalar: then only the first antiderivatives are computed, and all use
+                            the same <varname>Const</varname> value.
+                        </listitem>
+                        <listitem>
+                            an array of size size(P): then only the first antiderivatives are computed,
+                            with the respective <literal>Const(i)</literal> for <literal>Q(i)</literal>.
+                        </listitem>
+                        <listitem>
+                            a list that can mix scalars, arrays of size size(P), or undefined elements.
+                            Then <literal>Const(i)</literal> is used for the i<superscript>th</superscript>
+                            antiderivatives. Undefined elements are equivalent to 0.
+                        </listitem>
+                    </itemizedlist>
+                    <para/>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            polyint(..) computes the first or any n<superscript>th</superscript> antiderivative
+            of each polynomial of the input array.
+        </para>
+    </refsection>
+    <refsection>
+        <title>Examples</title>
+        <para>
+            Single integration (first order):
+        </para>
+        <programlisting role="example"><![CDATA[
+s = %s;
+P = [-2, s ; s^2-3, s-2*s^3]
+polyint(P)
+polyint(P, 1)
+polyint(P, [1 2 ; 3 4])
+     ]]></programlisting>
+        <screen><![CDATA[
+--> P = [-2, s ; s^2-3, s-2*s^3]
+ P  =
+  -2      s
+  -3 +s²  s -2s³
+
+--> polyint(P)
+ ans  =
+  -2s               0.5s²
+  -3s +0.3333333s³  0.5s² -0.5s⁴
+
+--> polyint(P, 1)
+ ans  =
+  1 -2s               1 +0.5s²
+  1 -3s +0.3333333s³  1 +0.5s² -0.5s⁴
+
+--> polyint(P, [1 2 ; 3 4])
+ ans  =
+  1 -2s               2 +0.5s²
+  3 -3s +0.3333333s³  4 +0.5s² -0.5s⁴
+]]></screen>
+        <para/>
+        <para>
+            Multiple integrations:
+        </para>
+        <programlisting role="example"><![CDATA[
+s = %s;
+polyint(1-3*s, list(-1,1))
+P = [3 ; 1-s ; 6*s^2-2]
+polyint(P, list(2, [-2 1 0]))
+polyint(P, list(, [-2 1 0]))
+
+k = list(); k(5) = 0;
+polyint(1+0*s, k)
+1 / factorial(5)
+     ]]></programlisting>
+        <screen><![CDATA[
+--> polyint(1-3*s, list(-1,1))
+ ans  =
+  1 -s +0.5s² -0.5s³
+
+--> P = [3 ; 1-s ; 6*s^2-2]
+ P  =
+  3
+  1 -s
+  -2 +6s²
+
+--> polyint(P, list(2, [-2 1 0]))
+ ans  =
+  -2 +2s +1.5s²
+  1 +2s +0.5s² -0.1666667s³
+  2s -s² +0.5s⁴
+
+--> polyint(P, list(, [-2 1 0]))
+ ans  =
+  -2 +1.5s²
+  1 +0.5s² -0.1666667s³
+  -s² +0.5s⁴
+
+
+--> k = list(); k(5) = 0;
+--> polyint(1+0*s, k)
+ ans  =
+  0.0083333s⁵
+
+--> 1 / factorial(5)
+ ans  =
+   0.0083333
+]]></screen>
+    </refsection>
+    <refsection role="see also">
+        <title>See also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="derivat">derivat</link>
+            </member>
+        </simplelist>
+    </refsection>
+    <refsection role="history">
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>6.1.1</revnumber>
+                <revdescription>
+                    polyint() introduced.
+                </revdescription>
+            </revision>
+        </revhistory>
+    </refsection>
+</refentry>
diff --git a/scilab/modules/polynomials/macros/polyint.sci b/scilab/modules/polynomials/macros/polyint.sci
new file mode 100644 (file)
index 0000000..5642639
--- /dev/null
@@ -0,0 +1,92 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - Samuel GOUGEON - Le Mans Université
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// pursuant to article 5.3.4 of the CeCILL v.2.1.
+// This file was originally licensed under the terms of the CeCILL v2.1,
+// and continues to be available under such terms.
+// For more information, see the COPYING file which you should have received
+// along with this program.
+
+function M = polyint(M, cstes)
+    // M : array (from scalar to hypermatrix) of polynomials with real or
+    //     complex coefficients
+    // Cstes: Integration constants (real or complex): scalar, array of size
+    //     size(M), or list of mixed scalar or sized(M) arrays or
+    //     undefined elements (valued as 0).
+
+    // EXAMPLE
+    // =======
+    if argn(2)==0 then
+        m = mode(); mode(6)
+        M = [ -1+%z, 1+2*%z+%z^2 ; 2-%z^3, 6]
+        mprintf("\n%s", "polyint(M)")
+        I = polyint(M)
+        mprintf("\n%s", "polyint(M, 1)")
+        I = polyint(M, 1)
+        mprintf("\n%s", "polyint(M, [1 2 ; 3 4])")
+        I = polyint(M, [1 2 ; 3 4])
+        mode(m)
+        M = I
+        return
+    end
+
+    s = size(M)
+    n = length(M)
+
+    // CHECKING ARGUMENTS
+    // ==================
+    rhs = argn(2)
+    if type(M)<>2 then
+        msg = _("%s: Argument #%d: Polynomial expected.\n")
+        error(msprintf(msg, "polyint",1))
+    end
+    if ~isdef("cstes","l")
+        cstes = 0
+    end
+    if and(type(cstes)<>[1 15])
+        msg = _("%s: Argument #%d: numbers or list of numbers expected.\n")
+        error(msprintf(msg, "polyint",2))
+    end
+    if type(cstes) <> 15 then
+        cstes = list(cstes)
+    end
+    for i = 1:length(cstes)
+        k = cstes(i)
+        if isdef("k","l")
+            if type(k) <> 1
+                msg = _("%s: Argument #%d(%d): Decimal or complex number expected.\n")
+                error(msprintf(msg, "polyint",2,i))
+            end
+            if length(k)<>1 & or(size(k)<>s)
+                msg = _("%s: Argument #%d(%d): Array of size [%s] expected.\n")
+                ts = strcat(msprintf("%d\n",s(:))," ")
+                error(msprintf(msg, "polyint", 2, i, ts))
+            end
+        end
+    end
+
+    // PROCESSING
+    // ==========
+    vn = poly(0, varn(M))
+    M = matrix(M, -1, 1)
+    for i = cstes
+        if ~isdef("i","l")
+            i = zeros(n,1)
+        elseif length(i)==1
+            i = i * ones(n,1)
+        else
+            i = matrix(i,-1,1)
+        end
+        M = M * vn
+        d = max(max(degree(M),0))
+        p = (0:d) .*. ones(M)
+        c = coeff(M)
+        k = find(p > 0)
+        c(k) = c(k) ./ p(k)
+        c(:,1) = c(:,1) + i
+        M = inv_coeff(c, d, varn(M))
+    end
+
+    M = matrix(M, s)
+endfunction
diff --git a/scilab/modules/polynomials/tests/unit_tests/polyint.tst b/scilab/modules/polynomials/tests/unit_tests/polyint.tst
new file mode 100644 (file)
index 0000000..1cfd31c
--- /dev/null
@@ -0,0 +1,55 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - Samuel GOUGEON - Le Mans Université
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+s = %s;
+P = s^[0 1 ; 2 3];
+
+// SINGLE INTEGRATION
+// ==================
+assert_checkequal(polyint(s), s^2/2);
+Ref0 = s^[1 2 ; 3 4] ./ [1 2 ; 3 4];
+assert_checkequal(polyint(P), Ref0);
+Ref = [0, -s+0.5*s^2 ; -s+s^3/3,-s+0.25*s^4];
+assert_checkequal(polyint(P-1), Ref);
+
+// With consts
+// -----------
+assert_checkequal(polyint(P, 1), Ref0+1);
+assert_checkequal(polyint(P, [1 2 ; 3 4]), Ref0+[1 2 ; 3 4]);
+assert_checkequal(polyint(P, list([1 2 ; 3 4])), Ref0+[1 2 ; 3 4]);
+
+
+// MULTIPLE INTEGRATIONS
+// =====================
+assert_checkequal(polyint(s,list(-1,1)), 1-s+s^3/6);
+
+o = list(); o(5) = 0;   // undefined elements #1-4
+assert_checkequal(polyint(1+0*s, o), s^5/factorial(5));
+
+Ref = [-2+2*s+1.5*s^2 ; 1+2*s+0.5*s^2-s^3/6 ; 2*s-s^2+s^4/12];
+assert_checkequal(polyint([3 ; 1-s ; s^2-2], list(2,[-2 1 0]')), Ref);
+Ref = [-2 + 1.5*s^2 ; 1 + 0.5*s^2 - s^3/6 ; -s^2 + s^4/12];
+assert_checkequal(polyint([3 ; 1-s ; s^2-2], list(,[-2 1 0]')), Ref);
+
+
+// ERROR MESSAGES
+// ==============
+assert_checkerror("polyint(1,2,3)", _("Wrong number of input arguments."));
+msg = msprintf(_("%s: Argument #%d: Polynomial expected.\n"), "polyint",1);
+assert_checkerror("polyint(3)", msg);
+msg = _("%s: Argument #%d: numbers or list of numbers expected.\n");
+assert_checkerror("polyint(%s, %f)", msprintf(msg, "polyint",2));
+msg = _("%s: Argument #%d(%d): Decimal or complex number expected.\n");
+assert_checkerror("polyint(%s, list(3,%f))", msprintf(msg, "polyint",2,2));
+msg = _("%s: Argument #%d(%d): Array of size [%s] expected.\n");
+assert_checkerror("polyint(%s, [1 2])", msprintf(msg, "polyint",2,1,"1 1"));
+assert_checkerror("polyint(%s, list([1 2]))", msprintf(msg, "polyint",2,1,"1 1"));
+assert_checkerror("polyint(%s, list([1 2],4))", msprintf(msg, "polyint",2,1,"1 1"));
+assert_checkerror("polyint(%s, list(4,,[1 2]))", msprintf(msg, "polyint",2,3,"1 1"));