derivatives of generalized Lambert



I was thinking about the options for the derivative of the generalized Lambert function with respect to
the first argument. Possibilities:

 (1) signal an error,
 (2) return an 'at' nounform,
 (3) give the function a silly name and hope that nobody asks for the derivative of that function.

Scheme (1) is honest and pretty easy to do with a simplifying error. One not so nice thing about this
method is that internally Maxima doesn't expect diff to signal an error, so things such as 
integrate(generalized_lambert_w(k,x),k) signals an error about the derivative of the 
generalized Lambert, instead of returning an integrate nounform. Code for scheme 1:

;;; A derivative of the generalized Lambert function with respect to the first argument signals an error.
;;; To do this, we need a simplifying error function:

(defun simp-serror (x y z) "A simplifying error function."
  (declare (ignore y))
  (merror (simpcheck (second x) z)))

(setf (get 'serror 'operators) #'simp-serror)

;;; Derivative of generalized_lambert_w. This code is adapted from specfun.lisp

(defprop %generalized_lambert_w
  ((k x) 
   ((serror) "Maxima doesn't know the derivative of generalized_lambert_w with respect to the first argument.")
   ((mtimes)
    ((mexpt) $%e ((mtimes) -1 ((%generalized_lambert_w) k x)))
    ((mexpt) ((mplus) 1 ((%generalized_lambert_w) k x)) -1)))
  grad)

Scheme (2) is a bit weird, but maybe it's not wrong:

(defprop %generalized_lambert_w
  ((k x)
    ((mprog)
     ((mlist) ((msetq) kk (($gensym))) ((msetq) xx (($gensym))))
     ((%at) ((%derivative) ((%generalized_lambert_w) kk xx) kk 1)
      ((mlist) ((mequal) kk k) ((mequal) xx x))))
    ((mtimes)
     ((mexpt) $%e ((mtimes) -1 ((%generalized_lambert_w) k x)))
     ((mexpt) ((mplus) 1 ((%generalized_lambert_w) k x)) -1)))
  grad)

(%i13) diff(%,k);
(%o13) block([kk:gensym(),xx:gensym()],at('diff(generalized_lambert_w(kk,xx),kk,1),[kk=k,xx=x]))

(%i14) ev(%,at);
(%o14) at('diff(generalized_lambert_w(g34265,g34266),g34265,1),[g34265=k,g34266=x])

(%i15) ev(%,diff);
(%o15) at(block([kk:gensym(),xx:gensym()],at('diff(generalized_lambert_w(kk,xx),kk,1),[kk=g34265,xx=g34266])),[g34265=k,g34266=x])

Scheme (3) isn't a serious option (name the function abracadabra, maybe).

--Barton