(math-clip, math-round, math-simplify)
[bpt/emacs.git] / lisp / calc / calc-ext.el
index 3347d8f..31203f9 100644 (file)
@@ -1,26 +1,27 @@
 ;;; calc-ext.el --- various extension functions for Calc
 
-;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2004 Free Software Foundation, Inc.
+;; 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 <belanger@truman.edu>
+;; 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.
-
-;; 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.
+;; 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.
+
+;; 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:
 
 (require 'calc)
 (require 'calc-macs)
 
+;; Declare functions which are defined elsewhere.
+(declare-function math-clip "calc-bin" (a &optional w))
+(declare-function math-round "calc-arith" (a &optional prec))
+(declare-function math-simplify "calc-alg" (top-expr))
+(declare-function math-simplify-extended "calc-alg" (a))
+(declare-function math-simplify-units "calc-units" (a))
+(declare-function calc-set-language "calc-lang" (lang &optional option no-refresh))
+(declare-function calc-flush-caches "calc-stuff" (&optional inhibit-msg))
+(declare-function calc-save-modes "calc-mode" ())
+(declare-function calc-embedded-modes-change "calc-embed" (vars))
+(declare-function calc-embedded-var-change "calc-embed" (var &optional buf))
+(declare-function math-mul-float "calc-arith" (a b))
+(declare-function math-arctan-raw "calc-math" (x))
+(declare-function math-sqrt-float "calc-math" (a &optional guess))
+(declare-function math-exp-minus-1-raw "calc-math" (x))
+(declare-function math-normalize-polar "calc-cplx" (a))
+(declare-function math-normalize-hms "calc-forms" (a))
+(declare-function math-normalize-mod "calc-forms" (a))
+(declare-function math-make-sdev "calc-forms" (x sigma))
+(declare-function math-make-intv "calc-forms" (mask lo hi))
+(declare-function math-normalize-logical-op "calc-prog" (a))
+(declare-function math-possible-signs "calc-arith" (a &optional origin))
+(declare-function math-infinite-dir "calc-math" (a &optional inf))
+(declare-function math-calcFunc-to-var "calc-map" (f))
+(declare-function calc-embedded-evaluate-expr "calc-embed" (x))
+(declare-function math-known-nonzerop "calc-arith" (a))
+(declare-function math-read-expr-level "calc-aent" (exp-prec &optional exp-term))
+(declare-function math-read-big-rec "calc-lang" (math-rb-h1 math-rb-v1 math-rb-h2 math-rb-v2))
+(declare-function math-read-big-balance "calc-lang" (h v what &optional commas))
+(declare-function math-format-date "calc-forms" (math-fd-date))
+(declare-function math-vector-is-string "calccomp" (a))
+(declare-function math-vector-to-string "calccomp" (a &optional quoted))
+(declare-function math-format-radix-float "calc-bin" (a prec))
+(declare-function math-compose-expr "calccomp" (a prec))
+(declare-function math-abs "calc-arith" (a))
+(declare-function math-format-bignum-binary "calc-bin" (a))
+(declare-function math-format-bignum-octal "calc-bin" (a))
+(declare-function math-format-bignum-hex "calc-bin" (a))
+(declare-function math-format-bignum-radix "calc-bin" (a))
+(declare-function math-compute-max-digits "calc-bin" (w r))
+
+
 (defvar math-simplifying nil)
 (defvar math-living-dangerously nil)   ; true if unsafe simplifications are okay.
 (defvar math-integrating nil)
@@ -43,6 +86,9 @@
 (defvar math-comp-sel-cpos nil)
 (defvar math-compose-hash-args nil)
 
+(defvar calc-alg-map)
+(defvar calc-alg-esc-map)
+
 ;;; The following was made a function so that it could be byte-compiled.
 (defun calc-init-extensions ()
 
   (define-key calc-mode-map "dO" 'calc-flat-language)
   (define-key calc-mode-map "dP" 'calc-pascal-language)
   (define-key calc-mode-map "dT" 'calc-tex-language)
+  (define-key calc-mode-map "dL" 'calc-latex-language)
   (define-key calc-mode-map "dU" 'calc-unformatted-language)
   (define-key calc-mode-map "dW" 'calc-maple-language)
   (define-key calc-mode-map "d[" 'calc-truncate-up)
   (define-key calc-mode-map "m?" 'calc-m-prefix-help)
   (define-key calc-mode-map "ma" 'calc-algebraic-mode)
   (define-key calc-mode-map "md" 'calc-degrees-mode)
+  (define-key calc-mode-map "me" 'calc-embedded-preserve-modes)
   (define-key calc-mode-map "mf" 'calc-frac-mode)
   (define-key calc-mode-map "mg" 'calc-get-modes)
   (define-key calc-mode-map "mh" 'calc-hms-mode)
   (define-key calc-mode-map "sd" 'calc-declare-variable)
   (define-key calc-mode-map "se" 'calc-edit-variable)
   (define-key calc-mode-map "si" 'calc-insert-variables)
+  (define-key calc-mode-map "sk" 'calc-copy-special-constant)
   (define-key calc-mode-map "sl" 'calc-let)
   (define-key calc-mode-map "sm" 'calc-store-map)
   (define-key calc-mode-map "sn" 'calc-store-neg)
 
   (calc-init-prefixes)
 
-  (mapcar (function
-          (lambda (x)
-            (define-key calc-mode-map (format "c%c" x) 'calc-clean-num)
-            (define-key calc-mode-map (format "j%c" x) 'calc-select-part)
-            (define-key calc-mode-map (format "r%c" x) 'calc-recall-quick)
-            (define-key calc-mode-map (format "s%c" x) 'calc-store-quick)
-            (define-key calc-mode-map (format "t%c" x) 'calc-store-into-quick)
-            (define-key calc-mode-map (format "u%c" x) 'calc-quick-units)))
-         "0123456789")
+  (mapc (function
+        (lambda (x)
+         (define-key calc-mode-map (format "c%c" x) 'calc-clean-num)
+         (define-key calc-mode-map (format "j%c" x) 'calc-select-part)
+         (define-key calc-mode-map (format "r%c" x) 'calc-recall-quick)
+         (define-key calc-mode-map (format "s%c" x) 'calc-store-quick)
+         (define-key calc-mode-map (format "t%c" x) 'calc-store-into-quick)
+         (define-key calc-mode-map (format "u%c" x) 'calc-quick-units)))
+       "0123456789")
 
   (let ((i ?A))
     (while (<= i ?z)
                (cons 'keymap (cons (cons ?\e (aref (nth 1 calc-mode-map) i))
                                    (cdr (aref (nth 1 calc-mode-map) i))))))
       (setq i (1+ i))))
-  
+
   (setq calc-alg-map (copy-keymap calc-mode-map)
        calc-alg-esc-map (copy-keymap esc-map))
   (let ((i 32))
   (define-key calc-alg-map "\e\177" 'calc-pop-above)
 
 ;;;; (Autoloads here)
-  (mapcar (function (lambda (x)
+  (mapc (function (lambda (x)
     (mapcar (function (lambda (func)
       (autoload func (car x)))) (cdr x))))
     '(
  ("calc-alg" calc-has-rules math-defsimplify
 calc-modify-simplify-mode calcFunc-collect calcFunc-esimplify
 calcFunc-islin calcFunc-islinnt calcFunc-lin calcFunc-linnt
-calcFunc-simplify calcFunc-subst math-beforep
+calcFunc-simplify calcFunc-subst calcFunc-powerexpand math-beforep
 math-build-polynomial-expr math-expand-formula math-expr-contains
 math-expr-contains-count math-expr-depends math-expr-height
 math-expr-subst math-expr-weight math-integer-plus math-is-linear
@@ -687,7 +736,7 @@ calcFunc-dnonneg calcFunc-dnonzero calcFunc-dnumint calcFunc-dodd
 calcFunc-dpos calcFunc-drange calcFunc-drat calcFunc-dreal
 calcFunc-dscalar calcFunc-fceil calcFunc-ffloor calcFunc-float
 calcFunc-fround calcFunc-frounde calcFunc-froundu calcFunc-ftrunc
-calcFunc-idiv calcFunc-incr calcFunc-mant calcFunc-max calcFunc-min
+calcFunc-idiv calcFunc-incr calcFunc-ldiv calcFunc-mant calcFunc-max calcFunc-min
 calcFunc-mod calcFunc-mul calcFunc-neg calcFunc-percent calcFunc-pow
 calcFunc-relch calcFunc-round calcFunc-rounde calcFunc-roundu
 calcFunc-scf calcFunc-sub calcFunc-xpon math-abs math-abs-approx
@@ -736,7 +785,8 @@ math-polar math-want-polar)
 
  ("calc-embed" calc-do-embedded
 calc-do-embedded-activate calc-embedded-evaluate-expr
-calc-embedded-modes-change calc-embedded-var-change)
+calc-embedded-modes-change calc-embedded-var-change
+calc-embedded-preserve-modes)
 
  ("calc-fin" calc-to-percentage calcFunc-ddb
 calcFunc-fv calcFunc-fvb calcFunc-fvl calcFunc-irr calcFunc-irrb
@@ -800,13 +850,16 @@ math-mul-mat-vec math-mul-mats math-row-matrix)
 
  ("calc-math" calcFunc-alog calcFunc-arccos
 calcFunc-arccosh calcFunc-arcsin calcFunc-arcsincos calcFunc-arcsinh
-calcFunc-arctan calcFunc-arctan2 calcFunc-arctanh calcFunc-cos
-calcFunc-cosh calcFunc-deg calcFunc-exp calcFunc-exp10 calcFunc-expm1
+calcFunc-arctan calcFunc-arctan2 calcFunc-arctanh calcFunc-csc
+calcFunc-csch calcFunc-cos calcFunc-cosh calcFunc-cot calcFunc-coth
+calcFunc-deg calcFunc-exp calcFunc-exp10 calcFunc-expm1
 calcFunc-hypot calcFunc-ilog calcFunc-isqrt calcFunc-ln calcFunc-lnp1
-calcFunc-log calcFunc-log10 calcFunc-nroot calcFunc-rad calcFunc-sin
+calcFunc-log calcFunc-log10 calcFunc-nroot calcFunc-rad calcFunc-sec
+calcFunc-sech calcFunc-sin
 calcFunc-sincos calcFunc-sinh calcFunc-sqr calcFunc-sqrt calcFunc-tan
 calcFunc-tanh math-arccos-raw math-arcsin-raw math-arctan-raw
-math-arctan2-raw math-cos-raw math-exp-minus-1-raw math-exp-raw
+math-arctan2-raw math-cos-raw math-cot-raw math-csc-raw
+math-exp-minus-1-raw math-exp-raw
 math-from-radians math-from-radians-2 math-hypot math-infinite-dir
 math-isqrt-small math-ln-raw math-nearly-equal math-nearly-equal-float
 math-nearly-zerop math-nearly-zerop-float math-nth-root
@@ -912,7 +965,7 @@ calc-force-refresh calc-locate-cursor-element calc-show-edit-buffer)
  ("calc-alg" calc-alg-evaluate calc-apart calc-collect calc-expand
 calc-expand-formula calc-factor calc-normalize-rat calc-poly-div
 calc-poly-div-rem calc-poly-gcd calc-poly-rem calc-simplify
-calc-simplify-extended calc-substitute)
+calc-simplify-extended calc-substitute calc-powerexpand)
 
  ("calcalg2" calc-alt-summation calc-derivative
 calc-dump-integral-cache calc-integral calc-num-integral
@@ -998,7 +1051,7 @@ calc-keypad-press)
  ("calc-lang" calc-big-language calc-c-language calc-eqn-language
 calc-flat-language calc-fortran-language calc-maple-language
 calc-mathematica-language calc-normal-language calc-pascal-language
-calc-tex-language calc-unformatted-language)
+calc-tex-language calc-latex-language calc-unformatted-language)
 
  ("calc-map" calc-accumulate calc-apply calc-inner-product calc-map
 calc-map-equation calc-map-stack calc-outer-product calc-reduce)
@@ -1007,9 +1060,11 @@ calc-map-equation calc-map-stack calc-outer-product calc-reduce)
 
  ("calc-math" calc-arccos calc-arccosh calc-arcsin calc-arcsinh
 calc-arctan calc-arctan2 calc-arctanh calc-conj calc-cos calc-cosh
+calc-cot calc-coth calc-csc calc-csch
 calc-degrees-mode calc-exp calc-expm1 calc-hypot calc-ilog
 calc-imaginary calc-isqrt calc-ln calc-lnp1 calc-log calc-log10
-calc-pi calc-radians-mode calc-sin calc-sincos calc-sinh calc-sqrt
+calc-pi calc-radians-mode calc-sec calc-sech
+calc-sin calc-sincos calc-sinh calc-sqrt
 calc-tan calc-tanh calc-to-degrees calc-to-radians)
 
  ("calc-mode" calc-alg-simplify-mode calc-algebraic-mode
@@ -1067,7 +1122,8 @@ calc-vector-pop-covariance calc-vector-pop-sdev
 calc-vector-pop-variance calc-vector-product calc-vector-sdev
 calc-vector-sum calc-vector-variance)
 
- ("calc-store" calc-assign calc-copy-variable calc-declare-variable
+ ("calc-store" calc-assign calc-copy-special-constant
+calc-copy-variable calc-declare-variable
 calc-edit-AlgSimpRules calc-edit-Decls calc-edit-EvalRules
 calc-edit-ExtSimpRules calc-edit-FitRules calc-edit-GenCount
 calc-edit-Holidays calc-edit-IntegLimit calc-edit-LineStyles
@@ -1182,8 +1238,9 @@ calc-kill calc-kill-region calc-yank))))
           (math-normalize val)))))
 
 
+(defvar calc-help-map nil)
 
-(if (boundp 'calc-help-map)
+(if calc-help-map
     nil
   (setq calc-help-map (make-keymap))
   (define-key calc-help-map "b" 'calc-describe-bindings)
@@ -1240,36 +1297,54 @@ calc-kill calc-kill-region calc-yank))))
 
 (defun calc-reset (arg)
   (interactive "P")
-  (save-excursion
-    (or (eq major-mode 'calc-mode)
-       (calc-create-buffer))
-    (if calc-embedded-info
-       (calc-embedded nil))
-    (or arg
-       (setq calc-stack nil))
-    (setq calc-undo-list nil
-         calc-redo-list nil)
-    (let (calc-stack calc-user-parse-tables calc-standard-date-formats
-                    calc-invocation-macro)
-      (mapcar (function (lambda (v) (set v nil))) calc-local-var-list)
-      (mapcar (function (lambda (v) (set (car v) (nth 1 v))))
-             calc-mode-var-list))
-    (calc-set-language nil nil t)
-    (calc-mode)
-    (calc-flush-caches t)
-    (run-hooks 'calc-reset-hook))
-  (calc-wrapper
-   (let ((win (get-buffer-window (current-buffer))))
-     (calc-realign 0)
-     (if win
-        (let ((height (- (window-height win) 2)))
-          (set-window-point win (point))
-          (or (= height calc-window-height)
-              (let ((swin (selected-window)))
-                (select-window win)
-                (enlarge-window (- calc-window-height height))
-                (select-window swin)))))))
-  (message "(Calculator reset)"))
+  (setq arg (if arg (prefix-numeric-value arg) nil))
+  (cond
+   ((and
+     calc-embedded-info
+     (equal (aref calc-embedded-info 0) (current-buffer))
+     (<= (point) (aref calc-embedded-info 5))
+     (>= (point) (aref calc-embedded-info 4)))
+    (let ((cbuf (aref calc-embedded-info 1))
+          (calc-embedded-quiet t))
+      (save-window-excursion
+        (calc-embedded nil)
+        (set-buffer cbuf)
+        (calc-reset arg))
+      (calc-embedded nil)))
+   ((eq major-mode 'calc-mode)
+    (save-excursion
+      (unless (and arg (> (abs arg) 0))
+        (setq calc-stack nil))
+      (setq calc-undo-list nil
+            calc-redo-list nil)
+      (let (calc-stack calc-user-parse-tables calc-standard-date-formats
+                       calc-invocation-macro)
+        (mapc (function (lambda (v) (set v nil))) calc-local-var-list)
+        (if (and arg (<= arg 0))
+            (calc-mode-var-list-restore-default-values)
+          (calc-mode-var-list-restore-saved-values)))
+      (calc-set-language nil nil t)
+      (calc-mode)
+      (calc-flush-caches t)
+      (run-hooks 'calc-reset-hook))
+    (calc-wrapper
+     (let ((win (get-buffer-window (current-buffer))))
+       (calc-realign 0)
+       ;; Adjust the window height if the window is visible, but doesn't
+       ;; take up the whole height of the frame.
+       (if (and
+            win
+            (< (window-height win) (1- (frame-height))))
+           (let ((height (- (window-height win) 2)))
+             (set-window-point win (point))
+             (or (= height calc-window-height)
+                 (let ((swin (selected-window)))
+                   (select-window win)
+                   (enlarge-window (- calc-window-height height))
+                   (select-window swin)))))))
+    (message "(Calculator reset)"))
+   (t
+    (message "(Not inside a Calc buffer)"))))
 
 ;; What a pain; scroll-left behaves differently when called non-interactively.
 (defun calc-scroll-left (n)
@@ -1318,11 +1393,13 @@ calc-kill calc-kill-region calc-yank))))
 
 (defun calc-inverse (&optional n)
   (interactive "P")
-  (let* ((hyp-flag (if (eq major-mode 'calc-keypad-mode)
+  (let* ((hyp-flag (if (or
+                        (eq major-mode 'calc-keypad-mode)
+                        (eq major-mode 'calc-trail-mode))
                        (with-current-buffer calc-main-buffer
                          calc-hyperbolic-flag)
                      calc-hyperbolic-flag))
-         (msg (if hyp-flag 
+         (msg (if hyp-flag
                  "Inverse Hyperbolic..."
                "Inverse...")))
     (calc-fancy-prefix 'calc-inverse-flag msg n)))
@@ -1374,10 +1451,14 @@ calc-kill calc-kill-region calc-yank))))
 
 (defun calc-fancy-prefix-other-key (arg)
   (interactive "P")
-  (if (or (not (integerp last-command-char))
-         (and (>= last-command-char 0) (< last-command-char ? )
-              (not (eq last-command-char meta-prefix-char))))
+  (if (and
+       (not (eq last-command-char 'tab))
+       (not (eq last-command-char 'M-tab))
+       (or (not (integerp last-command-char))
+           (and (>= last-command-char 0) (< last-command-char ? )
+                (not (eq last-command-char meta-prefix-char)))))
      (calc-wrapper))  ; clear flags if not a Calc command.
+  (setq prefix-arg arg)
   (calc-unread-command)
   (setq overriding-terminal-local-map nil))
 
@@ -1393,11 +1474,13 @@ calc-kill calc-kill-region calc-yank))))
 
 (defun calc-hyperbolic (&optional n)
   (interactive "P")
-  (let* ((inv-flag (if (eq major-mode 'calc-keypad-mode)
+  (let* ((inv-flag (if (or
+                        (eq major-mode 'calc-keypad-mode)
+                        (eq major-mode 'calc-trail-mode))
                        (with-current-buffer calc-main-buffer
                          calc-inverse-flag)
                      calc-inverse-flag))
-         (msg (if inv-flag 
+         (msg (if inv-flag
                   "Inverse Hyperbolic..."
                 "Hyperbolic...")))
     (calc-fancy-prefix 'calc-hyperbolic-flag msg n)))
@@ -1741,8 +1824,8 @@ calc-kill calc-kill-region calc-yank))))
 ;;; User menu.
 
 (defun calc-user-key-map ()
-  (if calc-emacs-type-lucid
-      (error "User-defined keys are not supported in Lucid Emacs"))
+  (if (featurep 'xemacs)
+      (error "User-defined keys are not supported in XEmacs"))
   (let ((res (cdr (lookup-key calc-mode-map "z"))))
     (if (eq (car (car res)) 27)
        (cdr res)
@@ -1808,7 +1891,7 @@ calc-kill calc-kill-region calc-yank))))
                 (setq calc-z-prefix-buf (concat (if (= flags 1) "SHIFT + " "")
                                   desc))
               (if (> (+ (length calc-z-prefix-buf) (length desc)) 58)
-                  (setq calc-z-prefix-msgs 
+                  (setq calc-z-prefix-msgs
                          (cons calc-z-prefix-buf calc-z-prefix-msgs)
                         calc-z-prefix-buf (concat (if (= flags 1) "SHIFT + " "")
                                     desc))
@@ -1837,8 +1920,19 @@ calc-kill calc-kill-region calc-yank))))
        (last-prec (intern (concat (symbol-name name) "-last-prec")))
        (last-val (intern (concat (symbol-name name) "-last"))))
     (list 'progn
-         (list 'defvar cache-prec (if init (math-numdigs (nth 1 init)) -100))
-         (list 'defvar cache-val (list 'quote init))
+;        (list 'defvar cache-prec (if init (math-numdigs (nth 1 init)) -100))
+         (list 'defvar cache-prec
+                `(cond
+                  ((consp ,init) (math-numdigs (nth 1 ,init)))
+                  (,init
+                   (nth 1 (math-numdigs (eval ,init))))
+                  (t
+                   -100)))
+         (list 'defvar cache-val
+                `(cond
+                  ((consp ,init) ,init)
+                  (,init (eval ,init))
+                  (t ,init)))
          (list 'defvar last-prec -100)
          (list 'defvar last-val nil)
          (list 'setq 'math-cache-list
@@ -1873,7 +1967,11 @@ calc-kill calc-kill-region calc-yank))))
 (put 'math-defcache 'lisp-indent-hook 2)
 
 ;;; Betcha didn't know that pi = 16 atan(1/5) - 4 atan(1/239).   [F] [Public]
-(math-defcache math-pi (float (bigpos 463 238 793 589 653 592 141 3) -21)
+(defconst math-approx-pi
+  (math-read-number-simple "3.141592653589793238463")
+  "An approximation for pi.")
+
+(math-defcache math-pi math-approx-pi
   (math-add-float (math-mul-float '(float 16 0)
                                  (math-arctan-raw '(float 2 -1)))
                  (math-mul-float '(float -4 0)
@@ -1904,7 +2002,11 @@ calc-kill calc-kill-region calc-yank))))
 (math-defcache math-sqrt-two-pi nil
   (math-sqrt-float (math-two-pi)))
 
-(math-defcache math-sqrt-e (float (bigpos 849 146 128 700 270 721 648 1) -21)
+(defconst math-approx-sqrt-e
+  (math-read-number-simple "1.648721270700128146849")
+  "An approximation for sqrt(3).")
+
+(math-defcache math-sqrt-e math-approx-sqrt-e
   (math-add-float '(float 1 0) (math-exp-minus-1-raw '(float 5 -1))))
 
 (math-defcache math-e nil
@@ -1914,10 +2016,13 @@ calc-kill calc-kill-region calc-yank))))
   (math-mul-float (math-add-float (math-sqrt-raw '(float 5 0)) '(float 1 0))
                  '(float 5 -1)))
 
+(defconst math-approx-gamma-const
+  (math-read-number-simple
+   "0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495")
+  "An approximation for gamma.")
+
 (math-defcache math-gamma-const nil
-  '(float (bigpos 495 467 917 632 470 369 709 646 776 267 677 848 348 672
-                 057 988 235 399 359 593 421 310 024 824 900 120 065 606
-                 328 015 649 156 772 5) -100))
+  math-approx-gamma-const)
 
 (defun math-half-circle (symb)
   (if (eq calc-angle-mode 'rad)
@@ -2066,6 +2171,35 @@ calc-kill calc-kill-region calc-yank))))
     (and (cdr dims)
         (= (car dims) (nth 1 dims)))))
 
+;;; True if MAT is an identity matrix.
+(defun math-identity-matrix-p (mat &optional mul)
+  (if (math-square-matrixp mat)
+      (let ((a (if mul
+                   (nth 1 (nth 1 mat))
+                 1))
+            (n (1- (length mat)))
+            (i 1))
+        (while (and (<= i n)
+                    (math-ident-row-p (nth i mat) i a))
+          (setq i (1+ i)))
+        (if (> i n)
+            a
+          nil))))
+
+(defun math-ident-row-p (row n &optional a)
+  (unless a
+    (setq a 1))
+  (and
+   (not (memq nil (mapcar
+                   (lambda (x) (eq x 0))
+                   (nthcdr (1+ n) row))))
+   (not (memq nil (mapcar
+                   (lambda (x) (eq x 0))
+                   (butlast
+                    (cdr row)
+                    (- (length row) n)))))
+   (eq (elt row n) a)))
+
 ;;; True if A is any scalar data object.  [P x]
 (defun math-objectp (a)    ;  [Public]
   (or (integerp a)
@@ -2119,6 +2253,25 @@ calc-kill calc-kill-region calc-yank))))
       a
     (math-reject-arg a 'constp)))
 
+;;; Some functions for working with error forms.
+(defun math-get-value (x)
+  "Get the mean value of the error form X.
+If X is not an error form, return X."
+  (if (eq (car-safe x) 'sdev)
+      (nth 1 x)
+    x))
+
+(defun math-get-sdev (x &optional one)
+  "Get the standard deviation of the error form X.
+If X is not an error form, return 1."
+  (if (eq (car-safe x) 'sdev)
+      (nth 2 x)
+    (if one 1 0)))
+
+(defun math-contains-sdev-p (ls)
+  "Non-nil if the list LS contains an error form."
+  (let ((ls (if (eq (car-safe ls) 'vec) (cdr ls) ls)))
+    (memq t (mapcar (lambda (x) (eq (car-safe x) 'sdev)) ls))))
 
 ;;; Coerce integer A to be a small integer.  [S I]
 (defun math-fixnum (a)
@@ -2132,7 +2285,7 @@ calc-kill calc-kill-region calc-yank))))
 
 (defun math-fixnum-big (a)
   (if (cdr a)
-      (+ (car a) (* (math-fixnum-big (cdr a)) 1000))
+      (+ (car a) (* (math-fixnum-big (cdr a)) math-bignum-digit-size))
     (car a)))
 
 (defvar math-simplify-only nil)
@@ -2220,15 +2373,15 @@ calc-kill calc-kill-region calc-yank))))
     (and (symbolp (car math-normalize-a))
         (or (eq calc-simplify-mode 'none)
             (and (eq calc-simplify-mode 'num)
-                 (let ((aptr (setq math-normalize-a 
+                 (let ((aptr (setq math-normalize-a
                                     (cons
                                      (car math-normalize-a)
-                                     (mapcar 'math-normalize 
+                                     (mapcar 'math-normalize
                                              (cdr math-normalize-a))))))
                    (while (and aptr (math-constp (car aptr)))
                      (setq aptr (cdr aptr)))
                    aptr)))
-        (cons (car math-normalize-a) 
+        (cons (car math-normalize-a)
                (mapcar 'math-normalize (cdr math-normalize-a))))))
 
 
@@ -2609,8 +2762,8 @@ calc-kill calc-kill-region calc-yank))))
                      (setq mmt-nextval (funcall math-mt-func mmt-expr))
                      (not (equal mmt-expr mmt-nextval)))
            (setq mmt-expr mmt-nextval
-                 math-mt-many (if (> math-mt-many 0) 
-                                   (1- math-mt-many) 
+                 math-mt-many (if (> math-mt-many 0)
+                                   (1- math-mt-many)
                                  (1+ math-mt-many))))
          (if (or (Math-primp mmt-expr)
                  (<= math-mt-many 0))
@@ -2783,7 +2936,7 @@ calc-kill calc-kill-region calc-yank))))
 
    ;; Integer+fraction with explicit radix
    ((string-match "^\\([0-9]+\\)\\(#\\|\\^\\^\\)\\([0-9a-zA-Z]*\\)[:/]\\([0-9a-zA-Z]*\\)[:/]\\([0-9a-zA-Z]\\)$" s)
-    (let ((radix (string-to-int (math-match-substring s 1)))
+    (let ((radix (string-to-number (math-match-substring s 1)))
          (int (math-match-substring s 3))
          (num (math-match-substring s 4))
          (den (math-match-substring s 5)))
@@ -2797,7 +2950,7 @@ calc-kill calc-kill-region calc-yank))))
 
    ;; Fraction with explicit radix
    ((string-match "^\\([0-9]+\\)\\(#\\|\\^\\^\\)\\([0-9a-zA-Z]*\\)[:/]\\([0-9a-zA-Z]*\\)$" s)
-    (let ((radix (string-to-int (math-match-substring s 1)))
+    (let ((radix (string-to-number (math-match-substring s 1)))
          (num (math-match-substring s 3))
          (den (math-match-substring s 4)))
       (let ((num (if (> (length num) 0) (math-read-radix num radix) 1))
@@ -2807,7 +2960,7 @@ calc-kill calc-kill-region calc-yank))))
    ;; Float with explicit radix and exponent
    ((or (string-match "^0*\\(\\([2-9]\\|1[0-4]\\)\\(#\\|\\^\\^\\)[0-9a-dA-D.]+\\)[eE]\\([-+]?[0-9]+\\)$" s)
        (string-match "^\\(\\([0-9]+\\)\\(#\\|\\^\\^\\)[0-9a-zA-Z.]+\\) *\\* *\\2\\.? *\\^ *\\([-+]?[0-9]+\\)$" s))
-    (let ((radix (string-to-int (math-match-substring s 2)))
+    (let ((radix (string-to-number (math-match-substring s 2)))
          (mant (math-match-substring s 1))
          (exp (math-match-substring s 4)))
       (let ((mant (math-read-number mant))
@@ -2817,7 +2970,7 @@ calc-kill calc-kill-region calc-yank))))
 
    ;; Float with explicit radix, no exponent
    ((string-match "^\\([0-9]+\\)\\(#\\|\\^\\^\\)\\([0-9a-zA-Z]*\\)\\.\\([0-9a-zA-Z]*\\)$" s)
-    (let ((radix (string-to-int (math-match-substring s 1)))
+    (let ((radix (string-to-number (math-match-substring s 1)))
          (int (math-match-substring s 3))
          (fracs (math-match-substring s 4)))
       (let ((int (if (> (length int) 0) (math-read-radix int radix) 0))
@@ -2829,7 +2982,7 @@ calc-kill calc-kill-region calc-yank))))
    ;; Integer with explicit radix
    ((string-match "^\\([0-9]+\\)\\(#\\|\\^\\^\\)\\([0-9a-zA-Z]+\\)$" s)
     (math-read-radix (math-match-substring s 3)
-                    (string-to-int (math-match-substring s 1))))
+                    (string-to-number (math-match-substring s 1))))
 
    ;; C language hexadecimal notation
    ((and (eq calc-language 'c)
@@ -2870,73 +3023,6 @@ calc-kill calc-kill-region calc-yank))))
 
 (defvar math-expr-data)
 
-(defvar math-read-replacement-list
-  '(;; Misc symbols
-    ("±" "+/-")  ; plus or minus
-    ("×" "*")    ; multiplication sign
-    ("÷" ":")    ; division sign
-    ("−" "-")    ; subtraction sign
-    ("∕" "/")    ; division sign
-    ("∗" "*")    ; asterisk multiplication
-    ("∞" "inf")  ; infinity symbol
-    ("≤" "<=")
-    ("≥" ">=")
-    ("≦" "<=")
-    ("≧" ">=")
-    ;; fractions
-    ("¼" "(1:4)") ; 1/4
-    ("½" "(1:2)") ; 1/2
-    ("¾" "(3:4)") ; 3/4
-    ("⅓" "(1:3)") ; 1/3
-    ("⅔" "(2:3)") ; 2/3
-    ("⅕" "(1:5)") ; 1/5
-    ("⅖" "(2:5)") ; 2/5
-    ("⅗" "(3:5)") ; 3/5
-    ("⅘" "(4:5)") ; 4/5
-    ("⅙" "(1:6)") ; 1/6
-    ("⅚" "(5:6)") ; 5/6
-    ("⅛" "(1:8)") ; 1/8
-    ("⅜" "(3:8)") ; 3/8
-    ("⅝" "(5:8)") ; 5/8
-    ("⅞" "(7:8)") ; 7/8
-    ("⅟" "1:")    ; 1/...
-    ;; superscripts
-    ("⁰" "0")  ; 0
-    ("¹" "1")  ; 1
-    ("²" "2")  ; 2
-    ("³" "3")  ; 3
-    ("⁴" "4")  ; 4
-    ("⁵" "5")  ; 5
-    ("⁶" "6")  ; 6
-    ("⁷" "7")  ; 7
-    ("⁸" "8")  ; 8
-    ("⁹" "9")  ; 9
-    ("⁺" "+")  ; +
-    ("⁻" "-")  ; -
-    ("⁽" "(")  ; (
-    ("⁾" ")")  ; )
-    ("ⁿ" "n")  ; n
-    ("ⁱ" "i")) ; i
-  "A list whose elements (old new) indicate replacements to make
-in Calc algebraic input.")
-
-(defvar math-read-superscripts
-  "⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁽⁾ⁿⁱ" ; 0123456789+-()ni
-  "A string consisting of the superscripts allowed by Calc.")
-
-(defun math-read-preprocess-string (str)
-  "Replace some substrings of STR by Calc equivalents."
-  (setq str
-        (replace-regexp-in-string (concat "[" math-read-superscripts "]+")
-                                  "^(\\&)" str))
-  (let ((rep-list math-read-replacement-list))
-    (while rep-list
-      (setq str
-            (replace-regexp-in-string (nth 0 (car rep-list))
-                                      (nth 1 (car rep-list)) str))
-      (setq rep-list (cdr rep-list))))
-  str)
-
 (defun math-read-expr (math-exp-str)
   (let ((math-exp-pos 0)
        (math-exp-old-pos 0)
@@ -2957,7 +3043,7 @@ in Calc algebraic input.")
 
 (defun math-read-plain-expr (exp-str &optional error-check)
   (let* ((calc-language nil)
-        (math-expr-opers math-standard-opers)
+        (math-expr-opers (math-standard-ops))
         (val (math-read-expr exp-str)))
     (and error-check
         (eq (car-safe val) 'error)
@@ -2987,13 +3073,13 @@ in Calc algebraic input.")
        (setq str (concat (substring str 0 (match-beginning 0))
                         (substring str (match-end 0)))))
   (if (string-match "\\\\[^ \n|]" str)
-      (if (eq calc-language 'tex)
+      (if (eq calc-language 'latex)
          (math-read-expr str)
-       (let ((calc-language 'tex)
+       (let ((calc-language 'latex)
              (calc-language-option nil)
-             (math-expr-opers (get 'tex 'math-oper-table))
-             (math-expr-function-mapping (get 'tex 'math-function-table))
-             (math-expr-variable-mapping (get 'tex 'math-variable-table)))
+             (math-expr-opers (get 'latex 'math-oper-table))
+             (math-expr-function-mapping (get 'latex 'math-function-table))
+             (math-expr-variable-mapping (get 'latex 'math-variable-table)))
          (math-read-expr str)))
     (let ((math-read-big-lines nil)
          (pos 0)
@@ -3002,10 +3088,10 @@ in Calc algebraic input.")
          math-read-big-baseline math-read-big-h2
          new-pos p)
       (while (setq new-pos (string-match "\n" str pos))
-       (setq math-read-big-lines 
+       (setq math-read-big-lines
               (cons (substring str pos new-pos) math-read-big-lines)
              pos (1+ new-pos)))
-      (setq math-read-big-lines 
+      (setq math-read-big-lines
             (nreverse (cons (substring str pos) math-read-big-lines))
            p math-read-big-lines)
       (while p
@@ -3113,7 +3199,7 @@ in Calc algebraic input.")
     (concat (substring (symbol-name (car a)) 9)
            "(" (math-vector-to-string (nth 1 a) t) ")"))
    (t
-    (let ((op (math-assq2 (car a) math-standard-opers)))
+    (let ((op (math-assq2 (car a) (math-standard-ops))))
       (cond ((and op (= (length a) 3))
             (if (> prec (min (nth 2 op) (nth 3 op)))
                 (concat "(" (math-format-flat-expr a 0) ")")