]> code.delx.au - gnu-emacs/blobdiff - lisp/calc/calc-poly.el
Merge from emacs--rel--22
[gnu-emacs] / lisp / calc / calc-poly.el
index eba14b7d62175e6177d16d71bab47a62770ea7b9..de2cf2e01660bfbfb2796778a4a7e2ac102a602a 100644 (file)
@@ -1,34 +1,37 @@
-;; Calculator for GNU Emacs, part II [calc-poly.el]
-;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
-;; Written by Dave Gillespie, daveg@synaptics.com.
+;;; calc-poly.el --- polynomial functions for Calc
+
+;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
+;;   2005, 2006, 2007 Free Software Foundation, Inc.
+
+;; Author: David Gillespie <daveg@synaptics.com>
+;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
 
 ;; This file is part of GNU Emacs.
 
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
 ;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY.  No author or distributor
-;; accepts responsibility to anyone for the consequences of using it
-;; or for whether it serves any particular purpose or works at all,
-;; unless he says so in writing.  Refer to the GNU Emacs General Public
-;; License for full details.
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
 
-;; Everyone is granted permission to copy, modify and redistribute
-;; GNU Emacs, but only under the conditions described in the
-;; GNU Emacs General Public License.   A copy of this license is
-;; supposed to have been given to you along with GNU Emacs so you
-;; can know your rights and responsibilities.  It should be in a
-;; file named COPYING.  Among other things, the copyright notice
-;; and this notice must be preserved on all copies.
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
+;;; Commentary:
 
+;;; Code:
 
 ;; This file is autoloaded from calc-ext.el.
-(require 'calc-ext)
 
+(require 'calc-ext)
 (require 'calc-macs)
 
-(defun calc-Need-calc-poly () nil)
-
-
 (defun calcFunc-pcont (expr &optional var)
   (cond ((Math-primp expr)
         (cond ((Math-zerop expr) 1)
                   (math-neg (math-poly-gcd cont c2))
                 (math-poly-gcd cont c2))))))
        (var expr)
-       (t 1))
-)
+       (t 1)))
 
 (defun calcFunc-pprim (expr &optional var)
   (let ((cont (calcFunc-pcont expr var)))
     (if (math-equal-int cont 1)
        expr
-      (math-poly-div-exact expr cont var)))
-)
+      (math-poly-div-exact expr cont var))))
 
 (defun math-div-poly-const (expr c)
   (cond ((memq (car-safe expr) '(+ -))
         (list (car expr)
               (math-div-poly-const (nth 1 expr) c)
               (math-div-poly-const (nth 2 expr) c)))
-       (t (math-div expr c)))
-)
+       (t (math-div expr c))))
 
 (defun calcFunc-pdeg (expr &optional var)
   (if (Math-zerop expr)
@@ -89,8 +89,7 @@
     (if var
        (or (math-polynomial-p expr var)
            (math-reject-arg expr "Expected a polynomial"))
-      (math-poly-degree expr)))
-)
+      (math-poly-degree expr))))
 
 (defun math-poly-degree (expr)
   (cond ((Math-primp expr)
        ((memq (car expr) '(+ -))
         (max (math-poly-degree (nth 1 expr))
              (math-poly-degree (nth 2 expr))))
-       (t 1))
-)
+       (t 1)))
 
 (defun calcFunc-plead (expr var)
   (cond ((eq (car-safe expr) '*)
         (let ((p (math-is-polynomial expr var)))
           (if (cdr p)
               (nth (1- (length p)) p)
-            1))))
-)
+            1)))))
 
 
 
 ;;; Originally by Ove Ewerlid (ewerlid@mizar.DoCS.UU.SE).
 ;;; Modifications and simplifications by daveg.
 
-(setq math-poly-modulus 1)
+(defvar math-poly-modulus 1)
 
 ;;; Return gcd of two polynomials
 (defun calcFunc-pgcd (pn pd)
       (math-reject-arg pd "Coefficients must be rational"))
   (let ((calc-prefer-frac t)
        (math-poly-modulus (math-poly-modulus pn pd)))
-    (math-poly-gcd pn pd))
-)
+    (math-poly-gcd pn pd)))
 
 ;;; Return only quotient to top of stack (nil if zero)
