1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070 |
- ;;; calc-arith.el --- arithmetic functions for Calc
- ;; Copyright (C) 1990-1993, 2001-2012 Free Software Foundation, Inc.
- ;; Author: David Gillespie <daveg@synaptics.com>
- ;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
- ;; This file is part of GNU Emacs.
- ;; GNU Emacs is free software: you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation, either version 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;;; Code:
- ;; This file is autoloaded from calc-ext.el.
- (require 'calc-ext)
- (require 'calc-macs)
- ;;; The following lists are not exhaustive.
- (defvar math-scalar-functions '(calcFunc-det
- calcFunc-cnorm calcFunc-rnorm
- calcFunc-vlen calcFunc-vcount
- calcFunc-vsum calcFunc-vprod
- calcFunc-vmin calcFunc-vmax))
- (defvar math-nonscalar-functions '(vec calcFunc-idn calcFunc-diag
- calcFunc-cvec calcFunc-index
- calcFunc-trn
- | calcFunc-append
- calcFunc-cons calcFunc-rcons
- calcFunc-tail calcFunc-rhead))
- (defvar math-scalar-if-args-functions '(+ - * / neg))
- (defvar math-real-functions '(calcFunc-arg
- calcFunc-re calcFunc-im
- calcFunc-floor calcFunc-ceil
- calcFunc-trunc calcFunc-round
- calcFunc-rounde calcFunc-roundu
- calcFunc-ffloor calcFunc-fceil
- calcFunc-ftrunc calcFunc-fround
- calcFunc-frounde calcFunc-froundu))
- (defvar math-positive-functions '())
- (defvar math-nonnegative-functions '(calcFunc-cnorm calcFunc-rnorm
- calcFunc-vlen calcFunc-vcount))
- (defvar math-real-scalar-functions '(% calcFunc-idiv calcFunc-abs
- calcFunc-choose calcFunc-perm
- calcFunc-eq calcFunc-neq
- calcFunc-lt calcFunc-gt
- calcFunc-leq calcFunc-geq
- calcFunc-lnot
- calcFunc-max calcFunc-min))
- (defvar math-real-if-arg-functions '(calcFunc-sin calcFunc-cos
- calcFunc-tan calcFunc-sec
- calcFunc-csc calcFunc-cot
- calcFunc-arctan
- calcFunc-sinh calcFunc-cosh
- calcFunc-tanh calcFunc-sech
- calcFunc-csch calcFunc-coth
- calcFunc-exp
- calcFunc-gamma calcFunc-fact))
- (defvar math-integer-functions '(calcFunc-idiv
- calcFunc-isqrt calcFunc-ilog
- calcFunc-vlen calcFunc-vcount))
- (defvar math-num-integer-functions '())
- (defvar math-rounding-functions '(calcFunc-floor
- calcFunc-ceil
- calcFunc-round calcFunc-trunc
- calcFunc-rounde calcFunc-roundu))
- (defvar math-float-rounding-functions '(calcFunc-ffloor
- calcFunc-fceil
- calcFunc-fround calcFunc-ftrunc
- calcFunc-frounde calcFunc-froundu))
- (defvar math-integer-if-args-functions '(+ - * % neg calcFunc-abs
- calcFunc-min calcFunc-max
- calcFunc-choose calcFunc-perm))
- ;;; Arithmetic.
- (defun calc-min (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-binary-op "min" 'calcFunc-min arg '(var inf var-inf))))
- (defun calc-max (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-binary-op "max" 'calcFunc-max arg '(neg (var inf var-inf)))))
- (defun calc-abs (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-unary-op "abs" 'calcFunc-abs arg)))
- (defun calc-idiv (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-binary-op "\\" 'calcFunc-idiv arg 1)))
- (defun calc-floor (arg)
- (interactive "P")
- (calc-slow-wrapper
- (if (calc-is-inverse)
- (if (calc-is-hyperbolic)
- (calc-unary-op "ceil" 'calcFunc-fceil arg)
- (calc-unary-op "ceil" 'calcFunc-ceil arg))
- (if (calc-is-hyperbolic)
- (calc-unary-op "flor" 'calcFunc-ffloor arg)
- (calc-unary-op "flor" 'calcFunc-floor arg)))))
- (defun calc-ceiling (arg)
- (interactive "P")
- (calc-invert-func)
- (calc-floor arg))
- (defun calc-round (arg)
- (interactive "P")
- (calc-slow-wrapper
- (if (calc-is-inverse)
- (if (calc-is-hyperbolic)
- (calc-unary-op "trnc" 'calcFunc-ftrunc arg)
- (calc-unary-op "trnc" 'calcFunc-trunc arg))
- (if (calc-is-hyperbolic)
- (calc-unary-op "rond" 'calcFunc-fround arg)
- (calc-unary-op "rond" 'calcFunc-round arg)))))
- (defun calc-trunc (arg)
- (interactive "P")
- (calc-invert-func)
- (calc-round arg))
- (defun calc-mant-part (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-unary-op "mant" 'calcFunc-mant arg)))
- (defun calc-xpon-part (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-unary-op "xpon" 'calcFunc-xpon arg)))
- (defun calc-scale-float (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-binary-op "scal" 'calcFunc-scf arg)))
- (defun calc-abssqr (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-unary-op "absq" 'calcFunc-abssqr arg)))
- (defun calc-sign (arg)
- (interactive "P")
- (calc-slow-wrapper
- (calc-unary-op "sign" 'calcFunc-sign arg)))
- (defun calc-increment (arg)
- (interactive "p")
- (calc-wrapper
- (calc-enter-result 1 "incr" (list 'calcFunc-incr (calc-top-n 1) arg))))
- (defun calc-decrement (arg)
- (interactive "p")
- (calc-wrapper
- (calc-enter-result 1 "decr" (list 'calcFunc-decr (calc-top-n 1) arg))))
- (defun math-abs-approx (a)
- (cond ((Math-negp a)
- (math-neg a))
- ((Math-anglep a)
- a)
- ((eq (car a) 'cplx)
- (math-add (math-abs (nth 1 a)) (math-abs (nth 2 a))))
- ((eq (car a) 'polar)
- (nth 1 a))
- ((eq (car a) 'sdev)
- (math-abs-approx (nth 1 a)))
- ((eq (car a) 'intv)
- (math-max (math-abs (nth 2 a)) (math-abs (nth 3 a))))
- ((eq (car a) 'date)
- a)
- ((eq (car a) 'vec)
- (math-reduce-vec 'math-add-abs-approx a))
- ((eq (car a) 'calcFunc-abs)
- (car a))
- (t a)))
- (defun math-add-abs-approx (a b)
- (math-add (math-abs-approx a) (math-abs-approx b)))
- ;;;; Declarations.
- (defvar math-decls-cache-tag nil)
- (defvar math-decls-cache nil)
- (defvar math-decls-all nil)
- ;;; Math-decls-cache is an a-list where each entry is a list of the form:
- ;;; (VAR TYPES RANGE)
- ;;; where VAR is a variable name (with var- prefix) or function name;
- ;;; TYPES is a list of type symbols (any, int, frac, ...)
- ;;; RANGE is a sorted vector of intervals describing the range.
- (defvar math-super-types
- '((int numint rat real number)
- (numint real number)
- (frac rat real number)
- (rat real number)
- (float real number)
- (real number)
- (number)
- (scalar)
- (sqmatrix matrix vector)
- (matrix vector)
- (vector)
- (const)))
- (defun math-setup-declarations ()
- (or (eq math-decls-cache-tag (calc-var-value 'var-Decls))
- (let ((p (calc-var-value 'var-Decls))
- vec type range)
- (setq math-decls-cache-tag p
- math-decls-cache nil)
- (and (eq (car-safe p) 'vec)
- (while (setq p (cdr p))
- (and (eq (car-safe (car p)) 'vec)
- (setq vec (nth 2 (car p)))
- (condition-case err
- (let ((v (nth 1 (car p))))
- (setq type nil range nil)
- (or (eq (car-safe vec) 'vec)
- (setq vec (list 'vec vec)))
- (while (and (setq vec (cdr vec))
- (not (Math-objectp (car vec))))
- (and (eq (car-safe (car vec)) 'var)
- (let ((st (assq (nth 1 (car vec))
- math-super-types)))
- (cond (st (setq type (append type st)))
- ((eq (nth 1 (car vec)) 'pos)
- (setq type (append type
- '(real number))
- range
- '(intv 1 0 (var inf var-inf))))
- ((eq (nth 1 (car vec)) 'nonneg)
- (setq type (append type
- '(real number))
- range
- '(intv 3 0
- (var inf var-inf))))))))
- (if vec
- (setq type (append type '(real number))
- range (math-prepare-set (cons 'vec vec))))
- (setq type (list type range))
- (or (eq (car-safe v) 'vec)
- (setq v (list 'vec v)))
- (while (setq v (cdr v))
- (if (or (eq (car-safe (car v)) 'var)
- (not (Math-primp (car v))))
- (setq math-decls-cache
- (cons (cons (if (eq (car (car v)) 'var)
- (nth 2 (car v))
- (car (car v)))
- type)
- math-decls-cache)))))
- (error nil)))))
- (setq math-decls-all (assq 'var-All math-decls-cache)))))
- (defun math-known-scalarp (a &optional assume-scalar)
- (math-setup-declarations)
- (if (if calc-matrix-mode
- (eq calc-matrix-mode 'scalar)
- assume-scalar)
- (not (math-check-known-matrixp a))
- (math-check-known-scalarp a)))
- (defun math-known-matrixp (a)
- (and (not (Math-scalarp a))
- (not (math-known-scalarp a t))))
- (defun math-known-square-matrixp (a)
- (and (math-known-matrixp a)
- (math-check-known-square-matrixp a)))
- ;;; Try to prove that A is a scalar (i.e., a non-vector).
- (defun math-check-known-scalarp (a)
- (cond ((Math-objectp a) t)
- ((memq (car a) math-scalar-functions)
- t)
- ((memq (car a) math-real-scalar-functions)
- t)
- ((memq (car a) math-scalar-if-args-functions)
- (while (and (setq a (cdr a))
- (math-check-known-scalarp (car a))))
- (null a))
- ((eq (car a) '^)
- (math-check-known-scalarp (nth 1 a)))
- ((math-const-var a) t)
- (t
- (let ((decl (if (eq (car a) 'var)
- (or (assq (nth 2 a) math-decls-cache)
- math-decls-all)
- (assq (car a) math-decls-cache)))
- val)
- (cond
- ((memq 'scalar (nth 1 decl))
- t)
- ((and (eq (car a) 'var)
- (symbolp (nth 2 a))
- (boundp (nth 2 a))
- (setq val (symbol-value (nth 2 a))))
- (math-check-known-scalarp val))
- (t
- nil))))))
- ;;; Try to prove that A is *not* a scalar.
- (defun math-check-known-matrixp (a)
- (cond ((Math-objectp a) nil)
- ((memq (car a) math-nonscalar-functions)
- t)
- ((memq (car a) math-scalar-if-args-functions)
- (while (and (setq a (cdr a))
- (not (math-check-known-matrixp (car a)))))
- a)
- ((eq (car a) '^)
- (math-check-known-matrixp (nth 1 a)))
- ((math-const-var a) nil)
- (t
- (let ((decl (if (eq (car a) 'var)
- (or (assq (nth 2 a) math-decls-cache)
- math-decls-all)
- (assq (car a) math-decls-cache)))
- val)
- (cond
- ((memq 'matrix (nth 1 decl))
- t)
- ((and (eq (car a) 'var)
- (symbolp (nth 2 a))
- (boundp (nth 2 a))
- (setq val (symbol-value (nth 2 a))))
- (math-check-known-matrixp val))
- (t
- nil))))))
- ;;; Given that A is a matrix, try to prove that it is a square matrix.
- (defun math-check-known-square-matrixp (a)
- (cond ((math-square-matrixp a)
- t)
- ((eq (car-safe a) '^)
- (math-check-known-square-matrixp (nth 1 a)))
- ((or
- (eq (car-safe a) '*)
- (eq (car-safe a) '+)
- (eq (car-safe a) '-))
- (and
- (math-check-known-square-matrixp (nth 1 a))
- (math-check-known-square-matrixp (nth 2 a))))
- (t
- (let ((decl (if (eq (car a) 'var)
- (or (assq (nth 2 a) math-decls-cache)
- math-decls-all)
- (assq (car a) math-decls-cache)))
- val)
- (cond
- ((memq 'sqmatrix (nth 1 decl))
- t)
- ((and (eq (car a) 'var)
- (boundp (nth 2 a))
- (setq val (symbol-value (nth 2 a))))
- (math-check-known-square-matrixp val))
- ((and (or
- (integerp calc-matrix-mode)
- (eq calc-matrix-mode 'sqmatrix))
- (eq (car-safe a) 'var))
- t)
- ((memq 'matrix (nth 1 decl))
- nil)
- (t
- nil))))))
- ;;; Try to prove that A is a real (i.e., not complex).
- (defun math-known-realp (a)
- (< (math-possible-signs a) 8))
- ;;; Try to prove that A is real and positive.
- (defun math-known-posp (a)
- (eq (math-possible-signs a) 4))
- ;;; Try to prove that A is real and negative.
- (defun math-known-negp (a)
- (eq (math-possible-signs a) 1))
- ;;; Try to prove that A is real and nonnegative.
- (defun math-known-nonnegp (a)
- (memq (math-possible-signs a) '(2 4 6)))
- ;;; Try to prove that A is real and nonpositive.
- (defun math-known-nonposp (a)
- (memq (math-possible-signs a) '(1 2 3)))
- ;;; Try to prove that A is nonzero.
- (defun math-known-nonzerop (a)
- (memq (math-possible-signs a) '(1 4 5 8 9 12 13)))
- ;;; Return true if A is negative, or looks negative but we don't know.
- (defun math-guess-if-neg (a)
- (let ((sgn (math-possible-signs a)))
- (if (memq sgn '(1 3))
- t
- (if (memq sgn '(2 4 6))
- nil
- (math-looks-negp a)))))
- ;;; Find the possible signs of A, assuming A is a number of some kind.
- ;;; Returns an integer with bits: 1 may be negative,
- ;;; 2 may be zero,
- ;;; 4 may be positive,
- ;;; 8 may be nonreal.
- (defun math-possible-signs (a &optional origin)
- (cond ((Math-objectp a)
- (if origin (setq a (math-sub a origin)))
- (cond ((Math-posp a) 4)
- ((Math-negp a) 1)
- ((Math-zerop a) 2)
- ((eq (car a) 'intv)
- (cond
- ((math-known-posp (nth 2 a)) 4)
- ((math-known-negp (nth 3 a)) 1)
- ((Math-zerop (nth 2 a)) 6)
- ((Math-zerop (nth 3 a)) 3)
- (t 7)))
- ((eq (car a) 'sdev)
- (if (math-known-realp (nth 1 a)) 7 15))
- (t 8)))
- ((memq (car a) '(+ -))
- (cond ((Math-realp (nth 1 a))
- (if (eq (car a) '-)
- (math-neg-signs
- (math-possible-signs (nth 2 a)
- (if origin
- (math-add origin (nth 1 a))
- (nth 1 a))))
- (math-possible-signs (nth 2 a)
- (if origin
- (math-sub origin (nth 1 a))
- (math-neg (nth 1 a))))))
- ((Math-realp (nth 2 a))
- (let ((org (if (eq (car a) '-)
- (nth 2 a)
- (math-neg (nth 2 a)))))
- (math-possible-signs (nth 1 a)
- (if origin
- (math-add origin org)
- org))))
- (t
- (let ((s1 (math-possible-signs (nth 1 a) origin))
- (s2 (math-possible-signs (nth 2 a))))
- (if (eq (car a) '-) (setq s2 (math-neg-signs s2)))
- (cond ((eq s1 s2) s1)
- ((eq s1 2) s2)
- ((eq s2 2) s1)
- ((>= s1 8) 15)
- ((>= s2 8) 15)
- ((and (eq s1 4) (eq s2 6)) 4)
- ((and (eq s2 4) (eq s1 6)) 4)
- ((and (eq s1 1) (eq s2 3)) 1)
- ((and (eq s2 1) (eq s1 3)) 1)
- (t 7))))))
- ((eq (car a) 'neg)
- (math-neg-signs (math-possible-signs
- (nth 1 a)
- (and origin (math-neg origin)))))
- ((and origin (Math-zerop origin) (setq origin nil)
- nil))
- ((and (or (eq (car a) '*)
- (and (eq (car a) '/) origin))
- (Math-realp (nth 1 a)))
- (let ((s (if (eq (car a) '*)
- (if (Math-zerop (nth 1 a))
- (math-possible-signs 0 origin)
- (math-possible-signs (nth 2 a)
- (math-div (or origin 0)
- (nth 1 a))))
- (math-neg-signs
- (math-possible-signs (nth 2 a)
- (math-div (nth 1 a)
- origin))))))
- (if (Math-negp (nth 1 a)) (math-neg-signs s) s)))
- ((and (memq (car a) '(* /)) (Math-realp (nth 2 a)))
- (let ((s (math-possible-signs (nth 1 a)
- (if (eq (car a) '*)
- (math-mul (or origin 0) (nth 2 a))
- (math-div (or origin 0) (nth 2 a))))))
- (if (Math-negp (nth 2 a)) (math-neg-signs s) s)))
- ((eq (car a) 'vec)
- (let ((signs 0))
- (while (and (setq a (cdr a)) (< signs 15))
- (setq signs (logior signs (math-possible-signs
- (car a) origin))))
- signs))
- (t (let ((sign
- (cond
- ((memq (car a) '(* /))
- (let ((s1 (math-possible-signs (nth 1 a)))
- (s2 (math-possible-signs (nth 2 a))))
- (cond ((>= s1 8) 15)
- ((>= s2 8) 15)
- ((and (eq (car a) '/) (memq s2 '(2 3 6 7))) 15)
- (t
- (logior (if (memq s1 '(4 5 6 7)) s2 0)
- (if (memq s1 '(2 3 6 7)) 2 0)
- (if (memq s1 '(1 3 5 7))
- (math-neg-signs s2) 0))))))
- ((eq (car a) '^)
- (let ((s1 (math-possible-signs (nth 1 a)))
- (s2 (math-possible-signs (nth 2 a))))
- (cond ((>= s1 8) 15)
- ((>= s2 8) 15)
- ((eq s1 4) 4)
- ((eq s1 2) (if (eq s2 4) 2 15))
- ((eq s2 2) (if (memq s1 '(1 5)) 2 15))
- ((Math-integerp (nth 2 a))
- (if (math-evenp (nth 2 a))
- (if (memq s1 '(3 6 7)) 6 4)
- s1))
- ((eq s1 6) (if (eq s2 4) 6 15))
- (t 7))))
- ((eq (car a) '%)
- (let ((s2 (math-possible-signs (nth 2 a))))
- (cond ((>= s2 8) 7)
- ((eq s2 2) 2)
- ((memq s2 '(4 6)) 6)
- ((memq s2 '(1 3)) 3)
- (t 7))))
- ((and (memq (car a) '(calcFunc-abs calcFunc-abssqr))
- (= (length a) 2))
- (let ((s1 (math-possible-signs (nth 1 a))))
- (cond ((eq s1 2) 2)
- ((memq s1 '(1 4 5)) 4)
- (t 6))))
- ((and (eq (car a) 'calcFunc-exp) (= (length a) 2))
- (let ((s1 (math-possible-signs (nth 1 a))))
- (if (>= s1 8)
- 15
- (if (or (not origin) (math-negp origin))
- 4
- (setq origin (math-sub (or origin 0) 1))
- (if (Math-zerop origin) (setq origin nil))
- s1))))
- ((or (and (memq (car a) '(calcFunc-ln calcFunc-log10))
- (= (length a) 2))
- (and (eq (car a) 'calcFunc-log)
- (= (length a) 3)
- (math-known-posp (nth 2 a))))
- (if (math-known-nonnegp (nth 1 a))
- (math-possible-signs (nth 1 a) 1)
- 15))
- ((and (eq (car a) 'calcFunc-sqrt) (= (length a) 2))
- (let ((s1 (math-possible-signs (nth 1 a))))
- (if (memq s1 '(2 4 6)) s1 15)))
- ((memq (car a) math-nonnegative-functions) 6)
- ((memq (car a) math-positive-functions) 4)
- ((memq (car a) math-real-functions) 7)
- ((memq (car a) math-real-scalar-functions) 7)
- ((and (memq (car a) math-real-if-arg-functions)
- (= (length a) 2))
- (if (math-known-realp (nth 1 a)) 7 15)))))
- (cond (sign
- (if origin
- (+ (logand sign 8)
- (if (Math-posp origin)
- (if (memq sign '(1 2 3 8 9 10 11)) 1 7)
- (if (memq sign '(2 4 6 8 10 12 14)) 4 7)))
- sign))
- ((math-const-var a)
- (cond ((eq (nth 2 a) 'var-pi)
- (if origin
- (math-possible-signs (math-pi) origin)
- 4))
- ((eq (nth 2 a) 'var-e)
- (if origin
- (math-possible-signs (math-e) origin)
- 4))
- ((eq (nth 2 a) 'var-inf) 4)
- ((eq (nth 2 a) 'var-uinf) 13)
- ((eq (nth 2 a) 'var-i) 8)
- (t 15)))
- (t
- (math-setup-declarations)
- (let ((decl (if (eq (car a) 'var)
- (or (assq (nth 2 a) math-decls-cache)
- math-decls-all)
- (assq (car a) math-decls-cache))))
- (if (and origin
- (memq 'int (nth 1 decl))
- (not (Math-num-integerp origin)))
- 5
- (if (nth 2 decl)
- (math-possible-signs (nth 2 decl) origin)
- (if (memq 'real (nth 1 decl))
- 7
- 15))))))))))
- (defun math-neg-signs (s1)
- (if (>= s1 8)
- (+ 8 (math-neg-signs (- s1 8)))
- (+ (if (memq s1 '(1 3 5 7)) 4 0)
- (if (memq s1 '(2 3 6 7)) 2 0)
- (if (memq s1 '(4 5 6 7)) 1 0))))
- ;;; Try to prove that A is an integer.
- (defun math-known-integerp (a)
- (eq (math-possible-types a) 1))
- (defun math-known-num-integerp (a)
- (<= (math-possible-types a t) 3))
- (defun math-known-imagp (a)
- (= (math-possible-types a) 16))
- ;;; Find the possible types of A.
- ;;; Returns an integer with bits: 1 may be integer.
- ;;; 2 may be integer-valued float.
- ;;; 4 may be fraction.
- ;;; 8 may be non-integer-valued float.
- ;;; 16 may be imaginary.
- ;;; 32 may be non-real, non-imaginary.
- ;;; Real infinities count as integers for the purposes of this function.
- (defun math-possible-types (a &optional num)
- (cond ((Math-objectp a)
- (cond ((Math-integerp a) (if num 3 1))
- ((Math-messy-integerp a) (if num 3 2))
- ((eq (car a) 'frac) (if num 12 4))
- ((eq (car a) 'float) (if num 12 8))
- ((eq (car a) 'intv)
- (if (equal (nth 2 a) (nth 3 a))
- (math-possible-types (nth 2 a))
- 15))
- ((eq (car a) 'sdev)
- (if (math-known-realp (nth 1 a)) 15 63))
- ((eq (car a) 'cplx)
- (if (math-zerop (nth 1 a)) 16 32))
- ((eq (car a) 'polar)
- (if (or (Math-equal (nth 2 a) (math-quarter-circle nil))
- (Math-equal (nth 2 a)
- (math-neg (math-quarter-circle nil))))
- 16 48))
- (t 63)))
- ((eq (car a) '/)
- (let* ((t1 (math-possible-types (nth 1 a) num))
- (t2 (math-possible-types (nth 2 a) num))
- (t12 (logior t1 t2)))
- (if (< t12 16)
- (if (> (logand t12 10) 0)
- 10
- (if (or (= t1 4) (= t2 4) calc-prefer-frac)
- 5
- 15))
- (if (< t12 32)
- (if (= t1 16)
- (if (= t2 16) 15
- (if (< t2 16) 16 31))
- (if (= t2 16)
- (if (< t1 16) 16 31)
- 31))
- 63))))
- ((memq (car a) '(+ - * %))
- (let* ((t1 (math-possible-types (nth 1 a) num))
- (t2 (math-possible-types (nth 2 a) num))
- (t12 (logior t1 t2)))
- (if (eq (car a) '%)
- (setq t1 (logand t1 15) t2 (logand t2 15) t12 (logand t12 15)))
- (if (< t12 16)
- (let ((mask (if (<= t12 3)
- 1
- (if (and (or (and (<= t1 3) (= (logand t2 3) 0))
- (and (<= t2 3) (= (logand t1 3) 0)))
- (memq (car a) '(+ -)))
- 4
- 5))))
- (if num
- (* mask 3)
- (logior (if (and (> (logand t1 5) 0) (> (logand t2 5) 0))
- mask 0)
- (if (> (logand t12 10) 0)
- (* mask 2) 0))))
- (if (< t12 32)
- (if (eq (car a) '*)
- (if (= t1 16)
- (if (= t2 16) 15
- (if (< t2 16) 16 31))
- (if (= t2 16)
- (if (< t1 16) 16 31)
- 31))
- (if (= t12 16) 16
- (if (or (and (= t1 16) (< t2 16))
- (and (= t2 16) (< t1 16))) 32 63)))
- 63))))
- ((eq (car a) 'neg)
- (math-possible-types (nth 1 a)))
- ((eq (car a) '^)
- (let* ((t1 (math-possible-types (nth 1 a) num))
- (t2 (math-possible-types (nth 2 a) num))
- (t12 (logior t1 t2)))
- (if (and (<= t2 3) (math-known-nonnegp (nth 2 a)) (< t1 16))
- (let ((mask (logior (if (> (logand t1 3) 0) 1 0)
- (logand t1 4)
- (if (> (logand t1 12) 0) 5 0))))
- (if num
- (* mask 3)
- (logior (if (and (> (logand t1 5) 0) (> (logand t2 5) 0))
- mask 0)
- (if (> (logand t12 10) 0)
- (* mask 2) 0))))
- (if (and (math-known-nonnegp (nth 1 a))
- (math-known-posp (nth 2 a)))
- 15
- 63))))
- ((eq (car a) 'calcFunc-sqrt)
- (let ((t1 (math-possible-signs (nth 1 a))))
- (logior (if (> (logand t1 2) 0) 3 0)
- (if (> (logand t1 1) 0) 16 0)
- (if (> (logand t1 4) 0) 15 0)
- (if (> (logand t1 8) 0) 32 0))))
- ((eq (car a) 'vec)
- (let ((types 0))
- (while (and (setq a (cdr a)) (< types 63))
- (setq types (logior types (math-possible-types (car a) t))))
- types))
- ((or (memq (car a) math-integer-functions)
- (and (memq (car a) math-rounding-functions)
- (math-known-nonnegp (or (nth 2 a) 0))))
- 1)
- ((or (memq (car a) math-num-integer-functions)
- (and (memq (car a) math-float-rounding-functions)
- (math-known-nonnegp (or (nth 2 a) 0))))
- 2)
- ((eq (car a) 'calcFunc-frac)
- 5)
- ((and (eq (car a) 'calcFunc-float) (= (length a) 2))
- (let ((t1 (math-possible-types (nth 1 a))))
- (logior (if (> (logand t1 3) 0) 2 0)
- (if (> (logand t1 12) 0) 8 0)
- (logand t1 48))))
- ((and (memq (car a) '(calcFunc-abs calcFunc-abssqr))
- (= (length a) 2))
- (let ((t1 (math-possible-types (nth 1 a))))
- (if (>= t1 16)
- 15
- t1)))
- ((math-const-var a)
- (cond ((memq (nth 2 a) '(var-e var-pi var-phi var-gamma)) 8)
- ((eq (nth 2 a) 'var-inf) 1)
- ((eq (nth 2 a) 'var-i) 16)
- (t 63)))
- (t
- (math-setup-declarations)
- (let ((decl (if (eq (car a) 'var)
- (or (assq (nth 2 a) math-decls-cache)
- math-decls-all)
- (assq (car a) math-decls-cache))))
- (cond ((memq 'int (nth 1 decl))
- 1)
- ((memq 'numint (nth 1 decl))
- 3)
- ((memq 'frac (nth 1 decl))
- 4)
- ((memq 'rat (nth 1 decl))
- 5)
- ((memq 'float (nth 1 decl))
- 10)
- ((nth 2 decl)
- (math-possible-types (nth 2 decl)))
- ((memq 'real (nth 1 decl))
- 15)
- (t 63))))))
- (defun math-known-evenp (a)
- (cond ((Math-integerp a)
- (math-evenp a))
- ((Math-messy-integerp a)
- (or (> (nth 2 a) 0)
- (math-evenp (math-trunc a))))
- ((eq (car a) '*)
- (if (math-known-evenp (nth 1 a))
- (math-known-num-integerp (nth 2 a))
- (if (math-known-num-integerp (nth 1 a))
- (math-known-evenp (nth 2 a)))))
- ((memq (car a) '(+ -))
- (or (and (math-known-evenp (nth 1 a))
- (math-known-evenp (nth 2 a)))
- (and (math-known-oddp (nth 1 a))
- (math-known-oddp (nth 2 a)))))
- ((eq (car a) 'neg)
- (math-known-evenp (nth 1 a)))))
- (defun math-known-oddp (a)
- (cond ((Math-integerp a)
- (math-oddp a))
- ((Math-messy-integerp a)
- (and (<= (nth 2 a) 0)
- (math-oddp (math-trunc a))))
- ((memq (car a) '(+ -))
- (or (and (math-known-evenp (nth 1 a))
- (math-known-oddp (nth 2 a)))
- (and (math-known-oddp (nth 1 a))
- (math-known-evenp (nth 2 a)))))
- ((eq (car a) 'neg)
- (math-known-oddp (nth 1 a)))))
- (defun calcFunc-dreal (expr)
- (let ((types (math-possible-types expr)))
- (if (< types 16) 1
- (if (= (logand types 15) 0) 0
- (math-reject-arg expr 'realp 'quiet)))))
- (defun calcFunc-dimag (expr)
- (let ((types (math-possible-types expr)))
- (if (= types 16) 1
- (if (= (logand types 16) 0) 0
- (math-reject-arg expr "Expected an imaginary number")))))
- (defun calcFunc-dpos (expr)
- (let ((signs (math-possible-signs expr)))
- (if (eq signs 4) 1
- (if (memq signs '(1 2 3)) 0
- (math-reject-arg expr 'posp 'quiet)))))
- (defun calcFunc-dneg (expr)
- (let ((signs (math-possible-signs expr)))
- (if (eq signs 1) 1
- (if (memq signs '(2 4 6)) 0
- (math-reject-arg expr 'negp 'quiet)))))
- (defun calcFunc-dnonneg (expr)
- (let ((signs (math-possible-signs expr)))
- (if (memq signs '(2 4 6)) 1
- (if (eq signs 1) 0
- (math-reject-arg expr 'posp 'quiet)))))
- (defun calcFunc-dnonzero (expr)
- (let ((signs (math-possible-signs expr)))
- (if (memq signs '(1 4 5 8 9 12 13)) 1
- (if (eq signs 2) 0
- (math-reject-arg expr 'nonzerop 'quiet)))))
- (defun calcFunc-dint (expr)
- (let ((types (math-possible-types expr)))
- (if (= types 1) 1
- (if (= (logand types 1) 0) 0
- (math-reject-arg expr 'integerp 'quiet)))))
- (defun calcFunc-dnumint (expr)
- (let ((types (math-possible-types expr t)))
- (if (<= types 3) 1
- (if (= (logand types 3) 0) 0
- (math-reject-arg expr 'integerp 'quiet)))))
- (defun calcFunc-dnatnum (expr)
- (let ((res (calcFunc-dint expr)))
- (if (eq res 1)
- (calcFunc-dnonneg expr)
- res)))
- (defun calcFunc-deven (expr)
- (if (math-known-evenp expr)
- 1
- (if (or (math-known-oddp expr)
- (= (logand (math-possible-types expr) 3) 0))
- 0
- (math-reject-arg expr "Can't tell if expression is odd or even"))))
- (defun calcFunc-dodd (expr)
- (if (math-known-oddp expr)
- 1
- (if (or (math-known-evenp expr)
- (= (logand (math-possible-types expr) 3) 0))
- 0
- (math-reject-arg expr "Can't tell if expression is odd or even"))))
- (defun calcFunc-drat (expr)
- (let ((types (math-possible-types expr)))
- (if (memq types '(1 4 5)) 1
- (if (= (logand types 5) 0) 0
- (math-reject-arg expr "Rational number expected")))))
- (defun calcFunc-drange (expr)
- (math-setup-declarations)
- (let (range)
- (if (Math-realp expr)
- (list 'vec expr)
- (if (eq (car-safe expr) 'intv)
- expr
- (if (eq (car-safe expr) 'var)
- (setq range (nth 2 (or (assq (nth 2 expr) math-decls-cache)
- math-decls-all)))
- (setq range (nth 2 (assq (car-safe expr) math-decls-cache))))
- (if range
- (math-clean-set (copy-sequence range))
- (setq range (math-possible-signs expr))
- (if (< range 8)
- (aref [(vec)
- (intv 2 (neg (var inf var-inf)) 0)
- (vec 0)
- (intv 3 (neg (var inf var-inf)) 0)
- (intv 1 0 (var inf var-inf))
- (vec (intv 2 (neg (var inf var-inf)) 0)
- (intv 1 0 (var inf var-inf)))
- (intv 3 0 (var inf var-inf))
- (intv 3 (neg (var inf var-inf)) (var inf var-inf))] range)
- (math-reject-arg expr 'realp 'quiet)))))))
- (defun calcFunc-dscalar (a)
- (if (math-known-scalarp a) 1
- (if (math-known-matrixp a) 0
- (math-reject-arg a 'objectp 'quiet))))
- ;;;; Arithmetic.
- (defsubst calcFunc-neg (a)
- (math-normalize (list 'neg a)))
- (defun math-neg-fancy (a)
- (cond ((eq (car a) 'polar)
- (list 'polar
- (nth 1 a)
- (if (math-posp (nth 2 a))
- (math-sub (nth 2 a) (math-half-circle nil))
- (math-add (nth 2 a) (math-half-circle nil)))))
- ((eq (car a) 'mod)
- (if (math-zerop (nth 1 a))
- a
- (list 'mod (math-sub (nth 2 a) (nth 1 a)) (nth 2 a))))
- ((eq (car a) 'sdev)
- (list 'sdev (math-neg (nth 1 a)) (nth 2 a)))
- ((eq (car a) 'intv)
- (math-make-intv (aref [0 2 1 3] (nth 1 a))
- (math-neg (nth 3 a))
- (math-neg (nth 2 a))))
- ((and math-simplify-only
- (not (equal a math-simplify-only)))
- (list 'neg a))
- ((eq (car a) '+)
- (math-sub (math-neg (nth 1 a)) (nth 2 a)))
- ((eq (car a) '-)
- (math-sub (nth 2 a) (nth 1 a)))
- ((and (memq (car a) '(* /))
- (math-okay-neg (nth 1 a)))
- (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
- ((and (memq (car a) '(* /))
- (math-okay-neg (nth 2 a)))
- (list (car a) (nth 1 a) (math-neg (nth 2 a))))
- ((and (memq (car a) '(* /))
- (or (math-objectp (nth 1 a))
- (and (eq (car (nth 1 a)) '*)
- (math-objectp (nth 1 (nth 1 a))))))
- (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
- ((and (eq (car a) '/)
- (or (math-objectp (nth 2 a))
- (and (eq (car (nth 2 a)) '*)
- (math-objectp (nth 1 (nth 2 a))))))
- (list (car a) (nth 1 a) (math-neg (nth 2 a))))
- ((and (eq (car a) 'var) (memq (nth 2 a) '(var-uinf var-nan)))
- a)
- ((eq (car a) 'neg)
- (nth 1 a))
- (t (list 'neg a))))
- (defun math-okay-neg (a)
- (or (math-looks-negp a)
- (eq (car-safe a) '-)))
- (defun math-neg-float (a)
- (list 'float (Math-integer-neg (nth 1 a)) (nth 2 a)))
- (defun calcFunc-add (&rest rest)
- (if rest
- (let ((a (car rest)))
- (while (setq rest (cdr rest))
- (setq a (list '+ a (car rest))))
- (math-normalize a))
- 0))
- (defun calcFunc-sub (&rest rest)
- (if rest
- (let ((a (car rest)))
- (while (setq rest (cdr rest))
- (setq a (list '- a (car rest))))
- (math-normalize a))
- 0))
- (defun math-add-objects-fancy (a b)
- (cond ((and (Math-numberp a) (Math-numberp b))
- (let ((aa (math-complex a))
- (bb (math-complex b)))
- (math-normalize
- (let ((res (list 'cplx
- (math-add (nth 1 aa) (nth 1 bb))
- (math-add (nth 2 aa) (nth 2 bb)))))
- (if (math-want-polar a b)
- (math-polar res)
- res)))))
- ((or (Math-vectorp a) (Math-vectorp b))
- (math-map-vec-2 'math-add a b))
- ((eq (car-safe a) 'sdev)
- (if (eq (car-safe b) 'sdev)
- (math-make-sdev (math-add (nth 1 a) (nth 1 b))
- (math-hypot (nth 2 a) (nth 2 b)))
- (and (or (Math-scalarp b)
- (not (Math-objvecp b)))
- (math-make-sdev (math-add (nth 1 a) b) (nth 2 a)))))
- ((and (eq (car-safe b) 'sdev)
- (or (Math-scalarp a)
- (not (Math-objvecp a))))
- (math-make-sdev (math-add a (nth 1 b)) (nth 2 b)))
- ((eq (car-safe a) 'intv)
- (if (eq (car-safe b) 'intv)
- (math-make-intv (logior (logand (nth 1 a) (nth 1 b))
- (if (equal (nth 2 a)
- '(neg (var inf var-inf)))
- (logand (nth 1 a) 2) 0)
- (if (equal (nth 2 b)
- '(neg (var inf var-inf)))
- (logand (nth 1 b) 2) 0)
- (if (equal (nth 3 a) '(var inf var-inf))
- (logand (nth 1 a) 1) 0)
- (if (equal (nth 3 b) '(var inf var-inf))
- (logand (nth 1 b) 1) 0))
- (math-add (nth 2 a) (nth 2 b))
- (math-add (nth 3 a) (nth 3 b)))
- (and (or (Math-anglep b)
- (eq (car b) 'date)
- (not (Math-objvecp b)))
- (math-make-intv (nth 1 a)
- (math-add (nth 2 a) b)
- (math-add (nth 3 a) b)))))
- ((and (eq (car-safe b) 'intv)
- (or (Math-anglep a)
- (eq (car a) 'date)
- (not (Math-objvecp a))))
- (math-make-intv (nth 1 b)
- (math-add a (nth 2 b))
- (math-add a (nth 3 b))))
- ((eq (car-safe a) 'date)
- (cond ((eq (car-safe b) 'date)
- (math-add (nth 1 a) (nth 1 b)))
- ((eq (car-safe b) 'hms)
- (let ((parts (math-date-parts (nth 1 a))))
- (list 'date
- (math-add (car parts) ; this minimizes roundoff
- (math-div (math-add
- (math-add (nth 1 parts)
- (nth 2 parts))
- (math-add
- (math-mul (nth 1 b) 3600)
- (math-add (math-mul (nth 2 b) 60)
- (nth 3 b))))
- 86400)))))
- ((Math-realp b)
- (list 'date (math-add (nth 1 a) b)))
- (t nil)))
- ((eq (car-safe b) 'date)
- (math-add-objects-fancy b a))
- ((and (eq (car-safe a) 'mod)
- (eq (car-safe b) 'mod)
- (equal (nth 2 a) (nth 2 b)))
- (math-make-mod (math-add (nth 1 a) (nth 1 b)) (nth 2 a)))
- ((and (eq (car-safe a) 'mod)
- (Math-anglep b))
- (math-make-mod (math-add (nth 1 a) b) (nth 2 a)))
- ((and (eq (car-safe b) 'mod)
- (Math-anglep a))
- (math-make-mod (math-add a (nth 1 b)) (nth 2 b)))
- ((and (or (eq (car-safe a) 'hms) (eq (car-safe b) 'hms))
- (and (Math-anglep a) (Math-anglep b)))
- (or (eq (car-safe a) 'hms) (setq a (math-to-hms a)))
- (or (eq (car-safe b) 'hms) (setq b (math-to-hms b)))
- (math-normalize
- (if (math-negp a)
- (math-neg (math-add (math-neg a) (math-neg b)))
- (if (math-negp b)
- (let* ((s (math-add (nth 3 a) (nth 3 b)))
- (m (math-add (nth 2 a) (nth 2 b)))
- (h (math-add (nth 1 a) (nth 1 b))))
- (if (math-negp s)
- (setq s (math-add s 60)
- m (math-add m -1)))
- (if (math-negp m)
- (setq m (math-add m 60)
- h (math-add h -1)))
- (if (math-negp h)
- (math-add b a)
- (list 'hms h m s)))
- (let* ((s (math-add (nth 3 a) (nth 3 b)))
- (m (math-add (nth 2 a) (nth 2 b)))
- (h (math-add (nth 1 a) (nth 1 b))))
- (list 'hms h m s))))))
- (t (calc-record-why "*Incompatible arguments for +" a b))))
- (defun math-add-symb-fancy (a b)
- (or (and math-simplify-only
- (not (equal a math-simplify-only))
- (list '+ a b))
- (and (eq (car-safe b) '+)
- (math-add (math-add a (nth 1 b))
- (nth 2 b)))
- (and (eq (car-safe b) '-)
- (math-sub (math-add a (nth 1 b))
- (nth 2 b)))
- (and (eq (car-safe b) 'neg)
- (eq (car-safe (nth 1 b)) '+)
- (math-sub (math-sub a (nth 1 (nth 1 b)))
- (nth 2 (nth 1 b))))
- (and (or (and (Math-vectorp a) (math-known-scalarp b))
- (and (Math-vectorp b) (math-known-scalarp a)))
- (math-map-vec-2 'math-add a b))
- (let ((inf (math-infinitep a)))
- (cond
- (inf
- (let ((inf2 (math-infinitep b)))
- (if inf2
- (if (or (memq (nth 2 inf) '(var-uinf var-nan))
- (memq (nth 2 inf2) '(var-uinf var-nan)))
- '(var nan var-nan)
- (let ((dir (math-infinite-dir a inf))
- (dir2 (math-infinite-dir b inf2)))
- (if (and (Math-objectp dir) (Math-objectp dir2))
- (if (Math-equal dir dir2)
- a
- '(var nan var-nan)))))
- (if (and (equal a '(var inf var-inf))
- (eq (car-safe b) 'intv)
- (memq (nth 1 b) '(2 3))
- (equal (nth 2 b) '(neg (var inf var-inf))))
- (list 'intv 3 (nth 2 b) a)
- (if (and (equal a '(neg (var inf var-inf)))
- (eq (car-safe b) 'intv)
- (memq (nth 1 b) '(1 3))
- (equal (nth 3 b) '(var inf var-inf)))
- (list 'intv 3 a (nth 3 b))
- a)))))
- ((math-infinitep b)
- (if (eq (car-safe a) 'intv)
- (math-add b a)
- b))
- ((eq (car-safe a) '+)
- (let ((temp (math-combine-sum (nth 2 a) b nil nil t)))
- (and temp
- (math-add (nth 1 a) temp))))
- ((eq (car-safe a) '-)
- (let ((temp (math-combine-sum (nth 2 a) b t nil t)))
- (and temp
- (math-add (nth 1 a) temp))))
- ((and (Math-objectp a) (Math-objectp b))
- nil)
- (t
- (math-combine-sum a b nil nil nil))))
- (and (Math-looks-negp b)
- (list '- a (math-neg b)))
- (and (Math-looks-negp a)
- (list '- b (math-neg a)))
- (and (eq (car-safe a) 'calcFunc-idn)
- (= (length a) 2)
- (or (and (eq (car-safe b) 'calcFunc-idn)
- (= (length b) 2)
- (list 'calcFunc-idn (math-add (nth 1 a) (nth 1 b))))
- (and (math-square-matrixp b)
- (math-add (math-mimic-ident (nth 1 a) b) b))
- (and (math-known-scalarp b)
- (math-add (nth 1 a) b))))
- (and (eq (car-safe b) 'calcFunc-idn)
- (= (length b) 2)
- (or (and (math-square-matrixp a)
- (math-add a (math-mimic-ident (nth 1 b) a)))
- (and (math-known-scalarp a)
- (math-add a (nth 1 b)))))
- (list '+ a b)))
- (defun calcFunc-mul (&rest rest)
- (if rest
- (let ((a (car rest)))
- (while (setq rest (cdr rest))
- (setq a (list '* a (car rest))))
- (math-normalize a))
- 1))
- (defun math-mul-objects-fancy (a b)
- (cond ((and (Math-numberp a) (Math-numberp b))
- (math-normalize
- (if (math-want-polar a b)
- (let ((a (math-polar a))
- (b (math-polar b)))
- (list 'polar
- (math-mul (nth 1 a) (nth 1 b))
- (math-fix-circular (math-add (nth 2 a) (nth 2 b)))))
- (setq a (math-complex a)
- b (math-complex b))
- (list 'cplx
- (math-sub (math-mul (nth 1 a) (nth 1 b))
- (math-mul (nth 2 a) (nth 2 b)))
- (math-add (math-mul (nth 1 a) (nth 2 b))
- (math-mul (nth 2 a) (nth 1 b)))))))
- ((Math-vectorp a)
- (if (Math-vectorp b)
- (if (math-matrixp a)
- (if (math-matrixp b)
- (if (= (length (nth 1 a)) (length b))
- (math-mul-mats a b)
- (math-dimension-error))
- (if (= (length (nth 1 a)) 2)
- (if (= (length a) (length b))
- (math-mul-mats a (list 'vec b))
- (math-dimension-error))
- (if (= (length (nth 1 a)) (length b))
- (math-mul-mat-vec a b)
- (math-dimension-error))))
- (if (math-matrixp b)
- (if (= (length a) (length b))
- (nth 1 (math-mul-mats (list 'vec a) b))
- (math-dimension-error))
- (if (= (length a) (length b))
- (math-dot-product a b)
- (math-dimension-error))))
- (math-map-vec-2 'math-mul a b)))
- ((Math-vectorp b)
- (math-map-vec-2 'math-mul a b))
- ((eq (car-safe a) 'sdev)
- (if (eq (car-safe b) 'sdev)
- (math-make-sdev (math-mul (nth 1 a) (nth 1 b))
- (math-hypot (math-mul (nth 2 a) (nth 1 b))
- (math-mul (nth 2 b) (nth 1 a))))
- (and (or (Math-scalarp b)
- (not (Math-objvecp b)))
- (math-make-sdev (math-mul (nth 1 a) b)
- (math-mul (nth 2 a) b)))))
- ((and (eq (car-safe b) 'sdev)
- (or (Math-scalarp a)
- (not (Math-objvecp a))))
- (math-make-sdev (math-mul a (nth 1 b)) (math-mul a (nth 2 b))))
- ((and (eq (car-safe a) 'intv) (Math-anglep b))
- (if (Math-negp b)
- (math-neg (math-mul a (math-neg b)))
- (math-make-intv (nth 1 a)
- (math-mul (nth 2 a) b)
- (math-mul (nth 3 a) b))))
- ((and (eq (car-safe b) 'intv) (Math-anglep a))
- (math-mul b a))
- ((and (eq (car-safe a) 'intv) (math-intv-constp a)
- (eq (car-safe b) 'intv) (math-intv-constp b))
- (let ((lo (math-mul a (nth 2 b)))
- (hi (math-mul a (nth 3 b))))
- (or (eq (car-safe lo) 'intv)
- (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0) lo lo)))
- (or (eq (car-safe hi) 'intv)
- (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0) hi hi)))
- (math-combine-intervals
- (nth 2 lo) (and (or (memq (nth 1 b) '(2 3))
- (math-infinitep (nth 2 lo)))
- (memq (nth 1 lo) '(2 3)))
- (nth 3 lo) (and (or (memq (nth 1 b) '(2 3))
- (math-infinitep (nth 3 lo)))
- (memq (nth 1 lo) '(1 3)))
- (nth 2 hi) (and (or (memq (nth 1 b) '(1 3))
- (math-infinitep (nth 2 hi)))
- (memq (nth 1 hi) '(2 3)))
- (nth 3 hi) (and (or (memq (nth 1 b) '(1 3))
- (math-infinitep (nth 3 hi)))
- (memq (nth 1 hi) '(1 3))))))
- ((and (eq (car-safe a) 'mod)
- (eq (car-safe b) 'mod)
- (equal (nth 2 a) (nth 2 b)))
- (math-make-mod (math-mul (nth 1 a) (nth 1 b)) (nth 2 a)))
- ((and (eq (car-safe a) 'mod)
- (Math-anglep b))
- (math-make-mod (math-mul (nth 1 a) b) (nth 2 a)))
- ((and (eq (car-safe b) 'mod)
- (Math-anglep a))
- (math-make-mod (math-mul a (nth 1 b)) (nth 2 b)))
- ((and (eq (car-safe a) 'hms) (Math-realp b))
- (math-with-extra-prec 2
- (math-to-hms (math-mul (math-from-hms a 'deg) b) 'deg)))
- ((and (eq (car-safe b) 'hms) (Math-realp a))
- (math-mul b a))
- (t (calc-record-why "*Incompatible arguments for *" a b))))
- ;;; Fast function to multiply floating-point numbers.
- (defun math-mul-float (a b) ; [F F F]
- (math-make-float (math-mul (nth 1 a) (nth 1 b))
- (+ (nth 2 a) (nth 2 b))))
- (defun math-sqr-float (a) ; [F F]
- (math-make-float (math-mul (nth 1 a) (nth 1 a))
- (+ (nth 2 a) (nth 2 a))))
- (defun math-intv-constp (a &optional finite)
- (and (or (Math-anglep (nth 2 a))
- (and (equal (nth 2 a) '(neg (var inf var-inf)))
- (or (not finite)
- (memq (nth 1 a) '(0 1)))))
- (or (Math-anglep (nth 3 a))
- (and (equal (nth 3 a) '(var inf var-inf))
- (or (not finite)
- (memq (nth 1 a) '(0 2)))))))
- (defun math-mul-zero (a b)
- (if (math-known-matrixp b)
- (if (math-vectorp b)
- (math-map-vec-2 'math-mul a b)
- (math-mimic-ident 0 b))
- (if (math-infinitep b)
- '(var nan var-nan)
- (let ((aa nil) (bb nil))
- (if (and (eq (car-safe b) 'intv)
- (progn
- (and (equal (nth 2 b) '(neg (var inf var-inf)))
- (memq (nth 1 b) '(2 3))
- (setq aa (nth 2 b)))
- (and (equal (nth 3 b) '(var inf var-inf))
- (memq (nth 1 b) '(1 3))
- (setq bb (nth 3 b)))
- (or aa bb)))
- (if (or (math-posp a)
- (and (math-zerop a)
- (or (memq calc-infinite-mode '(-1 1))
- (setq aa '(neg (var inf var-inf))
- bb '(var inf var-inf)))))
- (list 'intv 3 (or aa 0) (or bb 0))
- (if (math-negp a)
- (math-neg (list 'intv 3 (or aa 0) (or bb 0)))
- '(var nan var-nan)))
- (if (or (math-floatp a) (math-floatp b)) '(float 0 0) 0))))))
- (defun math-mul-symb-fancy (a b)
- (or (and math-simplify-only
- (not (equal a math-simplify-only))
- (list '* a b))
- (and (Math-equal-int a 1)
- b)
- (and (Math-equal-int a -1)
- (math-neg b))
- (and (or (and (Math-vectorp a) (math-known-scalarp b))
- (and (Math-vectorp b) (math-known-scalarp a)))
- (math-map-vec-2 'math-mul a b))
- (and (Math-objectp b) (not (Math-objectp a))
- (math-mul b a))
- (and (eq (car-safe a) 'neg)
- (math-neg (math-mul (nth 1 a) b)))
- (and (eq (car-safe b) 'neg)
- (math-neg (math-mul a (nth 1 b))))
- (and (eq (car-safe a) '*)
- (math-mul (nth 1 a)
- (math-mul (nth 2 a) b)))
- (and (eq (car-safe a) '^)
- (Math-looks-negp (nth 2 a))
- (not (and (eq (car-safe b) '^) (Math-looks-negp (nth 2 b))))
- (math-known-scalarp b t)
- (math-div b (math-normalize
- (list '^ (nth 1 a) (math-neg (nth 2 a))))))
- (and (eq (car-safe b) '^)
- (Math-looks-negp (nth 2 b))
- (not (and (eq (car-safe a) '^) (Math-looks-negp (nth 2 a))))
- (not (math-known-matrixp (nth 1 b)))
- (math-div a (math-normalize
- (list '^ (nth 1 b) (math-neg (nth 2 b))))))
- (and (eq (car-safe a) '/)
- (or (math-known-scalarp a t) (math-known-scalarp b t))
- (let ((temp (math-combine-prod (nth 2 a) b t nil t)))
- (if temp
- (math-mul (nth 1 a) temp)
- (math-div (math-mul (nth 1 a) b) (nth 2 a)))))
- (and (eq (car-safe b) '/)
- (math-div (math-mul a (nth 1 b)) (nth 2 b)))
- (and (eq (car-safe b) '+)
- (Math-numberp a)
- (or (Math-numberp (nth 1 b))
- (Math-numberp (nth 2 b)))
- (math-add (math-mul a (nth 1 b))
- (math-mul a (nth 2 b))))
- (and (eq (car-safe b) '-)
- (Math-numberp a)
- (or (Math-numberp (nth 1 b))
- (Math-numberp (nth 2 b)))
- (math-sub (math-mul a (nth 1 b))
- (math-mul a (nth 2 b))))
- (and (eq (car-safe b) '*)
- (Math-numberp (nth 1 b))
- (not (Math-numberp a))
- (math-mul (nth 1 b) (math-mul a (nth 2 b))))
- (and (eq (car-safe a) 'calcFunc-idn)
- (= (length a) 2)
- (or (and (eq (car-safe b) 'calcFunc-idn)
- (= (length b) 2)
- (list 'calcFunc-idn (math-mul (nth 1 a) (nth 1 b))))
- (and (math-known-scalarp b)
- (list 'calcFunc-idn (math-mul (nth 1 a) b)))
- (and (math-known-matrixp b)
- (math-mul (nth 1 a) b))))
- (and (eq (car-safe b) 'calcFunc-idn)
- (= (length b) 2)
- (or (and (math-known-scalarp a)
- (list 'calcFunc-idn (math-mul a (nth 1 b))))
- (and (math-known-matrixp a)
- (math-mul a (nth 1 b)))))
- (and (math-identity-matrix-p a t)
- (or (and (eq (car-safe b) 'calcFunc-idn)
- (= (length b) 2)
- (list 'calcFunc-idn (math-mul
- (nth 1 (nth 1 a))
- (nth 1 b))
- (1- (length a))))
- (and (math-known-scalarp b)
- (list 'calcFunc-idn (math-mul
- (nth 1 (nth 1 a)) b)
- (1- (length a))))
- (and (math-known-matrixp b)
- (math-mul (nth 1 (nth 1 a)) b))))
- (and (math-identity-matrix-p b t)
- (or (and (eq (car-safe a) 'calcFunc-idn)
- (= (length a) 2)
- (list 'calcFunc-idn (math-mul (nth 1 a)
- (nth 1 (nth 1 b)))
- (1- (length b))))
- (and (math-known-scalarp a)
- (list 'calcFunc-idn (math-mul a (nth 1 (nth 1 b)))
- (1- (length b))))
- (and (math-known-matrixp a)
- (math-mul a (nth 1 (nth 1 b))))))
- (and (math-looks-negp b)
- (math-mul (math-neg a) (math-neg b)))
- (and (eq (car-safe b) '-)
- (math-looks-negp a)
- (math-mul (math-neg a) (math-neg b)))
- (cond
- ((eq (car-safe b) '*)
- (let ((temp (math-combine-prod a (nth 1 b) nil nil t)))
- (and temp
- (math-mul temp (nth 2 b)))))
- (t
- (math-combine-prod a b nil nil nil)))
- (and (equal a '(var nan var-nan))
- a)
- (and (equal b '(var nan var-nan))
- b)
- (and (equal a '(var uinf var-uinf))
- a)
- (and (equal b '(var uinf var-uinf))
- b)
- (and (equal b '(var inf var-inf))
- (let ((s1 (math-possible-signs a)))
- (cond ((eq s1 4)
- b)
- ((eq s1 6)
- '(intv 3 0 (var inf var-inf)))
- ((eq s1 1)
- (math-neg b))
- ((eq s1 3)
- '(intv 3 (neg (var inf var-inf)) 0))
- ((and (eq (car a) 'intv) (math-intv-constp a))
- '(intv 3 (neg (var inf var-inf)) (var inf var-inf)))
- ((and (eq (car a) 'cplx)
- (math-zerop (nth 1 a)))
- (list '* (list 'cplx 0 (calcFunc-sign (nth 2 a))) b))
- ((eq (car a) 'polar)
- (list '* (list 'polar 1 (nth 2 a)) b)))))
- (and (equal a '(var inf var-inf))
- (math-mul b a))
- (list '* a b)))
- (defun calcFunc-div (a &rest rest)
- (while rest
- (setq a (list '/ a (car rest))
- rest (cdr rest)))
- (math-normalize a))
- (defun math-div-objects-fancy (a b)
- (cond ((and (Math-numberp a) (Math-numberp b))
- (math-normalize
- (cond ((math-want-polar a b)
- (let ((a (math-polar a))
- (b (math-polar b)))
- (list 'polar
- (math-div (nth 1 a) (nth 1 b))
- (math-fix-circular (math-sub (nth 2 a)
- (nth 2 b))))))
- ((Math-realp b)
- (setq a (math-complex a))
- (list 'cplx (math-div (nth 1 a) b)
- (math-div (nth 2 a) b)))
- (t
- (setq a (math-complex a)
- b (math-complex b))
- (math-div
- (list 'cplx
- (math-add (math-mul (nth 1 a) (nth 1 b))
- (math-mul (nth 2 a) (nth 2 b)))
- (math-sub (math-mul (nth 2 a) (nth 1 b))
- (math-mul (nth 1 a) (nth 2 b))))
- (math-add (math-sqr (nth 1 b))
- (math-sqr (nth 2 b))))))))
- ((math-matrixp b)
- (if (math-square-matrixp b)
- (let ((n1 (length b)))
- (if (Math-vectorp a)
- (if (math-matrixp a)
- (if (= (length a) n1)
- (math-lud-solve (math-matrix-lud b) a b)
- (if (= (length (nth 1 a)) n1)
- (math-transpose
- (math-lud-solve (math-matrix-lud
- (math-transpose b))
- (math-transpose a) b))
- (math-dimension-error)))
- (if (= (length a) n1)
- (math-mat-col (math-lud-solve (math-matrix-lud b)
- (math-col-matrix a) b)
- 1)
- (math-dimension-error)))
- (if (Math-equal-int a 1)
- (calcFunc-inv b)
- (math-mul a (calcFunc-inv b)))))
- (math-reject-arg b 'square-matrixp)))
- ((and (Math-vectorp a) (Math-objectp b))
- (math-map-vec-2 'math-div a b))
- ((eq (car-safe a) 'sdev)
- (if (eq (car-safe b) 'sdev)
- (let ((x (math-div (nth 1 a) (nth 1 b))))
- (math-make-sdev x
- (math-div (math-hypot (nth 2 a)
- (math-mul (nth 2 b) x))
- (nth 1 b))))
- (if (or (Math-scalarp b)
- (not (Math-objvecp b)))
- (math-make-sdev (math-div (nth 1 a) b) (math-div (nth 2 a) b))
- (math-reject-arg 'realp b))))
- ((and (eq (car-safe b) 'sdev)
- (or (Math-scalarp a)
- (not (Math-objvecp a))))
- (let ((x (math-div a (nth 1 b))))
- (math-make-sdev x
- (math-div (math-mul (nth 2 b) x) (nth 1 b)))))
- ((and (eq (car-safe a) 'intv) (Math-anglep b))
- (if (Math-negp b)
- (math-neg (math-div a (math-neg b)))
- (math-make-intv (nth 1 a)
- (math-div (nth 2 a) b)
- (math-div (nth 3 a) b))))
- ((and (eq (car-safe b) 'intv) (Math-anglep a))
- (if (or (Math-posp (nth 2 b))
- (and (Math-zerop (nth 2 b)) (or (memq (nth 1 b) '(0 1))
- calc-infinite-mode)))
- (if (Math-negp a)
- (math-neg (math-div (math-neg a) b))
- (let ((calc-infinite-mode 1))
- (math-make-intv (aref [0 2 1 3] (nth 1 b))
- (math-div a (nth 3 b))
- (math-div a (nth 2 b)))))
- (if (or (Math-negp (nth 3 b))
- (and (Math-zerop (nth 3 b)) (or (memq (nth 1 b) '(0 2))
- calc-infinite-mode)))
- (math-neg (math-div a (math-neg b)))
- (if calc-infinite-mode
- '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
- (math-reject-arg b "*Division by zero")))))
- ((and (eq (car-safe a) 'intv) (math-intv-constp a)
- (eq (car-safe b) 'intv) (math-intv-constp b))
- (if (or (Math-posp (nth 2 b))
- (and (Math-zerop (nth 2 b)) (or (memq (nth 1 b) '(0 1))
- calc-infinite-mode)))
- (let* ((calc-infinite-mode 1)
- (lo (math-div a (nth 2 b)))
- (hi (math-div a (nth 3 b))))
- (or (eq (car-safe lo) 'intv)
- (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0)
- lo lo)))
- (or (eq (car-safe hi) 'intv)
- (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0)
- hi hi)))
- (math-combine-intervals
- (nth 2 lo) (and (or (memq (nth 1 b) '(2 3))
- (and (math-infinitep (nth 2 lo))
- (not (math-zerop (nth 2 b)))))
- (memq (nth 1 lo) '(2 3)))
- (nth 3 lo) (and (or (memq (nth 1 b) '(2 3))
- (and (math-infinitep (nth 3 lo))
- (not (math-zerop (nth 2 b)))))
- (memq (nth 1 lo) '(1 3)))
- (nth 2 hi) (and (or (memq (nth 1 b) '(1 3))
- (and (math-infinitep (nth 2 hi))
- (not (math-zerop (nth 3 b)))))
- (memq (nth 1 hi) '(2 3)))
- (nth 3 hi) (and (or (memq (nth 1 b) '(1 3))
- (and (math-infinitep (nth 3 hi))
- (not (math-zerop (nth 3 b)))))
- (memq (nth 1 hi) '(1 3)))))
- (if (or (Math-negp (nth 3 b))
- (and (Math-zerop (nth 3 b)) (or (memq (nth 1 b) '(0 2))
- calc-infinite-mode)))
- (math-neg (math-div a (math-neg b)))
- (if calc-infinite-mode
- '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
- (math-reject-arg b "*Division by zero")))))
- ((and (eq (car-safe a) 'mod)
- (eq (car-safe b) 'mod)
- (equal (nth 2 a) (nth 2 b)))
- (math-make-mod (math-div-mod (nth 1 a) (nth 1 b) (nth 2 a))
- (nth 2 a)))
- ((and (eq (car-safe a) 'mod)
- (Math-anglep b))
- (math-make-mod (math-div-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
- ((and (eq (car-safe b) 'mod)
- (Math-anglep a))
- (math-make-mod (math-div-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
- ((eq (car-safe a) 'hms)
- (if (eq (car-safe b) 'hms)
- (math-with-extra-prec 1
- (math-div (math-from-hms a 'deg)
- (math-from-hms b 'deg)))
- (math-with-extra-prec 2
- (math-to-hms (math-div (math-from-hms a 'deg) b) 'deg))))
- (t (calc-record-why "*Incompatible arguments for /" a b))))
- (defun math-div-by-zero (a b)
- (if (math-infinitep a)
- (if (or (equal a '(var nan var-nan))
- (equal b '(var uinf var-uinf))
- (memq calc-infinite-mode '(-1 1)))
- a
- '(var uinf var-uinf))
- (if calc-infinite-mode
- (if (math-zerop a)
- '(var nan var-nan)
- (if (eq calc-infinite-mode 1)
- (math-mul a '(var inf var-inf))
- (if (eq calc-infinite-mode -1)
- (math-mul a '(neg (var inf var-inf)))
- (if (eq (car-safe a) 'intv)
- '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
- '(var uinf var-uinf)))))
- (math-reject-arg a "*Division by zero"))))
- (defun math-div-zero (a b)
- (if (math-known-matrixp b)
- (if (math-vectorp b)
- (math-map-vec-2 'math-div a b)
- (math-mimic-ident 0 b))
- (if (equal b '(var nan var-nan))
- b
- (if (and (eq (car-safe b) 'intv) (math-intv-constp b)
- (not (math-posp b)) (not (math-negp b)))
- (if calc-infinite-mode
- (list 'intv 3
- (if (and (math-zerop (nth 2 b))
- (memq calc-infinite-mode '(1 -1)))
- (nth 2 b) '(neg (var inf var-inf)))
- (if (and (math-zerop (nth 3 b))
- (memq calc-infinite-mode '(1 -1)))
- (nth 3 b) '(var inf var-inf)))
- (math-reject-arg b "*Division by zero"))
- a))))
- ;; For math-div-symb-fancy
- (defvar math-trig-inverses
- '((calcFunc-sin . calcFunc-csc)
- (calcFunc-cos . calcFunc-sec)
- (calcFunc-tan . calcFunc-cot)
- (calcFunc-sec . calcFunc-cos)
- (calcFunc-csc . calcFunc-sin)
- (calcFunc-cot . calcFunc-tan)
- (calcFunc-sinh . calcFunc-csch)
- (calcFunc-cosh . calcFunc-sech)
- (calcFunc-tanh . calcFunc-coth)
- (calcFunc-sech . calcFunc-cosh)
- (calcFunc-csch . calcFunc-sinh)
- (calcFunc-coth . calcFunc-tanh)))
- (defvar math-div-trig)
- (defvar math-div-non-trig)
- (defun math-div-new-trig (tr)
- (if math-div-trig
- (setq math-div-trig
- (list '* tr math-div-trig))
- (setq math-div-trig tr)))
- (defun math-div-new-non-trig (ntr)
- (if math-div-non-trig
- (setq math-div-non-trig
- (list '* ntr math-div-non-trig))
- (setq math-div-non-trig ntr)))
- (defun math-div-isolate-trig (expr)
- (if (eq (car-safe expr) '*)
- (progn
- (math-div-isolate-trig-term (nth 1 expr))
- (math-div-isolate-trig (nth 2 expr)))
- (math-div-isolate-trig-term expr)))
- (defun math-div-isolate-trig-term (term)
- (let ((fn (assoc (car-safe term) math-trig-inverses)))
- (if fn
- (math-div-new-trig
- (cons (cdr fn) (cdr term)))
- (math-div-new-non-trig term))))
- (defun math-div-symb-fancy (a b)
- (or (and (math-known-matrixp b)
- (math-mul a (math-pow b -1)))
- (and math-simplify-only
- (not (equal a math-simplify-only))
- (list '/ a b))
- (and (Math-equal-int b 1) a)
- (and (Math-equal-int b -1) (math-neg a))
- (and (Math-vectorp a) (math-known-scalarp b)
- (math-map-vec-2 'math-div a b))
- (and (eq (car-safe b) '^)
- (or (Math-looks-negp (nth 2 b)) (Math-equal-int a 1))
- (math-mul a (math-normalize
- (list '^ (nth 1 b) (math-neg (nth 2 b))))))
- (and (eq (car-safe a) 'neg)
- (math-neg (math-div (nth 1 a) b)))
- (and (eq (car-safe b) 'neg)
- (math-neg (math-div a (nth 1 b))))
- (and (eq (car-safe a) '/)
- (math-div (nth 1 a) (math-mul (nth 2 a) b)))
- (and (eq (car-safe b) '/)
- (or (math-known-scalarp (nth 1 b) t)
- (math-known-scalarp (nth 2 b) t))
- (math-div (math-mul a (nth 2 b)) (nth 1 b)))
- (and (eq (car-safe b) 'frac)
- (math-mul (math-make-frac (nth 2 b) (nth 1 b)) a))
- (and (eq (car-safe a) '+)
- (or (Math-numberp (nth 1 a))
- (Math-numberp (nth 2 a)))
- (Math-numberp b)
- (math-add (math-div (nth 1 a) b)
- (math-div (nth 2 a) b)))
- (and (eq (car-safe a) '-)
- (or (Math-numberp (nth 1 a))
- (Math-numberp (nth 2 a)))
- (Math-numberp b)
- (math-sub (math-div (nth 1 a) b)
- (math-div (nth 2 a) b)))
- (and (or (eq (car-safe a) '-)
- (math-looks-negp a))
- (math-looks-negp b)
- (math-div (math-neg a) (math-neg b)))
- (and (eq (car-safe b) '-)
- (math-looks-negp a)
- (math-div (math-neg a) (math-neg b)))
- (and (eq (car-safe a) 'calcFunc-idn)
- (= (length a) 2)
- (or (and (eq (car-safe b) 'calcFunc-idn)
- (= (length b) 2)
- (list 'calcFunc-idn (math-div (nth 1 a) (nth 1 b))))
- (and (math-known-scalarp b)
- (list 'calcFunc-idn (math-div (nth 1 a) b)))
- (and (math-known-matrixp b)
- (math-div (nth 1 a) b))))
- (and (eq (car-safe b) 'calcFunc-idn)
- (= (length b) 2)
- (or (and (math-known-scalarp a)
- (list 'calcFunc-idn (math-div a (nth 1 b))))
- (and (math-known-matrixp a)
- (math-div a (nth 1 b)))))
- (and math-simplifying
- (let ((math-div-trig nil)
- (math-div-non-trig nil))
- (math-div-isolate-trig b)
- (if math-div-trig
- (if math-div-non-trig
- (math-div (math-mul a math-div-trig) math-div-non-trig)
- (math-mul a math-div-trig))
- nil)))
- (if (and calc-matrix-mode
- (or (math-known-matrixp a) (math-known-matrixp b)))
- (math-combine-prod a b nil t nil)
- (if (eq (car-safe a) '*)
- (if (eq (car-safe b) '*)
- (let ((c (math-combine-prod (nth 1 a) (nth 1 b) nil t t)))
- (and c
- (math-div (math-mul c (nth 2 a)) (nth 2 b))))
- (let ((c (math-combine-prod (nth 1 a) b nil t t)))
- (and c
- (math-mul c (nth 2 a)))))
- (if (eq (car-safe b) '*)
- (let ((c (math-combine-prod a (nth 1 b) nil t t)))
- (and c
- (math-div c (nth 2 b))))
- (math-combine-prod a b nil t nil))))
- (and (math-infinitep a)
- (if (math-infinitep b)
- '(var nan var-nan)
- (if (or (equal a '(var nan var-nan))
- (equal a '(var uinf var-uinf)))
- a
- (if (equal a '(var inf var-inf))
- (if (or (math-posp b)
- (and (eq (car-safe b) 'intv)
- (math-zerop (nth 2 b))))
- (if (and (eq (car-safe b) 'intv)
- (not (math-intv-constp b t)))
- '(intv 3 0 (var inf var-inf))
- a)
- (if (or (math-negp b)
- (and (eq (car-safe b) 'intv)
- (math-zerop (nth 3 b))))
- (if (and (eq (car-safe b) 'intv)
- (not (math-intv-constp b t)))
- '(intv 3 (neg (var inf var-inf)) 0)
- (math-neg a))
- (if (and (eq (car-safe b) 'intv)
- (math-negp (nth 2 b)) (math-posp (nth 3 b)))
- '(intv 3 (neg (var inf var-inf))
- (var inf var-inf)))))))))
- (and (math-infinitep b)
- (if (equal b '(var nan var-nan))
- b
- (let ((calc-infinite-mode 1))
- (math-mul-zero b a))))
- (list '/ a b)))
- ;;; Division from the left.
- (defun calcFunc-ldiv (a b)
- (if (math-known-scalarp a)
- (math-div b a)
- (math-mul (math-pow a -1) b)))
- (defun calcFunc-mod (a b)
- (math-normalize (list '% a b)))
- (defun math-mod-fancy (a b)
- (cond ((equal b '(var inf var-inf))
- (if (or (math-posp a) (math-zerop a))
- a
- (if (math-negp a)
- b
- (if (eq (car-safe a) 'intv)
- (if (math-negp (nth 2 a))
- '(intv 3 0 (var inf var-inf))
- a)
- (list '% a b)))))
- ((and (eq (car-safe a) 'mod) (Math-realp b) (math-posp b))
- (math-make-mod (nth 1 a) b))
- ((and (eq (car-safe a) 'intv) (math-intv-constp a t) (math-posp b))
- (math-mod-intv a b))
- (t
- (if (Math-anglep a)
- (calc-record-why 'anglep b)
- (calc-record-why 'anglep a))
- (list '% a b))))
- (defun calcFunc-pow (a b)
- (math-normalize (list '^ a b)))
- (defun math-pow-of-zero (a b)
- "Raise A to the power of B, where A is a form of zero."
- (if (math-floatp b) (setq a (math-float a)))
- (cond
- ;; 0^0 = 1
- ((eq b 0)
- 1)
- ;; 0^0.0, etc., are undetermined
- ((Math-zerop b)
- (if calc-infinite-mode
- '(var nan var-nan)
- (math-reject-arg (list '^ a b) "*Indeterminate form")))
- ;; 0^positive = 0
- ((math-known-posp b)
- a)
- ;; 0^negative is undefined (let math-div handle it)
- ((math-known-negp b)
- (math-div 1 a))
- ;; 0^infinity is undefined
- ((math-infinitep b)
- '(var nan var-nan))
- ;; Some intervals
- ((and (eq (car b) 'intv)
- calc-infinite-mode
- (math-negp (nth 2 b))
- (math-posp (nth 3 b)))
- '(intv 3 (neg (var inf var-inf)) (var inf var-inf)))
- ;; If none of the above, leave it alone.
- (t
- (list '^ a b))))
- (defun math-pow-zero (a b)
- (if (eq (car-safe a) 'mod)
- (math-make-mod 1 (nth 2 a))
- (if (math-known-matrixp a)
- (math-mimic-ident 1 a)
- (if (math-infinitep a)
- '(var nan var-nan)
- (if (and (eq (car a) 'intv) (math-intv-constp a)
- (or (and (not (math-posp a)) (not (math-negp a)))
- (not (math-intv-constp a t))))
- '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
- (if (or (math-floatp a) (math-floatp b))
- '(float 1 0) 1))))))
- (defun math-pow-fancy (a b)
- (cond ((and (Math-numberp a) (Math-numberp b))
- (or (if (memq (math-quarter-integer b) '(1 2 3))
- (let ((sqrt (math-sqrt (if (math-floatp b)
- (math-float a) a))))
- (and (Math-numberp sqrt)
- (math-pow sqrt (math-mul 2 b))))
- (and (eq (car b) 'frac)
- (integerp (nth 2 b))
- (<= (nth 2 b) 10)
- (let ((root (math-nth-root a (nth 2 b))))
- (and root (math-ipow root (nth 1 b))))))
- (and (or (eq a 10) (equal a '(float 1 1)))
- (math-num-integerp b)
- (calcFunc-scf '(float 1 0) b))
- (and calc-symbolic-mode
- (list '^ a b))
- (math-with-extra-prec 2
- (math-exp-raw
- (math-float (math-mul b (math-ln-raw (math-float a))))))))
- ((or (not (Math-objvecp a))
- (not (Math-objectp b)))
- (let (temp)
- (cond ((and math-simplify-only
- (not (equal a math-simplify-only)))
- (list '^ a b))
- ((and (eq (car-safe a) '*)
- (or
- (and
- (math-known-matrixp (nth 1 a))
- (math-known-matrixp (nth 2 a)))
- (and
- calc-matrix-mode
- (not (eq calc-matrix-mode 'scalar))
- (and (not (math-known-scalarp (nth 1 a)))
- (not (math-known-scalarp (nth 2 a)))))))
- (if (and (= b -1)
- (math-known-square-matrixp (nth 1 a))
- (math-known-square-matrixp (nth 2 a)))
- (math-mul (math-pow-fancy (nth 2 a) -1)
- (math-pow-fancy (nth 1 a) -1))
- (list '^ a b)))
- ((and (eq (car-safe a) '*)
- (or (math-known-num-integerp b)
- (math-known-nonnegp (nth 1 a))
- (math-known-nonnegp (nth 2 a))))
- (math-mul (math-pow (nth 1 a) b)
- (math-pow (nth 2 a) b)))
- ((and (eq (car-safe a) '/)
- (or (math-known-num-integerp b)
- (math-known-nonnegp (nth 2 a))))
- (math-div (math-pow (nth 1 a) b)
- (math-pow (nth 2 a) b)))
- ((and (eq (car-safe a) '/)
- (math-known-nonnegp (nth 1 a))
- (not (math-equal-int (nth 1 a) 1)))
- (math-mul (math-pow (nth 1 a) b)
- (math-pow (math-div 1 (nth 2 a)) b)))
- ((and (eq (car-safe a) '^)
- (or (math-known-num-integerp b)
- (math-known-nonnegp (nth 1 a))))
- (math-pow (nth 1 a) (math-mul (nth 2 a) b)))
- ((and (eq (car-safe a) 'calcFunc-sqrt)
- (or (math-known-num-integerp b)
- (math-known-nonnegp (nth 1 a))))
- (math-pow (nth 1 a) (math-div b 2)))
- ((and (eq (car-safe a) '^)
- (math-known-evenp (nth 2 a))
- (memq (math-quarter-integer b) '(1 2 3))
- (math-known-realp (nth 1 a)))
- (math-abs (math-pow (nth 1 a) (math-mul (nth 2 a) b))))
- ((and (math-looks-negp a)
- (math-known-integerp b)
- (setq temp (or (and (math-known-evenp b)
- (math-pow (math-neg a) b))
- (and (math-known-oddp b)
- (math-neg (math-pow (math-neg a)
- b))))))
- temp)
- ((and (eq (car-safe a) 'calcFunc-abs)
- (math-known-realp (nth 1 a))
- (math-known-evenp b))
- (math-pow (nth 1 a) b))
- ((math-infinitep a)
- (cond ((equal a '(var nan var-nan))
- a)
- ((eq (car a) 'neg)
- (math-mul (math-pow -1 b) (math-pow (nth 1 a) b)))
- ((math-posp b)
- a)
- ((math-negp b)
- (if (math-floatp b) '(float 0 0) 0))
- ((and (eq (car-safe b) 'intv)
- (math-intv-constp b))
- '(intv 3 0 (var inf var-inf)))
- (t
- '(var nan var-nan))))
- ((math-infinitep b)
- (let (scale)
- (cond ((math-negp b)
- (math-pow (math-div 1 a) (math-neg b)))
- ((not (math-posp b))
- '(var nan var-nan))
- ((math-equal-int (setq scale (calcFunc-abssqr a)) 1)
- '(var nan var-nan))
- ((Math-lessp scale 1)
- (if (math-floatp a) '(float 0 0) 0))
- ((Math-lessp 1 a)
- b)
- ((Math-lessp a -1)
- '(var uinf var-uinf))
- ((and (eq (car a) 'intv)
- (math-intv-constp a))
- (if (Math-lessp -1 a)
- (if (math-equal-int (nth 3 a) 1)
- '(intv 3 0 1)
- '(intv 3 0 (var inf var-inf)))
- '(intv 3 (neg (var inf var-inf))
- (var inf var-inf))))
- (t (list '^ a b)))))
- ((and (eq (car-safe a) 'calcFunc-idn)
- (= (length a) 2)
- (math-known-num-integerp b))
- (list 'calcFunc-idn (math-pow (nth 1 a) b)))
- (t (if (Math-objectp a)
- (calc-record-why 'objectp b)
- (calc-record-why 'objectp a))
- (list '^ a b)))))
- ((and (eq (car-safe a) 'sdev) (eq (car-safe b) 'sdev))
- (if (and (math-constp a) (math-constp b))
- (math-with-extra-prec 2
- (let* ((ln (math-ln-raw (math-float (nth 1 a))))
- (pow (math-exp-raw
- (math-float (math-mul (nth 1 b) ln)))))
- (math-make-sdev
- pow
- (math-mul
- pow
- (math-hypot (math-mul (nth 2 a)
- (math-div (nth 1 b) (nth 1 a)))
- (math-mul (nth 2 b) ln))))))
- (let ((pow (math-pow (nth 1 a) (nth 1 b))))
- (math-make-sdev
- pow
- (math-mul pow
- (math-hypot (math-mul (nth 2 a)
- (math-div (nth 1 b) (nth 1 a)))
- (math-mul (nth 2 b) (calcFunc-ln
- (nth 1 a)))))))))
- ((and (eq (car-safe a) 'sdev) (Math-numberp b))
- (if (math-constp a)
- (math-with-extra-prec 2
- (let ((pow (math-pow (nth 1 a) (math-sub b 1))))
- (math-make-sdev (math-mul pow (nth 1 a))
- (math-mul pow (math-mul (nth 2 a) b)))))
- (math-make-sdev (math-pow (nth 1 a) b)
- (math-mul (math-pow (nth 1 a) (math-add b -1))
- (math-mul (nth 2 a) b)))))
- ((and (eq (car-safe b) 'sdev) (Math-numberp a))
- (math-with-extra-prec 2
- (let* ((ln (math-ln-raw (math-float a)))
- (pow (calcFunc-exp (math-mul (nth 1 b) ln))))
- (math-make-sdev pow (math-mul pow (math-mul (nth 2 b) ln))))))
- ((and (eq (car-safe a) 'intv) (math-intv-constp a)
- (Math-realp b)
- (or (Math-natnump b)
- (Math-posp (nth 2 a))
- (and (math-zerop (nth 2 a))
- (or (Math-posp b)
- (and (Math-integerp b) calc-infinite-mode)))
- (Math-negp (nth 3 a))
- (and (math-zerop (nth 3 a))
- (or (Math-posp b)
- (and (Math-integerp b) calc-infinite-mode)))))
- (if (math-evenp b)
- (setq a (math-abs a)))
- (let ((calc-infinite-mode (if (math-zerop (nth 3 a)) -1 1)))
- (math-sort-intv (nth 1 a)
- (math-pow (nth 2 a) b)
- (math-pow (nth 3 a) b))))
- ((and (eq (car-safe b) 'intv) (math-intv-constp b)
- (Math-realp a) (Math-posp a))
- (math-sort-intv (nth 1 b)
- (math-pow a (nth 2 b))
- (math-pow a (nth 3 b))))
- ((and (eq (car-safe a) 'intv) (math-intv-constp a)
- (eq (car-safe b) 'intv) (math-intv-constp b)
- (or (and (not (Math-negp (nth 2 a)))
- (not (Math-negp (nth 2 b))))
- (and (Math-posp (nth 2 a))
- (not (Math-posp (nth 3 b))))))
- (let ((lo (math-pow a (nth 2 b)))
- (hi (math-pow a (nth 3 b))))
- (or (eq (car-safe lo) 'intv)
- (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0) lo lo)))
- (or (eq (car-safe hi) 'intv)
- (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0) hi hi)))
- (math-combine-intervals
- (nth 2 lo) (and (or (memq (nth 1 b) '(2 3))
- (math-infinitep (nth 2 lo)))
- (memq (nth 1 lo) '(2 3)))
- (nth 3 lo) (and (or (memq (nth 1 b) '(2 3))
- (math-infinitep (nth 3 lo)))
- (memq (nth 1 lo) '(1 3)))
- (nth 2 hi) (and (or (memq (nth 1 b) '(1 3))
- (math-infinitep (nth 2 hi)))
- (memq (nth 1 hi) '(2 3)))
- (nth 3 hi) (and (or (memq (nth 1 b) '(1 3))
- (math-infinitep (nth 3 hi)))
- (memq (nth 1 hi) '(1 3))))))
- ((and (eq (car-safe a) 'mod) (eq (car-safe b) 'mod)
- (equal (nth 2 a) (nth 2 b)))
- (math-make-mod (math-pow-mod (nth 1 a) (nth 1 b) (nth 2 a))
- (nth 2 a)))
- ((and (eq (car-safe a) 'mod) (Math-anglep b))
- (math-make-mod (math-pow-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
- ((and (eq (car-safe b) 'mod) (Math-anglep a))
- (math-make-mod (math-pow-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
- ((not (Math-numberp a))
- (math-reject-arg a 'numberp))
- (t
- (math-reject-arg b 'numberp))))
- (defun math-quarter-integer (x)
- (if (Math-integerp x)
- 0
- (if (math-negp x)
- (progn
- (setq x (math-quarter-integer (math-neg x)))
- (and x (- 4 x)))
- (if (eq (car x) 'frac)
- (if (eq (nth 2 x) 2)
- 2
- (and (eq (nth 2 x) 4)
- (progn
- (setq x (nth 1 x))
- (% (if (consp x) (nth 1 x) x) 4))))
- (if (eq (car x) 'float)
- (if (>= (nth 2 x) 0)
- 0
- (if (= (nth 2 x) -1)
- (progn
- (setq x (nth 1 x))
- (and (= (% (if (consp x) (nth 1 x) x) 10) 5) 2))
- (if (= (nth 2 x) -2)
- (progn
- (setq x (nth 1 x)
- x (% (if (consp x) (nth 1 x) x) 100))
- (if (= x 25) 1
- (if (= x 75) 3)))))))))))
- ;;; This assumes A < M and M > 0.
- (defun math-pow-mod (a b m) ; [R R R R]
- (if (and (Math-integerp a) (Math-integerp b) (Math-integerp m))
- (if (Math-negp b)
- (math-div-mod 1 (math-pow-mod a (Math-integer-neg b) m) m)
- (if (eq m 1)
- 0
- (math-pow-mod-step a b m)))
- (math-mod (math-pow a b) m)))
- (defun math-pow-mod-step (a n m) ; [I I I I]
- (math-working "pow" a)
- (let ((val (cond
- ((eq n 0) 1)
- ((eq n 1) a)
- (t
- (let ((rest (math-pow-mod-step
- (math-imod (math-mul a a) m)
- (math-div2 n)
- m)))
- (if (math-evenp n)
- rest
- (math-mod (math-mul a rest) m)))))))
- (math-working "pow" val)
- val))
- ;;; Compute the minimum of two real numbers. [R R R] [Public]
- (defun math-min (a b)
- (if (and (consp a) (eq (car a) 'intv))
- (if (and (consp b) (eq (car b) 'intv))
- (let ((lo (nth 2 a))
- (lom (memq (nth 1 a) '(2 3)))
- (hi (nth 3 a))
- (him (memq (nth 1 a) '(1 3)))
- res)
- (if (= (setq res (math-compare (nth 2 b) lo)) -1)
- (setq lo (nth 2 b) lom (memq (nth 1 b) '(2 3)))
- (if (= res 0)
- (setq lom (or lom (memq (nth 1 b) '(2 3))))))
- (if (= (setq res (math-compare (nth 3 b) hi)) -1)
- (setq hi (nth 3 b) him (memq (nth 1 b) '(1 3)))
- (if (= res 0)
- (setq him (or him (memq (nth 1 b) '(1 3))))))
- (math-make-intv (+ (if lom 2 0) (if him 1 0)) lo hi))
- (math-min a (list 'intv 3 b b)))
- (if (and (consp b) (eq (car b) 'intv))
- (math-min (list 'intv 3 a a) b)
- (let ((res (math-compare a b)))
- (if (= res 1)
- b
- (if (= res 2)
- '(var nan var-nan)
- a))))))
- (defun calcFunc-min (&optional a &rest b)
- (if (not a)
- '(var inf var-inf)
- (if (not (or (Math-anglep a) (eq (car a) 'date)
- (and (eq (car a) 'intv) (math-intv-constp a))
- (math-infinitep a)))
- (math-reject-arg a 'anglep))
- (math-min-list a b)))
- (defun math-min-list (a b)
- (if b
- (if (or (Math-anglep (car b)) (eq (car b) 'date)
- (and (eq (car (car b)) 'intv) (math-intv-constp (car b)))
- (math-infinitep (car b)))
- (math-min-list (math-min a (car b)) (cdr b))
- (math-reject-arg (car b) 'anglep))
- a))
- ;;; Compute the maximum of two real numbers. [R R R] [Public]
- (defun math-max (a b)
- (if (or (and (consp a) (eq (car a) 'intv))
- (and (consp b) (eq (car b) 'intv)))
- (math-neg (math-min (math-neg a) (math-neg b)))
- (let ((res (math-compare a b)))
- (if (= res -1)
- b
- (if (= res 2)
- '(var nan var-nan)
- a)))))
- (defun calcFunc-max (&optional a &rest b)
- (if (not a)
- '(neg (var inf var-inf))
- (if (not (or (Math-anglep a) (eq (car a) 'date)
- (and (eq (car a) 'intv) (math-intv-constp a))
- (math-infinitep a)))
- (math-reject-arg a 'anglep))
- (math-max-list a b)))
- (defun math-max-list (a b)
- (if b
- (if (or (Math-anglep (car b)) (eq (car b) 'date)
- (and (eq (car (car b)) 'intv) (math-intv-constp (car b)))
- (math-infinitep (car b)))
- (math-max-list (math-max a (car b)) (cdr b))
- (math-reject-arg (car b) 'anglep))
- a))
- ;;; Compute the absolute value of A. [O O; r r] [Public]
- (defun math-abs (a)
- (cond ((Math-negp a)
- (math-neg a))
- ((Math-anglep a)
- a)
- ((eq (car a) 'cplx)
- (math-hypot (nth 1 a) (nth 2 a)))
- ((eq (car a) 'polar)
- (nth 1 a))
- ((eq (car a) 'vec)
- (if (cdr (cdr (cdr a)))
- (math-sqrt (calcFunc-abssqr a))
- (if (cdr (cdr a))
- (math-hypot (nth 1 a) (nth 2 a))
- (if (cdr a)
- (math-abs (nth 1 a))
- a))))
- ((eq (car a) 'sdev)
- (list 'sdev (math-abs (nth 1 a)) (nth 2 a)))
- ((and (eq (car a) 'intv) (math-intv-constp a))
- (if (Math-posp a)
- a
- (let* ((nlo (math-neg (nth 2 a)))
- (res (math-compare nlo (nth 3 a))))
- (cond ((= res 1)
- (math-make-intv (if (memq (nth 1 a) '(0 1)) 2 3) 0 nlo))
- ((= res 0)
- (math-make-intv (if (eq (nth 1 a) 0) 2 3) 0 nlo))
- (t
- (math-make-intv (if (memq (nth 1 a) '(0 2)) 2 3)
- 0 (nth 3 a)))))))
- ((math-looks-negp a)
- (list 'calcFunc-abs (math-neg a)))
- ((let ((signs (math-possible-signs a)))
- (or (and (memq signs '(2 4 6)) a)
- (and (memq signs '(1 3)) (math-neg a)))))
- ((let ((inf (math-infinitep a)))
- (and inf
- (if (equal inf '(var nan var-nan))
- inf
- '(var inf var-inf)))))
- (t (calc-record-why 'numvecp a)
- (list 'calcFunc-abs a))))
- (defalias 'calcFunc-abs 'math-abs)
- (defun math-float-fancy (a)
- (cond ((eq (car a) 'intv)
- (cons (car a) (cons (nth 1 a) (mapcar 'math-float (nthcdr 2 a)))))
- ((and (memq (car a) '(* /))
- (math-numberp (nth 1 a)))
- (list (car a) (math-float (nth 1 a))
- (list 'calcFunc-float (nth 2 a))))
- ((and (eq (car a) '/)
- (eq (car (nth 1 a)) '*)
- (math-numberp (nth 1 (nth 1 a))))
- (list '* (math-float (nth 1 (nth 1 a)))
- (list 'calcFunc-float (list '/ (nth 2 (nth 1 a)) (nth 2 a)))))
- ((math-infinitep a) a)
- ((eq (car a) 'calcFunc-float) a)
- ((let ((func (assq (car a) '((calcFunc-floor . calcFunc-ffloor)
- (calcFunc-ceil . calcFunc-fceil)
- (calcFunc-trunc . calcFunc-ftrunc)
- (calcFunc-round . calcFunc-fround)
- (calcFunc-rounde . calcFunc-frounde)
- (calcFunc-roundu . calcFunc-froundu)))))
- (and func (cons (cdr func) (cdr a)))))
- (t (math-reject-arg a 'objectp))))
- (defalias 'calcFunc-float 'math-float)
- ;; The variable math-trunc-prec is local to math-trunc in calc-misc.el,
- ;; but used by math-trunc-fancy which is called by math-trunc.
- (defvar math-trunc-prec)
- (defun math-trunc-fancy (a)
- (cond ((eq (car a) 'frac) (math-quotient (nth 1 a) (nth 2 a)))
- ((eq (car a) 'cplx) (math-trunc (nth 1 a)))
- ((eq (car a) 'polar) (math-trunc (math-complex a)))
- ((eq (car a) 'hms) (list 'hms (nth 1 a) 0 0))
- ((eq (car a) 'date) (list 'date (math-trunc (nth 1 a))))
- ((eq (car a) 'mod)
- (if (math-messy-integerp (nth 2 a))
- (math-trunc (math-make-mod (nth 1 a) (math-trunc (nth 2 a))))
- (math-make-mod (math-trunc (nth 1 a)) (nth 2 a))))
- ((eq (car a) 'intv)
- (math-make-intv (+ (if (and (equal (nth 2 a) '(neg (var inf var-inf)))
- (memq (nth 1 a) '(0 1)))
- 0 2)
- (if (and (equal (nth 3 a) '(var inf var-inf))
- (memq (nth 1 a) '(0 2)))
- 0 1))
- (if (and (Math-negp (nth 2 a))
- (Math-num-integerp (nth 2 a))
- (memq (nth 1 a) '(0 1)))
- (math-add (math-trunc (nth 2 a)) 1)
- (math-trunc (nth 2 a)))
- (if (and (Math-posp (nth 3 a))
- (Math-num-integerp (nth 3 a))
- (memq (nth 1 a) '(0 2)))
- (math-add (math-trunc (nth 3 a)) -1)
- (math-trunc (nth 3 a)))))
- ((math-provably-integerp a) a)
- ((Math-vectorp a)
- (math-map-vec (function (lambda (x) (math-trunc x math-trunc-prec))) a))
- ((math-infinitep a)
- (if (or (math-posp a) (math-negp a))
- a
- '(var nan var-nan)))
- ((math-to-integer a))
- (t (math-reject-arg a 'numberp))))
- (defun math-trunc-special (a prec)
- (if (Math-messy-integerp prec)
- (setq prec (math-trunc prec)))
- (or (integerp prec)
- (math-reject-arg prec 'fixnump))
- (if (and (<= prec 0)
- (math-provably-integerp a))
- a
- (calcFunc-scf (math-trunc (let ((calc-prefer-frac t))
- (calcFunc-scf a prec)))
- (- prec))))
- (defun math-to-integer (a)
- (let ((func (assq (car-safe a) '((calcFunc-ffloor . calcFunc-floor)
- (calcFunc-fceil . calcFunc-ceil)
- (calcFunc-ftrunc . calcFunc-trunc)
- (calcFunc-fround . calcFunc-round)
- (calcFunc-frounde . calcFunc-rounde)
- (calcFunc-froundu . calcFunc-roundu)))))
- (and func (= (length a) 2)
- (cons (cdr func) (cdr a)))))
- (defun calcFunc-ftrunc (a &optional prec)
- (if (and (Math-messy-integerp a)
- (or (not prec) (and (integerp prec)
- (<= prec 0))))
- a
- (math-float (math-trunc a prec))))
- ;; The variable math-floor-prec is local to math-floor in calc-misc.el,
- ;; but used by math-floor-fancy which is called by math-floor.
- (defvar math-floor-prec)
- (defun math-floor-fancy (a)
- (cond ((math-provably-integerp a) a)
- ((eq (car a) 'hms)
- (if (or (math-posp a)
- (and (math-zerop (nth 2 a))
- (math-zerop (nth 3 a))))
- (math-trunc a)
- (math-add (math-trunc a) -1)))
- ((eq (car a) 'date) (list 'date (math-floor (nth 1 a))))
- ((eq (car a) 'intv)
- (math-make-intv (+ (if (and (equal (nth 2 a) '(neg (var inf var-inf)))
- (memq (nth 1 a) '(0 1)))
- 0 2)
- (if (and (equal (nth 3 a) '(var inf var-inf))
- (memq (nth 1 a) '(0 2)))
- 0 1))
- (math-floor (nth 2 a))
- (if (and (Math-num-integerp (nth 3 a))
- (memq (nth 1 a) '(0 2)))
- (math-add (math-floor (nth 3 a)) -1)
- (math-floor (nth 3 a)))))
- ((Math-vectorp a)
- (math-map-vec (function (lambda (x) (math-floor x math-floor-prec))) a))
- ((math-infinitep a)
- (if (or (math-posp a) (math-negp a))
- a
- '(var nan var-nan)))
- ((math-to-integer a))
- (t (math-reject-arg a 'anglep))))
- (defun math-floor-special (a prec)
- (if (Math-messy-integerp prec)
- (setq prec (math-trunc prec)))
- (or (integerp prec)
- (math-reject-arg prec 'fixnump))
- (if (and (<= prec 0)
- (math-provably-integerp a))
- a
- (calcFunc-scf (math-floor (let ((calc-prefer-frac t))
- (calcFunc-scf a prec)))
- (- prec))))
- (defun calcFunc-ffloor (a &optional prec)
- (if (and (Math-messy-integerp a)
- (or (not prec) (and (integerp prec)
- (<= prec 0))))
- a
- (math-float (math-floor a prec))))
- ;;; Coerce A to be an integer (by truncation toward plus infinity). [I N]
- (defun math-ceiling (a &optional prec) ; [Public]
- (cond (prec
- (if (Math-messy-integerp prec)
- (setq prec (math-trunc prec)))
- (or (integerp prec)
- (math-reject-arg prec 'fixnump))
- (if (and (<= prec 0)
- (math-provably-integerp a))
- a
- (calcFunc-scf (math-ceiling (let ((calc-prefer-frac t))
- (calcFunc-scf a prec)))
- (- prec))))
- ((Math-integerp a) a)
- ((Math-messy-integerp a) (math-trunc a))
- ((Math-realp a)
- (if (Math-posp a)
- (math-add (math-trunc a) 1)
- (math-trunc a)))
- ((math-provably-integerp a) a)
- ((eq (car a) 'hms)
- (if (or (math-negp a)
- (and (math-zerop (nth 2 a))
- (math-zerop (nth 3 a))))
- (math-trunc a)
- (math-add (math-trunc a) 1)))
- ((eq (car a) 'date) (list 'date (math-ceiling (nth 1 a))))
- ((eq (car a) 'intv)
- (math-make-intv (+ (if (and (equal (nth 2 a) '(neg (var inf var-inf)))
- (memq (nth 1 a) '(0 1)))
- 0 2)
- (if (and (equal (nth 3 a) '(var inf var-inf))
- (memq (nth 1 a) '(0 2)))
- 0 1))
- (if (and (Math-num-integerp (nth 2 a))
- (memq (nth 1 a) '(0 1)))
- (math-add (math-floor (nth 2 a)) 1)
- (math-ceiling (nth 2 a)))
- (math-ceiling (nth 3 a))))
- ((Math-vectorp a)
- (math-map-vec (function (lambda (x) (math-ceiling x prec))) a))
- ((math-infinitep a)
- (if (or (math-posp a) (math-negp a))
- a
- '(var nan var-nan)))
- ((math-to-integer a))
- (t (math-reject-arg a 'anglep))))
- (defalias 'calcFunc-ceil 'math-ceiling)
- (defun calcFunc-fceil (a &optional prec)
- (if (and (Math-messy-integerp a)
- (or (not prec) (and (integerp prec)
- (<= prec 0))))
- a
- (math-float (math-ceiling a prec))))
- (defvar math-rounding-mode nil)
- ;;; Coerce A to be an integer (by rounding to nearest integer). [I N] [Public]
- (defun math-round (a &optional prec)
- (cond (prec
- (if (Math-messy-integerp prec)
- (setq prec (math-trunc prec)))
- (or (integerp prec)
- (math-reject-arg prec 'fixnump))
- (if (and (<= prec 0)
- (math-provably-integerp a))
- a
- (calcFunc-scf (math-round (let ((calc-prefer-frac t))
- (calcFunc-scf a prec)))
- (- prec))))
- ((Math-anglep a)
- (if (Math-num-integerp a)
- (math-trunc a)
- (if (and (Math-negp a) (not (eq math-rounding-mode 'up)))
- (math-neg (math-round (math-neg a)))
- (setq a (let ((calc-angle-mode 'deg)) ; in case of HMS forms
- (math-add a (if (Math-ratp a)
- '(frac 1 2)
- '(float 5 -1)))))
- (if (and (Math-num-integerp a) (eq math-rounding-mode 'even))
- (progn
- (setq a (math-floor a))
- (or (math-evenp a)
- (setq a (math-sub a 1)))
- a)
- (math-floor a)))))
- ((math-provably-integerp a) a)
- ((eq (car a) 'date) (list 'date (math-round (nth 1 a))))
- ((eq (car a) 'intv)
- (math-floor (math-add a '(frac 1 2))))
- ((Math-vectorp a)
- (math-map-vec (function (lambda (x) (math-round x prec))) a))
- ((math-infinitep a)
- (if (or (math-posp a) (math-negp a))
- a
- '(var nan var-nan)))
- ((math-to-integer a))
- (t (math-reject-arg a 'anglep))))
- (defalias 'calcFunc-round 'math-round)
- (defsubst calcFunc-rounde (a &optional prec)
- (let ((math-rounding-mode 'even))
- (math-round a prec)))
- (defsubst calcFunc-roundu (a &optional prec)
- (let ((math-rounding-mode 'up))
- (math-round a prec)))
- (defun calcFunc-fround (a &optional prec)
- (if (and (Math-messy-integerp a)
- (or (not prec) (and (integerp prec)
- (<= prec 0))))
- a
- (math-float (math-round a prec))))
- (defsubst calcFunc-frounde (a &optional prec)
- (let ((math-rounding-mode 'even))
- (calcFunc-fround a prec)))
- (defsubst calcFunc-froundu (a &optional prec)
- (let ((math-rounding-mode 'up))
- (calcFunc-fround a prec)))
- ;;; Pull floating-point values apart into mantissa and exponent.
- (defun calcFunc-mant (x)
- (if (Math-realp x)
- (if (or (Math-ratp x)
- (eq (nth 1 x) 0))
- x
- (list 'float (nth 1 x) (- 1 (math-numdigs (nth 1 x)))))
- (calc-record-why 'realp x)
- (list 'calcFunc-mant x)))
- (defun calcFunc-xpon (x)
- (if (Math-realp x)
- (if (or (Math-ratp x)
- (eq (nth 1 x) 0))
- 0
- (math-normalize (+ (nth 2 x) (1- (math-numdigs (nth 1 x))))))
- (calc-record-why 'realp x)
- (list 'calcFunc-xpon x)))
- (defun calcFunc-scf (x n)
- (if (integerp n)
- (cond ((eq n 0)
- x)
- ((Math-integerp x)
- (if (> n 0)
- (math-scale-int x n)
- (math-div x (math-scale-int 1 (- n)))))
- ((eq (car x) 'frac)
- (if (> n 0)
- (math-make-frac (math-scale-int (nth 1 x) n) (nth 2 x))
- (math-make-frac (nth 1 x) (math-scale-int (nth 2 x) (- n)))))
- ((eq (car x) 'float)
- (math-make-float (nth 1 x) (+ (nth 2 x) n)))
- ((memq (car x) '(cplx sdev))
- (math-normalize
- (list (car x)
- (calcFunc-scf (nth 1 x) n)
- (calcFunc-scf (nth 2 x) n))))
- ((memq (car x) '(polar mod))
- (math-normalize
- (list (car x)
- (calcFunc-scf (nth 1 x) n)
- (nth 2 x))))
- ((eq (car x) 'intv)
- (math-normalize
- (list (car x)
- (nth 1 x)
- (calcFunc-scf (nth 2 x) n)
- (calcFunc-scf (nth 3 x) n))))
- ((eq (car x) 'vec)
- (math-map-vec (function (lambda (x) (calcFunc-scf x n))) x))
- ((math-infinitep x)
- x)
- (t
- (calc-record-why 'realp x)
- (list 'calcFunc-scf x n)))
- (if (math-messy-integerp n)
- (if (< (nth 2 n) 10)
- (calcFunc-scf x (math-trunc n))
- (math-overflow n))
- (if (math-integerp n)
- (math-overflow n)
- (calc-record-why 'integerp n)
- (list 'calcFunc-scf x n)))))
- (defun calcFunc-incr (x &optional step relative-to)
- (or step (setq step 1))
- (cond ((not (Math-integerp step))
- (math-reject-arg step 'integerp))
- ((Math-integerp x)
- (math-add x step))
- ((eq (car x) 'float)
- (if (and (math-zerop x)
- (eq (car-safe relative-to) 'float))
- (math-mul step
- (calcFunc-scf relative-to (- 1 calc-internal-prec)))
- (math-add-float x (math-make-float
- step
- (+ (nth 2 x)
- (- (math-numdigs (nth 1 x))
- calc-internal-prec))))))
- ((eq (car x) 'date)
- (if (Math-integerp (nth 1 x))
- (math-add x step)
- (math-add x (list 'hms 0 0 step))))
- (t
- (math-reject-arg x 'realp))))
- (defsubst calcFunc-decr (x &optional step relative-to)
- (calcFunc-incr x (math-neg (or step 1)) relative-to))
- (defun calcFunc-percent (x)
- (if (math-objectp x)
- (let ((calc-prefer-frac nil))
- (math-div x 100))
- (list 'calcFunc-percent x)))
- (defun calcFunc-relch (x y)
- (if (and (math-objectp x) (math-objectp y))
- (math-div (math-sub y x) x)
- (list 'calcFunc-relch x y)))
- ;;; Compute the absolute value squared of A. [F N] [Public]
- (defun calcFunc-abssqr (a)
- (cond ((Math-realp a)
- (math-mul a a))
- ((eq (car a) 'cplx)
- (math-add (math-sqr (nth 1 a))
- (math-sqr (nth 2 a))))
- ((eq (car a) 'polar)
- (math-sqr (nth 1 a)))
- ((and (memq (car a) '(sdev intv)) (math-constp a))
- (math-sqr (math-abs a)))
- ((eq (car a) 'vec)
- (math-reduce-vec 'math-add (math-map-vec 'calcFunc-abssqr a)))
- ((math-known-realp a)
- (math-pow a 2))
- ((let ((inf (math-infinitep a)))
- (and inf
- (math-mul (calcFunc-abssqr (math-infinite-dir a inf)) inf))))
- (t (calc-record-why 'numvecp a)
- (list 'calcFunc-abssqr a))))
- (defsubst math-sqr (a)
- (math-mul a a))
- ;;;; Number theory.
- (defun calcFunc-idiv (a b) ; [I I I] [Public]
- (cond ((and (Math-natnump a) (Math-natnump b) (not (eq b 0)))
- (math-quotient a b))
- ((Math-realp a)
- (if (Math-realp b)
- (let ((calc-prefer-frac t))
- (math-floor (math-div a b)))
- (math-reject-arg b 'realp)))
- ((eq (car-safe a) 'hms)
- (if (eq (car-safe b) 'hms)
- (let ((calc-prefer-frac t))
- (math-floor (math-div a b)))
- (math-reject-arg b 'hmsp)))
- ((and (or (eq (car-safe a) 'intv) (Math-realp a))
- (or (eq (car-safe b) 'intv) (Math-realp b)))
- (math-floor (math-div a b)))
- ((or (math-infinitep a)
- (math-infinitep b))
- (math-div a b))
- (t (math-reject-arg a 'anglep))))
- ;;; Combine two terms being added, if possible.
- (defun math-combine-sum (a b nega negb scalar-okay)
- (if (and scalar-okay (Math-objvecp a) (Math-objvecp b))
- (math-add-or-sub a b nega negb)
- (let ((amult 1) (bmult 1))
- (and (consp a)
- (cond ((and (eq (car a) '*)
- (Math-objectp (nth 1 a)))
- (setq amult (nth 1 a)
- a (nth 2 a)))
- ((and (eq (car a) '/)
- (Math-objectp (nth 2 a)))
- (setq amult (if (Math-integerp (nth 2 a))
- (list 'frac 1 (nth 2 a))
- (math-div 1 (nth 2 a)))
- a (nth 1 a)))
- ((eq (car a) 'neg)
- (setq amult -1
- a (nth 1 a)))))
- (and (consp b)
- (cond ((and (eq (car b) '*)
- (Math-objectp (nth 1 b)))
- (setq bmult (nth 1 b)
- b (nth 2 b)))
- ((and (eq (car b) '/)
- (Math-objectp (nth 2 b)))
- (setq bmult (if (Math-integerp (nth 2 b))
- (list 'frac 1 (nth 2 b))
- (math-div 1 (nth 2 b)))
- b (nth 1 b)))
- ((eq (car b) 'neg)
- (setq bmult -1
- b (nth 1 b)))))
- (and (if math-simplifying
- (Math-equal a b)
- (equal a b))
- (progn
- (if nega (setq amult (math-neg amult)))
- (if negb (setq bmult (math-neg bmult)))
- (setq amult (math-add amult bmult))
- (math-mul amult a))))))
- (defun math-add-or-sub (a b aneg bneg)
- (if aneg (setq a (math-neg a)))
- (if bneg (setq b (math-neg b)))
- (if (or (Math-vectorp a) (Math-vectorp b))
- (math-normalize (list '+ a b))
- (math-add a b)))
- (defvar math-combine-prod-e '(var e var-e))
- ;;; The following is expanded out four ways for speed.
- ;; math-unit-prefixes is defined in calc-units.el,
- ;; but used here.
- (defvar math-unit-prefixes)
- (defun math-combine-prod (a b inva invb scalar-okay)
- (cond
- ((or (and inva (Math-zerop a))
- (and invb (Math-zerop b)))
- nil)
- ((and scalar-okay (Math-objvecp a) (Math-objvecp b))
- (setq a (math-mul-or-div a b inva invb))
- (and (Math-objvecp a)
- a))
- ((and (eq (car-safe a) '^)
- inva
- (math-looks-negp (nth 2 a)))
- (math-mul (math-pow (nth 1 a) (math-neg (nth 2 a))) b))
- ((and (eq (car-safe b) '^)
- invb
- (math-looks-negp (nth 2 b)))
- (math-mul a (math-pow (nth 1 b) (math-neg (nth 2 b)))))
- ((and math-simplifying
- (math-combine-prod-trig a b)))
- (t (let ((apow 1) (bpow 1))
- (and (consp a)
- (cond ((and (eq (car a) '^)
- (or math-simplifying
- (Math-numberp (nth 2 a))))
- (setq apow (nth 2 a)
- a (nth 1 a)))
- ((eq (car a) 'calcFunc-sqrt)
- (setq apow '(frac 1 2)
- a (nth 1 a)))
- ((and (eq (car a) 'calcFunc-exp)
- (or math-simplifying
- (Math-numberp (nth 1 a))))
- (setq apow (nth 1 a)
- a math-combine-prod-e))))
- (and (consp a) (eq (car a) 'frac)
- (Math-lessp (nth 1 a) (nth 2 a))
- (setq a (math-div 1 a) apow (math-neg apow)))
- (and (consp b)
- (cond ((and (eq (car b) '^)
- (or math-simplifying
- (Math-numberp (nth 2 b))))
- (setq bpow (nth 2 b)
- b (nth 1 b)))
- ((eq (car b) 'calcFunc-sqrt)
- (setq bpow '(frac 1 2)
- b (nth 1 b)))
- ((and (eq (car b) 'calcFunc-exp)
- (or math-simplifying
- (Math-numberp (nth 1 b))))
- (setq bpow (nth 1 b)
- b math-combine-prod-e))))
- (and (consp b) (eq (car b) 'frac)
- (Math-lessp (nth 1 b) (nth 2 b))
- (setq b (math-div 1 b) bpow (math-neg bpow)))
- (if inva (setq apow (math-neg apow)))
- (if invb (setq bpow (math-neg bpow)))
- (or (and (if math-simplifying
- (math-commutative-equal a b)
- (equal a b))
- (let ((sumpow (math-add apow bpow)))
- (and (or (not (Math-integerp a))
- (Math-zerop sumpow)
- (eq (eq (car-safe apow) 'frac)
- (eq (car-safe bpow) 'frac)))
- (progn
- (and (math-looks-negp sumpow)
- (Math-ratp a) (Math-posp a)
- (setq a (math-div 1 a)
- sumpow (math-neg sumpow)))
- (cond ((equal sumpow '(frac 1 2))
- (list 'calcFunc-sqrt a))
- ((equal sumpow '(frac -1 2))
- (math-div 1 (list 'calcFunc-sqrt a)))
- ((and (eq a math-combine-prod-e)
- (eq a b))
- (list 'calcFunc-exp sumpow))
- (t
- (condition-case err
- (math-pow a sumpow)
- (inexact-result (list '^ a sumpow)))))))))
- (and math-simplifying-units
- math-combining-units
- (let* ((ua (math-check-unit-name a))
- ub)
- (and ua
- (eq ua (setq ub (math-check-unit-name b)))
- (progn
- (setq ua (if (eq (nth 1 a) (car ua))
- 1
- (nth 1 (assq (aref (symbol-name (nth 1 a))
- 0)
- math-unit-prefixes)))
- ub (if (eq (nth 1 b) (car ub))
- 1
- (nth 1 (assq (aref (symbol-name (nth 1 b))
- 0)
- math-unit-prefixes))))
- (if (Math-lessp ua ub)
- (let (temp)
- (setq temp a a b b temp
- temp ua ua ub ub temp
- temp apow apow bpow bpow temp)))
- (math-mul (math-pow (math-div ua ub) apow)
- (math-pow b (math-add apow bpow)))))))
- (and (equal apow bpow)
- (Math-natnump a) (Math-natnump b)
- (cond ((equal apow '(frac 1 2))
- (list 'calcFunc-sqrt (math-mul a b)))
- ((equal apow '(frac -1 2))
- (math-div 1 (list 'calcFunc-sqrt (math-mul a b))))
- (t
- (setq a (math-mul a b))
- (condition-case err
- (math-pow a apow)
- (inexact-result (list '^ a apow)))))))))))
- (defun math-combine-prod-trig (a b)
- (cond
- ((and (eq (car-safe a) 'calcFunc-sin)
- (eq (car-safe b) 'calcFunc-csc)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- 1)
- ((and (eq (car-safe a) 'calcFunc-sin)
- (eq (car-safe b) 'calcFunc-sec)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-tan (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-sin)
- (eq (car-safe b) 'calcFunc-cot)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-cos (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-cos)
- (eq (car-safe b) 'calcFunc-sec)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- 1)
- ((and (eq (car-safe a) 'calcFunc-cos)
- (eq (car-safe b) 'calcFunc-csc)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-cot (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-cos)
- (eq (car-safe b) 'calcFunc-tan)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-sin (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-tan)
- (eq (car-safe b) 'calcFunc-cot)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- 1)
- ((and (eq (car-safe a) 'calcFunc-tan)
- (eq (car-safe b) 'calcFunc-csc)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-sec (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-sec)
- (eq (car-safe b) 'calcFunc-cot)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-csc (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-sinh)
- (eq (car-safe b) 'calcFunc-csch)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- 1)
- ((and (eq (car-safe a) 'calcFunc-sinh)
- (eq (car-safe b) 'calcFunc-sech)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-tanh (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-sinh)
- (eq (car-safe b) 'calcFunc-coth)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-cosh (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-cosh)
- (eq (car-safe b) 'calcFunc-sech)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- 1)
- ((and (eq (car-safe a) 'calcFunc-cosh)
- (eq (car-safe b) 'calcFunc-csch)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-coth (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-cosh)
- (eq (car-safe b) 'calcFunc-tanh)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-sinh (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-tanh)
- (eq (car-safe b) 'calcFunc-coth)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- 1)
- ((and (eq (car-safe a) 'calcFunc-tanh)
- (eq (car-safe b) 'calcFunc-csch)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-sech (cdr a)))
- ((and (eq (car-safe a) 'calcFunc-sech)
- (eq (car-safe b) 'calcFunc-coth)
- (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
- (cons 'calcFunc-csch (cdr a)))
- (t
- nil)))
- (defun math-mul-or-div (a b ainv binv)
- (if (or (Math-vectorp a) (Math-vectorp b))
- (math-normalize
- (if ainv
- (if binv
- (list '/ (math-div 1 a) b)
- (list '/ b a))
- (if binv
- (list '/ a b)
- (list '* a b))))
- (if ainv
- (if binv
- (math-div (math-div 1 a) b)
- (math-div b a))
- (if binv
- (math-div a b)
- (math-mul a b)))))
- ;; The variable math-com-bterms is local to math-commutative-equal,
- ;; but is used by math-commutative collect, which is called by
- ;; math-commutative-equal.
- (defvar math-com-bterms)
- (defun math-commutative-equal (a b)
- (if (memq (car-safe a) '(+ -))
- (and (memq (car-safe b) '(+ -))
- (let ((math-com-bterms nil) aterms p)
- (math-commutative-collect b nil)
- (setq aterms math-com-bterms math-com-bterms nil)
- (math-commutative-collect a nil)
- (and (= (length aterms) (length math-com-bterms))
- (progn
- (while (and aterms
- (progn
- (setq p math-com-bterms)
- (while (and p (not (equal (car aterms)
- (car p))))
- (setq p (cdr p)))
- p))
- (setq math-com-bterms (delq (car p) math-com-bterms)
- aterms (cdr aterms)))
- (not aterms)))))
- (equal a b)))
- (defun math-commutative-collect (b neg)
- (if (eq (car-safe b) '+)
- (progn
- (math-commutative-collect (nth 1 b) neg)
- (math-commutative-collect (nth 2 b) neg))
- (if (eq (car-safe b) '-)
- (progn
- (math-commutative-collect (nth 1 b) neg)
- (math-commutative-collect (nth 2 b) (not neg)))
- (setq math-com-bterms (cons (if neg (math-neg b) b) math-com-bterms)))))
- (provide 'calc-arith)
- ;;; calc-arith.el ends here
|