comparison lisp/calc/calc-alg.el @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 0d8b17d428b5
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 ;;; calc-alg.el --- algebraic functions for Calc 1 ;;; calc-alg.el --- algebraic functions for Calc
2 2
3 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc. 3 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
4 ;; 2005 Free Software Foundation, Inc.
4 5
5 ;; Author: David Gillespie <daveg@synaptics.com> 6 ;; Author: David Gillespie <daveg@synaptics.com>
6 ;; Maintainers: D. Goel <deego@gnufans.org> 7 ;; Maintainer: Jay Belanger <belanger@truman.edu>
7 ;; Colin Walters <walters@debian.org>
8 8
9 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
10 10
11 ;; GNU Emacs is distributed in the hope that it will be useful, 11 ;; GNU Emacs is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY. No author or distributor 12 ;; but WITHOUT ANY WARRANTY. No author or distributor
26 ;;; Commentary: 26 ;;; Commentary:
27 27
28 ;;; Code: 28 ;;; Code:
29 29
30 ;; This file is autoloaded from calc-ext.el. 30 ;; This file is autoloaded from calc-ext.el.
31
31 (require 'calc-ext) 32 (require 'calc-ext)
32
33 (require 'calc-macs) 33 (require 'calc-macs)
34
35 (defun calc-Need-calc-alg () nil)
36 34
37 ;;; Algebra commands. 35 ;;; Algebra commands.
38 36
39 (defun calc-alg-evaluate (arg) 37 (defun calc-alg-evaluate (arg)
40 (interactive "p") 38 (interactive "p")
91 (calc-enter-result 1 "expa" 89 (calc-enter-result 1 "expa"
92 (append (list 'calcFunc-expand 90 (append (list 'calcFunc-expand
93 (calc-top-n 1)) 91 (calc-top-n 1))
94 (and n (list (prefix-numeric-value n))))))) 92 (and n (list (prefix-numeric-value n)))))))
95 93
94 ;;; Write out powers (a*b*...)^n as a*b*...*a*b*...
95 (defun calcFunc-powerexpand (expr)
96 (math-normalize (math-map-tree 'math-powerexpand expr)))
97
98 (defun math-powerexpand (expr)
99 (if (eq (car-safe expr) '^)
100 (let ((n (nth 2 expr)))
101 (cond ((and (integerp n)
102 (> n 0))
103 (let ((i 1)
104 (a (nth 1 expr))
105 (prod (nth 1 expr)))
106 (while (< i n)
107 (setq prod (math-mul prod a))
108 (setq i (1+ i)))
109 prod))
110 ((and (integerp n)
111 (< n 0))
112 (let ((i -1)
113 (a (math-pow (nth 1 expr) -1))
114 (prod (math-pow (nth 1 expr) -1)))
115 (while (> i n)
116 (setq prod (math-mul a prod))
117 (setq i (1- i)))
118 prod))
119 (t
120 expr)))
121 expr))
122
123 (defun calc-powerexpand ()
124 (interactive)
125 (calc-slow-wrapper
126 (calc-enter-result 1 "pexp"
127 (calcFunc-powerexpand (calc-top-n 1)))))
128
96 (defun calc-collect (&optional var) 129 (defun calc-collect (&optional var)
97 (interactive "sCollect terms involving: ") 130 (interactive "sCollect terms involving: ")
98 (calc-slow-wrapper 131 (calc-slow-wrapper
99 (if (or (equal var "") (equal var "$") (null var)) 132 (if (or (equal var "") (equal var "$") (null var))
100 (calc-enter-result 2 "clct" (cons 'calcFunc-collect 133 (calc-enter-result 2 "clct" (cons 'calcFunc-collect
119 (defun calc-poly-gcd (arg) 152 (defun calc-poly-gcd (arg)
120 (interactive "P") 153 (interactive "P")
121 (calc-slow-wrapper 154 (calc-slow-wrapper
122 (calc-binary-op "pgcd" 'calcFunc-pgcd arg))) 155 (calc-binary-op "pgcd" 'calcFunc-pgcd arg)))
123 156
157
124 (defun calc-poly-div (arg) 158 (defun calc-poly-div (arg)
125 (interactive "P") 159 (interactive "P")
126 (calc-slow-wrapper 160 (calc-slow-wrapper
127 (setq calc-poly-div-remainder nil) 161 (let ((calc-poly-div-remainder nil))
128 (calc-binary-op "pdiv" 'calcFunc-pdiv arg) 162 (calc-binary-op "pdiv" 'calcFunc-pdiv arg)
129 (if (and calc-poly-div-remainder (null arg)) 163 (if (and calc-poly-div-remainder (null arg))
130 (progn 164 (progn
131 (calc-clear-command-flag 'clear-message) 165 (calc-clear-command-flag 'clear-message)
132 (calc-record calc-poly-div-remainder "prem") 166 (calc-record calc-poly-div-remainder "prem")
133 (if (not (Math-zerop calc-poly-div-remainder)) 167 (if (not (Math-zerop calc-poly-div-remainder))
134 (message "(Remainder was %s)" 168 (message "(Remainder was %s)"
135 (math-format-flat-expr calc-poly-div-remainder 0)) 169 (math-format-flat-expr calc-poly-div-remainder 0))
136 (message "(No remainder)")))))) 170 (message "(No remainder)")))))))
137 171
138 (defun calc-poly-rem (arg) 172 (defun calc-poly-rem (arg)
139 (interactive "P") 173 (interactive "P")
140 (calc-slow-wrapper 174 (calc-slow-wrapper
141 (calc-binary-op "prem" 'calcFunc-prem arg))) 175 (calc-binary-op "prem" 'calcFunc-prem arg)))
181 (defun calc-has-rules (name) 215 (defun calc-has-rules (name)
182 (setq name (calc-var-value name)) 216 (setq name (calc-var-value name))
183 (and (consp name) 217 (and (consp name)
184 (memq (car name) '(vec calcFunc-assign calcFunc-condition)) 218 (memq (car name) '(vec calcFunc-assign calcFunc-condition))
185 name)) 219 name))
220
221 ;; math-eval-rules-cache and math-eval-rules-cache-other are
222 ;; declared in calc.el, but are used here by math-recompile-eval-rules.
223 (defvar math-eval-rules-cache)
224 (defvar math-eval-rules-cache-other)
186 225
187 (defun math-recompile-eval-rules () 226 (defun math-recompile-eval-rules ()
188 (setq math-eval-rules-cache (and (calc-has-rules 'var-EvalRules) 227 (setq math-eval-rules-cache (and (calc-has-rules 'var-EvalRules)
189 (math-compile-rewrites 228 (math-compile-rewrites
190 '(var EvalRules var-EvalRules))) 229 '(var EvalRules var-EvalRules)))
264 (let ((math-living-dangerously t)) 303 (let ((math-living-dangerously t))
265 (math-simplify a))) 304 (math-simplify a)))
266 305
267 (defalias 'calcFunc-esimplify 'math-simplify-extended) 306 (defalias 'calcFunc-esimplify 'math-simplify-extended)
268 307
308 ;; math-top-only is local to math-simplify, but is used by
309 ;; math-simplify-step, which is called by math-simplify.
310 (defvar math-top-only)
311
269 (defun math-simplify (top-expr) 312 (defun math-simplify (top-expr)
270 (let ((math-simplifying t) 313 (let ((math-simplifying t)
271 (top-only (consp calc-simplify-mode)) 314 (math-top-only (consp calc-simplify-mode))
272 (simp-rules (append (and (calc-has-rules 'var-AlgSimpRules) 315 (simp-rules (append (and (calc-has-rules 'var-AlgSimpRules)
273 '((var AlgSimpRules var-AlgSimpRules))) 316 '((var AlgSimpRules var-AlgSimpRules)))
274 (and math-living-dangerously 317 (and math-living-dangerously
275 (calc-has-rules 'var-ExtSimpRules) 318 (calc-has-rules 'var-ExtSimpRules)
276 '((var ExtSimpRules var-ExtSimpRules))) 319 '((var ExtSimpRules var-ExtSimpRules)))
279 '((var UnitSimpRules var-UnitSimpRules))) 322 '((var UnitSimpRules var-UnitSimpRules)))
280 (and math-integrating 323 (and math-integrating
281 (calc-has-rules 'var-IntegSimpRules) 324 (calc-has-rules 'var-IntegSimpRules)
282 '((var IntegSimpRules var-IntegSimpRules))))) 325 '((var IntegSimpRules var-IntegSimpRules)))))
283 res) 326 res)
284 (if top-only 327 (if math-top-only
285 (let ((r simp-rules)) 328 (let ((r simp-rules))
286 (setq res (math-simplify-step (math-normalize top-expr)) 329 (setq res (math-simplify-step (math-normalize top-expr))
287 calc-simplify-mode '(nil) 330 calc-simplify-mode '(nil)
288 top-expr (math-normalize res)) 331 top-expr (math-normalize res))
289 (while r 332 (while r
306 ;;; occur only the first handler will be tried; this doesn't really 349 ;;; occur only the first handler will be tried; this doesn't really
307 ;;; matter, since math-simplify-step is iterated to a fixed point anyway. 350 ;;; matter, since math-simplify-step is iterated to a fixed point anyway.
308 (defun math-simplify-step (a) 351 (defun math-simplify-step (a)
309 (if (Math-primp a) 352 (if (Math-primp a)
310 a 353 a
311 (let ((aa (if (or top-only 354 (let ((aa (if (or math-top-only
312 (memq (car a) '(calcFunc-quote calcFunc-condition 355 (memq (car a) '(calcFunc-quote calcFunc-condition
313 calcFunc-evalto))) 356 calcFunc-evalto)))
314 a 357 a
315 (cons (car a) (mapcar 'math-simplify-step (cdr a)))))) 358 (cons (car a) (mapcar 'math-simplify-step (cdr a))))))
316 (and (symbolp (car aa)) 359 (and (symbolp (car aa))
322 a)) 365 a))
323 (setq handler (cdr handler)))))) 366 (setq handler (cdr handler))))))
324 aa))) 367 aa)))
325 368
326 369
327 ;; Placeholder, to synchronize autoloading. 370 (defmacro math-defsimplify (funcs &rest code)
328 (defun math-need-std-simps () 371 (append '(progn)
329 nil) 372 (mapcar (function
373 (lambda (func)
374 (list 'put (list 'quote func) ''math-simplify
375 (list 'nconc
376 (list 'get (list 'quote func) ''math-simplify)
377 (list 'list
378 (list 'function
379 (append '(lambda (math-simplify-expr))
380 code)))))))
381 (if (symbolp funcs) (list funcs) funcs))))
382 (put 'math-defsimplify 'lisp-indent-hook 1)
383
384 ;; The function created by math-defsimplify uses the variable
385 ;; math-simplify-expr, and so is used by functions in math-defsimplify
386 (defvar math-simplify-expr)
330 387
331 (math-defsimplify (+ -) 388 (math-defsimplify (+ -)
332 (math-simplify-plus)) 389 (math-simplify-plus))
333 390
334 (defun math-simplify-plus () 391 (defun math-simplify-plus ()
335 (cond ((and (memq (car-safe (nth 1 expr)) '(+ -)) 392 (cond ((and (memq (car-safe (nth 1 math-simplify-expr)) '(+ -))
336 (Math-numberp (nth 2 (nth 1 expr))) 393 (Math-numberp (nth 2 (nth 1 math-simplify-expr)))
337 (not (Math-numberp (nth 2 expr)))) 394 (not (Math-numberp (nth 2 math-simplify-expr))))
338 (let ((x (nth 2 expr)) 395 (let ((x (nth 2 math-simplify-expr))
339 (op (car expr))) 396 (op (car math-simplify-expr)))
340 (setcar (cdr (cdr expr)) (nth 2 (nth 1 expr))) 397 (setcar (cdr (cdr math-simplify-expr)) (nth 2 (nth 1 math-simplify-expr)))
341 (setcar expr (car (nth 1 expr))) 398 (setcar math-simplify-expr (car (nth 1 math-simplify-expr)))
342 (setcar (cdr (cdr (nth 1 expr))) x) 399 (setcar (cdr (cdr (nth 1 math-simplify-expr))) x)
343 (setcar (nth 1 expr) op))) 400 (setcar (nth 1 math-simplify-expr) op)))
344 ((and (eq (car expr) '+) 401 ((and (eq (car math-simplify-expr) '+)
345 (Math-numberp (nth 1 expr)) 402 (Math-numberp (nth 1 math-simplify-expr))
346 (not (Math-numberp (nth 2 expr)))) 403 (not (Math-numberp (nth 2 math-simplify-expr))))
347 (let ((x (nth 2 expr))) 404 (let ((x (nth 2 math-simplify-expr)))
348 (setcar (cdr (cdr expr)) (nth 1 expr)) 405 (setcar (cdr (cdr math-simplify-expr)) (nth 1 math-simplify-expr))
349 (setcar (cdr expr) x)))) 406 (setcar (cdr math-simplify-expr) x))))
350 (let ((aa expr) 407 (let ((aa math-simplify-expr)
351 aaa temp) 408 aaa temp)
352 (while (memq (car-safe (setq aaa (nth 1 aa))) '(+ -)) 409 (while (memq (car-safe (setq aaa (nth 1 aa))) '(+ -))
353 (if (setq temp (math-combine-sum (nth 2 aaa) (nth 2 expr) 410 (if (setq temp (math-combine-sum (nth 2 aaa) (nth 2 math-simplify-expr)
354 (eq (car aaa) '-) (eq (car expr) '-) t)) 411 (eq (car aaa) '-)
412 (eq (car math-simplify-expr) '-) t))
355 (progn 413 (progn
356 (setcar (cdr (cdr expr)) temp) 414 (setcar (cdr (cdr math-simplify-expr)) temp)
357 (setcar expr '+) 415 (setcar math-simplify-expr '+)
358 (setcar (cdr (cdr aaa)) 0))) 416 (setcar (cdr (cdr aaa)) 0)))
359 (setq aa (nth 1 aa))) 417 (setq aa (nth 1 aa)))
360 (if (setq temp (math-combine-sum aaa (nth 2 expr) 418 (if (setq temp (math-combine-sum aaa (nth 2 math-simplify-expr)
361 nil (eq (car expr) '-) t)) 419 nil (eq (car math-simplify-expr) '-) t))
362 (progn 420 (progn
363 (setcar (cdr (cdr expr)) temp) 421 (setcar (cdr (cdr math-simplify-expr)) temp)
364 (setcar expr '+) 422 (setcar math-simplify-expr '+)
365 (setcar (cdr aa) 0))) 423 (setcar (cdr aa) 0)))
366 expr)) 424 math-simplify-expr))
367 425
368 (math-defsimplify * 426 (math-defsimplify *
369 (math-simplify-times)) 427 (math-simplify-times))
370 428
371 (defun math-simplify-times () 429 (defun math-simplify-times ()
372 (if (eq (car-safe (nth 2 expr)) '*) 430 (if (eq (car-safe (nth 2 math-simplify-expr)) '*)
373 (and (math-beforep (nth 1 (nth 2 expr)) (nth 1 expr)) 431 (and (math-beforep (nth 1 (nth 2 math-simplify-expr)) (nth 1 math-simplify-expr))
374 (or (math-known-scalarp (nth 1 expr) t) 432 (or (math-known-scalarp (nth 1 math-simplify-expr) t)
375 (math-known-scalarp (nth 1 (nth 2 expr)) t)) 433 (math-known-scalarp (nth 1 (nth 2 math-simplify-expr)) t))
376 (let ((x (nth 1 expr))) 434 (let ((x (nth 1 math-simplify-expr)))
377 (setcar (cdr expr) (nth 1 (nth 2 expr))) 435 (setcar (cdr math-simplify-expr) (nth 1 (nth 2 math-simplify-expr)))
378 (setcar (cdr (nth 2 expr)) x))) 436 (setcar (cdr (nth 2 math-simplify-expr)) x)))
379 (and (math-beforep (nth 2 expr) (nth 1 expr)) 437 (and (math-beforep (nth 2 math-simplify-expr) (nth 1 math-simplify-expr))
380 (or (math-known-scalarp (nth 1 expr) t) 438 (or (math-known-scalarp (nth 1 math-simplify-expr) t)
381 (math-known-scalarp (nth 2 expr) t)) 439 (math-known-scalarp (nth 2 math-simplify-expr) t))
382 (let ((x (nth 2 expr))) 440 (let ((x (nth 2 math-simplify-expr)))
383 (setcar (cdr (cdr expr)) (nth 1 expr)) 441 (setcar (cdr (cdr math-simplify-expr)) (nth 1 math-simplify-expr))
384 (setcar (cdr expr) x)))) 442 (setcar (cdr math-simplify-expr) x))))
385 (let ((aa expr) 443 (let ((aa math-simplify-expr)
386 aaa temp 444 aaa temp
387 (safe t) (scalar (math-known-scalarp (nth 1 expr)))) 445 (safe t) (scalar (math-known-scalarp (nth 1 math-simplify-expr))))
388 (if (and (Math-ratp (nth 1 expr)) 446 (if (and (Math-ratp (nth 1 math-simplify-expr))
389 (setq temp (math-common-constant-factor (nth 2 expr)))) 447 (setq temp (math-common-constant-factor (nth 2 math-simplify-expr))))
390 (progn 448 (progn
391 (setcar (cdr (cdr expr)) 449 (setcar (cdr (cdr math-simplify-expr))
392 (math-cancel-common-factor (nth 2 expr) temp)) 450 (math-cancel-common-factor (nth 2 math-simplify-expr) temp))
393 (setcar (cdr expr) (math-mul (nth 1 expr) temp)))) 451 (setcar (cdr math-simplify-expr) (math-mul (nth 1 math-simplify-expr) temp))))
394 (while (and (eq (car-safe (setq aaa (nth 2 aa))) '*) 452 (while (and (eq (car-safe (setq aaa (nth 2 aa))) '*)
395 safe) 453 safe)
396 (if (setq temp (math-combine-prod (nth 1 expr) (nth 1 aaa) nil nil t)) 454 (if (setq temp (math-combine-prod (nth 1 math-simplify-expr)
455 (nth 1 aaa) nil nil t))
397 (progn 456 (progn
398 (setcar (cdr expr) temp) 457 (setcar (cdr math-simplify-expr) temp)
399 (setcar (cdr aaa) 1))) 458 (setcar (cdr aaa) 1)))
400 (setq safe (or scalar (math-known-scalarp (nth 1 aaa) t)) 459 (setq safe (or scalar (math-known-scalarp (nth 1 aaa) t))
401 aa (nth 2 aa))) 460 aa (nth 2 aa)))
402 (if (and (setq temp (math-combine-prod aaa (nth 1 expr) nil nil t)) 461 (if (and (setq temp (math-combine-prod aaa (nth 1 math-simplify-expr) nil nil t))
403 safe) 462 safe)
404 (progn 463 (progn
405 (setcar (cdr expr) temp) 464 (setcar (cdr math-simplify-expr) temp)
406 (setcar (cdr (cdr aa)) 1))) 465 (setcar (cdr (cdr aa)) 1)))
407 (if (and (eq (car-safe (nth 1 expr)) 'frac) 466 (if (and (eq (car-safe (nth 1 math-simplify-expr)) 'frac)
408 (memq (nth 1 (nth 1 expr)) '(1 -1))) 467 (memq (nth 1 (nth 1 math-simplify-expr)) '(1 -1)))
409 (math-div (math-mul (nth 2 expr) (nth 1 (nth 1 expr))) 468 (math-div (math-mul (nth 2 math-simplify-expr)
410 (nth 2 (nth 1 expr))) 469 (nth 1 (nth 1 math-simplify-expr)))
411 expr))) 470 (nth 2 (nth 1 math-simplify-expr)))
471 math-simplify-expr)))
412 472
413 (math-defsimplify / 473 (math-defsimplify /
414 (math-simplify-divide)) 474 (math-simplify-divide))
415 475
416 (defun math-simplify-divide () 476 (defun math-simplify-divide ()
417 (let ((np (cdr expr)) 477 (let ((np (cdr math-simplify-expr))
418 (nover nil) 478 (nover nil)
419 (nn (and (or (eq (car expr) '/) (not (Math-realp (nth 2 expr)))) 479 (nn (and (or (eq (car math-simplify-expr) '/)
420 (math-common-constant-factor (nth 2 expr)))) 480 (not (Math-realp (nth 2 math-simplify-expr))))
481 (math-common-constant-factor (nth 2 math-simplify-expr))))
421 n op) 482 n op)
422 (if nn 483 (if nn
423 (progn 484 (progn
424 (setq n (and (or (eq (car expr) '/) (not (Math-realp (nth 1 expr)))) 485 (setq n (and (or (eq (car math-simplify-expr) '/)
425 (math-common-constant-factor (nth 1 expr)))) 486 (not (Math-realp (nth 1 math-simplify-expr))))
487 (math-common-constant-factor (nth 1 math-simplify-expr))))
426 (if (and (eq (car-safe nn) 'frac) (eq (nth 1 nn) 1) (not n)) 488 (if (and (eq (car-safe nn) 'frac) (eq (nth 1 nn) 1) (not n))
427 (progn 489 (progn
428 (setcar (cdr expr) (math-mul (nth 2 nn) (nth 1 expr))) 490 (setcar (cdr math-simplify-expr)
429 (setcar (cdr (cdr expr)) 491 (math-mul (nth 2 nn) (nth 1 math-simplify-expr)))
430 (math-cancel-common-factor (nth 2 expr) nn)) 492 (setcar (cdr (cdr math-simplify-expr))
493 (math-cancel-common-factor (nth 2 math-simplify-expr) nn))
431 (if (and (math-negp nn) 494 (if (and (math-negp nn)
432 (setq op (assq (car expr) calc-tweak-eqn-table))) 495 (setq op (assq (car math-simplify-expr) calc-tweak-eqn-table)))
433 (setcar expr (nth 1 op)))) 496 (setcar math-simplify-expr (nth 1 op))))
434 (if (and n (not (eq (setq n (math-frac-gcd n nn)) 1))) 497 (if (and n (not (eq (setq n (math-frac-gcd n nn)) 1)))
435 (progn 498 (progn
436 (setcar (cdr expr) 499 (setcar (cdr math-simplify-expr)
437 (math-cancel-common-factor (nth 1 expr) n)) 500 (math-cancel-common-factor (nth 1 math-simplify-expr) n))
438 (setcar (cdr (cdr expr)) 501 (setcar (cdr (cdr math-simplify-expr))
439 (math-cancel-common-factor (nth 2 expr) n)) 502 (math-cancel-common-factor (nth 2 math-simplify-expr) n))
440 (if (and (math-negp n) 503 (if (and (math-negp n)
441 (setq op (assq (car expr) calc-tweak-eqn-table))) 504 (setq op (assq (car math-simplify-expr)
442 (setcar expr (nth 1 op)))))))) 505 calc-tweak-eqn-table)))
506 (setcar math-simplify-expr (nth 1 op))))))))
443 (if (and (eq (car-safe (car np)) '/) 507 (if (and (eq (car-safe (car np)) '/)
444 (math-known-scalarp (nth 2 expr) t)) 508 (math-known-scalarp (nth 2 math-simplify-expr) t))
445 (progn 509 (progn
446 (setq np (cdr (nth 1 expr))) 510 (setq np (cdr (nth 1 math-simplify-expr)))
447 (while (eq (car-safe (setq n (car np))) '*) 511 (while (eq (car-safe (setq n (car np))) '*)
448 (and (math-known-scalarp (nth 2 n) t) 512 (and (math-known-scalarp (nth 2 n) t)
449 (math-simplify-divisor (cdr n) (cdr (cdr expr)) nil t)) 513 (math-simplify-divisor (cdr n) (cdr (cdr math-simplify-expr)) nil t))
450 (setq np (cdr (cdr n)))) 514 (setq np (cdr (cdr n))))
451 (math-simplify-divisor np (cdr (cdr expr)) nil t) 515 (math-simplify-divisor np (cdr (cdr math-simplify-expr)) nil t)
452 (setq nover t 516 (setq nover t
453 np (cdr (cdr (nth 1 expr)))))) 517 np (cdr (cdr (nth 1 math-simplify-expr))))))
454 (while (eq (car-safe (setq n (car np))) '*) 518 (while (eq (car-safe (setq n (car np))) '*)
455 (and (math-known-scalarp (nth 2 n) t) 519 (and (math-known-scalarp (nth 2 n) t)
456 (math-simplify-divisor (cdr n) (cdr (cdr expr)) nover t)) 520 (math-simplify-divisor (cdr n) (cdr (cdr math-simplify-expr)) nover t))
457 (setq np (cdr (cdr n)))) 521 (setq np (cdr (cdr n))))
458 (math-simplify-divisor np (cdr (cdr expr)) nover t) 522 (math-simplify-divisor np (cdr (cdr math-simplify-expr)) nover t)
459 expr)) 523 math-simplify-expr))
460 524
461 (defun math-simplify-divisor (np dp nover dover) 525 ;; The variables math-simplify-divisor-nover and math-simplify-divisor-dover
526 ;; are local variables for math-simplify-divisor, but are used by
527 ;; math-simplify-one-divisor.
528 (defvar math-simplify-divisor-nover)
529 (defvar math-simplify-divisor-dover)
530
531 (defun math-simplify-divisor (np dp math-simplify-divisor-nover
532 math-simplify-divisor-dover)
462 (cond ((eq (car-safe (car dp)) '/) 533 (cond ((eq (car-safe (car dp)) '/)
463 (math-simplify-divisor np (cdr (car dp)) nover dover) 534 (math-simplify-divisor np (cdr (car dp))
535 math-simplify-divisor-nover
536 math-simplify-divisor-dover)
464 (and (math-known-scalarp (nth 1 (car dp)) t) 537 (and (math-known-scalarp (nth 1 (car dp)) t)
465 (math-simplify-divisor np (cdr (cdr (car dp))) 538 (math-simplify-divisor np (cdr (cdr (car dp)))
466 nover (not dover)))) 539 math-simplify-divisor-nover
467 ((or (or (eq (car expr) '/) 540 (not math-simplify-divisor-dover))))
541 ((or (or (eq (car math-simplify-expr) '/)
468 (let ((signs (math-possible-signs (car np)))) 542 (let ((signs (math-possible-signs (car np))))
469 (or (memq signs '(1 4)) 543 (or (memq signs '(1 4))
470 (and (memq (car expr) '(calcFunc-eq calcFunc-neq)) 544 (and (memq (car math-simplify-expr) '(calcFunc-eq calcFunc-neq))
471 (eq signs 5)) 545 (eq signs 5))
472 math-living-dangerously))) 546 math-living-dangerously)))
473 (math-numberp (car np))) 547 (math-numberp (car np)))
474 (let ((n (car np)) 548 (let (d
475 d dd temp op 549 (safe t)
476 (safe t) (scalar (math-known-scalarp n))) 550 (scalar (math-known-scalarp (car np))))
477 (while (and (eq (car-safe (setq d (car dp))) '*) 551 (while (and (eq (car-safe (setq d (car dp))) '*)
478 safe) 552 safe)
479 (math-simplify-one-divisor np (cdr d)) 553 (math-simplify-one-divisor np (cdr d))
480 (setq safe (or scalar (math-known-scalarp (nth 1 d) t)) 554 (setq safe (or scalar (math-known-scalarp (nth 1 d) t))
481 dp (cdr (cdr d)))) 555 dp (cdr (cdr d))))
482 (if safe 556 (if safe
483 (math-simplify-one-divisor np dp)))))) 557 (math-simplify-one-divisor np dp))))))
484 558
485 (defun math-simplify-one-divisor (np dp) 559 (defun math-simplify-one-divisor (np dp)
486 (if (setq temp (math-combine-prod (car np) (car dp) nover dover t)) 560 (let ((temp (math-combine-prod (car np) (car dp) math-simplify-divisor-nover
487 (progn 561 math-simplify-divisor-dover t))
488 (and (not (memq (car expr) '(/ calcFunc-eq calcFunc-neq))) 562 op)
489 (math-known-negp (car dp)) 563 (if temp
490 (setq op (assq (car expr) calc-tweak-eqn-table)) 564 (progn
491 (setcar expr (nth 1 op))) 565 (and (not (memq (car math-simplify-expr) '(/ calcFunc-eq calcFunc-neq)))
492 (setcar np (if nover (math-div 1 temp) temp)) 566 (math-known-negp (car dp))
493 (setcar dp 1)) 567 (setq op (assq (car math-simplify-expr) calc-tweak-eqn-table))
494 (and dover (not nover) (eq (car expr) '/) 568 (setcar math-simplify-expr (nth 1 op)))
495 (eq (car-safe (car dp)) 'calcFunc-sqrt) 569 (setcar np (if math-simplify-divisor-nover (math-div 1 temp) temp))
496 (Math-integerp (nth 1 (car dp))) 570 (setcar dp 1))
497 (progn 571 (and math-simplify-divisor-dover (not math-simplify-divisor-nover)
498 (setcar np (math-mul (car np) 572 (eq (car math-simplify-expr) '/)
499 (list 'calcFunc-sqrt (nth 1 (car dp))))) 573 (eq (car-safe (car dp)) 'calcFunc-sqrt)
500 (setcar dp (nth 1 (car dp))))))) 574 (Math-integerp (nth 1 (car dp)))
575 (progn
576 (setcar np (math-mul (car np)
577 (list 'calcFunc-sqrt (nth 1 (car dp)))))
578 (setcar dp (nth 1 (car dp))))))))
501 579
502 (defun math-common-constant-factor (expr) 580 (defun math-common-constant-factor (expr)
503 (if (Math-realp expr) 581 (if (Math-realp expr)
504 (if (Math-ratp expr) 582 (if (Math-ratp expr)
505 (and (not (memq expr '(0 1 -1))) 583 (and (not (memq expr '(0 1 -1)))
544 622
545 (math-defsimplify % 623 (math-defsimplify %
546 (math-simplify-mod)) 624 (math-simplify-mod))
547 625
548 (defun math-simplify-mod () 626 (defun math-simplify-mod ()
549 (and (Math-realp (nth 2 expr)) 627 (and (Math-realp (nth 2 math-simplify-expr))
550 (Math-posp (nth 2 expr)) 628 (Math-posp (nth 2 math-simplify-expr))
551 (let ((lin (math-is-linear (nth 1 expr))) 629 (let ((lin (math-is-linear (nth 1 math-simplify-expr)))
552 t1 t2 t3) 630 t1 t2 t3)
553 (or (and lin 631 (or (and lin
554 (or (math-negp (car lin)) 632 (or (math-negp (car lin))
555 (not (Math-lessp (car lin) (nth 2 expr)))) 633 (not (Math-lessp (car lin) (nth 2 math-simplify-expr))))
556 (list '% 634 (list '%
557 (list '+ 635 (list '+
558 (math-mul (nth 1 lin) (nth 2 lin)) 636 (math-mul (nth 1 lin) (nth 2 lin))
559 (math-mod (car lin) (nth 2 expr))) 637 (math-mod (car lin) (nth 2 math-simplify-expr)))
560 (nth 2 expr))) 638 (nth 2 math-simplify-expr)))
561 (and lin 639 (and lin
562 (not (math-equal-int (nth 1 lin) 1)) 640 (not (math-equal-int (nth 1 lin) 1))
563 (math-num-integerp (nth 1 lin)) 641 (math-num-integerp (nth 1 lin))
564 (math-num-integerp (nth 2 expr)) 642 (math-num-integerp (nth 2 math-simplify-expr))
565 (setq t1 (calcFunc-gcd (nth 1 lin) (nth 2 expr))) 643 (setq t1 (calcFunc-gcd (nth 1 lin) (nth 2 math-simplify-expr)))
566 (not (math-equal-int t1 1)) 644 (not (math-equal-int t1 1))
567 (list '* 645 (list '*
568 t1 646 t1
569 (list '% 647 (list '%
570 (list '+ 648 (list '+
571 (math-mul (math-div (nth 1 lin) t1) 649 (math-mul (math-div (nth 1 lin) t1)
572 (nth 2 lin)) 650 (nth 2 lin))
573 (let ((calc-prefer-frac t)) 651 (let ((calc-prefer-frac t))
574 (math-div (car lin) t1))) 652 (math-div (car lin) t1)))
575 (math-div (nth 2 expr) t1)))) 653 (math-div (nth 2 math-simplify-expr) t1))))
576 (and (math-equal-int (nth 2 expr) 1) 654 (and (math-equal-int (nth 2 math-simplify-expr) 1)
577 (math-known-integerp (if lin 655 (math-known-integerp (if lin
578 (math-mul (nth 1 lin) (nth 2 lin)) 656 (math-mul (nth 1 lin) (nth 2 lin))
579 (nth 1 expr))) 657 (nth 1 math-simplify-expr)))
580 (if lin (math-mod (car lin) 1) 0)))))) 658 (if lin (math-mod (car lin) 1) 0))))))
581 659
582 (math-defsimplify (calcFunc-eq calcFunc-neq calcFunc-lt 660 (math-defsimplify (calcFunc-eq calcFunc-neq calcFunc-lt
583 calcFunc-gt calcFunc-leq calcFunc-geq) 661 calcFunc-gt calcFunc-leq calcFunc-geq)
584 (if (= (length expr) 3) 662 (if (= (length math-simplify-expr) 3)
585 (math-simplify-ineq))) 663 (math-simplify-ineq)))
586 664
587 (defun math-simplify-ineq () 665 (defun math-simplify-ineq ()
588 (let ((np (cdr expr)) 666 (let ((np (cdr math-simplify-expr))
589 n) 667 n)
590 (while (memq (car-safe (setq n (car np))) '(+ -)) 668 (while (memq (car-safe (setq n (car np))) '(+ -))
591 (math-simplify-add-term (cdr (cdr n)) (cdr (cdr expr)) 669 (math-simplify-add-term (cdr (cdr n)) (cdr (cdr math-simplify-expr))
592 (eq (car n) '-) nil) 670 (eq (car n) '-) nil)
593 (setq np (cdr n))) 671 (setq np (cdr n)))
594 (math-simplify-add-term np (cdr (cdr expr)) nil (eq np (cdr expr))) 672 (math-simplify-add-term np (cdr (cdr math-simplify-expr)) nil
673 (eq np (cdr math-simplify-expr)))
595 (math-simplify-divide) 674 (math-simplify-divide)
596 (let ((signs (math-possible-signs (cons '- (cdr expr))))) 675 (let ((signs (math-possible-signs (cons '- (cdr math-simplify-expr)))))
597 (or (cond ((eq (car expr) 'calcFunc-eq) 676 (or (cond ((eq (car math-simplify-expr) 'calcFunc-eq)
598 (or (and (eq signs 2) 1) 677 (or (and (eq signs 2) 1)
599 (and (memq signs '(1 4 5)) 0))) 678 (and (memq signs '(1 4 5)) 0)))
600 ((eq (car expr) 'calcFunc-neq) 679 ((eq (car math-simplify-expr) 'calcFunc-neq)
601 (or (and (eq signs 2) 0) 680 (or (and (eq signs 2) 0)
602 (and (memq signs '(1 4 5)) 1))) 681 (and (memq signs '(1 4 5)) 1)))
603 ((eq (car expr) 'calcFunc-lt) 682 ((eq (car math-simplify-expr) 'calcFunc-lt)
604 (or (and (eq signs 1) 1) 683 (or (and (eq signs 1) 1)
605 (and (memq signs '(2 4 6)) 0))) 684 (and (memq signs '(2 4 6)) 0)))
606 ((eq (car expr) 'calcFunc-gt) 685 ((eq (car math-simplify-expr) 'calcFunc-gt)
607 (or (and (eq signs 4) 1) 686 (or (and (eq signs 4) 1)
608 (and (memq signs '(1 2 3)) 0))) 687 (and (memq signs '(1 2 3)) 0)))
609 ((eq (car expr) 'calcFunc-leq) 688 ((eq (car math-simplify-expr) 'calcFunc-leq)
610 (or (and (eq signs 4) 0) 689 (or (and (eq signs 4) 0)
611 (and (memq signs '(1 2 3)) 1))) 690 (and (memq signs '(1 2 3)) 1)))
612 ((eq (car expr) 'calcFunc-geq) 691 ((eq (car math-simplify-expr) 'calcFunc-geq)
613 (or (and (eq signs 1) 0) 692 (or (and (eq signs 1) 0)
614 (and (memq signs '(2 4 6)) 1)))) 693 (and (memq signs '(2 4 6)) 1))))
615 expr)))) 694 math-simplify-expr))))
616 695
617 (defun math-simplify-add-term (np dp minus lplain) 696 (defun math-simplify-add-term (np dp minus lplain)
618 (or (math-vectorp (car np)) 697 (or (math-vectorp (car np))
619 (let ((rplain t) 698 (let ((rplain t)
620 n d dd temp) 699 n d dd temp)
642 (progn 721 (progn
643 (setcar np 0) 722 (setcar np 0)
644 (setcar dp (setq n (math-neg temp))))))))) 723 (setcar dp (setq n (math-neg temp)))))))))
645 724
646 (math-defsimplify calcFunc-sin 725 (math-defsimplify calcFunc-sin
647 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-arcsin) 726 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
648 (nth 1 (nth 1 expr))) 727 (nth 1 (nth 1 math-simplify-expr)))
649 (and (math-looks-negp (nth 1 expr)) 728 (and (math-looks-negp (nth 1 math-simplify-expr))
650 (math-neg (list 'calcFunc-sin (math-neg (nth 1 expr))))) 729 (math-neg (list 'calcFunc-sin (math-neg (nth 1 math-simplify-expr)))))
651 (and (eq calc-angle-mode 'rad) 730 (and (eq calc-angle-mode 'rad)
652 (let ((n (math-linear-in (nth 1 expr) '(var pi var-pi)))) 731 (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
653 (and n 732 (and n
654 (math-known-sin (car n) (nth 1 n) 120 0)))) 733 (math-known-sin (car n) (nth 1 n) 120 0))))
655 (and (eq calc-angle-mode 'deg) 734 (and (eq calc-angle-mode 'deg)
656 (let ((n (math-integer-plus (nth 1 expr)))) 735 (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
657 (and n 736 (and n
658 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 0)))) 737 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 0))))
659 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arccos) 738 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
660 (list 'calcFunc-sqrt (math-sub 1 (math-sqr (nth 1 (nth 1 expr)))))) 739 (list 'calcFunc-sqrt (math-sub 1 (math-sqr
661 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arctan) 740 (nth 1 (nth 1 math-simplify-expr))))))
662 (math-div (nth 1 (nth 1 expr)) 741 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
742 (math-div (nth 1 (nth 1 math-simplify-expr))
663 (list 'calcFunc-sqrt 743 (list 'calcFunc-sqrt
664 (math-add 1 (math-sqr (nth 1 (nth 1 expr))))))) 744 (math-add 1 (math-sqr
665 (let ((m (math-should-expand-trig (nth 1 expr)))) 745 (nth 1 (nth 1 math-simplify-expr)))))))
746 (let ((m (math-should-expand-trig (nth 1 math-simplify-expr))))
666 (and m (integerp (car m)) 747 (and m (integerp (car m))
667 (let ((n (car m)) (a (nth 1 m))) 748 (let ((n (car m)) (a (nth 1 m)))
668 (list '+ 749 (list '+
669 (list '* (list 'calcFunc-sin (list '* (1- n) a)) 750 (list '* (list 'calcFunc-sin (list '* (1- n) a))
670 (list 'calcFunc-cos a)) 751 (list 'calcFunc-cos a))
671 (list '* (list 'calcFunc-cos (list '* (1- n) a)) 752 (list '* (list 'calcFunc-cos (list '* (1- n) a))
672 (list 'calcFunc-sin a)))))))) 753 (list 'calcFunc-sin a))))))))
673 754
674 (math-defsimplify calcFunc-cos 755 (math-defsimplify calcFunc-cos
675 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-arccos) 756 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
676 (nth 1 (nth 1 expr))) 757 (nth 1 (nth 1 math-simplify-expr)))
677 (and (math-looks-negp (nth 1 expr)) 758 (and (math-looks-negp (nth 1 math-simplify-expr))
678 (list 'calcFunc-cos (math-neg (nth 1 expr)))) 759 (list 'calcFunc-cos (math-neg (nth 1 math-simplify-expr))))
679 (and (eq calc-angle-mode 'rad) 760 (and (eq calc-angle-mode 'rad)
680 (let ((n (math-linear-in (nth 1 expr) '(var pi var-pi)))) 761 (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
681 (and n 762 (and n
682 (math-known-sin (car n) (nth 1 n) 120 300)))) 763 (math-known-sin (car n) (nth 1 n) 120 300))))
683 (and (eq calc-angle-mode 'deg) 764 (and (eq calc-angle-mode 'deg)
684 (let ((n (math-integer-plus (nth 1 expr)))) 765 (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
685 (and n 766 (and n
686 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 300)))) 767 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 300))))
687 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arcsin) 768 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
688 (list 'calcFunc-sqrt (math-sub 1 (math-sqr (nth 1 (nth 1 expr)))))) 769 (list 'calcFunc-sqrt
689 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arctan) 770 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr))))))
771 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
690 (math-div 1 772 (math-div 1
691 (list 'calcFunc-sqrt 773 (list 'calcFunc-sqrt
692 (math-add 1 (math-sqr (nth 1 (nth 1 expr))))))) 774 (math-add 1
693 (let ((m (math-should-expand-trig (nth 1 expr)))) 775 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
776 (let ((m (math-should-expand-trig (nth 1 math-simplify-expr))))
694 (and m (integerp (car m)) 777 (and m (integerp (car m))
695 (let ((n (car m)) (a (nth 1 m))) 778 (let ((n (car m)) (a (nth 1 m)))
696 (list '- 779 (list '-
697 (list '* (list 'calcFunc-cos (list '* (1- n) a)) 780 (list '* (list 'calcFunc-cos (list '* (1- n) a))
698 (list 'calcFunc-cos a)) 781 (list 'calcFunc-cos a))
699 (list '* (list 'calcFunc-sin (list '* (1- n) a)) 782 (list '* (list 'calcFunc-sin (list '* (1- n) a))
700 (list 'calcFunc-sin a)))))))) 783 (list 'calcFunc-sin a))))))))
784
785 (math-defsimplify calcFunc-sec
786 (or (and (math-looks-negp (nth 1 math-simplify-expr))
787 (list 'calcFunc-sec (math-neg (nth 1 math-simplify-expr))))
788 (and (eq calc-angle-mode 'rad)
789 (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
790 (and n
791 (math-div 1 (math-known-sin (car n) (nth 1 n) 120 300)))))
792 (and (eq calc-angle-mode 'deg)
793 (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
794 (and n
795 (math-div 1 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 300)))))
796 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
797 (math-div
798 1
799 (list 'calcFunc-sqrt
800 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
801 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
802 (math-div
803 1
804 (nth 1 (nth 1 math-simplify-expr))))
805 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
806 (list 'calcFunc-sqrt
807 (math-add 1
808 (math-sqr (nth 1 (nth 1 math-simplify-expr))))))))
809
810 (math-defsimplify calcFunc-csc
811 (or (and (math-looks-negp (nth 1 math-simplify-expr))
812 (math-neg (list 'calcFunc-csc (math-neg (nth 1 math-simplify-expr)))))
813 (and (eq calc-angle-mode 'rad)
814 (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
815 (and n
816 (math-div 1 (math-known-sin (car n) (nth 1 n) 120 0)))))
817 (and (eq calc-angle-mode 'deg)
818 (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
819 (and n
820 (math-div 1 (math-known-sin (car n) (nth 1 n) '(frac 2 3) 0)))))
821 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
822 (math-div 1 (nth 1 (nth 1 math-simplify-expr))))
823 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
824 (math-div
825 1
826 (list 'calcFunc-sqrt (math-sub 1 (math-sqr
827 (nth 1 (nth 1 math-simplify-expr)))))))
828 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
829 (math-div (list 'calcFunc-sqrt
830 (math-add 1 (math-sqr
831 (nth 1 (nth 1 math-simplify-expr)))))
832 (nth 1 (nth 1 math-simplify-expr))))))
701 833
702 (defun math-should-expand-trig (x &optional hyperbolic) 834 (defun math-should-expand-trig (x &optional hyperbolic)
703 (let ((m (math-is-multiple x))) 835 (let ((m (math-is-multiple x)))
704 (and math-living-dangerously 836 (and math-living-dangerously
705 m (or (and (integerp (car m)) (> (car m) 1)) 837 m (or (and (integerp (car m)) (> (car m) 1))
750 (cond ((eq n 0) (math-normalize (list 'calcFunc-sin plus))) 882 (cond ((eq n 0) (math-normalize (list 'calcFunc-sin plus)))
751 ((eq n 60) (math-normalize (list 'calcFunc-cos plus))) 883 ((eq n 60) (math-normalize (list 'calcFunc-cos plus)))
752 (t nil)))))) 884 (t nil))))))
753 885
754 (math-defsimplify calcFunc-tan 886 (math-defsimplify calcFunc-tan
755 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-arctan) 887 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
756 (nth 1 (nth 1 expr))) 888 (nth 1 (nth 1 math-simplify-expr)))
757 (and (math-looks-negp (nth 1 expr)) 889 (and (math-looks-negp (nth 1 math-simplify-expr))
758 (math-neg (list 'calcFunc-tan (math-neg (nth 1 expr))))) 890 (math-neg (list 'calcFunc-tan (math-neg (nth 1 math-simplify-expr)))))
759 (and (eq calc-angle-mode 'rad) 891 (and (eq calc-angle-mode 'rad)
760 (let ((n (math-linear-in (nth 1 expr) '(var pi var-pi)))) 892 (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
761 (and n 893 (and n
762 (math-known-tan (car n) (nth 1 n) 120)))) 894 (math-known-tan (car n) (nth 1 n) 120))))
763 (and (eq calc-angle-mode 'deg) 895 (and (eq calc-angle-mode 'deg)
764 (let ((n (math-integer-plus (nth 1 expr)))) 896 (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
765 (and n 897 (and n
766 (math-known-tan (car n) (nth 1 n) '(frac 2 3))))) 898 (math-known-tan (car n) (nth 1 n) '(frac 2 3)))))
767 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arcsin) 899 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
768 (math-div (nth 1 (nth 1 expr)) 900 (math-div (nth 1 (nth 1 math-simplify-expr))
769 (list 'calcFunc-sqrt 901 (list 'calcFunc-sqrt
770 (math-sub 1 (math-sqr (nth 1 (nth 1 expr))))))) 902 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
771 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arccos) 903 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
772 (math-div (list 'calcFunc-sqrt 904 (math-div (list 'calcFunc-sqrt
773 (math-sub 1 (math-sqr (nth 1 (nth 1 expr))))) 905 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))
774 (nth 1 (nth 1 expr)))) 906 (nth 1 (nth 1 math-simplify-expr))))
775 (let ((m (math-should-expand-trig (nth 1 expr)))) 907 (let ((m (math-should-expand-trig (nth 1 math-simplify-expr))))
776 (and m 908 (and m
777 (if (equal (car m) '(frac 1 2)) 909 (if (equal (car m) '(frac 1 2))
778 (math-div (math-sub 1 (list 'calcFunc-cos (nth 1 m))) 910 (math-div (math-sub 1 (list 'calcFunc-cos (nth 1 m)))
779 (list 'calcFunc-sin (nth 1 m))) 911 (list 'calcFunc-sin (nth 1 m)))
780 (math-div (list 'calcFunc-sin (nth 1 expr)) 912 (math-div (list 'calcFunc-sin (nth 1 math-simplify-expr))
781 (list 'calcFunc-cos (nth 1 expr)))))))) 913 (list 'calcFunc-cos (nth 1 math-simplify-expr))))))))
914
915 (math-defsimplify calcFunc-cot
916 (or (and (math-looks-negp (nth 1 math-simplify-expr))
917 (math-neg (list 'calcFunc-cot (math-neg (nth 1 math-simplify-expr)))))
918 (and (eq calc-angle-mode 'rad)
919 (let ((n (math-linear-in (nth 1 math-simplify-expr) '(var pi var-pi))))
920 (and n
921 (math-div 1 (math-known-tan (car n) (nth 1 n) 120)))))
922 (and (eq calc-angle-mode 'deg)
923 (let ((n (math-integer-plus (nth 1 math-simplify-expr))))
924 (and n
925 (math-div 1 (math-known-tan (car n) (nth 1 n) '(frac 2 3))))))
926 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsin)
927 (math-div (list 'calcFunc-sqrt
928 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))
929 (nth 1 (nth 1 math-simplify-expr))))
930 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccos)
931 (math-div (nth 1 (nth 1 math-simplify-expr))
932 (list 'calcFunc-sqrt
933 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
934 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctan)
935 (math-div 1 (nth 1 (nth 1 math-simplify-expr))))))
782 936
783 (defun math-known-tan (plus n mul) 937 (defun math-known-tan (plus n mul)
784 (setq n (math-mul n mul)) 938 (setq n (math-mul n mul))
785 (and (math-num-integerp n) 939 (and (math-num-integerp n)
786 (setq n (math-mod (math-trunc n) 120)) 940 (setq n (math-mod (math-trunc n) 120))
811 ((eq n 60) (math-normalize (list '/ -1 965 ((eq n 60) (math-normalize (list '/ -1
812 (list 'calcFunc-tan plus)))) 966 (list 'calcFunc-tan plus))))
813 (t nil)))))) 967 (t nil))))))
814 968
815 (math-defsimplify calcFunc-sinh 969 (math-defsimplify calcFunc-sinh
816 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-arcsinh) 970 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
817 (nth 1 (nth 1 expr))) 971 (nth 1 (nth 1 math-simplify-expr)))
818 (and (math-looks-negp (nth 1 expr)) 972 (and (math-looks-negp (nth 1 math-simplify-expr))
819 (math-neg (list 'calcFunc-sinh (math-neg (nth 1 expr))))) 973 (math-neg (list 'calcFunc-sinh (math-neg (nth 1 math-simplify-expr)))))
820 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arccosh) 974 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
821 math-living-dangerously 975 math-living-dangerously
822 (list 'calcFunc-sqrt (math-sub (math-sqr (nth 1 (nth 1 expr))) 1))) 976 (list 'calcFunc-sqrt
823 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arctanh) 977 (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1)))
978 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
824 math-living-dangerously 979 math-living-dangerously
825 (math-div (nth 1 (nth 1 expr)) 980 (math-div (nth 1 (nth 1 math-simplify-expr))
826 (list 'calcFunc-sqrt 981 (list 'calcFunc-sqrt
827 (math-sub 1 (math-sqr (nth 1 (nth 1 expr))))))) 982 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
828 (let ((m (math-should-expand-trig (nth 1 expr) t))) 983 (let ((m (math-should-expand-trig (nth 1 math-simplify-expr) t)))
829 (and m (integerp (car m)) 984 (and m (integerp (car m))
830 (let ((n (car m)) (a (nth 1 m))) 985 (let ((n (car m)) (a (nth 1 m)))
831 (if (> n 1) 986 (if (> n 1)
832 (list '+ 987 (list '+
833 (list '* (list 'calcFunc-sinh (list '* (1- n) a)) 988 (list '* (list 'calcFunc-sinh (list '* (1- n) a))
834 (list 'calcFunc-cosh a)) 989 (list 'calcFunc-cosh a))
835 (list '* (list 'calcFunc-cosh (list '* (1- n) a)) 990 (list '* (list 'calcFunc-cosh (list '* (1- n) a))
836 (list 'calcFunc-sinh a))))))))) 991 (list 'calcFunc-sinh a)))))))))
837 992
838 (math-defsimplify calcFunc-cosh 993 (math-defsimplify calcFunc-cosh
839 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-arccosh) 994 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
840 (nth 1 (nth 1 expr))) 995 (nth 1 (nth 1 math-simplify-expr)))
841 (and (math-looks-negp (nth 1 expr)) 996 (and (math-looks-negp (nth 1 math-simplify-expr))
842 (list 'calcFunc-cosh (math-neg (nth 1 expr)))) 997 (list 'calcFunc-cosh (math-neg (nth 1 math-simplify-expr))))
843 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arcsinh) 998 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
844 math-living-dangerously 999 math-living-dangerously
845 (list 'calcFunc-sqrt (math-add (math-sqr (nth 1 (nth 1 expr))) 1))) 1000 (list 'calcFunc-sqrt
846 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arctanh) 1001 (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1)))
1002 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
847 math-living-dangerously 1003 math-living-dangerously
848 (math-div 1 1004 (math-div 1
849 (list 'calcFunc-sqrt 1005 (list 'calcFunc-sqrt
850 (math-sub 1 (math-sqr (nth 1 (nth 1 expr))))))) 1006 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))))
851 (let ((m (math-should-expand-trig (nth 1 expr) t))) 1007 (let ((m (math-should-expand-trig (nth 1 math-simplify-expr) t)))
852 (and m (integerp (car m)) 1008 (and m (integerp (car m))
853 (let ((n (car m)) (a (nth 1 m))) 1009 (let ((n (car m)) (a (nth 1 m)))
854 (if (> n 1) 1010 (if (> n 1)
855 (list '+ 1011 (list '+
856 (list '* (list 'calcFunc-cosh (list '* (1- n) a)) 1012 (list '* (list 'calcFunc-cosh (list '* (1- n) a))
857 (list 'calcFunc-cosh a)) 1013 (list 'calcFunc-cosh a))
858 (list '* (list 'calcFunc-sinh (list '* (1- n) a)) 1014 (list '* (list 'calcFunc-sinh (list '* (1- n) a))
859 (list 'calcFunc-sinh a))))))))) 1015 (list 'calcFunc-sinh a)))))))))
860 1016
861 (math-defsimplify calcFunc-tanh 1017 (math-defsimplify calcFunc-tanh
862 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-arctanh) 1018 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
863 (nth 1 (nth 1 expr))) 1019 (nth 1 (nth 1 math-simplify-expr)))
864 (and (math-looks-negp (nth 1 expr)) 1020 (and (math-looks-negp (nth 1 math-simplify-expr))
865 (math-neg (list 'calcFunc-tanh (math-neg (nth 1 expr))))) 1021 (math-neg (list 'calcFunc-tanh (math-neg (nth 1 math-simplify-expr)))))
866 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arcsinh) 1022 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
867 math-living-dangerously 1023 math-living-dangerously
868 (math-div (nth 1 (nth 1 expr)) 1024 (math-div (nth 1 (nth 1 math-simplify-expr))
869 (list 'calcFunc-sqrt 1025 (list 'calcFunc-sqrt
870 (math-add (math-sqr (nth 1 (nth 1 expr))) 1)))) 1026 (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
871 (and (eq (car-safe (nth 1 expr)) 'calcFunc-arccosh) 1027 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
872 math-living-dangerously 1028 math-living-dangerously
873 (math-div (list 'calcFunc-sqrt 1029 (math-div (list 'calcFunc-sqrt
874 (math-sub (math-sqr (nth 1 (nth 1 expr))) 1)) 1030 (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))
875 (nth 1 (nth 1 expr)))) 1031 (nth 1 (nth 1 math-simplify-expr))))
876 (let ((m (math-should-expand-trig (nth 1 expr) t))) 1032 (let ((m (math-should-expand-trig (nth 1 math-simplify-expr) t)))
877 (and m 1033 (and m
878 (if (equal (car m) '(frac 1 2)) 1034 (if (equal (car m) '(frac 1 2))
879 (math-div (math-sub (list 'calcFunc-cosh (nth 1 m)) 1) 1035 (math-div (math-sub (list 'calcFunc-cosh (nth 1 m)) 1)
880 (list 'calcFunc-sinh (nth 1 m))) 1036 (list 'calcFunc-sinh (nth 1 m)))
881 (math-div (list 'calcFunc-sinh (nth 1 expr)) 1037 (math-div (list 'calcFunc-sinh (nth 1 math-simplify-expr))
882 (list 'calcFunc-cosh (nth 1 expr)))))))) 1038 (list 'calcFunc-cosh (nth 1 math-simplify-expr))))))))
1039
1040 (math-defsimplify calcFunc-sech
1041 (or (and (math-looks-negp (nth 1 math-simplify-expr))
1042 (list 'calcFunc-sech (math-neg (nth 1 math-simplify-expr))))
1043 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
1044 math-living-dangerously
1045 (math-div
1046 1
1047 (list 'calcFunc-sqrt
1048 (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
1049 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
1050 math-living-dangerously
1051 (math-div 1 (nth 1 (nth 1 math-simplify-expr))) 1)
1052 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
1053 math-living-dangerously
1054 (list 'calcFunc-sqrt
1055 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr))))))))
1056
1057 (math-defsimplify calcFunc-csch
1058 (or (and (math-looks-negp (nth 1 math-simplify-expr))
1059 (math-neg (list 'calcFunc-csch (math-neg (nth 1 math-simplify-expr)))))
1060 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
1061 math-living-dangerously
1062 (math-div 1 (nth 1 (nth 1 math-simplify-expr))))
1063 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
1064 math-living-dangerously
1065 (math-div
1066 1
1067 (list 'calcFunc-sqrt
1068 (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
1069 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
1070 math-living-dangerously
1071 (math-div (list 'calcFunc-sqrt
1072 (math-sub 1 (math-sqr (nth 1 (nth 1 math-simplify-expr)))))
1073 (nth 1 (nth 1 math-simplify-expr))))))
1074
1075 (math-defsimplify calcFunc-coth
1076 (or (and (math-looks-negp (nth 1 math-simplify-expr))
1077 (math-neg (list 'calcFunc-coth (math-neg (nth 1 math-simplify-expr)))))
1078 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arcsinh)
1079 math-living-dangerously
1080 (math-div (list 'calcFunc-sqrt
1081 (math-add (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))
1082 (nth 1 (nth 1 math-simplify-expr))))
1083 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arccosh)
1084 math-living-dangerously
1085 (math-div (nth 1 (nth 1 math-simplify-expr))
1086 (list 'calcFunc-sqrt
1087 (math-sub (math-sqr (nth 1 (nth 1 math-simplify-expr))) 1))))
1088 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-arctanh)
1089 math-living-dangerously
1090 (math-div 1 (nth 1 (nth 1 math-simplify-expr))))))
883 1091
884 (math-defsimplify calcFunc-arcsin 1092 (math-defsimplify calcFunc-arcsin
885 (or (and (math-looks-negp (nth 1 expr)) 1093 (or (and (math-looks-negp (nth 1 math-simplify-expr))
886 (math-neg (list 'calcFunc-arcsin (math-neg (nth 1 expr))))) 1094 (math-neg (list 'calcFunc-arcsin (math-neg (nth 1 math-simplify-expr)))))
887 (and (eq (nth 1 expr) 1) 1095 (and (eq (nth 1 math-simplify-expr) 1)
888 (math-quarter-circle t)) 1096 (math-quarter-circle t))
889 (and (equal (nth 1 expr) '(frac 1 2)) 1097 (and (equal (nth 1 math-simplify-expr) '(frac 1 2))
890 (math-div (math-half-circle t) 6)) 1098 (math-div (math-half-circle t) 6))
891 (and math-living-dangerously 1099 (and math-living-dangerously
892 (eq (car-safe (nth 1 expr)) 'calcFunc-sin) 1100 (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sin)
893 (nth 1 (nth 1 expr))) 1101 (nth 1 (nth 1 math-simplify-expr)))
894 (and math-living-dangerously 1102 (and math-living-dangerously
895 (eq (car-safe (nth 1 expr)) 'calcFunc-cos) 1103 (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cos)
896 (math-sub (math-quarter-circle t) 1104 (math-sub (math-quarter-circle t)
897 (nth 1 (nth 1 expr)))))) 1105 (nth 1 (nth 1 math-simplify-expr))))))
898 1106
899 (math-defsimplify calcFunc-arccos 1107 (math-defsimplify calcFunc-arccos
900 (or (and (eq (nth 1 expr) 0) 1108 (or (and (eq (nth 1 math-simplify-expr) 0)
901 (math-quarter-circle t)) 1109 (math-quarter-circle t))
902 (and (eq (nth 1 expr) -1) 1110 (and (eq (nth 1 math-simplify-expr) -1)
903 (math-half-circle t)) 1111 (math-half-circle t))
904 (and (equal (nth 1 expr) '(frac 1 2)) 1112 (and (equal (nth 1 math-simplify-expr) '(frac 1 2))
905 (math-div (math-half-circle t) 3)) 1113 (math-div (math-half-circle t) 3))
906 (and (equal (nth 1 expr) '(frac -1 2)) 1114 (and (equal (nth 1 math-simplify-expr) '(frac -1 2))
907 (math-div (math-mul (math-half-circle t) 2) 3)) 1115 (math-div (math-mul (math-half-circle t) 2) 3))
908 (and math-living-dangerously 1116 (and math-living-dangerously
909 (eq (car-safe (nth 1 expr)) 'calcFunc-cos) 1117 (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cos)
910 (nth 1 (nth 1 expr))) 1118 (nth 1 (nth 1 math-simplify-expr)))
911 (and math-living-dangerously 1119 (and math-living-dangerously
912 (eq (car-safe (nth 1 expr)) 'calcFunc-sin) 1120 (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sin)
913 (math-sub (math-quarter-circle t) 1121 (math-sub (math-quarter-circle t)
914 (nth 1 (nth 1 expr)))))) 1122 (nth 1 (nth 1 math-simplify-expr))))))
915 1123
916 (math-defsimplify calcFunc-arctan 1124 (math-defsimplify calcFunc-arctan
917 (or (and (math-looks-negp (nth 1 expr)) 1125 (or (and (math-looks-negp (nth 1 math-simplify-expr))
918 (math-neg (list 'calcFunc-arctan (math-neg (nth 1 expr))))) 1126 (math-neg (list 'calcFunc-arctan (math-neg (nth 1 math-simplify-expr)))))
919 (and (eq (nth 1 expr) 1) 1127 (and (eq (nth 1 math-simplify-expr) 1)
920 (math-div (math-half-circle t) 4)) 1128 (math-div (math-half-circle t) 4))
921 (and math-living-dangerously 1129 (and math-living-dangerously
922 (eq (car-safe (nth 1 expr)) 'calcFunc-tan) 1130 (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-tan)
923 (nth 1 (nth 1 expr))))) 1131 (nth 1 (nth 1 math-simplify-expr)))))
924 1132
925 (math-defsimplify calcFunc-arcsinh 1133 (math-defsimplify calcFunc-arcsinh
926 (or (and (math-looks-negp (nth 1 expr)) 1134 (or (and (math-looks-negp (nth 1 math-simplify-expr))
927 (math-neg (list 'calcFunc-arcsinh (math-neg (nth 1 expr))))) 1135 (math-neg (list 'calcFunc-arcsinh (math-neg (nth 1 math-simplify-expr)))))
928 (and (eq (car-safe (nth 1 expr)) 'calcFunc-sinh) 1136 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sinh)
929 (or math-living-dangerously 1137 (or math-living-dangerously
930 (math-known-realp (nth 1 (nth 1 expr)))) 1138 (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
931 (nth 1 (nth 1 expr))))) 1139 (nth 1 (nth 1 math-simplify-expr)))))
932 1140
933 (math-defsimplify calcFunc-arccosh 1141 (math-defsimplify calcFunc-arccosh
934 (and (eq (car-safe (nth 1 expr)) 'calcFunc-cosh) 1142 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cosh)
935 (or math-living-dangerously 1143 (or math-living-dangerously
936 (math-known-realp (nth 1 (nth 1 expr)))) 1144 (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
937 (nth 1 (nth 1 expr)))) 1145 (nth 1 (nth 1 math-simplify-expr))))
938 1146
939 (math-defsimplify calcFunc-arctanh 1147 (math-defsimplify calcFunc-arctanh
940 (or (and (math-looks-negp (nth 1 expr)) 1148 (or (and (math-looks-negp (nth 1 math-simplify-expr))
941 (math-neg (list 'calcFunc-arctanh (math-neg (nth 1 expr))))) 1149 (math-neg (list 'calcFunc-arctanh (math-neg (nth 1 math-simplify-expr)))))
942 (and (eq (car-safe (nth 1 expr)) 'calcFunc-tanh) 1150 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-tanh)
943 (or math-living-dangerously 1151 (or math-living-dangerously
944 (math-known-realp (nth 1 (nth 1 expr)))) 1152 (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
945 (nth 1 (nth 1 expr))))) 1153 (nth 1 (nth 1 math-simplify-expr)))))
946 1154
947 (math-defsimplify calcFunc-sqrt 1155 (math-defsimplify calcFunc-sqrt
948 (math-simplify-sqrt)) 1156 (math-simplify-sqrt))
949 1157
950 (defun math-simplify-sqrt () 1158 (defun math-simplify-sqrt ()
951 (or (and (eq (car-safe (nth 1 expr)) 'frac) 1159 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'frac)
952 (math-div (list 'calcFunc-sqrt (math-mul (nth 1 (nth 1 expr)) 1160 (math-div (list 'calcFunc-sqrt
953 (nth 2 (nth 1 expr)))) 1161 (math-mul (nth 1 (nth 1 math-simplify-expr))
954 (nth 2 (nth 1 expr)))) 1162 (nth 2 (nth 1 math-simplify-expr))))
955 (let ((fac (if (math-objectp (nth 1 expr)) 1163 (nth 2 (nth 1 math-simplify-expr))))
956 (math-squared-factor (nth 1 expr)) 1164 (let ((fac (if (math-objectp (nth 1 math-simplify-expr))
957 (math-common-constant-factor (nth 1 expr))))) 1165 (math-squared-factor (nth 1 math-simplify-expr))
1166 (math-common-constant-factor (nth 1 math-simplify-expr)))))
958 (and fac (not (eq fac 1)) 1167 (and fac (not (eq fac 1))
959 (math-mul (math-normalize (list 'calcFunc-sqrt fac)) 1168 (math-mul (math-normalize (list 'calcFunc-sqrt fac))
960 (math-normalize 1169 (math-normalize
961 (list 'calcFunc-sqrt 1170 (list 'calcFunc-sqrt
962 (math-cancel-common-factor (nth 1 expr) fac)))))) 1171 (math-cancel-common-factor
1172 (nth 1 math-simplify-expr) fac))))))
963 (and math-living-dangerously 1173 (and math-living-dangerously
964 (or (and (eq (car-safe (nth 1 expr)) '-) 1174 (or (and (eq (car-safe (nth 1 math-simplify-expr)) '-)
965 (math-equal-int (nth 1 (nth 1 expr)) 1) 1175 (math-equal-int (nth 1 (nth 1 math-simplify-expr)) 1)
966 (eq (car-safe (nth 2 (nth 1 expr))) '^) 1176 (eq (car-safe (nth 2 (nth 1 math-simplify-expr))) '^)
967 (math-equal-int (nth 2 (nth 2 (nth 1 expr))) 2) 1177 (math-equal-int (nth 2 (nth 2 (nth 1 math-simplify-expr))) 2)
968 (or (and (eq (car-safe (nth 1 (nth 2 (nth 1 expr)))) 1178 (or (and (eq (car-safe (nth 1 (nth 2 (nth 1 math-simplify-expr))))
969 'calcFunc-sin) 1179 'calcFunc-sin)
970 (list 'calcFunc-cos 1180 (list 'calcFunc-cos
971 (nth 1 (nth 1 (nth 2 (nth 1 expr)))))) 1181 (nth 1 (nth 1 (nth 2 (nth 1 math-simplify-expr))))))
972 (and (eq (car-safe (nth 1 (nth 2 (nth 1 expr)))) 1182 (and (eq (car-safe (nth 1 (nth 2 (nth 1 math-simplify-expr))))
973 'calcFunc-cos) 1183 'calcFunc-cos)
974 (list 'calcFunc-sin 1184 (list 'calcFunc-sin
975 (nth 1 (nth 1 (nth 2 (nth 1 expr)))))))) 1185 (nth 1 (nth 1 (nth 2
976 (and (eq (car-safe (nth 1 expr)) '-) 1186 (nth 1 math-simplify-expr))))))))
977 (math-equal-int (nth 2 (nth 1 expr)) 1) 1187 (and (eq (car-safe (nth 1 math-simplify-expr)) '-)
978 (eq (car-safe (nth 1 (nth 1 expr))) '^) 1188 (math-equal-int (nth 2 (nth 1 math-simplify-expr)) 1)
979 (math-equal-int (nth 2 (nth 1 (nth 1 expr))) 2) 1189 (eq (car-safe (nth 1 (nth 1 math-simplify-expr))) '^)
980 (and (eq (car-safe (nth 1 (nth 1 (nth 1 expr)))) 1190 (math-equal-int (nth 2 (nth 1 (nth 1 math-simplify-expr))) 2)
1191 (and (eq (car-safe (nth 1 (nth 1 (nth 1 math-simplify-expr))))
981 'calcFunc-cosh) 1192 'calcFunc-cosh)
982 (list 'calcFunc-sinh 1193 (list 'calcFunc-sinh
983 (nth 1 (nth 1 (nth 1 (nth 1 expr))))))) 1194 (nth 1 (nth 1 (nth 1 (nth 1 math-simplify-expr)))))))
984 (and (eq (car-safe (nth 1 expr)) '+) 1195 (and (eq (car-safe (nth 1 math-simplify-expr)) '+)
985 (let ((a (nth 1 (nth 1 expr))) 1196 (let ((a (nth 1 (nth 1 math-simplify-expr)))
986 (b (nth 2 (nth 1 expr)))) 1197 (b (nth 2 (nth 1 math-simplify-expr))))
987 (and (or (and (math-equal-int a 1) 1198 (and (or (and (math-equal-int a 1)
988 (setq a b b (nth 1 (nth 1 expr)))) 1199 (setq a b b (nth 1 (nth 1 math-simplify-expr))))
989 (math-equal-int b 1)) 1200 (math-equal-int b 1))
990 (eq (car-safe a) '^) 1201 (eq (car-safe a) '^)
991 (math-equal-int (nth 2 a) 2) 1202 (math-equal-int (nth 2 a) 2)
992 (or (and (eq (car-safe (nth 1 a)) 'calcFunc-sinh) 1203 (or (and (eq (car-safe (nth 1 a)) 'calcFunc-sinh)
993 (list 'calcFunc-cosh (nth 1 (nth 1 a)))) 1204 (list 'calcFunc-cosh (nth 1 (nth 1 a))))
1205 (and (eq (car-safe (nth 1 a)) 'calcFunc-csch)
1206 (list 'calcFunc-coth (nth 1 (nth 1 a))))
994 (and (eq (car-safe (nth 1 a)) 'calcFunc-tan) 1207 (and (eq (car-safe (nth 1 a)) 'calcFunc-tan)
995 (list '/ 1 (list 'calcFunc-cos 1208 (list '/ 1 (list 'calcFunc-cos
1209 (nth 1 (nth 1 a)))))
1210 (and (eq (car-safe (nth 1 a)) 'calcFunc-cot)
1211 (list '/ 1 (list 'calcFunc-sin
996 (nth 1 (nth 1 a))))))))) 1212 (nth 1 (nth 1 a)))))))))
997 (and (eq (car-safe (nth 1 expr)) '^) 1213 (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
998 (list '^ 1214 (list '^
999 (nth 1 (nth 1 expr)) 1215 (nth 1 (nth 1 math-simplify-expr))
1000 (math-div (nth 2 (nth 1 expr)) 2))) 1216 (math-div (nth 2 (nth 1 math-simplify-expr)) 2)))
1001 (and (eq (car-safe (nth 1 expr)) 'calcFunc-sqrt) 1217 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sqrt)
1002 (list '^ (nth 1 (nth 1 expr)) (math-div 1 4))) 1218 (list '^ (nth 1 (nth 1 math-simplify-expr)) (math-div 1 4)))
1003 (and (memq (car-safe (nth 1 expr)) '(* /)) 1219 (and (memq (car-safe (nth 1 math-simplify-expr)) '(* /))
1004 (list (car (nth 1 expr)) 1220 (list (car (nth 1 math-simplify-expr))
1005 (list 'calcFunc-sqrt (nth 1 (nth 1 expr))) 1221 (list 'calcFunc-sqrt (nth 1 (nth 1 math-simplify-expr)))
1006 (list 'calcFunc-sqrt (nth 2 (nth 1 expr))))) 1222 (list 'calcFunc-sqrt (nth 2 (nth 1 math-simplify-expr)))))
1007 (and (memq (car-safe (nth 1 expr)) '(+ -)) 1223 (and (memq (car-safe (nth 1 math-simplify-expr)) '(+ -))
1008 (not (math-any-floats (nth 1 expr))) 1224 (not (math-any-floats (nth 1 math-simplify-expr)))
1009 (let ((f (calcFunc-factors (calcFunc-expand 1225 (let ((f (calcFunc-factors (calcFunc-expand
1010 (nth 1 expr))))) 1226 (nth 1 math-simplify-expr)))))
1011 (and (math-vectorp f) 1227 (and (math-vectorp f)
1012 (or (> (length f) 2) 1228 (or (> (length f) 2)
1013 (> (nth 2 (nth 1 f)) 1)) 1229 (> (nth 2 (nth 1 f)) 1))
1014 (let ((out 1) (rest 1) (sums 1) fac pow) 1230 (let ((out 1) (rest 1) (sums 1) fac pow)
1015 (while (setq f (cdr f)) 1231 (while (setq f (cdr f))
1041 fac (math-mul fac (car prsqr))) 1257 fac (math-mul fac (car prsqr)))
1042 (setq prsqr (cdr prsqr)))) 1258 (setq prsqr (cdr prsqr))))
1043 fac))) 1259 fac)))
1044 1260
1045 (math-defsimplify calcFunc-exp 1261 (math-defsimplify calcFunc-exp
1046 (math-simplify-exp (nth 1 expr))) 1262 (math-simplify-exp (nth 1 math-simplify-expr)))
1047 1263
1048 (defun math-simplify-exp (x) 1264 (defun math-simplify-exp (x)
1049 (or (and (eq (car-safe x) 'calcFunc-ln) 1265 (or (and (eq (car-safe x) 'calcFunc-ln)
1050 (nth 1 x)) 1266 (nth 1 x))
1051 (and math-living-dangerously 1267 (and math-living-dangerously
1072 (setq s (math-known-sin (car n) (nth 1 n) 120 0)) 1288 (setq s (math-known-sin (car n) (nth 1 n) 120 0))
1073 (setq c (math-known-sin (car n) (nth 1 n) 120 300)) 1289 (setq c (math-known-sin (car n) (nth 1 n) 120 300))
1074 (list '+ c (list '* s '(var i var-i)))))))) 1290 (list '+ c (list '* s '(var i var-i))))))))
1075 1291
1076 (math-defsimplify calcFunc-ln 1292 (math-defsimplify calcFunc-ln
1077 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-exp) 1293 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-exp)
1078 (or math-living-dangerously 1294 (or math-living-dangerously
1079 (math-known-realp (nth 1 (nth 1 expr)))) 1295 (math-known-realp (nth 1 (nth 1 math-simplify-expr))))
1080 (nth 1 (nth 1 expr))) 1296 (nth 1 (nth 1 math-simplify-expr)))
1081 (and (eq (car-safe (nth 1 expr)) '^) 1297 (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
1082 (equal (nth 1 (nth 1 expr)) '(var e var-e)) 1298 (equal (nth 1 (nth 1 math-simplify-expr)) '(var e var-e))
1083 (or math-living-dangerously 1299 (or math-living-dangerously
1084 (math-known-realp (nth 2 (nth 1 expr)))) 1300 (math-known-realp (nth 2 (nth 1 math-simplify-expr))))
1085 (nth 2 (nth 1 expr))) 1301 (nth 2 (nth 1 math-simplify-expr)))
1086 (and calc-symbolic-mode 1302 (and calc-symbolic-mode
1087 (math-known-negp (nth 1 expr)) 1303 (math-known-negp (nth 1 math-simplify-expr))
1088 (math-add (list 'calcFunc-ln (math-neg (nth 1 expr))) 1304 (math-add (list 'calcFunc-ln (math-neg (nth 1 math-simplify-expr)))
1089 '(* (var pi var-pi) (var i var-i)))) 1305 '(* (var pi var-pi) (var i var-i))))
1090 (and calc-symbolic-mode 1306 (and calc-symbolic-mode
1091 (math-known-imagp (nth 1 expr)) 1307 (math-known-imagp (nth 1 math-simplify-expr))
1092 (let* ((ip (calcFunc-im (nth 1 expr))) 1308 (let* ((ip (calcFunc-im (nth 1 math-simplify-expr)))
1093 (ips (math-possible-signs ip))) 1309 (ips (math-possible-signs ip)))
1094 (or (and (memq ips '(4 6)) 1310 (or (and (memq ips '(4 6))
1095 (math-add (list 'calcFunc-ln ip) 1311 (math-add (list 'calcFunc-ln ip)
1096 '(/ (* (var pi var-pi) (var i var-i)) 2))) 1312 '(/ (* (var pi var-pi) (var i var-i)) 2)))
1097 (and (memq ips '(1 3)) 1313 (and (memq ips '(1 3))
1101 (math-defsimplify ^ 1317 (math-defsimplify ^
1102 (math-simplify-pow)) 1318 (math-simplify-pow))
1103 1319
1104 (defun math-simplify-pow () 1320 (defun math-simplify-pow ()
1105 (or (and math-living-dangerously 1321 (or (and math-living-dangerously
1106 (or (and (eq (car-safe (nth 1 expr)) '^) 1322 (or (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
1107 (list '^ 1323 (list '^
1108 (nth 1 (nth 1 expr)) 1324 (nth 1 (nth 1 math-simplify-expr))
1109 (math-mul (nth 2 expr) (nth 2 (nth 1 expr))))) 1325 (math-mul (nth 2 math-simplify-expr)
1110 (and (eq (car-safe (nth 1 expr)) 'calcFunc-sqrt) 1326 (nth 2 (nth 1 math-simplify-expr)))))
1327 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-sqrt)
1111 (list '^ 1328 (list '^
1112 (nth 1 (nth 1 expr)) 1329 (nth 1 (nth 1 math-simplify-expr))
1113 (math-div (nth 2 expr) 2))) 1330 (math-div (nth 2 math-simplify-expr) 2)))
1114 (and (memq (car-safe (nth 1 expr)) '(* /)) 1331 (and (memq (car-safe (nth 1 math-simplify-expr)) '(* /))
1115 (list (car (nth 1 expr)) 1332 (list (car (nth 1 math-simplify-expr))
1116 (list '^ (nth 1 (nth 1 expr)) (nth 2 expr)) 1333 (list '^ (nth 1 (nth 1 math-simplify-expr))
1117 (list '^ (nth 2 (nth 1 expr)) (nth 2 expr)))))) 1334 (nth 2 math-simplify-expr))
1118 (and (math-equal-int (nth 1 expr) 10) 1335 (list '^ (nth 2 (nth 1 math-simplify-expr))
1119 (eq (car-safe (nth 2 expr)) 'calcFunc-log10) 1336 (nth 2 math-simplify-expr))))))
1120 (nth 1 (nth 2 expr))) 1337 (and (math-equal-int (nth 1 math-simplify-expr) 10)
1121 (and (equal (nth 1 expr) '(var e var-e)) 1338 (eq (car-safe (nth 2 math-simplify-expr)) 'calcFunc-log10)
1122 (math-simplify-exp (nth 2 expr))) 1339 (nth 1 (nth 2 math-simplify-expr)))
1123 (and (eq (car-safe (nth 1 expr)) 'calcFunc-exp) 1340 (and (equal (nth 1 math-simplify-expr) '(var e var-e))
1341 (math-simplify-exp (nth 2 math-simplify-expr)))
1342 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-exp)
1124 (not math-integrating) 1343 (not math-integrating)
1125 (list 'calcFunc-exp (math-mul (nth 1 (nth 1 expr)) (nth 2 expr)))) 1344 (list 'calcFunc-exp (math-mul (nth 1 (nth 1 math-simplify-expr))
1126 (and (equal (nth 1 expr) '(var i var-i)) 1345 (nth 2 math-simplify-expr))))
1346 (and (equal (nth 1 math-simplify-expr) '(var i var-i))
1127 (math-imaginary-i) 1347 (math-imaginary-i)
1128 (math-num-integerp (nth 2 expr)) 1348 (math-num-integerp (nth 2 math-simplify-expr))
1129 (let ((x (math-mod (math-trunc (nth 2 expr)) 4))) 1349 (let ((x (math-mod (math-trunc (nth 2 math-simplify-expr)) 4)))
1130 (cond ((eq x 0) 1) 1350 (cond ((eq x 0) 1)
1131 ((eq x 1) (nth 1 expr)) 1351 ((eq x 1) (nth 1 math-simplify-expr))
1132 ((eq x 2) -1) 1352 ((eq x 2) -1)
1133 ((eq x 3) (math-neg (nth 1 expr)))))) 1353 ((eq x 3) (math-neg (nth 1 math-simplify-expr))))))
1134 (and math-integrating 1354 (and math-integrating
1135 (integerp (nth 2 expr)) 1355 (integerp (nth 2 math-simplify-expr))
1136 (>= (nth 2 expr) 2) 1356 (>= (nth 2 math-simplify-expr) 2)
1137 (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-cos) 1357 (or (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cos)
1138 (math-mul (math-pow (nth 1 expr) (- (nth 2 expr) 2)) 1358 (math-mul (math-pow (nth 1 math-simplify-expr)
1359 (- (nth 2 math-simplify-expr) 2))
1139 (math-sub 1 1360 (math-sub 1
1140 (math-sqr 1361 (math-sqr
1141 (list 'calcFunc-sin 1362 (list 'calcFunc-sin
1142 (nth 1 (nth 1 expr))))))) 1363 (nth 1 (nth 1 math-simplify-expr)))))))
1143 (and (eq (car-safe (nth 1 expr)) 'calcFunc-cosh) 1364 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-cosh)
1144 (math-mul (math-pow (nth 1 expr) (- (nth 2 expr) 2)) 1365 (math-mul (math-pow (nth 1 math-simplify-expr)
1366 (- (nth 2 math-simplify-expr) 2))
1145 (math-add 1 1367 (math-add 1
1146 (math-sqr 1368 (math-sqr
1147 (list 'calcFunc-sinh 1369 (list 'calcFunc-sinh
1148 (nth 1 (nth 1 expr))))))))) 1370 (nth 1 (nth 1 math-simplify-expr)))))))))
1149 (and (eq (car-safe (nth 2 expr)) 'frac) 1371 (and (eq (car-safe (nth 2 math-simplify-expr)) 'frac)
1150 (Math-ratp (nth 1 expr)) 1372 (Math-ratp (nth 1 math-simplify-expr))
1151 (Math-posp (nth 1 expr)) 1373 (Math-posp (nth 1 math-simplify-expr))
1152 (if (equal (nth 2 expr) '(frac 1 2)) 1374 (if (equal (nth 2 math-simplify-expr) '(frac 1 2))
1153 (list 'calcFunc-sqrt (nth 1 expr)) 1375 (list 'calcFunc-sqrt (nth 1 math-simplify-expr))
1154 (let ((flr (math-floor (nth 2 expr)))) 1376 (let ((flr (math-floor (nth 2 math-simplify-expr))))
1155 (and (not (Math-zerop flr)) 1377 (and (not (Math-zerop flr))
1156 (list '* (list '^ (nth 1 expr) flr) 1378 (list '* (list '^ (nth 1 math-simplify-expr) flr)
1157 (list '^ (nth 1 expr) 1379 (list '^ (nth 1 math-simplify-expr)
1158 (math-sub (nth 2 expr) flr))))))) 1380 (math-sub (nth 2 math-simplify-expr) flr)))))))
1159 (and (eq (math-quarter-integer (nth 2 expr)) 2) 1381 (and (eq (math-quarter-integer (nth 2 math-simplify-expr)) 2)
1160 (let ((temp (math-simplify-sqrt))) 1382 (let ((temp (math-simplify-sqrt)))
1161 (and temp 1383 (and temp
1162 (list '^ temp (math-mul (nth 2 expr) 2))))))) 1384 (list '^ temp (math-mul (nth 2 math-simplify-expr) 2)))))))
1163 1385
1164 (math-defsimplify calcFunc-log10 1386 (math-defsimplify calcFunc-log10
1165 (and (eq (car-safe (nth 1 expr)) '^) 1387 (and (eq (car-safe (nth 1 math-simplify-expr)) '^)
1166 (math-equal-int (nth 1 (nth 1 expr)) 10) 1388 (math-equal-int (nth 1 (nth 1 math-simplify-expr)) 10)
1167 (or math-living-dangerously 1389 (or math-living-dangerously
1168 (math-known-realp (nth 2 (nth 1 expr)))) 1390 (math-known-realp (nth 2 (nth 1 math-simplify-expr))))
1169 (nth 2 (nth 1 expr)))) 1391 (nth 2 (nth 1 math-simplify-expr))))
1170 1392
1171 1393
1172 (math-defsimplify calcFunc-erf 1394 (math-defsimplify calcFunc-erf
1173 (or (and (math-looks-negp (nth 1 expr)) 1395 (or (and (math-looks-negp (nth 1 math-simplify-expr))
1174 (math-neg (list 'calcFunc-erf (math-neg (nth 1 expr))))) 1396 (math-neg (list 'calcFunc-erf (math-neg (nth 1 math-simplify-expr)))))
1175 (and (eq (car-safe (nth 1 expr)) 'calcFunc-conj) 1397 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-conj)
1176 (list 'calcFunc-conj (list 'calcFunc-erf (nth 1 (nth 1 expr))))))) 1398 (list 'calcFunc-conj
1399 (list 'calcFunc-erf (nth 1 (nth 1 math-simplify-expr)))))))
1177 1400
1178 (math-defsimplify calcFunc-erfc 1401 (math-defsimplify calcFunc-erfc
1179 (or (and (math-looks-negp (nth 1 expr)) 1402 (or (and (math-looks-negp (nth 1 math-simplify-expr))
1180 (math-sub 2 (list 'calcFunc-erfc (math-neg (nth 1 expr))))) 1403 (math-sub 2 (list 'calcFunc-erfc (math-neg (nth 1 math-simplify-expr)))))
1181 (and (eq (car-safe (nth 1 expr)) 'calcFunc-conj) 1404 (and (eq (car-safe (nth 1 math-simplify-expr)) 'calcFunc-conj)
1182 (list 'calcFunc-conj (list 'calcFunc-erfc (nth 1 (nth 1 expr))))))) 1405 (list 'calcFunc-conj
1406 (list 'calcFunc-erfc (nth 1 (nth 1 math-simplify-expr)))))))
1183 1407
1184 1408
1185 (defun math-linear-in (expr term &optional always) 1409 (defun math-linear-in (expr term &optional always)
1186 (if (math-expr-contains expr term) 1410 (if (math-expr-contains expr term)
1187 (let* ((calc-prefer-frac t) 1411 (let* ((calc-prefer-frac t)
1323 (while (and (setq thing (cdr thing)) 1547 (while (and (setq thing (cdr thing))
1324 (not (math-expr-depends expr (car thing))))) 1548 (not (math-expr-depends expr (car thing)))))
1325 thing)) 1549 thing))
1326 1550
1327 ;;; Substitute all occurrences of old for new in expr (non-destructive). 1551 ;;; Substitute all occurrences of old for new in expr (non-destructive).
1328 (defun math-expr-subst (expr old new) 1552
1553 ;; The variables math-expr-subst-old and math-expr-subst-new are local
1554 ;; for math-expr-subst, but used by math-expr-subst-rec.
1555 (defvar math-expr-subst-old)
1556 (defvar math-expr-subst-new)
1557
1558 (defun math-expr-subst (expr math-expr-subst-old math-expr-subst-new)
1329 (math-expr-subst-rec expr)) 1559 (math-expr-subst-rec expr))
1330 1560
1331 (defalias 'calcFunc-subst 'math-expr-subst) 1561 (defalias 'calcFunc-subst 'math-expr-subst)
1332 1562
1333 (defun math-expr-subst-rec (expr) 1563 (defun math-expr-subst-rec (expr)
1334 (cond ((equal expr old) new) 1564 (cond ((equal expr math-expr-subst-old) math-expr-subst-new)
1335 ((Math-primp expr) expr) 1565 ((Math-primp expr) expr)
1336 ((memq (car expr) '(calcFunc-deriv 1566 ((memq (car expr) '(calcFunc-deriv
1337 calcFunc-tderiv)) 1567 calcFunc-tderiv))
1338 (if (= (length expr) 2) 1568 (if (= (length expr) 2)
1339 (if (equal (nth 1 expr) old) 1569 (if (equal (nth 1 expr) math-expr-subst-old)
1340 (append expr (list new)) 1570 (append expr (list math-expr-subst-new))
1341 expr) 1571 expr)
1342 (list (car expr) (nth 1 expr) 1572 (list (car expr) (nth 1 expr)
1343 (math-expr-subst-rec (nth 2 expr))))) 1573 (math-expr-subst-rec (nth 2 expr)))))
1344 (t 1574 (t
1345 (cons (car expr) 1575 (cons (car expr)
1373 (math-normalize ; fix selection bug 1603 (math-normalize ; fix selection bug
1374 (math-build-polynomial-expr p base)) 1604 (math-build-polynomial-expr p base))
1375 expr))) 1605 expr)))
1376 1606
1377 ;;; If expr is of the form "a + bx + cx^2 + ...", return the list (a b c ...), 1607 ;;; If expr is of the form "a + bx + cx^2 + ...", return the list (a b c ...),
1378 ;;; else return nil if not in polynomial form. If "loose", coefficients 1608 ;;; else return nil if not in polynomial form. If "loose" (math-is-poly-loose),
1379 ;;; may contain x, e.g., sin(x) + cos(x) x^2 is a loose polynomial in x. 1609 ;;; coefficients may contain x, e.g., sin(x) + cos(x) x^2 is a loose polynomial in x.
1380 (defun math-is-polynomial (expr var &optional degree loose) 1610
1381 (let* ((math-poly-base-variable (if loose 1611 ;; The variables math-is-poly-degree and math-is-poly-loose are local to
1382 (if (eq loose 'gen) var '(var XXX XXX)) 1612 ;; math-is-polynomial, but are used by math-is-poly-rec
1613 (defvar math-is-poly-degree)
1614 (defvar math-is-poly-loose)
1615
1616 (defun math-is-polynomial (expr var &optional math-is-poly-degree math-is-poly-loose)
1617 (let* ((math-poly-base-variable (if math-is-poly-loose
1618 (if (eq math-is-poly-loose 'gen) var '(var XXX XXX))
1383 math-poly-base-variable)) 1619 math-poly-base-variable))
1384 (poly (math-is-poly-rec expr math-poly-neg-powers))) 1620 (poly (math-is-poly-rec expr math-poly-neg-powers)))
1385 (and (or (null degree) 1621 (and (or (null math-is-poly-degree)
1386 (<= (length poly) (1+ degree))) 1622 (<= (length poly) (1+ math-is-poly-degree)))
1387 poly))) 1623 poly)))
1388 1624
1389 (defun math-is-poly-rec (expr negpow) 1625 (defun math-is-poly-rec (expr negpow)
1390 (math-poly-simplify 1626 (math-poly-simplify
1391 (or (cond ((or (equal expr var) 1627 (or (cond ((or (equal expr var)
1429 (list 0 1) 1665 (list 0 1)
1430 (math-is-poly-rec expr nil))) 1666 (math-is-poly-rec expr nil)))
1431 (n pow) 1667 (n pow)
1432 (accum (list 1))) 1668 (accum (list 1)))
1433 (and p1 1669 (and p1
1434 (or (null degree) 1670 (or (null math-is-poly-degree)
1435 (<= (* (1- (length p1)) n) degree)) 1671 (<= (* (1- (length p1)) n) math-is-poly-degree))
1436 (progn 1672 (progn
1437 (while (>= n 1) 1673 (while (>= n 1)
1438 (setq accum (math-poly-mul accum p1) 1674 (setq accum (math-poly-mul accum p1)
1439 n (1- n))) 1675 n (1- n)))
1440 accum))) 1676 accum)))
1458 ((eq (car expr) '*) 1694 ((eq (car expr) '*)
1459 (let ((p1 (math-is-poly-rec (nth 1 expr) negpow))) 1695 (let ((p1 (math-is-poly-rec (nth 1 expr) negpow)))
1460 (and p1 1696 (and p1
1461 (let ((p2 (math-is-poly-rec (nth 2 expr) negpow))) 1697 (let ((p2 (math-is-poly-rec (nth 2 expr) negpow)))
1462 (and p2 1698 (and p2
1463 (or (null degree) 1699 (or (null math-is-poly-degree)
1464 (<= (- (+ (length p1) (length p2)) 2) degree)) 1700 (<= (- (+ (length p1) (length p2)) 2)
1701 math-is-poly-degree))
1465 (math-poly-mul p1 p2)))))) 1702 (math-poly-mul p1 p2))))))
1466 ((eq (car expr) '/) 1703 ((eq (car expr) '/)
1467 (and (or (not (math-poly-depends (nth 2 expr) var)) 1704 (and (or (not (math-poly-depends (nth 2 expr) var))
1468 (and negpow 1705 (and negpow
1469 (math-is-poly-rec (nth 2 expr) nil) 1706 (math-is-poly-rec (nth 2 expr) nil)
1479 ((and (eq (car expr) 'calcFunc-sqrt) 1716 ((and (eq (car expr) 'calcFunc-sqrt)
1480 math-poly-frac-powers) 1717 math-poly-frac-powers)
1481 (math-is-poly-rec (list '^ (nth 1 expr) '(frac 1 2)) negpow)) 1718 (math-is-poly-rec (list '^ (nth 1 expr) '(frac 1 2)) negpow))
1482 (t nil)) 1719 (t nil))
1483 (and (or (not (math-poly-depends expr var)) 1720 (and (or (not (math-poly-depends expr var))
1484 loose) 1721 math-is-poly-loose)
1485 (not (eq (car expr) 'vec)) 1722 (not (eq (car expr) 'vec))
1486 (list expr))))) 1723 (list expr)))))
1487 1724
1488 ;;; Check if expr is a polynomial in var; if so, return its degree. 1725 ;;; Check if expr is a polynomial in var; if so, return its degree.
1489 (defun math-polynomial-p (expr var) 1726 (defun math-polynomial-p (expr var)
1515 (if math-poly-base-variable 1752 (if math-poly-base-variable
1516 (math-expr-contains expr math-poly-base-variable) 1753 (math-expr-contains expr math-poly-base-variable)
1517 (math-expr-depends expr var))) 1754 (math-expr-depends expr var)))
1518 1755
1519 ;;; Find the variable (or sub-expression) which is the base of polynomial expr. 1756 ;;; Find the variable (or sub-expression) which is the base of polynomial expr.
1520 (defun math-polynomial-base (mpb-top-expr &optional mpb-pred) 1757 ;; The variables math-poly-base-const-ok and math-poly-base-pred are
1521 (or mpb-pred 1758 ;; local to math-polynomial-base, but are used by math-polynomial-base-rec.
1522 (setq mpb-pred (function (lambda (base) (math-polynomial-p 1759 (defvar math-poly-base-const-ok)
1523 mpb-top-expr base))))) 1760 (defvar math-poly-base-pred)
1524 (or (let ((const-ok nil)) 1761
1525 (math-polynomial-base-rec mpb-top-expr)) 1762 ;; The variable math-poly-base-top-expr is local to math-polynomial-base,
1526 (let ((const-ok t)) 1763 ;; but is used by math-polynomial-p1 in calc-poly.el, which is called
1527 (math-polynomial-base-rec mpb-top-expr)))) 1764 ;; by math-polynomial-base.
1765
1766 (defun math-polynomial-base (math-poly-base-top-expr &optional math-poly-base-pred)
1767 (or math-poly-base-pred
1768 (setq math-poly-base-pred (function (lambda (base) (math-polynomial-p
1769 math-poly-base-top-expr base)))))
1770 (or (let ((math-poly-base-const-ok nil))
1771 (math-polynomial-base-rec math-poly-base-top-expr))
1772 (let ((math-poly-base-const-ok t))
1773 (math-polynomial-base-rec math-poly-base-top-expr))))
1528 1774
1529 (defun math-polynomial-base-rec (mpb-expr) 1775 (defun math-polynomial-base-rec (mpb-expr)
1530 (and (not (Math-objvecp mpb-expr)) 1776 (and (not (Math-objvecp mpb-expr))
1531 (or (and (memq (car mpb-expr) '(+ - *)) 1777 (or (and (memq (car mpb-expr) '(+ - *))
1532 (or (math-polynomial-base-rec (nth 1 mpb-expr)) 1778 (or (math-polynomial-base-rec (nth 1 mpb-expr))
1535 (math-polynomial-base-rec (nth 1 mpb-expr))) 1781 (math-polynomial-base-rec (nth 1 mpb-expr)))
1536 (and (eq (car mpb-expr) '^) 1782 (and (eq (car mpb-expr) '^)
1537 (math-polynomial-base-rec (nth 1 mpb-expr))) 1783 (math-polynomial-base-rec (nth 1 mpb-expr)))
1538 (and (eq (car mpb-expr) 'calcFunc-exp) 1784 (and (eq (car mpb-expr) 'calcFunc-exp)
1539 (math-polynomial-base-rec '(var e var-e))) 1785 (math-polynomial-base-rec '(var e var-e)))
1540 (and (or const-ok (math-expr-contains-vars mpb-expr)) 1786 (and (or math-poly-base-const-ok (math-expr-contains-vars mpb-expr))
1541 (funcall mpb-pred mpb-expr) 1787 (funcall math-poly-base-pred mpb-expr)
1542 mpb-expr)))) 1788 mpb-expr))))
1543 1789
1544 ;;; Return non-nil if expr refers to any variables. 1790 ;;; Return non-nil if expr refers to any variables.
1545 (defun math-expr-contains-vars (expr) 1791 (defun math-expr-contains-vars (expr)
1546 (or (eq (car-safe expr) 'var) 1792 (or (eq (car-safe expr) 'var)
1616 (< (nth 1 f) 1000) 1862 (< (nth 1 f) 1000)
1617 (math-make-frac (nth 1 f) 1863 (math-make-frac (nth 1 f)
1618 (math-scale-int 1 (- (nth 2 f))))))) 1864 (math-scale-int 1 (- (nth 2 f)))))))
1619 f)) 1865 f))
1620 1866
1867 (provide 'calc-alg)
1868
1869 ;;; arch-tag: 52e7dcdf-9688-464d-a02b-4bbe789348d0
1621 ;;; calc-alg.el ends here 1870 ;;; calc-alg.el ends here