+
+;; calc-poly-div-remainder is a local variable for 
+;; calc-poly-div (in calc-alg.el), but is used by
+;; calcFunc-pdiv, which is called by calc-poly-div.
+(defvar calc-poly-div-remainder)
+
 (defun calcFunc-pdiv (pn pd &optional base)
   (let* ((calc-prefer-frac t)
         (math-poly-modulus (math-poly-modulus pn pd))
         (res (math-poly-div pn pd base)))
     (setq calc-poly-div-remainder (cdr res))
-    (car res))
-)
+    (car res)))
 
 ;;; Return only remainder to top of stack
 (defun calcFunc-prem (pn pd &optional base)
   (let ((calc-prefer-frac t)
        (math-poly-modulus (math-poly-modulus pn pd)))
-    (cdr (math-poly-div pn pd base)))
-)
+    (cdr (math-poly-div pn pd base))))
 
 (defun calcFunc-pdivrem (pn pd &optional base)
   (let* ((calc-prefer-frac t)
         (math-poly-modulus (math-poly-modulus pn pd))
         (res (math-poly-div pn pd base)))
-    (list 'vec (car res) (cdr res)))
-)
+    (list 'vec (car res) (cdr res))))
 
 (defun calcFunc-pdivide (pn pd &optional base)
   (let* ((calc-prefer-frac t)
         (math-poly-modulus (math-poly-modulus pn pd))
         (res (math-poly-div pn pd base)))
-    (math-add (car res) (math-div (cdr res) pd)))
-)
+    (math-add (car res) (math-div (cdr res) pd))))
 
 
 ;;; Multiply two terms, expanding out products of sums.
        (list (car rhs)
              (math-mul-thru lhs (nth 1 rhs))
              (math-mul-thru lhs (nth 2 rhs)))
-      (math-mul lhs rhs)))
-)
+      (math-mul lhs rhs))))
 
 (defun math-div-thru (num den)
   (if (memq (car-safe num) '(+ -))
       (list (car num)
            (math-div-thru (nth 1 num) den)
            (math-div-thru (nth 2 num) den))
-    (math-div num den))
-)
+    (math-div num den)))
 
 
 ;;; Sort the terms of a sum into canonical order.
       (math-list-to-sum
        (sort (math-sum-to-list expr)
             (function (lambda (a b) (math-beforep (car a) (car b))))))
-    expr)
-)
+    expr))
 
 (defun math-list-to-sum (lst)
   (if (cdr lst)
            (car (car lst)))
     (if (cdr (car lst))
        (math-neg (car (car lst)))
-      (car (car lst))))
-)
+      (car (car lst)))))
 
 (defun math-sum-to-list (tree &optional neg)
   (cond ((eq (car-safe tree) '+)
        ((eq (car-safe tree) '-)
         (nconc (math-sum-to-list (nth 1 tree) neg)
                (math-sum-to-list (nth 2 tree) (not neg))))
-       (t (list (cons tree neg))))
-)
+       (t (list (cons tree neg)))))
 
 ;;; Check if the polynomial coefficients are modulo forms.
 (defun math-poly-modulus (expr &optional expr2)
   (or (math-poly-modulus-rec expr)
       (and expr2 (math-poly-modulus-rec expr2))
-      1)
-)
+      1))
 
 (defun math-poly-modulus-rec (expr)
   (if (and (eq (car-safe expr) 'mod) (Math-natnump (nth 2 expr)))
       (list 'mod 1 (nth 2 expr))
     (and (memq (car-safe expr) '(+ - * /))
         (or (math-poly-modulus-rec (nth 1 expr))
-            (math-poly-modulus-rec (nth 2 expr)))))
-)
+            (math-poly-modulus-rec (nth 2 expr))))))
 
 
 ;;; Divide two polynomials.  Return (quotient . remainder).
