ATM formal derivatives can give wrong InputForm:

(3) -> f := operator 'f

   (3)  f
                                                          Type: BasicOperator

(4) -> di2 := D(f(x, y^2), [x, y], [2, 1])

                     2
   (4)  2yf      (x,y )
           ,1,1,2
                                                    Type: Expression(Integer)
(5) -> di2::InputForm                     

   (5)
   (*  (* 2 y)
    (D (D (D (f x (^ y 2)) (:: x Symbol)) (:: x Symbol)) (:: (^ y 2) Symbol)))
                                                              Type: InputForm
(6) -> unparse(di2::InputForm)

   (6)  "2*y*D(D(D(f(x,y^2),x::Symbol),x::Symbol),(y^2)::Symbol)"
                                                                 Type: String

That is we are trying to differentiate with respect to something
which is not a symbol.  I have a patch that fixes this.  But
test showed that patch breaks assumption that some people make
that given expression have unique InputForm.  Namely, to get
correct value we need to differentiate with respect to a dummy
variable and than substitute argument in place of dummy.
To avoid accidental clashes we need to introduce fresh dummy
each time we create InputForm.  That is computing InputForm
second time gives new dummy.  This is a drawback, but I see
no other way to get correct InputForm.  In the patch I
introduce dummy only when argument is not a symbol (that
is when old code would produce wrong value).  In principle
we could avoid dummies in some other cases, but correct
coditions seem to be complicated and it is not clear if
gain justifies effort.

Anyway, patch in attachement.  I am going to apply it
unless sombody thinks that it will break something
important.

-- 
                              Waldek Hebisch

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/E1gmJqG-0005ey-KW%40hera.math.uni.wroc.pl.
For more options, visit https://groups.google.com/d/optout.
Index: src/algebra/fspace.spad
===================================================================
--- src/algebra/fspace.spad     (revision 2543)
+++ src/algebra/fspace.spad     (working copy)
@@ -433,6 +433,7 @@
          ++ applyQuote(foo, [x1, ..., xn]) returns \spad{'foo(x1, ..., xn)}.
        if R has ConvertibleTo InputForm then
          ConvertibleTo InputForm
+         -- FIXME: Avoid creating compiled functions
          eval     : (%, OP, %, SY) -> %
            ++ eval(x, s, f, y) replaces every \spad{s(a)} in x by \spad{f(y)}
            ++ with \spad{y} replaced by \spad{a} for any \spad{a}.
@@ -597,13 +598,26 @@
       import from MakeUnaryCompiledFunction(%, %, %)
       indiff : List % -> INP
       pint  : List INP-> INP
-      differentiand : List % -> %
 
-      differentiand l    == eval(first l, retract(second l)@K, third l)
       pint l  == convert concat(convert('D)@INP, l)
       indiff l ==
-         r2 := convert([convert("::"::SY)@INP,convert(third 
l)@INP,convert('Symbol)@INP]@List INP)@INP
-         pint [convert(differentiand l)@INP, r2]
+          a3 : % := third(l)
+          do_eval := false
+          s : SY :=
+              (su := retractIfCan(a3)@Union(SY, "failed")) case SY =>
+                  su::SY
+              do_eval := true
+              new()$SY
+          -- Ugly, but otherwise interpreter may have trouble
+          -- evaluating result
+          si := convert([convert("::"::SY)@INP, convert(s)@INP,
+                         convert('Symbol)@INP])@INP
+          ne := eval(first l, retract(second l)@K, (do_eval => s::%; a3))
+          d1 := pint([convert(ne)@INP, si])
+          do_eval =>
+              convert([convert('eval)@INP, d1, si, convert(third(l))@INP])
+          d1
+
       eval(f : %, s : OP, g : %, x : SY) == eval(f, [s], [g], x)
 
       eval(f : %, ls : List OP, lg : List %, x : SY) ==
Index: src/input/bugs2014.input
===================================================================
--- src/input/bugs2014.input    (revision 2543)
+++ src/input/bugs2014.input    (working copy)
@@ -16,7 +16,8 @@
 --  f    (%A,y(x))
 --   ,1,2
 -- in revision r1674
-testEquals("r1", "r2")
+testEquals("r1 - r2", "0")
+testEquals("r1::OutputForm", "r2::OutputForm")
 
 testcase "comutativity of formal diffs"
 f:=operator 'f
Index: src/input/series3.input
===================================================================
--- src/input/series3.input     (revision 2543)
+++ src/input/series3.input     (working copy)
@@ -26,7 +26,7 @@
 c2_3 := (eval(D(f(x), x), x = g(a))*D(g(a),a, 3) + _
    D(g(a),a)^3*eval(D(f(x), x, 3), x = g(a)) + _
    3*D(g(a),a)*eval(D(f(x), x, 2), x = g(a))*D(g(a),a,2))/6
-testEquals("coefficient(ss, 3)", "c2_3")
+testEquals("coefficient(ss, 3) - c2_3", "0")
 
 e3 := h(x, x^2)
 ss := series(e3, x = a);

Reply via email to