From: SourceForge.net <noreply@so...>  20031214 17:45:30

Bugs item #853720, was opened at 20031203 19:42 Message generated for change (Comment added) made by macrakis You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=104933&aid=853720&group_id=4933 Category: Lisp Core Group: None Status: Open Resolution: None Priority: 5 Submitted By: Robert Dodier (robert_dodier) Assigned to: Nobody/Anonymous (nobody) Summary: chain rule applied with commutative multiplication Initial Comment: It appears the chain rule is applied by diff() with commutative multiplication to form "f'(g(x))*g'(x)" as the derivative of "f(g(x))". That is OK if the functions and variables involved are scalars, so that they always commute. However, I've constructed an example for which diff() returns the wrong result. I have a patch which makes it return the correct result. Here is the example problem. We want to compute the derivative of A.x^2 w.r.t. x, where A is a matrix and x is a vector. The derivative of x^2 is 2 transpose(x). The derivative of transpose(x) is the identity matrix. Applying the chain rule, the derivative is 2 transpose(A.x) . A. (C1) declare(A,nonscalar)$ (C2) declare(x,nonscalar)$ (C3) norm2(x):=transpose(x).x$ (C4) gradef('norm2(x),2 .transpose(x))$ (C5) gradef('transpose(x),1)$ (C6) display2d:FALSE$ (C7) diff('norm2(A.x),x); (D7) 2*A*'TRANSPOSE(A . x) < OOPS. The multiplication operator for A times transpose(A.x) should be the noncommutative multiplication, and it should be transpose(A.x) times A. This particular problem can be fixed by changing line 401 of comm.lisp from "#'MUL2" to "#'NCMUL2". Then the return value from diff() is correct. However making that change would introduce noncommutative multiplications into expressions where they don't belong. I guess that there should be some kind of test to see if commutative is OK. What is the right test, and how is it implemented? Note 1. gradef('norm2(x),2 .transpose(x))$ shouldn't be needed, except that diff('norm2(x),x); returns transpose(x)+x, which is wrong, without that gradef(). Note 2. It appears the reason the gradef('norm2(x),...) is needed is because the derivative of transpose(x).A w.r.t. x is transpose(A), but Maxima thinks it is A.  >Comment By: Stavros Macrakis (macrakis) Date: 20031214 12:45 Message: Logged In: YES user_id=588346 Maxima actually should be able to do this one if you declare any one of f, g, or x to be nonscalar: declare(a,nonscalar) map(nonscalarp, [ a, f(a), a(1), a(x), f(a(x)) ] ) => all true Diff could perfectly well check nonscalarp; so this is a bug in diff. Note that nonscalarp assumes by default that functions of nonscalars are nonscalar. If you want a scalar function of a nonscalar, you need to explicitly declare it: declare([ns],nonscalar); declare([s],scalar); nonscalarp(f(ns)) => true nonscalarp(s(ns)) => false By the way, Maxima has no way of distinguishing the variable a from the function a. I am not sure what the right way to handle transpose is.  You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=104933&aid=853720&group_id=4933 