+(defvar math-poly-div-base nil)
 (defun math-poly-div (u v &optional math-poly-div-base)
   (if math-poly-div-base
       (math-do-poly-div u v)
-    (math-do-poly-div (calcFunc-expand u) (calcFunc-expand v)))
-)
-(setq math-poly-div-base nil)
+    (math-do-poly-div (calcFunc-expand u) (calcFunc-expand v))))
 
 (defun math-poly-div-exact (u v &optional base)
   (let ((res (math-poly-div u v base)))
     (if (eq (cdr res) 0)
        (car res)
-      (math-reject-arg (list 'vec u v) "Argument is not a polynomial")))
-)
+      (math-reject-arg (list 'vec u v) "Argument is not a polynomial"))))
 
 (defun math-do-poly-div (u v)
   (cond ((math-constp u)
             (setq up (math-is-polynomial u base nil 'gen)
                   res (math-poly-div-coefs up vp))
             (cons (math-build-polynomial-expr (car res) base)
-                  (math-build-polynomial-expr (cdr res) base))))))
-)
+                  (math-build-polynomial-expr (cdr res) base)))))))
 
 (defun math-poly-div-rec (u v)
   (cond ((math-constp u)
                   res (math-poly-div-coefs up vp))
             (math-add (math-build-polynomial-expr (car res) base)
                       (math-div (math-build-polynomial-expr (cdr res) base)
-                                v))))))
-)
+                                v)))))))
 
 ;;; Divide two polynomials in coefficient-list form.  Return (quot . rem).
 (defun math-poly-div-coefs (u v)
           (cons q (nreverse (mapcar 'math-simplify urev)))))
        (t
         (cons (list (math-poly-div-rec (car u) (car v)))
-              nil)))
-)
+              nil))))
 
 ;;; Perform a pseudo-division of polynomials.  (See Knuth section 4.6.1.)
 ;;; This returns only the remainder from the pseudo-division.
           (while (and urev (Math-zerop (car urev)))
             (setq urev (cdr urev)))
           (nreverse (mapcar 'math-simplify urev))))
-       (t nil))
-)
+       (t nil)))
 
 ;;; Compute the GCD of two multivariate polynomials.
 (defun math-poly-gcd (u v)
                  (math-poly-gcd-coefs (math-is-polynomial u base nil 'gen)
                                       (math-is-polynomial v base nil 'gen))
                  base)))
-            (calcFunc-gcd (calcFunc-pcont u) (calcFunc-pcont u))))))
-)
+            (calcFunc-gcd (calcFunc-pcont u) (calcFunc-pcont u)))))))
 
 (defun math-poly-div-list (lst a)
   (if (eq a 1)
       lst
     (if (eq a -1)
        (math-mul-list lst a)
-      (mapcar (function (lambda (x) (math-poly-div-exact x a))) lst)))
-)
+      (mapcar (function (lambda (x) (math-poly-div-exact x a))) lst))))
 
 (defun math-mul-list (lst a)
   (if (eq a 1)
     (if (eq a -1)
        (mapcar 'math-neg lst)
       (and (not (eq a 0))
-          (mapcar (function (lambda (x) (math-mul x a))) lst))))
-)
+          (mapcar (function (lambda (x) (math-mul x a))) lst)))))
 
 ;;; Run GCD on all elements in a list.
 (defun math-poly-gcd-list (lst)
        (or (eq (car lst) 0)
            (setq gcd (math-poly-gcd gcd (car lst)))))
       (if lst (setq lst (math-poly-gcd-frac-list lst)))
