summaryrefslogtreecommitdiff
path: root/lisp/calc
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/calc')
-rw-r--r--lisp/calc/README11
-rw-r--r--lisp/calc/calc-aent.el293
-rw-r--r--lisp/calc/calc-bin.el58
-rw-r--r--lisp/calc/calc-comb.el74
-rw-r--r--lisp/calc/calc-embed.el6
-rw-r--r--lisp/calc/calc-ext.el170
-rw-r--r--lisp/calc/calc-forms.el169
-rw-r--r--lisp/calc/calc-funcs.el228
-rw-r--r--lisp/calc/calc-graph.el74
-rw-r--r--lisp/calc/calc-help.el98
-rw-r--r--lisp/calc/calc-lang.el1191
-rw-r--r--lisp/calc/calc-macs.el10
-rw-r--r--lisp/calc/calc-math.el133
-rw-r--r--lisp/calc/calc-menu.el1429
-rw-r--r--lisp/calc/calc-misc.el37
-rw-r--r--lisp/calc/calc-mode.el6
-rw-r--r--lisp/calc/calc-nlfit.el823
-rw-r--r--lisp/calc/calc-poly.el6
-rw-r--r--lisp/calc/calc-prog.el7
-rw-r--r--lisp/calc/calc-store.el32
-rw-r--r--lisp/calc/calc-stuff.el2
-rw-r--r--lisp/calc/calc-units.el349
-rw-r--r--lisp/calc/calc-vec.el4
-rw-r--r--lisp/calc/calc-yank.el2
-rw-r--r--lisp/calc/calc.el636
-rw-r--r--lisp/calc/calcalg2.el4
-rw-r--r--lisp/calc/calcalg3.el230
-rw-r--r--lisp/calc/calccomp.el304
28 files changed, 5170 insertions, 1216 deletions
diff --git a/lisp/calc/README b/lisp/calc/README
index 5d250387a00..3366a0b6b3c 100644
--- a/lisp/calc/README
+++ b/lisp/calc/README
@@ -72,6 +72,17 @@ opinions.
Summary of changes to "Calc"
------- -- ------- -- ----
+* Added support for Yacas, Maxima and Giac languages.
+
+* Added a menu.
+
+* Added logistic non-linear curves to curve-fitting.
+
+* Added option of plotting data points and curve when curve-fitting.
+
+* Made unit conversions exact when possible.
+
+* Lower the precedence of negation.
Version 2.1:
diff --git a/lisp/calc/calc-aent.el b/lisp/calc/calc-aent.el
index af57453816a..fefe99c987b 100644
--- a/lisp/calc/calc-aent.el
+++ b/lisp/calc/calc-aent.el
@@ -32,6 +32,25 @@
(require 'calc)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function calc-refresh-evaltos "calc-ext" (&optional which-var))
+(declare-function calc-execute-kbd-macro "calc-prog" (mac arg &rest prefix))
+(declare-function math-is-true "calc-ext" (expr))
+(declare-function calc-explain-why "calc-stuff" (why &optional more))
+(declare-function calc-alg-edit "calc-yank" (str))
+(declare-function math-composite-inequalities "calc-prog" (x op))
+(declare-function math-flatten-lands "calc-rewr" (expr))
+(declare-function math-multi-subst "calc-map" (expr olds news))
+(declare-function calcFunc-vmatches "calc-rewr" (expr pat))
+(declare-function math-simplify "calc-alg" (top-expr))
+(declare-function math-known-matrixp "calc-arith" (a))
+(declare-function math-parse-fortran-subscr "calc-lang" (sym args))
+(declare-function math-to-radians-2 "calc-math" (a))
+(declare-function math-read-string "calc-ext" ())
+(declare-function math-read-brackets "calc-vec" (space-sep math-rb-close))
+(declare-function math-read-angle-brackets "calc-forms" ())
+(declare-function math-to-percentsigns "calccomp" (x))
+
(defvar calc-quick-calc-history nil
"The history list for quick-calc.")
@@ -74,6 +93,9 @@
", "
(let ((calc-number-radix 8))
(math-format-value (car alg-exp) 1000))
+ ", "
+ (let ((calc-number-radix 2))
+ (math-format-value (car alg-exp) 1000))
(if (and (integerp (car alg-exp))
(> (car alg-exp) 0)
(< (car alg-exp) 127))
@@ -100,7 +122,7 @@
(cond
((and (consp str) (not (symbolp (car str))))
(let ((calc-language nil)
- (math-expr-opers math-standard-opers)
+ (math-expr-opers (math-standard-ops))
(calc-internal-prec 12)
(calc-word-size 32)
(calc-symbolic-mode nil)
@@ -254,7 +276,7 @@ The value t means abort and give an error message.")
(interactive "P")
(calc-wrapper
(let ((calc-language (if prefix nil calc-language))
- (math-expr-opers (if prefix math-standard-opers math-expr-opers)))
+ (math-expr-opers (if prefix (math-standard-ops) (math-expr-ops))))
(calc-alg-entry (and auto (char-to-string last-command-char))))))
(defvar calc-alg-entry-history nil
@@ -573,10 +595,14 @@ in Calc algebraic input.")
(math-exp-keep-spaces nil)
math-exp-token math-expr-data)
(setq math-exp-str (math-read-preprocess-string math-exp-str))
+ (if (memq calc-language calc-lang-allow-percentsigns)
+ (setq math-exp-str (math-remove-percentsigns math-exp-str)))
(if calc-language-input-filter
(setq math-exp-str (funcall calc-language-input-filter math-exp-str)))
- (while (setq math-exp-token (string-match "\\.\\.\\([^.]\\|.[^.]\\)" math-exp-str))
- (setq math-exp-str (concat (substring math-exp-str 0 math-exp-token) "\\dots"
+ (while (setq math-exp-token
+ (string-match "\\.\\.\\([^.]\\|.[^.]\\)" math-exp-str))
+ (setq math-exp-str
+ (concat (substring math-exp-str 0 math-exp-token) "\\dots"
(substring math-exp-str (+ math-exp-token 2)))))
(math-build-parse-table)
(math-read-token)
@@ -600,6 +626,7 @@ in Calc algebraic input.")
(defvar calc-user-parse-table nil)
(defvar calc-last-main-parse-table nil)
+(defvar calc-last-user-lang-parse-table nil)
(defvar calc-last-lang-parse-table nil)
(defvar calc-user-tokens nil)
(defvar calc-user-token-chars nil)
@@ -609,10 +636,12 @@ in Calc algebraic input.")
(defun math-build-parse-table ()
(let ((mtab (cdr (assq nil calc-user-parse-tables)))
- (ltab (cdr (assq calc-language calc-user-parse-tables))))
+ (ltab (cdr (assq calc-language calc-user-parse-tables)))
+ (lltab (get calc-language 'math-parse-table)))
(or (and (eq mtab calc-last-main-parse-table)
- (eq ltab calc-last-lang-parse-table))
- (let ((p (append mtab ltab))
+ (eq ltab calc-last-user-lang-parse-table)
+ (eq lltab calc-last-lang-parse-table))
+ (let ((p (append mtab ltab lltab))
(math-toks nil))
(setq calc-user-parse-table p)
(setq calc-user-token-chars nil)
@@ -626,7 +655,8 @@ in Calc algebraic input.")
(length y)))))
"\\|")
calc-last-main-parse-table mtab
- calc-last-lang-parse-table ltab)))))
+ calc-last-user-lang-parse-table ltab
+ calc-last-lang-parse-table lltab)))))
(defun math-find-user-tokens (p)
(while p
@@ -657,7 +687,8 @@ in Calc algebraic input.")
(setq math-exp-old-pos math-exp-pos
math-exp-token 'end
math-expr-data "\000")
- (let ((ch (aref math-exp-str math-exp-pos)))
+ (let (adfn
+ (ch (aref math-exp-str math-exp-pos)))
(setq math-exp-old-pos math-exp-pos)
(cond ((memq ch '(32 10 9))
(setq math-exp-pos (1+ math-exp-pos))
@@ -667,37 +698,29 @@ in Calc algebraic input.")
(math-read-token)))
((and (memq ch calc-user-token-chars)
(let ((case-fold-search nil))
- (eq (string-match calc-user-tokens math-exp-str math-exp-pos)
+ (eq (string-match
+ calc-user-tokens math-exp-str math-exp-pos)
math-exp-pos)))
(setq math-exp-token 'punc
math-expr-data (math-match-substring math-exp-str 0)
math-exp-pos (match-end 0)))
((or (and (>= ch ?a) (<= ch ?z))
(and (>= ch ?A) (<= ch ?Z)))
- (string-match (if (memq calc-language '(c fortran pascal maple))
- "[a-zA-Z0-9_#]*"
- "[a-zA-Z0-9'#]*")
- math-exp-str math-exp-pos)
+ (string-match
+ (cond
+ ((and (memq calc-language calc-lang-allow-underscores)
+ (memq calc-language calc-lang-allow-percentsigns))
+ "[a-zA-Z0-9_'#]*")
+ ((memq calc-language calc-lang-allow-underscores)
+ "[a-zA-Z0-9_#]*")
+ (t "[a-zA-Z0-9'#]*"))
+ math-exp-str math-exp-pos)
(setq math-exp-token 'symbol
math-exp-pos (match-end 0)
math-expr-data (math-restore-dashes
(math-match-substring math-exp-str 0)))
- (if (eq calc-language 'eqn)
- (let ((code (assoc math-expr-data math-eqn-ignore-words)))
- (cond ((null code))
- ((null (cdr code))
- (math-read-token))
- ((consp (nth 1 code))
- (math-read-token)
- (if (assoc math-expr-data (cdr code))
- (setq math-expr-data (format "%s %s"
- (car code) math-expr-data))))
- ((eq (nth 1 code) 'punc)
- (setq math-exp-token 'punc
- math-expr-data (nth 2 code)))
- (t
- (math-read-token)
- (math-read-token))))))
+ (if (setq adfn (get calc-language 'math-lang-adjust-words))
+ (funcall adfn)))
((or (and (>= ch ?0) (<= ch ?9))
(and (eq ch '?\.)
(eq (string-match "\\.[0-9]" math-exp-str math-exp-pos)
@@ -706,35 +729,31 @@ in Calc algebraic input.")
(eq (string-match "_\\.?[0-9]" math-exp-str math-exp-pos)
math-exp-pos)
(or (eq math-exp-pos 0)
- (and (memq calc-language '(nil flat big unform
- tex latex eqn))
+ (and (not (memq calc-language
+ calc-lang-allow-underscores))
(eq (string-match "[^])}\"a-zA-Z0-9'$]_"
math-exp-str (1- math-exp-pos))
(1- math-exp-pos))))))
- (or (and (eq calc-language 'c)
+ (or (and (memq calc-language calc-lang-c-type-hex)
(string-match "0[xX][0-9a-fA-F]+" math-exp-str math-exp-pos))
(string-match "_?\\([0-9]+.?0*@ *\\)?\\([0-9]+.?0*' *\\)?\\(0*\\([2-9]\\|1[0-4]\\)\\(#\\|\\^\\^\\)[0-9a-dA-D.]+[eE][-+_]?[0-9]+\\|0*\\([2-9]\\|[0-2][0-9]\\|3[0-6]\\)\\(#\\|\\^\\^\\)[0-9a-zA-Z:.]+\\|[0-9]+:[0-9:]+\\|[0-9.]+\\([eE][-+_]?[0-9]+\\)?\"?\\)?"
math-exp-str math-exp-pos))
(setq math-exp-token 'number
math-expr-data (math-match-substring math-exp-str 0)
math-exp-pos (match-end 0)))
+ ((and (setq adfn
+ (assq ch (get calc-language 'math-lang-read-symbol)))
+ (eval (nth 1 adfn)))
+ (eval (nth 2 adfn)))
((eq ch ?\$)
- (if (and (eq calc-language 'pascal)
- (eq (string-match
- "\\(\\$[0-9a-fA-F]+\\)\\($\\|[^0-9a-zA-Z]\\)"
- math-exp-str math-exp-pos)
- math-exp-pos))
- (setq math-exp-token 'number
- math-expr-data (math-match-substring math-exp-str 1)
- math-exp-pos (match-end 1))
- (if (eq (string-match "\\$\\([1-9][0-9]*\\)" math-exp-str math-exp-pos)
- math-exp-pos)
- (setq math-expr-data (- (string-to-number (math-match-substring
- math-exp-str 1))))
- (string-match "\\$+" math-exp-str math-exp-pos)
- (setq math-expr-data (- (match-end 0) (match-beginning 0))))
- (setq math-exp-token 'dollar
- math-exp-pos (match-end 0))))
+ (if (eq (string-match "\\$\\([1-9][0-9]*\\)" math-exp-str math-exp-pos)
+ math-exp-pos)
+ (setq math-expr-data (- (string-to-number (math-match-substring
+ math-exp-str 1))))
+ (string-match "\\$+" math-exp-str math-exp-pos)
+ (setq math-expr-data (- (match-end 0) (match-beginning 0))))
+ (setq math-exp-token 'dollar
+ math-exp-pos (match-end 0)))
((eq ch ?\#)
(if (eq (string-match "#\\([1-9][0-9]*\\)" math-exp-str math-exp-pos)
math-exp-pos)
@@ -753,120 +772,18 @@ in Calc algebraic input.")
((and (eq ch ?\")
(string-match "\\(\"\\([^\"\\]\\|\\\\.\\)*\\)\\(\"\\|\\'\\)"
math-exp-str math-exp-pos))
- (if (eq calc-language 'eqn)
- (progn
- (setq math-exp-str (copy-sequence math-exp-str))
- (aset math-exp-str (match-beginning 1) ?\{)
- (if (< (match-end 1) (length math-exp-str))
- (aset math-exp-str (match-end 1) ?\}))
- (math-read-token))
- (setq math-exp-token 'string
- math-expr-data (math-match-substring math-exp-str 1)
- math-exp-pos (match-end 0))))
- ((and (= ch ?\\) (eq calc-language 'tex)
- (< math-exp-pos (1- (length math-exp-str))))
- (or (string-match "\\\\hbox *{\\([a-zA-Z0-9]+\\)}"
- math-exp-str math-exp-pos)
- (string-match "\\(\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)\\)"
- math-exp-str math-exp-pos))
- (setq math-exp-token 'symbol
- math-exp-pos (match-end 0)
- math-expr-data (math-restore-dashes
- (math-match-substring math-exp-str 1)))
- (let ((code (assoc math-expr-data math-latex-ignore-words)))
- (cond ((null code))
- ((null (cdr code))
- (math-read-token))
- ((eq (nth 1 code) 'punc)
- (setq math-exp-token 'punc
- math-expr-data (nth 2 code)))
- ((and (eq (nth 1 code) 'mat)
- (string-match " *{" math-exp-str math-exp-pos))
- (setq math-exp-pos (match-end 0)
- math-exp-token 'punc
- math-expr-data "[")
- (let ((right (string-match "}" math-exp-str math-exp-pos)))
- (and right
- (setq math-exp-str (copy-sequence math-exp-str))
- (aset math-exp-str right ?\])))))))
- ((and (= ch ?\\) (eq calc-language 'latex)
- (< math-exp-pos (1- (length math-exp-str))))
- (or (string-match "\\\\hbox *{\\([a-zA-Z0-9]+\\)}"
- math-exp-str math-exp-pos)
- (string-match "\\\\text *{\\([a-zA-Z0-9]+\\)}"
- math-exp-str math-exp-pos)
- (string-match "\\(\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)\\)"
- math-exp-str math-exp-pos))
- (setq math-exp-token 'symbol
- math-exp-pos (match-end 0)
- math-expr-data (math-restore-dashes
- (math-match-substring math-exp-str 1)))
- (let ((code (assoc math-expr-data math-tex-ignore-words))
- envname)
- (cond ((null code))
- ((null (cdr code))
- (math-read-token))
- ((eq (nth 1 code) 'punc)
- (setq math-exp-token 'punc
- math-expr-data (nth 2 code)))
- ((and (eq (nth 1 code) 'begenv)
- (string-match " *{\\([^}]*\\)}" math-exp-str math-exp-pos))
- (setq math-exp-pos (match-end 0)
- envname (match-string 1 math-exp-str)
- math-exp-token 'punc
- math-expr-data "[")
- (cond ((or (string= envname "matrix")
- (string= envname "bmatrix")
- (string= envname "smallmatrix")
- (string= envname "pmatrix"))
- (if (string-match (concat "\\\\end{" envname "}")
- math-exp-str math-exp-pos)
- (setq math-exp-str
- (replace-match "]" t t math-exp-str))
- (error "%s" (concat "No closing \\end{" envname "}"))))))
- ((and (eq (nth 1 code) 'mat)
- (string-match " *{" math-exp-str math-exp-pos))
- (setq math-exp-pos (match-end 0)
- math-exp-token 'punc
- math-expr-data "[")
- (let ((right (string-match "}" math-exp-str math-exp-pos)))
- (and right
- (setq math-exp-str (copy-sequence math-exp-str))
- (aset math-exp-str right ?\])))))))
- ((and (= ch ?\.) (eq calc-language 'fortran)
- (eq (string-match "\\.[a-zA-Z][a-zA-Z][a-zA-Z]?\\."
- math-exp-str math-exp-pos) math-exp-pos))
- (setq math-exp-token 'punc
- math-expr-data (upcase (math-match-substring math-exp-str 0))
- math-exp-pos (match-end 0)))
- ((and (eq calc-language 'math)
- (eq (string-match "\\[\\[\\|->\\|:>" math-exp-str math-exp-pos)
- math-exp-pos))
- (setq math-exp-token 'punc
- math-expr-data (math-match-substring math-exp-str 0)
- math-exp-pos (match-end 0)))
- ((and (eq calc-language 'eqn)
- (eq (string-match "->\\|<-\\|+-\\|\\\\dots\\|~\\|\\^"
- math-exp-str math-exp-pos)
- math-exp-pos))
- (setq math-exp-token 'punc
- math-expr-data (math-match-substring math-exp-str 0)
- math-exp-pos (match-end 0))
- (and (eq (string-match "\\\\dots\\." math-exp-str math-exp-pos)
- math-exp-pos)
- (setq math-exp-pos (match-end 0)))
- (if (memq (aref math-expr-data 0) '(?~ ?^))
- (math-read-token)))
+ (setq math-exp-token 'string
+ math-expr-data (math-match-substring math-exp-str 1)
+ math-exp-pos (match-end 0)))
+ ((and (setq adfn (get calc-language 'math-lang-read))
+ (eval (nth 0 adfn))
+ (eval (nth 1 adfn))))
((eq (string-match "%%.*$" math-exp-str math-exp-pos) math-exp-pos)
(setq math-exp-pos (match-end 0))
(math-read-token))
(t
- (if (and (eq ch ?\{) (memq calc-language '(tex latex eqn)))
- (setq ch ?\())
- (if (and (eq ch ?\}) (memq calc-language '(tex latex eqn)))
- (setq ch ?\)))
- (if (and (eq ch ?\&) (memq calc-language '(tex latex)))
- (setq ch ?\,))
+ (if (setq adfn (assq ch (get calc-language 'math-punc-table)))
+ (setq ch (cdr adfn)))
(setq math-exp-token 'punc
math-expr-data (char-to-string ch)
math-exp-pos (1+ math-exp-pos)))))))
@@ -876,7 +793,10 @@ in Calc algebraic input.")
calcFunc-eq calcFunc-neq))
(defun math-read-expr-level (exp-prec &optional exp-term)
- (let* ((x (math-read-factor)) (first t) op op2)
+ (let* ((math-expr-opers (math-expr-ops))
+ (x (math-read-factor))
+ (first t)
+ op op2)
(while (and (or (and calc-user-parse-table
(setq op (calc-check-user-syntax x exp-prec))
(setq x op
@@ -896,7 +816,9 @@ in Calc algebraic input.")
(memq math-exp-token '(symbol number dollar hash))
(equal math-expr-data "(")
(and (equal math-expr-data "[")
- (not (eq calc-language 'math))
+ (not (equal
+ (get calc-language
+ 'math-function-open) "["))
(not (and math-exp-keep-spaces
(eq (car-safe x) 'vec)))))
(or (not (setq op (assoc math-expr-data math-expr-opers)))
@@ -1097,12 +1019,39 @@ in Calc algebraic input.")
(concat (math-match-substring x 1) "#" (math-match-substring x 2)))
x))
+(defun math-remove-percentsigns (x)
+ (if (string-match "\\`\\(.*\\)%\\(.*\\)\\'" x)
+ (math-remove-percentsigns
+ (concat (math-match-substring x 1) "o'o" (math-match-substring x 2)))
+ x))
+
(defun math-restore-dashes (x)
(if (string-match "\\`\\(.*\\)[#_]\\(.*\\)\\'" x)
(math-restore-dashes
(concat (math-match-substring x 1) "-" (math-match-substring x 2)))
x))
+(defun math-restore-placeholders (x)
+ "Replace placeholders by the proper characters in the symbol x.
+This includes `#' for `_' and `'' for `%'.
+If the current Calc language does not use placeholders, return nil."
+ (if (or (memq calc-language calc-lang-allow-underscores)
+ (memq calc-language calc-lang-allow-percentsigns))
+ (let ((sx (symbol-name x)))
+ (when (memq calc-language calc-lang-allow-percentsigns)
+ (require 'calccomp)
+ (setq sx (math-to-percentsigns sx)))
+ (if (memq calc-language calc-lang-allow-underscores)
+ (setq sx (math-string-restore-underscores sx)))
+ (intern-soft sx))))
+
+(defun math-string-restore-underscores (x)
+ "Replace pound signs by underscores in the string x."
+ (if (string-match "\\`\\(.*\\)#\\(.*\\)\\'" x)
+ (math-string-restore-underscores
+ (concat (math-match-substring x 1) "_" (math-match-substring x 2)))
+ x))
+
(defun math-read-if (cond op)
(let ((then (math-read-expr-level 0)))
(or (equal math-expr-data ":")
@@ -1121,7 +1070,8 @@ in Calc algebraic input.")
(assoc math-expr-data '(("(") ("[") ("{"))))))
(defun math-read-factor ()
- (let (op)
+ (let ((math-expr-opers (math-expr-ops))
+ op)
(cond ((eq math-exp-token 'number)
(let ((num (math-read-number math-expr-data)))
(if (not num)
@@ -1171,7 +1121,9 @@ in Calc algebraic input.")
(eq math-exp-token 'end)))
(throw 'syntax "Expected `)'"))
(math-read-token)
- (if (and (eq calc-language 'fortran) args
+ (if (and (memq calc-language
+ calc-lang-parens-are-subscripts)
+ args
(require 'calc-ext)
(let ((calc-matrix-mode 'scalar))
(math-known-matrixp
@@ -1201,7 +1153,10 @@ in Calc algebraic input.")
sym
(intern (concat "var-"
(symbol-name sym)))))))
- (let ((v (assq (nth 1 val) math-expr-variable-mapping)))
+ (let ((v (or
+ (assq (nth 1 val) math-expr-variable-mapping)
+ (assq (math-restore-placeholders (nth 1 val))
+ math-expr-variable-mapping))))
(and v (setq val (if (consp (cdr v))
(funcall (car (cdr v)) v val)
(list 'var
@@ -1209,11 +1164,15 @@ in Calc algebraic input.")
(substring (symbol-name (cdr v))
4))
(cdr v))))))
- (while (and (memq calc-language '(c pascal maple))
+ (while (and (memq calc-language
+ calc-lang-brackets-are-subscripts)
(equal math-expr-data "["))
(math-read-token)
- (setq val (append (list 'calcFunc-subscr val)
- (math-read-expr-list)))
+ (let ((el (math-read-expr-list)))
+ (while el
+ (setq val (append (list 'calcFunc-subscr val)
+ (list (car el))))
+ (setq el (cdr el))))
(if (equal math-expr-data "]")
(math-read-token)
(throw 'syntax "Expected ']'")))
diff --git a/lisp/calc/calc-bin.el b/lisp/calc/calc-bin.el
index bf40ca6ef47..537c0e1be45 100644
--- a/lisp/calc/calc-bin.el
+++ b/lisp/calc/calc-bin.el
@@ -32,6 +32,17 @@
(require 'calc-ext)
(require 'calc-macs)
+;;; Some useful numbers
+(defconst math-bignum-logb-digit-size
+ (logb math-bignum-digit-size)
+ "The logb of the size of a bignum digit.
+This is the largest value of B such that 2^B is less than
+the size of a Calc bignum digit.")
+
+(defconst math-bignum-digit-power-of-two
+ (expt 2 (logb math-bignum-digit-size))
+ "The largest power of 2 less than the size of a Calc bignum digit.")
+
;;; b-prefix binary commands.
(defun calc-and (n)
@@ -297,11 +308,11 @@
(defun math-and-bignum (a b) ; [l l l]
(and a b
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-and-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logand (cdr qa) (cdr qb))))))
(defun calcFunc-or (a b &optional w) ; [I I I] [Public]
@@ -324,11 +335,11 @@
(defun math-or-bignum (a b) ; [l l l]
(and (or a b)
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-or-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logior (cdr qa) (cdr qb))))))
(defun calcFunc-xor (a b &optional w) ; [I I I] [Public]
@@ -351,11 +362,11 @@
(defun math-xor-bignum (a b) ; [l l l]
(and (or a b)
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-xor-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logxor (cdr qa) (cdr qb))))))
(defun calcFunc-diff (a b &optional w) ; [I I I] [Public]
@@ -378,11 +389,11 @@
(defun math-diff-bignum (a b) ; [l l l]
(and a
- (let ((qa (math-div-bignum-digit a 512))
- (qb (math-div-bignum-digit b 512)))
+ (let ((qa (math-div-bignum-digit a math-bignum-digit-power-of-two))
+ (qb (math-div-bignum-digit b math-bignum-digit-power-of-two)))
(math-mul-bignum-digit (math-diff-bignum (math-norm-bignum (car qa))
(math-norm-bignum (car qb)))
- 512
+ math-bignum-digit-power-of-two
(logand (cdr qa) (lognot (cdr qb)))))))
(defun calcFunc-not (a &optional w) ; [I I] [Public]
@@ -402,14 +413,15 @@
w))))))
(defun math-not-bignum (a w) ; [l l]
- (let ((q (math-div-bignum-digit a 512)))
- (if (<= w 9)
+ (let ((q (math-div-bignum-digit a math-bignum-digit-power-of-two)))
+ (if (<= w math-bignum-logb-digit-size)
(list (logand (lognot (cdr q))
(1- (lsh 1 w))))
(math-mul-bignum-digit (math-not-bignum (math-norm-bignum (car q))
- (- w 9))
- 512
- (logxor (cdr q) 511)))))
+ (- w math-bignum-logb-digit-size))
+ math-bignum-digit-power-of-two
+ (logxor (cdr q)
+ (1- math-bignum-digit-power-of-two))))))
(defun calcFunc-lsh (a &optional n w) ; [I I] [Public]
(setq a (math-trunc a)
@@ -510,8 +522,8 @@
(math-sub a (math-power-of-2 (- w)))))
((Math-negp a)
(math-normalize (cons 'bigpos (math-binary-arg a w))))
- ((and (integerp a) (< a 1000000))
- (if (>= w 20)
+ ((and (integerp a) (< a math-small-integer-size))
+ (if (> w (logb math-small-integer-size))
a
(logand a (1- (lsh 1 w)))))
(t
@@ -523,13 +535,13 @@
(defalias 'calcFunc-clip 'math-clip)
(defun math-clip-bignum (a w) ; [l l]
- (let ((q (math-div-bignum-digit a 512)))
- (if (<= w 9)
+ (let ((q (math-div-bignum-digit a math-bignum-digit-power-of-two)))
+ (if (<= w math-bignum-logb-digit-size)
(list (logand (cdr q)
(1- (lsh 1 w))))
(math-mul-bignum-digit (math-clip-bignum (math-norm-bignum (car q))
- (- w 9))
- 512
+ (- w math-bignum-logb-digit-size))
+ math-bignum-digit-power-of-two
(cdr q)))))
(defvar math-max-digits-cache nil)
diff --git a/lisp/calc/calc-comb.el b/lisp/calc/calc-comb.el
index 9aefc7405ce..33880f38dd7 100644
--- a/lisp/calc/calc-comb.el
+++ b/lisp/calc/calc-comb.el
@@ -294,6 +294,18 @@
;;; Factorial and related functions.
+(defconst math-small-factorial-table
+ (vector 1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800
+ (math-read-number-simple "479001600")
+ (math-read-number-simple "6227020800")
+ (math-read-number-simple "87178291200")
+ (math-read-number-simple "1307674368000")
+ (math-read-number-simple "20922789888000")
+ (math-read-number-simple "355687428096000")
+ (math-read-number-simple "6402373705728000")
+ (math-read-number-simple "121645100408832000")
+ (math-read-number-simple "2432902008176640000")))
+
(defun calcFunc-fact (n) ; [I I] [F F] [Public]
(let (temp)
(cond ((Math-integer-negp n)
@@ -302,14 +314,7 @@
(math-reject-arg n 'range)))
((integerp n)
(if (<= n 20)
- (aref '[1 1 2 6 24 120 720 5040 40320 362880
- (bigpos 800 628 3) (bigpos 800 916 39)
- (bigpos 600 1 479) (bigpos 800 20 227 6)
- (bigpos 200 291 178 87) (bigpos 0 368 674 307 1)
- (bigpos 0 888 789 922 20) (bigpos 0 96 428 687 355)
- (bigpos 0 728 705 373 402 6)
- (bigpos 0 832 408 100 645 121)
- (bigpos 0 640 176 8 902 432 2)] n)
+ (aref math-small-factorial-table n)
(math-factorial-iter (1- n) 2 1)))
((and (math-messy-integerp n)
(Math-lessp n 100))
@@ -551,9 +556,9 @@
nil
(if (Math-integerp var-RandSeed)
(let* ((seed (math-sub 161803 var-RandSeed))
- (mj (1+ (math-mod seed '(bigpos 0 0 1))))
- (mk (1+ (math-mod (math-quotient seed '(bigpos 0 0 1))
- '(bigpos 0 0 1))))
+ (mj (1+ (math-mod seed 1000000)))
+ (mk (1+ (math-mod (math-quotient seed 1000000)
+ 1000000)))
(i 0))
(setq math-random-table (cons 'vec (make-list 55 mj)))
(while (<= (setq i (1+ i)) 54)
@@ -601,7 +606,8 @@
;;; Avoid various pitfalls that may lurk in the built-in (random) function!
;;; Shuffling algorithm from Numerical Recipes, section 7.1.
(defvar math-random-last)
-(defun math-random-digit ()
+(defun math-random-three-digit-number ()
+ "Return a random three digit number."
(let (i)
(or (and (boundp 'var-RandSeed) (eq var-RandSeed math-last-RandSeed))
(math-init-random-base))
@@ -621,17 +627,17 @@
;;; Produce an N-digit random integer.
(defun math-random-digits (n)
- (cond ((<= n 6)
- (math-scale-right (+ (* (math-random-digit) 1000) (math-random-digit))
- (- 6 n)))
- (t (let* ((slop (% (- 900003 n) 3))
- (i (/ (+ n slop) 3))
- (digs nil))
- (while (> i 0)
- (setq digs (cons (math-random-digit) digs)
- i (1- i)))
- (math-normalize (math-scale-right (cons 'bigpos digs)
- slop))))))
+ "Produce a random N digit integer."
+ (let* ((slop (% (- 3 (% n 3)) 3))
+ (i (/ (+ n slop) 3))
+ (rnum 0))
+ (while (> i 0)
+ (setq rnum
+ (math-add
+ (math-random-three-digit-number)
+ (math-mul rnum 1000)))
+ (setq i (1- i)))
+ (math-normalize (math-scale-right rnum slop))))
;;; Produce a uniformly-distributed random float 0 <= N < 1.
(defun math-random-float ()
@@ -802,7 +808,7 @@
(error "Argument must be an integer"))
((Math-integer-negp n)
'(nil))
- ((Math-natnum-lessp n '(bigpos 0 0 8))
+ ((Math-natnum-lessp n 8000000)
(setq n (math-fixnum n))
(let ((i -1) v)
(while (and (> (% n (setq v (aref math-primes-table
@@ -815,15 +821,17 @@
((not (equal n (car math-prime-test-cache)))
(cond ((= (% (nth 1 n) 2) 0) '(nil 2))
((= (% (nth 1 n) 5) 0) '(nil 5))
- (t (let ((dig (cdr n)) (sum 0))
- (while dig
- (if (cdr dig)
- (setq sum (% (+ (+ sum (car dig))
- (* (nth 1 dig) 1000))
- 111111)
- dig (cdr (cdr dig)))
- (setq sum (% (+ sum (car dig)) 111111)
- dig nil)))
+ (t (let ((q n) (sum 0))
+ (while (not (eq q 0))
+ (setq sum (%
+ (+
+ sum
+ (calcFunc-mod
+ q 1000000))
+ 111111))
+ (setq q
+ (math-quotient
+ q 1000000)))
(cond ((= (% sum 3) 0) '(nil 3))
((= (% sum 7) 0) '(nil 7))
((= (% sum 11) 0) '(nil 11))
diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el
index dc3221b5047..51cdd3f9174 100644
--- a/lisp/calc/calc-embed.el
+++ b/lisp/calc/calc-embed.el
@@ -254,7 +254,7 @@
(set-buffer-modified-p (buffer-modified-p))
(calc-embedded-restore-original-modes)
(or calc-embedded-quiet
- (message "Back to %s mode" mode-name))))
+ (message "Back to %s mode" (format-mode-line mode-name)))))
(t
(if (buffer-name (aref calc-embedded-info 0))
@@ -403,7 +403,7 @@
(let ((val (save-excursion
(set-buffer (aref info 1))
(let ((calc-language nil)
- (math-expr-opers math-standard-opers))
+ (math-expr-opers (math-standard-ops)))
(math-read-expr str)))))
(if (eq (car-safe val) 'error)
(progn
@@ -1374,5 +1374,5 @@ The command \\[yank] can retrieve it from there."
(provide 'calc-embed)
-;;; arch-tag: 1b8f311e-fba1-40d3-b8c3-1d6f68fd26fc
+;; arch-tag: 1b8f311e-fba1-40d3-b8c3-1d6f68fd26fc
;;; calc-embed.el ends here
diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el
index 8c52305a46b..5e5ae8166db 100644
--- a/lisp/calc/calc-ext.el
+++ b/lisp/calc/calc-ext.el
@@ -30,6 +30,51 @@
(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-raw "calc-math" (a &optional guess))
+(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 &optional baseline prec short))
+(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))
+(declare-function math-map-vec "calc-vec" (f a))
+(declare-function math-make-frac "calc-frac" (num den))
+
+
(defvar math-simplifying nil)
(defvar math-living-dangerously nil) ; true if unsafe simplifications are okay.
(defvar math-integrating nil)
@@ -211,6 +256,7 @@
(define-key calc-mode-map "dt" 'calc-truncate-stack)
(define-key calc-mode-map "dw" 'calc-auto-why)
(define-key calc-mode-map "dz" 'calc-leading-zeros)
+ (define-key calc-mode-map "dA" 'calc-giac-language)
(define-key calc-mode-map "dB" 'calc-big-language)
(define-key calc-mode-map "dD" 'calc-redo)
(define-key calc-mode-map "dC" 'calc-c-language)
@@ -224,6 +270,8 @@
(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 "dX" 'calc-maxima-language)
+ (define-key calc-mode-map "dY" 'calc-yacas-language)
(define-key calc-mode-map "d[" 'calc-truncate-up)
(define-key calc-mode-map "d]" 'calc-truncate-down)
(define-key calc-mode-map "d." 'calc-point-char)
@@ -618,15 +666,15 @@
(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)
@@ -635,7 +683,7 @@
(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))
@@ -651,7 +699,7 @@
(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))))
'(
@@ -1008,6 +1056,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-yacas-language calc-maxima-language calc-giac-language
calc-mathematica-language calc-normal-language calc-pascal-language
calc-tex-language calc-latex-language calc-unformatted-language)
@@ -1021,7 +1070,7 @@ 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-sec calc-sech
+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)
@@ -1277,7 +1326,7 @@ calc-kill calc-kill-region calc-yank))))
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)
+ (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)))
@@ -1357,7 +1406,7 @@ calc-kill calc-kill-region calc-yank))))
(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)))
@@ -1389,7 +1438,7 @@ calc-kill calc-kill-region calc-yank))))
(calc-set-command-flag 'no-align)
(setq prefix (set flag (not (symbol-value flag)))
prefix-arg n)
- (message (if prefix msg "")))
+ (message "%s" (if prefix msg "")))
(and prefix
(not calc-is-keypad-press)
(if (boundp 'overriding-terminal-local-map)
@@ -1438,7 +1487,7 @@ calc-kill calc-kill-region calc-yank))))
(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)))
@@ -1782,8 +1831,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)
@@ -1849,7 +1898,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))
@@ -1878,8 +1927,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
@@ -1914,7 +1974,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)
@@ -1945,7 +2009,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
@@ -1955,10 +2023,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)
@@ -2068,7 +2139,7 @@ calc-kill calc-kill-region calc-yank))))
;;; True if A is a real or will evaluate to a real. [P x] [Public]
(defun math-provably-realp (a)
(or (Math-realp a)
- (math-provably-integer a)
+ (math-provably-integerp a)
(memq (car-safe a) '(abs arg))))
;;; True if A is a non-real, complex number. [P x] [Public]
@@ -2126,12 +2197,12 @@ calc-kill calc-kill-region calc-yank))))
(unless a
(setq a 1))
(and
- (not (memq nil (mapcar
+ (not (memq nil (mapcar
(lambda (x) (eq x 0))
(nthcdr (1+ n) row))))
- (not (memq nil (mapcar
+ (not (memq nil (mapcar
(lambda (x) (eq x 0))
- (butlast
+ (butlast
(cdr row)
(- (length row) n)))))
(eq (elt row n) a)))
@@ -2189,6 +2260,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)
@@ -2202,7 +2292,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)
@@ -2290,15 +2380,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))))))
@@ -2679,8 +2769,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))
@@ -2960,7 +3050,7 @@ calc-kill calc-kill-region calc-yank))))
(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)
@@ -3005,10 +3095,10 @@ calc-kill calc-kill-region calc-yank))))
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
@@ -3116,7 +3206,7 @@ calc-kill calc-kill-region calc-yank))))
(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) ")")
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index cc0bfde8ffe..086e083c4de 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -32,6 +32,12 @@
(require 'calc-ext)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function calendar-current-time-zone "cal-dst" ())
+(declare-function calendar-absolute-from-gregorian "calendar" (date))
+(declare-function dst-in-effect "cal-dst" (date))
+
+
(defun calc-time ()
(interactive)
(calc-wrapper
@@ -544,6 +550,14 @@
(setcdr math-fd-dt nil))
fmt))))
+(defconst math-julian-date-beginning '(float 17214235 -1)
+ "The beginning of the Julian calendar,
+as measured in the number of days before January 1 of the year 1AD.")
+
+(defconst math-julian-date-beginning-int 1721424
+ "The beginning of the Julian calendar,
+as measured in the integer number of days before January 1 of the year 1AD.")
+
(defun math-format-date-part (x)
(cond ((stringp x)
x)
@@ -558,9 +572,12 @@
((eq x 'n)
(math-format-number (math-floor math-fd-date)))
((eq x 'J)
- (math-format-number (math-add math-fd-date '(float (bigpos 235 214 17) -1))))
+ (math-format-number
+ (math-add math-fd-date math-julian-date-beginning)))
((eq x 'j)
- (math-format-number (math-add (math-floor math-fd-date) '(bigpos 424 721 1))))
+ (math-format-number (math-add
+ (math-floor math-fd-date)
+ math-julian-date-beginning-int)))
((eq x 'U)
(math-format-number (nth 1 (math-date-parts math-fd-date 719164))))
((progn
@@ -935,9 +952,8 @@
0
(if (or (eq this 'j)
(math-integerp num))
- '(bigpos 424 721 1)
- '(float (bigpos 235 214 17)
- -1))))
+ math-julian-date-beginning-int
+ math-julian-date-beginning)))
hour (or (nth 3 num) hour)
minute (or (nth 4 num) minute)
second (or (nth 5 num) second)
@@ -1146,14 +1162,14 @@
(defun calcFunc-julian (date &optional zone)
(if (math-realp date)
(list 'date (if (math-integerp date)
- (math-sub date '(bigpos 424 721 1))
- (setq date (math-sub date '(float (bigpos 235 214 17) -1)))
+ (math-sub date math-julian-date-beginning-int)
+ (setq date (math-sub date math-julian-date-beginning))
(math-sub date (math-div (calcFunc-tzone zone date)
'(float 864 2)))))
(if (eq (car date) 'date)
(math-add (nth 1 date) (if (math-integerp (nth 1 date))
- '(bigpos 424 721 1)
- (math-add '(float (bigpos 235 214 17) -1)
+ math-julian-date-beginning-int
+ (math-add math-julian-date-beginning
(math-div (calcFunc-tzone zone date)
'(float 864 2)))))
(math-reject-arg date 'datep))))
@@ -1191,7 +1207,29 @@
)
"No doc yet. See calc manual for now. ")
-(defvar var-TimeZone)
+(defvar var-TimeZone nil)
+
+;; From cal-dst
+(defvar calendar-current-time-zone-cache)
+
+(defvar math-calendar-tzinfo
+ nil
+ "Information about the timezone, retrieved from the calendar.")
+
+(defun math-get-calendar-tzinfo ()
+ "Get information about the timezone from the calendar.
+The result should be a list of two items about the current time zone:
+first, the number of seconds difference from GMT
+second, the number of seconds offset for daylight savings."
+ (if math-calendar-tzinfo
+ math-calendar-tzinfo
+ (require 'cal-dst)
+ (let ((tzinfo (progn
+ (calendar-current-time-zone)
+ calendar-current-time-zone-cache)))
+ (setq math-calendar-tzinfo
+ (list (* 60 (abs (nth 0 tzinfo)))
+ (* 60 (nth 1 tzinfo)))))))
(defun calcFunc-tzone (&optional zone date)
(if zone
@@ -1223,53 +1261,9 @@
(t (math-reject-arg zone "*Expected a time zone")))
(if (calc-var-value 'var-TimeZone)
(calcFunc-tzone (calc-var-value 'var-TimeZone) date)
- (let ((p math-tzone-names)
- (offset 0)
- (tz '(var error var-error)))
- (save-excursion
- (set-buffer (get-buffer-create " *Calc Temporary*"))
- (erase-buffer)
- (call-process "date" nil t)
- (goto-char 1)
- (let ((case-fold-search t))
- (while (and p (not (search-forward (car (car p)) nil t)))
- (setq p (cdr p))))
- (if (looking-at "\\([-+][0-9]?[0-9]\\)\\([0-9][0-9]\\)?\\(\\'\\|[^0-9]\\)")
- (setq offset (math-add
- (string-to-number (buffer-substring
- (match-beginning 1)
- (match-end 1)))
- (if (match-beginning 2)
- (math-div (string-to-number (buffer-substring
- (match-beginning 2)
- (match-end 2)))
- 60)
- 0)))))
- (if p
- (progn
- (setq p (car p))
- ;; Try to convert to a generalized time zone.
- (if (integerp (nth 2 p))
- (let ((gen math-tzone-names))
- (while (and gen
- (not (equal (nth 2 (car gen)) (car p)))
- (not (equal (nth 3 (car gen)) (car p)))
- (not (equal (nth 4 (car gen)) (car p)))
- (not (equal (nth 5 (car gen)) (car p))))
- (setq gen (cdr gen)))
- (and gen
- (setq gen (car gen))
- (equal (math-daylight-savings-adjust nil (car gen))
- (nth 2 p))
- (setq p gen))))
- (setq tz (math-add (list 'var
- (intern (car p))
- (intern (concat "var-" (car p))))
- offset))))
- (kill-buffer " *Calc Temporary*")
- (setq var-TimeZone tz)
- (calc-refresh-evaltos 'var-TimeZone)
- (calcFunc-tzone tz date)))))
+ (let ((tzinfo (math-get-calendar-tzinfo)))
+ (+ (nth 0 tzinfo)
+ (* (math-cal-daylight-savings-adjust date) (nth 1 tzinfo)))))))
(defvar math-daylight-savings-hook 'math-std-daylight-savings)
@@ -1290,21 +1284,60 @@
(and math-daylight-savings-hook
(funcall math-daylight-savings-hook date dt zone bump))))
+;;; Based on part of dst-adjust-time in cal-dst.el
+;;; For calcFunc-dst, when zone=nil
+(defun math-cal-daylight-savings-adjust (date)
+ "Return -1 if DATE is using daylight saving, 0 otherwise."
+ (require 'cal-dst)
+ (unless date (setq date (calcFunc-now)))
+ (let* ((dt (math-date-to-dt date))
+ (time (cond
+ ((nth 3 dt)
+ (nth 3 dt))
+ ((nth 4 dt)
+ (+ (nth 3 dt) (/ (nth 4 dt) 60.0)))
+ (t
+ 0)))
+ (rounded-abs-date
+ (+
+ (calendar-absolute-from-gregorian
+ (list (nth 1 dt) (nth 2 dt) (nth 0 dt)))
+ (/ (round (* 60 time)) 60.0 24.0))))
+ (if (dst-in-effect rounded-abs-date)
+ -1
+ 0)))
+
(defun calcFunc-dsadj (date &optional zone)
(if zone
(or (eq (car-safe zone) 'var)
(math-reject-arg zone "*Time zone variable expected"))
- (setq zone (or (calc-var-value 'var-TimeZone)
- (progn
- (calcFunc-tzone)
- (calc-var-value 'var-TimeZone)))))
- (setq zone (and (eq (car-safe zone) 'var)
- (upcase (symbol-name (nth 1 zone)))))
- (let ((zadj (assoc zone math-tzone-names)))
- (or zadj (math-reject-arg zone "*Unrecognized time zone name"))
- (if (integerp (nth 2 zadj))
- (nth 2 zadj)
- (math-daylight-savings-adjust date zone))))
+ (setq zone (calc-var-value 'var-TimeZone)))
+ (if zone
+ (progn
+ (setq zone (and (eq (car-safe zone) 'var)
+ (upcase (symbol-name (nth 1 zone)))))
+ (let ((zadj (assoc zone math-tzone-names)))
+ (or zadj (math-reject-arg zone "*Unrecognized time zone name"))
+ (if (integerp (nth 2 zadj))
+ (nth 2 zadj)
+ (math-daylight-savings-adjust date zone))))
+ (math-cal-daylight-savings-adjust date)))
+
+;; (defun calcFunc-dsadj (date &optional zone)
+;; (if zone
+;; (or (eq (car-safe zone) 'var)
+;; (math-reject-arg zone "*Time zone variable expected"))
+;; (setq zone (or (calc-var-value 'var-TimeZone)
+;; (progn
+;; (calcFunc-tzone)
+;; (calc-var-value 'var-TimeZone)))))
+;; (setq zone (and (eq (car-safe zone) 'var)
+;; (upcase (symbol-name (nth 1 zone)))))
+;; (let ((zadj (assoc zone math-tzone-names)))
+;; (or zadj (math-reject-arg zone "*Unrecognized time zone name"))
+;; (if (integerp (nth 2 zadj))
+;; (nth 2 zadj)
+;; (math-daylight-savings-adjust date zone))))
(defun calcFunc-tzconv (date z1 z2)
(if (math-realp date)
diff --git a/lisp/calc/calc-funcs.el b/lisp/calc/calc-funcs.el
index 162692b742c..f4f63d1df8a 100644
--- a/lisp/calc/calc-funcs.el
+++ b/lisp/calc/calc-funcs.el
@@ -147,7 +147,8 @@
(or (math-numberp x) (math-reject-arg x 'numberp))
(calcFunc-fact (math-add x -1)))
-(defun math-gammap1-raw (x &optional fprec nfprec) ; compute gamma(1 + x)
+(defun math-gammap1-raw (x &optional fprec nfprec)
+ "Compute gamma(1+X) to the appropriate precision."
(or fprec
(setq fprec (math-float calc-internal-prec)
nfprec (math-float (- calc-internal-prec))))
@@ -567,42 +568,48 @@
((Math-lessp '(float 8 0) (math-abs-approx x))
(let* ((z (math-div '(float 8 0) x))
(y (math-sqr z))
- (xx (math-add x '(float (bigneg 164 398 785) -9)))
+ (xx (math-add x
+ (math-read-number-simple "-0.785398164")))
(a1 (math-poly-eval y
- '((float (bigpos 211 887 093 2) -16)
- (float (bigneg 639 370 073 2) -15)
- (float (bigpos 407 510 734 2) -14)
- (float (bigneg 627 628 098 1) -12)
- (float 1 0))))
+ (list
+ (math-read-number-simple "0.0000002093887211")
+ (math-read-number-simple "-0.000002073370639")
+ (math-read-number-simple "0.00002734510407")
+ (math-read-number-simple "-0.001098628627")
+ '(float 1 0))))
(a2 (math-poly-eval y
- '((float (bigneg 152 935 934) -16)
- (float (bigpos 161 095 621 7) -16)
- (float (bigneg 651 147 911 6) -15)
- (float (bigpos 765 488 430 1) -13)
- (float (bigneg 995 499 562 1) -11))))
+ (list
+ (math-read-number-simple "-0.0000000934935152")
+ (math-read-number-simple "0.0000007621095161")
+ (math-read-number-simple "-0.000006911147651")
+ (math-read-number-simple "0.0001430488765")
+ (math-read-number-simple "-0.01562499995"))))
(sc (math-sin-cos-raw xx)))
(if yflag
(setq sc (cons (math-neg (cdr sc)) (car sc))))
(math-mul (math-sqrt
- (math-div '(float (bigpos 722 619 636) -9) x))
+ (math-div (math-read-number-simple "0.636619722")
+ x))
(math-sub (math-mul (cdr sc) a1)
(math-mul (car sc) (math-mul z a2))))))
(t
(let ((y (math-sqr x)))
(math-div (math-poly-eval y
- '((float (bigneg 456 052 849 1) -7)
- (float (bigpos 017 233 739 7) -5)
- (float (bigneg 418 442 121 1) -2)
- (float (bigpos 407 196 516 6) -1)
- (float (bigneg 354 590 362 13) 0)
- (float (bigpos 574 490 568 57) 0)))
+ (list
+ (math-read-number-simple "-184.9052456")
+ (math-read-number-simple "77392.33017")
+ (math-read-number-simple "-11214424.18")
+ (math-read-number-simple "651619640.7")
+ (math-read-number-simple "-13362590354.0")
+ (math-read-number-simple "57568490574.0")))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 712 532 678 2) -7)
- (float (bigpos 853 264 927 5) -5)
- (float (bigpos 718 680 494 9) -3)
- (float (bigpos 985 532 029 1) 0)
- (float (bigpos 411 490 568 57) 0))))))))
+ (list
+ '(float 1 0)
+ (math-read-number-simple "267.8532712")
+ (math-read-number-simple "59272.64853")
+ (math-read-number-simple "9494680.718")
+ (math-read-number-simple "1029532985.0")
+ (math-read-number-simple "57568490411.0"))))))))
(defun math-besJ1 (x &optional yflag)
(cond ((and (math-negp (calcFunc-re x)) (not yflag))
@@ -610,25 +617,29 @@
((Math-lessp '(float 8 0) (math-abs-approx x))
(let* ((z (math-div '(float 8 0) x))
(y (math-sqr z))
- (xx (math-add x '(float (bigneg 491 194 356 2) -9)))
+ (xx (math-add x (math-read-number-simple "-2.356194491")))
(a1 (math-poly-eval y
- '((float (bigneg 019 337 240) -15)
- (float (bigpos 174 520 457 2) -15)
- (float (bigneg 496 396 516 3) -14)
- (float 183105 -8)
- (float 1 0))))
+ (list
+ (math-read-number-simple "-0.000000240337019")
+ (math-read-number-simple "0.000002457520174")
+ (math-read-number-simple "-0.00003516396496")
+ '(float 183105 -8)
+ '(float 1 0))))
(a2 (math-poly-eval y
- '((float (bigpos 412 787 105) -15)
- (float (bigneg 987 228 88) -14)
- (float (bigpos 096 199 449 8) -15)
- (float (bigneg 873 690 002 2) -13)
- (float (bigpos 995 499 687 4) -11))))
+ (list
+ (math-read-number-simple "0.000000105787412")
+ (math-read-number-simple "-0.00000088228987")
+ (math-read-number-simple "0.000008449199096")
+ (math-read-number-simple "-0.0002002690873")
+ (math-read-number-simple "0.04687499995"))))
(sc (math-sin-cos-raw xx)))
(if yflag
(setq sc (cons (math-neg (cdr sc)) (car sc)))
(if (math-negp x)
(setq sc (cons (math-neg (car sc)) (math-neg (cdr sc))))))
- (math-mul (math-sqrt (math-div '(float (bigpos 722 619 636) -9) x))
+ (math-mul (math-sqrt (math-div
+ (math-read-number-simple "0.636619722")
+ x))
(math-sub (math-mul (cdr sc) a1)
(math-mul (car sc) (math-mul z a2))))))
(t
@@ -636,20 +647,21 @@
(math-mul
x
(math-div (math-poly-eval y
- '((float (bigneg 606 036 016 3) -8)
- (float (bigpos 826 044 157) -4)
- (float (bigneg 439 611 972 2) -3)
- (float (bigpos 531 968 423 2) -1)
- (float (bigneg 235 059 895 7) 0)
- (float (bigpos 232 614 362 72) 0)))
+ (list
+ (math-read-number-simple "-30.16036606")
+ (math-read-number-simple "15704.4826")
+ (math-read-number-simple "-2972611.439")
+ (math-read-number-simple "242396853.1")
+ (math-read-number-simple "-7895059235.0")
+ (math-read-number-simple "72362614232.0")))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 397 991 769 3) -7)
- (float (bigpos 394 743 944 9) -5)
- (float (bigpos 474 330 858 1) -2)
- (float (bigpos 178 535 300 2) 0)
- (float (bigpos 442 228 725 144)
- 0)))))))))
+ (list
+ '(float 1 0)
+ (math-read-number-simple "376.9991397")
+ (math-read-number-simple "99447.43394")
+ (math-read-number-simple "18583304.74")
+ (math-read-number-simple "2300535178.0")
+ (math-read-number-simple "144725228442.0")))))))))
(defun calcFunc-besY (v x)
(math-inexact-result)
@@ -688,22 +700,24 @@
(defun math-besY0 (x)
(cond ((Math-lessp (math-abs-approx x) '(float 8 0))
(let ((y (math-sqr x)))
- (math-add
+ (math-add
(math-div (math-poly-eval y
- '((float (bigpos 733 622 284 2) -7)
- (float (bigneg 757 792 632 8) -5)
- (float (bigpos 129 988 087 1) -2)
- (float (bigneg 036 598 123 5) -1)
- (float (bigpos 065 834 062 7) 0)
- (float (bigneg 389 821 957 2) 0)))
+ (list
+ (math-read-number-simple "228.4622733")
+ (math-read-number-simple "-86327.92757")
+ (math-read-number-simple "10879881.29")
+ (math-read-number-simple "-512359803.6")
+ (math-read-number-simple "7062834065.0")
+ (math-read-number-simple "-2957821389.0")))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 244 030 261 2) -7)
- (float (bigpos 647 472 474) -4)
- (float (bigpos 438 466 189 7) -3)
- (float (bigpos 648 499 452 7) -1)
- (float (bigpos 269 544 076 40) 0))))
- (math-mul '(float (bigpos 772 619 636) -9)
+ (list
+ '(float 1 0)
+ (math-read-number-simple "226.1030244")
+ (math-read-number-simple "47447.2647")
+ (math-read-number-simple "7189466.438")
+ (math-read-number-simple "745249964.8")
+ (math-read-number-simple "40076544269.0"))))
+ (math-mul (math-read-number-simple "0.636619772")
(math-mul (math-besJ0 x) (math-ln-raw x))))))
((math-negp (calcFunc-re x))
(math-add (math-besJ0 (math-neg x) t)
@@ -719,22 +733,24 @@
(math-mul
x
(math-div (math-poly-eval y
- '((float (bigpos 935 937 511 8) -6)
- (float (bigneg 726 922 237 4) -3)
- (float (bigpos 551 264 349 7) -1)
- (float (bigneg 139 438 153 5) 1)
- (float (bigpos 439 527 127) 4)
- (float (bigneg 943 604 900 4) 3)))
+ (list
+ (math-read-number-simple "8511.937935")
+ (math-read-number-simple "-4237922.726")
+ (math-read-number-simple "734926455.1")
+ (math-read-number-simple "-51534381390.0")
+ (math-read-number-simple "1275274390000.0")
+ (math-read-number-simple "-4900604943000.0")))
(math-poly-eval y
- '((float 1 0)
- (float (bigpos 885 632 549 3) -7)
- (float (bigpos 605 042 102) -3)
- (float (bigpos 002 904 245 2) -2)
- (float (bigpos 367 650 733 3) 0)
- (float (bigpos 664 419 244 4) 2)
- (float (bigpos 057 958 249) 5)))))
- (math-mul '(float (bigpos 772 619 636) -9)
- (math-sub (math-mul (math-besJ1 x) (math-ln-raw x))
+ (list
+ '(float 1 0)
+ (math-read-number-simple "354.9632885")
+ (math-read-number-simple "102042.605")
+ (math-read-number-simple "22459040.02")
+ (math-read-number-simple "3733650367.0")
+ (math-read-number-simple "424441966400.0")
+ (math-read-number-simple "24995805700000.0")))))
+ (math-mul (math-read-number-simple "0.636619772")
+ (math-sub (math-mul (math-besJ1 x) (math-ln-raw x))
(math-div 1 x))))))
((math-negp (calcFunc-re x))
(math-neg
@@ -799,21 +815,45 @@
(calcFunc-euler n '(float 5 -1)))
(calcFunc-euler n '(frac 1 2))))))
-(defvar math-bernoulli-b-cache '((frac -174611
- (bigpos 0 200 291 698 662 857 802))
- (frac 43867 (bigpos 0 944 170 217 94 109 5))
- (frac -3617 (bigpos 0 880 842 622 670 10))
- (frac 1 (bigpos 600 249 724 74))
- (frac -691 (bigpos 0 368 674 307 1))
- (frac 1 (bigpos 160 900 47))
- (frac -1 (bigpos 600 209 1))
- (frac 1 30240) (frac -1 720)
- (frac 1 12) 1 ))
-
-(defvar math-bernoulli-B-cache '((frac -174611 330) (frac 43867 798)
- (frac -3617 510) (frac 7 6) (frac -691 2730)
- (frac 5 66) (frac -1 30) (frac 1 42)
- (frac -1 30) (frac 1 6) 1 ))
+(defvar math-bernoulli-b-cache
+ (list
+ (list 'frac
+ -174611
+ (math-read-number-simple "802857662698291200000"))
+ (list 'frac
+ 43867
+ (math-read-number-simple "5109094217170944000"))
+ (list 'frac
+ -3617
+ (math-read-number-simple "10670622842880000"))
+ (list 'frac
+ 1
+ (math-read-number-simple "74724249600"))
+ (list 'frac
+ -691
+ (math-read-number-simple "1307674368000"))
+ (list 'frac
+ 1
+ (math-read-number-simple "47900160"))
+ (list 'frac
+ -1
+ (math-read-number-simple "1209600"))
+ (list 'frac
+ 1
+ 30240)
+ (list 'frac
+ -1
+ 720)
+ (list 'frac
+ 1
+ 12)
+ 1 ))
+
+(defvar math-bernoulli-B-cache
+ '((frac -174611 330) (frac 43867 798)
+ (frac -3617 510) (frac 7 6) (frac -691 2730)
+ (frac 5 66) (frac -1 30) (frac 1 42)
+ (frac -1 30) (frac 1 6) 1 ))
(defvar math-bernoulli-cache-size 11)
(defun math-bernoulli-coefs (n)
diff --git a/lisp/calc/calc-graph.el b/lisp/calc/calc-graph.el
index 6d9f7061c05..d52dc6d84b0 100644
--- a/lisp/calc/calc-graph.el
+++ b/lisp/calc/calc-graph.el
@@ -218,7 +218,8 @@
0)
(or (and (Math-num-integerp pstyle) (math-trunc pstyle))
(if (eq (car-safe (calc-var-value (nth 2 ydata))) 'vec)
- 0 -1)))))
+ 0 -1))
+ (math-contains-sdev-p (eval (nth 2 ydata))))))
(defun calc-graph-lookup (thing)
(if (and (eq (car-safe thing) 'var)
@@ -792,6 +793,10 @@
calc-graph-numsteps (1- (* calc-graph-numsteps (1+ calc-graph-numsteps3))))))
(defun calc-graph-format-data ()
+ (if (math-contains-sdev-p calc-graph-yp)
+ (let ((yp calc-graph-yp))
+ (setq calc-graph-yp (cons 'vec (mapcar 'math-get-value (cdr yp))))
+ (setq calc-graph-zp (cons 'vec (mapcar 'math-get-sdev (cdr yp))))))
(while (<= (setq calc-graph-stepcount (1+ calc-graph-stepcount)) calc-graph-numsteps)
(if calc-graph-xvec
(setq calc-graph-xp (cdr calc-graph-xp)
@@ -1059,7 +1064,7 @@ This \"dumb\" driver will be present in Gnuplot 3.0."
(interactive "P")
(calc-graph-set-styles t (and style (prefix-numeric-value style))))
-(defun calc-graph-set-styles (lines points)
+(defun calc-graph-set-styles (lines points &optional yerr)
(calc-graph-init)
(save-excursion
(set-buffer calc-gnuplot-input)
@@ -1067,7 +1072,7 @@ This \"dumb\" driver will be present in Gnuplot 3.0."
(error "No data points have been set!"))
(let ((base (point))
(mode nil) (lstyle nil) (pstyle nil)
- start end lenbl penbl)
+ start end lenbl penbl errform)
(re-search-forward "[,\n]")
(forward-char -1)
(setq end (point) start end)
@@ -1087,29 +1092,48 @@ This \"dumb\" driver will be present in Gnuplot 3.0."
(setq pstyle (string-to-number
(buffer-substring (match-beginning 1)
(match-end 1)))))))
- (setq lenbl (or (equal mode "lines") (equal mode "linespoints"))
- penbl (or (equal mode "points") (equal mode "linespoints")))
- (if lines
- (or (eq lines t)
- (setq lstyle lines
- lenbl (>= lines 0)))
- (setq lenbl (not lenbl)))
- (if points
- (or (eq points t)
- (setq pstyle points
- penbl (>= points 0)))
- (setq penbl (not penbl)))
- (delete-region start end)
+ (unless yerr
+ (setq lenbl (or (equal mode "lines")
+ (equal mode "linespoints"))
+ penbl (or (equal mode "points")
+ (equal mode "linespoints")))
+ (if lines
+ (or (eq lines t)
+ (setq lstyle lines
+ lenbl (>= lines 0)))
+ (setq lenbl (not lenbl)))
+ (if points
+ (or (eq points t)
+ (setq pstyle points
+ penbl (>= points 0)))
+ (setq penbl (not penbl))))
+ (delete-region start end)
(goto-char start)
- (insert " with "
- (if lenbl
- (if penbl "linespoints" "lines")
- (if penbl "points" "dots")))
- (if (and pstyle (> pstyle 0))
- (insert " " (if (and lstyle (> lstyle 0)) (int-to-string lstyle) "1")
- " " (int-to-string pstyle))
- (if (and lstyle (> lstyle 0))
- (insert " " (int-to-string lstyle))))))
+ (setq errform
+ (condition-case nil
+ (math-contains-sdev-p
+ (eval (intern
+ (concat "var-"
+ (save-excursion
+ (re-search-backward ":\\(.*\\)\\}")
+ (match-string 1))))))
+ (error nil)))
+ (if yerr
+ (insert " with yerrorbars")
+ (insert " with "
+ (if (and errform
+ (equal mode "dots")
+ (eq lines t))
+ "yerrorbars"
+ (if lenbl
+ (if penbl "linespoints" "lines")
+ (if penbl "points" "dots"))))
+ (if (and pstyle (> pstyle 0))
+ (insert " "
+ (if (and lstyle (> lstyle 0)) (int-to-string lstyle) "1")
+ " " (int-to-string pstyle))
+ (if (and lstyle (> lstyle 0))
+ (insert " " (int-to-string lstyle)))))))
(calc-graph-view-commands))
(defun calc-graph-zero-x (flag)
diff --git a/lisp/calc/calc-help.el b/lisp/calc/calc-help.el
index 46cf2ce8dbb..320e8e43459 100644
--- a/lisp/calc/calc-help.el
+++ b/lisp/calc/calc-help.el
@@ -32,6 +32,11 @@
(require 'calc-ext)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function Info-goto-node "info" (nodename &optional fork))
+(declare-function Info-last "info" ())
+
+
(defun calc-help-prefix (arg)
"This key is the prefix for Calc help functions. See calc-help-for-help."
(interactive "P")
@@ -321,11 +326,11 @@ C-w Describe how there is no warranty for Calc."
(defun calc-describe-function (&optional func)
(interactive)
(unless calc-help-function-list
- (setq calc-help-function-list
+ (setq calc-help-function-list
(calc-help-index-entries "Function" "Command")))
(or func
(setq func (completing-read "Describe function: "
- calc-help-function-list
+ calc-help-function-list
nil t)))
(if (string-match "\\`calc-." func)
(calc-describe-thing func "Command Index")
@@ -334,7 +339,7 @@ C-w Describe how there is no warranty for Calc."
(defun calc-describe-variable (&optional var)
(interactive)
(unless calc-help-variable-list
- (setq calc-help-variable-list
+ (setq calc-help-variable-list
(calc-help-index-entries "Variable")))
(or var
(setq var (completing-read "Describe variable: "
@@ -419,49 +424,49 @@ C-w Describe how there is no warranty for Calc."
(princ "Or type `h i' to read the full Calc manual on-line.\n\n")
(princ "Basic keys:\n")
(let* ((calc-full-help-flag t))
- (mapcar (function (lambda (x) (princ (format " %s\n" x))))
- (nreverse (cdr (reverse (cdr (calc-help))))))
- (mapcar (function (lambda (prefix)
- (let ((msgs (condition-case err
- (funcall prefix)
- (error nil))))
- (if (car msgs)
- (princ
- (if (eq (nth 2 msgs) ?v)
- "\n`v' or `V' prefix (vector/matrix) keys: \n"
- (if (nth 2 msgs)
- (format
- "\n`%c' prefix (%s) keys:\n"
- (nth 2 msgs)
- (or (cdr (assq (nth 2 msgs)
- calc-help-long-names))
- (nth 1 msgs)))
- (format "\n%s-modified keys:\n"
- (capitalize (nth 1 msgs)))))))
- (mapcar (function (lambda (x)
- (princ (format " %s\n" x))))
- (car msgs)))))
- '(calc-inverse-prefix-help
- calc-hyperbolic-prefix-help
- calc-inv-hyp-prefix-help
- calc-a-prefix-help
- calc-b-prefix-help
- calc-c-prefix-help
- calc-d-prefix-help
- calc-f-prefix-help
- calc-g-prefix-help
- calc-h-prefix-help
- calc-j-prefix-help
- calc-k-prefix-help
- calc-m-prefix-help
- calc-r-prefix-help
- calc-s-prefix-help
- calc-t-prefix-help
- calc-u-prefix-help
- calc-v-prefix-help
- calc-shift-Y-prefix-help
- calc-shift-Z-prefix-help
- calc-z-prefix-help)))
+ (mapc (function (lambda (x) (princ (format " %s\n" x))))
+ (nreverse (cdr (reverse (cdr (calc-help))))))
+ (mapc (function (lambda (prefix)
+ (let ((msgs (condition-case err
+ (funcall prefix)
+ (error nil))))
+ (if (car msgs)
+ (princ
+ (if (eq (nth 2 msgs) ?v)
+ "\n`v' or `V' prefix (vector/matrix) keys: \n"
+ (if (nth 2 msgs)
+ (format
+ "\n`%c' prefix (%s) keys:\n"
+ (nth 2 msgs)
+ (or (cdr (assq (nth 2 msgs)
+ calc-help-long-names))
+ (nth 1 msgs)))
+ (format "\n%s-modified keys:\n"
+ (capitalize (nth 1 msgs)))))))
+ (mapcar (function (lambda (x)
+ (princ (format " %s\n" x))))
+ (car msgs)))))
+ '(calc-inverse-prefix-help
+ calc-hyperbolic-prefix-help
+ calc-inv-hyp-prefix-help
+ calc-a-prefix-help
+ calc-b-prefix-help
+ calc-c-prefix-help
+ calc-d-prefix-help
+ calc-f-prefix-help
+ calc-g-prefix-help
+ calc-h-prefix-help
+ calc-j-prefix-help
+ calc-k-prefix-help
+ calc-m-prefix-help
+ calc-r-prefix-help
+ calc-s-prefix-help
+ calc-t-prefix-help
+ calc-u-prefix-help
+ calc-v-prefix-help
+ calc-shift-Y-prefix-help
+ calc-shift-Z-prefix-help
+ calc-z-prefix-help)))
(print-help-return-message)))
(defun calc-h-prefix-help ()
@@ -596,6 +601,7 @@ C-w Describe how there is no warranty for Calc."
"\" (strings); Truncate, [, ]; SPC (refresh), RET, @"
"SHIFT + language: Normal, One-line, Big, Unformatted"
"SHIFT + language: C, Pascal, Fortran; TeX, LaTeX, Eqn"
+ "SHIFT + language: Yacas, X=Maxima, A=Giac"
"SHIFT + language: Mathematica, W=Maple")
"display" ?d))
diff --git a/lisp/calc/calc-lang.el b/lisp/calc/calc-lang.el
index 7ea2fe4c49a..fc1a50f1d23 100644
--- a/lisp/calc/calc-lang.el
+++ b/lisp/calc/calc-lang.el
@@ -32,12 +32,28 @@
(require 'calc-ext)
(require 'calc-macs)
+
+;; Declare functions which are defined elsewhere.
+(declare-function math-compose-vector "calccomp" (a sep prec))
+(declare-function math-compose-var "calccomp" (a))
+(declare-function math-tex-expr-is-flat "calccomp" (a))
+(declare-function math-read-factor "calc-aent" ())
+(declare-function math-read-expr-level "calc-aent" (exp-prec &optional exp-term))
+
+;; Declare variables which are defined elsewhere.
+(defvar calc-lang-slash-idiv)
+(defvar calc-lang-allow-underscores)
+(defvar calc-lang-allow-percentsigns)
+(defvar math-comp-left-bracket)
+(defvar math-comp-right-bracket)
+(defvar math-comp-comma)
+(defvar math-comp-vector-prec)
+
;;; Alternate entry/display languages.
(defun calc-set-language (lang &optional option no-refresh)
- (setq math-expr-opers (or (get lang 'math-oper-table) math-standard-opers)
+ (setq math-expr-opers (or (get lang 'math-oper-table) (math-standard-ops))
math-expr-function-mapping (get lang 'math-function-table)
- math-expr-special-function-mapping (get lang 'math-special-function-table)
math-expr-variable-mapping (get lang 'math-variable-table)
calc-language-input-filter (get lang 'math-input-filter)
calc-language-output-filter (get lang 'math-output-filter)
@@ -84,10 +100,10 @@
(message "`C' language mode")))
(put 'c 'math-oper-table
- '( ( "u+" ident -1 1000 )
- ( "u-" neg -1 1000 )
- ( "u!" calcFunc-lnot -1 1000 )
+ '( ( "u!" calcFunc-lnot -1 1000 )
( "~" calcFunc-not -1 1000 )
+ ( "u+" ident -1 197 )
+ ( "u-" neg -1 197 )
( "*" * 190 191 )
( "/" / 190 191 )
( "%" % 190 191 )
@@ -135,6 +151,20 @@
(if (= r 8) (format "0%s" s)
(format "%d#%s" r s))))))
+(put 'c 'math-compose-subscr
+ (function
+ (lambda (a)
+ (let ((args (cdr (cdr a))))
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "["
+ (math-compose-vector args ", " 0)
+ "]")))))
+
+(add-to-list 'calc-lang-slash-idiv 'c)
+(add-to-list 'calc-lang-allow-underscores 'c)
+(add-to-list 'calc-lang-c-type-hex 'c)
+(add-to-list 'calc-lang-brackets-are-subscripts 'c)
(defun calc-pascal-language (n)
(interactive "P")
@@ -183,6 +213,32 @@
(if (= r 16) (format "$%s" s)
(format "%d#%s" r s)))))
+(put 'pascal 'math-lang-read-symbol
+ '((?\$
+ (eq (string-match
+ "\\(\\$[0-9a-fA-F]+\\)\\($\\|[^0-9a-zA-Z]\\)"
+ math-exp-str math-exp-pos)
+ math-exp-pos)
+ (setq math-exp-token 'number
+ math-expr-data (math-match-substring math-exp-str 1)
+ math-exp-pos (match-end 1)))))
+
+(put 'pascal 'math-compose-subscr
+ (function
+ (lambda (a)
+ (let ((args (cdr (cdr a))))
+ (while (eq (car-safe (nth 1 a)) 'calcFunc-subscr)
+ (setq args (append (cdr (cdr (nth 1 a))) args)
+ a (nth 1 a)))
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "["
+ (math-compose-vector args ", " 0)
+ "]")))))
+
+(add-to-list 'calc-lang-allow-underscores 'pascal)
+(add-to-list 'calc-lang-brackets-are-subscripts 'pascal)
+
(defun calc-input-case-filter (str)
(cond ((or (null calc-language-option) (= calc-language-option 0))
str)
@@ -253,8 +309,34 @@
( real . calcFunc-re )))
(put 'fortran 'math-input-filter 'calc-input-case-filter)
+
(put 'fortran 'math-output-filter 'calc-output-case-filter)
+(put 'fortran 'math-lang-read-symbol
+ '((?\.
+ (eq (string-match "\\.[a-zA-Z][a-zA-Z][a-zA-Z]?\\."
+ math-exp-str math-exp-pos) math-exp-pos)
+ (setq math-exp-token 'punc
+ math-expr-data (upcase (math-match-substring math-exp-str 0))
+ math-exp-pos (match-end 0)))))
+
+(put 'fortran 'math-compose-subscr
+ (function
+ (lambda (a)
+ (let ((args (cdr (cdr a))))
+ (while (eq (car-safe (nth 1 a)) 'calcFunc-subscr)
+ (setq args (append (cdr (cdr (nth 1 a))) args)
+ a (nth 1 a)))
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "("
+ (math-compose-vector args ", " 0)
+ ")")))))
+
+(add-to-list 'calc-lang-slash-idiv 'fortran)
+(add-to-list 'calc-lang-allow-underscores 'fortran)
+(add-to-list 'calc-lang-parens-are-subscripts 'fortran)
+
;; The next few variables are local to math-read-exprs in calc-aent.el
;; and math-read-expr in calc-ext.el, but are set in functions they call.
@@ -327,10 +409,11 @@
(message
"LaTeX language mode with \\func(\\text{var}) and multiline matrices")))))
+(put 'tex 'math-lang-name "TeX")
+(put 'latex 'math-lang-name "LaTeX")
+
(put 'tex 'math-oper-table
- '( ( "u+" ident -1 1000 )
- ( "u-" neg -1 1000 )
- ( "\\hat" calcFunc-hat -1 950 )
+ '( ( "\\hat" calcFunc-hat -1 950 )
( "\\check" calcFunc-check -1 950 )
( "\\tilde" calcFunc-tilde -1 950 )
( "\\acute" calcFunc-acute -1 950 )
@@ -351,13 +434,15 @@
( "!" calcFunc-fact 210 -1 )
( "^" ^ 201 200 )
( "_" calcFunc-subscr 201 200 )
+ ( "u+" ident -1 197 )
+ ( "u-" neg -1 197 )
( "\\times" * 191 190 )
( "*" * 191 190 )
( "2x" * 191 190 )
- ( "/" / 185 186 )
( "+" + 180 181 )
( "-" - 180 181 )
( "\\over" / 170 171 )
+ ( "/" / 170 171 )
( "\\choose" calcFunc-choose 170 171 )
( "\\mod" % 170 171 )
( "<" calcFunc-lt 160 161 )
@@ -408,6 +493,11 @@
( \\phi . calcFunc-totient )
( \\mu . calcFunc-moebius )))
+(put 'tex 'math-special-function-table
+ '((calcFunc-sum . (math-compose-tex-sum "\\sum"))
+ (calcFunc-prod . (math-compose-tex-sum "\\prod"))
+ (intv . math-compose-tex-intv)))
+
(put 'tex 'math-variable-table
'(
;; The Greek letters
@@ -458,8 +548,112 @@
( \\sum . (math-parse-tex-sum calcFunc-sum) )
( \\prod . (math-parse-tex-sum calcFunc-prod) )))
+(put 'tex 'math-punc-table
+ '((?\{ . ?\()
+ (?\} . ?\))
+ (?\& . ?\,)))
+
(put 'tex 'math-complex-format 'i)
+(put 'tex 'math-input-filter 'math-tex-input-filter)
+
+(put 'tex 'math-matrix-formatter
+ (function
+ (lambda (a)
+ (if (and (integerp calc-language-option)
+ (or (= calc-language-option 0)
+ (> calc-language-option 1)
+ (< calc-language-option -1)))
+ (append '(vleft 0 "\\matrix{")
+ (math-compose-tex-matrix (cdr a))
+ '("}"))
+ (append '(horiz "\\matrix{ ")
+ (math-compose-tex-matrix (cdr a))
+ '(" }"))))))
+
+(put 'tex 'math-var-formatter 'math-compose-tex-var)
+
+(put 'tex 'math-func-formatter 'math-compose-tex-func)
+
+(put 'tex 'math-dots "\\ldots")
+
+(put 'tex 'math-big-parens '("\\left( " . " \\right)"))
+
+(put 'tex 'math-evalto '("\\evalto " . " \\to "))
+
+(defconst math-tex-ignore-words
+ '( ("\\hbox") ("\\mbox") ("\\text") ("\\left") ("\\right")
+ ("\\,") ("\\>") ("\\:") ("\\;") ("\\!") ("\\ ")
+ ("\\quad") ("\\qquad") ("\\hfil") ("\\hfill")
+ ("\\displaystyle") ("\\textstyle") ("\\dsize") ("\\tsize")
+ ("\\scriptstyle") ("\\scriptscriptstyle") ("\\ssize") ("\\sssize")
+ ("\\rm") ("\\bf") ("\\it") ("\\sl")
+ ("\\roman") ("\\bold") ("\\italic") ("\\slanted")
+ ("\\cal") ("\\mit") ("\\Cal") ("\\Bbb") ("\\frak") ("\\goth")
+ ("\\evalto")
+ ("\\matrix" mat) ("\\bmatrix" mat) ("\\pmatrix" mat)
+ ("\\begin" begenv)
+ ("\\cr" punc ";") ("\\\\" punc ";") ("\\*" punc "*")
+ ("\\{" punc "[") ("\\}" punc "]")))
+
+(defconst math-latex-ignore-words
+ (append math-tex-ignore-words
+ '(("\\begin" begenv))))
+
+(put 'tex 'math-lang-read-symbol
+ '((?\\
+ (< math-exp-pos (1- (length math-exp-str)))
+ (progn
+ (or (string-match "\\\\hbox *{\\([a-zA-Z0-9]+\\)}"
+ math-exp-str math-exp-pos)
+ (string-match "\\(\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)\\)"
+ math-exp-str math-exp-pos))
+ (setq math-exp-token 'symbol
+ math-exp-pos (match-end 0)
+ math-expr-data (math-restore-dashes
+ (math-match-substring math-exp-str 1)))
+ (let ((code (assoc math-expr-data math-latex-ignore-words)))
+ (cond ((null code))
+ ((null (cdr code))
+ (math-read-token))
+ ((eq (nth 1 code) 'punc)
+ (setq math-exp-token 'punc
+ math-expr-data (nth 2 code)))
+ ((and (eq (nth 1 code) 'mat)
+ (string-match " *{" math-exp-str math-exp-pos))
+ (setq math-exp-pos (match-end 0)
+ math-exp-token 'punc
+ math-expr-data "[")
+ (let ((right (string-match "}" math-exp-str math-exp-pos)))
+ (and right
+ (setq math-exp-str (copy-sequence math-exp-str))
+ (aset math-exp-str right ?\]))))))))))
+
+(defun math-compose-tex-matrix (a &optional ltx)
+ (if (cdr a)
+ (cons (append (math-compose-vector (cdr (car a)) " & " 0)
+ (if ltx '(" \\\\ ") '(" \\cr ")))
+ (math-compose-tex-matrix (cdr a) ltx))
+ (list (math-compose-vector (cdr (car a)) " & " 0))))
+
+(defun math-compose-tex-sum (a fn)
+ (cond
+ ((nth 4 a)
+ (list 'horiz (nth 1 fn)
+ "_{" (math-compose-expr (nth 2 a) 0)
+ "=" (math-compose-expr (nth 3 a) 0)
+ "}^{" (math-compose-expr (nth 4 a) 0)
+ "}{" (math-compose-expr (nth 1 a) 0) "}"))
+ ((nth 3 a)
+ (list 'horiz (nth 1 fn)
+ "_{" (math-compose-expr (nth 2 a) 0)
+ "=" (math-compose-expr (nth 3 a) 0)
+ "}{" (math-compose-expr (nth 1 a) 0) "}"))
+ (t
+ (list 'horiz (nth 1 fn)
+ "_{" (math-compose-expr (nth 2 a) 0)
+ "}{" (math-compose-expr (nth 1 a) 0) "}"))))
+
(defun math-parse-tex-sum (f val)
(let (low high save)
(or (equal math-expr-data "_") (throw 'syntax "Expected `_'"))
@@ -480,7 +674,59 @@
(setq str (concat (substring str 0 (1+ (match-beginning 0)))
(substring str (1- (match-end 0))))))
str)
-(put 'tex 'math-input-filter 'math-tex-input-filter)
+
+;(defun math-tex-print-sqrt (a)
+; (list 'horiz
+; "\\sqrt{"
+; (math-compose-expr (nth 1 a) 0)
+; "}"))
+
+(defun math-compose-tex-intv (a)
+ (list 'horiz
+ (if (memq (nth 1 a) '(0 1)) "(" "[")
+ (math-compose-expr (nth 2 a) 0)
+ " \\ldots "
+ (math-compose-expr (nth 3 a) 0)
+ (if (memq (nth 1 a) '(0 2)) ")" "]")))
+
+(defun math-compose-tex-var (a prec)
+ (if (and calc-language-option
+ (not (= calc-language-option 0))
+ (string-match "\\`[a-zA-Z][a-zA-Z0-9]+\\'"
+ (symbol-name (nth 1 a))))
+ (if (eq calc-language 'latex)
+ (format "\\text{%s}" (symbol-name (nth 1 a)))
+ (format "\\hbox{%s}" (symbol-name (nth 1 a))))
+ (math-compose-var a)))
+
+(defun math-compose-tex-func (func a)
+ (let (left right)
+ (if (and calc-language-option
+ (not (= calc-language-option 0))
+ (string-match "\\`[a-zA-Z][a-zA-Z0-9]+\\'" func))
+ (if (< (prefix-numeric-value calc-language-option) 0)
+ (setq func (format "\\%s" func))
+ (setq func (if (eq calc-language 'latex)
+ (format "\\text{%s}" func)
+ (format "\\hbox{%s}" func)))))
+ (cond ((or (> (length a) 2)
+ (not (math-tex-expr-is-flat (nth 1 a))))
+ (setq left "\\left( "
+ right " \\right)"))
+ ((and (eq (aref func 0) ?\\)
+ (not (or
+ (string-match "\\hbox{" func)
+ (string-match "\\text{" func)))
+ (= (length a) 2)
+ (or (Math-realp (nth 1 a))
+ (memq (car (nth 1 a)) '(var *))))
+ (setq left "{" right "}"))
+ (t (setq left calc-function-open
+ right calc-function-close)))
+ (list 'horiz func
+ left
+ (math-compose-vector (cdr a) ", " 0)
+ right)))
(put 'latex 'math-oper-table
(append (get 'tex 'math-oper-table)
@@ -496,7 +742,7 @@
( "\\Vec" calcFunc-VEC -1 950 )
( "\\dddot" calcFunc-dddot -1 950 )
( "\\ddddot" calcFunc-ddddot -1 950 )
- ( "\div" / 170 171 )
+ ( "\\div" / 170 171 )
( "\\le" calcFunc-leq 160 161 )
( "\\leqq" calcFunc-leq 160 161 )
( "\\leqsland" calcFunc-leq 160 161 )
@@ -534,15 +780,93 @@
( \\mu . calcFunc-moebius ))))
(put 'latex 'math-special-function-table
- '((/ . (math-latex-print-frac "\\frac"))
- (calcFunc-choose . (math-latex-print-frac "\\binom"))))
+ '((/ . (math-compose-latex-frac "\\frac"))
+ (calcFunc-choose . (math-compose-latex-frac "\\binom"))
+ (calcFunc-sum . (math-compose-tex-sum "\\sum"))
+ (calcFunc-prod . (math-compose-tex-sum "\\prod"))
+ (intv . math-compose-tex-intv)))
(put 'latex 'math-variable-table
(get 'tex 'math-variable-table))
-(put 'latex 'math-complex-format 'i)
+(put 'latex 'math-punc-table
+ '((?\{ . ?\()
+ (?\} . ?\))
+ (?\& . ?\,)))
+(put 'latex 'math-complex-format 'i)
+(put 'latex 'math-matrix-formatter
+ (function
+ (lambda (a)
+ (if (and (integerp calc-language-option)
+ (or (= calc-language-option 0)
+ (> calc-language-option 1)
+ (< calc-language-option -1)))
+ (append '(vleft 0 "\\begin{pmatrix}")
+ (math-compose-tex-matrix (cdr a) t)
+ '("\\end{pmatrix}"))
+ (append '(horiz "\\begin{pmatrix} ")
+ (math-compose-tex-matrix (cdr a) t)
+ '(" \\end{pmatrix}"))))))
+
+(put 'latex 'math-var-formatter 'math-compose-tex-var)
+
+(put 'latex 'math-func-formatter 'math-compose-tex-func)
+
+(put 'latex 'math-dots "\\ldots")
+
+(put 'latex 'math-big-parens '("\\left( " . " \\right)"))
+
+(put 'latex 'math-evalto '("\\evalto " . " \\to "))
+
+(put 'latex 'math-lang-read-symbol
+ '((?\\
+ (< math-exp-pos (1- (length math-exp-str)))
+ (progn
+ (or (string-match "\\\\hbox *{\\([a-zA-Z0-9]+\\)}"
+ math-exp-str math-exp-pos)
+ (string-match "\\\\text *{\\([a-zA-Z0-9]+\\)}"
+ math-exp-str math-exp-pos)
+ (string-match "\\(\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)\\)"
+ math-exp-str math-exp-pos))
+ (setq math-exp-token 'symbol
+ math-exp-pos (match-end 0)
+ math-expr-data (math-restore-dashes
+ (math-match-substring math-exp-str 1)))
+ (let ((code (assoc math-expr-data math-tex-ignore-words))
+ envname)
+ (cond ((null code))
+ ((null (cdr code))
+ (math-read-token))
+ ((eq (nth 1 code) 'punc)
+ (setq math-exp-token 'punc
+ math-expr-data (nth 2 code)))
+ ((and (eq (nth 1 code) 'begenv)
+ (string-match " *{\\([^}]*\\)}" math-exp-str math-exp-pos))
+ (setq math-exp-pos (match-end 0)
+ envname (match-string 1 math-exp-str)
+ math-exp-token 'punc
+ math-expr-data "[")
+ (cond ((or (string= envname "matrix")
+ (string= envname "bmatrix")
+ (string= envname "smallmatrix")
+ (string= envname "pmatrix"))
+ (if (string-match (concat "\\\\end{" envname "}")
+ math-exp-str math-exp-pos)
+ (setq math-exp-str
+ (replace-match "]" t t math-exp-str))
+ (error "%s" (concat "No closing \\end{" envname "}"))))))
+ ((and (eq (nth 1 code) 'mat)
+ (string-match " *{" math-exp-str math-exp-pos))
+ (setq math-exp-pos (match-end 0)
+ math-exp-token 'punc
+ math-expr-data "[")
+ (let ((right (string-match "}" math-exp-str math-exp-pos)))
+ (and right
+ (setq math-exp-str (copy-sequence math-exp-str))
+ (aset math-exp-str right ?\]))))))))))
+
(defun math-latex-parse-frac (f val)
(let (numer denom)
(setq numer (car (math-read-expr-list)))
@@ -560,7 +884,7 @@
(setq second (math-read-factor))
(list (nth 2 f) first second)))
-(defun math-latex-print-frac (a fn)
+(defun math-compose-latex-frac (a fn)
(list 'horiz (nth 1 fn) "{" (math-compose-expr (nth 1 a) -1)
"}{"
(math-compose-expr (nth 2 a) -1)
@@ -575,9 +899,7 @@
(message "Eqn language mode")))
(put 'eqn 'math-oper-table
- '( ( "u+" ident -1 1000 )
- ( "u-" neg -1 1000 )
- ( "prime" (math-parse-eqn-prime) 950 -1 )
+ '( ( "prime" (math-parse-eqn-prime) 950 -1 )
( "prime" calcFunc-Prime 950 -1 )
( "dot" calcFunc-dot 950 -1 )
( "dotdot" calcFunc-dotdot 950 -1 )
@@ -599,6 +921,8 @@
( "right ceil" closing 0 -1 )
( "+-" sdev 300 300 )
( "!" calcFunc-fact 210 -1 )
+ ( "u+" ident -1 197 )
+ ( "u-" neg -1 197 )
( "times" * 191 190 )
( "*" * 191 190 )
( "2x" * 191 190 )
@@ -640,11 +964,162 @@
( mu . calcFunc-moebius )
( matrix . (math-parse-eqn-matrix) )))
+(put 'eqn 'math-special-function-table
+ '((intv . math-compose-eqn-intv)))
+
+(put 'eqn 'math-punc-table
+ '((?\{ . ?\()
+ (?\} . ?\))))
+
(put 'eqn 'math-variable-table
'( ( inf . var-uinf )))
(put 'eqn 'math-complex-format 'i)
+(put 'eqn 'math-big-parens '("{left ( " . " right )}"))
+
+(put 'eqn 'math-evalto '("evalto " . " -> "))
+
+(put 'eqn 'math-matrix-formatter
+ (function
+ (lambda (a)
+ (append '(horiz "matrix { ")
+ (math-compose-eqn-matrix
+ (cdr (math-transpose a)))
+ '("}")))))
+
+(put 'eqn 'math-var-formatter
+ (function
+ (lambda (a prec)
+ (let (v)
+ (if (and math-compose-hash-args
+ (let ((p calc-arg-values))
+ (setq v 1)
+ (while (and p (not (equal (car p) a)))
+ (setq p (and (eq math-compose-hash-args t) (cdr p))
+ v (1+ v)))
+ p))
+ (if (eq math-compose-hash-args 1)
+ "#"
+ (format "#%d" v))
+ (if (string-match ".'\\'" (symbol-name (nth 2 a)))
+ (math-compose-expr
+ (list 'calcFunc-Prime
+ (list
+ 'var
+ (intern (substring (symbol-name (nth 1 a)) 0 -1))
+ (intern (substring (symbol-name (nth 2 a)) 0 -1))))
+ prec)
+ (symbol-name (nth 1 a))))))))
+
+(defconst math-eqn-special-funcs
+ '( calcFunc-log
+ calcFunc-ln calcFunc-exp
+ calcFunc-sin calcFunc-cos calcFunc-tan
+ calcFunc-sec calcFunc-csc calcFunc-cot
+ calcFunc-sinh calcFunc-cosh calcFunc-tanh
+ calcFunc-sech calcFunc-csch calcFunc-coth
+ calcFunc-arcsin calcFunc-arccos calcFunc-arctan
+ calcFunc-arcsinh calcFunc-arccosh calcFunc-arctanh))
+
+(put 'eqn 'math-func-formatter
+ (function
+ (lambda (func a)
+ (let (left right)
+ (if (string-match "[^']'+\\'" func)
+ (let ((n (- (length func) (match-beginning 0) 1)))
+ (setq func (substring func 0 (- n)))
+ (while (>= (setq n (1- n)) 0)
+ (setq func (concat func " prime")))))
+ (cond ((or (> (length a) 2)
+ (not (math-tex-expr-is-flat (nth 1 a))))
+ (setq left "{left ( "
+ right " right )}"))
+
+ ((and
+ (memq (car a) math-eqn-special-funcs)
+ (= (length a) 2)
+ (or (Math-realp (nth 1 a))
+ (memq (car (nth 1 a)) '(var *))))
+ (setq left "~{" right "}"))
+ (t
+ (setq left " ( "
+ right " )")))
+ (list 'horiz func left
+ (math-compose-vector (cdr a) " , " 0)
+ right)))))
+
+(put 'eqn 'math-lang-read-symbol
+ '((?\"
+ (string-match "\\(\"\\([^\"\\]\\|\\\\.\\)*\\)\\(\"\\|\\'\\)"
+ math-exp-str math-exp-pos)
+ (progn
+ (setq math-exp-str (copy-sequence math-exp-str))
+ (aset math-exp-str (match-beginning 1) ?\{)
+ (if (< (match-end 1) (length math-exp-str))
+ (aset math-exp-str (match-end 1) ?\}))
+ (math-read-token)))))
+
+(defconst math-eqn-ignore-words
+ '( ("roman") ("bold") ("italic") ("mark") ("lineup") ("evalto")
+ ("left" ("floor") ("ceil"))
+ ("right" ("floor") ("ceil"))
+ ("arc" ("sin") ("cos") ("tan") ("sinh") ("cosh") ("tanh"))
+ ("size" n) ("font" n) ("fwd" n) ("back" n) ("up" n) ("down" n)
+ ("above" punc ",")))
+
+(put 'eqn 'math-lang-adjust-words
+ (function
+ (lambda ()
+ (let ((code (assoc math-expr-data math-eqn-ignore-words)))
+ (cond ((null code))
+ ((null (cdr code))
+ (math-read-token))
+ ((consp (nth 1 code))
+ (math-read-token)
+ (if (assoc math-expr-data (cdr code))
+ (setq math-expr-data (format "%s %s"
+ (car code) math-expr-data))))
+ ((eq (nth 1 code) 'punc)
+ (setq math-exp-token 'punc
+ math-expr-data (nth 2 code)))
+ (t
+ (math-read-token)
+ (math-read-token)))))))
+
+(put 'eqn 'math-lang-read
+ '((eq (string-match "->\\|<-\\|+-\\|\\\\dots\\|~\\|\\^"
+ math-exp-str math-exp-pos)
+ math-exp-pos)
+ (progn
+ (setq math-exp-token 'punc
+ math-expr-data (math-match-substring math-exp-str 0)
+ math-exp-pos (match-end 0))
+ (and (eq (string-match "\\\\dots\\." math-exp-str math-exp-pos)
+ math-exp-pos)
+ (setq math-exp-pos (match-end 0)))
+ (if (memq (aref math-expr-data 0) '(?~ ?^))
+ (math-read-token)))))
+
+
+(defun math-compose-eqn-matrix (a)
+ (if a
+ (cons
+ (cond ((eq calc-matrix-just 'right) "rcol ")
+ ((eq calc-matrix-just 'center) "ccol ")
+ (t "lcol "))
+ (cons
+ (list 'break math-compose-level)
+ (cons
+ "{ "
+ (cons
+ (let ((math-compose-level (1+ math-compose-level)))
+ (math-compose-vector (cdr (car a)) " above " 1000))
+ (cons
+ " } "
+ (math-compose-eqn-matrix (cdr a)))))))
+ nil))
+
(defun math-parse-eqn-matrix (f sym)
(let ((vec nil))
(while (assoc math-expr-data '(("ccol") ("lcol") ("rcol")))
@@ -680,6 +1155,634 @@
(intern (concat (symbol-name (nth 2 x)) "'"))))
(list 'calcFunc-Prime x)))
+(defun math-compose-eqn-intv (a)
+ (list 'horiz
+ (if (memq (nth 1 a) '(0 1)) "(" "[")
+ (math-compose-expr (nth 2 a) 0)
+ " ... "
+ (math-compose-expr (nth 3 a) 0)
+ (if (memq (nth 1 a) '(0 2)) ")" "]")))
+
+
+;;; Yacas
+
+(defun calc-yacas-language ()
+ "Change the Calc language to be Yacas-like."
+ (interactive)
+ (calc-wrapper
+ (calc-set-language 'yacas)
+ (message "`Yacas' language mode")))
+
+(put 'yacas 'math-vector-brackets "{}")
+
+(put 'yacas 'math-complex-format 'I)
+
+(add-to-list 'calc-lang-brackets-are-subscripts 'yacas)
+
+(put 'yacas 'math-variable-table
+ '(( Infinity . var-inf)
+ ( Infinity . var-uinf)
+ ( Undefined . var-nan)
+ ( Pi . var-pi)
+ ( E . var-e) ;; Not really in Yacas
+ ( GoldenRatio . var-phi)
+ ( Gamma . var-gamma)))
+
+(put 'yacas 'math-parse-table
+ '((("Deriv(" 0 ")" 0)
+ calcFunc-deriv (var ArgB var-ArgB) (var ArgA var-ArgA))
+ (("D(" 0 ")" 0)
+ calcFunc-deriv (var ArgB var-ArgB) (var ArgA var-ArgA))
+ (("Integrate(" 0 ")" 0)
+ calcFunc-integ (var ArgB var-ArgB)(var ArgA var-ArgA))
+ (("Integrate(" 0 "," 0 "," 0 ")" 0)
+ calcFunc-integ (var ArgD var-ArgD) (var ArgA var-ArgA)
+ (var ArgB var-ArgB) (var ArgC var-ArgC))
+ (("Subst(" 0 "," 0 ")" 0)
+ calcFunc-subst (var ArgC var-ArgC) (var ArgA var-ArgA)
+ (var ArgB var-ArgB))
+ (("Taylor(" 0 "," 0 "," 0 ")" 0)
+ calcFunc-taylor (var ArgD var-ArgD)
+ (calcFunc-eq (var ArgA var-ArgA) (var ArgB var-ArgB))
+ (var ArgC var-ArgC))))
+
+(put 'yacas 'math-oper-table
+ '(("+" + 30 30)
+ ("-" - 30 60)
+ ("*" * 60 60)
+ ("/" / 70 70)
+ ("u-" neg -1 60)
+ ("^" ^ 80 80)
+ ("u+" ident -1 30)
+ ("<<" calcFunc-lsh 80 80)
+ (">>" calcFunc-rsh 80 80)
+ ("!" calcFunc-fact 80 -1)
+ ("!!" calcFunc-dfact 80 -1)
+ ("X" calcFunc-cross 70 70)
+ ("=" calcFunc-eq 10 10)
+ ("!=" calcFunc-neq 10 10)
+ ("<" calcFunc-lt 10 10)
+ (">" calcFunc-gt 10 10)
+ ("<=" calcFunc-leq 10 10)
+ (">=" calcFunc-geq 10 10)
+ ("And" calcFunc-land 5 5)
+ ("Or" calcFunc-or 4 4)
+ ("Not" calcFunc-lnot -1 3)
+ (":=" calcFunc-assign 1 1)))
+
+(put 'yacas 'math-function-table
+ '(( Div . calcFunc-idiv)
+ ( Mod . calcFunc-mod)
+ ( Abs . calcFunc-abs)
+ ( Sign . calcFunc-sign)
+ ( Sqrt . calcFunc-sqrt)
+ ( Max . calcFunc-max)
+ ( Min . calcFunc-min)
+ ( Floor . calcFunc-floor)
+ ( Ceil . calcFunc-ceil)
+ ( Round . calcFunc-round)
+ ( Conjugate . calcFunc-conj)
+ ( Arg . calcFunc-arg)
+ ( Re . calcFunc-re)
+ ( Im . calcFunc-im)
+ ( Rationalize . calcFunc-pfrac)
+ ( Sin . calcFunc-sin)
+ ( Cos . calcFunc-cos)
+ ( Tan . calcFunc-tan)
+ ( Sec . calcFunc-sec)
+ ( Csc . calcFunc-csc)
+ ( Cot . calcFunc-cot)
+ ( ArcSin . calcFunc-arcsin)
+ ( ArcCos . calcFunc-arccos)
+ ( ArcTan . calcFunc-arctan)
+ ( Sinh . calcFunc-sinh)
+ ( Cosh . calcFunc-cosh)
+ ( Tanh . calcFunc-tanh)
+ ( Sech . calcFunc-sech)
+ ( Csch . calcFunc-csch)
+ ( Coth . calcFunc-coth)
+ ( ArcSinh . calcFunc-arcsinh)
+ ( ArcCosh . calcFunc-arccosh)
+ ( ArcTanh . calcFunc-arctanh)
+ ( Ln . calcFunc-ln)
+ ( Exp . calcFunc-exp)
+ ( Gamma . calcFunc-gamma)
+ ( Gcd . calcFunc-gcd)
+ ( Lcm . calcFunc-lcm)
+ ( Bin . calcFunc-choose)
+ ( Bernoulli . calcFunc-bern)
+ ( Euler . calcFunc-euler)
+ ( StirlingNumber1 . calcFunc-stir1)
+ ( StirlingNumber2 . calcFunc-stir2)
+ ( IsPrime . calcFunc-prime)
+ ( Factors . calcFunc-prfac)
+ ( NextPrime . calcFunc-nextprime)
+ ( Moebius . calcFunc-moebius)
+ ( Random . calcFunc-random)
+ ( Concat . calcFunc-vconcat)
+ ( Head . calcFunc-head)
+ ( Tail . calcFunc-tail)
+ ( Length . calcFunc-vlen)
+ ( Reverse . calcFunc-rev)
+ ( CrossProduct . calcFunc-cross)
+ ( Dot . calcFunc-mul)
+ ( DiagonalMatrix . calcFunc-diag)
+ ( Transpose . calcFunc-trn)
+ ( Inverse . calcFunc-inv)
+ ( Determinant . calcFunc-det)
+ ( Trace . calcFunc-tr)
+ ( RemoveDuplicates . calcFunc-rdup)
+ ( Union . calcFunc-vunion)
+ ( Intersection . calcFunc-vint)
+ ( Difference . calcFunc-vdiff)
+ ( Apply . calcFunc-apply)
+ ( Map . calcFunc-map)
+ ( Simplify . calcFunc-simplify)
+ ( ExpandBrackets . calcFunc-expand)
+ ( Solve . calcFunc-solve)
+ ( Degree . calcFunc-pdeg)
+ ( If . calcFunc-if)
+ ( Contains . (math-lang-switch-args calcFunc-in))
+ ( Sum . (math-yacas-parse-Sum calcFunc-sum))
+ ( Factorize . (math-yacas-parse-Sum calcFunc-prod))))
+
+(put 'yacas 'math-special-function-table
+ '(( calcFunc-sum . (math-yacas-compose-sum "Sum"))
+ ( calcFunc-prod . (math-yacas-compose-sum "Factorize"))
+ ( calcFunc-deriv . (math-yacas-compose-deriv "Deriv"))
+ ( calcFunc-integ . (math-yacas-compose-deriv "Integrate"))
+ ( calcFunc-taylor . math-yacas-compose-taylor)
+ ( calcFunc-in . (math-lang-compose-switch-args "Contains"))))
+
+(put 'yacas 'math-compose-subscr
+ (function
+ (lambda (a)
+ (let ((args (cdr (cdr a))))
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "["
+ (math-compose-vector args ", " 0)
+ "]")))))
+
+(defun math-yacas-parse-Sum (f val)
+ "Read in the arguments to \"Sum\" in Calc's Yacas mode."
+ (let ((args (math-read-expr-list)))
+ (math-read-token)
+ (list (nth 2 f)
+ (nth 3 args)
+ (nth 0 args)
+ (nth 1 args)
+ (nth 2 args))))
+
+(defun math-yacas-compose-sum (a fn)
+ "Compose the \"Sum\" function in Calc's Yacas mode."
+ (list 'horiz
+ (nth 1 fn)
+ "("
+ (math-compose-expr (nth 2 a) -1)
+ ","
+ (math-compose-expr (nth 3 a) -1)
+ ","
+ (math-compose-expr (nth 4 a) -1)
+ ","
+ (math-compose-expr (nth 1 a) -1)
+ ")"))
+
+(defun math-yacas-compose-deriv (a fn)
+ "Compose the \"Deriv\" function in Calc's Yacas mode."
+ (list 'horiz
+ (nth 1 fn)
+ "("
+ (math-compose-expr (nth 2 a) -1)
+ (if (not (nth 3 a))
+ ")"
+ (concat
+ ","
+ (math-compose-expr (nth 3 a) -1)
+ ","
+ (math-compose-expr (nth 4 a) -1)
+ ")"))
+ " "
+ (math-compose-expr (nth 1 a) -1)))
+
+(defun math-yacas-compose-taylor (a)
+ "Compose the \"Taylor\" function in Calc's Yacas mode."
+ (list 'horiz
+ "Taylor("
+ (if (eq (car-safe (nth 2 a)) 'calcFunc-eq)
+ (concat (math-compose-expr (nth 1 (nth 2 a)) -1)
+ ","
+ (math-compose-expr (nth 2 (nth 2 a)) -1))
+ (concat (math-compose-expr (nth 2 a) -1) ",0"))
+ ","
+ (math-compose-expr (nth 3 a) -1)
+ ") "
+ (math-compose-expr (nth 1 a) -1)))
+
+
+;;; Maxima
+
+(defun calc-maxima-language ()
+ "Change the Calc language to be Maxima-like."
+ (interactive)
+ (calc-wrapper
+ (calc-set-language 'maxima)
+ (message "`Maxima' language mode")))
+
+(put 'maxima 'math-oper-table
+ '(("+" + 100 100)
+ ("-" - 100 134)
+ ("*" * 120 120)
+ ("." * 130 129)
+ ("/" / 120 120)
+ ("u-" neg -1 180)
+ ("u+" ident -1 180)
+ ("^" ^ 140 139)
+ ("**" ^ 140 139)
+ ("!" calcFunc-fact 160 -1)
+ ("!!" calcFunc-dfact 160 -1)
+ ("=" calcFunc-eq 80 80)
+ ("#" calcFunc-neq 80 80)
+ ("<" calcFunc-lt 80 80)
+ (">" calcFunc-gt 80 80)
+ ("<=" calcFunc-leq 80 80)
+ (">=" calcFunc-geq 80 80)
+ ("and" calcFunc-land 65 65)
+ ("or" calcFunc-or 60 60)
+ ("not" calcFunc-lnot -1 70)
+ (":" calcFunc-assign 180 20)))
+
+
+(put 'maxima 'math-function-table
+ '(( matrix . vec)
+ ( abs . calcFunc-abs)
+ ( cabs . calcFunc-abs)
+ ( signum . calcFunc-sign)
+ ( floor . calcFunc-floor)
+ ( entier . calcFunc-floor)
+ ( fix . calcFunc-floor)
+ ( conjugate . calcFunc-conj )
+ ( carg . calcFunc-arg)
+ ( realpart . calcFunc-re)
+ ( imagpart . calcFunc-im)
+ ( rationalize . calcFunc-pfrac)
+ ( asin . calcFunc-arcsin)
+ ( acos . calcFunc-arccos)
+ ( atan . calcFunc-arctan)
+ ( atan2 . calcFunc-arctan2)
+ ( asinh . calcFunc-arcsinh)
+ ( acosh . calcFunc-arccosh)
+ ( atanh . calcFunc-arctanh)
+ ( log . calcFunc-ln)
+ ( plog . calcFunc-ln)
+ ( bessel_j . calcFunc-besJ)
+ ( bessel_y . calcFunc-besY)
+ ( factorial . calcFunc-fact)
+ ( binomial . calcFunc-choose)
+ ( primep . calcFunc-prime)
+ ( next_prime . calcFunc-nextprime)
+ ( prev_prime . calcFunc-prevprime)
+ ( append . calcFunc-vconcat)
+ ( rest . calcFunc-tail)
+ ( reverse . calcFunc-rev)
+ ( innerproduct . calcFunc-mul)
+ ( inprod . calcFunc-mul)
+ ( row . calcFunc-mrow)
+ ( columnvector . calcFunc-mcol)
+ ( covect . calcFunc-mcol)
+ ( transpose . calcFunc-trn)
+ ( invert . calcFunc-inv)
+ ( determinant . calcFunc-det)
+ ( mattrace . calcFunc-tr)
+ ( member . calcFunc-in)
+ ( lmax . calcFunc-vmax)
+ ( lmin . calcFunc-vmin)
+ ( distrib . calcFunc-expand)
+ ( partfrac . calcFunc-apart)
+ ( rat . calcFunc-nrat)
+ ( product . calcFunc-prod)
+ ( diff . calcFunc-deriv)
+ ( integrate . calcFunc-integ)
+ ( quotient . calcFunc-pdiv)
+ ( remainder . calcFunc-prem)
+ ( divide . calcFunc-pdivrem)
+ ( equal . calcFunc-eq)
+ ( notequal . calcFunc-neq)
+ ( rhs . calcFunc-rmeq)
+ ( subst . (math-maxima-parse-subst))
+ ( substitute . (math-maxima-parse-subst))
+ ( taylor . (math-maxima-parse-taylor))))
+
+(defun math-maxima-parse-subst (f val)
+ "Read in the arguments to \"subst\" in Calc's Maxima mode."
+ (let ((args (math-read-expr-list)))
+ (math-read-token)
+ (list 'calcFunc-subst
+ (nth 1 args)
+ (nth 2 args)
+ (nth 0 args))))
+
+(defun math-maxima-parse-taylor (f val)
+ "Read in the arguments to \"taylor\" in Calc's Maxima mode."
+ (let ((args (math-read-expr-list)))
+ (math-read-token)
+ (list 'calcFunc-taylor
+ (nth 0 args)
+ (list 'calcFunc-eq
+ (nth 1 args)
+ (nth 2 args))
+ (nth 3 args))))
+
+(put 'maxima 'math-parse-table
+ '((("if" 0 "then" 0 "else" 0)
+ calcFunc-if
+ (var ArgA var-ArgA)
+ (var ArgB var-ArgB)
+ (var ArgC var-ArgC))))
+
+(put 'maxima 'math-special-function-table
+ '(( calcFunc-taylor . math-maxima-compose-taylor)
+ ( calcFunc-subst . math-maxima-compose-subst)
+ ( calcFunc-if . math-maxima-compose-if)))
+
+(defun math-maxima-compose-taylor (a)
+ "Compose the \"taylor\" function in Calc's Maxima mode."
+ (list 'horiz
+ "taylor("
+ (math-compose-expr (nth 1 a) -1)
+ ","
+ (if (eq (car-safe (nth 2 a)) 'calcFunc-eq)
+ (concat (math-compose-expr (nth 1 (nth 2 a)) -1)
+ ","
+ (math-compose-expr (nth 2 (nth 2 a)) -1))
+ (concat (math-compose-expr (nth 2 a) -1) ",0"))
+ ","
+ (math-compose-expr (nth 3 a) -1)
+ ")"))
+
+(defun math-maxima-compose-subst (a)
+ "Compose the \"subst\" function in Calc's Maxima mode."
+ (list 'horiz
+ "substitute("
+ (math-compose-expr (nth 2 a) -1)
+ ","
+ (math-compose-expr (nth 3 a) -1)
+ ","
+ (math-compose-expr (nth 1 a) -1)
+ ")"))
+
+(defun math-maxima-compose-if (a)
+ "Compose the \"if\" function in Calc's Maxima mode."
+ (list 'horiz
+ "if "
+ (math-compose-expr (nth 1 a) -1)
+ " then "
+ (math-compose-expr (nth 2 a) -1)
+ " else "
+ (math-compose-expr (nth 3 a) -1)))
+
+(put 'maxima 'math-variable-table
+ '(( infinity . var-uinf)
+ ( %pi . var-pi)
+ ( %e . var-e)
+ ( %i . var-i)
+ ( %phi . var-phi)
+ ( %gamma . var-gamma)))
+
+(put 'maxima 'math-complex-format '%i)
+
+(add-to-list 'calc-lang-allow-underscores 'maxima)
+
+(add-to-list 'calc-lang-allow-percentsigns 'maxima)
+
+(add-to-list 'calc-lang-brackets-are-subscripts 'maxima)
+
+(put 'maxima 'math-compose-subscr
+ (function
+ (lambda (a)
+ (let ((args (cdr (cdr a))))
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "["
+ (math-compose-vector args ", " 0)
+ "]")))))
+
+(put 'maxima 'math-matrix-formatter
+ (function
+ (lambda (a)
+ (list 'horiz
+ "matrix("
+ (math-compose-vector (cdr a)
+ (concat math-comp-comma " ")
+ math-comp-vector-prec)
+ ")"))))
+
+
+;;; Giac
+
+(defun calc-giac-language ()
+ "Change the Calc language to be Giac-like."
+ (interactive)
+ (calc-wrapper
+ (calc-set-language 'giac)
+ (message "`Giac' language mode")))
+
+(put 'giac 'math-oper-table
+ '( ( "[" (math-read-giac-subscr) 250 -1 )
+ ( "+" + 180 181 )
+ ( "-" - 180 181 )
+ ( "/" / 191 192 )
+ ( "*" * 191 192 )
+ ( "^" ^ 201 200 )
+ ( "u+" ident -1 197 )
+ ( "u-" neg -1 197 )
+ ( "!" calcFunc-fact 210 -1 )
+ ( ".." (math-read-maple-dots) 165 165 )
+ ( "\\dots" (math-read-maple-dots) 165 165 )
+ ( "intersect" calcFunc-vint 191 192 )
+ ( "union" calcFunc-vunion 180 181 )
+ ( "minus" calcFunc-vdiff 180 181 )
+ ( "<" calcFunc-lt 160 160 )
+ ( ">" calcFunc-gt 160 160 )
+ ( "<=" calcFunc-leq 160 160 )
+ ( ">=" calcFunc-geq 160 160 )
+ ( "=" calcFunc-eq 160 160 )
+ ( "==" calcFunc-eq 160 160 )
+ ( "!=" calcFunc-neq 160 160 )
+ ( "and" calcFunc-land 110 111 )
+ ( "or" calcFunc-lor 100 101 )
+ ( "&&" calcFunc-land 110 111 )
+ ( "||" calcFunc-lor 100 101 )
+ ( "not" calcFunc-lnot -1 121 )
+ ( ":=" calcFunc-assign 51 50 )))
+
+
+(put 'giac 'math-function-table
+ '(( rdiv . calcFunc-div)
+ ( iquo . calcFunc-idiv)
+ ( irem . calcFunc-mod)
+ ( remain . calcFunc-mod)
+ ( floor . calcFunc-floor)
+ ( iPart . calcFunc-floor)
+ ( ceil . calcFunc-ceil)
+ ( ceiling . calcFunc-ceil)
+ ( re . calcFunc-re)
+ ( real . calcFunc-re)
+ ( im . calcFunc-im)
+ ( imag . calcFunc-im)
+ ( float2rational . calcFunc-pfrac)
+ ( exact . calcFunc-pfrac)
+ ( evalf . calcFunc-pfloat)
+ ( bitand . calcFunc-and)
+ ( bitor . calcFunc-or)
+ ( bitxor . calcFunc-xor)
+ ( asin . calcFunc-arcsin)
+ ( acos . calcFunc-arccos)
+ ( atan . calcFunc-arctan)
+ ( asinh . calcFunc-arcsinh)
+ ( acosh . calcFunc-arccosh)
+ ( atanh . calcFunc-arctanh)
+ ( log . calcFunc-ln)
+ ( logb . calcFunc-log)
+ ( factorial . calcFunc-fact)
+ ( comb . calcFunc-choose)
+ ( binomial . calcFunc-choose)
+ ( nCr . calcFunc-choose)
+ ( perm . calcFunc-perm)
+ ( nPr . calcFunc-perm)
+ ( bernoulli . calcFunc-bern)
+ ( is_prime . calcFunc-prime)
+ ( isprime . calcFunc-prime)
+ ( isPrime . calcFunc-prime)
+ ( ifactors . calcFunc-prfac)
+ ( euler . calcFunc-totient)
+ ( phi . calcFunc-totient)
+ ( rand . calcFunc-random)
+ ( concat . calcFunc-vconcat)
+ ( augment . calcFunc-vconcat)
+ ( mid . calcFunc-subvec)
+ ( length . calcFunc-length)
+ ( size . calcFunc-length)
+ ( nops . calcFunc-length)
+ ( SortA . calcFunc-sort)
+ ( SortB . calcFunc-rsort)
+ ( revlist . calcFunc-rev)
+ ( cross . calcFunc-cross)
+ ( crossP . calcFunc-cross)
+ ( crossproduct . calcFunc-cross)
+ ( mul . calcFunc-mul)
+ ( dot . calcFunc-mul)
+ ( dotprod . calcFunc-mul)
+ ( dotP . calcFunc-mul)
+ ( scalar_product . calcFunc-mul)
+ ( scalar_Product . calcFunc-mul)
+ ( row . calcFunc-mrow)
+ ( col . calcFunc-mcol)
+ ( dim . calcFunc-mdims)
+ ( tran . calcFunc-trn)
+ ( transpose . calcFunc-trn)
+ ( lu . calcFunc-lud)
+ ( trace . calcFunc-tr)
+ ( member . calcFunc-in)
+ ( sum . calcFunc-vsum)
+ ( add . calcFunc-vsum)
+ ( product . calcFunc-vprod)
+ ( mean . calcFunc-vmean)
+ ( median . calcFunc-vmedian)
+ ( stddev . calcFunc-vsdev)
+ ( stddevp . calcFunc-vpsdev)
+ ( variance . calcFunc-vpvar)
+ ( map . calcFunc-map)
+ ( apply . calcFunc-map)
+ ( of . calcFunc-map)
+ ( zip . calcFunc-map)
+ ( expand . calcFunc-expand)
+ ( fdistrib . calcFunc-expand)
+ ( partfrac . calcFunc-apart)
+ ( ratnormal . calcFunc-nrat)
+ ( diff . calcFunc-deriv)
+ ( derive . calcFunc-deriv)
+ ( integrate . calcFunc-integ)
+ ( int . calcFunc-integ)
+ ( Int . calcFunc-integ)
+ ( romberg . calcFunc-ninteg)
+ ( nInt . calcFunc-ninteg)
+ ( lcoeff . calcFunc-plead)
+ ( content . calcFunc-pcont)
+ ( primpart . calcFunc-pprim)
+ ( quo . calcFunc-pdiv)
+ ( rem . calcFunc-prem)
+ ( quorem . calcFunc-pdivrem)
+ ( divide . calcFunc-pdivrem)
+ ( equal . calcFunc-eq)
+ ( ifte . calcFunc-if)
+ ( not . calcFunc-lnot)
+ ( rhs . calcFunc-rmeq)
+ ( right . calcFunc-rmeq)
+ ( prepend . (math-lang-switch-args calcFunc-cons))
+ ( contains . (math-lang-switch-args calcFunc-in))
+ ( has . (math-lang-switch-args calcFunc-refers))))
+
+(defun math-lang-switch-args (f val)
+ "Read the arguments to a Calc function in reverse order.
+This is used for various language modes which have functions in reverse
+order to Calc's."
+ (let ((args (math-read-expr-list)))
+ (math-read-token)
+ (list (nth 2 f)
+ (nth 1 args)
+ (nth 0 args))))
+
+(put 'giac 'math-parse-table
+ '((("set" 0)
+ calcFunc-rdup
+ (var ArgA var-ArgA))))
+
+(put 'giac 'math-special-function-table
+ '((calcFunc-cons . (math-lang-compose-switch-args "prepend"))
+ (calcFunc-in . (math-lang-compose-switch-args "contains"))
+ (calcFunc-refers . (math-lang-compose-switch-args "has"))
+ (intv . math-compose-maple-intv)))
+
+(defun math-lang-compose-switch-args (a fn)
+ "Compose the arguments to a Calc function in reverse order.
+This is used for various language modes which have functions in reverse
+order to Calc's."
+ (list 'horiz (nth 1 fn)
+ "("
+ (math-compose-expr (nth 2 a) 0)
+ ","
+ (math-compose-expr (nth 1 a) 0)
+ ")"))
+
+(put 'giac 'math-variable-table
+ '(( infinity . var-inf)
+ ( infinity . var-uinf)))
+
+(put 'giac 'math-complex-format 'i)
+
+(add-to-list 'calc-lang-allow-underscores 'giac)
+
+(put 'giac 'math-compose-subscr
+ (function
+ (lambda (a)
+ (let ((args (cdr (cdr a))))
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "["
+ (math-compose-expr
+ (calc-normalize (list '- (nth 2 a) 1)) 0)
+ "]")))))
+
+(defun math-read-giac-subscr (x op)
+ (let ((idx (math-read-expr-level 0)))
+ (or (equal math-expr-data "]")
+ (throw 'syntax "Expected ']'"))
+ (math-read-token)
+ (list 'calcFunc-subscr x (calc-normalize (list '+ idx 1)))))
+
+(add-to-list 'calc-lang-c-type-hex 'giac)
+
(defun calc-mathematica-language ()
(interactive)
@@ -789,6 +1892,22 @@
(put 'math 'math-radix-formatter
(function (lambda (r s) (format "%d^^%s" r s))))
+(put 'math 'math-lang-read
+ '((eq (string-match "\\[\\[\\|->\\|:>" math-exp-str math-exp-pos)
+ math-exp-pos)
+ (setq math-exp-token 'punc
+ math-expr-data (math-match-substring math-exp-str 0)
+ math-exp-pos (match-end 0))))
+
+(put 'math 'math-compose-subscr
+ (function
+ (lambda (a)
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "[["
+ (math-compose-expr (nth 2 a) 0)
+ "]]"))))
+
(defun math-read-math-subscr (x op)
(let ((idx (math-read-expr-level 0)))
(or (and (equal math-expr-data "]")
@@ -862,6 +1981,9 @@
( vectdim . calcFunc-vlen )
))
+(put 'maple 'math-special-function-table
+ '((intv . math-compose-maple-intv)))
+
(put 'maple 'math-variable-table
'( ( I . var-i )
( Pi . var-pi )
@@ -873,6 +1995,37 @@
(put 'maple 'math-complex-format 'I)
+(put 'maple 'math-matrix-formatter
+ (function
+ (lambda (a)
+ (list 'horiz
+ "matrix("
+ math-comp-left-bracket
+ (math-compose-vector (cdr a)
+ (concat math-comp-comma " ")
+ math-comp-vector-prec)
+ math-comp-right-bracket
+ ")"))))
+
+(put 'maple 'math-compose-subscr
+ (function
+ (lambda (a)
+ (let ((args (cdr (cdr a))))
+ (list 'horiz
+ (math-compose-expr (nth 1 a) 1000)
+ "["
+ (math-compose-vector args ", " 0)
+ "]")))))
+
+(add-to-list 'calc-lang-allow-underscores 'maple)
+(add-to-list 'calc-lang-brackets-are-subscripts 'maple)
+
+(defun math-compose-maple-intv (a)
+ (list 'horiz
+ (math-compose-expr (nth 2 a) 0)
+ " .. "
+ (math-compose-expr (nth 3 a) 0)))
+
(defun math-read-maple-dots (x op)
(list 'intv 3 x (math-read-expr-level (nth 3 op))))
@@ -1225,7 +2378,7 @@
h (1+ v) (1+ h) math-rb-v2)
(string-match "<=\\|>=\\|\\+/-\\|!=\\|&&\\|||\\|:=\\|=>\\|." line h)
(assoc (math-match-substring line 0)
- math-standard-opers)))
+ (math-standard-ops))))
(and (>= (nth 2 widest) prec)
(setq h (match-end 0)))
(and (not (eq (string-match ",\\|;\\|\\.\\.\\|)\\|\\]\\|:" line h)
diff --git a/lisp/calc/calc-macs.el b/lisp/calc/calc-macs.el
index 4825ef4ab4a..c5d06031de7 100644
--- a/lisp/calc/calc-macs.el
+++ b/lisp/calc/calc-macs.el
@@ -27,6 +27,16 @@
;;; Code:
+;; Declare functions which are defined elsewhere.
+(declare-function math-zerop "calc-misc" (a))
+(declare-function math-negp "calc-misc" (a))
+(declare-function math-looks-negp "calc-misc" (a))
+(declare-function math-posp "calc-misc" (a))
+(declare-function math-compare "calc-ext" (a b))
+(declare-function math-bignum "calc" (a))
+(declare-function math-compare-bignum "calc-ext" (a b))
+
+
(defmacro calc-wrapper (&rest body)
`(calc-do (function (lambda ()
,@body))))
diff --git a/lisp/calc/calc-math.el b/lisp/calc/calc-math.el
index 07432a39881..920022aed91 100644
--- a/lisp/calc/calc-math.el
+++ b/lisp/calc/calc-math.el
@@ -32,6 +32,84 @@
(require 'calc-ext)
(require 'calc-macs)
+
+;;; Find out how many 9s in 9.9999... will give distinct Emacs floats,
+;;; then back off by one.
+
+(defvar math-emacs-precision
+ (let* ((n 1)
+ (x 9)
+ (xx (+ x (* 9 (expt 10 (- n))))))
+ (while (/= x xx)
+ (progn
+ (setq n (1+ n))
+ (setq x xx)
+ (setq xx (+ x (* 9 (expt 10 (- n)))))))
+ (1- n))
+ "The number of digits in an Emacs float.")
+
+;;; Find the largest power of 10 which is an Emacs float,
+;;; then back off by one so that any float d.dddd...eN
+;;; is an Emacs float, for acceptable d.dddd....
+
+(defvar math-largest-emacs-expt
+ (let ((x 1)
+ (pow 1e2))
+ ;; The following loop is for efficiency; it should stop when
+ ;; 10^(2x) is too large. This could be indicated by a range
+ ;; error when computing 10^(2x) or an infinite value for 10^(2x).
+ (while (and
+ pow
+ (< pow 1.0e+INF))
+ (setq x (* 2 x))
+ (setq pow (condition-case nil
+ (expt 10.0 (* 2 x))
+ (error nil))))
+ ;; The following loop should stop when 10^(x+1) is too large.
+ (setq pow (condition-case nil
+ (expt 10.0 (1+ x))
+ (error nil)))
+ (while (and
+ pow
+ (< pow 1.0e+INF))
+ (setq x (1+ x))
+ (setq pow (condition-case nil
+ (expt 10.0 (1+ x))
+ (error nil))))
+ (1- x))
+ "The largest exponent which Calc will convert to an Emacs float.")
+
+(defvar math-smallest-emacs-expt
+ (let ((x -1))
+ (while (condition-case nil
+ (> (expt 10.0 x) 0.0)
+ (error nil))
+ (setq x (* 2 x)))
+ (setq x (/ x 2))
+ (while (condition-case nil
+ (> (expt 10.0 x) 0.0)
+ (error nil))
+ (setq x (1- x)))
+ (+ x 2))
+ "The smallest exponent which Calc will convert to an Emacs float.")
+
+(defun math-use-emacs-fn (fn x)
+ "Use the native Emacs function FN to evaluate the Calc number X.
+If this can't be done, return NIL."
+ (and
+ (<= calc-internal-prec math-emacs-precision)
+ (math-realp x)
+ (let* ((fx (math-float x))
+ (xpon (+ (nth 2 x) (1- (math-numdigs (nth 1 x))))))
+ (and (<= math-smallest-emacs-expt xpon)
+ (<= xpon math-largest-emacs-expt)
+ (condition-case nil
+ (math-read-number
+ (number-to-string
+ (funcall fn
+ (string-to-number (math-format-number (math-float x))))))
+ (error nil))))))
+
(defun calc-sqrt (arg)
(interactive "P")
(calc-slow-wrapper
@@ -310,15 +388,15 @@
(let* ((top (nthcdr (- len 2) a)))
(math-isqrt-bignum-iter
a
- (math-scale-bignum-3
+ (math-scale-bignum-digit-size
(math-bignum-big
(1+ (math-isqrt-small
- (+ (* (nth 1 top) 1000) (car top)))))
+ (+ (* (nth 1 top) math-bignum-digit-size) (car top)))))
(1- (/ len 2)))))
(let* ((top (nth (1- len) a)))
(math-isqrt-bignum-iter
a
- (math-scale-bignum-3
+ (math-scale-bignum-digit-size
(list (1+ (math-isqrt-small top)))
(/ len 2)))))))
@@ -341,14 +419,15 @@
(while (eq (car (setq a (cdr a))) 0))
(null a))))
-(defun math-scale-bignum-3 (a n) ; [L L S]
+(defun math-scale-bignum-digit-size (a n) ; [L L S]
(while (> n 0)
(setq a (cons 0 a)
n (1- n)))
a)
(defun math-isqrt-small (a) ; A > 0. [S S]
- (let ((g (cond ((>= a 10000) 1000)
+ (let ((g (cond ((>= a 1000000) 10000)
+ ((>= a 10000) 1000)
((>= a 100) 100)
(t 10)))
g2)
@@ -463,13 +542,16 @@
(defun math-sqrt-raw (a &optional guess) ; [F F F]
(if (not (Math-posp a))
(math-sqrt a)
- (if (null guess)
- (let ((ldiff (- (math-numdigs (nth 1 a)) 6)))
- (or (= (% (+ (nth 2 a) ldiff) 2) 0) (setq ldiff (1+ ldiff)))
- (setq guess (math-make-float (math-isqrt-small
- (math-scale-int (nth 1 a) (- ldiff)))
- (/ (+ (nth 2 a) ldiff) 2)))))
- (math-sqrt-float-iter a guess)))
+ (cond
+ ((math-use-emacs-fn 'sqrt a))
+ (t
+ (if (null guess)
+ (let ((ldiff (- (math-numdigs (nth 1 a)) 6)))
+ (or (= (% (+ (nth 2 a) ldiff) 2) 0) (setq ldiff (1+ ldiff)))
+ (setq guess (math-make-float (math-isqrt-small
+ (math-scale-int (nth 1 a) (- ldiff)))
+ (/ (+ (nth 2 a) ldiff) 2)))))
+ (math-sqrt-float-iter a guess)))))
(defun math-sqrt-float-iter (a guess) ; [F F F]
(math-working "sqrt" guess)
@@ -1135,11 +1217,13 @@
((math-lessp-float x (math-neg (math-pi-over-4)))
(math-neg (math-cos-raw-2 (math-add (math-pi-over-2) x) orgx)))
((math-nearly-zerop-float x orgx) '(float 0 0))
+ ((math-use-emacs-fn 'sin x))
(calc-symbolic-mode (signal 'inexact-result nil))
(t (math-sin-series x 6 4 x (math-neg-float (math-sqr-float x)))))))
(defun math-cos-raw-2 (x orgx) ; [F F]
(cond ((math-nearly-zerop-float x orgx) '(float 1 0))
+ ((math-use-emacs-fn 'cos x))
(calc-symbolic-mode (signal 'inexact-result nil))
(t (let ((xnegsqr (math-neg-float (math-sqr-float x))))
(math-sin-series
@@ -1253,6 +1337,7 @@
((Math-integer-negp (nth 1 x))
(math-neg-float (math-arctan-raw (math-neg-float x))))
((math-zerop x) x)
+ ((math-use-emacs-fn 'atan x))
(calc-symbolic-mode (signal 'inexact-result nil))
((math-equal-int x 1) (math-pi-over-4))
((math-equal-int x -1) (math-neg (math-pi-over-4)))
@@ -1402,6 +1487,7 @@
(list 'polar
(math-exp-raw (nth 1 xc))
(math-from-radians (nth 2 xc)))))
+ ((math-use-emacs-fn 'exp x))
((or (math-lessp-float '(float 5 -1) x)
(math-lessp-float x '(float -5 -1)))
(if (math-lessp-float '(float 921035 1) x)
@@ -1670,10 +1756,13 @@
'(float 0 0))
(calc-symbolic-mode (signal 'inexact-result nil))
((math-posp (nth 1 x)) ; positive and real
- (let ((xdigs (1- (math-numdigs (nth 1 x)))))
- (math-add-float (math-ln-raw-2 (list 'float (nth 1 x) (- xdigs)))
- (math-mul-float (math-float (+ (nth 2 x) xdigs))
- (math-ln-10)))))
+ (cond
+ ((math-use-emacs-fn 'log x))
+ (t
+ (let ((xdigs (1- (math-numdigs (nth 1 x)))))
+ (math-add-float (math-ln-raw-2 (list 'float (nth 1 x) (- xdigs)))
+ (math-mul-float (math-float (+ (nth 2 x) xdigs))
+ (math-ln-10)))))))
((math-zerop x)
(math-reject-arg x "*Logarithm of zero"))
((eq calc-complex-mode 'polar) ; negative and real
@@ -1717,10 +1806,18 @@
sum
(math-lnp1-series nextsum (1+ n) nextx x))))
-(math-defcache math-ln-10 (float (bigpos 018 684 045 994 092 585 302 2) -21)
+(defconst math-approx-ln-10
+ (math-read-number-simple "2.302585092994045684018")
+ "An approximation for ln(10).")
+
+(math-defcache math-ln-10 math-approx-ln-10
(math-ln-raw-2 '(float 1 1)))
-(math-defcache math-ln-2 (float (bigpos 417 309 945 559 180 147 693) -21)
+(defconst math-approx-ln-2
+ (math-read-number-simple "0.693147180559945309417")
+ "An approximation for ln(2).")
+
+(math-defcache math-ln-2 math-approx-ln-2
(math-ln-raw-3 (math-float '(frac 1 3))))
diff --git a/lisp/calc/calc-menu.el b/lisp/calc/calc-menu.el
new file mode 100644
index 00000000000..ca67b65abfa
--- /dev/null
+++ b/lisp/calc/calc-menu.el
@@ -0,0 +1,1429 @@
+;;; calc-menu.el --- a menu for Calc
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; 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; 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:
+
+(defvar calc-arithmetic-menu
+ (list "Arithmetic"
+ (list "Basic"
+ ["-(1:)" calc-change-sign
+ :keys "n" :active (>= (calc-stack-size) 1)]
+ ["(2:) + (1:)" calc-plus
+ :keys "+" :active (>= (calc-stack-size) 2)]
+ ["(2:) - (1:)" calc-minus
+ :keys "-" :active (>= (calc-stack-size) 2)]
+ ["(2:) * (1:)" calc-times
+ :keys "*" :active (>= (calc-stack-size) 2)]
+ ["(2:) / (1:)" calc-divide
+ :keys "/" :active (>= (calc-stack-size) 2)]
+ ["(2:) ^ (1:)" calc-power
+ :keys "^" :active (>= (calc-stack-size) 2)]
+ ["(2:) ^ (1/(1:))"
+ (progn
+ (require 'calc-ext)
+ (let ((calc-inverse-flag t))
+ (call-interactively 'calc-power)))
+ :keys "I ^"
+ :active (>= (calc-stack-size) 2)
+ :help "The (1:)th root of (2:)"]
+ ["abs(1:)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-abs))
+ :keys "A"
+ :active (>= (calc-stack-size) 1)
+ :help "Absolute value"]
+ ["1/(1:)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-inv))
+ :keys "&"
+ :active (>= (calc-stack-size) 1)]
+ ["sqrt(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-sqrt))
+ :keys "Q"
+ :active (>= (calc-stack-size) 1)]
+ ["idiv(2:,1:)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-idiv))
+ :keys "\\"
+ :active (>= (calc-stack-size) 2)
+ :help "The integer quotient of (2:) over (1:)"]
+ ["(2:) mod (1:)"
+ (progn
+ (require 'calc-misc)
+ (call-interactively 'calc-mod))
+ :keys "%"
+ :active (>= (calc-stack-size) 2)
+ :help "The remainder when (2:) is divided by (1:)"])
+ (list "Rounding"
+ ["floor(1:)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-floor))
+ :keys "F"
+ :active (>= (calc-stack-size) 1)
+ :help "The greatest integer less than or equal to (1:)"]
+ ["ceiling(1:)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-ceiling))
+ :keys "I F"
+ :active (>= (calc-stack-size) 1)
+ :help "The smallest integer greater than or equal to (1:)"]
+ ["round(1:)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-round))
+ :keys "R"
+ :active (>= (calc-stack-size) 1)
+ :help "The nearest integer to (1:)"]
+ ["truncate(1:)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-trunc))
+ :keys "I R"
+ :active (>= (calc-stack-size) 1)
+ :help "The integer part of (1:)"])
+ (list "Complex Numbers"
+ ["Re(1:)"
+ (progn
+ (require 'calc-cplx)
+ (call-interactively 'calc-re))
+ :keys "f r"
+ :active (>= (calc-stack-size) 1)]
+ ["Im(1:)"
+ (progn
+ (require 'calc-cplx)
+ (call-interactively 'calc-im))
+ :keys "f i"
+ :active (>= (calc-stack-size) 1)]
+ ["conj(1:)"
+ (progn
+ (require 'calc-cplx)
+ (call-interactively 'calc-conj))
+ :keys "J"
+ :active (>= (calc-stack-size) 1)
+ :help "The complex conjugate of (1:)"]
+ ["length(1:)"
+ (progn (require 'calc-arith)
+ (call-interactively 'calc-abs))
+ :keys "A"
+ :active (>= (calc-stack-size) 1)
+ :help "The length (absolute value) of (1:)"]
+ ["arg(1:)"
+ (progn
+ (require 'calc-cplx)
+ (call-interactively 'calc-argument))
+ :keys "G"
+ :active (>= (calc-stack-size) 1)
+ :help "The argument (polar angle) of (1:)"])
+ (list "Conversion"
+ ["Convert (1:) to a float"
+ (progn
+ (require 'calc-ext)
+ (call-interactively 'calc-float))
+ :keys "c f"
+ :active (>= (calc-stack-size) 1)]
+ ["Convert (1:) to a fraction"
+ (progn
+ (require 'calc-ext)
+ (call-interactively 'calc-fraction))
+ :keys "c F"
+ :active (>= (calc-stack-size) 1)])
+ (list "Binary"
+ ["Set word size"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-word-size))
+ :keys "b w"]
+ ["Clip (1:) to word size"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-clip))
+ :keys "b c"
+ :active (>= (calc-stack-size) 1)
+ :help "Reduce (1:) modulo 2^wordsize"]
+ ["(2:) and (1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-and))
+ :keys "b a"
+ :active (>= (calc-stack-size) 2)
+ :help "Bitwise AND [modulo 2^wordsize]"]
+ ["(2:) or (1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-or))
+ :keys "b o"
+ :active (>= (calc-stack-size) 2)
+ :help "Bitwise inclusive OR [modulo 2^wordsize]"]
+ ["(2:) xor (1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-xor))
+ :keys "b x"
+ :active (>= (calc-stack-size) 2)
+ :help "Bitwise exclusive OR [modulo 2^wordsize]"]
+ ["diff(2:,1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-diff))
+ :keys "b d"
+ :active (>= (calc-stack-size) 2)
+ :help "Bitwise difference [modulo 2^wordsize]"]
+ ["not (1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-not))
+ :keys "b n"
+ :active (>= (calc-stack-size) 1)
+ :help "Bitwise NOT [modulo 2^wordsize]"]
+ ["left shift(1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-lshift-binary))
+ :keys "b l"
+ :active (>= (calc-stack-size) 1)
+ :help "Shift (1:)[modulo 2^wordsize] one bit left"]
+ ["right shift(1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-rshift-binary))
+ :keys "b r"
+ :active (>= (calc-stack-size) 1)
+ :help "Shift (1:)[modulo 2^wordsize] one bit right, putting 0s on the left"]
+ ["arithmetic right shift(1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-rshift-arith))
+ :keys "b R"
+ :active (>= (calc-stack-size) 1)
+ :help "Shift (1:)[modulo 2^wordsize] one bit right, duplicating the leftmost bit"]
+ ["rotate(1:)"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-rotate-binary))
+ :keys "b t"
+ :active (>= (calc-stack-size) 1)
+ :help "Rotate (1:)[modulo 2^wordsize] one bit left"])
+ "-------"
+ ["Help on Arithmetic"
+ (calc-info-goto-node "Arithmetic")])
+ "Menu for Calc's arithmetic functions.")
+
+(defvar calc-scientific-function-menu
+ (list "Scientific Functions"
+ (list "Constants"
+ ["pi"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-pi))
+ :keys "P"]
+ ["e"
+ (progn
+ (require 'calc-math)
+ (let ((calc-hyperbolic-flag t))
+ (call-interactively 'calc-pi)))
+ :keys "H P"]
+ ["phi"
+ (progn
+ (require 'calc-math)
+ (let ((calc-inverse-flag t)
+ (calc-hyperbolic-flag t))
+ (call-interactively 'calc-pi)))
+ :keys "I H P"
+ :help "The golden ratio"]
+ ["gamma"
+ (progn
+ (require 'calc-math)
+ (let ((calc-inverse-flag t))
+ (call-interactively 'calc-pi)))
+ :keys "I P"
+ :help "Euler's constant"])
+ (list "Logs and Exps"
+ ["ln(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-ln))
+ :keys "L"
+ :active (>= (calc-stack-size) 1)
+ :help "The natural logarithm"]
+ ["e^(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-exp))
+ :keys "E"
+ :active (>= (calc-stack-size) 1)]
+ ["log(1:) [base 10]"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-log10))
+ :keys "H L"
+ :active (>= (calc-stack-size) 1)
+ :help "The common logarithm"]
+ ["10^(1:)"
+ (progn
+ (require 'calc-math)
+ (let ((calc-inverse-flag t))
+ (call-interactively 'calc-log10)))
+ :keys "I H L"
+ :active (>= (calc-stack-size) 1)]
+ ["log(2:) [base(1:)]"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-log))
+ :keys "B"
+ :active (>= (calc-stack-size) 2)
+ :help "The logarithm with an arbitrary base"]
+ ["(2:) ^ (1:)"
+ calc-power
+ :keys "^"
+ :active (>= (calc-stack-size) 2)])
+ (list "Trigonometric Functions"
+ ["sin(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-sin))
+ :keys "S"
+ :active (>= (calc-stack-size) 1)]
+ ["cos(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-cos))
+ :keys "C"
+ :active (>= (calc-stack-size) 1)]
+ ["tan(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-tan))
+ :keys "T"
+ :active (>= (calc-stack-size) 1)]
+ ["arcsin(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-arcsin))
+ :keys "I S"
+ :active (>= (calc-stack-size) 1)]
+ ["arccos(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-arccos))
+ :keys "I C"
+ :active (>= (calc-stack-size) 1)]
+ ["arctan(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-arctan))
+ :keys "I T"
+ :active (>= (calc-stack-size) 1)]
+ ["arctan2(2:,1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-arctan2))
+ :keys "f T"
+ :active (>= (calc-stack-size) 2)]
+ "--Angle Measure--"
+ ["Radians"
+ (progn
+ (require 'calc-math)
+ (calc-radians-mode))
+ :keys "m r"
+ :style radio
+ :selected (eq calc-angle-mode 'rad)]
+ ["Degrees"
+ (progn
+ (require 'calc-math)
+ (calc-degrees-mode))
+ :keys "m d"
+ :style radio
+ :selected (eq calc-angle-mode 'deg)]
+ ["HMS"
+ (progn
+ (require 'calc-math)
+ (calc-hms-mode))
+ :keys "m h"
+ :style radio
+ :selected (eq calc-angle-mode 'hms)])
+ (list "Hyperbolic Functions"
+ ["sinh(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-sinh))
+ :keys "H S"
+ :active (>= (calc-stack-size) 1)]
+ ["cosh(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-cosh))
+ :keys "H C"
+ :active (>= (calc-stack-size) 1)]
+ ["tanh(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-tanh))
+ :keys "H T"
+ :active (>= (calc-stack-size) 1)]
+ ["arcsinh(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-arcsinh))
+ :keys "I H S"
+ :active (>= (calc-stack-size) 1)]
+ ["arccosh(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-arccosh))
+ :keys "I H C"
+ :active (>= (calc-stack-size) 1)]
+ ["arctanh(1:)"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-arctanh))
+ :keys "I H T"
+ :active (>= (calc-stack-size) 1)])
+ (list "Advanced Math Functions"
+ ["Gamma(1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-gamma))
+ :keys "f g"
+ :active (>= (calc-stack-size) 1)
+ :help "The Euler Gamma function"]
+ ["GammaP(2:,1:)"
+ (progn
+ (require 'calc-funcs)
+ (call-interactively 'calc-inc-gamma))
+ :keys "f G"
+ :active (>= (calc-stack-size) 2)
+ :help "The lower incomplete Gamma function"]
+ ["Beta(2:,1:)"
+ (progn
+ (require 'calc-funcs)
+ (call-interactively 'calc-beta))
+ :keys "f b"
+ :active (>= (calc-stack-size) 2)
+ :help "The Euler Beta function"]
+ ["BetaI(3:,2:,1:)"
+ (progn
+ (require 'calc-funcs)
+ (call-interactively 'calc-inc-beta))
+ :keys "f B"
+ :active (>= (calc-stack-size) 3)
+ :help "The incomplete Beta function"]
+ ["erf(1:)"
+ (progn
+ (require 'calc-funcs)
+ (call-interactively 'calc-erf))
+ :keys "f e"
+ :active (>= (calc-stack-size) 1)
+ :help "The error function"]
+ ["BesselJ(2:,1:)"
+ (progn
+ (require 'calc-funcs)
+ (call-interactively 'calc-bessel-J))
+ :keys "f j"
+ :active (>= (calc-stack-size) 2)
+ :help "The Bessel function of the first kind (of order (2:))"]
+ ["BesselY(2:,1:)"
+ (progn
+ (require 'calc-funcs)
+ (call-interactively 'calc-bessel-Y))
+ :keys "f y"
+ :active (>= (calc-stack-size) 2)
+ :help "The Bessel function of the second kind (of order (2:))"])
+ (list "Combinatorial Functions"
+ ["gcd(2:,1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-gcd))
+ :keys "k g"
+ :active (>= (calc-stack-size) 2)]
+ ["lcm(2:,1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-lcm))
+ :keys "k l"
+ :active (>= (calc-stack-size) 2)]
+ ["factorial(1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-factorial))
+ :keys "!"
+ :active (>= (calc-stack-size) 1)]
+ ["(2:) choose (1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-choose))
+ :keys "k c"
+ :active (>= (calc-stack-size) 2)]
+ ["permutations(2:,1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-perm))
+ :keys "H k c"
+ :active (>= (calc-stack-size) 2)]
+ ["Primality test for (1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-prime-test))
+ :keys "k p"
+ :active (>= (calc-stack-size) 1)
+ :help "For large (1:), a probabilistic test"]
+ ["Factor (1:) into primes"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-prime-factors))
+ :keys "k f"
+ :active (>= (calc-stack-size) 1)]
+ ["Next prime after (1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-next-prime))
+ :keys "k n"
+ :active (>= (calc-stack-size) 1)]
+ ["Previous prime before (1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-prev-prime))
+ :keys "I k n"
+ :active (>= (calc-stack-size) 1)]
+ ["phi(1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-totient))
+ :keys "k n"
+ :active (>= (calc-stack-size) 1)
+ :help "Euler's totient function"]
+ ["random(1:)"
+ (progn
+ (require 'calc-comb)
+ (call-interactively 'calc-random))
+ :keys "k r"
+ :active (>= (calc-stack-size) 1)
+ :help "A random number >=1 and < (1:)"])
+ "----"
+ ["Help on Scientific Functions"
+ (calc-info-goto-node "Scientific Functions")])
+ "Menu for Calc's scientific functions.")
+
+(defvar calc-algebra-menu
+ (list "Algebra"
+ (list "Simplification"
+ ["Simplify (1:)"
+ (progn
+ (require 'calc-alg)
+ (call-interactively 'calc-simplify))
+ :keys "a s"
+ :active (>= (calc-stack-size) 1)]
+ ["Simplify (1:) with extended rules"
+ (progn
+ (require 'calc-alg)
+ (call-interactively 'calc-simplify-extended))
+ :keys "a e"
+ :active (>= (calc-stack-size) 1)
+ :help "Apply possibly unsafe simplifications"])
+ (list "Manipulation"
+ ["Expand formula (1:)"
+ (progn
+ (require 'calc-alg)
+ (call-interactively 'calc-expand-formula))
+ :keys "a \""
+ :active (>= (calc-stack-size) 1)
+ :help "Expand (1:) into its defining formula, if possible"]
+ ["Evaluate variables in (1:)"
+ (progn
+ (require 'calc-ext)
+ (call-interactively 'calc-evaluate))
+ :keys "="
+ :active (>= (calc-stack-size) 1)]
+ ["Make substitution in (1:)"
+ (progn
+ (require 'calc-alg)
+ (call-interactively 'calc-substitute))
+ :keys "a b"
+ :active (>= (calc-stack-size) 1)
+ :help
+ "Substitute all occurrences of a sub-expression with a new sub-expression"])
+ (list "Polynomials"
+ ["Factor (1:)"
+ (progn
+ (require 'calc-alg)
+ (call-interactively 'calc-factor))
+ :keys "a f"
+ :active (>= (calc-stack-size) 1)]
+ ["Collect terms in (1:)"
+ (progn
+ (require 'calc-alg)
+ (call-interactively 'calc-collect))
+ :keys "a c"
+ :active (>= (calc-stack-size) 1)
+ :help "Arrange as a polynomial in a given variable"]
+ ["Expand (1:)"
+ (progn
+ (require 'calc-alg)
+ (call-interactively 'calc-expand))
+ :keys "a x"
+ :active (>= (calc-stack-size) 1)
+ :help "Apply distributive law everywhere"]
+ ["Find roots of (1:)"
+ (progn
+ (require 'calcalg2)
+ (call-interactively 'calc-poly-roots))
+ :keys "a P"
+ :active (>= (calc-stack-size) 1)])
+ (list "Calculus"
+ ["Differentiate (1:)"
+ (progn
+ (require 'calcalg2)
+ (call-interactively 'calc-derivative))
+ :keys "a d"
+ :active (>= (calc-stack-size) 1)]
+ ["Integrate (1:) [indefinite]"
+ (progn
+ (require 'calcalg2)
+ (call-interactively 'calc-integral))
+ :keys "a i"
+ :active (>= (calc-stack-size) 1)]
+ ["Integrate (1:) [definite]"
+ (progn
+ (require 'calcalg2)
+ (let ((var (read-string "Integration variable: ")))
+ (calc-tabular-command 'calcFunc-integ "Integration"
+ "intg" nil var nil nil)))
+ :keys "C-u a i"
+ :active (>= (calc-stack-size) 1)]
+ ["Integrate (1:) [numeric]"
+ (progn
+ (require 'calcalg2)
+ (call-interactively 'calc-num-integral))
+ :keys "a I"
+ :active (>= (calc-stack-size) 1)
+ :help "Integrate using the open Romberg method"]
+ ["Taylor expand (1:)"
+ (progn
+ (require 'calcalg2)
+ (call-interactively 'calc-taylor))
+ :keys "a t"
+ :active (>= (calc-stack-size) 1)]
+ ["Minimize (2:) [initial guess = (1:)]"
+ (progn
+ (require 'calcalg3)
+ (call-interactively 'calc-find-minimum))
+ :keys "a N"
+ :active (>= (calc-stack-size) 2)
+ :help "Find a local minimum"]
+ ["Maximize (2:) [initial guess = (1:)]"
+ (progn
+ (require 'calcalg3)
+ (call-interactively 'calc-find-maximum))
+ :keys "a X"
+ :active (>= (calc-stack-size) 2)
+ :help "Find a local maximum"])
+ (list "Solving"
+ ["Solve equation (1:)"
+ (progn
+ (require 'calcalg2)
+ (call-interactively 'calc-solve-for))
+ :keys "a S"
+ :active (>= (calc-stack-size) 1)]
+ ["Solve equation (2:) numerically [initial guess = (1:)]"
+ (progn
+ (require 'calcalg3)
+ (call-interactively 'calc-find-root))
+ :keys "a R"
+ :active (>= (calc-stack-size) 2)]
+ ["Find roots of polynomial (1:)"
+ (progn
+ (require 'calcalg2)
+ (call-interactively 'calc-poly-roots))
+ :keys "a P"
+ :active (>= (calc-stack-size) 1)])
+ (list "Curve Fitting"
+ ["Fit (1:)=[x values, y values] to a curve"
+ (progn
+ (require 'calcalg3)
+ (call-interactively 'calc-curve-fit))
+ :keys "a F"
+ :active (>= (calc-stack-size) 1)])
+ "----"
+ ["Help on Algebra"
+ (calc-info-goto-node "Algebra")])
+ "Menu for Calc's algebraic facilities.")
+
+
+(defvar calc-graphics-menu
+ (list "Graphics"
+ ["Graph 2D [(1:)= y values, (2:)= x values]"
+ (progn
+ (require 'calc-graph)
+ (call-interactively 'calc-graph-fast))
+ :keys "g f"
+ :active (>= (calc-stack-size) 2)]
+ ["Graph 3D [(1:)= z values, (2:)= y values, (3:)= x values]"
+ (progn
+ (require 'calc-graph)
+ (call-interactively 'calc-graph-fast-3d))
+ :keys "g F"
+ :active (>= (calc-stack-size) 3)]
+ "----"
+ ["Help on Graphics"
+ (calc-info-goto-node "Graphics")])
+ "Menu for Calc's graphics.")
+
+
+(defvar calc-vectors-menu
+ (list "Matrices/Vectors"
+ (list "Matrices"
+ ["(2:) + (1:)" calc-plus
+ :keys "+" :active (>= (calc-stack-size) 2)]
+ ["(2:) - (1:)" calc-minus
+ :keys "-" :active (>= (calc-stack-size) 2)]
+ ["(2:) * (1:)" calc-times
+ :keys "*" :active (>= (calc-stack-size) 2)]
+ ["(1:)^(-1)"
+ (progn
+ (require 'calc-arith)
+ (call-interactively 'calc-inv))
+ :keys "&"
+ :active (>= (calc-stack-size) 1)]
+ ["Create an identity matrix"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-ident))
+ :keys "v i"]
+ ["transpose(1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-transpose))
+ :keys "v t"
+ :active (>= (calc-stack-size) 1)]
+ ["det(1:)"
+ (progn
+ (require 'calc-mtx)
+ (call-interactively 'calc-mdet))
+ :keys "V D"
+ :active (>= (calc-stack-size) 1)]
+ ["trace(1:)"
+ (progn
+ (require 'calc-mtx)
+ (call-interactively 'calc-mtrace))
+ :keys "V T"
+ :active (>= (calc-stack-size) 1)]
+ ["LUD decompose (1:)"
+ (progn
+ (require 'calc-mtx)
+ (call-interactively 'calc-mlud))
+ :keys "V L"
+ :active (>= (calc-stack-size) 1)]
+ ["Extract a row from (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-mrow))
+ :keys "v r"
+ :active (>= (calc-stack-size) 1)]
+ ["Extract a column from (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-mcol))
+ :keys "v c"
+ :active (>= (calc-stack-size) 1)])
+ (list "Vectors"
+ ["Extract the first element of (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-head))
+ :keys "v h"
+ :active (>= (calc-stack-size) 1)]
+ ["Extract an element from (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-mrow))
+ :keys "v r"
+ :active (>= (calc-stack-size) 1)]
+ ["Reverse (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-reverse-vector))
+ :keys "v v"
+ :active (>= (calc-stack-size) 1)]
+ ["Unpack (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-unpack))
+ :keys "v u"
+ :active (>= (calc-stack-size) 1)
+ :help "Separate the elements of (1:)"]
+ ["(2:) cross (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-cross))
+ :keys "V C"
+ :active (>= (calc-stack-size) 2)
+ :help "The cross product in R^3"]
+ ["(2:) dot (1:)"
+ calc-mult
+ :keys "*"
+ :active (>= (calc-stack-size) 2)
+ :help "The dot product"]
+ ["Map a function across (1:)"
+ (progn
+ (require 'calc-map)
+ (call-interactively 'calc-map))
+ :keys "V M"
+ :active (>= (calc-stack-size) 1)
+ :help "Apply a function to each element"])
+ (list "Vectors As Sets"
+ ["Remove duplicates from (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-remove-duplicates))
+ :keys "V +"
+ :active (>= (calc-stack-size) 1)]
+ ["(2:) union (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-set-union))
+ :keys "V V"
+ :active (>= (calc-stack-size) 2)]
+ ["(2:) intersect (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-set-intersect))
+ :keys "V ^"
+ :active (>= (calc-stack-size) 2)]
+ ["(2:) \\ (1:)"
+ (progn
+ (require 'calc-vec)
+ (call-interactively 'calc-set-difference))
+ :keys "V -"
+ :help "Set difference"
+ :active (>= (calc-stack-size) 2)])
+ (list "Statistics On Vectors"
+ ["length(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-count))
+ :keys "u #"
+ :active (>= (calc-stack-size) 1)
+ :help "The number of data values"]
+ ["sum(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-sum))
+ :keys "u +"
+ :active (>= (calc-stack-size) 1)
+ :help "The sum of the data values"]
+ ["max(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-max))
+ :keys "u x"
+ :active (>= (calc-stack-size) 1)
+ :help "The maximum of the data values"]
+ ["min(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-min))
+ :keys "u N"
+ :active (>= (calc-stack-size) 1)
+ :help "The minumum of the data values"]
+ ["mean(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-mean))
+ :keys "u M"
+ :active (>= (calc-stack-size) 1)
+ :help "The average (arithmetic mean) of the data values"]
+ ["mean(1:) with error"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-mean-error))
+ :keys "I u M"
+ :active (>= (calc-stack-size) 1)
+ :help "The average (arithmetic mean) of the data values as an error form"]
+ ["sdev(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-sdev))
+ :keys "u S"
+ :active (>= (calc-stack-size) 1)
+ :help "The sample sdev, sqrt[sum((values - mean)^2)/(N-1)]"]
+ ["variance(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-variance))
+ :keys "H u S"
+ :active (>= (calc-stack-size) 1)
+ :help "The sample variance, sum((values - mean)^2)/(N-1)"]
+ ["population sdev(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-pop-sdev))
+ :keys "I u S"
+ :active (>= (calc-stack-size) 1)
+ :help "The population sdev, sqrt[sum((values - mean)^2)/N]"]
+ ["population variance(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-pop-variance))
+ :keys "H I u S"
+ :active (>= (calc-stack-size) 1)
+ :help "The population variance, sum((values - mean)^2)/N"]
+ ["median(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-median))
+ :keys "H u M"
+ :active (>= (calc-stack-size) 1)
+ :help "The median of the data values"]
+ ["harmonic mean(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-harmonic-mean))
+ :keys "H I u M"
+ :active (>= (calc-stack-size) 1)]
+ ["geometric mean(1:)"
+ (progn
+ (require 'calc-stat)
+ (call-interactively 'calc-vector-geometric-mean))
+ :keys "u G"
+ :active (>= (calc-stack-size) 1)]
+ ["arithmetic-geometric mean(1:)"
+ (progn
+ (require 'calc-stat)
+ (let ((calc-hyperbolic-flag t))
+ (call-interactively 'calc-vector-geometric-mean)))
+ :keys "H u G"
+ :active (>= (calc-stack-size) 1)]
+ ["RMS(1:)"
+ (progn (require 'calc-arith)
+ (call-interactively 'calc-abs))
+ :keys "A"
+ :active (>= (calc-stack-size) 1)
+ :help "The root-mean-square, or quadratic mean"])
+ ["Abbreviate long vectors"
+ (progn
+ (require 'calc-mode)
+ (call-interactively 'calc-full-vectors))
+ :keys "v ."
+ :style toggle
+ :selected (not calc-full-vectors)]
+ "----"
+ ["Help on Matrices/Vectors"
+ (calc-info-goto-node "Matrix Functions")])
+ "Menu for Calc's vector and matrix functions.")
+
+(defvar calc-units-menu
+ (list "Units"
+ ["Convert units in (1:)"
+ (progn
+ (require 'calc-units)
+ (call-interactively 'calc-convert-units ))
+ :keys "u c"
+ :active (>= (calc-stack-size) 1)]
+ ["Convert temperature in (1:)"
+ (progn
+ (require 'calc-units)
+ (call-interactively 'calc-convert-temperature))
+ :keys "u t"
+ :active (>= (calc-stack-size) 1)]
+ ["Simplify units in (1:)"
+ (progn
+ (require 'calc-units)
+ (call-interactively 'calc-simplify-units))
+ :keys "u s"
+ :active (>= (calc-stack-size) 1)]
+ ["View units table"
+ (progn
+ (require 'calc-units)
+ (call-interactively 'calc-view-units-table))
+ :keys "u V"]
+ "----"
+ ["Help on Units"
+ (calc-info-goto-node "Units")])
+ "Menu for Calc's units functions.")
+
+(defvar calc-variables-menu
+ (list "Variables"
+ ["Store (1:) into a variable"
+ (progn
+ (require 'calc-store)
+ (call-interactively 'calc-store))
+ :keys "s s"
+ :active (>= (calc-stack-size) 1)]
+ ["Recall a variable value"
+ (progn
+ (require 'calc-store)
+ (call-interactively 'calc-recall ))
+ :keys "s r"]
+ ["Edit the value of a variable"
+ (progn
+ (require 'calc-store)
+ (call-interactively 'calc-edit-variable))
+ :keys "s e"]
+ ["Exchange (1:) with a variable value"
+ (progn
+ (require 'calc-store)
+ (call-interactively 'calc-store-exchange))
+ :keys "s x"
+ :active (>= (calc-stack-size) 1)]
+ ["Clear variable value"
+ (progn
+ (require 'calc-store)
+ (call-interactively 'calc-unstore))
+ :keys "s u"]
+ ["Evaluate variables in (1:)"
+ (progn
+ (require 'calc-ext)
+ (call-interactively 'calc-evaluate))
+ :keys "="
+ :active (>= (calc-stack-size) 1)]
+ ["Evaluate (1:), assigning a value to a variable"
+ (progn
+ (require 'calc-store)
+ (call-interactively 'calc-let))
+ :keys "s l"
+ :active (>= (calc-stack-size) 1)
+ :help "Evaluate (1:) under a temporary assignment of a variable"]
+ "----"
+ ["Help on Variables"
+ (calc-info-goto-node "Store and Recall")])
+ "Menu for Calc's variables.")
+
+(defvar calc-stack-menu
+ (list "Stack"
+ ["Remove (1:)"
+ calc-pop
+ :keys "DEL"
+ :active (>= (calc-stack-size) 1)]
+ ["Switch (1:) and (2:)"
+ calc-roll-down
+ :keys "TAB"
+ :active (>= (calc-stack-size) 2)]
+ ["Duplicate (1:)"
+ calc-enter
+ :keys "RET"
+ :active (>= (calc-stack-size) 1)]
+ ["Edit (1:)"
+ (progn
+ (require 'calc-yank)
+ (call-interactively calc-edit))
+ :keys "`"
+ :active (>= (calc-stack-size) 1)]
+ "----"
+ ["Help on Stack"
+ (calc-info-goto-node "Stack and Trail")])
+ "Menu for Calc's stack functions.")
+
+(defvar calc-errors-menu
+ (list "Undo"
+ ["Undo"
+ (progn
+ (require 'calc-undo)
+ (call-interactively 'calc-undo))
+ :keys "U"]
+ ["Redo"
+ (progn
+ (require 'calc-undo)
+ (call-interactively 'calc-redo))
+ :keys "D"]
+ "----"
+ ["Help on Undo"
+ (progn
+ (calc-info-goto-node "Introduction")
+ (Info-goto-node "Undo"))]))
+
+(defvar calc-modes-menu
+ (list "Modes"
+ ["Precision"
+ (progn
+ (require 'calc-ext)
+ (call-interactively 'calc-precision))
+ :keys "p"
+ :help "Set the precision for floating point calculations"]
+ ["Fraction mode"
+ (progn
+ (require 'calc-frac)
+ (call-interactively 'calc-frac-mode))
+ :keys "m f"
+ :style toggle
+ :selected calc-prefer-frac
+ :help "Leave integer quotients as fractions"]
+ ["Symbolic mode"
+ (lambda ()
+ (interactive)
+ (require 'calc-mode)
+ (calc-symbolic-mode nil))
+ :keys "m s"
+ :style toggle
+ :selected calc-symbolic-mode
+ :help "Leave functions producing inexact answers in symbolic form"]
+ ["Infinite mode"
+ (lambda ()
+ (interactive)
+ (require 'calc-mode)
+ (calc-infinite-mode nil))
+ :keys "m i"
+ :style toggle
+ :selected calc-infinite-mode
+ :help "Let expressions like 1/0 produce infinite results"]
+ ["Abbreviate long vectors"
+ (progn
+ (require 'calc-mode)
+ (call-interactively 'calc-full-vectors))
+ :keys "v ."
+ :style toggle
+ :selected (not calc-full-vectors)]
+ (list "Angle Measure"
+ ["Radians"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-radians-mode))
+ :keys "m r"
+ :style radio
+ :selected (eq calc-angle-mode 'rad)]
+ ["Degrees"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-degrees-mode))
+ :keys "m d"
+ :style radio
+ :selected (eq calc-angle-mode 'deg)]
+ ["HMS"
+ (progn
+ (require 'calc-math)
+ (call-interactively 'calc-hms-mode))
+ :keys "m h"
+ :style radio
+ :selected (eq calc-angle-mode 'hms)])
+ (list "Radix"
+ ["Decimal"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-decimal-radix))
+ :keys "d 0"
+ :style radio
+ :selected (= calc-number-radix 10)]
+ ["Binary"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-binary-radix))
+ :keys "d 2"
+ :style radio
+ :selected (= calc-number-radix 2)]
+ ["Octal"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-octal-radix))
+ :keys "d 8"
+ :style radio
+ :selected (= calc-number-radix 8)]
+ ["Hexadecimal"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-hex-radix))
+ :keys "d 6"
+ :style radio
+ :selected (= calc-number-radix 16)]
+ ["Other"
+ (progn
+ (require 'calc-bin)
+ (call-interactively 'calc-radix))
+ :keys "d r"
+ :style radio
+ :selected (not
+ (or
+ (= calc-number-radix 10)
+ (= calc-number-radix 2)
+ (= calc-number-radix 8)
+ (= calc-number-radix 16)))])
+ (list "Float Format"
+ ["Normal"
+ (progn
+ (require 'calc-mode)
+ (call-interactively 'calc-normal-notation))
+ :keys "d n"
+ :style radio
+ :selected (eq (car-safe calc-float-format) 'float)]
+ ["Fixed point"
+ (progn
+ (require 'calc-mode)
+ (call-interactively 'calc-fix-notation))
+ :keys "d f"
+ :style radio
+ :selected (eq (car-safe calc-float-format) 'fix)]
+ ["Scientific notation"
+ (progn
+ (require 'calc-mode)
+ (call-interactively 'calc-sci-notation))
+ :keys "d s"
+ :style radio
+ :selected (eq (car-safe calc-float-format) 'sci)]
+ ["Engineering notation"
+ (progn
+ (require 'calc-mode)
+ (call-interactively 'calc-eng-notation))
+ :keys "d e"
+ :style radio
+ :selected (eq (car-safe calc-float-format) 'eng)])
+ (list "Complex Format"
+ ["Default"
+ (progn
+ (require 'calc-cplx)
+ (calc-complex-notation))
+ :style radio
+ :selected (not calc-complex-format)
+ :keys "d c"
+ :help "Display complex numbers as ordered pairs."]
+ ["i notation"
+ (progn
+ (require 'calc-cplx)
+ (calc-i-notation))
+ :style radio
+ :selected (eq calc-complex-format 'i)
+ :keys "d i"
+ :help "Display complex numbers as a+bi."]
+ ["j notation"
+ (progn
+ (require 'calc-cplx)
+ (calc-i-notation))
+ :style radio
+ :selected (eq calc-complex-format 'j)
+ :keys "d j"
+ :help "Display complex numbers as a+bj."]
+ ["Other"
+ (calc-complex-notation)
+ :style radio
+ :selected (and calc-complex-format
+ (not (eq calc-complex-format 'i))
+ (not (eq calc-complex-format 'j)))
+ :active nil]
+ "----"
+ ["Polar mode"
+ (progn
+ (require 'calc-cplx)
+ (calc-polar-mode nil))
+ :style toggle
+ :selected (eq calc-complex-mode 'polar)
+ :keys "m p"
+ :help "Prefer polar form for complex numbers."])
+ (list "Algebraic"
+ ["Normal"
+ (progn
+ (require 'calc-mode)
+ (cond
+ (calc-incomplete-algebraic-mode
+ (calc-algebraic-mode t))
+ (calc-algebraic-mode
+ (calc-algebraic-mode nil))))
+ :style radio
+ :selected (not calc-algebraic-mode)]
+ ["Algebraic mode"
+ (progn
+ (require 'calc-mode)
+ (if (or
+ calc-incomplete-algebraic-mode
+ (not calc-algebraic-mode))
+ (calc-algebraic-mode nil)))
+ :keys "m a"
+ :style radio
+ :selected (and calc-algebraic-mode
+ (not calc-incomplete-algebraic-mode))
+ :help "Keys which start numeric entry also start algebraic entry"]
+ ["Incomplete algebraic mode"
+ (progn
+ (require 'calc-mode)
+ (unless calc-incomplete-algebraic-mode
+ (calc-algebraic-mode t)))
+ :keys "C-u m a"
+ :style radio
+ :selected calc-incomplete-algebraic-mode
+ :help "Only ( and [ begin algebraic entry"]
+ ["Total algebraic mode"
+ (progn
+ (require 'calc-mode)
+ (unless (eq calc-algebraic-mode 'total)
+ (calc-total-algebraic-mode nil)))
+ :keys "m t"
+ :style radio
+ :selected (eq calc-algebraic-mode 'total)
+ :help "All regular letters and punctuation begin algebraic entry"])
+ (list "Language"
+ ["Normal"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-normal-language))
+ :keys "d N"
+ :style radio
+ :selected (eq calc-language nil)]
+ ["Big"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-big-language))
+ :keys "d B"
+ :style radio
+ :selected (eq calc-language 'big)
+ :help "Use textual approximations to various mathematical notations"]
+ ["Flat"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-flat-language))
+ :keys "d O"
+ :style radio
+ :selected (eq calc-language 'flat)
+ :help "Write matrices on a single line"]
+ ["C"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-c-language))
+ :keys "d C"
+ :style radio
+ :selected (eq calc-language 'c)]
+ ["Pascal"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-pascal-language))
+ :keys "d P"
+ :style radio
+ :selected (eq calc-language 'pascal)]
+ ["Fortran"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-fortran-language))
+ :keys "d F"
+ :style radio
+ :selected (eq calc-language 'fortran)]
+ ["TeX"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-tex-language))
+ :keys "d T"
+ :style radio
+ :selected (eq calc-language 'tex)]
+ ["LaTeX"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-latex-language))
+ :keys "d L"
+ :style radio
+ :selected (eq calc-language 'latex)]
+ ["Eqn"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-eqn-language))
+ :keys "d E"
+ :style radio
+ :selected (eq calc-language 'eqn)]
+ ["Yacas"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-yacas-language))
+ :keys "d Y"
+ :style radio
+ :selected (eq calc-language 'yacas)]
+ ["Maxima"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-maxima-language))
+ :keys "d X"
+ :style radio
+ :selected (eq calc-language 'maxima)]
+ ["Giac"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-giac-language))
+ :keys "d A"
+ :style radio
+ :selected (eq calc-language 'giac)]
+ ["Mma"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-mathematica-language))
+ :keys "d M"
+ :style radio
+ :selected (eq calc-language 'math)]
+ ["Maple"
+ (progn
+ (require 'calc-lang)
+ (call-interactively 'calc-maple-language))
+ :keys "d W"
+ :style radio
+ :selected (eq calc-language 'maple)])
+ "----"
+ ["Save mode settings" calc-save-modes :keys "m m"]
+ "----"
+ ["Help on Modes"
+ (calc-info-goto-node "Mode settings")])
+ "Menu for Calc's mode settings.")
+
+(defvar calc-help-menu
+ (list "Help"
+ ["Manual"
+ calc-info
+ :keys "h i"]
+ ["Tutorial"
+ calc-tutorial
+ :keys "h t"]
+ ["Summary"
+ calc-info-summary
+ :keys "h s"]
+ "----"
+ ["Help on Help"
+ (progn
+ (calc-info-goto-node "Introduction")
+ (Info-goto-node "Help Commands"))])
+ "Menu for Calc's help functions.")
+
+(defvar calc-mode-map)
+
+(easy-menu-define
+ calc-menu
+ calc-mode-map
+ "Menu for Calc."
+ (list "Calc"
+ :visible '(eq major-mode 'calc-mode)
+ calc-arithmetic-menu
+ calc-scientific-function-menu
+ calc-algebra-menu
+ calc-graphics-menu
+ calc-vectors-menu
+ calc-units-menu
+ calc-variables-menu
+ calc-stack-menu
+ calc-errors-menu
+ calc-modes-menu
+ calc-help-menu
+ ["Reset"
+ (progn
+ (require 'calc-ext)
+ (call-interactively 'calc-reset))
+ :help "Reset Calc to its initial state"]
+ ["Quit" calc-quit]))
+
+(provide 'calc-menu)
+
+;; arch-tag: 9612c86a-cd4f-4baa-ab0b-40af7344d21f
diff --git a/lisp/calc/calc-misc.el b/lisp/calc/calc-misc.el
index ecbc4c57190..036850e3a25 100644
--- a/lisp/calc/calc-misc.el
+++ b/lisp/calc/calc-misc.el
@@ -32,6 +32,35 @@
(require 'calc)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function calc-do-keypad "calc-keypd" (&optional full-display interactive))
+(declare-function calc-inv-hyp-prefix-help "calc-help" ())
+(declare-function calc-inverse-prefix-help "calc-help" ())
+(declare-function calc-hyperbolic-prefix-help "calc-help" ())
+(declare-function calc-explain-why "calc-stuff" (why &optional more))
+(declare-function calc-clear-command-flag "calc-ext" (f))
+(declare-function calc-roll-down-with-selections "calc-sel" (n m))
+(declare-function calc-roll-up-with-selections "calc-sel" (n m))
+(declare-function calc-last-args "calc-undo" (n))
+(declare-function calc-is-inverse "calc-ext" ())
+(declare-function calc-do-prefix-help "calc-ext" (msgs group key))
+(declare-function math-objvecp "calc-ext" (a))
+(declare-function math-known-scalarp "calc-arith" (a &optional assume-scalar))
+(declare-function math-vectorp "calc-ext" (a))
+(declare-function math-matrixp "calc-ext" (a))
+(declare-function math-trunc-special "calc-arith" (a prec))
+(declare-function math-trunc-fancy "calc-arith" (a))
+(declare-function math-floor-special "calc-arith" (a prec))
+(declare-function math-floor-fancy "calc-arith" (a))
+(declare-function math-square-matrixp "calc-ext" (a))
+(declare-function math-matrix-inv-raw "calc-mtx" (m))
+(declare-function math-known-matrixp "calc-arith" (a))
+(declare-function math-mod-fancy "calc-arith" (a b))
+(declare-function math-pow-of-zero "calc-arith" (a b))
+(declare-function math-pow-zero "calc-arith" (a b))
+(declare-function math-pow-fancy "calc-arith" (a b))
+
+
(defun calc-dispatch-help (arg)
"C-x* is a prefix key sequence; follow it with one of these letters:
@@ -145,9 +174,9 @@ Calc user interface as before (either C-x * C or C-x * K; initially C-x * C).
"Create another, independent Calculator buffer."
(interactive)
(if (eq major-mode 'calc-mode)
- (mapcar (function
- (lambda (v)
- (set-default v (symbol-value v)))) calc-local-var-list))
+ (mapc (function
+ (lambda (v)
+ (set-default v (symbol-value v)))) calc-local-var-list))
(set-buffer (generate-new-buffer "*Calculator*"))
(pop-to-buffer (current-buffer))
(calc-mode))
@@ -579,7 +608,7 @@ loaded and the keystroke automatically re-typed."
(defun math-div2-bignum (a) ; [l l]
(if (cdr a)
- (cons (+ (/ (car a) 2) (* (% (nth 1 a) 2) 500))
+ (cons (+ (/ (car a) 2) (* (% (nth 1 a) 2) (/ math-bignum-digit-size 2)))
(math-div2-bignum (cdr a)))
(list (/ (car a) 2))))
diff --git a/lisp/calc/calc-mode.el b/lisp/calc/calc-mode.el
index e315a7d475b..730a80e5a48 100644
--- a/lisp/calc/calc-mode.el
+++ b/lisp/calc/calc-mode.el
@@ -32,6 +32,10 @@
(require 'calc-ext)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function calc-embedded-save-original-modes "calc-embed" ())
+
+
(defun calc-line-numbering (n)
(interactive "P")
(calc-wrapper
@@ -501,7 +505,7 @@
mode)
(and (not (eq calc-simplify-mode mode))
mode)))
- (message (if (eq calc-simplify-mode mode)
+ (message "%s" (if (eq calc-simplify-mode mode)
msg
"Default simplifications enabled")))
diff --git a/lisp/calc/calc-nlfit.el b/lisp/calc/calc-nlfit.el
new file mode 100644
index 00000000000..4019058a567
--- /dev/null
+++ b/lisp/calc/calc-nlfit.el
@@ -0,0 +1,823 @@
+;;; calc-nlfit.el --- nonlinear curve fitting for Calc
+
+;; Copyright (C) 2007 Free Software Foundation, Inc.
+
+;; 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; 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:
+
+;; This code uses the Levenberg-Marquardt method, as described in
+;; _Numerical Analysis_ by H. R. Schwarz, to fit data to
+;; nonlinear curves. Currently, the only the following curves are
+;; supported:
+;; The logistic S curve, y=a/(1+exp(b*(t-c)))
+;; Here, y is usually interpreted as the population of some
+;; quantity at time t. So we will think of the data as consisting
+;; of quantities q0, q1, ..., qn and their respective times
+;; t0, t1, ..., tn.
+
+;; The logistic bell curve, y=A*exp(B*(t-C))/(1+exp(B*(t-C)))^2
+;; Note that this is the derivative of the formula for the S curve.
+;; We get A=-a*b, B=b and C=c. Here, y is interpreted as the rate
+;; of growth of a population at time t. So we will think of the
+;; data as consisting of rates p0, p1, ..., pn and their
+;; respective times t0, t1, ..., tn.
+
+;; The Hubbert Linearization, y/x=A*(1-x/B)
+;; Here, y is thought of as the rate of growth of a population
+;; and x represents the actual population. This is essentially
+;; the differential equation describing the actual population.
+
+;; The Levenberg-Marquardt method is an iterative process: it takes
+;; an initial guess for the parameters and refines them. To get an
+;; initial guess for the parameters, we'll use a method described by
+;; Luis de Sousa in "Hubbert's Peak Mathematics". The idea is that
+;; given quantities Q and the corresponding rates P, they should
+;; satisfy P/Q= mQ+a. We can use the parameter a for an
+;; approximation for the parameter a in the S curve, and
+;; approximations for b and c are found using least squares on the
+;; linearization log((a/y)-1) = log(bb) + cc*t of
+;; y=a/(1+bb*exp(cc*t)), which is equivalent to the above s curve
+;; formula, and then tranlating it to b and c. From this, we can
+;; also get approximations for the bell curve parameters.
+
+;;; Code:
+
+(require 'calc-arith)
+(require 'calcalg3)
+
+;; Declare functions which are defined elsewhere.
+(declare-function calc-get-fit-variables "calcalg3" (nv nc &optional defv defc with-y homog))
+(declare-function math-map-binop "calcalg3" (binop args1 args2))
+
+(defun math-nlfit-least-squares (xdata ydata &optional sdata sigmas)
+ "Return the parameters A and B for the best least squares fit y=a+bx."
+ (let* ((n (length xdata))
+ (s2data (if sdata
+ (mapcar 'calcFunc-sqr sdata)
+ (make-list n 1)))
+ (S (if sdata 0 n))
+ (Sx 0)
+ (Sy 0)
+ (Sxx 0)
+ (Sxy 0)
+ D)
+ (while xdata
+ (let ((x (car xdata))
+ (y (car ydata))
+ (s (car s2data)))
+ (setq Sx (math-add Sx (if s (math-div x s) x)))
+ (setq Sy (math-add Sy (if s (math-div y s) y)))
+ (setq Sxx (math-add Sxx (if s (math-div (math-mul x x) s)
+ (math-mul x x))))
+ (setq Sxy (math-add Sxy (if s (math-div (math-mul x y) s)
+ (math-mul x y))))
+ (if sdata
+ (setq S (math-add S (math-div 1 s)))))
+ (setq xdata (cdr xdata))
+ (setq ydata (cdr ydata))
+ (setq s2data (cdr s2data)))
+ (setq D (math-sub (math-mul S Sxx) (math-mul Sx Sx)))
+ (let ((A (math-div (math-sub (math-mul Sxx Sy) (math-mul Sx Sxy)) D))
+ (B (math-div (math-sub (math-mul S Sxy) (math-mul Sx Sy)) D)))
+ (if sigmas
+ (let ((C11 (math-div Sxx D))
+ (C12 (math-neg (math-div Sx D)))
+ (C22 (math-div S D)))
+ (list (list 'sdev A (calcFunc-sqrt C11))
+ (list 'sdev B (calcFunc-sqrt C22))
+ (list 'vec
+ (list 'vec C11 C12)
+ (list 'vec C12 C22))))
+ (list A B)))))
+
+;;; The methods described by de Sousa require the cumulative data qdata
+;;; and the rates pdata. We will assume that we are given either
+;;; qdata and the corresponding times tdata, or pdata and the corresponding
+;;; tdata. The following two functions will find pdata or qdata,
+;;; given the other..
+
+;;; First, given two lists; one of values q0, q1, ..., qn and one of
+;;; corresponding times t0, t1, ..., tn; return a list
+;;; p0, p1, ..., pn of the rates of change of the qi with respect to t.
+;;; p0 is the right hand derivative (q1 - q0)/(t1 - t0).
+;;; pn is the left hand derivative (qn - q(n-1))/(tn - t(n-1)).
+;;; The other pis are the averages of the two:
+;;; (1/2)((qi - q(i-1))/(ti - t(i-1)) + (q(i+1) - qi)/(t(i+1) - ti)).
+
+(defun math-nlfit-get-rates-from-cumul (tdata qdata)
+ (let ((pdata (list
+ (math-div
+ (math-sub (nth 1 qdata)
+ (nth 0 qdata))
+ (math-sub (nth 1 tdata)
+ (nth 0 tdata))))))
+ (while (> (length qdata) 2)
+ (setq pdata
+ (cons
+ (math-mul
+ '(float 5 -1)
+ (math-add
+ (math-div
+ (math-sub (nth 2 qdata)
+ (nth 1 qdata))
+ (math-sub (nth 2 tdata)
+ (nth 1 tdata)))
+ (math-div
+ (math-sub (nth 1 qdata)
+ (nth 0 qdata))
+ (math-sub (nth 1 tdata)
+ (nth 0 tdata)))))
+ pdata))
+ (setq qdata (cdr qdata)))
+ (setq pdata
+ (cons
+ (math-div
+ (math-sub (nth 1 qdata)
+ (nth 0 qdata))
+ (math-sub (nth 1 tdata)
+ (nth 0 tdata)))
+ pdata))
+ (reverse pdata)))
+
+;;; Next, given two lists -- one of rates p0, p1, ..., pn and one of
+;;; corresponding times t0, t1, ..., tn -- and an initial values q0,
+;;; return a list q0, q1, ..., qn of the cumulative values.
+;;; q0 is the initial value given.
+;;; For i>0, qi is computed using the trapezoid rule:
+;;; qi = q(i-1) + (1/2)(pi + p(i-1))(ti - t(i-1))
+
+(defun math-nlfit-get-cumul-from-rates (tdata pdata q0)
+ (let* ((qdata (list q0)))
+ (while (cdr pdata)
+ (setq qdata
+ (cons
+ (math-add (car qdata)
+ (math-mul
+ (math-mul
+ '(float 5 -1)
+ (math-add (nth 1 pdata) (nth 0 pdata)))
+ (math-sub (nth 1 tdata)
+ (nth 0 tdata))))
+ qdata))
+ (setq pdata (cdr pdata))
+ (setq tdata (cdr tdata)))
+ (reverse qdata)))
+
+;;; Given the qdata, pdata and tdata, find the parameters
+;;; a, b and c that fit q = a/(1+b*exp(c*t)).
+;;; a is found using the method described by de Sousa.
+;;; b and c are found using least squares on the linearization
+;;; log((a/q)-1) = log(b) + c*t
+;;; In some cases (where the logistic curve may well be the wrong
+;;; model), the computed a will be less than or equal to the maximum
+;;; value of q in qdata; in which case the above linearization won't work.
+;;; In this case, a will be replaced by a number slightly above
+;;; the maximum value of q.
+
+(defun math-nlfit-find-qmax (qdata pdata tdata)
+ (let* ((ratios (math-map-binop 'math-div pdata qdata))
+ (lsdata (math-nlfit-least-squares ratios tdata))
+ (qmax (math-max-list (car qdata) (cdr qdata)))
+ (a (math-neg (math-div (nth 1 lsdata) (nth 0 lsdata)))))
+ (if (math-lessp a qmax)
+ (math-add '(float 5 -1) qmax)
+ a)))
+
+(defun math-nlfit-find-logistic-parameters (qdata pdata tdata)
+ (let* ((a (math-nlfit-find-qmax qdata pdata tdata))
+ (newqdata
+ (mapcar (lambda (q) (calcFunc-ln (math-sub (math-div a q) 1)))
+ qdata))
+ (bandc (math-nlfit-least-squares tdata newqdata)))
+ (list
+ a
+ (calcFunc-exp (nth 0 bandc))
+ (nth 1 bandc))))
+
+;;; Next, given the pdata and tdata, we can find the qdata if we know q0.
+;;; We first try to find q0, using the fact that when p takes on its largest
+;;; value, q is half of its maximum value. So we'll find the maximum value
+;;; of q given various q0, and use bisection to approximate the correct q0.
+
+;;; First, given pdata and tdata, find what half of qmax would be if q0=0.
+
+(defun math-nlfit-find-qmaxhalf (pdata tdata)
+ (let ((pmax (math-max-list (car pdata) (cdr pdata)))
+ (qmh 0))
+ (while (math-lessp (car pdata) pmax)
+ (setq qmh
+ (math-add qmh
+ (math-mul
+ (math-mul
+ '(float 5 -1)
+ (math-add (nth 1 pdata) (nth 0 pdata)))
+ (math-sub (nth 1 tdata)
+ (nth 0 tdata)))))
+ (setq pdata (cdr pdata))
+ (setq tdata (cdr tdata)))
+ qmh))
+
+;;; Next, given pdata and tdata, approximate q0.
+
+(defun math-nlfit-find-q0 (pdata tdata)
+ (let* ((qhalf (math-nlfit-find-qmaxhalf pdata tdata))
+ (q0 (math-mul 2 qhalf))
+ (qdata (math-nlfit-get-cumul-from-rates tdata pdata q0)))
+ (while (math-lessp (math-nlfit-find-qmax
+ (mapcar
+ (lambda (q) (math-add q0 q))
+ qdata)
+ pdata tdata)
+ (math-mul
+ '(float 5 -1)
+ (math-add
+ q0
+ qhalf)))
+ (setq q0 (math-add q0 qhalf)))
+ (let* ((qmin (math-sub q0 qhalf))
+ (qmax q0)
+ (qt (math-nlfit-find-qmax
+ (mapcar
+ (lambda (q) (math-add q0 q))
+ qdata)
+ pdata tdata))
+ (i 0))
+ (while (< i 10)
+ (setq q0 (math-mul '(float 5 -1) (math-add qmin qmax)))
+ (if (math-lessp
+ (math-nlfit-find-qmax
+ (mapcar
+ (lambda (q) (math-add q0 q))
+ qdata)
+ pdata tdata)
+ (math-mul '(float 5 -1) (math-add qhalf q0)))
+ (setq qmin q0)
+ (setq qmax q0))
+ (setq i (1+ i)))
+ (math-mul '(float 5 -1) (math-add qmin qmax)))))
+
+;;; To improve the approximations to the parameters, we can use
+;;; Marquardt method as described in Schwarz's book.
+
+;;; Small numbers used in the Givens algorithm
+(defvar math-nlfit-delta '(float 1 -8))
+
+(defvar math-nlfit-epsilon '(float 1 -5))
+
+;;; Maximum number of iterations
+(defvar math-nlfit-max-its 100)
+
+;;; Next, we need some functions for dealing with vectors and
+;;; matrices. For convenience, we'll work with Emacs lists
+;;; as vectors, rather than Calc's vectors.
+
+(defun math-nlfit-set-elt (vec i x)
+ (setcar (nthcdr (1- i) vec) x))
+
+(defun math-nlfit-get-elt (vec i)
+ (nth (1- i) vec))
+
+(defun math-nlfit-make-matrix (i j)
+ (let ((row (make-list j 0))
+ (mat nil)
+ (k 0))
+ (while (< k i)
+ (setq mat (cons (copy-sequence row) mat))
+ (setq k (1+ k)))
+ mat))
+
+(defun math-nlfit-set-matx-elt (mat i j x)
+ (setcar (nthcdr (1- j) (nth (1- i) mat)) x))
+
+(defun math-nlfit-get-matx-elt (mat i j)
+ (nth (1- j) (nth (1- i) mat)))
+
+;;; For solving the linearized system.
+;;; (The Givens method, from Schwarz.)
+
+(defun math-nlfit-givens (C d)
+ (let* ((C (copy-tree C))
+ (d (copy-tree d))
+ (n (length (car C)))
+ (N (length C))
+ (j 1)
+ (r (make-list N 0))
+ (x (make-list N 0))
+ w
+ gamma
+ sigma
+ rho)
+ (while (<= j n)
+ (let ((i (1+ j)))
+ (while (<= i N)
+ (let ((cij (math-nlfit-get-matx-elt C i j))
+ (cjj (math-nlfit-get-matx-elt C j j)))
+ (when (not (math-equal 0 cij))
+ (if (math-lessp (calcFunc-abs cjj)
+ (math-mul math-nlfit-delta (calcFunc-abs cij)))
+ (setq w (math-neg cij)
+ gamma 0
+ sigma 1
+ rho 1)
+ (setq w (math-mul
+ (calcFunc-sign cjj)
+ (calcFunc-sqrt
+ (math-add
+ (math-mul cjj cjj)
+ (math-mul cij cij))))
+ gamma (math-div cjj w)
+ sigma (math-neg (math-div cij w)))
+ (if (math-lessp (calcFunc-abs sigma) gamma)
+ (setq rho sigma)
+ (setq rho (math-div (calcFunc-sign sigma) gamma))))
+ (setq cjj w
+ cij rho)
+ (math-nlfit-set-matx-elt C j j w)
+ (math-nlfit-set-matx-elt C i j rho)
+ (let ((k (1+ j)))
+ (while (<= k n)
+ (let* ((cjk (math-nlfit-get-matx-elt C j k))
+ (cik (math-nlfit-get-matx-elt C i k))
+ (h (math-sub
+ (math-mul gamma cjk) (math-mul sigma cik))))
+ (setq cik (math-add
+ (math-mul sigma cjk)
+ (math-mul gamma cik)))
+ (setq cjk h)
+ (math-nlfit-set-matx-elt C i k cik)
+ (math-nlfit-set-matx-elt C j k cjk)
+ (setq k (1+ k)))))
+ (let* ((di (math-nlfit-get-elt d i))
+ (dj (math-nlfit-get-elt d j))
+ (h (math-sub
+ (math-mul gamma dj)
+ (math-mul sigma di))))
+ (setq di (math-add
+ (math-mul sigma dj)
+ (math-mul gamma di)))
+ (setq dj h)
+ (math-nlfit-set-elt d i di)
+ (math-nlfit-set-elt d j dj))))
+ (setq i (1+ i))))
+ (setq j (1+ j)))
+ (let ((i n)
+ s)
+ (while (>= i 1)
+ (math-nlfit-set-elt r i 0)
+ (setq s (math-nlfit-get-elt d i))
+ (let ((k (1+ i)))
+ (while (<= k n)
+ (setq s (math-add s (math-mul (math-nlfit-get-matx-elt C i k)
+ (math-nlfit-get-elt x k))))
+ (setq k (1+ k))))
+ (math-nlfit-set-elt x i
+ (math-neg
+ (math-div s
+ (math-nlfit-get-matx-elt C i i))))
+ (setq i (1- i))))
+ (let ((i (1+ n)))
+ (while (<= i N)
+ (math-nlfit-set-elt r i (math-nlfit-get-elt d i))
+ (setq i (1+ i))))
+ (let ((j n))
+ (while (>= j 1)
+ (let ((i N))
+ (while (>= i (1+ j))
+ (setq rho (math-nlfit-get-matx-elt C i j))
+ (if (math-equal rho 1)
+ (setq gamma 0
+ sigma 1)
+ (if (math-lessp (calcFunc-abs rho) 1)
+ (setq sigma rho
+ gamma (calcFunc-sqrt
+ (math-sub 1 (math-mul sigma sigma))))
+ (setq gamma (math-div 1 (calcFunc-abs rho))
+ sigma (math-mul (calcFunc-sign rho)
+ (calcFunc-sqrt
+ (math-sub 1 (math-mul gamma gamma)))))))
+ (let ((ri (math-nlfit-get-elt r i))
+ (rj (math-nlfit-get-elt r j))
+ h)
+ (setq h (math-add (math-mul gamma rj)
+ (math-mul sigma ri)))
+ (setq ri (math-sub
+ (math-mul gamma ri)
+ (math-mul sigma rj)))
+ (setq rj h)
+ (math-nlfit-set-elt r i ri)
+ (math-nlfit-set-elt r j rj))
+ (setq i (1- i))))
+ (setq j (1- j))))
+
+ x))
+
+(defun math-nlfit-jacobian (grad xlist parms &optional slist)
+ (let ((j nil))
+ (while xlist
+ (let ((row (apply grad (car xlist) parms)))
+ (setq j
+ (cons
+ (if slist
+ (mapcar (lambda (x) (math-div x (car slist))) row)
+ row)
+ j)))
+ (setq slist (cdr slist))
+ (setq xlist (cdr xlist)))
+ (reverse j)))
+
+(defun math-nlfit-make-ident (l n)
+ (let ((m (math-nlfit-make-matrix n n))
+ (i 1))
+ (while (<= i n)
+ (math-nlfit-set-matx-elt m i i l)
+ (setq i (1+ i)))
+ m))
+
+(defun math-nlfit-chi-sq (xlist ylist parms fn &optional slist)
+ (let ((cs 0))
+ (while xlist
+ (let ((c
+ (math-sub
+ (apply fn (car xlist) parms)
+ (car ylist))))
+ (if slist
+ (setq c (math-div c (car slist))))
+ (setq cs
+ (math-add cs
+ (math-mul c c))))
+ (setq xlist (cdr xlist))
+ (setq ylist (cdr ylist))
+ (setq slist (cdr slist)))
+ cs))
+
+(defun math-nlfit-init-lambda (C)
+ (let ((l 0)
+ (n (length (car C)))
+ (N (length C)))
+ (while C
+ (let ((row (car C)))
+ (while row
+ (setq l (math-add l (math-mul (car row) (car row))))
+ (setq row (cdr row))))
+ (setq C (cdr C)))
+ (calcFunc-sqrt (math-div l (math-mul n N)))))
+
+(defun math-nlfit-make-Ctilda (C l)
+ (let* ((n (length (car C)))
+ (bot (math-nlfit-make-ident l n)))
+ (append C bot)))
+
+(defun math-nlfit-make-d (fn xdata ydata parms &optional sdata)
+ (let ((d nil))
+ (while xdata
+ (setq d (cons
+ (let ((dd (math-sub (apply fn (car xdata) parms)
+ (car ydata))))
+ (if sdata (math-div dd (car sdata)) dd))
+ d))
+ (setq xdata (cdr xdata))
+ (setq ydata (cdr ydata))
+ (setq sdata (cdr sdata)))
+ (reverse d)))
+
+(defun math-nlfit-make-dtilda (d n)
+ (append d (make-list n 0)))
+
+(defun math-nlfit-fit (xlist ylist parms fn grad &optional slist)
+ (let*
+ ((C (math-nlfit-jacobian grad xlist parms slist))
+ (d (math-nlfit-make-d fn xlist ylist parms slist))
+ (chisq (math-nlfit-chi-sq xlist ylist parms fn slist))
+ (lambda (math-nlfit-init-lambda C))
+ (really-done nil)
+ (iters 0))
+ (while (and
+ (not really-done)
+ (< iters math-nlfit-max-its))
+ (setq iters (1+ iters))
+ (let ((done nil))
+ (while (not done)
+ (let* ((Ctilda (math-nlfit-make-Ctilda C lambda))
+ (dtilda (math-nlfit-make-dtilda d (length (car C))))
+ (zeta (math-nlfit-givens Ctilda dtilda))
+ (newparms (math-map-binop 'math-add (copy-tree parms) zeta))
+ (newchisq (math-nlfit-chi-sq xlist ylist newparms fn slist)))
+ (if (math-lessp newchisq chisq)
+ (progn
+ (if (math-lessp
+ (math-div
+ (math-sub chisq newchisq) newchisq) math-nlfit-epsilon)
+ (setq really-done t))
+ (setq lambda (math-div lambda 10))
+ (setq chisq newchisq)
+ (setq parms newparms)
+ (setq done t))
+ (setq lambda (math-mul lambda 10)))))
+ (setq C (math-nlfit-jacobian grad xlist parms slist))
+ (setq d (math-nlfit-make-d fn xlist ylist parms slist))))
+ (list chisq parms)))
+
+;;; The functions that describe our models, and their gradients.
+
+(defun math-nlfit-s-logistic-fn (x a b c)
+ (math-div a (math-add 1 (math-mul b (calcFunc-exp (math-mul c x))))))
+
+(defun math-nlfit-s-logistic-grad (x a b c)
+ (let* ((ep (calcFunc-exp (math-mul c x)))
+ (d (math-add 1 (math-mul b ep)))
+ (d2 (math-mul d d)))
+ (list
+ (math-div 1 d)
+ (math-neg (math-div (math-mul a ep) d2))
+ (math-neg (math-div (math-mul a (math-mul b (math-mul x ep))) d2)))))
+
+(defun math-nlfit-b-logistic-fn (x a c d)
+ (let ((ex (calcFunc-exp (math-mul c (math-sub x d)))))
+ (math-div
+ (math-mul a ex)
+ (math-sqr
+ (math-add
+ 1 ex)))))
+
+(defun math-nlfit-b-logistic-grad (x a c d)
+ (let* ((ex (calcFunc-exp (math-mul c (math-sub x d))))
+ (ex1 (math-add 1 ex))
+ (xd (math-sub x d)))
+ (list
+ (math-div
+ ex
+ (math-sqr ex1))
+ (math-sub
+ (math-div
+ (math-mul a (math-mul xd ex))
+ (math-sqr ex1))
+ (math-div
+ (math-mul 2 (math-mul a (math-mul xd (math-sqr ex))))
+ (math-pow ex1 3)))
+ (math-sub
+ (math-div
+ (math-mul 2 (math-mul a (math-mul c (math-sqr ex))))
+ (math-pow ex1 3))
+ (math-div
+ (math-mul a (math-mul c ex))
+ (math-sqr ex1))))))
+
+;;; Functions to get the final covariance matrix and the sdevs
+
+(defun math-nlfit-find-covar (grad xlist pparms)
+ (let ((j nil))
+ (while xlist
+ (setq j (cons (cons 'vec (apply grad (car xlist) pparms)) j))
+ (setq xlist (cdr xlist)))
+ (setq j (cons 'vec (reverse j)))
+ (setq j
+ (math-mul
+ (calcFunc-trn j) j))
+ (calcFunc-inv j)))
+
+(defun math-nlfit-get-sigmas (grad xlist pparms chisq)
+ (let* ((sgs nil)
+ (covar (math-nlfit-find-covar grad xlist pparms))
+ (n (1- (length covar)))
+ (N (length xlist))
+ (i 1))
+ (when (> N n)
+ (while (<= i n)
+ (setq sgs (cons (calcFunc-sqrt (nth i (nth i covar))) sgs))
+ (setq i (1+ i)))
+ (setq sgs (reverse sgs)))
+ (list sgs covar)))
+
+;;; Now the Calc functions
+
+(defun math-nlfit-s-logistic-params (xdata ydata)
+ (let ((pdata (math-nlfit-get-rates-from-cumul xdata ydata)))
+ (math-nlfit-find-logistic-parameters ydata pdata xdata)))
+
+(defun math-nlfit-b-logistic-params (xdata ydata)
+ (let* ((q0 (math-nlfit-find-q0 ydata xdata))
+ (qdata (math-nlfit-get-cumul-from-rates xdata ydata q0))
+ (abc (math-nlfit-find-logistic-parameters qdata ydata xdata))
+ (B (nth 1 abc))
+ (C (nth 2 abc))
+ (A (math-neg
+ (math-mul
+ (nth 0 abc)
+ (math-mul B C))))
+ (D (math-neg (math-div (calcFunc-ln B) C)))
+ (A (math-div A B)))
+ (list A C D)))
+
+;;; Some functions to turn the parameter lists and variables
+;;; into the appropriate functions.
+
+(defun math-nlfit-s-logistic-solnexpr (pms var)
+ (let ((a (nth 0 pms))
+ (b (nth 1 pms))
+ (c (nth 2 pms)))
+ (list '/ a
+ (list '+
+ 1
+ (list '*
+ b
+ (calcFunc-exp
+ (list '*
+ c
+ var)))))))
+
+(defun math-nlfit-b-logistic-solnexpr (pms var)
+ (let ((a (nth 0 pms))
+ (c (nth 1 pms))
+ (d (nth 2 pms)))
+ (list '/
+ (list '*
+ a
+ (calcFunc-exp
+ (list '*
+ c
+ (list '- var d))))
+ (list '^
+ (list '+
+ 1
+ (calcFunc-exp
+ (list '*
+ c
+ (list '- var d))))
+ 2))))
+
+(defun math-nlfit-enter-result (n prefix vals)
+ (setq calc-aborted-prefix prefix)
+ (calc-pop-push-record-list n prefix vals)
+ (calc-handle-whys))
+
+(defun math-nlfit-fit-curve (fn grad solnexpr initparms &optional sdv)
+ (calc-slow-wrapper
+ (let* ((sdevv (or (eq sdv 'calcFunc-efit) (eq sdv 'calcFunc-xfit)))
+ (calc-display-working-message nil)
+ (data (calc-top 1))
+ (xdata (cdr (car (cdr data))))
+ (ydata (cdr (car (cdr (cdr data)))))
+ (sdata (if (math-contains-sdev-p ydata)
+ (mapcar (lambda (x) (math-get-sdev x t)) ydata)
+ nil))
+ (ydata (mapcar (lambda (x) (math-get-value x)) ydata))
+ (calc-curve-varnames nil)
+ (calc-curve-coefnames nil)
+ (calc-curve-nvars 1)
+ (fitvars (calc-get-fit-variables 1 3))
+ (var (nth 1 calc-curve-varnames))
+ (parms (cdr calc-curve-coefnames))
+ (parmguess
+ (funcall initparms xdata ydata))
+ (fit (math-nlfit-fit xdata ydata parmguess fn grad sdata))
+ (finalparms (nth 1 fit))
+ (sigmacovar
+ (if sdevv
+ (math-nlfit-get-sigmas grad xdata finalparms (nth 0 fit))))
+ (sigmas
+ (if sdevv
+ (nth 0 sigmacovar)))
+ (finalparms
+ (if sigmas
+ (math-map-binop
+ (lambda (x y) (list 'sdev x y)) finalparms sigmas)
+ finalparms))
+ (soln (funcall solnexpr finalparms var)))
+ (let ((calc-fit-to-trail t)
+ (traillist nil))
+ (while parms
+ (setq traillist (cons (list 'calcFunc-eq (car parms) (car finalparms))
+ traillist))
+ (setq finalparms (cdr finalparms))
+ (setq parms (cdr parms)))
+ (setq traillist (calc-normalize (cons 'vec (nreverse traillist))))
+ (cond ((eq sdv 'calcFunc-efit)
+ (math-nlfit-enter-result 1 "efit" soln))
+ ((eq sdv 'calcFunc-xfit)
+ (let (sln)
+ (setq sln
+ (list 'vec
+ soln
+ traillist
+ (nth 1 sigmacovar)
+ '(vec)
+ (nth 0 fit)
+ (let ((n (length xdata))
+ (m (length finalparms)))
+ (if (and sdata (> n m))
+ (calcFunc-utpc (nth 0 fit)
+ (- n m))
+ '(var nan var-nan)))))
+ (math-nlfit-enter-result 1 "xfit" sln)))
+ (t
+ (math-nlfit-enter-result 1 "fit" soln)))
+ (calc-record traillist "parm")))))
+
+(defun calc-fit-s-shaped-logistic-curve (arg)
+ (interactive "P")
+ (math-nlfit-fit-curve 'math-nlfit-s-logistic-fn
+ 'math-nlfit-s-logistic-grad
+ 'math-nlfit-s-logistic-solnexpr
+ 'math-nlfit-s-logistic-params
+ arg))
+
+(defun calc-fit-bell-shaped-logistic-curve (arg)
+ (interactive "P")
+ (math-nlfit-fit-curve 'math-nlfit-b-logistic-fn
+ 'math-nlfit-b-logistic-grad
+ 'math-nlfit-b-logistic-solnexpr
+ 'math-nlfit-b-logistic-params
+ arg))
+
+(defun calc-fit-hubbert-linear-curve (&optional sdv)
+ (calc-slow-wrapper
+ (let* ((sdevv (or (eq sdv 'calcFunc-efit) (eq sdv 'calcFunc-xfit)))
+ (calc-display-working-message nil)
+ (data (calc-top 1))
+ (qdata (cdr (car (cdr data))))
+ (pdata (cdr (car (cdr (cdr data)))))
+ (sdata (if (math-contains-sdev-p pdata)
+ (mapcar (lambda (x) (math-get-sdev x t)) pdata)
+ nil))
+ (pdata (mapcar (lambda (x) (math-get-value x)) pdata))
+ (poverqdata (math-map-binop 'math-div pdata qdata))
+ (parmvals (math-nlfit-least-squares qdata poverqdata sdata sdevv))
+ (finalparms (list (nth 0 parmvals)
+ (math-neg
+ (math-div (nth 0 parmvals)
+ (nth 1 parmvals)))))
+ (calc-curve-varnames nil)
+ (calc-curve-coefnames nil)
+ (calc-curve-nvars 1)
+ (fitvars (calc-get-fit-variables 1 2))
+ (var (nth 1 calc-curve-varnames))
+ (parms (cdr calc-curve-coefnames))
+ (soln (list '* (nth 0 finalparms)
+ (list '- 1
+ (list '/ var (nth 1 finalparms))))))
+ (let ((calc-fit-to-trail t)
+ (traillist nil))
+ (setq traillist
+ (list 'vec
+ (list 'calcFunc-eq (nth 0 parms) (nth 0 finalparms))
+ (list 'calcFunc-eq (nth 1 parms) (nth 1 finalparms))))
+ (cond ((eq sdv 'calcFunc-efit)
+ (math-nlfit-enter-result 1 "efit" soln))
+ ((eq sdv 'calcFunc-xfit)
+ (let (sln
+ (chisq
+ (math-nlfit-chi-sq
+ qdata poverqdata
+ (list (nth 1 (nth 0 finalparms))
+ (nth 1 (nth 1 finalparms)))
+ (lambda (x a b)
+ (math-mul a
+ (math-sub
+ 1
+ (math-div x b))))
+ sdata)))
+ (setq sln
+ (list 'vec
+ soln
+ traillist
+ (nth 2 parmvals)
+ (list
+ 'vec
+ '(calcFunc-fitdummy 1)
+ (list 'calcFunc-neg
+ (list '/
+ '(calcFunc-fitdummy 1)
+ '(calcFunc-fitdummy 2))))
+ chisq
+ (let ((n (length qdata)))
+ (if (and sdata (> n 2))
+ (calcFunc-utpc
+ chisq
+ (- n 2))
+ '(var nan var-nan)))))
+ (math-nlfit-enter-result 1 "xfit" sln)))
+ (t
+ (math-nlfit-enter-result 1 "fit" soln)))
+ (calc-record traillist "parm")))))
+
+(provide 'calc-nlfit)
+
+;; arch-tag: 6eba3cd6-f48b-4a84-8174-10c15a024928
diff --git a/lisp/calc/calc-poly.el b/lisp/calc/calc-poly.el
index 29396a57dc1..608d16fbab8 100644
--- a/lisp/calc/calc-poly.el
+++ b/lisp/calc/calc-poly.el
@@ -982,10 +982,16 @@
(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))))
(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)
diff --git a/lisp/calc/calc-prog.el b/lisp/calc/calc-prog.el
index e5642002be0..124558c4ca0 100644
--- a/lisp/calc/calc-prog.el
+++ b/lisp/calc/calc-prog.el
@@ -32,6 +32,11 @@
(require 'calc-ext)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function edmacro-format-keys "edmacro" (macro &optional verbose))
+(declare-function edmacro-parse-keys "edmacro" (string &optional need-vector))
+(declare-function math-read-expr-level "calc-aent" (exp-prec &optional exp-term))
+
(defun calc-equal-to (arg)
(interactive "P")
@@ -568,7 +573,7 @@
(set-buffer calc-buf)
(let ((calc-user-parse-tables nil)
(calc-language nil)
- (math-expr-opers math-standard-opers)
+ (math-expr-opers (math-standard-ops))
(calc-hashes-used 0))
(math-read-expr
(if (string-match ",[ \t]*\\'" str)
diff --git a/lisp/calc/calc-store.el b/lisp/calc/calc-store.el
index 6191a0f2e05..5ffabe4adba 100644
--- a/lisp/calc/calc-store.el
+++ b/lisp/calc/calc-store.el
@@ -127,7 +127,7 @@
(cond
((and (memq var '(var-e var-i var-pi var-phi var-gamma))
(eq (car-safe old) 'special-const))
- (setq msg (format " (Note: Built-in definition of %s has been lost)"
+ (setq msg (format " (Note: Built-in definition of %s has been lost)"
(calc-var-name var))))
((and (memq var '(var-inf var-uinf var-nan))
(null old))
@@ -172,28 +172,28 @@
()
(setq calc-var-name-map (copy-keymap minibuffer-local-completion-map))
(define-key calc-var-name-map " " 'self-insert-command)
- (mapcar (function
- (lambda (x)
- (define-key calc-var-name-map (char-to-string x)
- 'calcVar-digit)))
- "0123456789")
- (mapcar (function
- (lambda (x)
- (define-key calc-var-name-map (char-to-string x)
- 'calcVar-oper)))
- "+-*/^|"))
+ (mapc (function
+ (lambda (x)
+ (define-key calc-var-name-map (char-to-string x)
+ 'calcVar-digit)))
+ "0123456789")
+ (mapc (function
+ (lambda (x)
+ (define-key calc-var-name-map (char-to-string x)
+ 'calcVar-oper)))
+ "+-*/^|"))
(defvar calc-store-opers)
(defun calc-read-var-name (prompt &optional calc-store-opers)
(setq calc-given-value nil
calc-aborted-prefix nil)
- (let ((var (concat
+ (let ((var (concat
"var-"
(let ((minibuffer-completion-table
- (mapcar (lambda (x) (substring x 4))
+ (mapcar (lambda (x) (substring x 4))
(all-completions "var-" obarray)))
- (minibuffer-completion-predicate
+ (minibuffer-completion-predicate
(lambda (x) (boundp (intern (concat "var-" x)))))
(minibuffer-completion-confirm t))
(read-from-minibuffer prompt nil calc-var-name-map nil)))))
@@ -401,7 +401,7 @@
(unless (string= sconst "")
(let ((value (cdr (assoc sconst sc))))
(or var (setq var (calc-read-var-name
- (format "Copy special constant %s, to: "
+ (format "Copy special constant %s, to: "
sconst))))
(if var
(let ((msg (calc-store-value var value "")))
@@ -417,7 +417,7 @@
(or value
(error "No such variable: \"%s\"" (calc-var-name var1)))
(or var2 (setq var2 (calc-read-var-name
- (format "Copy variable: %s, to: "
+ (format "Copy variable: %s, to: "
(calc-var-name var1)))))
(if var2
(let ((msg (calc-store-value var2 value "")))
diff --git a/lisp/calc/calc-stuff.el b/lisp/calc/calc-stuff.el
index 10002dcb4e5..8840ad827e1 100644
--- a/lisp/calc/calc-stuff.el
+++ b/lisp/calc/calc-stuff.el
@@ -191,7 +191,7 @@ With a prefix, push that prefix as a number onto the stack."
math-eval-rules-cache-tag t
math-format-date-cache nil
math-holidays-cache-tag t)
- (mapcar (function (lambda (x) (set x -100))) math-cache-list)
+ (mapc (function (lambda (x) (set x -100))) math-cache-list)
(unless inhibit-msg
(message "All internal calculator caches have been reset"))))
diff --git a/lisp/calc/calc-units.el b/lisp/calc/calc-units.el
index f648a37cb7f..27d76fe4b8a 100644
--- a/lisp/calc/calc-units.el
+++ b/lisp/calc/calc-units.el
@@ -40,45 +40,47 @@
;;; with some additions by Przemek Klosowski (przemek@rrdstrad.nist.gov)
;;; Updated April 2002 by Jochen Küpper
-;;; for CODATA 1998 see one of
-;;; - Journal of Physical and Chemical Reference Data, 28(6), 1713-1852, 1999.
-;;; - Reviews of Modern Physics, 72(2), 351-495, 2000.
-;;; for CODATA 2005 see
-;;; - http://physics.nist.gov/cuu/Constants/index.html
+;;; Updated August 2007, using
+;;; CODATA (http://physics.nist.gov/cuu/Constants/index.html)
+;;; NIST (http://physics.nist.gov/Pubs/SP811/appenB9.html)
+;;; ESUWM (Encyclopaedia of Scientific Units, Weights and
+;;; Measures, by François Cardarelli)
+;;; All conversions are exact unless otherwise noted.
(defvar math-standard-units
'( ;; Length
( m nil "*Meter" )
- ( in "2.54 cm" "Inch" )
+ ( in "254*10^(-2) cm" "Inch" )
( ft "12 in" "Foot" )
( yd "3 ft" "Yard" )
( mi "5280 ft" "Mile" )
- ( au "149597870691 m" "Astronomical Unit" ) ;; NASA JPL (http://neo.jpl.nasa.gov/glossary/au.html)
- ( lyr "9460536207068016 m" "Light Year" )
- ( pc "206264.80625 au" "Parsec" )
+ ( au "149597870691. m" "Astronomical Unit" )
+ ;; (approx) NASA JPL (http://neo.jpl.nasa.gov/glossary/au.html)
+ ( lyr "c yr" "Light Year" )
+ ( pc "3.0856775854e16 m" "Parsec" ) ;; (approx) ESUWM
( nmi "1852 m" "Nautical Mile" )
( fath "6 ft" "Fathom" )
( mu "1 um" "Micron" )
( mil "in/1000" "Mil" )
( point "in/72" "Point (1/72 inch)" )
- ( Ang "1e-10 m" "Angstrom" )
+ ( Ang "10^(-10) m" "Angstrom" )
( mfi "mi+ft+in" "Miles + feet + inches" )
;; TeX lengths
- ( texpt "in/72.27" "Point (TeX conventions)" )
+ ( texpt "(100/7227) in" "Point (TeX conventions)" )
( texpc "12 texpt" "Pica" )
( texbp "point" "Big point (TeX conventions)" )
- ( texdd "1238/1157 texpt" "Didot point" )
+ ( texdd "(1238/1157) texpt" "Didot point" )
( texcc "12 texdd" "Cicero" )
- ( texsp "1/66536 texpt" "Scaled TeX point" )
+ ( texsp "(1/65536) texpt" "Scaled TeX point" )
;; Area
( hect "10000 m^2" "*Hectare" )
( a "100 m^2" "Are")
( acre "mi^2 / 640" "Acre" )
- ( b "1e-28 m^2" "Barn" )
+ ( b "10^(-28) m^2" "Barn" )
;; Volume
- ( L "1e-3 m^3" "*Liter" )
+ ( L "10^(-3) m^3" "*Liter" )
( l "L" "Liter" )
( gal "4 qt" "US Gallon" )
( qt "2 pt" "Quart" )
@@ -87,10 +89,12 @@
( ozfl "2 tbsp" "Fluid Ounce" )
( floz "2 tbsp" "Fluid Ounce" )
( tbsp "3 tsp" "Tablespoon" )
- ( tsp "4.92892159375 ml" "Teaspoon" )
+ ;; ESUWM defines a US gallon as 231 in^3.
+ ;; That gives the following exact value for tsp.
+ ( tsp "492892159375*10^(-11) ml" "Teaspoon" )
( vol "tsp+tbsp+ozfl+cup+pt+qt+gal" "Gallons + ... + teaspoons" )
- ( galC "4.54609 L" "Canadian Gallon" )
- ( galUK "4.546092 L" "UK Gallon" )
+ ( galC "galUK" "Canadian Gallon" )
+ ( galUK "454609*10^(-5) L" "UK Gallon" ) ;; NIST
;; Time
( s nil "*Second" )
@@ -100,44 +104,44 @@
( day "24 hr" "Day" )
( wk "7 day" "Week" )
( hms "wk+day+hr+min+s" "Hours, minutes, seconds" )
- ( yr "365.25 day" "Year" )
+ ( yr "365.25 day" "Year" ) ;; (approx, but keep)
( Hz "1/s" "Hertz" )
;; Speed
( mph "mi/hr" "*Miles per hour" )
( kph "km/hr" "Kilometers per hour" )
( knot "nmi/hr" "Knot" )
- ( c "299792458 m/s" "Speed of light" ) ;;; CODATA 2005
+ ( c "299792458 m/s" "Speed of light" ) ;;; CODATA
;; Acceleration
- ( ga "9.80665 m/s^2" "*\"g\" acceleration" ) ;; CODATA 2005
+ ( ga "980665*10^(-5) m/s^2" "*\"g\" acceleration" ) ;; CODATA
;; Mass
( g nil "*Gram" )
( lb "16 oz" "Pound (mass)" )
- ( oz "28.349523125 g" "Ounce (mass)" )
+ ( oz "28349523125*10^(-9) g" "Ounce (mass)" ) ;; ESUWM
( ton "2000 lb" "Ton" )
( tpo "ton+lb+oz" "Tons + pounds + ounces (mass)" )
( t "1000 kg" "Metric ton" )
- ( tonUK "1016.0469088 kg" "UK ton" )
+ ( tonUK "10160469088*10^(-7) kg" "UK ton" ) ;; ESUWM
( lbt "12 ozt" "Troy pound" )
- ( ozt "31.103475 g" "Troy ounce" )
- ( ct ".2 g" "Carat" )
- ( u "1.66053886e-27 kg" "Unified atomic mass" ) ;; CODATA 2005
+ ( ozt "31.10347680 g" "Troy ounce" ) ;; (approx) ESUWM
+ ( ct "(2/10) g" "Carat" ) ;; ESUWM
+ ( u "1.660538782e-27 kg" "Unified atomic mass" );;(approx) CODATA
;; Force
( N "m kg/s^2" "*Newton" )
- ( dyn "1e-5 N" "Dyne" )
+ ( dyn "10^(-5) N" "Dyne" )
( gf "ga g" "Gram (force)" )
- ( lbf "4.44822161526 N" "Pound (force)" )
+ ( lbf "ga lb" "Pound (force)" )
( kip "1000 lbf" "Kilopound (force)" )
- ( pdl "0.138255 N" "Poundal" )
+ ( pdl "138254954376*10^(-12) N" "Poundal" ) ;; ESUWM
;; Energy
( J "N m" "*Joule" )
- ( erg "1e-7 J" "Erg" )
- ( cal "4.1868 J" "International Table Calorie" )
- ( Btu "1055.05585262 J" "International Table Btu" )
+ ( erg "10^(-7) J" "Erg" )
+ ( cal "4.18674 J" "International Table Calorie" );;(approx) ESUWM
+ ( Btu "105505585262*10^(-8) J" "International Table Btu" ) ;; ESUWM
( eV "ech V" "Electron volt" )
( ev "eV" "Electron volt" )
( therm "105506000 J" "EEC therm" )
@@ -151,7 +155,7 @@
;; Power
( W "J/s" "*Watt" )
- ( hp "745.7 W" "Horsepower" )
+ ( hp "745.699871581 W" "Horsepower" ) ;;(approx) ESUWM
;; Temperature
( K nil "*Degree Kelvin" K )
@@ -164,24 +168,24 @@
;; Pressure
( Pa "N/m^2" "*Pascal" )
- ( bar "1e5 Pa" "Bar" )
- ( atm "101325 Pa" "Standard atmosphere" ) ;; CODATA 2005
- ( Torr " 1.333224e2 Pa" "Torr" ) ;; NIST (http://physics.nist.gov/Pubs/SP811/appenB9.html)
+ ( bar "10^5 Pa" "Bar" )
+ ( atm "101325 Pa" "Standard atmosphere" ) ;; CODATA
+ ( Torr "1.333224e2 Pa" "Torr" ) ;;(approx) NIST
( mHg "1000 Torr" "Meter of mercury" )
- ( inHg "25.4 mmHg" "Inch of mercury" )
- ( inH2O "2.490889e2 Pa" "Inch of water" ) ;; NIST (http://physics.nist.gov/Pubs/SP811/appenB9.html)
- ( psi "6894.75729317 Pa" "Pound per square inch" )
+ ( inHg "254*10^(-1) mmHg" "Inch of mercury" )
+ ( inH2O "2.490889e2 Pa" "Inch of water" ) ;;(approx) NIST
+ ( psi "lbf/in^2" "Pounds per square inch" )
;; Viscosity
- ( P "0.1 Pa s" "*Poise" )
- ( St "1e-4 m^2/s" "Stokes" )
+ ( P "(1/10) Pa s" "*Poise" )
+ ( St "10^(-4) m^2/s" "Stokes" )
;; Electromagnetism
( A nil "*Ampere" )
( C "A s" "Coulomb" )
( Fdy "ech Nav" "Faraday" )
- ( e "1.60217653e-19 C" "Elementary charge" ) ;; CODATA 2005
- ( ech "1.60217653e-19 C" "Elementary charge" ) ;; CODATA 2005
+ ( e "ech" "Elementary charge" )
+ ( ech "1.602176487e-19 C" "Elementary charge" ) ;;(approx) CODATA
( V "W/A" "Volt" )
( ohm "V/A" "Ohm" )
( mho "A/V" "Mho" )
@@ -189,26 +193,26 @@
( F "C/V" "Farad" )
( H "Wb/A" "Henry" )
( T "Wb/m^2" "Tesla" )
- ( Gs "1e-4 T" "Gauss" )
+ ( Gs "10^(-4) T" "Gauss" )
( Wb "V s" "Weber" )
;; Luminous intensity
( cd nil "*Candela" )
- ( sb "1e4 cd/m^2" "Stilb" )
+ ( sb "10000 cd/m^2" "Stilb" )
( lm "cd sr" "Lumen" )
( lx "lm/m^2" "Lux" )
- ( ph "1e4 lx" "Phot" )
- ( fc "10.76391 lx" "Footcandle" ) ;; NIST (http://physics.nist.gov/Pubs/SP811/appenB9.html)
- ( lam "1e4 lm/m^2" "Lambert" )
- ( flam "3.426259 cd/m^2" "Footlambert" ) ;; NIST (http://physics.nist.gov/Pubs/SP811/appenB9.html)
+ ( ph "10000 lx" "Phot" )
+ ( fc "10.76391 lx" "Footcandle" ) ;;(approx) NIST
+ ( lam "10000 lm/m^2" "Lambert" )
+ ( flam "3.426259 cd/m^2" "Footlambert" ) ;;(approx) NIST
;; Radioactivity
( Bq "1/s" "*Becquerel" )
- ( Ci "3.7e10 Bq" "Curie" )
+ ( Ci "37*10^9 Bq" "Curie" ) ;; ESUWM
( Gy "J/kg" "Gray" )
( Sv "Gy" "Sievert" )
- ( R "2.58e-4 C/kg" "Roentgen" )
- ( rd ".01 Gy" "Rad" )
+ ( R "258*10^(-6) C/kg" "Roentgen" ) ;; NIST
+ ( rd "(1/100) Gy" "Rad" )
( rem "rd" "Rem" )
;; Amount of substance
@@ -228,23 +232,24 @@
( sr nil "*Steradian" )
;; Other physical quantities
- ( h "6.6260693e-34 J s" "*Planck's constant" ) ;; CODATA 2005
- ( hbar "h / 2 pi" "Planck's constant" )
- ( mu0 "4 pi 1e-7 H/m" "Permeability of vacuum" )
- ( G "6.6742e-11 m^3/kg^1/s^2" "Gravitational constant" ) ;; CODATA 2005
- ( Nav "6.02214115e23 / mol" "Avagadro's constant" ) ;; CODATA 2005
- ( me "9.1093826e-31 kg" "Electron rest mass" ) ;; CODATA 2005
- ( mp "1.67262171e-27 kg" "Proton rest mass" ) ;; CODATA 2005
- ( mn "1.67492728e-27 kg" "Neutron rest mass" ) ;; CODATA 2005
- ( mmu "1.88353140e-28 kg" "Muon rest mass" ) ;; CODATA 2005
- ( Ryd "10973731.568525 /m" "Rydberg's constant" ) ;; CODATA 2005
- ( k "1.3806505e-23 J/K" "Boltzmann's constant" ) ;; CODATA 2005
- ( alpha "7.297352568e-3" "Fine structure constant" ) ;; CODATA 2005
- ( muB "927.400949e-26 J/T" "Bohr magneton" ) ;; CODATA 2005
- ( muN "5.05078343e-27 J/T" "Nuclear magneton" ) ;; CODATA 2005
- ( mue "-928.476412e-26 J/T" "Electron magnetic moment" ) ;; CODATA 2005
- ( mup "1.41060671e-26 J/T" "Proton magnetic moment" ) ;; CODATA 2005
- ( R0 "8.314472 J/mol/K" "Molar gas constant" ) ;; CODATA 2005
+ ;; The values are from CODATA, and are approximate.
+ ( h "6.62606896e-34 J s" "*Planck's constant" )
+ ( hbar "h / (2 pi)" "Planck's constant" )
+ ( mu0 "4 pi 10^(-7) H/m" "Permeability of vacuum" )
+ ( G "6.67428e-11 m^3/(kg s^2)" "Gravitational constant" )
+ ( Nav "6.02214179e23 / mol" "Avagadro's constant" )
+ ( me "9.10938215e-31 kg" "Electron rest mass" )
+ ( mp "1.672621637e-27 kg" "Proton rest mass" )
+ ( mn "1.674927211e-27 kg" "Neutron rest mass" )
+ ( mmu "1.88353130e-28 kg" "Muon rest mass" )
+ ( Ryd "10973731.568527 /m" "Rydberg's constant" )
+ ( k "1.3806504e-23 J/K" "Boltzmann's constant" )
+ ( alpha "7.2973525376e-3" "Fine structure constant" )
+ ( muB "927.400915e-26 J/T" "Bohr magneton" )
+ ( muN "5.05078324e-27 J/T" "Nuclear magneton" )
+ ( mue "-928.476377e-26 J/T" "Electron magnetic moment" )
+ ( mup "1.410606662e-26 J/T" "Proton magnetic moment" )
+ ( R0 "8.314472 J/(mol K)" "Molar gas constant" )
( V0 "22.710981e-3 m^3/mol" "Standard volume of ideal gas" )))
@@ -255,35 +260,35 @@ If this is changed, be sure to set math-units-table to nil to ensure
that the combined units table will be rebuilt.")
(defvar math-unit-prefixes
- '( ( ?Y (float 1 24) "Yotta" )
- ( ?Z (float 1 21) "Zetta" )
- ( ?E (float 1 18) "Exa" )
- ( ?P (float 1 15) "Peta" )
- ( ?T (float 1 12) "Tera" )
- ( ?G (float 1 9) "Giga" )
- ( ?M (float 1 6) "Mega" )
- ( ?k (float 1 3) "Kilo" )
- ( ?K (float 1 3) "Kilo" )
- ( ?h (float 1 2) "Hecto" )
- ( ?H (float 1 2) "Hecto" )
- ( ?D (float 1 1) "Deka" )
- ( 0 (float 1 0) nil )
- ( ?d (float 1 -1) "Deci" )
- ( ?c (float 1 -2) "Centi" )
- ( ?m (float 1 -3) "Milli" )
- ( ?u (float 1 -6) "Micro" )
- ( ?n (float 1 -9) "Nano" )
- ( ?p (float 1 -12) "Pico" )
- ( ?f (float 1 -15) "Femto" )
- ( ?a (float 1 -18) "Atto" )
- ( ?z (float 1 -21) "zepto" )
- ( ?y (float 1 -24) "yocto" )))
+ '( ( ?Y (^ 10 24) "Yotta" )
+ ( ?Z (^ 10 21) "Zetta" )
+ ( ?E (^ 10 18) "Exa" )
+ ( ?P (^ 10 15) "Peta" )
+ ( ?T (^ 10 12) "Tera" )
+ ( ?G (^ 10 9) "Giga" )
+ ( ?M (^ 10 6) "Mega" )
+ ( ?k (^ 10 3) "Kilo" )
+ ( ?K (^ 10 3) "Kilo" )
+ ( ?h (^ 10 2) "Hecto" )
+ ( ?H (^ 10 2) "Hecto" )
+ ( ?D (^ 10 1) "Deka" )
+ ( 0 (^ 10 0) nil )
+ ( ?d (^ 10 -1) "Deci" )
+ ( ?c (^ 10 -2) "Centi" )
+ ( ?m (^ 10 -3) "Milli" )
+ ( ?u (^ 10 -6) "Micro" )
+ ( ?n (^ 10 -9) "Nano" )
+ ( ?p (^ 10 -12) "Pico" )
+ ( ?f (^ 10 -15) "Femto" )
+ ( ?a (^ 10 -18) "Atto" )
+ ( ?z (^ 10 -21) "zepto" )
+ ( ?y (^ 10 -24) "yocto" )))
(defvar math-standard-units-systems
'( ( base nil )
- ( si ( ( g '(* (var kg var-kg) (float 1 -3)) ) ) )
- ( mks ( ( g '(* (var kg var-kg) (float 1 -3)) ) ) )
- ( cgs ( ( m '(* (var cm var-cm) 100 ) ) ) )))
+ ( si ( ( g '(/ (var kg var-kg) 1000) ) ) )
+ ( mks ( ( g '(/ (var kg var-kg) 1000) ) ) )
+ ( cgs ( ( m '(* (var cm var-cm) 100 ) ) ) )))
(defvar math-units-table nil
"Internal units table derived from math-defined-units.
@@ -321,13 +326,67 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(math-simplify-units
(math-mul expr (nth pos units))))))))
+(defun math-get-standard-units (expr)
+ "Return the standard units in EXPR."
+ (math-simplify-units
+ (math-extract-units
+ (math-to-standard-units expr nil))))
+
+(defun math-get-units (expr)
+ "Return the units in EXPR."
+ (math-simplify-units
+ (math-extract-units expr)))
+
+(defun math-make-unit-string (expr)
+ "Return EXPR in string form.
+If EXPR is nil, return nil."
+ (if expr
+ (let ((cexpr (math-compose-expr expr 0)))
+ (replace-regexp-in-string
+ " / " "/"
+ (if (stringp cexpr)
+ cexpr
+ (math-composition-to-string cexpr))))))
+
+(defvar math-default-units-table
+ (make-hash-table :test 'equal)
+ "A table storing previously converted units.")
+
+(defun math-get-default-units (expr)
+ "Get default units to use when converting the units in EXPR."
+ (let* ((units (math-get-units expr))
+ (standard-units (math-get-standard-units expr))
+ (default-units (gethash
+ standard-units
+ math-default-units-table)))
+ (if (equal units (car default-units))
+ (math-make-unit-string (cadr default-units))
+ (math-make-unit-string (car default-units)))))
+
+(defun math-put-default-units (expr)
+ "Put the units in EXPR in the default units table."
+ (let* ((units (math-get-units expr))
+ (standard-units (math-get-standard-units expr))
+ (default-units (gethash
+ standard-units
+ math-default-units-table)))
+ (cond
+ ((not default-units)
+ (puthash standard-units (list units) math-default-units-table))
+ ((not (equal units (car default-units)))
+ (puthash standard-units
+ (list units (car default-units))
+ math-default-units-table)))))
+
+
(defun calc-convert-units (&optional old-units new-units)
(interactive)
(calc-slow-wrapper
(let ((expr (calc-top-n 1))
(uoldname nil)
unew
- units)
+ units
+ defunits)
(unless (math-units-in-expr-p expr t)
(let ((uold (or old-units
(progn
@@ -343,16 +402,31 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(error "Bad format in units expression: %s" (nth 1 uold)))
(setq expr (math-mul expr uold))))
(unless new-units
- (setq new-units (read-string (if uoldname
- (concat "Old units: "
- uoldname
- ", new units: ")
- "New units: "))))
+ (setq defunits (math-get-default-units expr))
+ (setq new-units
+ (read-string (concat
+ (if uoldname
+ (concat "Old units: "
+ uoldname
+ ", new units")
+ "New units")
+ (if defunits
+ (concat
+ " (default "
+ defunits
+ "): ")
+ ": "))))
+
+ (if (and
+ (string= new-units "")
+ defunits)
+ (setq new-units defunits)))
(when (string-match "\\` */" new-units)
(setq new-units (concat "1" new-units)))
(setq units (math-read-expr new-units))
(when (eq (car-safe units) 'error)
(error "Bad format in units expression: %s" (nth 2 units)))
+ (math-put-default-units units)
(let ((unew (math-units-in-expr-p units t))
(std (and (eq (car-safe units) 'var)
(assq (nth 1 units) math-standard-units-systems))))
@@ -381,7 +455,8 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(let ((expr (calc-top-n 1))
(uold nil)
(uoldname nil)
- unew)
+ unew
+ defunits)
(setq uold (or old-units
(let ((units (math-single-units-in-expr-p expr)))
(if units
@@ -398,18 +473,32 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(error "Bad format in units expression: %s" (nth 2 uold)))
(or (math-units-in-expr-p expr nil)
(setq expr (math-mul expr uold)))
+ (setq defunits (math-get-default-units expr))
(setq unew (or new-units
(math-read-expr
- (read-string (if uoldname
- (concat "Old temperature units: "
- uoldname
- ", new units: ")
- "New temperature units: ")))))
+ (read-string
+ (concat
+ (if uoldname
+ (concat "Old temperature units: "
+ uoldname
+ ", new units")
+ "New temperature units")
+ (if defunits
+ (concat " (default "
+ defunits
+ "): ")
+ ": "))))))
(when (eq (car-safe unew) 'error)
(error "Bad format in units expression: %s" (nth 2 unew)))
- (calc-enter-result 1 "cvtm" (math-simplify-units
- (math-convert-temperature expr uold unew
- uoldname))))))
+ (math-put-default-units unew)
+ (let ((ntemp (calc-normalize
+ (math-simplify-units
+ (math-convert-temperature expr uold unew
+ uoldname)))))
+ (if (Math-zerop ntemp)
+ (setq ntemp (list '* ntemp unew)))
+ (let ((calc-simplify-mode 'none))
+ (calc-enter-result 1 "cvtm" ntemp))))))
(defun calc-remove-units ()
(interactive)
@@ -423,7 +512,7 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(calc-enter-result 1 "rmun" (math-simplify-units
(math-extract-units (calc-top-n 1))))))
-;; The variables calc-num-units and calc-den-units are local to
+;; The variables calc-num-units and calc-den-units are local to
;; calc-explain-units, but are used by calc-explain-units-rec,
;; which is called by calc-explain-units.
(defvar calc-num-units)
@@ -668,7 +757,7 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(list (cons (car x) 1))))))
combined-units))
(let ((math-units-table tab))
- (mapcar 'math-find-base-units tab))
+ (mapc 'math-find-base-units tab))
(message "Building units table...done")
(setq math-units-table tab))))
@@ -710,7 +799,7 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(old (assq (car (car ulist)) math-fbu-base)))
(if old
(setcdr old (+ (cdr old) p))
- (setq math-fbu-base
+ (setq math-fbu-base
(cons (cons (car (car ulist)) p) math-fbu-base))))
(setq ulist (cdr ulist)))))
((math-scalarp expr))
@@ -904,8 +993,8 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(if (equal (nth 4 math-fcu-u) (nth 4 u2))
(cons expr pow))))))
-;; The variables math-cu-new-units and math-cu-pure are local to
-;; math-convert-units, but are used by math-convert-units-rec,
+;; The variables math-cu-new-units and math-cu-pure are local to
+;; math-convert-units, but are used by math-convert-units-rec,
;; which is called by math-convert-units.
(defvar math-cu-new-units)
(defvar math-cu-pure)
@@ -917,7 +1006,7 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(if (eq (car-safe (nth 1 unew)) '+)
(setq math-cu-new-units (nth 1 unew)))))
(math-with-extra-prec 2
- (let ((compat (and (not math-cu-pure)
+ (let ((compat (and (not math-cu-pure)
(math-find-compatible-unit expr math-cu-new-units)))
(math-cu-unit-list nil)
(math-combining-units nil))
@@ -944,7 +1033,7 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(defun math-convert-units-rec (expr)
(if (math-units-in-expr-p expr nil)
- (math-apply-units (math-to-standard-units
+ (math-apply-units (math-to-standard-units
(list '/ expr math-cu-new-units) nil)
math-cu-new-units math-cu-unit-list math-cu-pure)
(if (Math-primp expr)
@@ -971,17 +1060,17 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(symbol-name v)))))))
(or (eq (nth 3 uold) (nth 3 unew))
(cond ((eq (nth 3 uold) 'K)
- (setq expr (list '- expr '(float 27315 -2)))
+ (setq expr (list '- expr '(/ 27315 100)))
(if (eq (nth 3 unew) 'F)
- (setq expr (list '+ (list '* expr '(frac 9 5)) 32))))
+ (setq expr (list '+ (list '* expr '(/ 9 5)) 32))))
((eq (nth 3 uold) 'C)
(if (eq (nth 3 unew) 'F)
- (setq expr (list '+ (list '* expr '(frac 9 5)) 32))
- (setq expr (list '+ expr '(float 27315 -2)))))
+ (setq expr (list '+ (list '* expr '(/ 9 5)) 32))
+ (setq expr (list '+ expr '(/ 27315 100)))))
(t
- (setq expr (list '* (list '- expr 32) '(frac 5 9)))
+ (setq expr (list '* (list '- expr 32) '(/ 5 9)))
(if (eq (nth 3 unew) 'K)
- (setq expr (list '+ expr '(float 27315 -2)))))))
+ (setq expr (list '+ expr '(/ 27315 100)))))))
(if pure
expr
(list '* expr new))))
@@ -1009,7 +1098,7 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(calc-record-why "*Inconsistent units" math-simplify-expr)
math-simplify-expr)
(list '* (math-add (math-remove-units (nth 1 math-simplify-expr))
- (if (eq (car math-simplify-expr) '-)
+ (if (eq (car math-simplify-expr) '-)
(math-neg ratio) ratio))
units)))))
@@ -1103,7 +1192,7 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(math-simplify-units-divisor np (cdr (cdr math-simplify-expr)))
(if (eq math-try-cancel-units 0)
(let* ((math-simplifying-units nil)
- (base (math-simplify
+ (base (math-simplify
(math-to-standard-units math-simplify-expr nil))))
(if (Math-numberp base)
(setq math-simplify-expr base))))
@@ -1138,7 +1227,9 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(and un ud
(if (and (equal (nth 4 un) (nth 4 ud))
(eq pow1 pow2))
- (math-to-standard-units (list '/ n d) nil)
+ (if (eq pow1 1)
+ (math-to-standard-units (list '/ n d) nil)
+ (list '^ (math-to-standard-units (list '/ n d) nil) pow1))
(let (ud1)
(setq un (nth 4 un)
ud (nth 4 ud))
@@ -1159,11 +1250,11 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(math-realp (nth 2 math-simplify-expr))
(if (memq (car-safe (nth 1 math-simplify-expr)) '(* /))
(list (car (nth 1 math-simplify-expr))
- (list '^ (nth 1 (nth 1 math-simplify-expr))
+ (list '^ (nth 1 (nth 1 math-simplify-expr))
(nth 2 math-simplify-expr))
- (list '^ (nth 2 (nth 1 math-simplify-expr))
+ (list '^ (nth 2 (nth 1 math-simplify-expr))
(nth 2 math-simplify-expr)))
- (math-simplify-units-pow (nth 1 math-simplify-expr)
+ (math-simplify-units-pow (nth 1 math-simplify-expr)
(nth 2 math-simplify-expr)))))
(math-defsimplify calcFunc-sqrt
diff --git a/lisp/calc/calc-vec.el b/lisp/calc/calc-vec.el
index e0f2a86bf29..b869a1e08a8 100644
--- a/lisp/calc/calc-vec.el
+++ b/lisp/calc/calc-vec.el
@@ -32,6 +32,10 @@
(require 'calc-ext)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function math-read-expr-level "calc-aent" (exp-prec &optional exp-term))
+
+
(defun calc-display-strings (n)
(interactive "P")
(calc-wrapper
diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el
index 89a9f1339b0..41a8d4157c9 100644
--- a/lisp/calc/calc-yank.el
+++ b/lisp/calc/calc-yank.el
@@ -559,7 +559,7 @@ To cancel the edit, simply kill the *Calc Edit* buffer."
(aset str pos ?\,)))
(switch-to-buffer calc-original-buffer)
(let ((vals (let ((calc-language nil)
- (math-expr-opers math-standard-opers))
+ (math-expr-opers (math-standard-ops)))
(and (string-match "[^\n\t ]" str)
(math-read-exprs str)))))
(when (eq (car-safe vals) 'error)
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index ad514707018..d14f667d752 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -206,6 +206,84 @@
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function calc-set-language "calc-lang" (lang &optional option no-refresh))
+(declare-function calc-edit-finish "calc-yank" (&optional keep))
+(declare-function calc-edit-cancel "calc-yank" ())
+(declare-function calc-do-quick-calc "calc-aent" ())
+(declare-function calc-do-calc-eval "calc-aent" (str separator args))
+(declare-function calc-do-keypad "calc-keypd" (&optional full-display interactive))
+(declare-function calcFunc-unixtime "calc-forms" (date &optional zone))
+(declare-function math-parse-date "calc-forms" (math-pd-str))
+(declare-function math-lessp "calc-ext" (a b))
+(declare-function calc-embedded-finish-command "calc-embed" ())
+(declare-function calc-embedded-select-buffer "calc-embed" ())
+(declare-function calc-embedded-mode-line-change "calc-embed" ())
+(declare-function calc-push-list-in-macro "calc-prog" (vals m sels))
+(declare-function calc-replace-selections "calc-sel" (n vals m))
+(declare-function calc-record-list "calc-misc" (vals &optional prefix))
+(declare-function calc-normalize-fancy "calc-ext" (val))
+(declare-function calc-do-handle-whys "calc-misc" ())
+(declare-function calc-top-selected "calc-sel" (&optional n m))
+(declare-function calc-sel-error "calc-sel" ())
+(declare-function calc-pop-stack-in-macro "calc-prog" (n mm))
+(declare-function calc-embedded-stack-change "calc-embed" ())
+(declare-function calc-refresh-evaltos "calc-ext" (&optional which-var))
+(declare-function calc-do-refresh "calc-misc" ())
+(declare-function calc-binary-op-fancy "calc-ext" (name func arg ident unary))
+(declare-function calc-unary-op-fancy "calc-ext" (name func arg))
+(declare-function calc-delete-selection "calc-sel" (n))
+(declare-function calc-alg-digit-entry "calc-aent" ())
+(declare-function calc-alg-entry "calc-aent" (&optional initial prompt))
+(declare-function calc-dots "calc-incom" ())
+(declare-function calc-temp-minibuffer-message "calc-misc" (m))
+(declare-function math-read-radix-digit "calc-misc" (dig))
+(declare-function calc-digit-dots "calc-incom" ())
+(declare-function math-normalize-fancy "calc-ext" (a))
+(declare-function math-normalize-nonstandard "calc-ext" ())
+(declare-function math-recompile-eval-rules "calc-alg" ())
+(declare-function math-apply-rewrites "calc-rewr" (expr rules &optional heads math-apply-rw-ruleset))
+(declare-function calc-record-why "calc-misc" (&rest stuff))
+(declare-function math-dimension-error "calc-vec" ())
+(declare-function calc-incomplete-error "calc-incom" (a))
+(declare-function math-float-fancy "calc-arith" (a))
+(declare-function math-neg-fancy "calc-arith" (a))
+(declare-function math-zerop "calc-misc" (a))
+(declare-function calc-add-fractions "calc-frac" (a b))
+(declare-function math-add-objects-fancy "calc-arith" (a b))
+(declare-function math-add-symb-fancy "calc-arith" (a b))
+(declare-function math-mul-zero "calc-arith" (a b))
+(declare-function calc-mul-fractions "calc-frac" (a b))
+(declare-function math-mul-objects-fancy "calc-arith" (a b))
+(declare-function math-mul-symb-fancy "calc-arith" (a b))
+(declare-function math-reject-arg "calc-misc" (&optional a p option))
+(declare-function math-div-by-zero "calc-arith" (a b))
+(declare-function math-div-zero "calc-arith" (a b))
+(declare-function math-make-frac "calc-frac" (num den))
+(declare-function calc-div-fractions "calc-frac" (a b))
+(declare-function math-div-objects-fancy "calc-arith" (a b))
+(declare-function math-div-symb-fancy "calc-arith" (a b))
+(declare-function math-compose-expr "calccomp" (a prec))
+(declare-function math-comp-width "calccomp" (c))
+(declare-function math-composition-to-string "calccomp" (c &optional width))
+(declare-function math-stack-value-offset-fancy "calccomp" ())
+(declare-function math-format-flat-expr-fancy "calc-ext" (a prec))
+(declare-function math-adjust-fraction "calc-ext" (a))
+(declare-function math-format-binary "calc-bin" (a))
+(declare-function math-format-radix "calc-bin" (a))
+(declare-function math-group-float "calc-ext" (str))
+(declare-function math-mod "calc-misc" (a b))
+(declare-function math-format-number-fancy "calc-ext" (a prec))
+(declare-function math-format-bignum-fancy "calc-ext" (a))
+(declare-function math-read-number-fancy "calc-ext" (s))
+(declare-function calc-do-grab-region "calc-yank" (top bot arg))
+(declare-function calc-do-grab-rectangle "calc-yank" (top bot arg &optional reduce))
+(declare-function calc-do-embedded "calc-embed" (calc-embed-arg end obeg oend))
+(declare-function calc-do-embedded-activate "calc-embed" (calc-embed-arg cbuf))
+(declare-function math-do-defmath "calc-prog" (func args body))
+(declare-function calc-load-everything "calc-ext" ())
+
+
(defgroup calc nil
"GNU Calc."
:prefix "calc-"
@@ -213,7 +291,7 @@
:group 'applications)
;;;###autoload
-(defcustom calc-settings-file
+(defcustom calc-settings-file
(convert-standard-filename "~/.calc.el")
"*File in which to record permanent settings."
:group 'calc
@@ -229,13 +307,14 @@
(c-mode . c)
(c++-mode . c)
(fortran-mode . fortran)
- (f90-mode . fortran))
+ (f90-mode . fortran)
+ (texinfo-mode . calc-normal-language))
"*Alist of major modes with appropriate Calc languages."
:group 'calc
- :type '(alist :key-type (symbol :tag "Major mode")
+ :type '(alist :key-type (symbol :tag "Major mode")
:value-type (symbol :tag "Calc language")))
-(defcustom calc-embedded-announce-formula
+(defcustom calc-embedded-announce-formula
"%Embed\n\\(% .*\n\\)*"
"*A regular expression which is sure to be followed by a calc-embedded formula."
:group 'calc
@@ -258,13 +337,13 @@
:type '(alist :key-type (symbol :tag "Major mode")
:value-type (regexp :tag "Regexp to announce formula")))
-(defcustom calc-embedded-open-formula
+(defcustom calc-embedded-open-formula
"\\`\\|^\n\\|\\$\\$?\\|\\\\\\[\\|^\\\\begin[^{].*\n\\|^\\\\begin{.*[^x]}.*\n\\|^@.*\n\\|^\\.EQ.*\n\\|\\\\(\\|^%\n\\|^\\.\\\\\"\n"
"*A regular expression for the opening delimiter of a formula used by calc-embedded."
:group 'calc
:type '(regexp))
-(defcustom calc-embedded-close-formula
+(defcustom calc-embedded-close-formula
"\\'\\|\n$\\|\\$\\$?\\|\\\\]\\|^\\\\end[^{].*\n\\|^\\\\end{.*[^x]}.*\n\\|^@.*\n\\|^\\.EN.*\n\\|\\\\)\\|\n%\n\\|^\\.\\\\\"\n"
"*A regular expression for the closing delimiter of a formula used by calc-embedded."
:group 'calc
@@ -278,13 +357,13 @@
:value-type (list (regexp :tag "Opening formula delimiter")
(regexp :tag "Closing formula delimiter"))))
-(defcustom calc-embedded-open-word
+(defcustom calc-embedded-open-word
"^\\|[^-+0-9.eE]"
"*A regular expression for the opening delimiter of a formula used by calc-embedded-word."
:group 'calc
:type '(regexp))
-(defcustom calc-embedded-close-word
+(defcustom calc-embedded-close-word
"$\\|[^-+0-9.eE]"
"*A regular expression for the closing delimiter of a formula used by calc-embedded-word."
:group 'calc
@@ -298,7 +377,7 @@
:value-type (list (regexp :tag "Opening word delimiter")
(regexp :tag "Closing word delimiter"))))
-(defcustom calc-embedded-open-plain
+(defcustom calc-embedded-open-plain
"%%% "
"*A string which is the opening delimiter for a \"plain\" formula.
If calc-show-plain mode is enabled, this is inserted at the front of
@@ -306,7 +385,7 @@ each formula."
:group 'calc
:type '(string))
-(defcustom calc-embedded-close-plain
+(defcustom calc-embedded-close-plain
" %%%\n"
"*A string which is the closing delimiter for a \"plain\" formula.
See calc-embedded-open-plain."
@@ -331,13 +410,13 @@ See calc-embedded-open-plain."
:value-type (list (string :tag "Opening \"plain\" delimiter")
(string :tag "Closing \"plain\" delimiter"))))
-(defcustom calc-embedded-open-new-formula
+(defcustom calc-embedded-open-new-formula
"\n\n"
"*A string which is inserted at front of formula by calc-embedded-new-formula."
:group 'calc
:type '(string))
-(defcustom calc-embedded-close-new-formula
+(defcustom calc-embedded-close-new-formula
"\n\n"
"*A string which is inserted at end of formula by calc-embedded-new-formula."
:group 'calc
@@ -351,14 +430,14 @@ See calc-embedded-open-plain."
:value-type (list (string :tag "Opening new formula delimiter")
(string :tag "Closing new formula delimiter"))))
-(defcustom calc-embedded-open-mode
+(defcustom calc-embedded-open-mode
"% "
"*A string which should precede calc-embedded mode annotations.
This is not required to be present for user-written mode annotations."
:group 'calc
:type '(string))
-(defcustom calc-embedded-close-mode
+(defcustom calc-embedded-close-mode
"\n"
"*A string which should follow calc-embedded mode annotations.
This is not required to be present for user-written mode annotations."
@@ -383,24 +462,31 @@ This is not required to be present for user-written mode annotations."
:value-type (list (string :tag "Opening annotation delimiter")
(string :tag "Closing annotation delimiter"))))
-(defcustom calc-gnuplot-name
+(defcustom calc-gnuplot-name
"gnuplot"
"*Name of GNUPLOT program, for calc-graph features."
:group 'calc
:type '(string))
-(defcustom calc-gnuplot-plot-command
+(defcustom calc-gnuplot-plot-command
nil
"*Name of command for displaying GNUPLOT output; %s = file name to print."
:group 'calc
:type '(choice (string) (sexp)))
-(defcustom calc-gnuplot-print-command
+(defcustom calc-gnuplot-print-command
"lp %s"
"*Name of command for printing GNUPLOT output; %s = file name to print."
:group 'calc
:type '(choice (string) (sexp)))
+(defcustom calc-multiplication-has-precedence
+ t
+ "*If non-nil, multiplication has precedence over division
+in normal mode."
+ :group 'calc
+ :type 'boolean)
+
(defvar calc-bug-address "jay.p.belanger@gmail.com"
"Address of the maintainer of Calc, for use by `report-calc-bug'.")
@@ -512,7 +598,7 @@ This is used only when calc-group-digits mode is on.")
(defcalcmodevar calc-point-char "."
"The character (in the form of a string) to be used as a decimal point.")
-
+
(defcalcmodevar calc-frac-format '(":" nil)
"Format of displayed fractions; a string of one or two of \":\" or \"/\".")
@@ -599,6 +685,9 @@ If `C' is present, display outer brackets for matrices (centered).")
tex Use TeX notation.
latex Use LaTeX notation.
eqn Use eqn notation.
+ yacas Use Yacas notation.
+ maxima Use Maxima notation.
+ giac Use Giac notation.
math Use Mathematica(tm) notation.
maple Use Maple notation.")
@@ -702,9 +791,9 @@ If nil, selections displayed but ignored.")
"YYddd< hh:mm:ss>"))
(defcalcmodevar calc-autorange-units nil)
-
+
(defcalcmodevar calc-was-keypad-mode nil)
-
+
(defcalcmodevar calc-full-mode nil)
(defcalcmodevar calc-user-parse-tables nil)
@@ -714,7 +803,7 @@ If nil, selections displayed but ignored.")
(defcalcmodevar calc-gnuplot-default-output "STDOUT")
(defcalcmodevar calc-gnuplot-print-device "postscript")
-
+
(defcalcmodevar calc-gnuplot-print-output "auto")
(defcalcmodevar calc-gnuplot-geometry nil)
@@ -722,7 +811,7 @@ If nil, selections displayed but ignored.")
(defcalcmodevar calc-graph-default-resolution 15)
(defcalcmodevar calc-graph-default-resolution-3d 5)
-
+
(defcalcmodevar calc-invocation-macro nil)
(defcalcmodevar calc-show-banner t
@@ -813,9 +902,6 @@ If nil, selections displayed but ignored.")
(defvar calc-embedded-mode-hook nil
"Hook run when starting embedded mode.")
-;; Verify that Calc is running on the right kind of system.
-(defvar calc-emacs-type-lucid (not (not (string-match "Lucid" emacs-version))))
-
;; Set up the autoloading linkage.
(let ((name (and (fboundp 'calc-dispatch)
(eq (car-safe (symbol-function 'calc-dispatch)) 'autoload)
@@ -884,6 +970,18 @@ If nil, selections displayed but ignored.")
"Function through which to pass strings before parsing.")
(defvar calc-radix-formatter nil
"Formatting function used for non-decimal numbers.")
+(defvar calc-lang-slash-idiv nil
+ "A list of languages in which / might represent integer division.")
+(defvar calc-lang-allow-underscores nil
+ "A list of languages which allow underscores in variable names.")
+(defvar calc-lang-allow-percentsigns nil
+ "A list of languages which allow percent signs in variable names.")
+(defvar calc-lang-c-type-hex nil
+ "Languages in which octal and hex numbers are written with leading 0 and 0x,")
+(defvar calc-lang-brackets-are-subscripts nil
+ "Languages in which subscripts are indicated by brackets.")
+(defvar calc-lang-parens-are-subscripts nil
+ "Languages in which subscripts are indicated by parentheses.")
(defvar calc-last-kill nil) ; Last number killed in calc-mode.
(defvar calc-dollar-values nil) ; Values to be used for '$'.
@@ -906,7 +1004,6 @@ If nil, selections displayed but ignored.")
(defvar math-eval-rules-cache-tag t)
(defvar math-radix-explicit-format t)
(defvar math-expr-function-mapping nil)
-(defvar math-expr-special-function-mapping nil)
(defvar math-expr-variable-mapping nil)
(defvar math-read-expr-quotes nil)
(defvar math-working-step nil)
@@ -918,8 +1015,8 @@ If nil, selections displayed but ignored.")
(defvar var-gamma '(special-const (math-gamma-const)))
(defvar var-Modes '(special-const (math-get-modes-vec)))
-(mapcar (lambda (v) (or (boundp v) (set v nil)))
- calc-local-var-list)
+(mapc (lambda (v) (or (boundp v) (set v nil)))
+ calc-local-var-list)
(defvar calc-mode-map
(let ((map (make-keymap)))
@@ -960,7 +1057,7 @@ If nil, selections displayed but ignored.")
(defvar calc-digit-map
(let ((map (make-keymap)))
- (if calc-emacs-type-lucid
+ (if (featurep 'xemacs)
(map-keymap (function
(lambda (keys bind)
(define-key map keys
@@ -975,89 +1072,90 @@ If nil, selections displayed but ignored.")
(if (eq (aref cmap i) 'undefined)
'undefined 'calcDigit-nondigit))
(setq i (1+ i)))))
- (mapcar (lambda (x) (define-key map (char-to-string x) 'calcDigit-key))
- "_0123456789.e+-:n#@oh'\"mspM")
- (mapcar (lambda (x) (define-key map (char-to-string x) 'calcDigit-letter))
+ (mapc (lambda (x) (define-key map (char-to-string x) 'calcDigit-key))
+ "_0123456789.e+-:n#@oh'\"mspM")
+ (mapc (lambda (x) (define-key map (char-to-string x) 'calcDigit-letter))
"abcdfgijklqrtuvwxyzABCDEFGHIJKLNOPQRSTUVWXYZ")
(define-key map "'" 'calcDigit-algebraic)
(define-key map "`" 'calcDigit-edit)
(define-key map "\C-g" 'abort-recursive-edit)
map))
-(mapcar (lambda (x)
- (condition-case err
- (progn
- (define-key calc-digit-map x 'calcDigit-backspace)
- (define-key calc-mode-map x 'calc-pop)
- (define-key calc-mode-map
- (if (vectorp x)
- (if calc-emacs-type-lucid
- (if (= (length x) 1)
- (vector (if (consp (aref x 0))
- (cons 'meta (aref x 0))
- (list 'meta (aref x 0))))
- "\e\C-d")
- (vconcat "\e" x))
- (concat "\e" x))
- 'calc-pop-above))
- (error nil)))
- (if calc-scan-for-dels
- (append (where-is-internal 'delete-backward-char global-map)
- (where-is-internal 'backward-delete-char global-map)
- '("\C-d"))
- '("\177" "\C-d")))
+(mapc (lambda (x)
+ (condition-case err
+ (progn
+ (define-key calc-digit-map x 'calcDigit-backspace)
+ (define-key calc-mode-map x 'calc-pop)
+ (define-key calc-mode-map
+ (if (vectorp x)
+ (if (featurep 'xemacs)
+ (if (= (length x) 1)
+ (vector (if (consp (aref x 0))
+ (cons 'meta (aref x 0))
+ (list 'meta (aref x 0))))
+ "\e\C-d")
+ (vconcat "\e" x))
+ (concat "\e" x))
+ 'calc-pop-above))
+ (error nil)))
+ (if calc-scan-for-dels
+ (append (where-is-internal 'delete-backward-char global-map)
+ (where-is-internal 'backward-delete-char global-map)
+ (where-is-internal 'backward-delete-char-untabify global-map)
+ '("\C-d"))
+ '("\177" "\C-d")))
(defvar calc-dispatch-map
(let ((map (make-keymap)))
- (mapcar (lambda (x)
- (define-key map (char-to-string (car x)) (cdr x))
- (when (string-match "abcdefhijklnopqrstuwxyz"
- (char-to-string (car x)))
- (define-key map (char-to-string (- (car x) ?a -1)) (cdr x)))
- (define-key map (format "\e%c" (car x)) (cdr x)))
- '( ( ?a . calc-embedded-activate )
- ( ?b . calc-big-or-small )
- ( ?c . calc )
- ( ?d . calc-embedded-duplicate )
- ( ?e . calc-embedded )
- ( ?f . calc-embedded-new-formula )
- ( ?g . calc-grab-region )
- ( ?h . calc-dispatch-help )
- ( ?i . calc-info )
- ( ?j . calc-embedded-select )
- ( ?k . calc-keypad )
- ( ?l . calc-load-everything )
- ( ?m . read-kbd-macro )
- ( ?n . calc-embedded-next )
- ( ?o . calc-other-window )
- ( ?p . calc-embedded-previous )
- ( ?q . quick-calc )
- ( ?r . calc-grab-rectangle )
- ( ?s . calc-info-summary )
- ( ?t . calc-tutorial )
- ( ?u . calc-embedded-update-formula )
- ( ?w . calc-embedded-word )
- ( ?x . calc-quit )
- ( ?y . calc-copy-to-buffer )
- ( ?z . calc-user-invocation )
- ( ?\' . calc-embedded-new-formula )
- ( ?\` . calc-embedded-edit )
- ( ?: . calc-grab-sum-down )
- ( ?_ . calc-grab-sum-across )
- ( ?0 . calc-reset )
- ( ?? . calc-dispatch-help )
- ( ?# . calc-same-interface )
- ( ?& . calc-same-interface )
- ( ?\\ . calc-same-interface )
- ( ?= . calc-same-interface )
- ( ?* . calc-same-interface )
- ( ?/ . calc-same-interface )
- ( ?+ . calc-same-interface )
- ( ?- . calc-same-interface ) ))
+ (mapc (lambda (x)
+ (define-key map (char-to-string (car x)) (cdr x))
+ (when (string-match "abcdefhijklnopqrstuwxyz"
+ (char-to-string (car x)))
+ (define-key map (char-to-string (- (car x) ?a -1)) (cdr x)))
+ (define-key map (format "\e%c" (car x)) (cdr x)))
+ '( ( ?a . calc-embedded-activate )
+ ( ?b . calc-big-or-small )
+ ( ?c . calc )
+ ( ?d . calc-embedded-duplicate )
+ ( ?e . calc-embedded )
+ ( ?f . calc-embedded-new-formula )
+ ( ?g . calc-grab-region )
+ ( ?h . calc-dispatch-help )
+ ( ?i . calc-info )
+ ( ?j . calc-embedded-select )
+ ( ?k . calc-keypad )
+ ( ?l . calc-load-everything )
+ ( ?m . read-kbd-macro )
+ ( ?n . calc-embedded-next )
+ ( ?o . calc-other-window )
+ ( ?p . calc-embedded-previous )
+ ( ?q . quick-calc )
+ ( ?r . calc-grab-rectangle )
+ ( ?s . calc-info-summary )
+ ( ?t . calc-tutorial )
+ ( ?u . calc-embedded-update-formula )
+ ( ?w . calc-embedded-word )
+ ( ?x . calc-quit )
+ ( ?y . calc-copy-to-buffer )
+ ( ?z . calc-user-invocation )
+ ( ?\' . calc-embedded-new-formula )
+ ( ?\` . calc-embedded-edit )
+ ( ?: . calc-grab-sum-down )
+ ( ?_ . calc-grab-sum-across )
+ ( ?0 . calc-reset )
+ ( ?? . calc-dispatch-help )
+ ( ?# . calc-same-interface )
+ ( ?& . calc-same-interface )
+ ( ?\\ . calc-same-interface )
+ ( ?= . calc-same-interface )
+ ( ?* . calc-same-interface )
+ ( ?/ . calc-same-interface )
+ ( ?+ . calc-same-interface )
+ ( ?- . calc-same-interface ) ))
map))
;;;; (Autoloads here)
-(mapcar
+(mapc
(lambda (x) (dolist (func (cdr x)) (autoload func (car x))))
'(
@@ -1069,7 +1167,7 @@ If nil, selections displayed but ignored.")
("calc-embed" calc-do-embedded-activate)
- ("calc-misc"
+ ("calc-misc"
calc-do-handle-whys calc-do-refresh calc-num-prefix-name
calc-record-list calc-record-why calc-report-bug calc-roll-down-stack
calc-roll-up-stack calc-temp-minibuffer-message calcFunc-floor
@@ -1079,7 +1177,7 @@ If nil, selections displayed but ignored.")
math-negp math-posp math-pow math-read-radix-digit math-reject-arg
math-trunc math-zerop)))
-(mapcar
+(mapc
(lambda (x) (dolist (cmd (cdr x)) (autoload cmd (car x) nil t)))
'(
@@ -1087,7 +1185,7 @@ If nil, selections displayed but ignored.")
calcDigit-algebraic calcDigit-edit)
("calc-misc" another-calc calc-big-or-small calc-dispatch-help
- calc-help calc-info calc-info-goto-node calc-info-summary calc-inv
+ calc-help calc-info calc-info-goto-node calc-info-summary calc-inv
calc-last-args-stub
calc-missing-key calc-mod calc-other-window calc-over calc-percent
calc-pop-above calc-power calc-roll-down calc-roll-up
@@ -1135,7 +1233,7 @@ If nil, selections displayed but ignored.")
(let ((prompt2 (format "%s " (key-description (this-command-keys))))
(glob (current-global-map))
(loc (current-local-map)))
- (or (input-pending-p) (message prompt))
+ (or (input-pending-p) (message "%s" prompt))
(let ((key (calc-read-key t)))
(calc-unread-command (cdr key))
(unwind-protect
@@ -1151,7 +1249,7 @@ If nil, selections displayed but ignored.")
(defun calc-version ()
"Return version of this version of Calc."
(interactive)
- (message (concat "Calc version " calc-version)))
+ (message "Calc version %s" calc-version))
(defun calc-mode ()
"Calculator major mode.
@@ -1185,12 +1283,12 @@ Notations: 3.14e6 3.14 * 10^6
\\{calc-mode-map}
"
(interactive)
- (mapcar (function
- (lambda (v) (set-default v (symbol-value v)))) calc-local-var-list)
+ (mapc (function
+ (lambda (v) (set-default v (symbol-value v)))) calc-local-var-list)
(kill-all-local-variables)
(use-local-map (if (eq calc-algebraic-mode 'total)
(progn (require 'calc-ext) calc-alg-map) calc-mode-map))
- (mapcar (function (lambda (v) (make-local-variable v))) calc-local-var-list)
+ (mapc (function (lambda (v) (make-local-variable v))) calc-local-var-list)
(make-local-variable 'overlay-arrow-position)
(make-local-variable 'overlay-arrow-string)
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
@@ -1216,6 +1314,7 @@ Notations: 3.14e6 3.14 * 10^6
(string-match "full" (nth 1 p))
(setq calc-standalone-flag t))
(setq p (cdr p))))
+ (require 'calc-menu)
(run-mode-hooks 'calc-mode-hook)
(calc-refresh t)
(calc-set-mode-line)
@@ -1367,8 +1466,8 @@ commands given here will actually operate on the *Calculator* stack."
(calc-create-buffer))
(run-hooks 'calc-end-hook)
(setq calc-undo-list nil calc-redo-list nil)
- (mapcar (function (lambda (v) (set-default v (symbol-value v))))
- calc-local-var-list)
+ (mapc (function (lambda (v) (set-default v (symbol-value v))))
+ calc-local-var-list)
(let ((buf (current-buffer))
(win (get-buffer-window (current-buffer)))
(kbuf (get-buffer "*Calc Keypad*")))
@@ -1581,8 +1680,8 @@ See calc-keypad for details."
(t (format "Radix%d " calc-number-radix)))
(if calc-leading-zeros "Zero " "")
(cond ((null calc-language) "")
- ((eq calc-language 'tex) "TeX ")
- ((eq calc-language 'latex) "LaTeX ")
+ ((get calc-language 'math-lang-name)
+ (concat (get calc-language 'math-lang-name) " "))
(t (concat
(capitalize (symbol-name calc-language))
" ")))
@@ -2101,13 +2200,13 @@ See calc-keypad for details."
(calc-prev-char nil)
(calc-prev-prev-char nil)
(calc-buffer (current-buffer))
- (buf (if calc-emacs-type-lucid
+ (buf (if (featurep 'xemacs)
(catch 'calc-foo
(catch 'execute-kbd-macro
(throw 'calc-foo
(read-from-minibuffer
"Calc: " "" calc-digit-map)))
- (error "Lucid Emacs requires RET after %s"
+ (error "XEmacs requires RET after %s"
"digit entry in kbd macro"))
(let ((old-esc (lookup-key global-map "\e")))
(unwind-protect
@@ -2276,7 +2375,21 @@ See calc-keypad for details."
+(defconst math-bignum-digit-length
+ (truncate (/ (log10 (/ most-positive-fixnum 2)) 2))
+ "The length of a \"digit\" in Calc bignums.
+If a big integer is of the form (bigpos N0 N1 ...), this is the
+length of the allowable Emacs integers N0, N1,...
+The value of 2*10^(2*MATH-BIGNUM-DIGIT-LENGTH) must be less than the
+largest Emacs integer.")
+
+(defconst math-bignum-digit-size
+ (expt 10 math-bignum-digit-length)
+ "An upper bound for the size of the \"digit\"s in Calc bignums.")
+(defconst math-small-integer-size
+ (expt math-bignum-digit-size 2)
+ "An upper bound for the size of \"small integer\"s in Calc.")
;;;; Arithmetic routines.
@@ -2285,11 +2398,17 @@ See calc-keypad for details."
;;; following forms:
;;;
;;; integer An integer. For normalized numbers, this format
-;;; is used only for -999999 ... 999999.
+;;; is used only for
+;;; negative math-small-integer-size + 1 to
+;;; math-small-integer-size - 1
;;;
-;;; (bigpos N0 N1 N2 ...) A big positive integer, N0 + N1*1000 + N2*10^6 ...
-;;; (bigneg N0 N1 N2 ...) A big negative integer, - N0 - N1*1000 ...
-;;; Each digit N is in the range 0 ... 999.
+;;; (bigpos N0 N1 N2 ...) A big positive integer,
+;;; N0 + N1*math-bignum-digit-size
+;;; + N2*(math-bignum-digit-size)^2 ...
+;;; (bigneg N0 N1 N2 ...) A big negative integer,
+;;; - N0 - N1*math-bignum-digit-size ...
+;;; Each digit N is in the range
+;;; 0 ... math-bignum-digit-size -1.
;;; Normalized, always at least three N present,
;;; and the most significant N is nonzero.
;;;
@@ -2379,13 +2498,14 @@ See calc-keypad for details."
(cond
((not (consp math-normalize-a))
(if (integerp math-normalize-a)
- (if (or (>= math-normalize-a 1000000) (<= math-normalize-a -1000000))
+ (if (or (>= math-normalize-a math-small-integer-size)
+ (<= math-normalize-a (- math-small-integer-size)))
(math-bignum math-normalize-a)
math-normalize-a)
math-normalize-a))
((eq (car math-normalize-a) 'bigpos)
(if (eq (nth (1- (length math-normalize-a)) math-normalize-a) 0)
- (let* ((last (setq math-normalize-a
+ (let* ((last (setq math-normalize-a
(copy-sequence math-normalize-a))) (digs math-normalize-a))
(while (setq digs (cdr digs))
(or (eq (car digs) 0) (setq last digs)))
@@ -2393,13 +2513,14 @@ See calc-keypad for details."
(if (cdr (cdr (cdr math-normalize-a)))
math-normalize-a
(cond
- ((cdr (cdr math-normalize-a)) (+ (nth 1 math-normalize-a)
- (* (nth 2 math-normalize-a) 1000)))
+ ((cdr (cdr math-normalize-a)) (+ (nth 1 math-normalize-a)
+ (* (nth 2 math-normalize-a)
+ math-bignum-digit-size)))
((cdr math-normalize-a) (nth 1 math-normalize-a))
(t 0))))
((eq (car math-normalize-a) 'bigneg)
(if (eq (nth (1- (length math-normalize-a)) math-normalize-a) 0)
- (let* ((last (setq math-normalize-a (copy-sequence math-normalize-a)))
+ (let* ((last (setq math-normalize-a (copy-sequence math-normalize-a)))
(digs math-normalize-a))
(while (setq digs (cdr digs))
(or (eq (car digs) 0) (setq last digs)))
@@ -2407,20 +2528,21 @@ See calc-keypad for details."
(if (cdr (cdr (cdr math-normalize-a)))
math-normalize-a
(cond
- ((cdr (cdr math-normalize-a)) (- (+ (nth 1 math-normalize-a)
- (* (nth 2 math-normalize-a) 1000))))
+ ((cdr (cdr math-normalize-a)) (- (+ (nth 1 math-normalize-a)
+ (* (nth 2 math-normalize-a)
+ math-bignum-digit-size))))
((cdr math-normalize-a) (- (nth 1 math-normalize-a)))
(t 0))))
((eq (car math-normalize-a) 'float)
- (math-make-float (math-normalize (nth 1 math-normalize-a))
+ (math-make-float (math-normalize (nth 1 math-normalize-a))
(nth 2 math-normalize-a)))
- ((or (memq (car math-normalize-a)
+ ((or (memq (car math-normalize-a)
'(frac cplx polar hms date mod sdev intv vec var quote
special-const calcFunc-if calcFunc-lambda
calcFunc-quote calcFunc-condition
calcFunc-evalto))
(integerp (car math-normalize-a))
- (and (consp (car math-normalize-a))
+ (and (consp (car math-normalize-a))
(not (eq (car (car math-normalize-a)) 'lambda))))
(require 'calc-ext)
(math-normalize-fancy math-normalize-a))
@@ -2430,7 +2552,7 @@ See calc-keypad for details."
(math-normalize-nonstandard))
(let ((args (mapcar 'math-normalize (cdr math-normalize-a))))
(or (condition-case err
- (let ((func
+ (let ((func
(assq (car math-normalize-a) '( ( + . math-add )
( - . math-sub )
( * . math-mul )
@@ -2446,7 +2568,7 @@ See calc-keypad for details."
(require 'calc-ext)
(math-recompile-eval-rules)))
(and (or math-eval-rules-cache-other
- (assq (car math-normalize-a)
+ (assq (car math-normalize-a)
math-eval-rules-cache))
(math-apply-rewrites
(cons (car math-normalize-a) args)
@@ -2465,12 +2587,12 @@ See calc-keypad for details."
(cons (car math-normalize-a) args))
nil)
(wrong-type-argument
- (or calc-next-why
+ (or calc-next-why
(calc-record-why "Wrong type of argument"
(cons (car math-normalize-a) args)))
nil)
(args-out-of-range
- (calc-record-why "*Argument out of range"
+ (calc-record-why "*Argument out of range"
(cons (car math-normalize-a) args))
nil)
(inexact-result
@@ -2528,7 +2650,8 @@ See calc-keypad for details."
(defun math-bignum-big (a) ; [L s]
(if (= a 0)
nil
- (cons (% a 1000) (math-bignum-big (/ a 1000)))))
+ (cons (% a math-bignum-digit-size)
+ (math-bignum-big (/ a math-bignum-digit-size)))))
;;; Build a normalized floating-point number. [F I S]
@@ -2545,7 +2668,7 @@ See calc-keypad for details."
(progn
(while (= (car digs) 0)
(setq digs (cdr digs)
- exp (+ exp 3)))
+ exp (+ exp math-bignum-digit-length)))
(while (= (% (car digs) 10) 0)
(setq digs (math-div10-bignum digs)
exp (1+ exp)))
@@ -2563,7 +2686,8 @@ See calc-keypad for details."
(defun math-div10-bignum (a) ; [l l]
(if (cdr a)
- (cons (+ (/ (car a) 10) (* (% (nth 1 a) 10) 100))
+ (cons (+ (/ (car a) 10) (* (% (nth 1 a) 10)
+ (expt 10 (1- math-bignum-digit-length))))
(math-div10-bignum (cdr a)))
(list (/ (car a) 10))))
@@ -2594,7 +2718,7 @@ See calc-keypad for details."
(if (cdr a)
(let* ((len (1- (length a)))
(top (nth len a)))
- (+ (* len 3) (cond ((>= top 100) 0) ((>= top 10) -1) (t -2))))
+ (+ (* (1- len) math-bignum-digit-length) (math-numdigs top)))
0)
(cond ((>= a 100) (+ (math-numdigs (/ a 1000)) 3))
((>= a 10) 2)
@@ -2615,24 +2739,24 @@ See calc-keypad for details."
a
(if (consp a)
(cons (car a) (math-scale-left-bignum (cdr a) n))
- (if (>= n 3)
- (if (or (>= a 1000) (<= a -1000))
+ (if (>= n math-bignum-digit-length)
+ (if (or (>= a math-bignum-digit-size)
+ (<= a (- math-bignum-digit-size)))
(math-scale-left (math-bignum a) n)
- (math-scale-left (* a 1000) (- n 3)))
- (if (= n 2)
- (if (or (>= a 10000) (<= a -10000))
- (math-scale-left (math-bignum a) 2)
- (* a 100))
- (if (or (>= a 100000) (<= a -100000))
- (math-scale-left (math-bignum a) 1)
- (* a 10)))))))
+ (math-scale-left (* a math-bignum-digit-size)
+ (- n math-bignum-digit-length)))
+ (let ((sz (expt 10 (- (* 2 math-bignum-digit-length) n))))
+ (if (or (>= a sz) (<= a (- sz)))
+ (math-scale-left (math-bignum a) n)
+ (* a (expt 10 n))))))))
(defun math-scale-left-bignum (a n)
- (if (>= n 3)
+ (if (>= n math-bignum-digit-length)
(while (>= (setq a (cons 0 a)
- n (- n 3)) 3)))
+ n (- n math-bignum-digit-length))
+ math-bignum-digit-length)))
(if (> n 0)
- (math-mul-bignum-digit a (if (= n 2) 100 10) 0)
+ (math-mul-bignum-digit a (expt 10 n) 0)
a))
(defun math-scale-right (a n) ; [i i S]
@@ -2644,21 +2768,20 @@ See calc-keypad for details."
(if (= a 0)
0
(- (math-scale-right (- a) n)))
- (if (>= n 3)
- (while (and (> (setq a (/ a 1000)) 0)
- (>= (setq n (- n 3)) 3))))
- (if (= n 2)
- (/ a 100)
- (if (= n 1)
- (/ a 10)
- a))))))
+ (if (>= n math-bignum-digit-length)
+ (while (and (> (setq a (/ a math-bignum-digit-size)) 0)
+ (>= (setq n (- n math-bignum-digit-length))
+ math-bignum-digit-length))))
+ (if (> n 0)
+ (/ a (expt 10 n))
+ a)))))
(defun math-scale-right-bignum (a n) ; [L L S; l l S]
- (if (>= n 3)
- (setq a (nthcdr (/ n 3) a)
- n (% n 3)))
+ (if (>= n math-bignum-digit-length)
+ (setq a (nthcdr (/ n math-bignum-digit-length) a)
+ n (% n math-bignum-digit-length)))
(if (> n 0)
- (cdr (math-mul-bignum-digit a (if (= n 2) 10 100) 0))
+ (cdr (math-mul-bignum-digit a (expt 10 (- math-bignum-digit-length n)) 0))
a))
;;; Multiply (with rounding) the integer A by 10^N. [I i S]
@@ -2668,16 +2791,18 @@ See calc-keypad for details."
((consp a)
(math-normalize
(cons (car a)
- (let ((val (if (< n -3)
- (math-scale-right-bignum (cdr a) (- -3 n))
- (if (= n -2)
- (math-mul-bignum-digit (cdr a) 10 0)
- (if (= n -1)
- (math-mul-bignum-digit (cdr a) 100 0)
- (cdr a)))))) ; n = -3
- (if (and val (>= (car val) 500))
+ (let ((val (if (< n (- math-bignum-digit-length))
+ (math-scale-right-bignum
+ (cdr a)
+ (- (- math-bignum-digit-length) n))
+ (if (< n 0)
+ (math-mul-bignum-digit
+ (cdr a)
+ (expt 10 (+ math-bignum-digit-length n)) 0)
+ (cdr a))))) ; n = -math-bignum-digit-length
+ (if (and val (>= (car val) (/ math-bignum-digit-size 2)))
(if (cdr val)
- (if (eq (car (cdr val)) 999)
+ (if (eq (car (cdr val)) (1- math-bignum-digit-size))
(math-add-bignum (cdr val) '(1))
(cons (1+ (car (cdr val))) (cdr (cdr val))))
'(1))
@@ -2696,7 +2821,7 @@ See calc-keypad for details."
(and (not (or (consp a) (consp b)))
(progn
(setq a (+ a b))
- (if (or (<= a -1000000) (>= a 1000000))
+ (if (or (<= a (- math-small-integer-size)) (>= a math-small-integer-size))
(math-bignum a)
a)))
(and (Math-zerop a) (not (eq (car-safe a) 'mod))
@@ -2745,21 +2870,22 @@ See calc-keypad for details."
(let* ((a (copy-sequence a)) (aa a) (carry nil) sum)
(while (and aa b)
(if carry
- (if (< (setq sum (+ (car aa) (car b))) 999)
+ (if (< (setq sum (+ (car aa) (car b)))
+ (1- math-bignum-digit-size))
(progn
(setcar aa (1+ sum))
(setq carry nil))
- (setcar aa (+ sum -999)))
- (if (< (setq sum (+ (car aa) (car b))) 1000)
+ (setcar aa (- sum (1- math-bignum-digit-size))))
+ (if (< (setq sum (+ (car aa) (car b))) math-bignum-digit-size)
(setcar aa sum)
- (setcar aa (+ sum -1000))
+ (setcar aa (- sum math-bignum-digit-size))
(setq carry t)))
(setq aa (cdr aa)
b (cdr b)))
(if carry
(if b
(nconc a (math-add-bignum b '(1)))
- (while (eq (car aa) 999)
+ (while (eq (car aa) (1- math-bignum-digit-size))
(setcar aa 0)
(setq aa (cdr aa)))
(if aa
@@ -2783,17 +2909,17 @@ See calc-keypad for details."
(progn
(setcar aa (1- diff))
(setq borrow nil))
- (setcar aa (+ diff 999)))
+ (setcar aa (+ diff (1- math-bignum-digit-size))))
(if (>= (setq diff (- (car aa) (car b))) 0)
(setcar aa diff)
- (setcar aa (+ diff 1000))
+ (setcar aa (+ diff math-bignum-digit-size))
(setq borrow t)))
(setq aa (cdr aa)
b (cdr b)))
(if borrow
(progn
(while (eq (car aa) 0)
- (setcar aa 999)
+ (setcar aa (1- math-bignum-digit-size))
(setq aa (cdr aa)))
(if aa
(progn
@@ -2833,7 +2959,7 @@ See calc-keypad for details."
(if (or (consp a) (consp b))
(math-add a (math-neg b))
(setq a (- a b))
- (if (or (<= a -1000000) (>= a 1000000))
+ (if (or (<= a (- math-small-integer-size)) (>= a math-small-integer-size))
(math-bignum a)
a)))
@@ -2860,7 +2986,8 @@ See calc-keypad for details."
(defun math-mul (a b)
(or
(and (not (consp a)) (not (consp b))
- (< a 1000) (> a -1000) (< b 1000) (> b -1000)
+ (< a math-bignum-digit-size) (> a (- math-bignum-digit-size))
+ (< b math-bignum-digit-size) (> b (- math-bignum-digit-size))
(* a b))
(and (Math-zerop a) (not (eq (car-safe b) 'mod))
(if (Math-scalarp b)
@@ -2929,14 +3056,14 @@ See calc-keypad for details."
aa a)
(while (progn
(setcar ss (% (setq prod (+ (+ (car ss) (* (car aa) d))
- c)) 1000))
+ c)) math-bignum-digit-size))
(setq aa (cdr aa)))
- (setq c (/ prod 1000)
+ (setq c (/ prod math-bignum-digit-size)
ss (or (cdr ss) (setcdr ss (list 0)))))
- (if (>= prod 1000)
+ (if (>= prod math-bignum-digit-size)
(if (cdr ss)
- (setcar (cdr ss) (+ (/ prod 1000) (car (cdr ss))))
- (setcdr ss (list (/ prod 1000))))))
+ (setcar (cdr ss) (+ (/ prod math-bignum-digit-size) (car (cdr ss))))
+ (setcdr ss (list (/ prod math-bignum-digit-size))))))
sum)))
;;; Multiply digit list A by digit D. [L L D D; l l D D]
@@ -2946,12 +3073,14 @@ See calc-keypad for details."
(and (= d 1) a)
(let* ((a (copy-sequence a)) (aa a) prod)
(while (progn
- (setcar aa (% (setq prod (+ (* (car aa) d) c)) 1000))
+ (setcar aa
+ (% (setq prod (+ (* (car aa) d) c))
+ math-bignum-digit-size))
(cdr aa))
(setq aa (cdr aa)
- c (/ prod 1000)))
- (if (>= prod 1000)
- (setcdr aa (list (/ prod 1000))))
+ c (/ prod math-bignum-digit-size)))
+ (if (>= prod math-bignum-digit-size)
+ (setcdr aa (list (/ prod math-bignum-digit-size))))
a))
(and (> c 0)
(list c))))
@@ -2964,7 +3093,7 @@ See calc-keypad for details."
(if (eq b 0)
(math-reject-arg a "*Division by zero"))
(if (or (consp a) (consp b))
- (if (and (natnump b) (< b 1000))
+ (if (and (natnump b) (< b math-bignum-digit-size))
(let ((res (math-div-bignum-digit (cdr a) b)))
(cons
(math-normalize (cons (car a) (car res)))
@@ -2983,7 +3112,7 @@ See calc-keypad for details."
(if (= b 0)
(math-reject-arg a "*Division by zero")
(/ a b))
- (if (and (natnump b) (< b 1000))
+ (if (and (natnump b) (< b math-bignum-digit-size))
(if (= b 0)
(math-reject-arg a "*Division by zero")
(math-normalize (cons (car a)
@@ -2992,7 +3121,7 @@ See calc-keypad for details."
(or (consp b) (setq b (math-bignum b)))
(let* ((alen (1- (length a)))
(blen (1- (length b)))
- (d (/ 1000 (1+ (nth (1- blen) (cdr b)))))
+ (d (/ math-bignum-digit-size (1+ (nth (1- blen) (cdr b)))))
(res (math-div-bignum-big (math-mul-bignum-digit (cdr a) d 0)
(math-mul-bignum-digit (cdr b) d 0)
alen blen)))
@@ -3006,7 +3135,7 @@ See calc-keypad for details."
(if (cdr b)
(let* ((alen (length a))
(blen (length b))
- (d (/ 1000 (1+ (nth (1- blen) b))))
+ (d (/ math-bignum-digit-size (1+ (nth (1- blen) b))))
(res (math-div-bignum-big (math-mul-bignum-digit a d 0)
(math-mul-bignum-digit b d 0)
alen blen)))
@@ -3021,7 +3150,7 @@ See calc-keypad for details."
(defun math-div-bignum-digit (a b)
(if a
(let* ((res (math-div-bignum-digit (cdr a) b))
- (num (+ (* (cdr res) 1000) (car a))))
+ (num (+ (* (cdr res) math-bignum-digit-size) (car a))))
(cons
(cons (/ num b) (car res))
(% num b)))
@@ -3037,10 +3166,11 @@ See calc-keypad for details."
(cons (car res2) (car res))
(cdr res2)))))
-(defun math-div-bignum-part (a b blen) ; a < b*1000 [D.l l L]
- (let* ((num (+ (* (or (nth blen a) 0) 1000) (or (nth (1- blen) a) 0)))
+(defun math-div-bignum-part (a b blen) ; a < b*math-bignum-digit-size [D.l l L]
+ (let* ((num (+ (* (or (nth blen a) 0) math-bignum-digit-size)
+ (or (nth (1- blen) a) 0)))
(den (nth (1- blen) b))
- (guess (min (/ num den) 999)))
+ (guess (min (/ num den) (1- math-bignum-digit-size))))
(math-div-bignum-try a b (math-mul-bignum-digit b guess 0) guess)))
(defun math-div-bignum-try (a b c guess) ; [D.l l l D]
@@ -3351,15 +3481,22 @@ See calc-keypad for details."
(if a
(let ((s ""))
(while (cdr (cdr a))
- (setq s (concat (format "%06d" (+ (* (nth 1 a) 1000) (car a))) s)
+ (setq s (concat
+ (format
+ (concat "%0"
+ (number-to-string (* 2 math-bignum-digit-length))
+ "d")
+ (+ (* (nth 1 a) math-bignum-digit-size) (car a))) s)
a (cdr (cdr a))))
- (concat (int-to-string (+ (* (or (nth 1 a) 0) 1000) (car a))) s))
+ (concat (int-to-string
+ (+ (* (or (nth 1 a) 0) math-bignum-digit-size) (car a))) s))
"0"))
;;; Parse a simple number in string form. [N X] [Public]
(defun math-read-number (s)
+ "Convert the string S into a Calc number."
(math-normalize
(cond
@@ -3370,7 +3507,7 @@ See calc-keypad for details."
(> (length digs) 1)
(eq (aref digs 0) ?0))
(math-read-number (concat "8#" digs))
- (if (<= (length digs) 6)
+ (if (<= (length digs) (* 2 math-bignum-digit-length))
(string-to-number digs)
(cons 'bigpos (math-read-bignum digs))))))
@@ -3416,50 +3553,47 @@ See calc-keypad for details."
;; Syntax error!
(t nil))))
+;;; Parse a very simple number, keeping all digits.
+(defun math-read-number-simple (s)
+ "Convert the string S into a Calc number.
+S is assumed to be a simple number (integer or float without an exponent)
+and all digits are kept, regardless of Calc's current precision."
+ (cond
+ ;; Integer
+ ((string-match "^[0-9]+$" s)
+ (if (string-match "^\\(0+\\)" s)
+ (setq s (substring s (match-end 0))))
+ (if (<= (length s) (* 2 math-bignum-digit-length))
+ (string-to-number s)
+ (cons 'bigpos (math-read-bignum s))))
+ ;; Minus sign
+ ((string-match "^-[0-9]+$" s)
+ (if (<= (length s) (1+ (* 2 math-bignum-digit-length)))
+ (string-to-number s)
+ (cons 'bigneg (math-read-bignum (substring s 1)))))
+ ;; Decimal point
+ ((string-match "^\\(-?[0-9]*\\)\\.\\([0-9]*\\)$" s)
+ (let ((int (math-match-substring s 1))
+ (frac (math-match-substring s 2)))
+ (list 'float (math-read-number-simple (concat int frac))
+ (- (length frac)))))
+ ;; Syntax error!
+ (t nil)))
+
(defun math-match-substring (s n)
(if (match-beginning n)
(substring s (match-beginning n) (match-end n))
""))
(defun math-read-bignum (s) ; [l X]
- (if (> (length s) 3)
- (cons (string-to-number (substring s -3))
- (math-read-bignum (substring s 0 -3)))
+ (if (> (length s) math-bignum-digit-length)
+ (cons (string-to-number (substring s (- math-bignum-digit-length)))
+ (math-read-bignum (substring s 0 (- math-bignum-digit-length))))
(list (string-to-number s))))
-
-(defconst math-tex-ignore-words
- '( ("\\hbox") ("\\mbox") ("\\text") ("\\left") ("\\right")
- ("\\,") ("\\>") ("\\:") ("\\;") ("\\!") ("\\ ")
- ("\\quad") ("\\qquad") ("\\hfil") ("\\hfill")
- ("\\displaystyle") ("\\textstyle") ("\\dsize") ("\\tsize")
- ("\\scriptstyle") ("\\scriptscriptstyle") ("\\ssize") ("\\sssize")
- ("\\rm") ("\\bf") ("\\it") ("\\sl")
- ("\\roman") ("\\bold") ("\\italic") ("\\slanted")
- ("\\cal") ("\\mit") ("\\Cal") ("\\Bbb") ("\\frak") ("\\goth")
- ("\\evalto")
- ("\\matrix" mat) ("\\bmatrix" mat) ("\\pmatrix" mat)
- ("\\begin" begenv)
- ("\\cr" punc ";") ("\\\\" punc ";") ("\\*" punc "*")
- ("\\{" punc "[") ("\\}" punc "]")))
-
-(defconst math-latex-ignore-words
- (append math-tex-ignore-words
- '(("\\begin" begenv))))
-
-(defconst math-eqn-ignore-words
- '( ("roman") ("bold") ("italic") ("mark") ("lineup") ("evalto")
- ("left" ("floor") ("ceil"))
- ("right" ("floor") ("ceil"))
- ("arc" ("sin") ("cos") ("tan") ("sinh") ("cosh") ("tanh"))
- ("size" n) ("font" n) ("fwd" n) ("back" n) ("up" n) ("down" n)
- ("above" punc ",")))
-
(defconst math-standard-opers
'( ( "_" calcFunc-subscr 1200 1201 )
( "%" calcFunc-percent 1100 -1 )
- ( "u+" ident -1 1000 )
- ( "u-" neg -1 1000 197 )
( "u!" calcFunc-lnot -1 1000 )
( "mod" mod 400 400 185 )
( "+/-" sdev 300 300 185 )
@@ -3467,8 +3601,8 @@ See calc-keypad for details."
( "!" calcFunc-fact 210 -1 )
( "^" ^ 201 200 )
( "**" ^ 201 200 )
- ( "*" * 196 195 )
- ( "2x" * 196 195 )
+ ( "u+" ident -1 197 )
+ ( "u-" neg -1 197 )
( "/" / 190 191 )
( "%" % 190 191 )
( "\\" calcFunc-idiv 190 191 )
@@ -3492,7 +3626,31 @@ See calc-keypad for details."
( "::" calcFunc-condition 45 46 )
( "=>" calcFunc-evalto 40 41 )
( "=>" calcFunc-evalto 40 -1 )))
-(defvar math-expr-opers math-standard-opers)
+
+(defun math-standard-ops ()
+ (if calc-multiplication-has-precedence
+ (cons
+ '( "*" * 196 195 )
+ (cons
+ '( "2x" * 196 195 )
+ math-standard-opers))
+ (cons
+ '( "*" * 190 191 )
+ (cons
+ '( "2x" * 190 191 )
+ math-standard-opers))))
+
+(defvar math-expr-opers (math-standard-ops))
+
+(defun math-standard-ops-p ()
+ (let ((meo (caar math-expr-opers)))
+ (and (stringp meo)
+ (string= meo "*"))))
+
+(defun math-expr-ops ()
+ (if (math-standard-ops-p)
+ (math-standard-ops)
+ math-expr-opers))
;;;###autoload
(defun calc-grab-region (top bot arg)
@@ -3551,7 +3709,7 @@ Also looks for the equivalent TeX words, \\gets and \\evalto."
;;; Functions needed for Lucid Emacs support.
(defun calc-read-key (&optional optkey)
- (cond (calc-emacs-type-lucid
+ (cond ((featurep 'xemacs)
(let ((event (next-command-event)))
(let ((key (event-to-character event t t)))
(or key optkey (error "Expected a plain keystroke"))
@@ -3569,7 +3727,7 @@ Also looks for the equivalent TeX words, \\gets and \\evalto."
(defun calc-clear-unread-commands ()
(if (featurep 'xemacs)
- (calc-emacs-type-lucid (setq unread-command-event nil))
+ (setq unread-command-event nil)
(setq unread-command-events nil)))
(when calc-always-load-extensions
diff --git a/lisp/calc/calcalg2.el b/lisp/calc/calcalg2.el
index b836a7d0cf0..c348e18937c 100644
--- a/lisp/calc/calcalg2.el
+++ b/lisp/calc/calcalg2.el
@@ -746,7 +746,7 @@
(setq math-integ-msg (format
"Working... Integrating %s"
(math-format-flat-expr expr 0)))
- (message math-integ-msg)))
+ (message "%s" math-integ-msg)))
(if math-cur-record
(setcar (cdr math-cur-record)
(if same-as-above (vector simp) 'busy))
@@ -773,7 +773,7 @@
"simplification...\n")
(setq val (math-integral simp 'no t))))))))
(if (eq calc-display-working-message 'lots)
- (message math-integ-msg)))
+ (message "%s" math-integ-msg)))
(setcar (cdr math-cur-record) (or val
(if (or math-enable-subst
(not math-any-substs))
diff --git a/lisp/calc/calcalg3.el b/lisp/calc/calcalg3.el
index a7b70643b63..7a5f28c13a3 100644
--- a/lisp/calc/calcalg3.el
+++ b/lisp/calc/calcalg3.el
@@ -32,6 +32,24 @@
(require 'calc-ext)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function calc-fit-s-shaped-logistic-curve "calc-nlfit" (arg))
+(declare-function calc-fit-bell-shaped-logistic-curve "calc-nlfit" (arg))
+(declare-function calc-fit-hubbert-linear-curve "calc-nlfit" (&optional sdv))
+(declare-function calc-graph-add-curve "calc-graph" (xdata ydata &optional zdata))
+(declare-function calc-graph-lookup "calc-graph" (thing))
+(declare-function calc-graph-set-styles "calc-graph" (lines points &optional yerr))
+(declare-function math-min-list "calc-arith" (a b))
+(declare-function math-max-list "calc-arith" (a b))
+
+
+(defun math-map-binop (binop args1 args2)
+ "Apply BINOP to the elements of the lists ARGS1 and ARGS2"
+ (if args1
+ (cons
+ (funcall binop (car args1) (car args2))
+ (funcall 'math-map-binop binop (cdr args1) (cdr args2)))))
+
(defun calc-find-root (var)
(interactive "sVariable(s) to solve for: ")
(calc-slow-wrapper
@@ -115,6 +133,8 @@
(if (calc-is-hyperbolic) 'calcFunc-efit
'calcFunc-fit)))
key (which 0)
+ (nonlinear nil)
+ (plot nil)
n calc-curve-nvars temp data
(homog nil)
(msgs '( "(Press ? for help)"
@@ -125,12 +145,18 @@
"E = a 10^(b x), X = 10^(a + b x), L = a + b log10(x)"
"q = a + b (x-c)^2"
"g = (a/b sqrt(2 pi)) exp(-0.5*((x-c)/b)^2)"
+ "s = a/(1 + exp(b (x - c)))"
+ "b = a exp(b (x - c))/(1 + exp(b (x - c)))^2"
+ "o = (y/x) = a (1 - x/b)"
"h prefix = homogeneous model (no constant term)"
+ "P prefix = plot result"
"' = alg entry, $ = stack, u = Model1, U = Model2")))
(while (not calc-curve-model)
- (message "Fit to model: %s:%s"
- (nth which msgs)
- (if homog " h" ""))
+ (message
+ "Fit to model: %s:%s%s"
+ (nth which msgs)
+ (if plot "P" " ")
+ (if homog "h" ""))
(setq key (read-char))
(cond ((= key ?\C-g)
(keyboard-quit))
@@ -138,6 +164,16 @@
(setq which (% (1+ which) (length msgs))))
((memq key '(?h ?H))
(setq homog (not homog)))
+ ((= key ?P)
+ (if plot
+ (setq plot nil)
+ (let ((data (calc-top 1)))
+ (if (or
+ (calc-is-hyperbolic)
+ (calc-is-inverse)
+ (not (= (length data) 3)))
+ (setq plot "Can't plot")
+ (setq plot data)))))
((progn
(if (eq key ?\$)
(setq n 1)
@@ -164,8 +200,9 @@
((= key ?1) ; linear or multilinear
(calc-get-fit-variables calc-curve-nvars
(1+ calc-curve-nvars) (and homog 0))
- (setq calc-curve-model (math-mul calc-curve-coefnames
- (cons 'vec (cons 1 (cdr calc-curve-varnames))))))
+ (setq calc-curve-model
+ (math-mul calc-curve-coefnames
+ (cons 'vec (cons 1 (cdr calc-curve-varnames))))))
((and (>= key ?2) (<= key ?9)) ; polynomial
(calc-get-fit-variables 1 (- key ?0 -1) (and homog 0))
(setq calc-curve-model
@@ -180,58 +217,88 @@
((= key ?p) ; power law
(calc-get-fit-variables calc-curve-nvars
(1+ calc-curve-nvars) (and homog 1))
- (setq calc-curve-model (math-mul (nth 1 calc-curve-coefnames)
- (calcFunc-reduce
- '(var mul var-mul)
- (calcFunc-map
- '(var pow var-pow)
- calc-curve-varnames
- (cons 'vec (cdr (cdr calc-curve-coefnames))))))))
+ (setq calc-curve-model
+ (math-mul
+ (nth 1 calc-curve-coefnames)
+ (calcFunc-reduce
+ '(var mul var-mul)
+ (calcFunc-map
+ '(var pow var-pow)
+ calc-curve-varnames
+ (cons 'vec (cdr (cdr calc-curve-coefnames))))))))
((= key ?^) ; exponential law
(calc-get-fit-variables calc-curve-nvars
(1+ calc-curve-nvars) (and homog 1))
- (setq calc-curve-model (math-mul (nth 1 calc-curve-coefnames)
- (calcFunc-reduce
- '(var mul var-mul)
- (calcFunc-map
- '(var pow var-pow)
- (cons 'vec (cdr (cdr calc-curve-coefnames)))
- calc-curve-varnames)))))
+ (setq calc-curve-model
+ (math-mul (nth 1 calc-curve-coefnames)
+ (calcFunc-reduce
+ '(var mul var-mul)
+ (calcFunc-map
+ '(var pow var-pow)
+ (cons 'vec (cdr (cdr calc-curve-coefnames)))
+ calc-curve-varnames)))))
+ ((= key ?s)
+ (setq nonlinear t)
+ (setq calc-curve-model t)
+ (require 'calc-nlfit)
+ (calc-fit-s-shaped-logistic-curve func))
+ ((= key ?b)
+ (setq nonlinear t)
+ (setq calc-curve-model t)
+ (require 'calc-nlfit)
+ (calc-fit-bell-shaped-logistic-curve func))
+ ((= key ?o)
+ (setq nonlinear t)
+ (setq calc-curve-model t)
+ (require 'calc-nlfit)
+ (if (and plot (not (stringp plot)))
+ (setq plot
+ (list 'vec
+ (nth 1 plot)
+ (cons
+ 'vec
+ (math-map-binop 'calcFunc-div
+ (cdr (nth 2 plot))
+ (cdr (nth 1 plot)))))))
+ (calc-fit-hubbert-linear-curve func))
((memq key '(?e ?E))
(calc-get-fit-variables calc-curve-nvars
(1+ calc-curve-nvars) (and homog 1))
- (setq calc-curve-model (math-mul (nth 1 calc-curve-coefnames)
- (calcFunc-reduce
- '(var mul var-mul)
- (calcFunc-map
- (if (eq key ?e)
- '(var exp var-exp)
- '(calcFunc-lambda
- (var a var-a)
- (^ 10 (var a var-a))))
- (calcFunc-map
- '(var mul var-mul)
- (cons 'vec (cdr (cdr calc-curve-coefnames)))
- calc-curve-varnames))))))
+ (setq calc-curve-model
+ (math-mul (nth 1 calc-curve-coefnames)
+ (calcFunc-reduce
+ '(var mul var-mul)
+ (calcFunc-map
+ (if (eq key ?e)
+ '(var exp var-exp)
+ '(calcFunc-lambda
+ (var a var-a)
+ (^ 10 (var a var-a))))
+ (calcFunc-map
+ '(var mul var-mul)
+ (cons 'vec (cdr (cdr calc-curve-coefnames)))
+ calc-curve-varnames))))))
((memq key '(?x ?X))
(calc-get-fit-variables calc-curve-nvars
(1+ calc-curve-nvars) (and homog 0))
- (setq calc-curve-model (math-mul calc-curve-coefnames
- (cons 'vec (cons 1 (cdr calc-curve-varnames)))))
+ (setq calc-curve-model
+ (math-mul calc-curve-coefnames
+ (cons 'vec (cons 1 (cdr calc-curve-varnames)))))
(setq calc-curve-model (if (eq key ?x)
(list 'calcFunc-exp calc-curve-model)
(list '^ 10 calc-curve-model))))
((memq key '(?l ?L))
(calc-get-fit-variables calc-curve-nvars
(1+ calc-curve-nvars) (and homog 0))
- (setq calc-curve-model (math-mul calc-curve-coefnames
- (cons 'vec
- (cons 1 (cdr (calcFunc-map
- (if (eq key ?l)
- '(var ln var-ln)
- '(var log10
- var-log10))
- calc-curve-varnames)))))))
+ (setq calc-curve-model
+ (math-mul calc-curve-coefnames
+ (cons 'vec
+ (cons 1 (cdr (calcFunc-map
+ (if (eq key ?l)
+ '(var ln var-ln)
+ '(var log10
+ var-log10))
+ calc-curve-varnames)))))))
((= key ?q)
(calc-get-fit-variables calc-curve-nvars
(1+ (* 2 calc-curve-nvars)) (and homog 0))
@@ -247,12 +314,14 @@
(list '- (car v) (nth 1 c))
2)))))))
((= key ?g)
- (setq calc-curve-model
- (math-read-expr "(AFit / BFit sqrt(2 pi)) exp(-0.5 * ((XFit - CFit) / BFit)^2)")
- calc-curve-varnames '(vec (var XFit var-XFit))
- calc-curve-coefnames '(vec (var AFit var-AFit)
- (var BFit var-BFit)
- (var CFit var-CFit)))
+ (setq
+ calc-curve-model
+ (math-read-expr
+ "(AFit / BFit sqrt(2 pi)) exp(-0.5 * ((XFit - CFit) / BFit)^2)")
+ calc-curve-varnames '(vec (var XFit var-XFit))
+ calc-curve-coefnames '(vec (var AFit var-AFit)
+ (var BFit var-BFit)
+ (var CFit var-CFit)))
(calc-get-fit-variables 1 (1- (length calc-curve-coefnames))
(and homog 1)))
((memq key '(?\$ ?\' ?u ?U))
@@ -262,8 +331,9 @@
(let* ((calc-dollar-values calc-arg-values)
(calc-dollar-used 0)
(calc-hashes-used 0))
- (setq calc-curve-model (calc-do-alg-entry "" "Model formula: "
- nil 'calc-curve-fit-history))
+ (setq calc-curve-model
+ (calc-do-alg-entry "" "Model formula: "
+ nil 'calc-curve-fit-history))
(if (/= (length calc-curve-model) 1)
(error "Bad format"))
(setq calc-curve-model (car calc-curve-model)
@@ -296,11 +366,13 @@
(or (nth 3 calc-curve-model)
(cons 'vec
(math-all-vars-but
- calc-curve-model calc-curve-varnames)))
+ calc-curve-model
+ calc-curve-varnames)))
calc-curve-model (nth 1 calc-curve-model))
(error "Incorrect model specifier")))))
(or calc-curve-varnames
- (let ((with-y (eq (car-safe calc-curve-model) 'calcFunc-eq)))
+ (let ((with-y
+ (eq (car-safe calc-curve-model) 'calcFunc-eq)))
(if calc-curve-coefnames
(calc-get-fit-variables
(if with-y (1+ calc-curve-nvars) calc-curve-nvars)
@@ -310,7 +382,10 @@
nil with-y)
(let* ((coefs (math-all-vars-but calc-curve-model nil))
(vars nil)
- (n (- (length coefs) calc-curve-nvars (if with-y 2 1)))
+ (n (-
+ (length coefs)
+ calc-curve-nvars
+ (if with-y 2 1)))
p)
(if (< n 0)
(error "Not enough variables in model"))
@@ -326,18 +401,43 @@
calc-curve-varnames calc-curve-coefnames)
"modl"))))
(t (beep))))
- (let ((calc-fit-to-trail t))
- (calc-enter-result n (substring (symbol-name func) 9)
- (list func calc-curve-model
- (if (= (length calc-curve-varnames) 2)
- (nth 1 calc-curve-varnames)
- calc-curve-varnames)
- (if (= (length calc-curve-coefnames) 2)
- (nth 1 calc-curve-coefnames)
- calc-curve-coefnames)
- data))
- (if (consp calc-fit-to-trail)
- (calc-record (calc-normalize calc-fit-to-trail) "parm"))))))
+ (unless nonlinear
+ (let ((calc-fit-to-trail t))
+ (calc-enter-result n (substring (symbol-name func) 9)
+ (list func calc-curve-model
+ (if (= (length calc-curve-varnames) 2)
+ (nth 1 calc-curve-varnames)
+ calc-curve-varnames)
+ (if (= (length calc-curve-coefnames) 2)
+ (nth 1 calc-curve-coefnames)
+ calc-curve-coefnames)
+ data))
+ (if (consp calc-fit-to-trail)
+ (calc-record (calc-normalize calc-fit-to-trail) "parm"))))
+ (when plot
+ (if (stringp plot)
+ (message "%s" plot)
+ (let ((calc-graph-no-auto-view t))
+ (calc-graph-delete t)
+ (calc-graph-add-curve
+ (calc-graph-lookup (nth 1 plot))
+ (calc-graph-lookup (nth 2 plot)))
+ (unless (math-contains-sdev-p (nth 2 data))
+ (calc-graph-set-styles nil nil)
+ (calc-graph-point-style nil))
+ (setq plot (cdr (nth 1 plot)))
+ (setq plot
+ (list 'intv
+ 3
+ (math-sub
+ (math-min-list (car plot) (cdr plot))
+ '(float 5 -1))
+ (math-add
+ '(float 5 -1)
+ (math-max-list (car plot) (cdr plot)))))
+ (calc-graph-add-curve (calc-graph-lookup plot)
+ (calc-graph-lookup (calc-top-n 1)))
+ (calc-graph-plot nil)))))))
(defun calc-invent-independent-variables (n &optional but)
(calc-invent-variables n but '(x y z t) "x"))
diff --git a/lisp/calc/calccomp.el b/lisp/calc/calccomp.el
index 90e431a61e7..d2111131f03 100644
--- a/lisp/calc/calccomp.el
+++ b/lisp/calc/calccomp.el
@@ -32,16 +32,6 @@
(require 'calc-ext)
(require 'calc-macs)
-(defconst math-eqn-special-funcs
- '( calcFunc-log
- calcFunc-ln calcFunc-exp
- calcFunc-sin calcFunc-cos calcFunc-tan
- calcFunc-sec calcFunc-csc calcFunc-cot
- calcFunc-sinh calcFunc-cosh calcFunc-tanh
- calcFunc-sech calcFunc-csch calcFunc-coth
- calcFunc-arcsin calcFunc-arccos calcFunc-arctan
- calcFunc-arcsinh calcFunc-arccosh calcFunc-arctanh))
-
;;; A "composition" has one of the following forms:
;;;
;;; "string" A literal string
@@ -80,9 +70,28 @@
(defvar math-comp-right-bracket)
(defvar math-comp-comma)
+(defun math-compose-var (a)
+ (let (v sn)
+ (if (and math-compose-hash-args
+ (let ((p calc-arg-values))
+ (setq v 1)
+ (while (and p (not (equal (car p) a)))
+ (setq p (and (eq math-compose-hash-args t) (cdr p))
+ v (1+ v)))
+ p))
+ (if (eq math-compose-hash-args 1)
+ "#"
+ (format "#%d" v))
+ (setq sn (symbol-name (nth 1 a)))
+ (if (memq calc-language calc-lang-allow-percentsigns)
+ (setq sn (math-to-percentsigns sn)))
+ (if (memq calc-language calc-lang-allow-underscores)
+ (setq sn (math-to-underscores sn)))
+ sn)))
(defun math-compose-expr (a prec)
(let ((math-compose-level (1+ math-compose-level))
+ (math-expr-opers (math-expr-ops))
spfn)
(cond
((or (and (eq a math-comp-selected) a)
@@ -93,17 +102,24 @@
(list 'tag a (math-compose-expr a prec))))
((and (not (consp a)) (not (integerp a)))
(concat "'" (prin1-to-string a)))
- ((setq spfn (assq (car-safe a) math-expr-special-function-mapping))
+ ((setq spfn (assq (car-safe a)
+ (get calc-language 'math-special-function-table)))
(setq spfn (cdr spfn))
- (funcall (car spfn) a spfn))
+ (if (consp spfn)
+ (funcall (car spfn) a spfn)
+ (funcall spfn a)))
((math-scalarp a)
(if (or (eq (car-safe a) 'frac)
(and (nth 1 calc-frac-format) (Math-integerp a)))
- (if (memq calc-language '(tex latex eqn math maple c fortran pascal))
+ (if (and
+ calc-language
+ (not (memq calc-language
+ '(flat big unform))))
(let ((aa (math-adjust-fraction a))
(calc-frac-format nil))
(math-compose-expr (list '/
- (if (memq calc-language '(c fortran))
+ (if (memq calc-language
+ calc-lang-slash-idiv)
(math-float (nth 1 aa))
(nth 1 aa))
(nth 2 aa)) prec))
@@ -267,59 +283,25 @@
(cdr a)
(if full rows 3) t)))))
(if (or calc-full-vectors (< (length a) 7))
- (if (and (eq calc-language 'tex)
- (math-matrixp a))
- (if (and (integerp calc-language-option)
- (or (= calc-language-option 0)
- (> calc-language-option 1)
- (< calc-language-option -1)))
- (append '(vleft 0 "\\matrix{")
- (math-compose-tex-matrix (cdr a))
- '("}"))
- (append '(horiz "\\matrix{ ")
- (math-compose-tex-matrix (cdr a))
- '(" }")))
- (if (and (eq calc-language 'latex)
- (math-matrixp a))
- (if (and (integerp calc-language-option)
- (or (= calc-language-option 0)
- (> calc-language-option 1)
- (< calc-language-option -1)))
- (append '(vleft 0 "\\begin{pmatrix}")
- (math-compose-tex-matrix (cdr a) t)
- '("\\end{pmatrix}"))
- (append '(horiz "\\begin{pmatrix} ")
- (math-compose-tex-matrix (cdr a) t)
- '(" \\end{pmatrix}")))
- (if (and (eq calc-language 'eqn)
- (math-matrixp a))
- (append '(horiz "matrix { ")
- (math-compose-eqn-matrix
- (cdr (math-transpose a)))
- '("}"))
- (if (and (eq calc-language 'maple)
- (math-matrixp a))
- (list 'horiz
- "matrix("
- math-comp-left-bracket
- (math-compose-vector (cdr a)
- (concat math-comp-comma " ")
- math-comp-vector-prec)
- math-comp-right-bracket
- ")")
- (list 'horiz
- math-comp-left-bracket
- (math-compose-vector (cdr a)
- (concat math-comp-comma " ")
- math-comp-vector-prec)
- math-comp-right-bracket)))))
+ (if (and
+ (setq spfn (get calc-language 'math-matrix-formatter))
+ (math-matrixp a))
+ (funcall spfn a)
+ (list 'horiz
+ math-comp-left-bracket
+ (math-compose-vector (cdr a)
+ (concat math-comp-comma " ")
+ math-comp-vector-prec)
+ math-comp-right-bracket))
(list 'horiz
math-comp-left-bracket
(math-compose-vector (list (nth 1 a) (nth 2 a) (nth 3 a))
(concat math-comp-comma " ")
math-comp-vector-prec)
- math-comp-comma (if (memq calc-language '(tex latex))
- " \\ldots" " ...")
+ math-comp-comma
+ (if (setq spfn (get calc-language 'math-dots))
+ (concat " " spfn)
+ " ...")
math-comp-comma " "
(list 'break math-compose-level)
(math-compose-expr (nth (1- (length a)) a)
@@ -353,62 +335,23 @@
(let ((v (rassq (nth 2 a) math-expr-variable-mapping)))
(if v
(symbol-name (car v))
- (if (and (memq calc-language '(tex latex))
- calc-language-option
- (not (= calc-language-option 0))
- (string-match "\\`[a-zA-Z][a-zA-Z0-9]+\\'"
- (symbol-name (nth 1 a))))
- (if (eq calc-language 'latex)
- (format "\\text{%s}" (symbol-name (nth 1 a)))
- (format "\\hbox{%s}" (symbol-name (nth 1 a))))
- (if (and math-compose-hash-args
- (let ((p calc-arg-values))
- (setq v 1)
- (while (and p (not (equal (car p) a)))
- (setq p (and (eq math-compose-hash-args t) (cdr p))
- v (1+ v)))
- p))
- (if (eq math-compose-hash-args 1)
- "#"
- (format "#%d" v))
- (if (memq calc-language '(c fortran pascal maple))
- (math-to-underscores (symbol-name (nth 1 a)))
- (if (and (eq calc-language 'eqn)
- (string-match ".'\\'" (symbol-name (nth 2 a))))
- (math-compose-expr
- (list 'calcFunc-Prime
- (list
- 'var
- (intern (substring (symbol-name (nth 1 a)) 0 -1))
- (intern (substring (symbol-name (nth 2 a)) 0 -1))))
- prec)
- (symbol-name (nth 1 a)))))))))
+ (if (setq spfn (get calc-language 'math-var-formatter))
+ (funcall spfn a prec)
+ (math-compose-var a)))))
((eq (car a) 'intv)
(list 'horiz
- (if (eq calc-language 'maple) ""
- (if (memq (nth 1 a) '(0 1)) "(" "["))
+ (if (memq (nth 1 a) '(0 1)) "(" "[")
(math-compose-expr (nth 2 a) 0)
- (if (memq calc-language '(tex latex)) " \\ldots "
- (if (eq calc-language 'eqn) " ... " " .. "))
+ " .. "
(math-compose-expr (nth 3 a) 0)
- (if (eq calc-language 'maple) ""
- (if (memq (nth 1 a) '(0 2)) ")" "]"))))
+ (if (memq (nth 1 a) '(0 2)) ")" "]")))
((eq (car a) 'date)
(if (eq (car calc-date-format) 'X)
(math-format-date a)
(concat "<" (math-format-date a) ">")))
- ((and (eq (car a) 'calcFunc-subscr) (cdr (cdr a))
- (memq calc-language '(c pascal fortran maple)))
- (let ((args (cdr (cdr a))))
- (while (and (memq calc-language '(pascal fortran))
- (eq (car-safe (nth 1 a)) 'calcFunc-subscr))
- (setq args (append (cdr (cdr (nth 1 a))) args)
- a (nth 1 a)))
- (list 'horiz
- (math-compose-expr (nth 1 a) 1000)
- (if (eq calc-language 'fortran) "(" "[")
- (math-compose-vector args ", " 0)
- (if (eq calc-language 'fortran) ")" "]"))))
+ ((and (eq (car a) 'calcFunc-subscr)
+ (setq spfn (get calc-language 'math-compose-subscr)))
+ (funcall spfn a))
((and (eq (car a) 'calcFunc-subscr) (= (length a) 3)
(eq calc-language 'big))
(let* ((a1 (math-compose-expr (nth 1 a) 1000))
@@ -425,25 +368,6 @@
", "
a2))
(list 'subscr a1 a2))))
- ((and (eq (car a) 'calcFunc-subscr) (= (length a) 3)
- (eq calc-language 'math))
- (list 'horiz
- (math-compose-expr (nth 1 a) 1000)
- "[["
- (math-compose-expr (nth 2 a) 0)
- "]]"))
- ((and (eq (car a) 'calcFunc-sqrt)
- (memq calc-language '(tex latex)))
- (list 'horiz
- "\\sqrt{"
- (math-compose-expr (nth 1 a) 0)
- "}"))
- ((and nil (eq (car a) 'calcFunc-sqrt)
- (eq calc-language 'eqn))
- (list 'horiz
- "sqrt {"
- (math-compose-expr (nth 1 a) -1)
- "}"))
((and (eq (car a) '^)
(eq calc-language 'big))
(list 'supscr
@@ -468,14 +392,6 @@
(list 'vcent
(math-comp-height a1)
a1 '(rule ?-) a2)))
- ((and (memq (car a) '(calcFunc-sum calcFunc-prod))
- (memq calc-language '(tex latex))
- (= (length a) 5))
- (list 'horiz (if (eq (car a) 'calcFunc-sum) "\\sum" "\\prod")
- "_{" (math-compose-expr (nth 2 a) 0)
- "=" (math-compose-expr (nth 3 a) 0)
- "}^{" (math-compose-expr (nth 4 a) 0)
- "}{" (math-compose-expr (nth 1 a) 0) "}"))
((and (eq (car a) 'calcFunc-lambda)
(> (length a) 2)
(memq calc-language '(nil flat big)))
@@ -524,11 +440,9 @@
(integerp (nth 2 a)))
(let ((c (math-compose-expr (nth 1 a) -1)))
(if (> prec (nth 2 a))
- (if (memq calc-language '(tex latex))
- (list 'horiz "\\left( " c " \\right)")
- (if (eq calc-language 'eqn)
- (list 'horiz "{left ( " c " right )}")
- (list 'horiz "(" c ")")))
+ (if (setq spfn (get calc-language 'math-big-parens))
+ (list 'horiz (car spfn) c (cdr spfn))
+ (list 'horiz "(" c ")"))
c)))
((and (eq (car a) 'calcFunc-choriz)
(not (eq calc-language 'unform))
@@ -662,13 +576,13 @@
(make-list (nth 1 a) c))))))
((and (eq (car a) 'calcFunc-evalto)
(setq calc-any-evaltos t)
- (memq calc-language '(tex latex eqn))
+ (setq spfn (get calc-language 'math-evalto))
(= math-compose-level (if math-comp-tagged 2 1))
(= (length a) 3))
(list 'horiz
- (if (memq calc-language '(tex latex)) "\\evalto " "evalto ")
+ (car spfn)
(math-compose-expr (nth 1 a) 0)
- (if (memq calc-language '(tex latex)) " \\to " " -> ")
+ (cdr spfn)
(math-compose-expr (nth 2 a) 0)))
(t
(let ((op (and (not (eq calc-language 'unform))
@@ -867,6 +781,9 @@
( tex . math-compose-tex )
( latex . math-compose-latex )
( eqn . math-compose-eqn )
+ ( yacas . math-compose-yacas )
+ ( maxima . math-compose-maxima )
+ ( giac . math-compose-giac )
( math . math-compose-math )
( maple . math-compose-maple ))))
(setq op (get (car a) (cdr op)))
@@ -894,56 +811,16 @@
(symbol-name func))
(math-match-substring (symbol-name func) 1)
(symbol-name func))))
- (if (memq calc-language '(c fortran pascal maple))
+ (if (memq calc-language calc-lang-allow-percentsigns)
+ (setq func (math-to-percentsigns func)))
+ (if (memq calc-language calc-lang-allow-underscores)
(setq func (math-to-underscores func)))
- (if (and (memq calc-language '(tex latex))
- calc-language-option
- (not (= calc-language-option 0))
- (string-match "\\`[a-zA-Z][a-zA-Z0-9]+\\'" func))
- (if (< (prefix-numeric-value calc-language-option) 0)
- (setq func (format "\\%s" func))
- (setq func (if (eq calc-language 'latex)
- (format "\\text{%s}" func)
- (format "\\hbox{%s}" func)))))
- (if (and (eq calc-language 'eqn)
- (string-match "[^']'+\\'" func))
- (let ((n (- (length func) (match-beginning 0) 1)))
- (setq func (substring func 0 (- n)))
- (while (>= (setq n (1- n)) 0)
- (setq func (concat func " prime")))))
- (cond ((and (memq calc-language '(tex latex))
- (or (> (length a) 2)
- (not (math-tex-expr-is-flat (nth 1 a)))))
- (setq left "\\left( "
- right " \\right)"))
- ((and (eq calc-language 'eqn)
- (or (> (length a) 2)
- (not (math-tex-expr-is-flat (nth 1 a)))))
- (setq left "{left ( "
- right " right )}"))
- ((and (or (and (memq calc-language '(tex latex))
- (eq (aref func 0) ?\\))
- (and (eq calc-language 'eqn)
- (memq (car a) math-eqn-special-funcs)))
- (not (or
- (string-match "\\hbox{" func)
- (string-match "\\text{" func)))
- (= (length a) 2)
- (or (Math-realp (nth 1 a))
- (memq (car (nth 1 a)) '(var *))))
- (setq left (if (eq calc-language 'eqn) "~{" "{")
- right "}"))
- ((eq calc-language 'eqn)
- (setq left " ( "
- right " )"))
- (t (setq left calc-function-open
- right calc-function-close)))
- (list 'horiz func left
- (math-compose-vector (cdr a)
- (if (eq calc-language 'eqn)
- " , " ", ")
- 0)
- right)))))))))
+ (if (setq spfn (get calc-language 'math-func-formatter))
+ (funcall spfn func a)
+
+ (list 'horiz func calc-function-open
+ (math-compose-vector (cdr a) ", " 0)
+ calc-function-close))))))))))
(defun math-prod-first-term (x)
@@ -1002,8 +879,12 @@
(if (<= count 0)
(if (< count 0)
(math-compose-rows (cdr a) -1 nil)
- (cons (concat (if (memq calc-language '(tex latex)) " \\ldots" " ...")
- math-comp-comma)
+ (cons (concat
+ (let ((mdots (get calc-language 'math-dots)))
+ (if mdots
+ (concat " " mdots)
+ " ..."))
+ math-comp-comma)
(math-compose-rows (cdr a) -1 nil)))
(cons (list 'horiz
(if first (concat math-comp-left-bracket " ") " ")
@@ -1015,31 +896,6 @@
(math-compose-expr (car a) math-comp-vector-prec)
(concat " " math-comp-right-bracket)))))
-(defun math-compose-tex-matrix (a &optional ltx)
- (if (cdr a)
- (cons (append (math-compose-vector (cdr (car a)) " & " 0)
- (if ltx '(" \\\\ ") '(" \\cr ")))
- (math-compose-tex-matrix (cdr a) ltx))
- (list (math-compose-vector (cdr (car a)) " & " 0))))
-
-(defun math-compose-eqn-matrix (a)
- (if a
- (cons
- (cond ((eq calc-matrix-just 'right) "rcol ")
- ((eq calc-matrix-just 'center) "ccol ")
- (t "lcol "))
- (cons
- (list 'break math-compose-level)
- (cons
- "{ "
- (cons
- (let ((math-compose-level (1+ math-compose-level)))
- (math-compose-vector (cdr (car a)) " above " 1000))
- (cons
- " } "
- (math-compose-eqn-matrix (cdr a)))))))
- nil))
-
(defun math-vector-is-string (a)
(while (and (setq a (cdr a))
(or (and (natnump (car a))
@@ -1091,6 +947,12 @@
(concat (math-match-substring x 1) "_" (math-match-substring x 2)))
x))
+(defun math-to-percentsigns (x)
+ (if (string-match "\\`\\(.*\\)o'o\\(.*\\)\\'" x)
+ (math-to-underscores
+ (concat (math-match-substring x 1) "%" (math-match-substring x 2)))
+ x))
+
(defun math-tex-expr-is-flat (a)
(or (Math-integerp a)
(memq (car a) '(float var))