* Bug #14099 fixed - sci2exp macro was fixed to avoid "a+[] Warning". string(polynomi... 85/17885/7
Nicolas [Thu, 10 Mar 2016 13:07:01 +0000 (14:07 +0100)]
* Bug #14099 - string(polynomials) (rationals as well) improved

   http://bugzilla.scilab.org/14099#c4
 * Coefficients equal to +1|-1 were not masked: 1x^n  =>  x^n
 * Coefficients with imaginary parts were output as "%i*##": =>"##i"
 * Pure imaginary coefficients had parentheses: (%i*3)z^n  => 3iz^n
 * format("e") was as well applied to exponents: 3.4D+04x^2.0D+00 => 3.4D+04x^2
 * The processing was not vectorized

Change-Id: I49b1c64b3821e4c72d12b1eb1859c179f687348f

scilab/CHANGES
scilab/modules/overloading/macros/%p_string.sci
scilab/modules/polynomials/tests/nonreg_tests/bug_7101.dia.ref
scilab/modules/string/tests/nonreg_tests/bug_14099.dia.ref [new file with mode: 0644]
scilab/modules/string/tests/nonreg_tests/bug_14099.tst [new file with mode: 0644]

index 9027398..44f5987 100644 (file)
@@ -373,7 +373,7 @@ In 6.0.0:
 
 * Bug #14035 fixed - ndgrid did not manage all homogeneous data type (booleans, integers, polynomials, rationals, strings, [])
 
-* Bug #14099 fixed - sci2exp macro was fixed to avoid "a+[] Warning"
+* Bug #14099 fixed - sci2exp macro was fixed to avoid "a+[] Warning". string(polynomials|rationals) had badly formated outputs and was not vectorized
 
 * Bug #14111 fixed - modified lib function to detect Scilab version 5 libraries and give proper error messages
 
index ad11d9d..10924dc 100644 (file)
@@ -1,6 +1,5 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA
-//
+// Copyright (C) 2016 - Samuel GOUGEON
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
 //
 // 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 txt=%p_string(p)
-    [m,n]=size(p)
-    s=stripblanks(varn(p))
-    txt=emptystr(2*m,n)
+function txt = %p_string(p)
+    Sizes = size(p)
+    p = p(:)             // 1 polynomial per row
+    N = size(p,1)        // N rows
+
+    C = coeff(p)          // Matrix of coefficients
+    signPs = emptystr(C)  // Pure reals or imaginary: Signs
+                          // Mixed complex: Signs of real parts
+    valuePs = emptystr(C) // reals: |real|
+                          // Pure imaginaries: |imag|i
+                          // Mixed complex: mantissa (|real|+-imag i)
+    r0 = real(C)
+    im0 = imag(C)
 
-    for l=1:m
-        for k=1:n
-            c=coeff(p(l,k))
-            knz=find(c<>0)
-            if knz==[] then
-                txt(2*l-1:2*l,k)=[" ";"0"];
-            else
-                c=c(knz)
-                //special case for i=1
-                if isreal(c(1),0) then
-                    w=real(c(1))
-                    if w<0 then
-                        C(1)=" - "+string(abs(c(1))),
-                    else
-                        C(1)=string(c(1)),
-                    end
-                else
-                    w=string(c(1));
-                    if knz(1)<> 1 then w="("+w+")",end
-                    C(1)=w;
-                end
+    // Special case: null polynomials
+    k = (p==0)
+    valuePs(k) = "0"
 
-                for i=2:size(c,"*"),
-                    if isreal(c(i),0) then
-                        w=real(c(i))
-                        if w<0 then
-                            C(i)=" - "+string(abs(c(i))),
-                        else
-                            C(i)=" + "+string(c(i)),
-                        end
-                    else
-                        C(i)=" + ("+string(c(i))+")";
-                    end
-                end
+    // Pure real coeffs
+    k = find((r0~=0 | isnan(r0)) & im0==0)
+    if k~=[] then
+        r = r0(k)
+        kp = find(r>0 | isnan(r))
+        signPs(k(kp)) = "+"
+        valuePs(k(kp)) = string(r(kp))
+        km = find(r<0)
+        signPs(k(km)) = "-"
+        valuePs(k(km)) = string(-r(km))
+    end
 