-      gcd))
-)
+      gcd)))
 
 (defun math-poly-gcd-frac-list (lst)
   (while (and lst (not (eq (car-safe (car lst)) 'frac)))
          (if (eq (car-safe (car lst)) 'frac)
              (setq denom (calcFunc-lcm denom (nth 2 (car lst))))))
        (list 'frac 1 denom))
-    1)
-)
+    1))
 
 ;;; Compute the GCD of two monovariate polynomial lists.
 ;;; Knuth section 4.6.1, algorithm C.
        (setq v (math-mul-list v -1)))
     (while (>= (setq z (1- z)) 0)
       (setq v (cons 0 v)))
-    v)
-)
+    v))
 
 
 ;;; Return true if is a factor containing no sums or quotients.
         nil)
        ((memq (car-safe expr) '(^ neg))
         (math-atomic-factorp (nth 1 expr)))
-       (t t))
-)
+       (t t)))
 
 ;;; Find a suitable base for dividing a by b.
 ;;; The base must exist in both expressions.
               (if maybe
                   (if (>= (nth 1 (car a-base)) (nth 1 maybe))
                       (throw 'return (car (car a-base))))))
-            (setq a-base (cdr a-base))))))
-)
+            (setq a-base (cdr a-base)))))))
 
 ;;; Same as above but for gcd algorithm.
 ;;; Here there is no requirement that degree(a) > degree(b).
                   (setq a-base (cdr a-base)))
               (if (assoc (car (car b-base)) a-base)
                   (throw 'return (car (car b-base)))
-                (setq b-base (cdr b-base))))))))
-)
+                (setq b-base (cdr b-base)))))))))
 
 ;;; Sort a list of polynomial bases.
 (defun math-sort-poly-base-list (lst)
   (sort lst (function (lambda (a b)
                        (or (> (nth 1 a) (nth 1 b))
                            (and (= (nth 1 a) (nth 1 b))
-                                (math-beforep (car a) (car b)))))))
-)
+                                (math-beforep (car a) (car b))))))))
 
 ;;; Given an expression find all variables that are polynomial bases.
 ;;; Return list in the form '( (var1 degree1) (var2 degree2) ... ).
-;;; Note dynamic scope of mpb-total-base.
+
+;; The variable math-poly-base-total-base is local to 
+;; math-total-polynomial-base, but is used by math-polynomial-p1,
+;; which is called by math-total-polynomial-base.
+(defvar math-poly-base-total-base)
+
 (defun math-total-polynomial-base (expr)
-  (let ((mpb-total-base nil))
+  (let ((math-poly-base-total-base nil))
     (math-polynomial-base expr 'math-polynomial-p1)
-    (math-sort-poly-base-list mpb-total-base))
-)
+    (math-sort-poly-base-list math-poly-base-total-base)))
+
+;; The variable math-poly-base-top-expr is local to math-polynomial-base
+;; in calc-alg.el, but is used by math-polynomial-p1 which is called
+;; by math-polynomial-base.
+(defvar math-poly-base-top-expr)
 
 (defun math-polynomial-p1 (subexpr)
-  (or (assoc subexpr mpb-total-base)
+  (or (assoc subexpr math-poly-base-total-base)
       (memq (car subexpr) '(+ - * / neg))
       (and (eq (car subexpr) '^) (natnump (nth 2 subexpr)))
       (let* ((math-poly-base-variable subexpr)
-            (exponent (math-polynomial-p mpb-top-expr subexpr)))
+            (exponent (math-polynomial-p math-poly-base-top-expr subexpr)))
        (if exponent
-           (setq mpb-total-base (cons (list subexpr exponent)
-                                      mpb-total-base)))))
-  nil
-)
-
-
-
-
-(defun calcFunc-factors (expr &optional var)
+           (setq math-poly-base-total-base (cons (list subexpr exponent)
+                                      math-poly-base-total-base)))))
+  nil)
+
+;; The variable math-factored-vars is local to calcFunc-factors and
+;; calcFunc-factor, but is used by math-factor-expr and 
+;; math-factor-expr-part, which are called (directly and indirectly) by
+;; calcFunc-factor and calcFunc-factors.
+(defvar math-factored-vars)
+
+;; The variable math-fact-expr is local to calcFunc-factors,
+;; calcFunc-factor and math-factor-expr, but is used by math-factor-expr-try 
+;; and math-factor-expr-part, which are called (directly and indirectly) by
+;; calcFunc-factor, calcFunc-factors and math-factor-expr.
+(defvar math-fact-expr)
+
+;; The variable math-to-list is local to calcFunc-factors and 
+;; calcFunc-factor, but is used by math-accum-factors, which is 
+;; called (indirectly) by calcFunc-factors and calcFunc-factor.
+(defvar math-to-list)
+
+(defun calcFunc-factors (math-fact-expr &optional var)
   (let ((math-factored-vars (if var t nil))
        (math-to-list t)
        (calc-prefer-frac t))
     (or var
-       (setq var (math-polynomial-base expr)))
+       (setq var (math-polynomial-base math-fact-expr)))
     (let ((res (math-factor-finish
                (or (catch 'factor (math-factor-expr-try var))
-                   expr))))
+                   math-fact-expr))))
       (math-simplify (if (math-vectorp res)
                         res
-                      (list 'vec (list 'vec res 1))))))
-)
+                      (list 'vec (list 'vec res 1)))))))
 
