/* GENERAL DIFFERENTIATION SIMPLIFICATION: DIFF(E,X,N), FOR
N SYMBOLIC  */
GENDIFF(E,X,N):= IF NUMBERP(N)THEN IF INTEGERP(N) THEN DIFF(E,X,N) ELSE (PRINT ("FRACTIONAL DERIVATIVES NOT SUPPORTED"),'DIFF(E,X,N)) 
ELSE IF FREEOF(X,E) THEN 0
 ELSE IF ATOM(E) THEN 'DIFF(E,X,N)
 ELSE IF INPART(E,0)="+" THEN MAP(GENDIFF1,E)
 ELSE IF INPART(E,0)="*" THEN GENDIFFPROD(INPART(E,1),
E/INPART(E,1))
 ELSE IF INPART(E,0)="**" THEN GENDIFFPOW(INPART(E,1),INPART(E,2))
 ELSE 'DIFF(E,X,N)$

/* DIFF OF X1^X2 WRT X N TIMES */
GENDIFFPOW(X1,X2):=
IF X1=X THEN GENFACT(X2,N,1)*X^(X2-N)
ELSE 
 IF (X1=%E)AND FREEOF(X,DIFF(X2,X)) THEN DIFF(X2,X)^N*%E^X2 
 ELSE 
 IF INTEGERP(X2) AND X2>1 THEN GENDIFF1(RATEXPAND(X2)) ELSE 
 'DIFF(X1^X2,X,N)$

GENDIFF1(Q):=GENDIFF(Q,X,N)$


/* A FIRST APPROACH */
GENDIFFPROD(A,B):=IF FREEOF(X,A)THEN A*GENDIFF(B,X,N) ELSE
 IF FREEOF(X,B) THEN B*GENDIFF(A,X,N) ELSE
(BLOCK([Q,R],
Q:GENDIFF(A,X,I),
R:GENDIFF(B,X,N-I),
RETURN(SUM(BINOMIAL(N,I)*Q*R,I,0,N))))$
