;; 4/4/08 RJF ;; I can't find the hashtable polynomial multiplication, so I'll rewrite it. ;; multivar version, sparse monomials (defun ptimes(r s) (declare (hash-table r s) (optimize (speed 3)(safety 0))) (let ((ans (make-hash-table :test 'equal ))) (maphash #'(lambda(ex co) ; exponent, coefficient (declare (integer co)) (maphash #'(lambda (ex2 co2) (declare(integer co2)) (incf (gethash (addexp ex ex2) ans 0) (* co co2)))r)) s) ans)) ;; add exponent vectors (defun addexp(a b)(cond ((null a) b)((null b) a) ;this may be slow.. better to pack in a word? (t (cons (the fixnum (+(the fixnum (car a))(the fixnum (car b)))) (addexp (cdr a)(cdr b)))))) (defun ppower(r n) (cond((= n 0) 1) ((= n 1) r) (t (ptimes r (ppower r (1- n)))))) (defun list2hash(k) ;; k looks like ((30 . (5 4 3))(21 . (9 7 0))) 30*x^5*y^4*z^3+ .. (let ((ans (make-hash-table :test 'equal))) (dolist (i k ans)(setf (gethash (cdr i) ans) (car i))))) (defun pdumps(r varlist) ; like pdump but sorted; 0 coeffs removed (let ((ans nil)) (cond ((numberp r) r) (t (maphash #'(lambda(key val)(unless (= 0 val) (push (cons key val) ans))) r) (map nil #'(lambda(k) (format t "~%~s" (cons (cdr k) (apply #'append (map 'list #'(lambda(r s) (cond ((= s 0)nil) ; ((= s 1) (list r)) (t (list '* r '^ s)))) varlist (car k))) ))) (sort ans #'lex> :key #'car)) )))) (defun lex> (a b)(cond ((null b) nil)((null a) t) ((= (car a)(car b))(lex> (cdr a)(cdr b))) ((> (car a)(car b)) t) (t nil))) (setf xx (list2hash '((1 . (1 2 4)) (10 .(3 4))) )) (setf xyzt1 '((1 . (1)) (1 . (0 1)) (1 . (0 0 1)) (1 . (0 0 0 1)) (1 0))) (setf fh (list2hash xyzt1)) ;; (setf xpy (list2hash `((,xx . 1)) 1)) ;;x+y ;(setf fh2 (ppower fh 2)) ;(pdumps fh2 '(x y z t))