-(defun calcFunc-factor (expr &optional var)
+(defun calcFunc-factor (math-fact-expr &optional var)
   (let ((math-factored-vars nil)
        (math-to-list nil)
        (calc-prefer-frac t))
     (math-simplify (math-factor-finish
                    (if var
                        (let ((math-factored-vars t))
-                         (or (catch 'factor (math-factor-expr-try var)) expr))
-                     (math-factor-expr expr)))))
-)
+                         (or (catch 'factor (math-factor-expr-try var)) math-fact-expr))
+                     (math-factor-expr math-fact-expr))))))
 
 (defun math-factor-finish (x)
   (if (Math-primp x)
       x
     (if (eq (car x) 'calcFunc-Fac-Prot)
        (math-factor-finish (nth 1 x))
-      (cons (car x) (mapcar 'math-factor-finish (cdr x)))))
-)
+      (cons (car x) (mapcar 'math-factor-finish (cdr x))))))
 
 (defun math-factor-protect (x)
   (if (memq (car-safe x) '(+ -))
       (list 'calcFunc-Fac-Prot x)
-    x)
-)
-
-(defun math-factor-expr (expr)
-  (cond ((eq math-factored-vars t) expr)
-       ((or (memq (car-safe expr) '(* / ^ neg))
-            (assq (car-safe expr) calc-tweak-eqn-table))
-        (cons (car expr) (mapcar 'math-factor-expr (cdr expr))))
-       ((memq (car-safe expr) '(+ -))
+    x))
+
+(defun math-factor-expr (math-fact-expr)
+  (cond ((eq math-factored-vars t) math-fact-expr)
+       ((or (memq (car-safe math-fact-expr) '(* / ^ neg))
+            (assq (car-safe math-fact-expr) calc-tweak-eqn-table))
+        (cons (car math-fact-expr) (mapcar 'math-factor-expr (cdr math-fact-expr))))
+       ((memq (car-safe math-fact-expr) '(+ -))
         (let* ((math-factored-vars math-factored-vars)
-               (y (catch 'factor (math-factor-expr-part expr))))
+               (y (catch 'factor (math-factor-expr-part math-fact-expr))))
           (if y
               (math-factor-expr y)
-            expr)))
-       (t expr))
-)
+            math-fact-expr)))
+       (t math-fact-expr)))
 
 (defun math-factor-expr-part (x)    ; uses "expr"
   (if (memq (car-safe x) '(+ - * / ^ neg))
        (math-factor-expr-part (car x)))
     (and (not (Math-objvecp x))
         (not (assoc x math-factored-vars))
-        (> (math-factor-contains expr x) 1)
+        (> (math-factor-contains math-fact-expr x) 1)
         (setq math-factored-vars (cons (list x) math-factored-vars))
-        (math-factor-expr-try x)))
-)
-
-(defun math-factor-expr-try (x)
-  (if (eq (car-safe expr) '*)
-      (let ((res1 (catch 'factor (let ((expr (nth 1 expr)))
-                                  (math-factor-expr-try x))))
-           (res2 (catch 'factor (let ((expr (nth 2 expr)))
-                                  (math-factor-expr-try x)))))
+        (math-factor-expr-try x))))
+
+;; The variable math-fet-x is local to math-factor-expr-try, but is
+;; used by math-factor-poly-coefs, which is called by math-factor-expr-try.
+(defvar math-fet-x)
+
+(defun math-factor-expr-try (math-fet-x)
+  (if (eq (car-safe math-fact-expr) '*)
+      (let ((res1 (catch 'factor (let ((math-fact-expr (nth 1 math-fact-expr)))
+                                  (math-factor-expr-try math-fet-x))))
+           (res2 (catch 'factor (let ((math-fact-expr (nth 2 math-fact-expr)))
+                                  (math-factor-expr-try math-fet-x)))))
        (and (or res1 res2)
-            (throw 'factor (math-accum-factors (or res1 (nth 1 expr)) 1
-                                               (or res2 (nth 2 expr))))))
-    (let* ((p (math-is-polynomial expr x 30 'gen))
-          (math-poly-modulus (math-poly-modulus expr))
+            (throw 'factor (math-accum-factors (or res1 (nth 1 math-fact-expr)) 1
+                                               (or res2 (nth 2 math-fact-expr))))))
+    (let* ((p (math-is-polynomial math-fact-expr math-fet-x 30 'gen))
+          (math-poly-modulus (math-poly-modulus math-fact-expr))
           res)
       (and (cdr p)
           (setq res (math-factor-poly-coefs p))
-          (throw 'factor res))))
-)
+          (throw 'factor res)))))
 
 (defun math-accum-factors (fac pow facs)
   (if math-to-list
                  (cons 'vec (cons (nth 1 facs) (cons (list 'vec fac pow)
                                                      (cdr (cdr facs)))))
                (cons 'vec (cons (list 'vec fac pow) (cdr facs))))))))
-    (math-mul (math-pow fac pow) facs))
-)
+    (math-mul (math-pow fac pow) facs)))
 
 (defun math-factor-poly-coefs (p &optional square-free)    ; uses "x"
-  (let (t1 t2)
+  (let (t1 t2 temp)
     (cond ((not (cdr p))
           (or (car p) 0))
 
-         ;; Strip off multiples of x.
+         ;; Strip off multiples of math-fet-x.
          ((Math-zerop (car p))
           (let ((z 0))
             (while (and p (Math-zerop (car p)))
             (if (cdr p)
                 (setq p (math-factor-poly-coefs p square-free))
               (setq p (math-sort-terms (math-factor-expr (car p)))))
-            (math-accum-factors x z (math-factor-protect p))))
+            (math-accum-factors math-fet-x z (math-factor-protect p))))
 
          ;; Factor out content.
          ((and (not square-free)
           (math-accum-factors t1 1 (math-factor-poly-coefs
                                     (math-poly-div-list p t1) 'cont)))
 
-         ;; Check if linear in x.
+         ;; Check if linear in math-fet-x.
          ((not (cdr (cdr p)))
-          (math-add (math-factor-protect
-                     (math-sort-terms
-                      (math-factor-expr (car p))))
-                    (math-mul x (math-factor-protect
-                                 (math-sort-terms
-                                  (math-factor-expr (nth 1 p)))))))
+           (math-sort-terms
+            (math-add (math-factor-protect
+                       (math-sort-terms
+                        (math-factor-expr (car p))))
+                      (math-mul math-fet-x (math-factor-protect
+                                            (math-sort-terms
+                                             (math-factor-expr (nth 1 p))))))))
 
          ;; If symbolic coefficients, use FactorRules.
          ((let ((pp p))
               (setq pp (cdr pp)))
             pp)
           (let ((res (math-rewrite
-                      (list 'calcFunc-thecoefs x (cons 'vec p))
+                      (list 'calcFunc-thecoefs math-fet-x (cons 'vec p))
                       '(var FactorRules var-FactorRules))))
             (or (and (eq (car-safe res) 'calcFunc-thefactors)
                      (= (length res) 3)
                        (while (setq vec (cdr vec))
                          (setq facs (math-accum-factors (car vec) 1 facs)))
                        facs))
-                (math-build-polynomial-expr p x))))
+                (math-build-polynomial-expr p math-fet-x))))
 
          ;; Check if rational coefficients (i.e., not modulo a prime).
          ((eq math-poly-modulus 1)
                                           (setq scale (math-div scale den))
                                           (math-add
                                            (math-add
-                                            (math-mul den (math-pow x 2))
-                                            (math-mul (math-mul coef1 den) x))
+                                            (math-mul den (math-pow math-fet-x 2))
+                                            (math-mul (math-mul coef1 den) 
+                                                       math-fet-x))
                                            (math-mul coef0 den)))
                                       (let ((den (math-lcm-denoms coef0)))
                                         (setq scale (math-div scale den))
-                                        (math-add (math-mul den x)
+                                        (math-add (math-mul den math-fet-x)
                                                   (math-mul coef0 den))))
                                     1 expr)
                               roots (cdr roots))))
                                 (math-mul csign
                                           (math-build-polynomial-expr
                                            (math-mul-list (nth 1 t1) scale)
-                                           x)))))
-                (math-build-polynomial-expr p x))   ; can't factor it.
+                                           math-fet-x)))))
+                (math-build-polynomial-expr p math-fet-x))   ; can't factor it.
 
             ;; Separate out the squared terms (Knuth exercise 4.6.2-34).
             ;; This step also divides out the content of the polynomial.
           (and (setq temp (math-factor-poly-coefs p))
                (math-pow temp (nth 2 math-poly-modulus))))
          (t
-          (math-reject-arg nil "*Modulo factorization not yet implemented"))))
-)
+          (math-reject-arg nil "*Modulo factorization not yet implemented")))))
 
 (defun math-poly-deriv-coefs (p)
   (let ((n 1)
     (while (setq p (cdr p))
       (setq dp (cons (math-mul (car p) n) dp)
            n (1+ n)))
-    (nreverse dp))
-)
+    (nreverse dp)))
 
 (defun math-factor-contains (x a)
   (if (equal x a)
       (if (and (eq (car-safe x) '^)
               (natnump (nth 2 x)))
          (* (math-factor-contains (nth 1 x) a) (nth 2 x))
-       0)))
-)
+       0))))
 
 
 
                (den2 (math-poly-div den g)))
            (and (eq (cdr num2) 0) (eq (cdr den2) 0)
                 (setq num (car num2) den (car den2)))))
