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