123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069 |
- ;;; calc-arith.el --- arithmetic functions for Calc
- ;; Copyright (C) 1990-1993, 2001-2017 Free Software Foundation, Inc.
- ;; Author: David Gillespie <daveg@synaptics.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 (caar 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 (caar 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
|