-      (math-simplify (math-div num den))))
-)
+      (math-simplify (math-div num den)))))
 
 ;;; Returns expressions (num . denom).
 (defun math-to-ratpoly (expr)
   (let ((res (math-to-ratpoly-rec expr)))
-    (cons (math-simplify (car res)) (math-simplify (cdr res))))
-)
+    (cons (math-simplify (car res)) (math-simplify (cdr res)))))
 
 (defun math-to-ratpoly-rec (expr)
   (cond ((Math-primp expr)
        ((eq (car expr) 'neg)
         (let ((r1 (math-to-ratpoly-rec (nth 1 expr))))
           (cons (math-neg (car r1)) (cdr r1))))
-       (t (cons expr 1)))
-)
+       (t (cons expr 1))))
 
 
 (defun math-ratpoly-p (expr &optional var)
           (and p1 (* p1 (nth 2 expr)))))
        ((not var) 1)
        ((math-poly-depends expr var) nil)
-       (t 0))
-)
+       (t 0)))
 
 
 (defun calcFunc-apart (expr &optional var)
           (math-add q (or (and var
                                (math-expr-contains den var)
                                (math-partial-fractions r den var))
-                          (math-div r den))))))
-)
+                          (math-div r den)))))))
 
 
 (defun math-padded-polynomial (expr var deg)
+  "Return a polynomial as list of coefficients.
+If EXPR is of the form \"a + bx + cx^2 + ...\" in the variable VAR, return
+the list (a b c ...) with at least DEG elements, else return NIL."
   (let ((p (math-is-polynomial expr var deg)))
-    (append p (make-list (- deg (length p)) 0)))
-)
+    (append p (make-list (- deg (length p)) 0))))
 
 (defun math-partial-fractions (r den var)
+  "Return R divided by DEN expressed in partial fractions of VAR.
+All whole factors of DEN have already been split off from R.
+If no partial fraction representation can be found, return nil."
   (let* ((fden (calcFunc-factors den var))
         (tdeg (math-polynomial-p den var))
         (fp fden)
                              res (math-add res (math-div num (car dlist)))
                              num nil))
                    (setq dlist (cdr dlist)))