-                if knz(1)>1 then
-                    C=C+s
-                else
-                    if ~isempty(s) && (size(C, "*") >= 2)
-                        C(2:$)=C(2:$)+s
-                    end
-                end
+    // pure imag coeffs
+    k = find((im0~=0 | isnan(im0)) & r0==0)
+    if k~=[] then
+        im = im0(k)
+        kp = find(im>0 | isnan(im))
+        if kp~=[]
+            signPs(k(kp)) = "+"
+            valuePs(k(kp)) = string(im(kp))+"i"
+        end
+        km = find(im<0)
+        if km~=[]
+            signPs(k(km)) = "-"
+            valuePs(k(km)) = string(-im(km))+"i"
+        end
+        kIsOne = find(valuePs(k)==string(1)+"i")
+        valuePs(k(kIsOne)) = "i"
+    end
 
-                i=min(find(knz>2));
-                blank=" ";
-                if ~isempty(i)
-                    e=blank(ones(1,i-1));
-                else
-                    e = [];
-                end
-                if size(knz,"*")>=i then
-                    e=[e string(knz(i:$)-1)];
-                end
+    // coeffs with real and imag parts
+    k = find((r0~=0 | isnan(r0)) & (im0~=0 | isnan(im0)))
+    if k~=[] then
+        r = r0(k)
+        kp = find(r>0 | isnan(r))
+        signPs(k(kp)) = "+"
+        km = find(r<0)
+        signPs(k(km)) = "-"
+        C(k(km)) = -C(k(km))  // + (-1.2+3i) => - (1.2-3i)
+        valuePs(k) = "("+string(real(C(k)));
 
-                lc=cumsum(length(C))
-                C=strcat(C)
-                E="";
-                if isempty(e)
-                    for i=1:size(c,"*")
-                        E = E + part(" ", 1:(lc(i) - length(E)));
-                    end
-                else
-                    for i=1:size(c,"*")
-                        E = E + part(" ", 1:(lc(i) - length(E))) + e(i);
-                    end
-                end
-                txt(2*l-1:2*l,k)=[E;C];
-            end
+        s = ""
+        if format()(1)==0   // format("e")
+            s = " "
+        end
+            // sign of imag part:
+        im = imag(C(k))
+        kp = find(im>0 | isnan(im))
+        if kp~=[]
+            valuePs(k(kp)) = valuePs(k(kp)) + s+"+"+s
+        end
+        km = find(im<0)
+        if km~=[]
+            valuePs(k(km)) = valuePs(k(km)) + s+"-"+s
+            C(k(km)) = conj(C(k(km)))
+            im = imag(C(k))
+        end
+            // 1i => i
+        kNoOne = find(abs(im)~=1)
+        if kNoOne~=[]
+            valuePs(k(kNoOne)) = valuePs(k(kNoOne))+string(im(kNoOne))+"i)"
+        end
+        kIsOne = find(abs(im)==1)
+        if kIsOne~=[]
+            valuePs(k(kIsOne)) = valuePs(k(kIsOne))+"i)"
         end
     end
