documentation of source?



Am Montag, den 07.09.2009, 08:48 -0700 schrieb dlakelan:
> I'd like to go one step further and suggest that someone write a 
> "getting started in maxima development" document. Perhaps 5 pages or 
> less, which describes the basic format of maxima data structures (really 
> specialized lists I guess), and the basic utility functions for 
> constructing them, simplifying them, etc. In other words, what are the 
> most important things you would want to know to begin working on the code.
> 
> I am actually a fairly knowledgeable common lisp programmer, but the few 
> times I have looked at maxima internals, I simply don't know what is 
> going on because maxima has its own way of expressing everything.
> 
> I thought i'd seen an introduction like this at one point, but it does 
> not appear on the documentation page for maxima.

Sometimes ago I started to write a tutorial to implement a mathematical
function. Perhaps it is of interest.

I have described step by step the different techniques to do numerical
evaluation, the implementation of symmetry and transformation rules,
support differentiation and integration, ... At the moment I have
written 5 Chapters. I have written the tutorial as an documented Lisp
file.

This is the first chapter:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Chapter 1:
;;;
;;; Implement the minimal code for a new function sqr. 
;;; The sqr function is defined as sqr(z) = z^2.
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Support the properties verb, noun, reverse, and reversealias.
;;;
;;; These properties make sure that the simplifying function is handled
;;; correctly by the parser and display.

(defprop $sqr %sqr verb)
(defprop $sqr %sqr alias)

(defprop %sqr $sqr noun)
(defprop %sqr $sqr reversealias)

;;; Sqr is a symplifying function.
;;;
;;; Put the symbol %sqr for the simplifying function on the 
;;; property list to the indicator 'operators

(defprop %sqr simp-sqr operators)

;;; Support a verb function $sqr.
;;;
;;; This function is never called from the input of an user. We can use
;;; this function in Lisp code, when we need a call to the simplifier of
;;; the sqr function, e.g. ($sqr 4). Compare this with other widely
;;; used possibilities in Maxima code:
;;;
;;;    (simplifya (list '(%sqr) 4) nil)
;;;    (simplify (list '(%sqr) 4))
;;;    (take '(%sqr) 4) or
;;;    ($sqr 4)

(defun $sqr (z)
  (simplify (list '(%sqr) z)))

;;; Support a simplifying function.
;;;
;;; This might be the most simple, but complete simplifying function.
;;; It does not do much, but returns at least a simplified expression.
;;; The simplifying function is never called directly (it is bad 
;;; style to do it), it is called by the general simplifier, that is 
;;; the Lisp function simplifya.
;;;
;;; The simplifying function has three arguments.
;;;
;;; First argument expr: 
;;;    Contains the Maxima expression, which has to be simplified. 
;;;    It has the form ((%sqr) arg). The argument arg can be any
;;;    other Maxima expression.
;;;
;;; Second argument z: 
;;;    The simplifier calls the simplifying function always with 1 as 
;;;    the the second argument. This variable is free for use in the
;;;    function.
;;;    For a function with one argument it is convenient to use this
;;;    variable for the argument of the function.
;;;
;;; Third argument simpflag:
;;;    The simpflag has the values T or NIL. If NIL the argument of the
;;;    function is assumed not to be simplified. Otherwise the 
;;;    simplifier assumes that the argument is already simplified.    

(defun simp-sqr (expr z simpflag)
  ;; First check the correct number of arguments.
  ;; This function checks for one argument. If there are more or less 
  ;; then one argument then a Maxima error is generated.
  (oneargcheck expr)
  ;; Extract the argument of the function from the Maxima expression. 
  ;; The argument is the second element of the list. But first we pass
  ;; the argument and the value of simpflag to the function simpcheck. 
  ;; The function simpcheck checks if it is necessary to simplify the 
  ;; argument.
  ;; Furthermore, simpcheck removes special representations of the 
  ;; argument. These special representations are CRE-Expressions, 
  ;; Taylor- or Poission expansions.
  (setq z (simpcheck (cadr expr) simpflag))
  (cond
    (t
     ;; We have not done any useful simplification, but return a noun 
     ;; form.
     ;; The noun form is not returned directly, but via the function 
     ;; eqtest. This function has two important tasks:
     ;;   1. Add a simpflag to the expression.
     ;;   2. Check if the new expression is identical to the original
     ;;      expression. If this is the case, the orignal expression is
     ;;      returned.
     (eqtest (list '(%sqr) z) expr))))

;;; This implementation does not do much, but it is interesting to have
;;; a look at the main calls which are done to simplify a user input
;;; (This is a trace for the Lisp functions meval and simplifya): 
;;;
;;; (%i1) sqr(z);
;;; 
;;; * The user input is passed to meval.
;;; * First meval is called for the argument of the function.
;;; * After the call to meval for the argument, the argument is 
;;; * simplified.
;;; 1. Trace: (MEVAL '((%SQR) $Z))
;;;
;;; * meval is called for the argument of the the function.
;;; 2. Trace: (MEVAL '$Z)
;;;
;;; * Next the argument is simplified.
;;; 3. Trace: (SIMPLIFYA '$Z 'NIL)
;;; 3. Trace: SIMPLIFYA ==> $Z
;;; 2. Trace: MEVAL ==> $Z
;;;
;;; * Now the simplifer is called.
;;; 2. Trace: (SIMPLIFYA '((%SQR) $Z) 'NIL)
;;;
;;; * The simplifier detects, that we have a simplifying function.
;;; 3. Trace: (SIMP-SQR '((%SQR) $Z) '1 'NIL)
;;;
;;; * The argument of the functions is simplified again.
;;; 4. Trace: (SIMPLIFYA '$Z 'NIL)
;;;
;;; * We return from the calls
;;; 4. Trace: SIMPLIFYA ==> $Z
;;; 3. Trace: SIMP-SQR ==> ((%SQR SIMP) $Z)
;;; 2. Trace: SIMPLIFYA ==> ((%SQR SIMP) $Z)
;;; 1. Trace: MEVAL ==> ((%SQR SIMP) $Z)
;;;
;;; * The output is a simplified expression.
;;;
;;; (%o1)                               sqr(z)
;;;
;;; We need two calls to meval and three calls to simplifya to simplify
;;; an expression with an atomic argument this way.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; End of Chapter 1.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Dieter Kaiser