-                 (math-normalize res))))))
-)
+                 (math-normalize res)))))))
 
 
 
        ((and (eq (car-safe expr) '^)
              (memq (car-safe (nth 1 expr)) '(+ -))
              (integerp (nth 2 expr))
-             (if (> (nth 2 expr) 0)
-                 (or (and (or (> mmt-many 500000) (< mmt-many -500000))
-                          (math-expand-power (nth 1 expr) (nth 2 expr)
-                                             nil t))
-                     (list '*
-                           (nth 1 expr)
-                           (list '^ (nth 1 expr) (1- (nth 2 expr)))))
-               (if (< (nth 2 expr) 0)
-                   (list '/ 1 (list '^ (nth 1 expr) (- (nth 2 expr))))))))
-       (t expr))
-)
+              (if (and 
+                   (or (math-known-matrixp (nth 1 (nth 1 expr)))
+                       (math-known-matrixp (nth 2 (nth 1 expr)))
+                       (and
+                        calc-matrix-mode
+                        (not (eq calc-matrix-mode 'scalar))
+                        (not (and (math-known-scalarp (nth 1 (nth 1 expr)))
+                                  (math-known-scalarp (nth 2 (nth 1 expr)))))))
+                   (> (nth 2 expr) 1))
+                  (if (= (nth 2 expr) 2)
+                      (math-add-or-sub (list '* (nth 1 (nth 1 expr)) (nth 1 expr))
+                                       (list '* (nth 2 (nth 1 expr)) (nth 1 expr))
+                                       nil (eq (car (nth 1 expr)) '-))
+                    (math-add-or-sub (list '* (nth 1 (nth 1 expr)) 
+                                           (list '^ (nth 1 expr) 
+                                                 (1- (nth 2 expr))))
+                                     (list '* (nth 2 (nth 1 expr)) 
+                                           (list '^ (nth 1 expr) 
+                                                 (1- (nth 2 expr))))
+                                     nil (eq (car (nth 1 expr)) '-)))
+                (if (> (nth 2 expr) 0)
+                    (or (and (or (> math-mt-many 500000) (< math-mt-many -500000))
+                             (math-expand-power (nth 1 expr) (nth 2 expr)
+                                                nil t))
+                        (list '*
+                              (nth 1 expr)
+                              (list '^ (nth 1 expr) (1- (nth 2 expr)))))
+                  (if (< (nth 2 expr) 0)
+                      (list '/ 1 (list '^ (nth 1 expr) (- (nth 2 expr)))))))))
+       (t expr)))
 
 (defun calcFunc-expand (expr &optional many)
-  (math-normalize (math-map-tree 'math-expand-term expr many))
-)
+  (math-normalize (math-map-tree 'math-expand-term expr many)))
 
 (defun math-expand-power (x n &optional var else-nil)
   (or (and (natnump n)
                         (setq p1 (cdr p1)))
                       accum))))))
       (and (not else-nil)
-          (list '^ x n)))
-)
+          (list '^ x n))))
 
 (defun calcFunc-expandpow (x n)
-  (math-normalize (math-expand-power x n))
-)
-
+  (math-normalize (math-expand-power x n)))
 
+(provide 'calc-poly)
 
+;;; arch-tag: d2566c51-2ccc-45f1-8c50-f3462c2953ff
+;;; calc-poly.el ends here