+
+    // Adding the name of the variable
+    s = stripblanks(varn(p))
+    k = find(C~=0)
+    k2 = find(k>N)  // skip z^0 terms
+    if k2~=[] then
+        valuePs(k(k2)) = valuePs(k(k2))+s
+    end
+
+    // Simplifying 1z => z
+    k = find(valuePs==string(1)+s)
+    valuePs(k) = s
+    // Integrating signs to values
+    k = find(valuePs~="" & valuePs~="0")
+    valuePs2 = valuePs
+    if k~=[] then
+        valuePs2(k) = " "+signPs(k)+" "+valuePs(k)
+    end
+
+    // Exponents
+    E = emptystr(C)
+    k = find(valuePs~="")
+    k2 = find(k>2*N)        // skipping z^0 and z^1 terms
+    if k2~=[] then
+        k = k(k2)'
+        E(k) = msprintf("%d\n",(k-1)/N)
+
+        // Prepending blanks to exponents.
+        LE = length(E)
+        Ls = length(valuePs2)   // Length of spaces: init
+        Ls(:,4:$) = Ls(:,4:$) - LE(:,3:$-1)
+        Ls0 = Ls;
+        c = Ls(:,2);
+        for j = 3:size(Ls,2)
+            k = find(Ls(:,j)>0 & c<0);
+            Ls(k,j) = Ls(k,j)+c(k);
+            c(k) = Ls(k,j);
+            k = find(Ls0(:,j)<0);
+            c(k) = Ls0(k,j);
+        end
+        Ls(Ls<0) = 0
+        S = strsplit(part(" ",ones(1,3+sum(Ls))), [1 cumsum(Ls)(:)'+1])
+        S = matrix(S(2:size(E,"*")+1),N,-1)
+        E = S+E
+    end
+
+    // Gluing terms
+    ps = strcat(valuePs2,"","c")
+    es = strcat(E,"","c")
+
+    // Removing heading "+ " and " "
+    k = grep(ps,"/^ \+ /","r")
+    ps = strsubst(ps, "/^ \+ /", "", "r")
+    es(k) = part(es(k),4:$)
+    k = grep(ps,"/^ /","r")
+    ps = strsubst(ps, "/^ /", "", "r")
+    es(k) = part(es(k),2:$)
+
+    // Final reshaping
+    txt = [es' ; ps']
+    txt = txt(:)
+    Sizes(1) = Sizes(1)*2
+    txt = matrix(txt,Sizes)
 endfunction
index 6367a71..92827db 100644 (file)
@@ -246,8 +246,7 @@ for i=-100:100
                p=[1 1 -7 j 1 -4 4 7 4 i 1 i -8 3 3 0 9  j];
                roots(p); 
        end; 
-end;
-i=-100
+end;i=-100
 i=-80
 i=-60
 i=-40
diff --git a/scilab/modules/string/tests/nonreg_tests/bug_14099.dia.ref b/scilab/modules/string/tests/nonreg_tests/bug_14099.dia.ref
new file mode 100644 (file)
index 0000000..f3fa5b2
--- /dev/null
@@ -0,0 +1,119 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- Non-regression test for bug 14099 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/14099
+//
+// <-- Short Description -->
+// string(polynomial) and string(rational) had badly formated outputs
+//  and were not vectorized
+//
+// * Coefficients equal to +1|-1 were not masked: 1x^n  =>  x^n
+// * Coefficients with imaginary parts were output as "%i*##": =>"##i"
+// * Pure imaginary coefficients had parentheses: (%i*3)z^n  => 3iz^n
+// * format("e") was as well applied to exponents: 3.4D+04x^2.0D+00 => 3.4D+04x^2
+format("v", 10);
+// Single polynomials
+    // Constantes
+assert_checkequal(string(0*%z), ["";"0"]);
+assert_checkequal(string(0*%i*%z), ["";"0"]);
+assert_checkequal(string(3+0*%z), ["";"3"]);
+assert_checkequal(string(-3+0*%z), ["";"- 3"]);
+assert_checkequal(string(3*%i+0*%z), ["";"3i"]);
+assert_checkequal(string(-3*%i+0*%z), ["";"- 3i"]);
+assert_checkequal(string(1-3*%i+0*%z), ["";"(1-3i)"]);
+assert_checkequal(string(-1+3*%i+0*%z), ["";"- (1-3i)"]);
+assert_checkequal(string(-1-3*%i+0*%z), ["";"- (1+3i)"]);
+    //
+assert_checkequal(string(-3*%i*%z), ["";"- 3iz"]);
+assert_checkequal(string((1-3*%i)*%z), ["";"(1-3i)z"]);
+assert_checkequal(string((-1+3*%i)*%z), ["";"- (1-3i)z"]);
+assert_checkequal(string((-1-3*%i)*%z), ["";"- (1+3i)z"]);
+assert_checkequal(string(-3*%i*%z^13), ["     13";"- 3iz"]);
+assert_checkequal(string((1-3*%i)*%z^13), ["       13";"(1-3i)z"]);
+assert_checkequal(string((-1+3*%i)*%z^13), ["         13";"- (1-3i)z"]);
+assert_checkequal(string((-1-3*%i)*%z^13), ["         13";"- (1+3i)z"]);
+p = (1-%i) - %i*%z -3*%i*%z^8 + 4*%z^15 - %i*%z^18;
+assert_checktrue(and(string(p)==["                8    15   18"; "(1-i) - iz - 3iz + 4z - iz"]));
+p = - %i*%z -3*%i*%z^8 + 4*%z^15 - %i*%z^18;
+assert_checktrue(and(string(p)==["          8    15   18"; "- iz - 3iz + 4z - iz"]));
+// Matrix of polynomials
+ps = "[0*z, 3+0*%i*z; -z, -%i*z;  -z^17, -%i*z^17;  "+..
+     "1-z+5*z^3+41*z^20, (1+(1-%i)*z)^3-1;  "+..
+     "-z+z^3+3*z^4, (%i-2)-3*z-3*%i*z^13+(1+7*%i)*z^20; ]";
+z = poly(0,"x");
+p = evstr(ps);
+refS = [" "                   " "
+        "0"                   "3"
+        "   "                 "    "
+        "- x"                 "- ix"
+        "   17"               "    17"
+        "- x"                 "- ix"
+        "          3     20"  "             2         3"
+        "1 - x + 5x + 41x"    "(3-3i)x - 6ix - (2+2i)x"
+        "       3    4"       "                  13        20"
+        "- x + x + 3x"        "- (2-i) - 3x - 3ix + (1+7i)x"
+        ];
+assert_checktrue(and(string(p)==refS));
+x = poly(0,"x");
+p = "[64.692+38.966*x-36.580*x^2+90.044*x^3-93.111*x^4;64.381-74.963*x+52.75*x^2-1.8822*x^3+32.721*x^4]";
+p = evstr(p);
+format(6);
+refS = ["                       2        3        4"
+        "64.69 + 38.97x - 36.58x + 90.04x - 93.11x"
+        "                       2        3        4"
+        "64.38 - 74.96x + 52.75x - 1.882x + 32.72x"
+       ];
+assert_checktrue(and(string(p)==refS));
+p = p/3+p*%i/4;
+format(5);
+refS = ["                                            2               3               4"
+        "(21.6+16.2i) + (13.0+9.74i)x - (12.2+9.14i)x + (30.0+22.5i)x - (31.0+23.3i)x"
+        "                                            2               3               4"
+        "(21.5+16.1i) - (25.0+18.7i)x + (17.6+13.2i)x - (0.63+0.47i)x + (10.9+8.18i)x"
+        ];
+assert_checktrue(and(string(p)==refS));
+// with %nan and %inf
+p = poly([%nan 2 3 -%nan 8],"x","coeff");
+p = p+%i*p/2;
+//""""+string(p)+""""
+refS = ["                               2             3         4"
+        "(Nan+Nani) + (2+i)x + (3+1.5i)x + (Nan+Nani)x + (8+4i)x"
+        ];
+assert_checktrue(and(string(p)==refS));
+// with format("e")
+format("e",8);
+ps = "[0*z, 3+0*%i*z; -z, -%i*z;"+..
+     "1+5*z^3-%pi*z^17,  -z^17; "+..
+     "(1+(1-%i)*z)^3-1+%e*%i*z^11, -%i*z^17]";
+z = poly(0,"x");
+p = evstr(ps);
+if getos()=="Windows" then // The exponential notation may depend on the OS
+    refS = [" "                                                                        "       "
+            "0"                                                                        "3.0D+00"
+            "   "                                                                      "    "
+            "- x"                                                                      "- ix"
+            "                  3          17"                                          "   17"
+            "1.0D+00 + 5.0D+00x - 3.1D+00x"                                            "- x"
+            "                                 2                       3           11"  "    17"
+            "(3.0D+00 - 3.0D+00i)x - 6.0D+00ix - (2.0D+00 + 2.0D+00i)x + 2.7D+00ix"    "- ix"
+            ];
+    assert_checktrue(and(string(p)==refS));
+end
+// With a name of variable longer than 1 character:
+x = poly(0,"ABC");
+p = (2-%i+x).^[2 4 ; 1 3];
+format("v",10);
+//""""+string(p)+""""
+refS = ["                        2"  "                                    2           3     4"
+        "(3-4i) + (4-2i)ABC + ABC"   "- (7+24i) + (8-44i)ABC + (18-24i)ABC + (8-4i)ABC + ABC"
+        "           "                "                                2     3"
+        "(2-i) + ABC"                "(2-11i) + (9-12i)ABC + (6-3i)ABC + ABC"
+       ];
+assert_checktrue(and(string(p)==refS));
diff --git a/scilab/modules/string/tests/nonreg_tests/bug_14099.tst b/scilab/modules/string/tests/nonreg_tests/bug_14099.tst
new file mode 100644 (file)
index 0000000..c41a51c
--- /dev/null
@@ -0,0 +1,133 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- Non-regression test for bug 14099 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/14099
+//
+// <-- Short Description -->
+// string(polynomial) and string(rational) had badly formated outputs
+//  and were not vectorized
+//
+// * Coefficients equal to +1|-1 were not masked: 1x^n  =>  x^n
+// * Coefficients with imaginary parts were output as "%i*##": =>"##i"
+// * Pure imaginary coefficients had parentheses: (%i*3)z^n  => 3iz^n
+// * format("e") was as well applied to exponents: 3.4D+04x^2.0D+00 => 3.4D+04x^2
+
+format("v", 10);
+
+// Single polynomials
+    // Constantes
+assert_checkequal(string(0*%z), ["";"0"]);
+assert_checkequal(string(0*%i*%z), ["";"0"]);
+assert_checkequal(string(3+0*%z), ["";"3"]);
+assert_checkequal(string(-3+0*%z), ["";"- 3"]);
+
+assert_checkequal(string(3*%i+0*%z), ["";"3i"]);
+assert_checkequal(string(-3*%i+0*%z), ["";"- 3i"]);
+
+assert_checkequal(string(1-3*%i+0*%z), ["";"(1-3i)"]);
+assert_checkequal(string(-1+3*%i+0*%z), ["";"- (1-3i)"]);
+assert_checkequal(string(-1-3*%i+0*%z), ["";"- (1+3i)"]);
+    //
+assert_checkequal(string(-3*%i*%z), ["";"- 3iz"]);
+assert_checkequal(string((1-3*%i)*%z), ["";"(1-3i)z"]);
+assert_checkequal(string((-1+3*%i)*%z), ["";"- (1-3i)z"]);
+assert_checkequal(string((-1-3*%i)*%z), ["";"- (1+3i)z"]);
+
+assert_checkequal(string(-3*%i*%z^13), ["     13";"- 3iz"]);
+assert_checkequal(string((1-3*%i)*%z^13), ["       13";"(1-3i)z"]);
+assert_checkequal(string((-1+3*%i)*%z^13), ["         13";"- (1-3i)z"]);
+assert_checkequal(string((-1-3*%i)*%z^13), ["         13";"- (1+3i)z"]);
+
+p = (1-%i) - %i*%z -3*%i*%z^8 + 4*%z^15 - %i*%z^18;
+assert_checktrue(and(string(p)==["                8    15   18"; "(1-i) - iz - 3iz + 4z - iz"]));
+
+p = - %i*%z -3*%i*%z^8 + 4*%z^15 - %i*%z^18;
+assert_checktrue(and(string(p)==["          8    15   18"; "- iz - 3iz + 4z - iz"]));
+
+// Matrix of polynomials
+ps = "[0*z, 3+0*%i*z; -z, -%i*z;  -z^17, -%i*z^17;  "+..
+     "1-z+5*z^3+41*z^20, (1+(1-%i)*z)^3-1;  "+..
+     "-z+z^3+3*z^4, (%i-2)-3*z-3*%i*z^13+(1+7*%i)*z^20; ]";
+z = poly(0,"x");
+p = evstr(ps);
+refS = [" "                   " "
+        "0"                   "3"
+        "   "                 "    "
+        "- x"                 "- ix"
+        "   17"               "    17"
+        "- x"                 "- ix"
+        "          3     20"  "             2         3"
+        "1 - x + 5x + 41x"    "(3-3i)x - 6ix - (2+2i)x"
+        "       3    4"       "                  13        20"
+        "- x + x + 3x"        "- (2-i) - 3x - 3ix + (1+7i)x"
+        ];
+assert_checktrue(and(string(p)==refS));
+
+x = poly(0,"x");
+p = "[64.692+38.966*x-36.580*x^2+90.044*x^3-93.111*x^4;64.381-74.963*x+52.75*x^2-1.8822*x^3+32.721*x^4]";
+p = evstr(p);
+format(6);
+refS = ["                       2        3        4"
+        "64.69 + 38.97x - 36.58x + 90.04x - 93.11x"
+        "                       2        3        4"
+        "64.38 - 74.96x + 52.75x - 1.882x + 32.72x"
+       ];
+assert_checktrue(and(string(p)==refS));
+
+p = p/3+p*%i/4;
+format(5);
+refS = ["                                            2               3               4"
+        "(21.6+16.2i) + (13.0+9.74i)x - (12.2+9.14i)x + (30.0+22.5i)x - (31.0+23.3i)x"
+        "                                            2               3               4"
+        "(21.5+16.1i) - (25.0+18.7i)x + (17.6+13.2i)x - (0.63+0.47i)x + (10.9+8.18i)x"
+        ];
+assert_checktrue(and(string(p)==refS));
+
+// with %nan and %inf
+p = poly([%nan 2 3 -%nan 8],"x","coeff");
+p = p+%i*p/2;
+//""""+string(p)+""""
+refS = ["                               2             3         4"
+        "(Nan+Nani) + (2+i)x + (3+1.5i)x + (Nan+Nani)x + (8+4i)x"
+        ];
+assert_checktrue(and(string(p)==refS));
+
+// with format("e")
+format("e",8);
+ps = "[0*z, 3+0*%i*z; -z, -%i*z;"+..
+     "1+5*z^3-%pi*z^17,  -z^17; "+..
+     "(1+(1-%i)*z)^3-1+%e*%i*z^11, -%i*z^17]";
+z = poly(0,"x");
+p = evstr(ps);
+if getos()=="Windows" then // The exponential notation may depend on the OS
+    refS = [" "                                                                        "       "
+            "0"                                                                        "3.0D+00"
+            "   "                                                                      "    "
+            "- x"                                                                      "- ix"
+            "                  3          17"                                          "   17"
+            "1.0D+00 + 5.0D+00x - 3.1D+00x"                                            "- x"
+            "                                 2                       3           11"  "    17"
+            "(3.0D+00 - 3.0D+00i)x - 6.0D+00ix - (2.0D+00 + 2.0D+00i)x + 2.7D+00ix"    "- ix"
+            ];
+    assert_checktrue(and(string(p)==refS));
+end
+
+// With a name of variable longer than 1 character:
+x = poly(0,"ABC");
+p = (2-%i+x).^[2 4 ; 1 3];
+format("v",10);
+//""""+string(p)+""""
+refS = ["                        2"  "                                    2           3     4"
+        "(3-4i) + (4-2i)ABC + ABC"   "- (7+24i) + (8-44i)ABC + (18-24i)ABC + (8-4i)ABC + ABC"
+        "           "                "                                2     3"
+        "(2-i) + ABC"                "(2-11i) + (9-12i)ABC + (6-3i)ABC + ABC"
+       ];
+assert_checktrue(and(string(p)==refS));
+