12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311 |
- This is ../../info/calc, produced by makeinfo version 4.13 from
- calc.texi.
- This file documents Calc, the GNU Emacs calculator.
- Copyright (C) 1990-1991, 2001-2012 Free Software Foundation, Inc.
- Permission is granted to copy, distribute and/or modify this
- document under the terms of the GNU Free Documentation License,
- Version 1.3 or any later version published by the Free Software
- Foundation; with the Invariant Sections being just "GNU GENERAL
- PUBLIC LICENSE", with the Front-Cover texts being "A GNU Manual,"
- and with the Back-Cover Texts as in (a) below. A copy of the
- license is included in the section entitled "GNU Free
- Documentation License."
- (a) The FSF's Back-Cover Text is: "You have the freedom to copy and
- modify this GNU manual. Buying copies from the FSF supports it in
- developing GNU and promoting software freedom."
- INFO-DIR-SECTION Emacs misc features
- START-INFO-DIR-ENTRY
- * Calc: (calc). Advanced desk calculator and mathematical tool.
- END-INFO-DIR-ENTRY
- File: calc, Node: Logical Operations, Next: Rewrite Rules, Prev: Summations, Up: Algebra
- 12.10 Logical Operations
- ========================
- The following commands and algebraic functions return true/false values,
- where 1 represents "true" and 0 represents "false." In cases where a
- truth value is required (such as for the condition part of a rewrite
- rule, or as the condition for a `Z [ Z ]' control structure), any
- nonzero value is accepted to mean "true." (Specifically, anything for
- which `dnonzero' returns 1 is "true," and anything for which `dnonzero'
- returns 0 or cannot decide is assumed "false." Note that this means
- that `Z [ Z ]' will execute the "then" portion if its condition is
- provably true, but it will execute the "else" portion for any condition
- like `a = b' that is not provably true, even if it might be true.
- Algebraic functions that have conditions as arguments, like `? :' and
- `&&', remain unevaluated if the condition is neither provably true nor
- provably false. *Note Declarations::.)
- The `a =' (`calc-equal-to') command, or `eq(a,b)' function (which
- can also be written `a = b' or `a == b' in an algebraic formula) is
- true if `a' and `b' are equal, either because they are identical
- expressions, or because they are numbers which are numerically equal.
- (Thus the integer 1 is considered equal to the float 1.0.) If the
- equality of `a' and `b' cannot be determined, the comparison is left in
- symbolic form. Note that as a command, this operation pops two values
- from the stack and pushes back either a 1 or a 0, or a formula `a = b'
- if the values' equality cannot be determined.
- Many Calc commands use `=' formulas to represent "equations". For
- example, the `a S' (`calc-solve-for') command rearranges an equation to
- solve for a given variable. The `a M' (`calc-map-equation') command
- can be used to apply any function to both sides of an equation; for
- example, `2 a M *' multiplies both sides of the equation by two. Note
- that just `2 *' would not do the same thing; it would produce the
- formula `2 (a = b)' which represents 2 if the equality is true or zero
- if not.
- The `eq' function with more than two arguments (e.g., `C-u 3 a =' or
- `a = b = c') tests if all of its arguments are equal. In algebraic
- notation, the `=' operator is unusual in that it is neither left- nor
- right-associative: `a = b = c' is not the same as `(a = b) = c' or `a
- = (b = c)' (which each compare one variable with the 1 or 0 that
- results from comparing two other variables).
- The `a #' (`calc-not-equal-to') command, or `neq(a,b)' or `a != b'
- function, is true if `a' and `b' are not equal. This also works with
- more than two arguments; `a != b != c != d' tests that all four of `a',
- `b', `c', and `d' are distinct numbers.
- The `a <' (`calc-less-than') [`lt(a,b)' or `a < b'] operation is
- true if `a' is less than `b'. Similar functions are `a >'
- (`calc-greater-than') [`gt(a,b)' or `a > b'], `a [' (`calc-less-equal')
- [`leq(a,b)' or `a <= b'], and `a ]' (`calc-greater-equal') [`geq(a,b)'
- or `a >= b'].
- While the inequality functions like `lt' do not accept more than two
- arguments, the syntax `a <= b < c' is translated to an equivalent
- expression involving intervals: `b in [a .. c)'. (See the description
- of `in' below.) All four combinations of `<' and `<=' are allowed, or
- any of the four combinations of `>' and `>='. Four-argument
- constructions like `a < b < c < d', and mixtures like `a < b = c' that
- involve both equations and inequalities, are not allowed.
- The `a .' (`calc-remove-equal') [`rmeq'] command extracts the
- righthand side of the equation or inequality on the top of the stack.
- It also works elementwise on vectors. For example, if `[x = 2.34, y =
- z / 2]' is on the stack, then `a .' produces `[2.34, z / 2]'. As a
- special case, if the righthand side is a variable and the lefthand side
- is a number (as in `2.34 = x'), then Calc keeps the lefthand side
- instead. Finally, this command works with assignments `x := 2.34' as
- well as equations, always taking the righthand side, and for `=>'
- (evaluates-to) operators, always taking the lefthand side.
- The `a &' (`calc-logical-and') [`land(a,b)' or `a && b'] function is
- true if both of its arguments are true, i.e., are non-zero numbers. In
- this case, the result will be either `a' or `b', chosen arbitrarily.
- If either argument is zero, the result is zero. Otherwise, the formula
- is left in symbolic form.
- The `a |' (`calc-logical-or') [`lor(a,b)' or `a || b'] function is
- true if either or both of its arguments are true (nonzero). The result
- is whichever argument was nonzero, choosing arbitrarily if both are
- nonzero. If both `a' and `b' are zero, the result is zero.
- The `a !' (`calc-logical-not') [`lnot(a)' or `! a'] function is true
- if `a' is false (zero), or false if `a' is true (nonzero). It is left
- in symbolic form if `a' is not a number.
- The `a :' (`calc-logical-if') [`if(a,b,c)' or `a ? b : c'] function
- is equal to either `b' or `c' if `a' is a nonzero number or zero,
- respectively. If `a' is not a number, the test is left in symbolic
- form and neither `b' nor `c' is evaluated in any way. In algebraic
- formulas, this is one of the few Calc functions whose arguments are not
- automatically evaluated when the function itself is evaluated. The
- others are `lambda', `quote', and `condition'.
- One minor surprise to watch out for is that the formula `a?3:4' will
- not work because the `3:4' is parsed as a fraction instead of as three
- separate symbols. Type something like `a ? 3 : 4' or `a?(3):4' instead.
- As a special case, if `a' evaluates to a vector, then both `b' and
- `c' are evaluated; the result is a vector of the same length as `a'
- whose elements are chosen from corresponding elements of `b' and `c'
- according to whether each element of `a' is zero or nonzero. Each of
- `b' and `c' must be either a vector of the same length as `a', or a
- non-vector which is matched with all elements of `a'.
- The `a {' (`calc-in-set') [`in(a,b)'] function is true if the number
- `a' is in the set of numbers represented by `b'. If `b' is an interval
- form, `a' must be one of the values encompassed by the interval. If
- `b' is a vector, `a' must be equal to one of the elements of the
- vector. (If any vector elements are intervals, `a' must be in any of
- the intervals.) If `b' is a plain number, `a' must be numerically
- equal to `b'. *Note Set Operations::, for a group of commands that
- manipulate sets of this sort.
- The `typeof(a)' function produces an integer or variable which
- characterizes `a'. If `a' is a number, vector, or variable, the result
- will be one of the following numbers:
- 1 Integer
- 2 Fraction
- 3 Floating-point number
- 4 HMS form
- 5 Rectangular complex number
- 6 Polar complex number
- 7 Error form
- 8 Interval form
- 9 Modulo form
- 10 Date-only form
- 11 Date/time form
- 12 Infinity (inf, uinf, or nan)
- 100 Variable
- 101 Vector (but not a matrix)
- 102 Matrix
- Otherwise, `a' is a formula, and the result is a variable which
- represents the name of the top-level function call.
- The `integer(a)' function returns true if `a' is an integer. The
- `real(a)' function is true if `a' is a real number, either integer,
- fraction, or float. The `constant(a)' function returns true if `a' is
- any of the objects for which `typeof' would produce an integer code
- result except for variables, and provided that the components of an
- object like a vector or error form are themselves constant. Note that
- infinities do not satisfy any of these tests, nor do special constants
- like `pi' and `e'.
- *Note Declarations::, for a set of similar functions that recognize
- formulas as well as actual numbers. For example, `dint(floor(x))' is
- true because `floor(x)' is provably integer-valued, but
- `integer(floor(x))' does not because `floor(x)' is not literally an
- integer constant.
- The `refers(a,b)' function is true if the variable (or
- sub-expression) `b' appears in `a', or false otherwise. Unlike the
- other tests described here, this function returns a definite "no" answer
- even if its arguments are still in symbolic form. The only case where
- `refers' will be left unevaluated is if `a' is a plain variable
- (different from `b').
- The `negative(a)' function returns true if `a' "looks" negative,
- because it is a negative number, because it is of the form `-x', or
- because it is a product or quotient with a term that looks negative.
- This is most useful in rewrite rules. Beware that `negative(a)'
- evaluates to 1 or 0 for _any_ argument `a', so it can only be stored in
- a formula if the default simplifications are turned off first with `m
- O' (or if it appears in an unevaluated context such as a rewrite rule
- condition).
- The `variable(a)' function is true if `a' is a variable, or false if
- not. If `a' is a function call, this test is left in symbolic form.
- Built-in variables like `pi' and `inf' are considered variables like
- any others by this test.
- The `nonvar(a)' function is true if `a' is a non-variable. If its
- argument is a variable it is left unsimplified; it never actually
- returns zero. However, since Calc's condition-testing commands
- consider "false" anything not provably true, this is often good enough.
- The functions `lin', `linnt', `islin', and `islinnt' check if an
- expression is "linear," i.e., can be written in the form `a + b x' for
- some constants `a' and `b', and some variable or subformula `x'. The
- function `islin(f,x)' checks if formula `f' is linear in `x', returning
- 1 if so. For example, `islin(x,x)', `islin(-x,x)', `islin(3,x)', and
- `islin(x y / 3 - 2, x)' all return 1. The `lin(f,x)' function is
- similar, except that instead of returning 1 it returns the vector `[a,
- b, x]'. For the above examples, this vector would be `[0, 1, x]', `[0,
- -1, x]', `[3, 0, x]', and `[-2, y/3, x]', respectively. Both `lin' and
- `islin' generally remain unevaluated for expressions which are not
- linear, e.g., `lin(2 x^2, x)' and `lin(sin(x), x)'. The second
- argument can also be a formula; `islin(2 + 3 sin(x), sin(x))' returns
- true.
- The `linnt' and `islinnt' functions perform a similar check, but
- require a "non-trivial" linear form, which means that the `b'
- coefficient must be non-zero. For example, `lin(2,x)' returns `[2, 0,
- x]' and `lin(y,x)' returns `[y, 0, x]', but `linnt(2,x)' and
- `linnt(y,x)' are left unevaluated (in other words, these formulas are
- considered to be only "trivially" linear in `x').
- All four linearity-testing functions allow you to omit the second
- argument, in which case the input may be linear in any non-constant
- formula. Here, the `a=0', `b=1' case is also considered trivial, and
- only constant values for `a' and `b' are recognized. Thus, `lin(2 x
- y)' returns `[0, 2, x y]', `lin(2 - x y)' returns `[2, -1, x y]', and
- `lin(x y)' returns `[0, 1, x y]'. The `linnt' function would allow the
- first two cases but not the third. Also, neither `lin' nor `linnt'
- accept plain constants as linear in the one-argument case: `islin(2,x)'
- is true, but `islin(2)' is false.
- The `istrue(a)' function returns 1 if `a' is a nonzero number or
- provably nonzero formula, or 0 if `a' is anything else. Calls to
- `istrue' can only be manipulated if `m O' mode is used to make sure
- they are not evaluated prematurely. (Note that declarations are used
- when deciding whether a formula is true; `istrue' returns 1 when
- `dnonzero' would return 1, and it returns 0 when `dnonzero' would
- return 0 or leave itself in symbolic form.)
- File: calc, Node: Rewrite Rules, Prev: Logical Operations, Up: Algebra
- 12.11 Rewrite Rules
- ===================
- The `a r' (`calc-rewrite') [`rewrite'] command makes substitutions in a
- formula according to a specified pattern or patterns known as "rewrite
- rules". Whereas `a b' (`calc-substitute') matches literally, so that
- substituting `sin(x)' with `cos(x)' matches only the `sin' function
- applied to the variable `x', rewrite rules match general kinds of
- formulas; rewriting using the rule `sin(x) := cos(x)' matches `sin' of
- any argument and replaces it with `cos' of that same argument. The
- only significance of the name `x' is that the same name is used on both
- sides of the rule.
- Rewrite rules rearrange formulas already in Calc's memory. *Note
- Syntax Tables::, to read about "syntax rules", which are similar to
- algebraic rewrite rules but operate when new algebraic entries are
- being parsed, converting strings of characters into Calc formulas.
- * Menu:
- * Entering Rewrite Rules::
- * Basic Rewrite Rules::
- * Conditional Rewrite Rules::
- * Algebraic Properties of Rewrite Rules::
- * Other Features of Rewrite Rules::
- * Composing Patterns in Rewrite Rules::
- * Nested Formulas with Rewrite Rules::
- * Multi-Phase Rewrite Rules::
- * Selections with Rewrite Rules::
- * Matching Commands::
- * Automatic Rewrites::
- * Debugging Rewrites::
- * Examples of Rewrite Rules::
- File: calc, Node: Entering Rewrite Rules, Next: Basic Rewrite Rules, Prev: Rewrite Rules, Up: Rewrite Rules
- 12.11.1 Entering Rewrite Rules
- ------------------------------
- Rewrite rules normally use the "assignment" operator `OLD := NEW'.
- This operator is equivalent to the function call `assign(old, new)'.
- The `assign' function is undefined by itself in Calc, so an assignment
- formula such as a rewrite rule will be left alone by ordinary Calc
- commands. But certain commands, like the rewrite system, interpret
- assignments in special ways.
- For example, the rule `sin(x)^2 := 1-cos(x)^2' says to replace every
- occurrence of the sine of something, squared, with one minus the square
- of the cosine of that same thing. All by itself as a formula on the
- stack it does nothing, but when given to the `a r' command it turns
- that command into a sine-squared-to-cosine-squared converter.
- To specify a set of rules to be applied all at once, make a vector of
- rules.
- When `a r' prompts you to enter the rewrite rules, you can answer in
- several ways:
- 1. With a rule: `f(x) := g(x) <RET>'.
- 2. With a vector of rules: `[f1(x) := g1(x), f2(x) := g2(x)] <RET>'.
- (You can omit the enclosing square brackets if you wish.)
- 3. With the name of a variable that contains the rule or rules vector:
- `myrules <RET>'.
- 4. With any formula except a rule, a vector, or a variable name; this
- will be interpreted as the OLD half of a rewrite rule, and you
- will be prompted a second time for the NEW half: `f(x) <RET> g(x)
- <RET>'.
- 5. With a blank line, in which case the rule, rules vector, or
- variable will be taken from the top of the stack (and the formula
- to be rewritten will come from the second-to-top position).
- If you enter the rules directly (as opposed to using rules stored in
- a variable), those rules will be put into the Trail so that you can
- retrieve them later. *Note Trail Commands::.
- It is most convenient to store rules you use often in a variable and
- invoke them by giving the variable name. The `s e'
- (`calc-edit-variable') command is an easy way to create or edit a rule
- set stored in a variable. You may also wish to use `s p'
- (`calc-permanent-variable') to save your rules permanently; *note
- Operations on Variables::.
- Rewrite rules are compiled into a special internal form for faster
- matching. If you enter a rule set directly it must be recompiled every
- time. If you store the rules in a variable and refer to them through
- that variable, they will be compiled once and saved away along with the
- variable for later reference. This is another good reason to store
- your rules in a variable.
- Calc also accepts an obsolete notation for rules, as vectors `[OLD,
- NEW]'. But because it is easily confused with a vector of two rules,
- the use of this notation is no longer recommended.
- File: calc, Node: Basic Rewrite Rules, Next: Conditional Rewrite Rules, Prev: Entering Rewrite Rules, Up: Rewrite Rules
- 12.11.2 Basic Rewrite Rules
- ---------------------------
- To match a particular formula `x' with a particular rewrite rule `OLD
- := NEW', Calc compares the structure of `x' with the structure of OLD.
- Variables that appear in OLD are treated as "meta-variables"; the
- corresponding positions in `x' may contain any sub-formulas. For
- example, the pattern `f(x,y)' would match the expression `f(12, a+1)'
- with the meta-variable `x' corresponding to 12 and with `y'
- corresponding to `a+1'. However, this pattern would not match `f(12)'
- or `g(12, a+1)', since there is no assignment of the meta-variables
- that will make the pattern match these expressions. Notice that if the
- pattern is a single meta-variable, it will match any expression.
- If a given meta-variable appears more than once in OLD, the
- corresponding sub-formulas of `x' must be identical. Thus the pattern
- `f(x,x)' would match `f(12, 12)' and `f(a+1, a+1)' but not `f(12, a+1)'
- or `f(a+b, b+a)'. (*Note Conditional Rewrite Rules::, for a way to
- match the latter.)
- Things other than variables must match exactly between the pattern
- and the target formula. To match a particular variable exactly, use
- the pseudo-function `quote(v)' in the pattern. For example, the
- pattern `x+quote(y)' matches `x+y', `2+y', or `sin(a)+y'.
- The special variable names `e', `pi', `i', `phi', `gamma', `inf',
- `uinf', and `nan' always match literally. Thus the pattern `sin(d + e
- + f)' acts exactly like `sin(d + quote(e) + f)'.
- If the OLD pattern is found to match a given formula, that formula
- is replaced by NEW, where any occurrences in NEW of meta-variables from
- the pattern are replaced with the sub-formulas that they matched.
- Thus, applying the rule `f(x,y) := g(y+x,x)' to `f(12, a+1)' would
- produce `g(a+13, 12)'.
- The normal `a r' command applies rewrite rules over and over
- throughout the target formula until no further changes are possible (up
- to a limit of 100 times). Use `C-u 1 a r' to make only one change at a
- time.
- File: calc, Node: Conditional Rewrite Rules, Next: Algebraic Properties of Rewrite Rules, Prev: Basic Rewrite Rules, Up: Rewrite Rules
- 12.11.3 Conditional Rewrite Rules
- ---------------------------------
- A rewrite rule can also be "conditional", written in the form `OLD :=
- NEW :: COND'. (There is also the obsolete form `[OLD, NEW, COND]'.)
- If a COND part is present in the rule, this is an additional condition
- that must be satisfied before the rule is accepted. Once OLD has been
- successfully matched to the target expression, COND is evaluated (with
- all the meta-variables substituted for the values they matched) and
- simplified with `a s' (`calc-simplify'). If the result is a nonzero
- number or any other object known to be nonzero (*note Declarations::),
- the rule is accepted. If the result is zero or if it is a symbolic
- formula that is not known to be nonzero, the rule is rejected. *Note
- Logical Operations::, for a number of functions that return 1 or 0
- according to the results of various tests.
- For example, the formula `n > 0' simplifies to 1 or 0 if `n' is
- replaced by a positive or nonpositive number, respectively (or if `n'
- has been declared to be positive or nonpositive). Thus, the rule
- `f(x,y) := g(y+x,x) :: x+y > 0' would apply to `f(0, 4)' but not to
- `f(-3, 2)' or `f(12, a+1)' (assuming no outstanding declarations for
- `a'). In the case of `f(-3, 2)', the condition can be shown not to be
- satisfied; in the case of `f(12, a+1)', the condition merely cannot be
- shown to be satisfied, but that is enough to reject the rule.
- While Calc will use declarations to reason about variables in the
- formula being rewritten, declarations do not apply to meta-variables.
- For example, the rule `f(a) := g(a+1)' will match for any values of
- `a', such as complex numbers, vectors, or formulas, even if `a' has
- been declared to be real or scalar. If you want the meta-variable `a'
- to match only literal real numbers, use `f(a) := g(a+1) :: real(a)'.
- If you want `a' to match only reals and formulas which are provably
- real, use `dreal(a)' as the condition.
- The `::' operator is a shorthand for the `condition' function; `OLD
- := NEW :: COND' is equivalent to the formula `condition(assign(OLD,
- NEW), COND)'.
- If you have several conditions, you can use `... :: c1 :: c2 :: c3'
- or `... :: c1 && c2 && c3'. The two are entirely equivalent.
- It is also possible to embed conditions inside the pattern: `f(x ::
- x>0, y) := g(y+x, x)'. This is purely a notational convenience,
- though; where a condition appears in a rule has no effect on when it is
- tested. The rewrite-rule compiler automatically decides when it is
- best to test each condition while a rule is being matched.
- Certain conditions are handled as special cases by the rewrite rule
- system and are tested very efficiently: Where `x' is any
- meta-variable, these conditions are `integer(x)', `real(x)',
- `constant(x)', `negative(x)', `x >= y' where `y' is either a constant
- or another meta-variable and `>=' may be replaced by any of the six
- relational operators, and `x % a = b' where `a' and `b' are constants.
- Other conditions, like `x >= y+1' or `dreal(x)', will be less efficient
- to check since Calc must bring the whole evaluator and simplifier into
- play.
- An interesting property of `::' is that neither of its arguments
- will be touched by Calc's default simplifications. This is important
- because conditions often are expressions that cannot safely be
- evaluated early. For example, the `typeof' function never remains in
- symbolic form; entering `typeof(a)' will put the number 100 (the type
- code for variables like `a') on the stack. But putting the condition
- `... :: typeof(a) = 6' on the stack is safe since `::' prevents the
- `typeof' from being evaluated until the condition is actually used by
- the rewrite system.
- Since `::' protects its lefthand side, too, you can use a dummy
- condition to protect a rule that must itself not evaluate early. For
- example, it's not safe to put `a(f,x) := apply(f, [x])' on the stack
- because it will immediately evaluate to `a(f,x) := f(x)', where the
- meta-variable-ness of `f' on the righthand side has been lost. But
- `a(f,x) := apply(f, [x]) :: 1' is safe, and of course the condition `1'
- is always true (nonzero) so it has no effect on the functioning of the
- rule. (The rewrite compiler will ensure that it doesn't even impact
- the speed of matching the rule.)
- File: calc, Node: Algebraic Properties of Rewrite Rules, Next: Other Features of Rewrite Rules, Prev: Conditional Rewrite Rules, Up: Rewrite Rules
- 12.11.4 Algebraic Properties of Rewrite Rules
- ---------------------------------------------
- The rewrite mechanism understands the algebraic properties of functions
- like `+' and `*'. In particular, pattern matching takes the
- associativity and commutativity of the following functions into account:
- + - * = != && || and or xor vint vunion vxor gcd lcm max min beta
- For example, the rewrite rule:
- a x + b x := (a + b) x
- will match formulas of the form,
- a x + b x, x a + x b, a x + x b, x a + b x
- Rewrites also understand the relationship between the `+' and `-'
- operators. The above rewrite rule will also match the formulas,
- a x - b x, x a - x b, a x - x b, x a - b x
- by matching `b' in the pattern to `-b' from the formula.
- Applied to a sum of many terms like `r + a x + s + b x + t', this
- pattern will check all pairs of terms for possible matches. The rewrite
- will take whichever suitable pair it discovers first.
- In general, a pattern using an associative operator like `a + b'
- will try 2 N different ways to match a sum of N terms like `x + y + z -
- w'. First, `a' is matched against each of `x', `y', `z', and `-w' in
- turn, with `b' being matched to the remainders `y + z - w', `x + z -
- w', etc. If none of these succeed, then `b' is matched against each of
- the four terms with `a' matching the remainder. Half-and-half matches,
- like `(x + y) + (z - w)', are not tried.
- Note that `*' is not commutative when applied to matrices, but
- rewrite rules pretend that it is. If you type `m v' to enable Matrix
- mode (*note Matrix Mode::), rewrite rules will match `*' literally,
- ignoring its usual commutativity property. (In the current
- implementation, the associativity also vanishes--it is as if the
- pattern had been enclosed in a `plain' marker; see below.) If you are
- applying rewrites to formulas with matrices, it's best to enable Matrix
- mode first to prevent algebraically incorrect rewrites from occurring.
- The pattern `-x' will actually match any expression. For example,
- the rule
- f(-x) := -f(x)
- will rewrite `f(a)' to `-f(-a)'. To avoid this, either use a `plain'
- marker as described below, or add a `negative(x)' condition. The
- `negative' function is true if its argument "looks" negative, for
- example, because it is a negative number or because it is a formula
- like `-x'. The new rule using this condition is:
- f(x) := -f(-x) :: negative(x) or, equivalently,
- f(-x) := -f(x) :: negative(-x)
- In the same way, the pattern `x - y' will match the sum `a + b' by
- matching `y' to `-b'.
- The pattern `a b' will also match the formula `x/y' if `y' is a
- number. Thus the rule `a x + b x := (a+b) x' will also convert `a x +
- x / 2' to `(a + 0.5) x' (or `(a + 1:2) x', depending on the current
- fraction mode).
- Calc will _not_ take other liberties with `*', `/', and `^'. For
- example, the pattern `f(a b)' will not match `f(x^2)', and `f(a + b)'
- will not match `f(2 x)', even though conceivably these patterns could
- match with `a = b = x'. Nor will `f(a b)' match `f(x / y)' if `y' is
- not a constant, even though it could be considered to match with `a = x'
- and `b = 1/y'. The reasons are partly for efficiency, and partly
- because while few mathematical operations are substantively different
- for addition and subtraction, often it is preferable to treat the cases
- of multiplication, division, and integer powers separately.
- Even more subtle is the rule set
- [ f(a) + f(b) := f(a + b), -f(a) := f(-a) ]
- attempting to match `f(x) - f(y)'. You might think that Calc will view
- this subtraction as `f(x) + (-f(y))' and then apply the above two rules
- in turn, but actually this will not work because Calc only does this
- when considering rules for `+' (like the first rule in this set). So
- it will see first that `f(x) + (-f(y))' does not match `f(a) + f(b)'
- for any assignments of the meta-variables, and then it will see that
- `f(x) - f(y)' does not match `-f(a)' for any assignment of `a'.
- Because Calc tries only one rule at a time, it will not be able to
- rewrite `f(x) - f(y)' with this rule set. An explicit `f(a) - f(b)'
- rule will have to be added.
- Another thing patterns will _not_ do is break up complex numbers.
- The pattern `myconj(a + b i) := a - b i' will work for formulas
- involving the special constant `i' (such as `3 - 4 i'), but it will not
- match actual complex numbers like `(3, -4)'. A version of the above
- rule for complex numbers would be
- myconj(a) := re(a) - im(a) (0,1) :: im(a) != 0
- (Because the `re' and `im' functions understand the properties of the
- special constant `i', this rule will also work for `3 - 4 i'. In fact,
- this particular rule would probably be better without the `im(a) != 0'
- condition, since if `im(a) = 0' the righthand side of the rule will
- still give the correct answer for the conjugate of a real number.)
- It is also possible to specify optional arguments in patterns. The
- rule
- opt(a) x + opt(b) (x^opt(c) + opt(d)) := f(a, b, c, d)
- will match the formula
- 5 (x^2 - 4) + 3 x
- in a fairly straightforward manner, but it will also match reduced
- formulas like
- x + x^2, 2(x + 1) - x, x + x
- producing, respectively,
- f(1, 1, 2, 0), f(-1, 2, 1, 1), f(1, 1, 1, 0)
- (The latter two formulas can be entered only if default
- simplifications have been turned off with `m O'.)
- The default value for a term of a sum is zero. The default value
- for a part of a product, for a power, or for the denominator of a
- quotient, is one. Also, `-x' matches the pattern `opt(a) b' with `a =
- -1'.
- In particular, the distributive-law rule can be refined to
- opt(a) x + opt(b) x := (a + b) x
- so that it will convert, e.g., `a x - x', to `(a - 1) x'.
- The pattern `opt(a) + opt(b) x' matches almost any formulas which
- are linear in `x'. You can also use the `lin' and `islin' functions
- with rewrite conditions to test for this; *note Logical Operations::.
- These functions are not as convenient to use in rewrite rules, but they
- recognize more kinds of formulas as linear: `x/z' is considered linear
- with `b = 1/z' by `lin', but it will not match the above pattern
- because that pattern calls for a multiplication, not a division.
- As another example, the obvious rule to replace `sin(x)^2 + cos(x)^2'
- by 1,
- sin(x)^2 + cos(x)^2 := 1
- misses many cases because the sine and cosine may both be multiplied by
- an equal factor. Here's a more successful rule:
- opt(a) sin(x)^2 + opt(a) cos(x)^2 := a
- Note that this rule will _not_ match `sin(x)^2 + 6 cos(x)^2' because
- one `a' would have "matched" 1 while the other matched 6.
- Calc automatically converts a rule like
- f(x-1, x) := g(x)
- into the form
- f(temp, x) := g(x) :: temp = x-1
- (where `temp' stands for a new, invented meta-variable that doesn't
- actually have a name). This modified rule will successfully match
- `f(6, 7)', binding `temp' and `x' to 6 and 7, respectively, then
- verifying that they differ by one even though `6' does not
- superficially look like `x-1'.
- However, Calc does not solve equations to interpret a rule. The
- following rule,
- f(x-1, x+1) := g(x)
- will not work. That is, it will match `f(a - 1 + b, a + 1 + b)' but
- not `f(6, 8)'. Calc always interprets at least one occurrence of a
- variable by literal matching. If the variable appears "isolated" then
- Calc is smart enough to use it for literal matching. But in this last
- example, Calc is forced to rewrite the rule to `f(x-1, temp) := g(x) ::
- temp = x+1' where the `x-1' term must correspond to an actual
- "something-minus-one" in the target formula.
- A successful way to write this would be `f(x, x+2) := g(x+1)'. You
- could make this resemble the original form more closely by using `let'
- notation, which is described in the next section:
- f(xm1, x+1) := g(x) :: let(x := xm1+1)
- Calc does this rewriting or "conditionalizing" for any sub-pattern
- which involves only the functions in the following list, operating only
- on constants and meta-variables which have already been matched
- elsewhere in the pattern. When matching a function call, Calc is
- careful to match arguments which are plain variables before arguments
- which are calls to any of the functions below, so that a pattern like
- `f(x-1, x)' can be conditionalized even though the isolated `x' comes
- after the `x-1'.
- + - * / \ % ^ abs sign round rounde roundu trunc floor ceil
- max min re im conj arg
- You can suppress all of the special treatments described in this
- section by surrounding a function call with a `plain' marker. This
- marker causes the function call which is its argument to be matched
- literally, without regard to commutativity, associativity, negation, or
- conditionalization. When you use `plain', the "deep structure" of the
- formula being matched can show through. For example,
- plain(a - a b) := f(a, b)
- will match only literal subtractions. However, the `plain' marker does
- not affect its arguments' arguments. In this case, commutativity and
- associativity is still considered while matching the `a b' sub-pattern,
- so the whole pattern will match `x - y x' as well as `x - x y'. We
- could go still further and use
- plain(a - plain(a b)) := f(a, b)
- which would do a completely strict match for the pattern.
- By contrast, the `quote' marker means that not only the function
- name but also the arguments must be literally the same. The above
- pattern will match `x - x y' but
- quote(a - a b) := f(a, b)
- will match only the single formula `a - a b'. Also,
- quote(a - quote(a b)) := f(a, b)
- will match only `a - quote(a b)'--probably not the desired effect!
- A certain amount of algebra is also done when substituting the
- meta-variables on the righthand side of a rule. For example, in the
- rule
- a + f(b) := f(a + b)
- matching `f(x) - y' would produce `f((-y) + x)' if taken literally, but
- the rewrite mechanism will simplify the righthand side to `f(x - y)'
- automatically. (Of course, the default simplifications would do this
- anyway, so this special simplification is only noticeable if you have
- turned the default simplifications off.) This rewriting is done only
- when a meta-variable expands to a "negative-looking" expression. If
- this simplification is not desirable, you can use a `plain' marker on
- the righthand side:
- a + f(b) := f(plain(a + b))
- In this example, we are still allowing the pattern-matcher to use all
- the algebra it can muster, but the righthand side will always simplify
- to a literal addition like `f((-y) + x)'.
- File: calc, Node: Other Features of Rewrite Rules, Next: Composing Patterns in Rewrite Rules, Prev: Algebraic Properties of Rewrite Rules, Up: Rewrite Rules
- 12.11.5 Other Features of Rewrite Rules
- ---------------------------------------
- Certain "function names" serve as markers in rewrite rules. Here is a
- complete list of these markers. First are listed the markers that work
- inside a pattern; then come the markers that work in the righthand side
- of a rule.
- One kind of marker, `import(x)', takes the place of a whole rule.
- Here `x' is the name of a variable containing another rule set; those
- rules are "spliced into" the rule set that imports them. For example,
- if `[f(a+b) := f(a) + f(b), f(a b) := a f(b) :: real(a)]' is stored in
- variable `linearF', then the rule set `[f(0) := 0, import(linearF)]'
- will apply all three rules. It is possible to modify the imported rules
- slightly: `import(x, v1, x1, v2, x2, ...)' imports the rule set `x'
- with all occurrences of `v1', as either a variable name or a function
- name, replaced with `x1' and so on. (If `v1' is used as a function
- name, then `x1' must be either a function name itself or a `< >'
- nameless function; *note Specifying Operators::.) For example, `[g(0)
- := 0, import(linearF, f, g)]' applies the linearity rules to the
- function `g' instead of `f'. Imports can be nested, but the
- import-with-renaming feature may fail to rename sub-imports properly.
- The special functions allowed in patterns are:
- `quote(x)'
- This pattern matches exactly `x'; variable names in `x' are not
- interpreted as meta-variables. The only flexibility is that
- numbers are compared for numeric equality, so that the pattern
- `f(quote(12))' will match both `f(12)' and `f(12.0)'. (Numbers
- are always treated this way by the rewrite mechanism: The rule
- `f(x,x) := g(x)' will match `f(12, 12.0)'. The rewrite may
- produce either `g(12)' or `g(12.0)' as a result in this case.)
- `plain(x)'
- Here `x' must be a function call `f(x1,x2,...)'. This pattern
- matches a call to function `f' with the specified argument
- patterns. No special knowledge of the properties of the function
- `f' is used in this case; `+' is not commutative or associative.
- Unlike `quote', the arguments `x1,x2,...' are treated as patterns.
- If you wish them to be treated "plainly" as well, you must enclose
- them with more `plain' markers: `plain(plain(-a) + plain(b c))'.
- `opt(x,def)'
- Here `x' must be a variable name. This must appear as an argument
- to a function or an element of a vector; it specifies that the
- argument or element is optional. As an argument to `+', `-', `*',
- `&&', or `||', or as the second argument to `/' or `^', the value
- DEF may be omitted. The pattern `x + opt(y)' matches a sum by
- binding one summand to `x' and the other to `y', and it matches
- anything else by binding the whole expression to `x' and zero to
- `y'. The other operators above work similarly.
- For general miscellaneous functions, the default value `def' must
- be specified. Optional arguments are dropped starting with the
- rightmost one during matching. For example, the pattern
- `f(opt(a,0), b, opt(c,b))' will match `f(b)', `f(a,b)', or
- `f(a,b,c)'. Default values of zero and `b' are supplied in this
- example for the omitted arguments. Note that the literal variable
- `b' will be the default in the latter case, _not_ the value that
- matched the meta-variable `b'. In other words, the default DEF is
- effectively quoted.
- `condition(x,c)'
- This matches the pattern `x', with the attached condition `c'. It
- is the same as `x :: c'.
- `pand(x,y)'
- This matches anything that matches both pattern `x' and pattern
- `y'. It is the same as `x &&& y'. *note Composing Patterns in
- Rewrite Rules::.
- `por(x,y)'
- This matches anything that matches either pattern `x' or pattern
- `y'. It is the same as `x ||| y'.
- `pnot(x)'
- This matches anything that does not match pattern `x'. It is the
- same as `!!! x'.
- `cons(h,t)'
- This matches any vector of one or more elements. The first
- element is matched to `h'; a vector of the remaining elements is
- matched to `t'. Note that vectors of fixed length can also be
- matched as actual vectors: The rule `cons(a,cons(b,[])) :=
- cons(a+b,[])' is equivalent to the rule `[a,b] := [a+b]'.
- `rcons(t,h)'
- This is like `cons', except that the _last_ element is matched to
- `h', with the remaining elements matched to `t'.
- `apply(f,args)'
- This matches any function call. The name of the function, in the
- form of a variable, is matched to `f'. The arguments of the
- function, as a vector of zero or more objects, are matched to
- `args'. Constants, variables, and vectors do _not_ match an
- `apply' pattern. For example, `apply(f,x)' matches any function
- call, `apply(quote(f),x)' matches any call to the function `f',
- `apply(f,[a,b])' matches any function call with exactly two
- arguments, and `apply(quote(f), cons(a,cons(b,x)))' matches any
- call to the function `f' with two or more arguments. Another way
- to implement the latter, if the rest of the rule does not need to
- refer to the first two arguments of `f' by name, would be
- `apply(quote(f), x :: vlen(x) >= 2)'. Here's a more interesting
- sample use of `apply':
- apply(f,[x+n]) := n + apply(f,[x])
- :: in(f, [floor,ceil,round,trunc]) :: integer(n)
- Note, however, that this will be slower to match than a rule set
- with four separate rules. The reason is that Calc sorts the rules
- of a rule set according to top-level function name; if the
- top-level function is `apply', Calc must try the rule for every
- single formula and sub-formula. If the top-level function in the
- pattern is, say, `floor', then Calc invokes the rule only for
- sub-formulas which are calls to `floor'.
- Formulas normally written with operators like `+' are still
- considered function calls: `apply(f,x)' matches `a+b' with `f =
- add', `x = [a,b]'.
- You must use `apply' for meta-variables with function names on
- both sides of a rewrite rule: `apply(f, [x]) := f(x+1)' is _not_
- correct, because it rewrites `spam(6)' into `f(7)'. The righthand
- side should be `apply(f, [x+1])'. Also note that you will have to
- use No-Simplify mode (`m O') when entering this rule so that the
- `apply' isn't evaluated immediately to get the new rule `f(x) :=
- f(x+1)'. Or, use `s e' to enter the rule without going through
- the stack, or enter the rule as `apply(f, [x]) := apply(f, [x+1])
- :: 1'. *Note Conditional Rewrite Rules::.
- `select(x)'
- This is used for applying rules to formulas with selections; *note
- Selections with Rewrite Rules::.
- Special functions for the righthand sides of rules are:
- `quote(x)'
- The notation `quote(x)' is changed to `x' when the righthand side
- is used. As far as the rewrite rule is concerned, `quote' is
- invisible. However, `quote' has the special property in Calc that
- its argument is not evaluated. Thus, while it will not work to
- put the rule `t(a) := typeof(a)' on the stack because `typeof(a)'
- is evaluated immediately to produce `t(a) := 100', you can use
- `quote' to protect the righthand side: `t(a) := quote(typeof(a))'.
- (*Note Conditional Rewrite Rules::, for another trick for
- protecting rules from evaluation.)
- `plain(x)'
- Special properties of and simplifications for the function call
- `x' are not used. One interesting case where `plain' is useful is
- the rule, `q(x) := quote(x)', trying to expand a shorthand
- notation for the `quote' function. This rule will not work as
- shown; instead of replacing `q(foo)' with `quote(foo)', it will
- replace it with `foo'! The correct rule would be `q(x) :=
- plain(quote(x))'.
- `cons(h,t)'
- Where `t' is a vector, this is converted into an expanded vector
- during rewrite processing. Note that `cons' is a regular Calc
- function which normally does this anyway; the only way `cons' is
- treated specially by rewrites is that `cons' on the righthand side
- of a rule will be evaluated even if default simplifications have
- been turned off.
- `rcons(t,h)'
- Analogous to `cons' except putting `h' at the _end_ of the vector
- `t'.
- `apply(f,args)'
- Where `f' is a variable and ARGS is a vector, this is converted to
- a function call. Once again, note that `apply' is also a regular
- Calc function.
- `eval(x)'
- The formula `x' is handled in the usual way, then the default
- simplifications are applied to it even if they have been turned
- off normally. This allows you to treat any function similarly to
- the way `cons' and `apply' are always treated. However, there is
- a slight difference: `cons(2+3, [])' with default simplifications
- off will be converted to `[2+3]', whereas `eval(cons(2+3, []))'
- will be converted to `[5]'.
- `evalsimp(x)'
- The formula `x' has meta-variables substituted in the usual way,
- then algebraically simplified as if by the `a s' command.
- `evalextsimp(x)'
- The formula `x' has meta-variables substituted in the normal way,
- then "extendedly" simplified as if by the `a e' command.
- `select(x)'
- *Note Selections with Rewrite Rules::.
- There are also some special functions you can use in conditions.
- `let(v := x)'
- The expression `x' is evaluated with meta-variables substituted.
- The `a s' command's simplifications are _not_ applied by default,
- but `x' can include calls to `evalsimp' or `evalextsimp' as
- described above to invoke higher levels of simplification. The
- result of `x' is then bound to the meta-variable `v'. As usual,
- if this meta-variable has already been matched to something else
- the two values must be equal; if the meta-variable is new then it
- is bound to the result of the expression. This variable can then
- appear in later conditions, and on the righthand side of the rule.
- In fact, `v' may be any pattern in which case the result of
- evaluating `x' is matched to that pattern, binding any
- meta-variables that appear in that pattern. Note that `let' can
- only appear by itself as a condition, or as one term of an `&&'
- which is a whole condition: It cannot be inside an `||' term or
- otherwise buried.
- The alternate, equivalent form `let(v, x)' is also recognized.
- Note that the use of `:=' by `let', while still being
- assignment-like in character, is unrelated to the use of `:=' in
- the main part of a rewrite rule.
- As an example, `f(a) := g(ia) :: let(ia := 1/a) :: constant(ia)'
- replaces `f(a)' with `g' of the inverse of `a', if that inverse
- exists and is constant. For example, if `a' is a singular matrix
- the operation `1/a' is left unsimplified and `constant(ia)' fails,
- but if `a' is an invertible matrix then the rule succeeds.
- Without `let' there would be no way to express this rule that
- didn't have to invert the matrix twice. Note that, because the
- meta-variable `ia' is otherwise unbound in this rule, the `let'
- condition itself always "succeeds" because no matter what `1/a'
- evaluates to, it can successfully be bound to `ia'.
- Here's another example, for integrating cosines of linear terms:
- `myint(cos(y),x) := sin(y)/b :: let([a,b,x] := lin(y,x))'. The
- `lin' function returns a 3-vector if its argument is linear, or
- leaves itself unevaluated if not. But an unevaluated `lin' call
- will not match the 3-vector on the lefthand side of the `let', so
- this `let' both verifies that `y' is linear, and binds the
- coefficients `a' and `b' for use elsewhere in the rule. (It would
- have been possible to use `sin(a x + b)/b' for the righthand side
- instead, but using `sin(y)/b' avoids gratuitous rearrangement of
- the argument of the sine.)
- Similarly, here is a rule that implements an inverse-`erf'
- function. It uses `root' to search for a solution. If `root'
- succeeds, it will return a vector of two numbers where the first
- number is the desired solution. If no solution is found, `root'
- remains in symbolic form. So we use `let' to check that the
- result was indeed a vector.
- ierf(x) := y :: let([y,z] := root(erf(a) = x, a, .5))
- `matches(v,p)'
- The meta-variable V, which must already have been matched to
- something elsewhere in the rule, is compared against pattern P.
- Since `matches' is a standard Calc function, it can appear
- anywhere in a condition. But if it appears alone or as a term of
- a top-level `&&', then you get the special extra feature that
- meta-variables which are bound to things inside P can be used
- elsewhere in the surrounding rewrite rule.
- The only real difference between `let(p := v)' and `matches(v, p)'
- is that the former evaluates `v' using the default
- simplifications, while the latter does not.
- `remember'
- This is actually a variable, not a function. If `remember'
- appears as a condition in a rule, then when that rule succeeds the
- original expression and rewritten expression are added to the
- front of the rule set that contained the rule. If the rule set
- was not stored in a variable, `remember' is ignored. The lefthand
- side is enclosed in `quote' in the added rule if it contains any
- variables.
- For example, the rule `f(n) := n f(n-1) :: remember' applied to
- `f(7)' will add the rule `f(7) := 7 f(6)' to the front of the rule
- set. The rule set `EvalRules' works slightly differently: There,
- the evaluation of `f(6)' will complete before the result is added
- to the rule set, in this case as `f(7) := 5040'. Thus `remember'
- is most useful inside `EvalRules'.
- It is up to you to ensure that the optimization performed by
- `remember' is safe. For example, the rule `foo(n) := n ::
- evalv(eatfoo) > 0 :: remember' is a bad idea (`evalv' is the
- function equivalent of the `=' command); if the variable `eatfoo'
- ever contains 1, rules like `foo(7) := 7' will be added to the
- rule set and will continue to operate even if `eatfoo' is later
- changed to 0.
- `remember(c)'
- Remember the match as described above, but only if condition `c'
- is true. For example, `remember(n % 4 = 0)' in the above factorial
- rule remembers only every fourth result. Note that `remember(1)'
- is equivalent to `remember', and `remember(0)' has no effect.
- File: calc, Node: Composing Patterns in Rewrite Rules, Next: Nested Formulas with Rewrite Rules, Prev: Other Features of Rewrite Rules, Up: Rewrite Rules
- 12.11.6 Composing Patterns in Rewrite Rules
- -------------------------------------------
- There are three operators, `&&&', `|||', and `!!!', that combine
- rewrite patterns to make larger patterns. The combinations are "and,"
- "or," and "not," respectively, and these operators are the pattern
- equivalents of `&&', `||' and `!' (which operate on zero-or-nonzero
- logical values).
- Note that `&&&', `|||', and `!!!' are left in symbolic form by all
- regular Calc features; they have special meaning only in the context of
- rewrite rule patterns.
- The pattern `P1 &&& P2' matches anything that matches both P1 and
- P2. One especially useful case is when one of P1 or P2 is a
- meta-variable. For example, here is a rule that operates on error
- forms:
- f(x &&& a +/- b, x) := g(x)
- This does the same thing, but is arguably simpler than, the rule
- f(a +/- b, a +/- b) := g(a +/- b)
- Here's another interesting example:
- ends(cons(a, x) &&& rcons(y, b)) := [a, b]
- which effectively clips out the middle of a vector leaving just the
- first and last elements. This rule will change a one-element vector
- `[a]' to `[a, a]'. The similar rule
- ends(cons(a, rcons(y, b))) := [a, b]
- would do the same thing except that it would fail to match a
- one-element vector.
- The pattern `P1 ||| P2' matches anything that matches either P1 or
- P2. Calc first tries matching against P1; if that fails, it goes on to
- try P2.
- A simple example of `|||' is
- curve(inf ||| -inf) := 0
- which converts both `curve(inf)' and `curve(-inf)' to zero.
- Here is a larger example:
- log(a, b) ||| (ln(a) :: let(b := e)) := mylog(a, b)
- This matches both generalized and natural logarithms in a single
- rule. Note that the `::' term must be enclosed in parentheses because
- that operator has lower precedence than `|||' or `:='.
- (In practice this rule would probably include a third alternative,
- omitted here for brevity, to take care of `log10'.)
- While Calc generally treats interior conditions exactly the same as
- conditions on the outside of a rule, it does guarantee that if all the
- variables in the condition are special names like `e', or already bound
- in the pattern to which the condition is attached (say, if `a' had
- appeared in this condition), then Calc will process this condition
- right after matching the pattern to the left of the `::'. Thus, we
- know that `b' will be bound to `e' only if the `ln' branch of the `|||'
- was taken.
- Note that this rule was careful to bind the same set of
- meta-variables on both sides of the `|||'. Calc does not check this,
- but if you bind a certain meta-variable only in one branch and then use
- that meta-variable elsewhere in the rule, results are unpredictable:
- f(a,b) ||| g(b) := h(a,b)
- Here if the pattern matches `g(17)', Calc makes no promises about
- the value that will be substituted for `a' on the righthand side.
- The pattern `!!! PAT' matches anything that does not match PAT. Any
- meta-variables that are bound while matching PAT remain unbound outside
- of PAT.
- For example,
- f(x &&& !!! a +/- b, !!![]) := g(x)
- converts `f' whose first argument is anything _except_ an error form,
- and whose second argument is not the empty vector, into a similar call
- to `g' (but without the second argument).
- If we know that the second argument will be a vector (empty or not),
- then an equivalent rule would be:
- f(x, y) := g(x) :: typeof(x) != 7 :: vlen(y) > 0
- where of course 7 is the `typeof' code for error forms. Another final
- condition, that works for any kind of `y', would be `!istrue(y == [])'.
- (The `istrue' function returns an explicit 0 if its argument was left
- in symbolic form; plain `!(y == [])' or `y != []' would not work to
- replace `!!![]' since these would be left unsimplified, and thus cause
- the rule to fail, if `y' was something like a variable name.)
- It is possible for a `!!!' to refer to meta-variables bound
- elsewhere in the pattern. For example,
- f(a, !!!a) := g(a)
- matches any call to `f' with different arguments, changing this to `g'
- with only the first argument.
- If a function call is to be matched and one of the argument patterns
- contains a `!!!' somewhere inside it, that argument will be matched
- last. Thus
- f(!!!a, a) := g(a)
- will be careful to bind `a' to the second argument of `f' before
- testing the first argument. If Calc had tried to match the first
- argument of `f' first, the results would have been disastrous: since
- `a' was unbound so far, the pattern `a' would have matched anything at
- all, and the pattern `!!!a' therefore would _not_ have matched anything
- at all!
- File: calc, Node: Nested Formulas with Rewrite Rules, Next: Multi-Phase Rewrite Rules, Prev: Composing Patterns in Rewrite Rules, Up: Rewrite Rules
- 12.11.7 Nested Formulas with Rewrite Rules
- ------------------------------------------
- When `a r' (`calc-rewrite') is used, it takes an expression from the
- top of the stack and attempts to match any of the specified rules to
- any part of the expression, starting with the whole expression and
- then, if that fails, trying deeper and deeper sub-expressions. For
- each part of the expression, the rules are tried in the order they
- appear in the rules vector. The first rule to match the first
- sub-expression wins; it replaces the matched sub-expression according
- to the NEW part of the rule.
- Often, the rule set will match and change the formula several times.
- The top-level formula is first matched and substituted repeatedly until
- it no longer matches the pattern; then, sub-formulas are tried, and so
- on. Once every part of the formula has gotten its chance, the rewrite
- mechanism starts over again with the top-level formula (in case a
- substitution of one of its arguments has caused it again to match).
- This continues until no further matches can be made anywhere in the
- formula.
- It is possible for a rule set to get into an infinite loop. The
- most obvious case, replacing a formula with itself, is not a problem
- because a rule is not considered to "succeed" unless the righthand side
- actually comes out to something different than the original formula or
- sub-formula that was matched. But if you accidentally had both `ln(a
- b) := ln(a) + ln(b)' and the reverse `ln(a) + ln(b) := ln(a b)' in your
- rule set, Calc would run forever switching a formula back and forth
- between the two forms.
- To avoid disaster, Calc normally stops after 100 changes have been
- made to the formula. This will be enough for most multiple rewrites,
- but it will keep an endless loop of rewrites from locking up the
- computer forever. (On most systems, you can also type `C-g' to halt
- any Emacs command prematurely.)
- To change this limit, give a positive numeric prefix argument. In
- particular, `M-1 a r' applies only one rewrite at a time, useful when
- you are first testing your rule (or just if repeated rewriting is not
- what is called for by your application).
- You can also put a "function call" `iterations(N)' in place of a
- rule anywhere in your rules vector (but usually at the top). Then, N
- will be used instead of 100 as the default number of iterations for
- this rule set. You can use `iterations(inf)' if you want no iteration
- limit by default. A prefix argument will override the `iterations'
- limit in the rule set.
- [ iterations(1),
- f(x) := f(x+1) ]
- More precisely, the limit controls the number of "iterations," where
- each iteration is a successful matching of a rule pattern whose
- righthand side, after substituting meta-variables and applying the
- default simplifications, is different from the original sub-formula
- that was matched.
- A prefix argument of zero sets the limit to infinity. Use with
- caution!
- Given a negative numeric prefix argument, `a r' will match and
- substitute the top-level expression up to that many times, but will not
- attempt to match the rules to any sub-expressions.
- In a formula, `rewrite(EXPR, RULES, N)' does a rewriting operation.
- Here EXPR is the expression being rewritten, RULES is the rule, vector
- of rules, or variable containing the rules, and N is the optional
- iteration limit, which may be a positive integer, a negative integer,
- or `inf' or `-inf'. If N is omitted the `iterations' value from the
- rule set is used; if both are omitted, 100 is used.
- File: calc, Node: Multi-Phase Rewrite Rules, Next: Selections with Rewrite Rules, Prev: Nested Formulas with Rewrite Rules, Up: Rewrite Rules
- 12.11.8 Multi-Phase Rewrite Rules
- ---------------------------------
- It is possible to separate a rewrite rule set into several "phases".
- During each phase, certain rules will be enabled while certain others
- will be disabled. A "phase schedule" controls the order in which
- phases occur during the rewriting process.
- If a call to the marker function `phase' appears in the rules vector
- in place of a rule, all rules following that point will be members of
- the phase(s) identified in the arguments to `phase'. Phases are given
- integer numbers. The markers `phase()' and `phase(all)' both mean the
- following rules belong to all phases; this is the default at the start
- of the rule set.
- If you do not explicitly schedule the phases, Calc sorts all phase
- numbers that appear in the rule set and executes the phases in
- ascending order. For example, the rule set
- [ f0(x) := g0(x),
- phase(1),
- f1(x) := g1(x),
- phase(2),
- f2(x) := g2(x),
- phase(3),
- f3(x) := g3(x),
- phase(1,2),
- f4(x) := g4(x) ]
- has three phases, 1 through 3. Phase 1 consists of the `f0', `f1', and
- `f4' rules (in that order). Phase 2 consists of `f0', `f2', and `f4'.
- Phase 3 consists of `f0' and `f3'.
- When Calc rewrites a formula using this rule set, it first rewrites
- the formula using only the phase 1 rules until no further changes are
- possible. Then it switches to the phase 2 rule set and continues until
- no further changes occur, then finally rewrites with phase 3. When no
- more phase 3 rules apply, rewriting finishes. (This is assuming `a r'
- with a large enough prefix argument to allow the rewriting to run to
- completion; the sequence just described stops early if the number of
- iterations specified in the prefix argument, 100 by default, is
- reached.)
- During each phase, Calc descends through the nested levels of the
- formula as described previously. (*Note Nested Formulas with Rewrite
- Rules::.) Rewriting starts at the top of the formula, then works its
- way down to the parts, then goes back to the top and works down again.
- The phase 2 rules do not begin until no phase 1 rules apply anywhere in
- the formula.
- A `schedule' marker appearing in the rule set (anywhere, but
- conventionally at the top) changes the default schedule of phases. In
- the simplest case, `schedule' has a sequence of phase numbers for
- arguments; each phase number is invoked in turn until the arguments to
- `schedule' are exhausted. Thus adding `schedule(3,2,1)' at the top of
- the above rule set would reverse the order of the phases;
- `schedule(1,2,3)' would have no effect since this is the default
- schedule; and `schedule(1,2,1,3)' would give phase 1 a second chance
- after phase 2 has completed, before moving on to phase 3.
- Any argument to `schedule' can instead be a vector of phase numbers
- (or even of sub-vectors). Then the sub-sequence of phases described by
- the vector are tried repeatedly until no change occurs in any phase in
- the sequence. For example, `schedule([1, 2], 3)' tries phase 1, then
- phase 2, then, if either phase made any changes to the formula, repeats
- these two phases until they can make no further progress. Finally, it
- goes on to phase 3 for finishing touches.
- Also, items in `schedule' can be variable names as well as numbers.
- A variable name is interpreted as the name of a function to call on the
- whole formula. For example, `schedule(1, simplify)' says to apply the
- phase-1 rules (presumably, all of them), then to call `simplify' which
- is the function name equivalent of `a s'. Likewise, `schedule([1,
- simplify])' says to alternate between phase 1 and `a s' until no
- further changes occur.
- Phases can be used purely to improve efficiency; if it is known that
- a certain group of rules will apply only at the beginning of rewriting,
- and a certain other group will apply only at the end, then rewriting
- will be faster if these groups are identified as separate phases. Once
- the phase 1 rules are done, Calc can put them aside and no longer spend
- any time on them while it works on phase 2.
- There are also some problems that can only be solved with several
- rewrite phases. For a real-world example of a multi-phase rule set,
- examine the set `FitRules', which is used by the curve-fitting command
- to convert a model expression to linear form. *Note Curve Fitting
- Details::. This set is divided into four phases. The first phase
- rewrites certain kinds of expressions to be more easily linearizable,
- but less computationally efficient. After the linear components have
- been picked out, the final phase includes the opposite rewrites to put
- each component back into an efficient form. If both sets of rules were
- included in one big phase, Calc could get into an infinite loop going
- back and forth between the two forms.
- Elsewhere in `FitRules', the components are first isolated, then
- recombined where possible to reduce the complexity of the linear fit,
- then finally packaged one component at a time into vectors. If the
- packaging rules were allowed to begin before the recombining rules were
- finished, some components might be put away into vectors before they
- had a chance to recombine. By putting these rules in two separate
- phases, this problem is neatly avoided.
- File: calc, Node: Selections with Rewrite Rules, Next: Matching Commands, Prev: Multi-Phase Rewrite Rules, Up: Rewrite Rules
- 12.11.9 Selections with Rewrite Rules
- -------------------------------------
- If a sub-formula of the current formula is selected (as by `j s'; *note
- Selecting Subformulas::), the `a r' (`calc-rewrite') command applies
- only to that sub-formula. Together with a negative prefix argument,
- you can use this fact to apply a rewrite to one specific part of a
- formula without affecting any other parts.
- The `j r' (`calc-rewrite-selection') command allows more
- sophisticated operations on selections. This command prompts for the
- rules in the same way as `a r', but it then applies those rules to the
- whole formula in question even though a sub-formula of it has been
- selected. However, the selected sub-formula will first have been
- surrounded by a `select( )' function call. (Calc's evaluator does not
- understand the function name `select'; this is only a tag used by the
- `j r' command.)
- For example, suppose the formula on the stack is `2 (a + b)^2' and
- the sub-formula `a + b' is selected. This formula will be rewritten to
- `2 select(a + b)^2' and then the rewrite rules will be applied in the
- usual way. The rewrite rules can include references to `select' to
- tell where in the pattern the selected sub-formula should appear.
- If there is still exactly one `select( )' function call in the
- formula after rewriting is done, it indicates which part of the formula
- should be selected afterwards. Otherwise, the formula will be
- unselected.
- You can make `j r' act much like `a r' by enclosing both parts of
- the rewrite rule with `select()'. However, `j r' allows you to use the
- current selection in more flexible ways. Suppose you wished to make a
- rule which removed the exponent from the selected term; the rule
- `select(a)^x := select(a)' would work. In the above example, it would
- rewrite `2 select(a + b)^2' to `2 select(a + b)'. This would then be
- returned to the stack as `2 (a + b)' with the `a + b' selected.
- The `j r' command uses one iteration by default, unlike `a r' which
- defaults to 100 iterations. A numeric prefix argument affects `j r' in
- the same way as `a r'. *Note Nested Formulas with Rewrite Rules::.
- As with other selection commands, `j r' operates on the stack entry
- that contains the cursor. (If the cursor is on the top-of-stack `.'
- marker, it works as if the cursor were on the formula at stack level 1.)
- If you don't specify a set of rules, the rules are taken from the
- top of the stack, just as with `a r'. In this case, the cursor must
- indicate stack entry 2 or above as the formula to be rewritten
- (otherwise the same formula would be used as both the target and the
- rewrite rules).
- If the indicated formula has no selection, the cursor position within
- the formula temporarily selects a sub-formula for the purposes of this
- command. If the cursor is not on any sub-formula (e.g., it is in the
- line-number area to the left of the formula), the `select( )' markers
- are ignored by the rewrite mechanism and the rules are allowed to apply
- anywhere in the formula.
- As a special feature, the normal `a r' command also ignores `select(
- )' calls in rewrite rules. For example, if you used the above rule
- `select(a)^x := select(a)' with `a r', it would apply the rule as if it
- were `a^x := a'. Thus, you can write general purpose rules with
- `select( )' hints inside them so that they will "do the right thing" in
- both `a r' and `j r', both with and without selections.
- File: calc, Node: Matching Commands, Next: Automatic Rewrites, Prev: Selections with Rewrite Rules, Up: Rewrite Rules
- 12.11.10 Matching Commands
- --------------------------
- The `a m' (`calc-match') [`match'] function takes a vector of formulas
- and a rewrite-rule-style pattern, and produces a vector of all formulas
- which match the pattern. The command prompts you to enter the pattern;
- as for `a r', you can enter a single pattern (i.e., a formula with
- meta-variables), or a vector of patterns, or a variable which contains
- patterns, or you can give a blank response in which case the patterns
- are taken from the top of the stack. The pattern set will be compiled
- once and saved if it is stored in a variable. If there are several
- patterns in the set, vector elements are kept if they match any of the
- patterns.
- For example, `match(a+b, [x, x+y, x-y, 7, x+y+z])' will return
- `[x+y, x-y, x+y+z]'.
- The `import' mechanism is not available for pattern sets.
- The `a m' command can also be used to extract all vector elements
- which satisfy any condition: The pattern `x :: x>0' will select all
- the positive vector elements.
- With the Inverse flag [`matchnot'], this command extracts all vector
- elements which do _not_ match the given pattern.
- There is also a function `matches(X, P)' which evaluates to 1 if
- expression X matches pattern P, or to 0 otherwise. This is sometimes
- useful for including into the conditional clauses of other rewrite
- rules.
- The function `vmatches' is just like `matches', except that if the
- match succeeds it returns a vector of assignments to the meta-variables
- instead of the number 1. For example, `vmatches(f(1,2), f(a,b))'
- returns `[a := 1, b := 2]'. If the match fails, the function returns
- the number 0.
- File: calc, Node: Automatic Rewrites, Next: Debugging Rewrites, Prev: Matching Commands, Up: Rewrite Rules
- 12.11.11 Automatic Rewrites
- ---------------------------
- It is possible to get Calc to apply a set of rewrite rules on all
- results, effectively adding to the built-in set of default
- simplifications. To do this, simply store your rule set in the
- variable `EvalRules'. There is a convenient `s E' command for editing
- `EvalRules'; *note Operations on Variables::.
- For example, suppose you want `sin(a + b)' to be expanded out to
- `sin(b) cos(a) + cos(b) sin(a)' wherever it appears, and similarly for
- `cos(a + b)'. The corresponding rewrite rule set would be,
- [ sin(a + b) := cos(a) sin(b) + sin(a) cos(b),
- cos(a + b) := cos(a) cos(b) - sin(a) sin(b) ]
- To apply these manually, you could put them in a variable called
- `trigexp' and then use `a r trigexp' every time you wanted to expand
- trig functions. But if instead you store them in the variable
- `EvalRules', they will automatically be applied to all sines and
- cosines of sums. Then, with `2 x' and `45' on the stack, typing `+ S'
- will (assuming Degrees mode) result in `0.7071 sin(2 x) + 0.7071 cos(2
- x)' automatically.
- As each level of a formula is evaluated, the rules from `EvalRules'
- are applied before the default simplifications. Rewriting continues
- until no further `EvalRules' apply. Note that this is different from
- the usual order of application of rewrite rules: `EvalRules' works
- from the bottom up, simplifying the arguments to a function before the
- function itself, while `a r' applies rules from the top down.
- Because the `EvalRules' are tried first, you can use them to
- override the normal behavior of any built-in Calc function.
- It is important not to write a rule that will get into an infinite
- loop. For example, the rule set `[f(0) := 1, f(n) := n f(n-1)]'
- appears to be a good definition of a factorial function, but it is
- unsafe. Imagine what happens if `f(2.5)' is simplified. Calc will
- continue to subtract 1 from this argument forever without reaching
- zero. A safer second rule would be `f(n) := n f(n-1) :: n>0'. Another
- dangerous rule is `g(x, y) := g(y, x)'. Rewriting `g(2, 4)', this
- would bounce back and forth between that and `g(4, 2)' forever. If an
- infinite loop in `EvalRules' occurs, Emacs will eventually stop with a
- "Computation got stuck or ran too long" message.
- Another subtle difference between `EvalRules' and regular rewrites
- concerns rules that rewrite a formula into an identical formula. For
- example, `f(n) := f(floor(n))' "fails to match" when `n' is already an
- integer. But in `EvalRules' this case is detected only if the
- righthand side literally becomes the original formula before any
- further simplification. This means that `f(n) := f(floor(n))' will get
- into an infinite loop if it occurs in `EvalRules'. Calc will replace
- `f(6)' with `f(floor(6))', which is different from `f(6)', so it will
- consider the rule to have matched and will continue simplifying that
- formula; first the argument is simplified to get `f(6)', then the rule
- matches again to get `f(floor(6))' again, ad infinitum. A much safer
- rule would check its argument first, say, with `f(n) := f(floor(n)) ::
- !dint(n)'.
- (What really happens is that the rewrite mechanism substitutes the
- meta-variables in the righthand side of a rule, compares to see if the
- result is the same as the original formula and fails if so, then uses
- the default simplifications to simplify the result and compares again
- (and again fails if the formula has simplified back to its original
- form). The only special wrinkle for the `EvalRules' is that the same
- rules will come back into play when the default simplifications are
- used. What Calc wants to do is build `f(floor(6))', see that this is
- different from the original formula, simplify to `f(6)', see that this
- is the same as the original formula, and thus halt the rewriting. But
- while simplifying, `f(6)' will again trigger the same `EvalRules' rule
- and Calc will get into a loop inside the rewrite mechanism itself.)
- The `phase', `schedule', and `iterations' markers do not work in
- `EvalRules'. If the rule set is divided into phases, only the phase 1
- rules are applied, and the schedule is ignored. The rules are always
- repeated as many times as possible.
- The `EvalRules' are applied to all function calls in a formula, but
- not to numbers (and other number-like objects like error forms), nor to
- vectors or individual variable names. (Though they will apply to
- _components_ of vectors and error forms when appropriate.) You might
- try to make a variable `phihat' which automatically expands to its
- definition without the need to press `=' by writing the rule
- `quote(phihat) := (1-sqrt(5))/2', but unfortunately this rule will not
- work as part of `EvalRules'.
- Finally, another limitation is that Calc sometimes calls its built-in
- functions directly rather than going through the default
- simplifications. When it does this, `EvalRules' will not be able to
- override those functions. For example, when you take the absolute
- value of the complex number `(2, 3)', Calc computes `sqrt(2*2 + 3*3)'
- by calling the multiplication, addition, and square root functions
- directly rather than applying the default simplifications to this
- formula. So an `EvalRules' rule that (perversely) rewrites `sqrt(13)
- := 6' would not apply. (However, if you put Calc into Symbolic mode so
- that `sqrt(13)' will be left in symbolic form by the built-in square
- root function, your rule will be able to apply. But if the complex
- number were `(3,4)', so that `sqrt(25)' must be calculated, then
- Symbolic mode will not help because `sqrt(25)' can be evaluated exactly
- to 5.)
- One subtle restriction that normally only manifests itself with
- `EvalRules' is that while a given rewrite rule is in the process of
- being checked, that same rule cannot be recursively applied. Calc
- effectively removes the rule from its rule set while checking the rule,
- then puts it back once the match succeeds or fails. (The technical
- reason for this is that compiled pattern programs are not reentrant.)
- For example, consider the rule `foo(x) := x :: foo(x/2) > 0' attempting
- to match `foo(8)'. This rule will be inactive while the condition
- `foo(4) > 0' is checked, even though it might be an integral part of
- evaluating that condition. Note that this is not a problem for the
- more usual recursive type of rule, such as `foo(x) := foo(x/2)',
- because there the rule has succeeded and been reactivated by the time
- the righthand side is evaluated.
- If `EvalRules' has no stored value (its default state), or if
- anything but a vector is stored in it, then it is ignored.
- Even though Calc's rewrite mechanism is designed to compare rewrite
- rules to formulas as quickly as possible, storing rules in `EvalRules'
- may make Calc run substantially slower. This is particularly true of
- rules where the top-level call is a commonly used function, or is not
- fixed. The rule `f(n) := n f(n-1) :: n>0' will only activate the
- rewrite mechanism for calls to the function `f', but `lg(n) + lg(m) :=
- lg(n m)' will check every `+' operator.
- apply(f, [a*b]) := apply(f, [a]) + apply(f, [b]) :: in(f, [ln, log10])
- may seem more "efficient" than two separate rules for `ln' and `log10',
- but actually it is vastly less efficient because rules with `apply' as
- the top-level pattern must be tested against _every_ function call that
- is simplified.
- Suppose you want `sin(a + b)' to be expanded out not all the time,
- but only when `a s' is used to simplify the formula. The variable
- `AlgSimpRules' holds rules for this purpose. The `a s' command will
- apply `EvalRules' and `AlgSimpRules' to the formula, as well as all of
- its built-in simplifications.
- Most of the special limitations for `EvalRules' don't apply to
- `AlgSimpRules'. Calc simply does an `a r AlgSimpRules' command with an
- infinite repeat count as the first step of `a s'. It then applies its
- own built-in simplifications throughout the formula, and then repeats
- these two steps (along with applying the default simplifications) until
- no further changes are possible.
- There are also `ExtSimpRules' and `UnitSimpRules' variables that are
- used by `a e' and `u s', respectively; these commands also apply
- `EvalRules' and `AlgSimpRules'. The variable `IntegSimpRules' contains
- simplification rules that are used only during integration by `a i'.
- File: calc, Node: Debugging Rewrites, Next: Examples of Rewrite Rules, Prev: Automatic Rewrites, Up: Rewrite Rules
- 12.11.12 Debugging Rewrites
- ---------------------------
- If a buffer named `*Trace*' exists, the rewrite mechanism will record
- some useful information there as it operates. The original formula is
- written there, as is the result of each successful rewrite, and the
- final result of the rewriting. All phase changes are also noted.
- Calc always appends to `*Trace*'. You must empty this buffer
- yourself periodically if it is in danger of growing unwieldy.
- Note that the rewriting mechanism is substantially slower when the
- `*Trace*' buffer exists, even if the buffer is not visible on the
- screen. Once you are done, you will probably want to kill this buffer
- (with `C-x k *Trace* <RET>'). If you leave it in existence and forget
- about it, all your future rewrite commands will be needlessly slow.
- File: calc, Node: Examples of Rewrite Rules, Prev: Debugging Rewrites, Up: Rewrite Rules
- 12.11.13 Examples of Rewrite Rules
- ----------------------------------
- Returning to the example of substituting the pattern `sin(x)^2 +
- cos(x)^2' with 1, we saw that the rule `opt(a) sin(x)^2 + opt(a)
- cos(x)^2 := a' does a good job of finding suitable cases. Another
- solution would be to use the rule `cos(x)^2 := 1 - sin(x)^2', followed
- by algebraic simplification if necessary. This rule will be the most
- effective way to do the job, but at the expense of making some changes
- that you might not desire.
- Another algebraic rewrite rule is `exp(x+y) := exp(x) exp(y)'. To
- make this work with the `j r' command so that it can be easily targeted
- to a particular exponential in a large formula, you might wish to write
- the rule as `select(exp(x+y)) := select(exp(x) exp(y))'. The `select'
- markers will be ignored by the regular `a r' command (*note Selections
- with Rewrite Rules::).
- A surprisingly useful rewrite rule is `a/(b-c) := a*(b+c)/(b^2-c^2)'.
- This will simplify the formula whenever `b' and/or `c' can be made
- simpler by squaring. For example, applying this rule to `2 / (sqrt(2)
- + 3)' yields `6:7 - 2:7 sqrt(2)' (assuming Symbolic mode has been
- enabled to keep the square root from being evaluated to a
- floating-point approximation). This rule is also useful when working
- with symbolic complex numbers, e.g., `(a + b i) / (c + d i)'.
- As another example, we could define our own "triangular numbers"
- function with the rules `[tri(0) := 0, tri(n) := n + tri(n-1) :: n>0]'.
- Enter this vector and store it in a variable: `s t trirules'. Now,
- given a suitable formula like `tri(5)' on the stack, type `a r trirules'
- to apply these rules repeatedly. After six applications, `a r' will
- stop with 15 on the stack. Once these rules are debugged, it would
- probably be most useful to add them to `EvalRules' so that Calc will
- evaluate the new `tri' function automatically. We could then use `Z K'
- on the keyboard macro `' tri($) <RET>' to make a command that applies
- `tri' to the value on the top of the stack. *Note Programming::.
- The following rule set, contributed by Francois Pinard, implements
- "quaternions", a generalization of the concept of complex numbers.
- Quaternions have four components, and are here represented by function
- calls `quat(W, [X, Y, Z])' with "real part" W and the three "imaginary"
- parts collected into a vector. Various arithmetical operations on
- quaternions are supported. To use these rules, either add them to
- `EvalRules', or create a command based on `a r' for simplifying
- quaternion formulas. A convenient way to enter quaternions would be a
- command defined by a keyboard macro containing: `' quat($$$$, [$$$, $$,
- $]) <RET>'.
- [ quat(w, x, y, z) := quat(w, [x, y, z]),
- quat(w, [0, 0, 0]) := w,
- abs(quat(w, v)) := hypot(w, v),
- -quat(w, v) := quat(-w, -v),
- r + quat(w, v) := quat(r + w, v) :: real(r),
- r - quat(w, v) := quat(r - w, -v) :: real(r),
- quat(w1, v1) + quat(w2, v2) := quat(w1 + w2, v1 + v2),
- r * quat(w, v) := quat(r * w, r * v) :: real(r),
- plain(quat(w1, v1) * quat(w2, v2))
- := quat(w1 * w2 - v1 * v2, w1 * v2 + w2 * v1 + cross(v1, v2)),
- quat(w1, v1) / r := quat(w1 / r, v1 / r) :: real(r),
- z / quat(w, v) := z * quatinv(quat(w, v)),
- quatinv(quat(w, v)) := quat(w, -v) / (w^2 + v^2),
- quatsqr(quat(w, v)) := quat(w^2 - v^2, 2 * w * v),
- quat(w, v)^k := quatsqr(quat(w, v)^(k / 2))
- :: integer(k) :: k > 0 :: k % 2 = 0,
- quat(w, v)^k := quatsqr(quat(w, v)^((k - 1) / 2)) * quat(w, v)
- :: integer(k) :: k > 2,
- quat(w, v)^-k := quatinv(quat(w, v)^k) :: integer(k) :: k > 0 ]
- Quaternions, like matrices, have non-commutative multiplication. In
- other words, `q1 * q2 = q2 * q1' is not necessarily true if `q1' and
- `q2' are `quat' forms. The `quat*quat' rule above uses `plain' to
- prevent Calc from rearranging the product. It may also be wise to add
- the line `[quat(), matrix]' to the `Decls' matrix, to ensure that
- Calc's other algebraic operations will not rearrange a quaternion
- product. *Note Declarations::.
- These rules also accept a four-argument `quat' form, converting it
- to the preferred form in the first rule. If you would rather see
- results in the four-argument form, just append the two items `phase(2),
- quat(w, [x, y, z]) := quat(w, x, y, z)' to the end of the rule set.
- (But remember that multi-phase rule sets don't work in `EvalRules'.)
- File: calc, Node: Units, Next: Store and Recall, Prev: Algebra, Up: Top
- 13 Operating on Units
- *********************
- One special interpretation of algebraic formulas is as numbers with
- units. For example, the formula `5 m / s^2' can be read "five meters
- per second squared." The commands in this chapter help you manipulate
- units expressions in this form. Units-related commands begin with the
- `u' prefix key.
- * Menu:
- * Basic Operations on Units::
- * The Units Table::
- * Predefined Units::
- * User-Defined Units::
- * Logarithmic Units::
- * Musical Notes::
- File: calc, Node: Basic Operations on Units, Next: The Units Table, Prev: Units, Up: Units
- 13.1 Basic Operations on Units
- ==============================
- A "units expression" is a formula which is basically a number
- multiplied and/or divided by one or more "unit names", which may
- optionally be raised to integer powers. Actually, the value part need
- not be a number; any product or quotient involving unit names is a units
- expression. Many of the units commands will also accept any formula,
- where the command applies to all units expressions which appear in the
- formula.
- A unit name is a variable whose name appears in the "unit table", or
- a variable whose name is a prefix character like `k' (for "kilo") or
- `u' (for "micro") followed by a name in the unit table. A substantial
- table of built-in units is provided with Calc; *note Predefined
- Units::. You can also define your own unit names; *note User-Defined
- Units::.
- Note that if the value part of a units expression is exactly `1', it
- will be removed by the Calculator's automatic algebra routines: The
- formula `1 mm' is "simplified" to `mm'. This is only a display
- anomaly, however; `mm' will work just fine as a representation of one
- millimeter.
- You may find that Algebraic mode (*note Algebraic Entry::) makes
- working with units expressions easier. Otherwise, you will have to
- remember to hit the apostrophe key every time you wish to enter units.
- The `u s' (`calc-simplify-units') [`usimplify'] command simplifies a
- units expression. It uses `a s' (`calc-simplify') to simplify the
- expression first as a regular algebraic formula; it then looks for
- features that can be further simplified by converting one object's units
- to be compatible with another's. For example, `5 m + 23 mm' will
- simplify to `5.023 m'. When different but compatible units are added,
- the righthand term's units are converted to match those of the lefthand
- term. *Note Simplification Modes::, for a way to have this done
- automatically at all times.
- Units simplification also handles quotients of two units with the
- same dimensionality, as in `2 in s/L cm' to `5.08 s/L'; fractional
- powers of unit expressions, as in `sqrt(9 mm^2)' to `3 mm' and `sqrt(9
- acre)' to a quantity in meters; and `floor', `ceil', `round', `rounde',
- `roundu', `trunc', `float', `frac', `abs', and `clean' applied to units
- expressions, in which case the operation in question is applied only to
- the numeric part of the expression. Finally, trigonometric functions
- of quantities with units of angle are evaluated, regardless of the
- current angular mode.
- The `u c' (`calc-convert-units') command converts a units expression
- to new, compatible units. For example, given the units expression `55
- mph', typing `u c m/s <RET>' produces `24.5872 m/s'. If you have
- previously converted a units expression with the same type of units (in
- this case, distance over time), you will be offered the previous choice
- of new units as a default. Continuing the above example, entering the
- units expression `100 km/hr' and typing `u c <RET>' (without specifying
- new units) produces `27.7777777778 m/s'.
- The `u c' command treats temperature units (like `degC' and `K') as
- relative temperatures. For example, `u c' converts `10 degC' to `18
- degF': A change of 10 degrees Celsius corresponds to a change of 18
- degrees Fahrenheit. To convert absolute temperatures, you can use the
- `u t' (`calc-convert-temperature') command. The value on the stack
- must be a simple units expression with units of temperature only. This
- command would convert `10 degC' to `50 degF', the equivalent
- temperature on the Fahrenheit scale.
- While many of Calc's conversion factors are exact, some are
- necessarily approximate. If Calc is in fraction mode (*note Fraction
- Mode::), then unit conversions will try to give exact, rational
- conversions, but it isn't always possible. Given `55 mph' in fraction
- mode, typing `u c m/s <RET>' produces `15367:625 m/s', for example,
- while typing `u c au/yr <RET>' produces `5.18665819999e-3 au/yr'.
- If the units you request are inconsistent with the original units,
- the number will be converted into your units times whatever "remainder"
- units are left over. For example, converting `55 mph' into acres
- produces `6.08e-3 acre / m s'. (Recall that multiplication binds more
- strongly than division in Calc formulas, so the units here are acres
- per meter-second.) Remainder units are expressed in terms of
- "fundamental" units like `m' and `s', regardless of the input units.
- One special exception is that if you specify a single unit name, and
- a compatible unit appears somewhere in the units expression, then that
- compatible unit will be converted to the new unit and the remaining
- units in the expression will be left alone. For example, given the
- input `980 cm/s^2', the command `u c ms' will change the `s' to `ms' to
- get `9.8e-4 cm/ms^2'. The "remainder unit" `cm' is left alone rather
- than being changed to the base unit `m'.
- You can use explicit unit conversion instead of the `u s' command to
- gain more control over the units of the result of an expression. For
- example, given `5 m + 23 mm', you can type `u c m' or `u c mm' to
- express the result in either meters or millimeters. (For that matter,
- you could type `u c fath' to express the result in fathoms, if you
- preferred!)
- In place of a specific set of units, you can also enter one of the
- units system names `si', `mks' (equivalent), or `cgs'. For example, `u
- c si <RET>' converts the expression into International System of Units
- (SI) base units. Also, `u c base' converts to Calc's base units, which
- are the same as `si' units except that `base' uses `g' as the
- fundamental unit of mass whereas `si' uses `kg'.
- The `u c' command also accepts "composite units", which are
- expressed as the sum of several compatible unit names. For example,
- converting `30.5 in' to units `mi+ft+in' (miles, feet, and inches)
- produces `2 ft + 6.5 in'. Calc first sorts the unit names into order
- of decreasing relative size. It then accounts for as much of the input
- quantity as it can using an integer number times the largest unit, then
- moves on to the next smaller unit, and so on. Only the smallest unit
- may have a non-integer amount attached in the result. A few standard
- unit names exist for common combinations, such as `mfi' for `mi+ft+in',
- and `tpo' for `ton+lb+oz'. Composite units are expanded as if by `a
- x', so that `(ft+in)/hr' is first converted to `ft/hr+in/hr'.
- If the value on the stack does not contain any units, `u c' will
- prompt first for the old units which this value should be considered to
- have, then for the new units. Assuming the old and new units you give
- are consistent with each other, the result also will not contain any
- units. For example, `u c cm <RET> in <RET>' converts the number 2 on
- the stack to 5.08.
- The `u b' (`calc-base-units') command is shorthand for `u c base';
- it converts the units expression on the top of the stack into `base'
- units. If `u s' does not simplify a units expression as far as you
- would like, try `u b'.
- Like the `u c' command, the `u b' command treats temperature units
- as relative temperatures.
- The `u r' (`calc-remove-units') command removes units from the
- formula at the top of the stack. The `u x' (`calc-extract-units')
- command extracts only the units portion of a formula. These commands
- essentially replace every term of the formula that does or doesn't
- (respectively) look like a unit name by the constant 1, then resimplify
- the formula.
- The `u a' (`calc-autorange-units') command turns on and off a mode
- in which unit prefixes like `k' ("kilo") are automatically applied to
- keep the numeric part of a units expression in a reasonable range.
- This mode affects `u s' and all units conversion commands except `u b'.
- For example, with autoranging on, `12345 Hz' will be simplified to
- `12.345 kHz'. Autoranging is useful for some kinds of units (like `Hz'
- and `m'), but is probably undesirable for non-metric units like `ft'
- and `tbsp'. (Composite units are more appropriate for those; see
- above.)
- Autoranging always applies the prefix to the leftmost unit name.
- Calc chooses the largest prefix that causes the number to be greater
- than or equal to 1.0. Thus an increasing sequence of adjusted times
- would be `1 ms, 10 ms, 100 ms, 1 s, 10 s, 100 s, 1 ks'. Generally the
- rule of thumb is that the number will be adjusted to be in the interval
- `[1 .. 1000)', although there are several exceptions to this rule.
- First, if the unit has a power then this is not possible; `0.1 s^2'
- simplifies to `100000 ms^2'. Second, the "centi-" prefix is allowed to
- form `cm' (centimeters), but will not apply to other units. The
- "deci-," "deka-," and "hecto-" prefixes are never used. Thus the
- allowable interval is `[1 .. 10)' for millimeters and `[1 .. 100)' for
- centimeters. Finally, a prefix will not be added to a unit if the
- resulting name is also the actual name of another unit; `1e-15 t' would
- normally be considered a "femto-ton," but it is written as `1000 at'
- (1000 atto-tons) instead because `ft' would be confused with feet.
- File: calc, Node: The Units Table, Next: Predefined Units, Prev: Basic Operations on Units, Up: Units
- 13.2 The Units Table
- ====================
- The `u v' (`calc-enter-units-table') command displays the units table
- in another buffer called `*Units Table*'. Each entry in this table
- gives the unit name as it would appear in an expression, the definition
- of the unit in terms of simpler units, and a full name or description of
- the unit. Fundamental units are defined as themselves; these are the
- units produced by the `u b' command. The fundamental units are meters,
- seconds, grams, kelvins, amperes, candelas, moles, radians, and
- steradians.
- The Units Table buffer also displays the Unit Prefix Table. Note
- that two prefixes, "kilo" and "hecto," accept either upper- or
- lower-case prefix letters. `Meg' is also accepted as a synonym for the
- `M' prefix. Whenever a unit name can be interpreted as either a
- built-in name or a prefix followed by another built-in name, the former
- interpretation wins. For example, `2 pt' means two pints, not two
- pico-tons.
- The Units Table buffer, once created, is not rebuilt unless you
- define new units. To force the buffer to be rebuilt, give any numeric
- prefix argument to `u v'.
- The `u V' (`calc-view-units-table') command is like `u v' except
- that the cursor is not moved into the Units Table buffer. You can type
- `u V' again to remove the Units Table from the display. To return from
- the Units Table buffer after a `u v', type `C-x * c' again or use the
- regular Emacs `C-x o' (`other-window') command. You can also kill the
- buffer with `C-x k' if you wish; the actual units table is safely
- stored inside the Calculator.
- The `u g' (`calc-get-unit-definition') command retrieves a unit's
- defining expression and pushes it onto the Calculator stack. For
- example, `u g in' will produce the expression `2.54 cm'. This is the
- same definition for the unit that would appear in the Units Table
- buffer. Note that this command works only for actual unit names; `u g
- km' will report that no such unit exists, for example, because `km' is
- really the unit `m' with a `k' ("kilo") prefix. To see a definition of
- a unit in terms of base units, it is easier to push the unit name on
- the stack and then reduce it to base units with `u b'.
- The `u e' (`calc-explain-units') command displays an English
- description of the units of the expression on the stack. For example,
- for the expression `62 km^2 g / s^2 mol K', the description is
- "Square-Kilometer Gram per (Second-squared Mole Degree-Kelvin)." This
- command uses the English descriptions that appear in the righthand
- column of the Units Table.
- File: calc, Node: Predefined Units, Next: User-Defined Units, Prev: The Units Table, Up: Units
- 13.3 Predefined Units
- =====================
- The definitions of many units have changed over the years. For example,
- the meter was originally defined in 1791 as one ten-millionth of the
- distance from the equator to the north pole. In order to be more
- precise, the definition was adjusted several times, and now a meter is
- defined as the distance that light will travel in a vacuum in
- 1/299792458 of a second; consequently, the speed of light in a vacuum
- is exactly 299792458 m/s. Many other units have been redefined in
- terms of fundamental physical processes; a second, for example, is
- currently defined as 9192631770 periods of a certain radiation related
- to the cesium-133 atom. The only SI unit that is not based on a
- fundamental physical process (although there are efforts to change
- this) is the kilogram, which was originally defined as the mass of one
- liter of water, but is now defined as the mass of the International
- Prototype Kilogram (IPK), a cylinder of platinum-iridium kept at the
- Bureau International des Poids et Mesures in Se`vres, France. (There
- are several copies of the IPK throughout the world.) The British
- imperial units, once defined in terms of physical objects, were
- redefined in 1963 in terms of SI units. The US customary units, which
- were the same as British units until the British imperial system was
- created in 1824, were also defined in terms of the SI units in 1893.
- Because of these redefinitions, conversions between metric, British
- Imperial, and US customary units can often be done precisely.
- Since the exact definitions of many kinds of units have evolved over
- the years, and since certain countries sometimes have local differences
- in their definitions, it is a good idea to examine Calc's definition of
- a unit before depending on its exact value. For example, there are
- three different units for gallons, corresponding to the US (`gal'),
- Canadian (`galC'), and British (`galUK') definitions. Also, note that
- `oz' is a standard ounce of mass, `ozt' is a Troy ounce, and `ozfl' is
- a fluid ounce.
- The temperature units corresponding to degrees Kelvin and Centigrade
- (Celsius) are the same in this table, since most units commands treat
- temperatures as being relative. The `calc-convert-temperature' command
- has special rules for handling the different absolute magnitudes of the
- various temperature scales.
- The unit of volume "liters" can be referred to by either the
- lower-case `l' or the upper-case `L'.
- The unit `A' stands for Amperes; the name `Ang' is used for
- Angstroms.
- The unit `pt' stands for pints; the name `point' stands for a
- typographical point, defined by `72 point = 1 in'. This is slightly
- different than the point defined by the American Typefounder's
- Association in 1886, but the point used by Calc has become standard
- largely due to its use by the PostScript page description language.
- There is also `texpt', which stands for a printer's point as defined by
- the TeX typesetting system: `72.27 texpt = 1 in'. Other units used by
- TeX are available; they are `texpc' (a pica), `texbp' (a "big point",
- equal to a standard point which is larger than the point used by TeX),
- `texdd' (a Didot point), `texcc' (a Cicero) and `texsp' (a scaled TeX
- point, all dimensions representable in TeX are multiples of this value).
- When Calc is using the TeX or LaTeX language mode (*note TeX and
- LaTeX Language Modes::), the TeX specific unit names will not use the
- `tex' prefix; the unit name for a TeX point will be `pt' instead of
- `texpt', for example. To avoid conflicts, the unit names for pint and
- parsec will simply be `pint' and `parsec' instead of `pt' and `pc'.
- The unit `e' stands for the elementary (electron) unit of charge;
- because algebra command could mistake this for the special constant
- `e', Calc provides the alternate unit name `ech' which is preferable to
- `e'.
- The name `g' stands for one gram of mass; there is also `gf', one
- gram of force. (Likewise for `lb', pounds, and `lbf'.) Meanwhile, one
- "`g'" of acceleration is denoted `ga'.
- The unit `ton' is a U.S. ton of `2000 lb', and `t' is a metric ton
- of `1000 kg'.
- The names `s' (or `sec') and `min' refer to units of time; `arcsec'
- and `arcmin' are units of angle.
- Some "units" are really physical constants; for example, `c'
- represents the speed of light, and `h' represents Planck's constant.
- You can use these just like other units: converting `.5 c' to `m/s'
- expresses one-half the speed of light in meters per second. You can
- also use this merely as a handy reference; the `u g' command gets the
- definition of one of these constants in its normal terms, and `u b'
- expresses the definition in base units.
- Two units, `pi' and `alpha' (the fine structure constant,
- approximately 1/137) are dimensionless. The units simplification
- commands simply treat these names as equivalent to their corresponding
- values. However you can, for example, use `u c' to convert a pure
- number into multiples of the fine structure constant, or `u b' to
- convert this back into a pure number. (When `u c' prompts for the "old
- units," just enter a blank line to signify that the value really is
- unitless.)
- File: calc, Node: User-Defined Units, Next: Logarithmic Units, Prev: Predefined Units, Up: Units
- 13.4 User-Defined Units
- =======================
- Calc provides ways to get quick access to your selected "favorite"
- units, as well as ways to define your own new units.
- To select your favorite units, store a vector of unit names or
- expressions in the Calc variable `Units'. The `u 1' through `u 9'
- commands (`calc-quick-units') provide access to these units. If the
- value on the top of the stack is a plain number (with no units
- attached), then `u 1' gives it the specified units. (Basically, it
- multiplies the number by the first item in the `Units' vector.) If the
- number on the stack _does_ have units, then `u 1' converts that number
- to the new units. For example, suppose the vector `[in, ft]' is stored
- in `Units'. Then `30 u 1' will create the expression `30 in', and `u
- 2' will convert that expression to `2.5 ft'.
- The `u 0' command accesses the tenth element of `Units'. Only ten
- quick units may be defined at a time. If the `Units' variable has no
- stored value (the default), or if its value is not a vector, then the
- quick-units commands will not function. The `s U' command is a
- convenient way to edit the `Units' variable; *note Operations on
- Variables::.
- The `u d' (`calc-define-unit') command records the units expression
- on the top of the stack as the definition for a new, user-defined unit.
- For example, putting `16.5 ft' on the stack and typing `u d rod'
- defines the new unit `rod' to be equivalent to 16.5 feet. The unit
- conversion and simplification commands will now treat `rod' just like
- any other unit of length. You will also be prompted for an optional
- English description of the unit, which will appear in the Units Table.
- If you wish the definition of this unit to be displayed in a special
- way in the Units Table buffer (such as with an asterisk to indicate an
- approximate value), then you can call this command with an argument,
- `C-u u d'; you will then also be prompted for a string that will be
- used to display the definition.
- The `u u' (`calc-undefine-unit') command removes a user-defined
- unit. It is not possible to remove one of the predefined units,
- however.
- If you define a unit with an existing unit name, your new definition
- will replace the original definition of that unit. If the unit was a
- predefined unit, the old definition will not be replaced, only
- "shadowed." The built-in definition will reappear if you later use `u
- u' to remove the shadowing definition.
- To create a new fundamental unit, use either 1 or the unit name
- itself as the defining expression. Otherwise the expression can
- involve any other units that you like (except for composite units like
- `mfi'). You can create a new composite unit with a sum of other units
- as the defining expression. The next unit operation like `u c' or `u v'
- will rebuild the internal unit table incorporating your modifications.
- Note that erroneous definitions (such as two units defined in terms of
- each other) will not be detected until the unit table is next rebuilt;
- `u v' is a convenient way to force this to happen.
- Temperature units are treated specially inside the Calculator; it is
- not possible to create user-defined temperature units.
- The `u p' (`calc-permanent-units') command stores the user-defined
- units in your Calc init file (the file given by the variable
- `calc-settings-file', typically `~/.emacs.d/calc.el'), so that the
- units will still be available in subsequent Emacs sessions. If there
- was already a set of user-defined units in your Calc init file, it is
- replaced by the new set. (*Note General Mode Commands::, for a way to
- tell Calc to use a different file for the Calc init file.)
- File: calc, Node: Logarithmic Units, Next: Musical Notes, Prev: User-Defined Units, Up: Units
- 13.5 Logarithmic Units
- ======================
- The units `dB' (decibels) and `Np' (nepers) are logarithmic units which
- are manipulated differently than standard units. Calc provides
- commands to work with these logarithmic units.
- Decibels and nepers are used to measure power quantities as well as
- field quantities (quantities whose squares are proportional to power);
- these two types of quantities are handled slightly different from each
- other. By default the Calc commands work as if power quantities are
- being used; with the `H' prefix the Calc commands work as if field
- quantities are being used.
- The decibel level of a power P1, relative to a reference power P0,
- is defined to be 10 log10(P1/P0) dB. (The factor of 10 is because a
- decibel, as its name implies, is one-tenth of a bel. The bel, named
- after Alexander Graham Bell, was considered to be too large of a unit
- and was effectively replaced by the decibel.) If F is a field quantity
- with power P=k F^2, then a reference quantity of F0 would correspond to
- a power of P0=k F0^2. If P1=k F1^2, then
- 10 log10(P1/P0) = 10 log10(F1^2/F0^2) = 20 log10(F1/F0).
- In order to get the same decibel level regardless of whether a field
- quantity or the corresponding power quantity is used, the decibel
- level of a field quantity F1, relative to a reference F0, is defined as
- 20 log10(F1/F0) dB. For example, the decibel value of a sound pressure
- level of 60 uPa relative to 20 uPa (the threshold of human hearing) is
- 20 log10(60 uPa/ 20 uPa) dB = 20 log10(3) dB, which is about 9.54 dB.
- Note that in taking the ratio, the original units cancel and so these
- logarithmic units are dimensionless.
- Nepers (named after John Napier, who is credited with inventing the
- logarithm) are similar to bels except they use natural logarithms
- instead of common logarithms. The neper level of a power P1, relative
- to a reference power P0, is (1/2) ln(P1/P0) Np. The neper level of a
- field F1, relative to a reference field F0, is ln(F1/F0) Np.
- For power quantities, Calc uses 1 mW as the default reference
- quantity; this default can be changed by changing the value of the
- customizable variable `calc-lu-power-reference' (*note Customizing
- Calc::). For field quantities, Calc uses 20 uPa as the default
- reference quantity; this is the value used in acoustics which is where
- decibels are commonly encountered. This default can be changed by
- changing the value of the customizable variable
- `calc-lu-field-reference' (*note Customizing Calc::). A non-default
- reference quantity will be read from the stack if the capital `O'
- prefix is used.
- The `l q' (`calc-lu-quant') [`lupquant'] command computes the power
- quantity corresponding to a given number of logarithmic units. With the
- capital `O' prefix, `O l q', the reference level will be read from the
- top of the stack. (In an algebraic formula, `lupquant' can be given an
- optional second argument which will be used for the reference level.)
- For example, `20 dB <RET> l q' will return `100 mW'; `20 dB <RET> 4 W
- <RET> O l q' will return `400 W'. The `H l q' [`lufquant'] command
- behaves like `l q' but computes field quantities instead of power
- quantities.
- The `l d' (`calc-db') [`dbpower'] command will compute the decibel
- level of a power quantity using the default reference level; `H l d'
- [`dbfield'] will compute the decibel level of a field quantity. The
- commands `l n' (`calc-np') [`nppower'] and `H l n' [`npfield'] will
- similarly compute neper levels. With the capital `O' prefix these
- commands will read a reference level from the stack; in an algebraic
- formula the reference level can be given as an optional second argument.
- The sum of two power or field quantities doesn't correspond to the
- sum of the corresponding decibel or neper levels. If the powers
- corresponding to decibel levels D1 and D2 are added, the corresponding
- decibel level "sum" will be
- 10 log10(10^(D1/10) + 10^(D2/10)) dB.
- When field quantities are combined, it often means the corresponding
- powers are added and so the above formula might be used. In acoustics,
- for example, the sound pressure level is a field quantity and so the
- decibels are often defined using the field formula, but the sound
- pressure levels are combined as the sound power levels, and so the
- above formula should be used. If two field quantities themselves are
- added, the new decibel level will be
- 20 log10(10^(D1/20) + 10^(D2/20)) dB.
- If the power corresponding to D dB is multiplied by a number N, then
- the corresponding decibel level will be
- D + 10 log10(N) dB,
- if a field quantity is multiplied by N the corresponding decibel level
- will be
- D + 20 log10(N) dB.
- There are similar formulas for combining nepers. The `l +'
- (`calc-lu-plus') [`lupadd'] command will "add" two logarithmic unit
- power levels this way; with the `H' prefix, `H l +' [`lufadd'] will add
- logarithmic unit field levels. Similarly, logarithmic units can be
- "subtracted" with `l -' (`calc-lu-minus') [`lupsub'] or `H l -'
- [`lufsub']. The `l *' (`calc-lu-times') [`lupmul'] and `H l *'
- [`lufmul'] commands will "multiply" a logarithmic unit by a number; the
- `l /' (`calc-lu-divide') [`lupdiv'] and `H l /' [`lufdiv'] commands
- will "divide" a logarithmic unit by a number. Note that the reference
- quantities don't play a role in this arithmetic.
- File: calc, Node: Musical Notes, Prev: Logarithmic Units, Up: Units
- 13.6 Musical Notes
- ==================
- Calc can convert between musical notes and their associated
- frequencies. Notes can be given using either scientific pitch notation
- or midi numbers. Since these note systems are basically logarithmic
- scales, Calc uses the `l' prefix for functions operating on notes.
- Scientific pitch notation refers to a note by giving a letter A
- through G, possibly followed by a flat or sharp) with a subscript
- indicating an octave number. Each octave starts with C and ends with B
- and the octave numbered 0 was chosen to correspond to the lowest
- audible frequency. Using this system, middle C (about 261.625 Hz)
- corresponds to the note `C' in octave 4 and is denoted `C_4'. Any
- frequency can be described by giving a note plus an offset in cents
- (where a cent is a ratio of frequencies so that a semitone consists of
- 100 cents).
- The midi note number system assigns numbers to notes so that
- `C_(-1)' corresponds to the midi note number 0 and `G_9' corresponds to
- the midi note number 127. A midi controller can have up to 128 keys
- and each midi note number from 0 to 127 corresponds to a possible key.
- The `l s' (`calc-spn') [`spn'] command converts either a frequency
- or a midi number to scientific pitch notation. For example, `500 Hz'
- gets converted to `B_4 + 21.3094853649 cents' and `84' to `C_6'.
- The `l m' (`calc-midi') [`midi'] command converts either a frequency
- or a note given in scientific pitch notation to the corresponding midi
- number. For example, `C_6' gets converted to 84 and `440 Hz' to 69.
- The `l f' (`calc-freq') [`freq'] command converts either either a
- midi number or a note given in scientific pitch notation to the
- corresponding frequency. For example, `Asharp_2 + 30 cents' gets
- converted to `118.578040134 Hz' and `55' to `195.99771799 Hz'.
- Since the frequencies of notes are not usually given exactly (and are
- typically irrational), the customizable variable `calc-note-threshold'
- determines how close (in cents) a frequency needs to be to a note to be
- recognized as that note (*note Customizing Calc::). This variable has
- a default value of `1'. For example, middle C is approximately
- `261.625565302 Hz'; this frequency is often shortened to `261.625 Hz'.
- Without `calc-note-threshold' (or a value of `0'), Calc would convert
- `261.625 Hz' to scientific pitch notation `B_3 + 99.9962592773 cents';
- with the default value of `1', Calc converts `261.625 Hz' to `C_4'.
- File: calc, Node: Store and Recall, Next: Graphics, Prev: Units, Up: Top
- 14 Storing and Recalling
- ************************
- Calculator variables are really just Lisp variables that contain numbers
- or formulas in a form that Calc can understand. The commands in this
- section allow you to manipulate variables conveniently. Commands
- related to variables use the `s' prefix key.
- * Menu:
- * Storing Variables::
- * Recalling Variables::
- * Operations on Variables::
- * Let Command::
- * Evaluates-To Operator::
- File: calc, Node: Storing Variables, Next: Recalling Variables, Prev: Store and Recall, Up: Store and Recall
- 14.1 Storing Variables
- ======================
- The `s s' (`calc-store') command stores the value at the top of the
- stack into a specified variable. It prompts you to enter the name of
- the variable. If you press a single digit, the value is stored
- immediately in one of the "quick" variables `q0' through `q9'. Or you
- can enter any variable name.
- The `s s' command leaves the stored value on the stack. There is
- also an `s t' (`calc-store-into') command, which removes a value from
- the stack and stores it in a variable.
- If the top of stack value is an equation `a = 7' or assignment `a :=
- 7' with a variable on the lefthand side, then Calc will assign that
- variable with that value by default, i.e., if you type `s s <RET>' or
- `s t <RET>'. In this example, the value 7 would be stored in the
- variable `a'. (If you do type a variable name at the prompt, the
- top-of-stack value is stored in its entirety, even if it is an
- equation: `s s b <RET>' with `a := 7' on the stack stores `a := 7' in
- `b'.)
- In fact, the top of stack value can be a vector of equations or
- assignments with different variables on their lefthand sides; the
- default will be to store all the variables with their corresponding
- righthand sides simultaneously.
- It is also possible to type an equation or assignment directly at
- the prompt for the `s s' or `s t' command: `s s foo = 7'. In this
- case the expression to the right of the `=' or `:=' symbol is evaluated
- as if by the `=' command, and that value is stored in the variable. No
- value is taken from the stack; `s s' and `s t' are equivalent when used
- in this way.
- The prefix keys `s' and `t' may be followed immediately by a digit;
- `s 9' is equivalent to `s s 9', and `t 9' is equivalent to `s t 9'.
- (The `t' prefix is otherwise used for trail and time/date commands.)
- There are also several "arithmetic store" commands. For example, `s
- +' removes a value from the stack and adds it to the specified
- variable. The other arithmetic stores are `s -', `s *', `s /', `s ^',
- and `s |' (vector concatenation), plus `s n' and `s &' which negate or
- invert the value in a variable, and `s [' and `s ]' which decrease or
- increase a variable by one.
- All the arithmetic stores accept the Inverse prefix to reverse the
- order of the operands. If `v' represents the contents of the variable,
- and `a' is the value drawn from the stack, then regular `s -' assigns
- `v := v - a', but `I s -' assigns `v := a - v'. While `I s *' might
- seem pointless, it is useful if matrix multiplication is involved.
- Actually, all the arithmetic stores use formulas designed to behave
- usefully both forwards and backwards:
- s + v := v + a v := a + v
- s - v := v - a v := a - v
- s * v := v * a v := a * v
- s / v := v / a v := a / v
- s ^ v := v ^ a v := a ^ v
- s | v := v | a v := a | v
- s n v := v / (-1) v := (-1) / v
- s & v := v ^ (-1) v := (-1) ^ v
- s [ v := v - 1 v := 1 - v
- s ] v := v - (-1) v := (-1) - v
- In the last four cases, a numeric prefix argument will be used in
- place of the number one. (For example, `M-2 s ]' increases a variable
- by 2, and `M-2 I s ]' replaces a variable by minus-two minus the
- variable.
- The first six arithmetic stores can also be typed `s t +', `s t -',
- etc. The commands `s s +', `s s -', and so on are analogous arithmetic
- stores that don't remove the value `a' from the stack.
- All arithmetic stores report the new value of the variable in the
- Trail for your information. They signal an error if the variable
- previously had no stored value. If default simplifications have been
- turned off, the arithmetic stores temporarily turn them on for numeric
- arguments only (i.e., they temporarily do an `m N' command). *Note
- Simplification Modes::. Large vectors put in the trail by these
- commands always use abbreviated (`t .') mode.
- The `s m' command is a general way to adjust a variable's value
- using any Calc function. It is a "mapping" command analogous to `V M',
- `V R', etc. *Note Reducing and Mapping::, to see how to specify a
- function for a mapping command. Basically, all you do is type the Calc
- command key that would invoke that function normally. For example, `s
- m n' applies the `n' key to negate the contents of the variable, so `s
- m n' is equivalent to `s n'. Also, `s m Q' takes the square root of
- the value stored in a variable, `s m v v' uses `v v' to reverse the
- vector stored in the variable, and `s m H I S' takes the hyperbolic
- arcsine of the variable contents.
- If the mapping function takes two or more arguments, the additional
- arguments are taken from the stack; the old value of the variable is
- provided as the first argument. Thus `s m -' with `a' on the stack
- computes `v - a', just like `s -'. With the Inverse prefix, the
- variable's original value becomes the _last_ argument instead of the
- first. Thus `I s m -' is also equivalent to `I s -'.
- The `s x' (`calc-store-exchange') command exchanges the value of a
- variable with the value on the top of the stack. Naturally, the
- variable must already have a stored value for this to work.
- You can type an equation or assignment at the `s x' prompt. The
- command `s x a=6' takes no values from the stack; instead, it pushes
- the old value of `a' on the stack and stores `a = 6'.
- Until you store something in them, most variables are "void," that
- is, they contain no value at all. If they appear in an algebraic
- formula they will be left alone even if you press `=' (`calc-evaluate').
- The `s u' (`calc-unstore') command returns a variable to the void state.
- The `s c' (`calc-copy-variable') command copies the stored value of
- one variable to another. One way it differs from a simple `s r'
- followed by an `s t' (aside from saving keystrokes) is that the value
- never goes on the stack and thus is never rounded, evaluated, or
- simplified in any way; it is not even rounded down to the current
- precision.
- The only variables with predefined values are the "special constants"
- `pi', `e', `i', `phi', and `gamma'. You are free to unstore these
- variables or to store new values into them if you like, although some
- of the algebraic-manipulation functions may assume these variables
- represent their standard values. Calc displays a warning if you change
- the value of one of these variables, or of one of the other special
- variables `inf', `uinf', and `nan' (which are normally void).
- Note that `pi' doesn't actually have 3.14159265359 stored in it, but
- rather a special magic value that evaluates to `pi' at the current
- precision. Likewise `e', `i', and `phi' evaluate according to the
- current precision or polar mode. If you recall a value from `pi' and
- store it back, this magic property will be lost. The magic property is
- preserved, however, when a variable is copied with `s c'.
- If one of the "special constants" is redefined (or undefined) so that
- it no longer has its magic property, the property can be restored with
- `s k' (`calc-copy-special-constant'). This command will prompt for a
- special constant and a variable to store it in, and so a special
- constant can be stored in any variable. Here, the special constant that
- you enter doesn't depend on the value of the corresponding variable;
- `pi' will represent 3.14159... regardless of what is currently stored
- in the Calc variable `pi'. If one of the other special variables,
- `inf', `uinf' or `nan', is given a value, its original behavior can be
- restored by voiding it with `s u'.
- File: calc, Node: Recalling Variables, Next: Operations on Variables, Prev: Storing Variables, Up: Store and Recall
- 14.2 Recalling Variables
- ========================
- The most straightforward way to extract the stored value from a variable
- is to use the `s r' (`calc-recall') command. This command prompts for
- a variable name (similarly to `calc-store'), looks up the value of the
- specified variable, and pushes that value onto the stack. It is an
- error to try to recall a void variable.
- It is also possible to recall the value from a variable by
- evaluating a formula containing that variable. For example, `' a <RET>
- =' is the same as `s r a <RET>' except that if the variable is void, the
- former will simply leave the formula `a' on the stack whereas the
- latter will produce an error message.
- The `r' prefix may be followed by a digit, so that `r 9' is
- equivalent to `s r 9'.
- File: calc, Node: Operations on Variables, Next: Let Command, Prev: Recalling Variables, Up: Store and Recall
- 14.3 Other Operations on Variables
- ==================================
- The `s e' (`calc-edit-variable') command edits the stored value of a
- variable without ever putting that value on the stack or simplifying or
- evaluating the value. It prompts for the name of the variable to edit.
- If the variable has no stored value, the editing buffer will start out
- empty. If the editing buffer is empty when you press `C-c C-c' to
- finish, the variable will be made void. *Note Editing Stack Entries::,
- for a general description of editing.
- The `s e' command is especially useful for creating and editing
- rewrite rules which are stored in variables. Sometimes these rules
- contain formulas which must not be evaluated until the rules are
- actually used. (For example, they may refer to `deriv(x,y)', where `x'
- will someday become some expression involving `y'; if you let Calc
- evaluate the rule while you are defining it, Calc will replace
- `deriv(x,y)' with 0 because the formula `x' does not itself refer to
- `y'.) By contrast, recalling the variable, editing with ``', and
- storing will evaluate the variable's value as a side effect of putting
- the value on the stack.
- There are several special-purpose variable-editing commands that use
- the `s' prefix followed by a shifted letter:
- `s A'
- Edit `AlgSimpRules'. *Note Algebraic Simplifications::.
- `s D'
- Edit `Decls'. *Note Declarations::.
- `s E'
- Edit `EvalRules'. *Note Default Simplifications::.
- `s F'
- Edit `FitRules'. *Note Curve Fitting::.
- `s G'
- Edit `GenCount'. *Note Solving Equations::.
- `s H'
- Edit `Holidays'. *Note Business Days::.
- `s I'
- Edit `IntegLimit'. *Note Calculus::.
- `s L'
- Edit `LineStyles'. *Note Graphics::.
- `s P'
- Edit `PointStyles'. *Note Graphics::.
- `s R'
- Edit `PlotRejects'. *Note Graphics::.
- `s T'
- Edit `TimeZone'. *Note Time Zones::.
- `s U'
- Edit `Units'. *Note User-Defined Units::.
- `s X'
- Edit `ExtSimpRules'. *Note Unsafe Simplifications::.
- These commands are just versions of `s e' that use fixed variable
- names rather than prompting for the variable name.
- The `s p' (`calc-permanent-variable') command saves a variable's
- value permanently in your Calc init file (the file given by the
- variable `calc-settings-file', typically `~/.emacs.d/calc.el'), so that
- its value will still be available in future Emacs sessions. You can
- re-execute `s p' later on to update the saved value, but the only way
- to remove a saved variable is to edit your calc init file by hand.
- (*Note General Mode Commands::, for a way to tell Calc to use a
- different file for the Calc init file.)
- If you do not specify the name of a variable to save (i.e., `s p
- <RET>'), all Calc variables with defined values are saved except for
- the special constants `pi', `e', `i', `phi', and `gamma'; the variables
- `TimeZone' and `PlotRejects'; `FitRules', `DistribRules', and other
- built-in rewrite rules; and `PlotDataN' variables generated by the
- graphics commands. (You can still save these variables by explicitly
- naming them in an `s p' command.)
- The `s i' (`calc-insert-variables') command writes the values of all
- Calc variables into a specified buffer. The variables are written with
- the prefix `var-' in the form of Lisp `setq' commands which store the
- values in string form. You can place these commands in your Calc init
- file (or `.emacs') if you wish, though in this case it would be easier
- to use `s p <RET>'. (Note that `s i' omits the same set of variables
- as `s p <RET>'; the difference is that `s i' will store the variables
- in any buffer, and it also stores in a more human-readable format.)
- File: calc, Node: Let Command, Next: Evaluates-To Operator, Prev: Operations on Variables, Up: Store and Recall
- 14.4 The Let Command
- ====================
- If you have an expression like `a+b^2' on the stack and you wish to
- compute its value where `b=3', you can simply store 3 in `b' and then
- press `=' to reevaluate the formula. This has the side-effect of
- leaving the stored value of 3 in `b' for future operations.
- The `s l' (`calc-let') command evaluates a formula under a
- _temporary_ assignment of a variable. It stores the value on the top
- of the stack into the specified variable, then evaluates the
- second-to-top stack entry, then restores the original value (or lack of
- one) in the variable. Thus after `' a+b^2 <RET> 3 s l b <RET>', the
- stack will contain the formula `a + 9'. The subsequent command
- `5 s l a <RET>' will replace this formula with the number 14. The
- variables `a' and `b' are not permanently affected in any way by these
- commands.
- The value on the top of the stack may be an equation or assignment,
- or a vector of equations or assignments, in which case the default will
- be analogous to the case of `s t <RET>'. *Note Storing Variables::.
- Also, you can answer the variable-name prompt with an equation or
- assignment: `s l b=3 <RET>' is the same as storing 3 on the stack and
- typing `s l b <RET>'.
- The `a b' (`calc-substitute') command is another way to substitute a
- variable with a value in a formula. It does an actual substitution
- rather than temporarily assigning the variable and evaluating. For
- example, letting `n=2' in `f(n pi)' with `a b' will produce `f(2 pi)',
- whereas `s l' would give `f(6.28)' since the evaluation step will also
- evaluate `pi'.
- File: calc, Node: Evaluates-To Operator, Prev: Let Command, Up: Store and Recall
- 14.5 The Evaluates-To Operator
- ==============================
- The special algebraic symbol `=>' is known as the "evaluates-to
- operator". (It will show up as an `evalto' function call in other
- language modes like Pascal and LaTeX.) This is a binary operator, that
- is, it has a lefthand and a righthand argument, although it can be
- entered with the righthand argument omitted.
- A formula like `A => B' is evaluated by Calc as follows: First, A
- is not simplified or modified in any way. The previous value of
- argument B is thrown away; the formula A is then copied and evaluated
- as if by the `=' command according to all current modes and stored
- variable values, and the result is installed as the new value of B.
- For example, suppose you enter the algebraic formula `2 + 3 => 17'.
- The number 17 is ignored, and the lefthand argument is left in its
- unevaluated form; the result is the formula `2 + 3 => 5'.
- You can enter an `=>' formula either directly using algebraic entry
- (in which case the righthand side may be omitted since it is going to
- be replaced right away anyhow), or by using the `s =' (`calc-evalto')
- command, which takes A from the stack and replaces it with `A => B'.
- Calc keeps track of all `=>' operators on the stack, and recomputes
- them whenever anything changes that might affect their values, i.e., a
- mode setting or variable value. This occurs only if the `=>' operator
- is at the top level of the formula, or if it is part of a top-level
- vector. In other words, pushing `2 + (a => 17)' will change the 17 to
- the actual value of `a' when you enter the formula, but the result will
- not be dynamically updated when `a' is changed later because the `=>'
- operator is buried inside a sum. However, a vector of `=>' operators
- will be recomputed, since it is convenient to push a vector like `[a
- =>, b =>, c =>]' on the stack to make a concise display of all the
- variables in your problem. (Another way to do this would be to use
- `[a, b, c] =>', which provides a slightly different format of display.
- You can use whichever you find easiest to read.)
- The `m C' (`calc-auto-recompute') command allows you to turn this
- automatic recomputation on or off. If you turn recomputation off, you
- must explicitly recompute an `=>' operator on the stack in one of the
- usual ways, such as by pressing `='. Turning recomputation off
- temporarily can save a lot of time if you will be changing several
- modes or variables before you look at the `=>' entries again.
- Most commands are not especially useful with `=>' operators as
- arguments. For example, given `x + 2 => 17', it won't work to type `1
- +' to get `x + 3 => 18'. If you want to operate on the lefthand side
- of the `=>' operator on the top of the stack, type `j 1' (that's the
- digit "one") to select the lefthand side, execute your commands, then
- type `j u' to unselect.
- All current modes apply when an `=>' operator is computed, including
- the current simplification mode. Recall that the formula `x + y + x'
- is not handled by Calc's default simplifications, but the `a s' command
- will reduce it to the simpler form `y + 2 x'. You can also type `m A'
- to enable an Algebraic Simplification mode in which the equivalent of
- `a s' is used on all of Calc's results. If you enter `x + y + x =>'
- normally, the result will be `x + y + x => x + y + x'. If you change to
- Algebraic Simplification mode, the result will be `x + y + x => y + 2
- x'. However, just pressing `a s' once will have no effect on `x + y +
- x => x + y + x', because the righthand side depends only on the
- lefthand side and the current mode settings, and the lefthand side is
- not affected by commands like `a s'.
- The "let" command (`s l') has an interesting interaction with the
- `=>' operator. The `s l' command evaluates the second-to-top stack
- entry with the top stack entry supplying a temporary value for a given
- variable. As you might expect, if that stack entry is an `=>' operator
- its righthand side will temporarily show this value for the variable.
- In fact, all `=>'s on the stack will be updated if they refer to that
- variable. But this change is temporary in the sense that the next
- command that causes Calc to look at those stack entries will make them
- revert to the old variable value.
- 2: a => a 2: a => 17 2: a => a
- 1: a + 1 => a + 1 1: a + 1 => 18 1: a + 1 => a + 1
- . . .
- 17 s l a <RET> p 8 <RET>
- Here the `p 8' command changes the current precision, thus causing
- the `=>' forms to be recomputed after the influence of the "let" is
- gone. The `d <SPC>' command (`calc-refresh') is a handy way to force
- the `=>' operators on the stack to be recomputed without any other side
- effects.
- Embedded mode also uses `=>' operators. In Embedded mode, the
- lefthand side of an `=>' operator can refer to variables assigned
- elsewhere in the file by `:=' operators. The assignment operator `a :=
- 17' does not actually do anything by itself. But Embedded mode
- recognizes it and marks it as a sort of file-local definition of the
- variable. You can enter `:=' operators in Algebraic mode, or by using
- the `s :' (`calc-assign') [`assign'] command which takes a variable and
- value from the stack and replaces them with an assignment.
- *Note TeX and LaTeX Language Modes::, for the way `=>' appears in
- TeX language output. The "eqn" mode gives similar treatment to `=>'.
- File: calc, Node: Graphics, Next: Kill and Yank, Prev: Store and Recall, Up: Top
- 15 Graphics
- ***********
- The commands for graphing data begin with the `g' prefix key. Calc
- uses GNUPLOT 2.0 or later to do graphics. These commands will only work
- if GNUPLOT is available on your system. (While GNUPLOT sounds like a
- relative of GNU Emacs, it is actually completely unrelated. However,
- it is free software. It can be obtained from
- `http://www.gnuplot.info'.)
- If you have GNUPLOT installed on your system but Calc is unable to
- find it, you may need to set the `calc-gnuplot-name' variable in your
- Calc init file or `.emacs'. You may also need to set some Lisp
- variables to show Calc how to run GNUPLOT on your system; these are
- described under `g D' and `g O' below. If you are using the X window
- system or MS-Windows, Calc will configure GNUPLOT for you
- automatically. If you have GNUPLOT 3.0 or later and you are using a
- Unix or GNU system without X, Calc will configure GNUPLOT to display
- graphs using simple character graphics that will work on any
- Posix-compatible terminal.
- * Menu:
- * Basic Graphics::
- * Three Dimensional Graphics::
- * Managing Curves::
- * Graphics Options::
- * Devices::
- File: calc, Node: Basic Graphics, Next: Three Dimensional Graphics, Prev: Graphics, Up: Graphics
- 15.1 Basic Graphics
- ===================
- The easiest graphics command is `g f' (`calc-graph-fast'). This
- command takes two vectors of equal length from the stack. The vector
- at the top of the stack represents the "y" values of the various data
- points. The vector in the second-to-top position represents the
- corresponding "x" values. This command runs GNUPLOT (if it has not
- already been started by previous graphing commands) and displays the
- set of data points. The points will be connected by lines, and there
- will also be some kind of symbol to indicate the points themselves.
- The "x" entry may instead be an interval form, in which case suitable
- "x" values are interpolated between the minimum and maximum values of
- the interval (whether the interval is open or closed is ignored).
- The "x" entry may also be a number, in which case Calc uses the
- sequence of "x" values `x', `x+1', `x+2', etc. (Generally the number 0
- or 1 would be used for `x' in this case.)
- The "y" entry may be any formula instead of a vector. Calc
- effectively uses `N' (`calc-eval-num') to evaluate variables in the
- formula; the result of this must be a formula in a single (unassigned)
- variable. The formula is plotted with this variable taking on the
- various "x" values. Graphs of formulas by default use lines without
- symbols at the computed data points. Note that if neither "x" nor "y"
- is a vector, Calc guesses at a reasonable number of data points to use.
- See the `g N' command below. (The "x" values must be either a vector
- or an interval if "y" is a formula.)
- If "y" is (or evaluates to) a formula of the form `xy(X, Y)' then
- the result is a parametric plot. The two arguments of the fictitious
- `xy' function are used as the "x" and "y" coordinates of the curve,
- respectively. In this case the "x" vector or interval you specified is
- not directly visible in the graph. For example, if "x" is the interval
- `[0..360]' and "y" is the formula `xy(sin(t), cos(t))', the resulting
- graph will be a circle.
- Also, "x" and "y" may each be variable names, in which case Calc
- looks for suitable vectors, intervals, or formulas stored in those
- variables.
- The "x" and "y" values for the data points (as pulled from the
- vectors, calculated from the formulas, or interpolated from the
- intervals) should be real numbers (integers, fractions, or floats).
- One exception to this is that the "y" entry can consist of a vector of
- numbers combined with error forms, in which case the points will be
- plotted with the appropriate error bars. Other than this, if either
- the "x" value or the "y" value of a given data point is not a real
- number, that data point will be omitted from the graph. The points on
- either side of the invalid point will _not_ be connected by a line.
- See the documentation for `g a' below for a description of the way
- numeric prefix arguments affect `g f'.
- If you store an empty vector in the variable `PlotRejects' (i.e., `[
- ] s t PlotRejects'), Calc will append information to this vector for
- every data point which was rejected because its "x" or "y" values were
- not real numbers. The result will be a matrix where each row holds the
- curve number, data point number, "x" value, and "y" value for a
- rejected data point. *Note Evaluates-To Operator::, for a handy way to
- keep tabs on the current value of `PlotRejects'. *Note Operations on
- Variables::, for the `s R' command which is another easy way to examine
- `PlotRejects'.
- To clear the graphics display, type `g c' (`calc-graph-clear'). If
- the GNUPLOT output device is an X window, the window will go away.
- Effects on other kinds of output devices will vary. You don't need to
- use `g c' if you don't want to--if you give another `g f' or `g p'
- command later on, it will reuse the existing graphics window if there
- is one.
- File: calc, Node: Three Dimensional Graphics, Next: Managing Curves, Prev: Basic Graphics, Up: Graphics
- 15.2 Three-Dimensional Graphics
- ===============================
- The `g F' (`calc-graph-fast-3d') command makes a three-dimensional
- graph. It works only if you have GNUPLOT 3.0 or later; with GNUPLOT
- 2.0, you will see a GNUPLOT error message if you try this command.
- The `g F' command takes three values from the stack, called "x",
- "y", and "z", respectively. As was the case for 2D graphs, there are
- several options for these values.
- In the first case, "x" and "y" are each vectors (not necessarily of
- the same length); either or both may instead be interval forms. The
- "z" value must be a matrix with the same number of rows as elements in
- "x", and the same number of columns as elements in "y". The result is
- a surface plot where `z_ij' is the height of the point at coordinate
- `(x_i, y_j)' on the surface. The 3D graph will be displayed from a
- certain default viewpoint; you can change this viewpoint by adding a
- `set view' to the `*Gnuplot Commands*' buffer as described later. See
- the GNUPLOT documentation for a description of the `set view' command.
- Each point in the matrix will be displayed as a dot in the graph,
- and these points will be connected by a grid of lines ("isolines").
- In the second case, "x", "y", and "z" are all vectors of equal
- length. The resulting graph displays a 3D line instead of a surface,
- where the coordinates of points along the line are successive triplets
- of values from the input vectors.
- In the third case, "x" and "y" are vectors or interval forms, and
- "z" is any formula involving two variables (not counting variables with
- assigned values). These variables are sorted into alphabetical order;
- the first takes on values from "x" and the second takes on values from
- "y" to form a matrix of results that are graphed as a 3D surface.
- If the "z" formula evaluates to a call to the fictitious function
- `xyz(X, Y, Z)', then the result is a "parametric surface." In this
- case, the axes of the graph are taken from the X and Y values in these
- calls, and the "x" and "y" values from the input vectors or intervals
- are used only to specify the range of inputs to the formula. For
- example, plotting `[0..360], [0..180], xyz(sin(x)*sin(y),
- cos(x)*sin(y), cos(y))' will draw a sphere. (Since the default
- resolution for 3D plots is 5 steps in each of "x" and "y", this will
- draw a very crude sphere. You could use the `g N' command, described
- below, to increase this resolution, or specify the "x" and "y" values as
- vectors with more than 5 elements.
- It is also possible to have a function in a regular `g f' plot
- evaluate to an `xyz' call. Since `g f' plots a line, not a surface,
- the result will be a 3D parametric line. For example, `[[0..720],
- xyz(sin(x), cos(x), x)]' will plot two turns of a helix (a
- three-dimensional spiral).
- As for `g f', each of "x", "y", and "z" may instead be variables
- containing the relevant data.
- File: calc, Node: Managing Curves, Next: Graphics Options, Prev: Three Dimensional Graphics, Up: Graphics
- 15.3 Managing Curves
- ====================
- The `g f' command is really shorthand for the following commands: `C-u
- g d g a g p'. Likewise, `g F' is shorthand for `C-u g d g A g p'.
- You can gain more control over your graph by using these commands
- directly.
- The `g a' (`calc-graph-add') command adds the "curve" represented by
- the two values on the top of the stack to the current graph. You can
- have any number of curves in the same graph. When you give the `g p'
- command, all the curves will be drawn superimposed on the same axes.
- The `g a' command (and many others that affect the current graph)
- will cause a special buffer, `*Gnuplot Commands*', to be displayed in
- another window. This buffer is a template of the commands that will be
- sent to GNUPLOT when it is time to draw the graph. The first `g a'
- command adds a `plot' command to this buffer. Succeeding `g a'
- commands add extra curves onto that `plot' command. Other
- graph-related commands put other GNUPLOT commands into this buffer. In
- normal usage you never need to work with this buffer directly, but you
- can if you wish. The only constraint is that there must be only one
- `plot' command, and it must be the last command in the buffer. If you
- want to save and later restore a complete graph configuration, you can
- use regular Emacs commands to save and restore the contents of the
- `*Gnuplot Commands*' buffer.
- If the values on the stack are not variable names, `g a' will invent
- variable names for them (of the form `PlotDataN') and store the values
- in those variables. The "x" and "y" variables are what go into the
- `plot' command in the template. If you add a curve that uses a certain
- variable and then later change that variable, you can replot the graph
- without having to delete and re-add the curve. That's because the
- variable name, not the vector, interval or formula itself, is what was
- added by `g a'.
- A numeric prefix argument on `g a' or `g f' changes the way stack
- entries are interpreted as curves. With a positive prefix argument
- `n', the top `n' stack entries are "y" values for `n' different curves
- which share a common "x" value in the `n+1'st stack entry. (Thus `g a'
- with no prefix argument is equivalent to `C-u 1 g a'.)
- A prefix of zero or plain `C-u' means to take two stack entries, "x"
- and "y" as usual, but to interpret "y" as a vector of "y" values for
- several curves that share a common "x".
- A negative prefix argument tells Calc to read `n' vectors from the
- stack; each vector `[x, y]' describes an independent curve. This is
- the only form of `g a' that creates several curves at once that don't
- have common "x" values. (Of course, the range of "x" values covered by
- all the curves ought to be roughly the same if they are to look nice on
- the same graph.)
- For example, to plot `sin(n x)' for integers `n' from 1 to 5, you
- could use `v x' to create a vector of integers (`n'), then `V M '' or
- `V M $' to map `sin(n x)' across this vector. The resulting vector of
- formulas is suitable for use as the "y" argument to a `C-u g a' or `C-u
- g f' command.
- The `g A' (`calc-graph-add-3d') command adds a 3D curve to the
- graph. It is not valid to intermix 2D and 3D curves in a single graph.
- This command takes three arguments, "x", "y", and "z", from the stack.
- With a positive prefix `n', it takes `n+2' arguments (common "x" and
- "y", plus `n' separate "z"s). With a zero prefix, it takes three stack
- entries but the "z" entry is a vector of curve values. With a negative
- prefix `-n', it takes `n' vectors of the form `[x, y, z]'. The `g A'
- command works by adding a `splot' (surface-plot) command to the
- `*Gnuplot Commands*' buffer.
- (Although `g a' adds a 2D `plot' command to the `*Gnuplot Commands*'
- buffer, Calc changes this to `splot' before sending it to GNUPLOT if it
- notices that the data points are evaluating to `xyz' calls. It will
- not work to mix 2D and 3D `g a' curves in a single graph, although Calc
- does not currently check for this.)
- The `g d' (`calc-graph-delete') command deletes the most recently
- added curve from the graph. It has no effect if there are no curves in
- the graph. With a numeric prefix argument of any kind, it deletes all
- of the curves from the graph.
- The `g H' (`calc-graph-hide') command "hides" or "unhides" the most
- recently added curve. A hidden curve will not appear in the actual
- plot, but information about it such as its name and line and point
- styles will be retained.
- The `g j' (`calc-graph-juggle') command moves the curve at the end
- of the list (the "most recently added curve") to the front of the list.
- The next-most-recent curve is thus exposed for `g d' or similar
- commands to use. With `g j' you can work with any curve in the graph
- even though curve-related commands only affect the last curve in the
- list.
- The `g p' (`calc-graph-plot') command uses GNUPLOT to draw the graph
- described in the `*Gnuplot Commands*' buffer. Any GNUPLOT parameters
- which are not defined by commands in this buffer are reset to their
- default values. The variables named in the `plot' command are written
- to a temporary data file and the variable names are then replaced by
- the file name in the template. The resulting plotting commands are fed
- to the GNUPLOT program. See the documentation for the GNUPLOT program
- for more specific information. All temporary files are removed when
- Emacs or GNUPLOT exits.
- If you give a formula for "y", Calc will remember all the values that
- it calculates for the formula so that later plots can reuse these
- values. Calc throws out these saved values when you change any
- circumstances that may affect the data, such as switching from Degrees
- to Radians mode, or changing the value of a parameter in the formula.
- You can force Calc to recompute the data from scratch by giving a
- negative numeric prefix argument to `g p'.
- Calc uses a fairly rough step size when graphing formulas over
- intervals. This is to ensure quick response. You can "refine" a plot
- by giving a positive numeric prefix argument to `g p'. Calc goes
- through the data points it has computed and saved from previous plots
- of the function, and computes and inserts a new data point midway
- between each of the existing points. You can refine a plot any number
- of times, but beware that the amount of calculation involved doubles
- each time.
- Calc does not remember computed values for 3D graphs. This means the
- numerix prefix argument, if any, to `g p' is effectively ignored if the
- current graph is three-dimensional.
- The `g P' (`calc-graph-print') command is like `g p', except that it
- sends the output to a printer instead of to the screen. More
- precisely, `g p' looks for `set terminal' or `set output' commands in
- the `*Gnuplot Commands*' buffer; lacking these it uses the default
- settings. However, `g P' ignores `set terminal' and `set output'
- commands and uses a different set of default values. All of these
- values are controlled by the `g D' and `g O' commands discussed below.
- Provided everything is set up properly, `g p' will plot to the screen
- unless you have specified otherwise and `g P' will always plot to the
- printer.
- File: calc, Node: Graphics Options, Next: Devices, Prev: Managing Curves, Up: Graphics
- 15.4 Graphics Options
- =====================
- The `g g' (`calc-graph-grid') command turns the "grid" on and off. It
- is off by default; tick marks appear only at the edges of the graph.
- With the grid turned on, dotted lines appear across the graph at each
- tick mark. Note that this command only changes the setting in
- `*Gnuplot Commands*'; to see the effects of the change you must give
- another `g p' command.
- The `g b' (`calc-graph-border') command turns the border (the box
- that surrounds the graph) on and off. It is on by default. This
- command will only work with GNUPLOT 3.0 and later versions.
- The `g k' (`calc-graph-key') command turns the "key" on and off.
- The key is a chart in the corner of the graph that shows the
- correspondence between curves and line styles. It is off by default,
- and is only really useful if you have several curves on the same graph.
- The `g N' (`calc-graph-num-points') command allows you to select the
- number of data points in the graph. This only affects curves where
- neither "x" nor "y" is specified as a vector. Enter a blank line to
- revert to the default value (initially 15). With no prefix argument,
- this command affects only the current graph. With a positive prefix
- argument this command changes or, if you enter a blank line, displays
- the default number of points used for all graphs created by `g a' that
- don't specify the resolution explicitly. With a negative prefix
- argument, this command changes or displays the default value (initially
- 5) used for 3D graphs created by `g A'. Note that a 3D setting of 5
- means that a total of `5^2 = 25' points will be computed for the
- surface.
- Data values in the graph of a function are normally computed to a
- precision of five digits, regardless of the current precision at the
- time. This is usually more than adequate, but there are cases where it
- will not be. For example, plotting `1 + x' with `x' in the interval
- `[0 .. 1e-6]' will round all the data points down to 1.0! Putting the
- command `set precision N' in the `*Gnuplot Commands*' buffer will cause
- the data to be computed at precision N instead of 5. Since this is
- such a rare case, there is no keystroke-based command to set the
- precision.
- The `g h' (`calc-graph-header') command sets the title for the
- graph. This will show up centered above the graph. The default title
- is blank (no title).
- The `g n' (`calc-graph-name') command sets the title of an
- individual curve. Like the other curve-manipulating commands, it
- affects the most recently added curve, i.e., the last curve on the list
- in the `*Gnuplot Commands*' buffer. To set the title of the other
- curves you must first juggle them to the end of the list with `g j', or
- edit the `*Gnuplot Commands*' buffer by hand. Curve titles appear in
- the key; if the key is turned off they are not used.
- The `g t' (`calc-graph-title-x') and `g T' (`calc-graph-title-y')
- commands set the titles on the "x" and "y" axes, respectively. These
- titles appear next to the tick marks on the left and bottom edges of
- the graph, respectively. Calc does not have commands to control the
- tick marks themselves, but you can edit them into the `*Gnuplot
- Commands*' buffer if you wish. See the GNUPLOT documentation for
- details.
- The `g r' (`calc-graph-range-x') and `g R' (`calc-graph-range-y')
- commands set the range of values on the "x" and "y" axes, respectively.
- You are prompted to enter a suitable range. This should be either a
- pair of numbers of the form, `MIN:MAX', or a blank line to revert to the
- default behavior of setting the range based on the range of values in
- the data, or `$' to take the range from the top of the stack. Ranges
- on the stack can be represented as either interval forms or vectors:
- `[MIN .. MAX]' or `[MIN, MAX]'.
- The `g l' (`calc-graph-log-x') and `g L' (`calc-graph-log-y')
- commands allow you to set either or both of the axes of the graph to be
- logarithmic instead of linear.
- For 3D plots, `g C-t', `g C-r', and `g C-l' (those are letters with
- the Control key held down) are the corresponding commands for the "z"
- axis.
- The `g z' (`calc-graph-zero-x') and `g Z' (`calc-graph-zero-y')
- commands control whether a dotted line is drawn to indicate the "x"
- and/or "y" zero axes. (These are the same dotted lines that would be
- drawn there anyway if you used `g g' to turn the "grid" feature on.)
- Zero-axis lines are on by default, and may be turned off only in
- GNUPLOT 3.0 and later versions. They are not available for 3D plots.
- The `g s' (`calc-graph-line-style') command turns the connecting
- lines on or off for the most recently added curve, and optionally
- selects the style of lines to be used for that curve. Plain `g s'
- simply toggles the lines on and off. With a numeric prefix argument,
- `g s' turns lines on and sets a particular line style. Line style
- numbers start at one and their meanings vary depending on the output
- device. GNUPLOT guarantees that there will be at least six different
- line styles available for any device.
- The `g S' (`calc-graph-point-style') command similarly turns the
- symbols at the data points on or off, or sets the point style. If you
- turn both lines and points off, the data points will show as tiny dots.
- If the "y" values being plotted contain error forms and the connecting
- lines are turned off, then this command will also turn the error bars
- on or off.
- Another way to specify curve styles is with the `LineStyles' and
- `PointStyles' variables. These variables initially have no stored
- values, but if you store a vector of integers in one of these variables,
- the `g a' and `g f' commands will use those style numbers instead of
- the defaults for new curves that are added to the graph. An entry
- should be a positive integer for a specific style, or 0 to let the
- style be chosen automatically, or -1 to turn off lines or points
- altogether. If there are more curves than elements in the vector, the
- last few curves will continue to have the default styles. Of course,
- you can later use `g s' and `g S' to change any of these styles.
- For example, `'[2 -1 3] <RET> s t LineStyles' causes the first curve
- to have lines in style number 2, the second curve to have no connecting
- lines, and the third curve to have lines in style 3. Point styles will
- still be assigned automatically, but you could store another vector in
- `PointStyles' to define them, too.
- File: calc, Node: Devices, Prev: Graphics Options, Up: Graphics
- 15.5 Graphical Devices
- ======================
- The `g D' (`calc-graph-device') command sets the device name (or
- "terminal name" in GNUPLOT lingo) to be used by `g p' commands on this
- graph. It does not affect the permanent default device name. If you
- enter a blank name, the device name reverts to the default. Enter `?'
- to see a list of supported devices.
- With a positive numeric prefix argument, `g D' instead sets the
- default device name, used by all plots in the future which do not
- override it with a plain `g D' command. If you enter a blank line this
- command shows you the current default. The special name `default'
- signifies that Calc should choose `x11' if the X window system is in
- use (as indicated by the presence of a `DISPLAY' environment variable),
- `windows' on MS-Windows, or otherwise `dumb' under GNUPLOT 3.0 and
- later, or `postscript' under GNUPLOT 2.0. This is the initial default
- value.
- The `dumb' device is an interface to "dumb terminals," i.e.,
- terminals with no special graphics facilities. It writes a crude
- picture of the graph composed of characters like `-' and `|' to a
- buffer called `*Gnuplot Trail*', which Calc then displays. The graph
- is made the same size as the Emacs screen, which on most dumb terminals
- will be 80x24 characters. The graph is displayed in an Emacs
- "recursive edit"; type `q' or `C-c C-c' to exit the recursive edit and
- return to Calc. Note that the `dumb' device is present only in GNUPLOT
- 3.0 and later versions.
- The word `dumb' may be followed by two numbers separated by spaces.
- These are the desired width and height of the graph in characters.
- Also, the device name `big' is like `dumb' but creates a graph four
- times the width and height of the Emacs screen. You will then have to
- scroll around to view the entire graph. In the `*Gnuplot Trail*'
- buffer, <SPC>, <DEL>, `<', and `>' are defined to scroll by one
- screenful in each of the four directions.
- With a negative numeric prefix argument, `g D' sets or displays the
- device name used by `g P' (`calc-graph-print'). This is initially
- `postscript'. If you don't have a PostScript printer, you may decide
- once again to use `dumb' to create a plot on any text-only printer.
- The `g O' (`calc-graph-output') command sets the name of the output
- file used by GNUPLOT. For some devices, notably `x11' and `windows',
- there is no output file and this information is not used. Many other
- "devices" are really file formats like `postscript'; in these cases the
- output in the desired format goes into the file you name with `g O'.
- Type `g O stdout <RET>' to set GNUPLOT to write to its standard output
- stream, i.e., to `*Gnuplot Trail*'. This is the default setting.
- Another special output name is `tty', which means that GNUPLOT is
- going to write graphics commands directly to its standard output, which
- you wish Emacs to pass through to your terminal. Tektronix graphics
- terminals, among other devices, operate this way. Calc does this by
- telling GNUPLOT to write to a temporary file, then running a sub-shell
- executing the command `cat tempfile >/dev/tty'. On typical Unix
- systems, this will copy the temporary file directly to the terminal,
- bypassing Emacs entirely. You will have to type `C-l' to Emacs
- afterwards to refresh the screen.
- Once again, `g O' with a positive or negative prefix argument sets
- the default or printer output file names, respectively. In each case
- you can specify `auto', which causes Calc to invent a temporary file
- name for each `g p' (or `g P') command. This temporary file will be
- deleted once it has been displayed or printed. If the output file name
- is not `auto', the file is not automatically deleted.
- The default and printer devices and output files can be saved
- permanently by the `m m' (`calc-save-modes') command. The default
- number of data points (see `g N') and the X geometry (see `g X') are
- also saved. Other graph information is _not_ saved; you can save a
- graph's configuration simply by saving the contents of the `*Gnuplot
- Commands*' buffer.
- You may wish to configure the default and printer devices and output
- files for the whole system. The relevant Lisp variables are
- `calc-gnuplot-default-device' and `-output', and
- `calc-gnuplot-print-device' and `-output'. The output file names must
- be either strings as described above, or Lisp expressions which are
- evaluated on the fly to get the output file names.
- Other important Lisp variables are `calc-gnuplot-plot-command' and
- `calc-gnuplot-print-command', which give the system commands to display
- or print the output of GNUPLOT, respectively. These may be `nil' if no
- command is necessary, or strings which can include `%s' to signify the
- name of the file to be displayed or printed. Or, these variables may
- contain Lisp expressions which are evaluated to display or print the
- output. These variables are customizable (*note Customizing Calc::).
- The `g x' (`calc-graph-display') command lets you specify on which X
- window system display your graphs should be drawn. Enter a blank line
- to see the current display name. This command has no effect unless the
- current device is `x11'.
- The `g X' (`calc-graph-geometry') command is a similar command for
- specifying the position and size of the X window. The normal value is
- `default', which generally means your window manager will let you place
- the window interactively. Entering `800x500+0+0' would create an
- 800-by-500 pixel window in the upper-left corner of the screen. This
- command has no effect if the current device is `windows'.
- The buffer called `*Gnuplot Trail*' holds a transcript of the
- session with GNUPLOT. This shows the commands Calc has "typed" to
- GNUPLOT and the responses it has received. Calc tries to notice when an
- error message has appeared here and display the buffer for you when
- this happens. You can check this buffer yourself if you suspect
- something has gone wrong(1).
- The `g C' (`calc-graph-command') command prompts you to enter any
- line of text, then simply sends that line to the current GNUPLOT
- process. The `*Gnuplot Trail*' buffer looks deceptively like a Shell
- buffer but you can't type commands in it yourself. Instead, you must
- use `g C' for this purpose.
- The `g v' (`calc-graph-view-commands') and `g V'
- (`calc-graph-view-trail') commands display the `*Gnuplot Commands*' and
- `*Gnuplot Trail*' buffers, respectively, in another window. This
- happens automatically when Calc thinks there is something you will want
- to see in either of these buffers. If you type `g v' or `g V' when the
- relevant buffer is already displayed, the buffer is hidden again.
- (Note that on MS-Windows, the `*Gnuplot Trail*' buffer will usually
- show nothing of interest, because GNUPLOT's responses are not
- communicated back to Calc.)
- One reason to use `g v' is to add your own commands to the `*Gnuplot
- Commands*' buffer. Press `g v', then use `C-x o' to switch into that
- window. For example, GNUPLOT has `set label' and `set arrow' commands
- that allow you to annotate your plots. Since Calc doesn't understand
- these commands, you have to add them to the `*Gnuplot Commands*' buffer
- yourself, then use `g p' to replot using these new commands. Note that
- your commands must appear _before_ the `plot' command. To get help on
- any GNUPLOT feature, type, e.g., `g C help set label'. You may have to
- type `g C <RET>' a few times to clear the "press return for more" or
- "subtopic of ..." requests. Note that Calc always sends commands (like
- `set nolabel') to reset all plotting parameters to the defaults before
- each plot, so to delete a label all you need to do is delete the `set
- label' line you added (or comment it out with `#') and then replot with
- `g p'.
- You can use `g q' (`calc-graph-quit') to kill the GNUPLOT process
- that is running. The next graphing command you give will start a fresh
- GNUPLOT process. The word `Graph' appears in the Calc window's mode
- line whenever a GNUPLOT process is currently running. The GNUPLOT
- process is automatically killed when you exit Emacs if you haven't
- killed it manually by then.
- The `g K' (`calc-graph-kill') command is like `g q' except that it
- also views the `*Gnuplot Trail*' buffer so that you can see the process
- being killed. This is better if you are killing GNUPLOT because you
- think it has gotten stuck.
- ---------- Footnotes ----------
- (1) On MS-Windows, due to the peculiarities of how the Windows
- version of GNUPLOT (called `wgnuplot') works, the GNUPLOT responses are
- not communicated back to Calc. Instead, you need to look them up in
- the GNUPLOT command window that is displayed as in normal interactive
- usage of GNUPLOT.
- File: calc, Node: Kill and Yank, Next: Keypad Mode, Prev: Graphics, Up: Top
- 16 Kill and Yank Functions
- **************************
- The commands in this chapter move information between the Calculator and
- other Emacs editing buffers.
- In many cases Embedded mode is an easier and more natural way to
- work with Calc from a regular editing buffer. *Note Embedded Mode::.
- * Menu:
- * Killing From Stack::
- * Yanking Into Stack::
- * Saving Into Registers::
- * Inserting From Registers::
- * Grabbing From Buffers::
- * Yanking Into Buffers::
- * X Cut and Paste::
- File: calc, Node: Killing From Stack, Next: Yanking Into Stack, Prev: Kill and Yank, Up: Kill and Yank
- 16.1 Killing from the Stack
- ===========================
- "Kill" commands are Emacs commands that insert text into the "kill
- ring," from which it can later be "yanked" by a `C-y' command. Three
- common kill commands in normal Emacs are `C-k', which kills one line,
- `C-w', which kills the region between mark and point, and `M-w', which
- puts the region into the kill ring without actually deleting it. All
- of these commands work in the Calculator, too, although in the
- Calculator they operate on whole stack entries, so they "round up" the
- specified region to encompass full lines. (To copy only parts of
- lines, the `M-C-w' command in the Calculator will copy the region to
- the kill ring without any "rounding up", just like the `M-w' command in
- normal Emacs.) Also, `M-k' has been provided to complete the set; it
- puts the current line into the kill ring without deleting anything.
- The kill commands are unusual in that they pay attention to the
- location of the cursor in the Calculator buffer. If the cursor is on
- or below the bottom line, the kill commands operate on the top of the
- stack. Otherwise, they operate on whatever stack element the cursor is
- on. The text is copied into the kill ring exactly as it appears on the
- screen, including line numbers if they are enabled.
- A numeric prefix argument to `C-k' or `M-k' affects the number of
- lines killed. A positive argument kills the current line and `n-1'
- lines below it. A negative argument kills the `-n' lines above the
- current line. Again this mirrors the behavior of the standard Emacs
- `C-k' command. Although a whole line is always deleted, `C-k' with no
- argument copies only the number itself into the kill ring, whereas
- `C-k' with a prefix argument of 1 copies the number with its trailing
- newline.
- File: calc, Node: Yanking Into Stack, Next: Saving Into Registers, Prev: Killing From Stack, Up: Kill and Yank
- 16.2 Yanking into the Stack
- ===========================
- The `C-y' command yanks the most recently killed text back into the
- Calculator. It pushes this value onto the top of the stack regardless
- of the cursor position. In general it re-parses the killed text as a
- number or formula (or a list of these separated by commas or newlines).
- However if the thing being yanked is something that was just killed
- from the Calculator itself, its full internal structure is yanked. For
- example, if you have set the floating-point display mode to show only
- four significant digits, then killing and re-yanking 3.14159 (which
- displays as 3.142) will yank the full 3.14159, even though yanking it
- into any other buffer would yank the number in its displayed form,
- 3.142. (Since the default display modes show all objects to their full
- precision, this feature normally makes no difference.)
- File: calc, Node: Saving Into Registers, Next: Inserting From Registers, Prev: Yanking Into Stack, Up: Kill and Yank
- 16.3 Saving into Registers
- ==========================
- An alternative to killing and yanking stack entries is using registers
- in Calc. Saving stack entries in registers is like saving text in
- normal Emacs registers; although, like Calc's kill commands, register
- commands always operate on whole stack entries.
- Registers in Calc are places to store stack entries for later use;
- each register is indexed by a single character. To store the current
- region (rounded up, of course, to include full stack entries) into a
- register, use the command `r s' (`calc-copy-to-register'). You will
- then be prompted for a register to use, the next character you type
- will be the index for the register. To store the region in register R,
- the full command will be `r s R'. With an argument, `C-u r s R', the
- region being copied to the register will be deleted from the Calc
- buffer.
- It is possible to add additional stack entries to a register. The
- command `M-x calc-append-to-register' will prompt for a register, then
- add the stack entries in the region to the end of the register
- contents. The command `M-x calc-prepend-to-register' will similarly
- prompt for a register and add the stack entries in the region to the
- beginning of the register contents. Both commands take `C-u'
- arguments, which will cause the region to be deleted after being added
- to the register.
- File: calc, Node: Inserting From Registers, Next: Grabbing From Buffers, Prev: Saving Into Registers, Up: Kill and Yank
- 16.4 Inserting from Registers
- =============================
- The command `r i' (`calc-insert-register') will prompt for a register,
- then insert the contents of that register into the Calculator. If the
- contents of the register were placed there from within Calc, then the
- full internal structure of the contents will be inserted into the
- Calculator, otherwise whatever text is in the register is reparsed and
- then inserted into the Calculator.
- File: calc, Node: Grabbing From Buffers, Next: Yanking Into Buffers, Prev: Inserting From Registers, Up: Kill and Yank
- 16.5 Grabbing from Other Buffers
- ================================
- The `C-x * g' (`calc-grab-region') command takes the text between point
- and mark in the current buffer and attempts to parse it as a vector of
- values. Basically, it wraps the text in vector brackets `[ ]' unless
- the text already is enclosed in vector brackets, then reads the text as
- if it were an algebraic entry. The contents of the vector may be
- numbers, formulas, or any other Calc objects. If the `C-x * g' command
- works successfully, it does an automatic `C-x * c' to enter the
- Calculator buffer.
- A numeric prefix argument grabs the specified number of lines around
- point, ignoring the mark. A positive prefix grabs from point to the
- `n'th following newline (so that `M-1 C-x * g' grabs from point to the
- end of the current line); a negative prefix grabs from point back to
- the `n+1'st preceding newline. In these cases the text that is grabbed
- is exactly the same as the text that `C-k' would delete given that
- prefix argument.
- A prefix of zero grabs the current line; point may be anywhere on the
- line.
- A plain `C-u' prefix interprets the region between point and mark as
- a single number or formula rather than a vector. For example, `C-x *
- g' on the text `2 a b' produces the vector of three values `[2, a, b]',
- but `C-u C-x * g' on the same region reads a formula which is a product
- of three things: `2 a b'. (The text `a + b', on the other hand, will
- be grabbed as a vector of one element by plain `C-x * g' because the
- interpretation `[a, +, b]' would be a syntax error.)
- If a different language has been specified (*note Language Modes::),
- the grabbed text will be interpreted according to that language.
- The `C-x * r' (`calc-grab-rectangle') command takes the text between
- point and mark and attempts to parse it as a matrix. If point and mark
- are both in the leftmost column, the lines in between are parsed in
- their entirety. Otherwise, point and mark define the corners of a
- rectangle whose contents are parsed.
- Each line of the grabbed area becomes a row of the matrix. The
- result will actually be a vector of vectors, which Calc will treat as a
- matrix only if every row contains the same number of values.
- If a line contains a portion surrounded by square brackets (or curly
- braces), that portion is interpreted as a vector which becomes a row of
- the matrix. Any text surrounding the bracketed portion on the line is
- ignored.
- Otherwise, the entire line is interpreted as a row vector as if it
- were surrounded by square brackets. Leading line numbers (in the
- format used in the Calc stack buffer) are ignored. If you wish to
- force this interpretation (even if the line contains bracketed
- portions), give a negative numeric prefix argument to the `C-x * r'
- command.
- If you give a numeric prefix argument of zero or plain `C-u', each
- line is instead interpreted as a single formula which is converted into
- a one-element vector. Thus the result of `C-u C-x * r' will be a
- one-column matrix. For example, suppose one line of the data is the
- expression `2 a'. A plain `C-x * r' will interpret this as `[2 a]',
- which in turn is read as a two-element vector that forms one row of the
- matrix. But a `C-u C-x * r' will interpret this row as `[2*a]'.
- If you give a positive numeric prefix argument N, then each line
- will be split up into columns of width N; each column is parsed
- separately as a matrix element. If a line contained `2 +/- 3 4 +/- 5',
- then grabbing with a prefix argument of 8 would correctly split the
- line into two error forms.
- *Note Matrix Functions::, to see how to pull the matrix apart into
- its constituent rows and columns. (If it is a 1x1 matrix, just hit `v
- u' (`calc-unpack') twice.)
- The `C-x * :' (`calc-grab-sum-down') command is a handy way to grab
- a rectangle of data and sum its columns. It is equivalent to typing
- `C-x * r', followed by `V R : +' (the vector reduction command that
- sums the columns of a matrix; *note Reducing::). The result of the
- command will be a vector of numbers, one for each column in the input
- data. The `C-x * _' (`calc-grab-sum-across') command similarly grabs a
- rectangle and sums its rows by executing `V R _ +'.
- As well as being more convenient, `C-x * :' and `C-x * _' are also
- much faster because they don't actually place the grabbed vector on the
- stack. In a `C-x * r V R : +' sequence, formatting the vector for
- display on the stack takes a large fraction of the total time (unless
- you have planned ahead and used `v .' and `t .' modes).
- For example, suppose we have a column of numbers in a file which we
- wish to sum. Go to one corner of the column and press `C-@' to set the
- mark; go to the other corner and type `C-x * :'. Since there is only
- one column, the result will be a vector of one number, the sum. (You
- can type `v u' to unpack this vector into a plain number if you want to
- do further arithmetic with it.)
- To compute the product of the column of numbers, we would have to do
- it "by hand" since there's no special grab-and-multiply command. Use
- `C-x * r' to grab the column of numbers into the calculator in the form
- of a column matrix. The statistics command `u *' is a handy way to
- find the product of a vector or matrix of numbers. *Note Statistical
- Operations::. Another approach would be to use an explicit column
- reduction command, `V R : *'.
- File: calc, Node: Yanking Into Buffers, Next: X Cut and Paste, Prev: Grabbing From Buffers, Up: Kill and Yank
- 16.6 Yanking into Other Buffers
- ===============================
- The plain `y' (`calc-copy-to-buffer') command inserts the number at the
- top of the stack into the most recently used normal editing buffer.
- (More specifically, this is the most recently used buffer which is
- displayed in a window and whose name does not begin with `*'. If there
- is no such buffer, this is the most recently used buffer except for
- Calculator and Calc Trail buffers.) The number is inserted exactly as
- it appears and without a newline. (If line-numbering is enabled, the
- line number is normally not included.) The number is _not_ removed
- from the stack.
- With a prefix argument, `y' inserts several numbers, one per line.
- A positive argument inserts the specified number of values from the top
- of the stack. A negative argument inserts the `n'th value from the top
- of the stack. An argument of zero inserts the entire stack. Note that
- `y' with an argument of 1 is slightly different from `y' with no
- argument; the former always copies full lines, whereas the latter
- strips off the trailing newline.
- With a lone `C-u' as a prefix argument, `y' _replaces_ the region in
- the other buffer with the yanked text, then quits the Calculator,
- leaving you in that buffer. A typical use would be to use `C-x * g' to
- read a region of data into the Calculator, operate on the data to
- produce a new matrix, then type `C-u y' to replace the original data
- with the new data. One might wish to alter the matrix display style
- (*note Vector and Matrix Formats::) or change the current display
- language (*note Language Modes::) before doing this. Also, note that
- this command replaces a linear region of text (as grabbed by `C-x *
- g'), not a rectangle (as grabbed by `C-x * r').
- If the editing buffer is in overwrite (as opposed to insert) mode,
- and the `C-u' prefix was not used, then the yanked number will
- overwrite the characters following point rather than being inserted
- before those characters. The usual conventions of overwrite mode are
- observed; for example, characters will be inserted at the end of a line
- rather than overflowing onto the next line. Yanking a multi-line
- object such as a matrix in overwrite mode overwrites the next N lines
- in the buffer, lengthening or shortening each line as necessary.
- Finally, if the thing being yanked is a simple integer or floating-point
- number (like `-1.2345e-3') and the characters following point also make
- up such a number, then Calc will replace that number with the new
- number, lengthening or shortening as necessary. The concept of
- "overwrite mode" has thus been generalized from overwriting characters
- to overwriting one complete number with another.
- The `C-x * y' key sequence is equivalent to `y' except that it can
- be typed anywhere, not just in Calc. This provides an easy way to
- guarantee that Calc knows which editing buffer you want to use!
- File: calc, Node: X Cut and Paste, Prev: Yanking Into Buffers, Up: Kill and Yank
- 16.7 X Cut and Paste
- ====================
- If you are using Emacs with the X window system, there is an easier way
- to move small amounts of data into and out of the calculator: Use the
- mouse-oriented cut and paste facilities of X.
- The default bindings for a three-button mouse cause the left button
- to move the Emacs cursor to the given place, the right button to select
- the text between the cursor and the clicked location, and the middle
- button to yank the selection into the buffer at the clicked location.
- So, if you have a Calc window and an editing window on your Emacs
- screen, you can use left-click/right-click to select a number, vector,
- or formula from one window, then middle-click to paste that value into
- the other window. When you paste text into the Calc window, Calc
- interprets it as an algebraic entry. It doesn't matter where you click
- in the Calc window; the new value is always pushed onto the top of the
- stack.
- The `xterm' program that is typically used for general-purpose shell
- windows in X interprets the mouse buttons in the same way. So you can
- use the mouse to move data between Calc and any other Unix program.
- One nice feature of `xterm' is that a double left-click selects one
- word, and a triple left-click selects a whole line. So you can usually
- transfer a single number into Calc just by double-clicking on it in the
- shell, then middle-clicking in the Calc window.
- File: calc, Node: Keypad Mode, Next: Embedded Mode, Prev: Kill and Yank, Up: Top
- 17 Keypad Mode
- **************
- The `C-x * k' (`calc-keypad') command starts the Calculator and
- displays a picture of a calculator-style keypad. If you are using the
- X window system, you can click on any of the "keys" in the keypad using
- the left mouse button to operate the calculator. The original window
- remains the selected window; in Keypad mode you can type in your file
- while simultaneously performing calculations with the mouse.
- If you have used `C-x * b' first, `C-x * k' instead invokes the
- `full-calc-keypad' command, which takes over the whole Emacs screen and
- displays the keypad, the Calc stack, and the Calc trail all at once.
- This mode would normally be used when running Calc standalone (*note
- Standalone Operation::).
- If you aren't using the X window system, you must switch into the
- `*Calc Keypad*' window, place the cursor on the desired "key," and type
- <SPC> or <RET>. If you think this is easier than using Calc normally,
- go right ahead.
- Calc commands are more or less the same in Keypad mode. Certain
- keypad keys differ slightly from the corresponding normal Calc
- keystrokes; all such deviations are described below.
- Keypad mode includes many more commands than will fit on the keypad
- at once. Click the right mouse button [`calc-keypad-menu'] to switch
- to the next menu. The bottom five rows of the keypad stay the same;
- the top three rows change to a new set of commands. To return to
- earlier menus, click the middle mouse button [`calc-keypad-menu-back']
- or simply advance through the menus until you wrap around. Typing
- <TAB> inside the keypad window is equivalent to clicking the right
- mouse button there.
- You can always click the <EXEC> button and type any normal Calc key
- sequence. This is equivalent to switching into the Calc buffer, typing
- the keys, then switching back to your original buffer.
- * Menu:
- * Keypad Main Menu::
- * Keypad Functions Menu::
- * Keypad Binary Menu::
- * Keypad Vectors Menu::
- * Keypad Modes Menu::
- File: calc, Node: Keypad Main Menu, Next: Keypad Functions Menu, Prev: Keypad Mode, Up: Keypad Mode
- 17.1 Main Menu
- ==============
- |----+----+--Calc---+----+----1
- |FLR |CEIL|RND |TRNC|CLN2|FLT |
- |----+----+----+----+----+----|
- | LN |EXP | |ABS |IDIV|MOD |
- |----+----+----+----+----+----|
- |SIN |COS |TAN |SQRT|y^x |1/x |
- |----+----+----+----+----+----|
- | ENTER |+/- |EEX |UNDO| <- |
- |-----+---+-+--+--+-+---++----|
- | INV | 7 | 8 | 9 | / |
- |-----+-----+-----+-----+-----|
- | HYP | 4 | 5 | 6 | * |
- |-----+-----+-----+-----+-----|
- |EXEC | 1 | 2 | 3 | - |
- |-----+-----+-----+-----+-----|
- | OFF | 0 | . | PI | + |
- |-----+-----+-----+-----+-----+
- This is the menu that appears the first time you start Keypad mode. It
- will show up in a vertical window on the right side of your screen.
- Above this menu is the traditional Calc stack display. On a 24-line
- screen you will be able to see the top three stack entries.
- The ten digit keys, decimal point, and <EEX> key are used for
- entering numbers in the obvious way. <EEX> begins entry of an exponent
- in scientific notation. Just as with regular Calc, the number is
- pushed onto the stack as soon as you press <ENTER> or any other
- function key.
- The <+/-> key corresponds to normal Calc's `n' key. During numeric
- entry it changes the sign of the number or of the exponent. At other
- times it changes the sign of the number on the top of the stack.
- The <INV> and <HYP> keys modify other keys. As well as having the
- effects described elsewhere in this manual, Keypad mode defines several
- other "inverse" operations. These are described below and in the
- following sections.
- The <ENTER> key finishes the current numeric entry, or otherwise
- duplicates the top entry on the stack.
- The <UNDO> key undoes the most recent Calc operation. `INV UNDO' is
- the "redo" command, and `HYP UNDO' is "last arguments" (`M-<RET>').
- The <<-> key acts as a "backspace" during numeric entry. At other
- times it removes the top stack entry. `INV <-' clears the entire
- stack. `HYP <-' takes an integer from the stack, then removes that
- many additional stack elements.
- The <EXEC> key prompts you to enter any keystroke sequence that
- would normally work in Calc mode. This can include a numeric prefix if
- you wish. It is also possible simply to switch into the Calc window
- and type commands in it; there is nothing "magic" about this window
- when Keypad mode is active.
- The other keys in this display perform their obvious calculator
- functions. <CLN2> rounds the top-of-stack by temporarily reducing the
- precision by 2 digits. <FLT> converts an integer or fraction on the
- top of the stack to floating-point.
- The <INV> and <HYP> keys combined with several of these keys give
- you access to some common functions even if the appropriate menu is not
- displayed. Obviously you don't need to learn these keys unless you
- find yourself wasting time switching among the menus.
- `INV +/-'
- is the same as <1/x>.
- `INV +'
- is the same as <SQRT>.
- `INV -'
- is the same as <CONJ>.
- `INV *'
- is the same as <y^x>.
- `INV /'
- is the same as <INV y^x> (the `x'th root of `y').
- `HYP/INV 1'
- are the same as <SIN> / `INV SIN'.
- `HYP/INV 2'
- are the same as <COS> / `INV COS'.
- `HYP/INV 3'
- are the same as <TAN> / `INV TAN'.
- `INV/HYP 4'
- are the same as <LN> / `HYP LN'.
- `INV/HYP 5'
- are the same as <EXP> / `HYP EXP'.
- `INV 6'
- is the same as <ABS>.
- `INV 7'
- is the same as <RND> (`calc-round').
- `INV 8'
- is the same as <CLN2>.
- `INV 9'
- is the same as <FLT> (`calc-float').
- `INV 0'
- is the same as <IMAG>.
- `INV .'
- is the same as <PREC>.
- `INV ENTER'
- is the same as <SWAP>.
- `HYP ENTER'
- is the same as <RLL3>.
- `INV HYP ENTER'
- is the same as <OVER>.
- `HYP +/-'
- packs the top two stack entries as an error form.
- `HYP EEX'
- packs the top two stack entries as a modulo form.
- `INV EEX'
- creates an interval form; this removes an integer which is one of
- 0 `[]', 1 `[)', 2 `(]' or 3 `()', followed by the two limits of
- the interval.
- The `OFF' key turns Calc off; typing `C-x * k' or `C-x * *' again
- has the same effect. This is analogous to typing `q' or hitting `C-x *
- c' again in the normal calculator. If Calc is running standalone (the
- `full-calc-keypad' command appeared in the command line that started
- Emacs), then `OFF' is replaced with `EXIT'; clicking on this actually
- exits Emacs itself.
- File: calc, Node: Keypad Functions Menu, Next: Keypad Binary Menu, Prev: Keypad Main Menu, Up: Keypad Mode
- 17.2 Functions Menu
- ===================
- |----+----+----+----+----+----2
- |IGAM|BETA|IBET|ERF |BESJ|BESY|
- |----+----+----+----+----+----|
- |IMAG|CONJ| RE |ATN2|RAND|RAGN|
- |----+----+----+----+----+----|
- |GCD |FACT|DFCT|BNOM|PERM|NXTP|
- |----+----+----+----+----+----|
- This menu provides various operations from the `f' and `k' prefix keys.
- <IMAG> multiplies the number on the stack by the imaginary number `i
- = (0, 1)'.
- <RE> extracts the real part a complex number. `INV RE' extracts the
- imaginary part.
- <RAND> takes a number from the top of the stack and computes a
- random number greater than or equal to zero but less than that number.
- (*Note Random Numbers::.) <RAGN> is the "random again" command; it
- computes another random number using the same limit as last time.
- <INV GCD> computes the LCM (least common multiple) function.
- <INV FACT> is the gamma function. `gamma(x) = (x-1)!'.
- <PERM> is the number-of-permutations function, which is on the `H k
- c' key in normal Calc.
- <NXTP> finds the next prime after a number. `INV NXTP' finds the
- previous prime.
- File: calc, Node: Keypad Binary Menu, Next: Keypad Vectors Menu, Prev: Keypad Functions Menu, Up: Keypad Mode
- 17.3 Binary Menu
- ================
- |----+----+----+----+----+----3
- |AND | OR |XOR |NOT |LSH |RSH |
- |----+----+----+----+----+----|
- |DEC |HEX |OCT |BIN |WSIZ|ARSH|
- |----+----+----+----+----+----|
- | A | B | C | D | E | F |
- |----+----+----+----+----+----|
- The keys in this menu perform operations on binary integers. Note that
- both logical and arithmetic right-shifts are provided. <INV LSH>
- rotates one bit to the left.
- The "difference" function (normally on `b d') is on <INV AND>. The
- "clip" function (normally on `b c') is on <INV NOT>.
- The <DEC>, <HEX>, <OCT>, and <BIN> keys select the current radix for
- display and entry of numbers: Decimal, hexadecimal, octal, or binary.
- The six letter keys <A> through <F> are used for entering hexadecimal
- numbers.
- The <WSIZ> key displays the current word size for binary operations
- and allows you to enter a new word size. You can respond to the prompt
- using either the keyboard or the digits and <ENTER> from the keypad.
- The initial word size is 32 bits.
- File: calc, Node: Keypad Vectors Menu, Next: Keypad Modes Menu, Prev: Keypad Binary Menu, Up: Keypad Mode
- 17.4 Vectors Menu
- =================
- |----+----+----+----+----+----4
- |SUM |PROD|MAX |MAP*|MAP^|MAP$|
- |----+----+----+----+----+----|
- |MINV|MDET|MTRN|IDNT|CRSS|"x" |
- |----+----+----+----+----+----|
- |PACK|UNPK|INDX|BLD |LEN |... |
- |----+----+----+----+----+----|
- The keys in this menu operate on vectors and matrices.
- <PACK> removes an integer N from the top of the stack; the next N
- stack elements are removed and packed into a vector, which is replaced
- onto the stack. Thus the sequence `1 ENTER 3 ENTER 5 ENTER 3 PACK'
- enters the vector `[1, 3, 5]' onto the stack. To enter a matrix, build
- each row on the stack as a vector, then use a final <PACK> to collect
- the rows into a matrix.
- <UNPK> unpacks the vector on the stack, pushing each of its
- components separately.
- <INDX> removes an integer N, then builds a vector of integers from 1
- to N. `INV INDX' takes three numbers from the stack: The vector size
- N, the starting number, and the increment. `BLD' takes an integer N
- and any value X and builds a vector of N copies of X.
- <IDNT> removes an integer N, then builds an N-by-N identity matrix.
- <LEN> replaces a vector by its length, an integer.
- <...> turns on or off "abbreviated" display mode for large vectors.
- <MINV>, <MDET>, <MTRN>, and <CROSS> are the matrix inverse,
- determinant, and transpose, and vector cross product.
- <SUM> replaces a vector by the sum of its elements. It is
- equivalent to `u +' in normal Calc (*note Statistical Operations::).
- <PROD> computes the product of the elements of a vector, and <MAX>
- computes the maximum of all the elements of a vector.
- <INV SUM> computes the alternating sum of the first element minus
- the second, plus the third, minus the fourth, and so on. <INV MAX>
- computes the minimum of the vector elements.
- <HYP SUM> computes the mean of the vector elements. <HYP PROD>
- computes the sample standard deviation. <HYP MAX> computes the median.
- <MAP*> multiplies two vectors elementwise. It is equivalent to the
- `V M *' command. <MAP^> computes powers elementwise. The arguments
- must be vectors of equal length, or one must be a vector and the other
- must be a plain number. For example, `2 MAP^' squares all the elements
- of a vector.
- <MAP$> maps the formula on the top of the stack across the vector in
- the second-to-top position. If the formula contains several variables,
- Calc takes that many vectors starting at the second-to-top position and
- matches them to the variables in alphabetical order. The result is a
- vector of the same size as the input vectors, whose elements are the
- formula evaluated with the variables set to the various sets of numbers
- in those vectors. For example, you could simulate <MAP^> using <MAP$>
- with the formula `x^y'.
- The `"x"' key pushes the variable name `x' onto the stack. To build
- the formula `x^2 + 6', you would use the key sequence `"x" 2 y^x 6 +'.
- This formula would then be suitable for use with the <MAP$> key
- described above. With <INV>, <HYP>, or <INV> and <HYP>, the `"x"' key
- pushes the variable names `y', `z', and `t', respectively.
- File: calc, Node: Keypad Modes Menu, Prev: Keypad Vectors Menu, Up: Keypad Mode
- 17.5 Modes Menu
- ===============
- |----+----+----+----+----+----5
- |FLT |FIX |SCI |ENG |GRP | |
- |----+----+----+----+----+----|
- |RAD |DEG |FRAC|POLR|SYMB|PREC|
- |----+----+----+----+----+----|
- |SWAP|RLL3|RLL4|OVER|STO |RCL |
- |----+----+----+----+----+----|
- The keys in this menu manipulate modes, variables, and the stack.
- The <FLT>, <FIX>, <SCI>, and <ENG> keys select floating-point,
- fixed-point, scientific, or engineering notation. <FIX> displays two
- digits after the decimal by default; the others display full precision.
- With the <INV> prefix, these keys pop a number-of-digits argument from
- the stack.
- The <GRP> key turns grouping of digits with commas on or off. `INV
- GRP' enables grouping to the right of the decimal point as well as to
- the left.
- The <RAD> and <DEG> keys switch between radians and degrees for
- trigonometric functions.
- The <FRAC> key turns Fraction mode on or off. This affects whether
- commands like `/' with integer arguments produce fractional or
- floating-point results.
- The <POLR> key turns Polar mode on or off, determining whether polar
- or rectangular complex numbers are used by default.
- The <SYMB> key turns Symbolic mode on or off, in which operations
- that would produce inexact floating-point results are left unevaluated
- as algebraic formulas.
- The <PREC> key selects the current precision. Answer with the
- keyboard or with the keypad digit and <ENTER> keys.
- The <SWAP> key exchanges the top two stack elements. The <RLL3> key
- rotates the top three stack elements upwards. The <RLL4> key rotates
- the top four stack elements upwards. The <OVER> key duplicates the
- second-to-top stack element.
- The <STO> and <RCL> keys are analogous to `s t' and `s r' in regular
- Calc. *Note Store and Recall::. Click the <STO> or <RCL> key, then
- one of the ten digits. (Named variables are not available in Keypad
- mode.) You can also use, for example, `STO + 3' to add to register 3.
- File: calc, Node: Embedded Mode, Next: Programming, Prev: Keypad Mode, Up: Top
- 18 Embedded Mode
- ****************
- Embedded mode in Calc provides an alternative to copying numbers and
- formulas back and forth between editing buffers and the Calc stack. In
- Embedded mode, your editing buffer becomes temporarily linked to the
- stack and this copying is taken care of automatically.
- * Menu:
- * Basic Embedded Mode::
- * More About Embedded Mode::
- * Assignments in Embedded Mode::
- * Mode Settings in Embedded Mode::
- * Customizing Embedded Mode::
- File: calc, Node: Basic Embedded Mode, Next: More About Embedded Mode, Prev: Embedded Mode, Up: Embedded Mode
- 18.1 Basic Embedded Mode
- ========================
- To enter Embedded mode, position the Emacs point (cursor) on a formula
- in any buffer and press `C-x * e' (`calc-embedded'). Note that `C-x *
- e' is not to be used in the Calc stack buffer like most Calc commands,
- but rather in regular editing buffers that are visiting your own files.
- Calc will try to guess an appropriate language based on the major
- mode of the editing buffer. (*Note Language Modes::.) If the current
- buffer is in `latex-mode', for example, Calc will set its language to
- LaTeX. Similarly, Calc will use TeX language for `tex-mode',
- `plain-tex-mode' and `context-mode', C language for `c-mode' and
- `c++-mode', FORTRAN language for `fortran-mode' and `f90-mode', Pascal
- for `pascal-mode', and eqn for `nroff-mode' (*note Customizing Calc::).
- These can be overridden with Calc's mode changing commands (*note Mode
- Settings in Embedded Mode::). If no suitable language is available,
- Calc will continue with its current language.
- Calc normally scans backward and forward in the buffer for the
- nearest opening and closing "formula delimiters". The simplest
- delimiters are blank lines. Other delimiters that Embedded mode
- understands are:
- 1. The TeX and LaTeX math delimiters `$ $', `$$ $$', `\[ \]', and `\(
- \)';
- 2. Lines beginning with `\begin' and `\end' (except matrix
- delimiters);
- 3. Lines beginning with `@' (Texinfo delimiters).
- 4. Lines beginning with `.EQ' and `.EN' ("eqn" delimiters);
- 5. Lines containing a single `%' or `.\"' symbol and nothing else.
- *Note Customizing Embedded Mode::, to see how to make Calc recognize
- your own favorite delimiters. Delimiters like `$ $' can appear on
- their own separate lines or in-line with the formula.
- If you give a positive or negative numeric prefix argument, Calc
- instead uses the current point as one end of the formula, and includes
- that many lines forward or backward (respectively, including the current
- line). Explicit delimiters are not necessary in this case.
- With a prefix argument of zero, Calc uses the current region
- (delimited by point and mark) instead of formula delimiters. With a
- prefix argument of `C-u' only, Calc uses the current line as the
- formula.
- The `C-x * w' (`calc-embedded-word') command will start Embedded
- mode on the current "word"; in this case Calc will scan for the first
- non-numeric character (i.e., the first character that is not a digit,
- sign, decimal point, or upper- or lower-case `e') forward and backward
- to delimit the formula.
- When you enable Embedded mode for a formula, Calc reads the text
- between the delimiters and tries to interpret it as a Calc formula.
- Calc can generally identify TeX formulas and Big-style formulas even if
- the language mode is wrong. If Calc can't make sense of the formula,
- it beeps and refuses to enter Embedded mode. But if the current
- language is wrong, Calc can sometimes parse the formula successfully
- (but incorrectly); for example, the C expression `atan(a[1])' can be
- parsed in Normal language mode, but the `atan' won't correspond to the
- built-in `arctan' function, and the `a[1]' will be interpreted as `a'
- times the vector `[1]'!
- If you press `C-x * e' or `C-x * w' to activate an embedded formula
- which is blank, say with the cursor on the space between the two
- delimiters `$ $', Calc will immediately prompt for an algebraic entry.
- Only one formula in one buffer can be enabled at a time. If you
- move to another area of the current buffer and give Calc commands, Calc
- turns Embedded mode off for the old formula and then tries to restart
- Embedded mode at the new position. Other buffers are not affected by
- Embedded mode.
- When Embedded mode begins, Calc pushes the current formula onto the
- stack. No Calc stack window is created; however, Calc copies the
- top-of-stack position into the original buffer at all times. You can
- create a Calc window by hand with `C-x * o' if you find you need to see
- the entire stack.
- For example, typing `C-x * e' while somewhere in the formula `n>2'
- in the following line enables Embedded mode on that inequality:
- We define $F_n = F_(n-1)+F_(n-2)$ for all $n>2$.
- The formula `n>2' will be pushed onto the Calc stack, and the top of
- stack will be copied back into the editing buffer. This means that
- spaces will appear around the `>' symbol to match Calc's usual display
- style:
- We define $F_n = F_(n-1)+F_(n-2)$ for all $n > 2$.
- No spaces have appeared around the `+' sign because it's in a different
- formula, one which we have not yet touched with Embedded mode.
- Now that Embedded mode is enabled, keys you type in this buffer are
- interpreted as Calc commands. At this point we might use the "commute"
- command `j C' to reverse the inequality. This is a selection-based
- command for which we first need to move the cursor onto the operator
- (`>' in this case) that needs to be commuted.
- We define $F_n = F_(n-1)+F_(n-2)$ for all $2 < n$.
- The `C-x * o' command is a useful way to open a Calc window without
- actually selecting that window. Giving this command verifies that `2 <
- n' is also on the Calc stack. Typing `17 <RET>' would produce:
- We define $F_n = F_(n-1)+F_(n-2)$ for all $17$.
- with `2 < n' and `17' on the stack; typing <TAB> at this point will
- exchange the two stack values and restore `2 < n' to the embedded
- formula. Even though you can't normally see the stack in Embedded
- mode, it is still there and it still operates in the same way. But, as
- with old-fashioned RPN calculators, you can only see the value at the
- top of the stack at any given time (unless you use `C-x * o').
- Typing `C-x * e' again turns Embedded mode off. The Calc window
- reveals that the formula `2 < n' is automatically removed from the
- stack, but the `17' is not. Entering Embedded mode always pushes one
- thing onto the stack, and leaving Embedded mode always removes one
- thing. Anything else that happens on the stack is entirely your
- business as far as Embedded mode is concerned.
- If you press `C-x * e' in the wrong place by accident, it is
- possible that Calc will be able to parse the nearby text as a formula
- and will mangle that text in an attempt to redisplay it "properly" in
- the current language mode. If this happens, press `C-x * e' again to
- exit Embedded mode, then give the regular Emacs "undo" command (`C-_'
- or `C-x u') to put the text back the way it was before Calc edited it.
- Note that Calc's own Undo command (typed before you turn Embedded mode
- back off) will not do you any good, because as far as Calc is concerned
- you haven't done anything with this formula yet.
- File: calc, Node: More About Embedded Mode, Next: Assignments in Embedded Mode, Prev: Basic Embedded Mode, Up: Embedded Mode
- 18.2 More About Embedded Mode
- =============================
- When Embedded mode "activates" a formula, i.e., when it examines the
- formula for the first time since the buffer was created or loaded, Calc
- tries to sense the language in which the formula was written. If the
- formula contains any LaTeX-like `\' sequences, it is parsed (i.e.,
- read) in LaTeX mode. If the formula appears to be written in
- multi-line Big mode, it is parsed in Big mode. Otherwise, it is parsed
- according to the current language mode.
- Note that Calc does not change the current language mode according
- the formula it reads in. Even though it can read a LaTeX formula when
- not in LaTeX mode, it will immediately rewrite this formula using
- whatever language mode is in effect.
- Calc's parser is unable to read certain kinds of formulas. For
- example, with `v ]' (`calc-matrix-brackets') you can specify matrix
- display styles which the parser is unable to recognize as matrices.
- The `d p' (`calc-show-plain') command turns on a mode in which a
- "plain" version of a formula is placed in front of the fully-formatted
- version. When Calc reads a formula that has such a plain version in
- front, it reads the plain version and ignores the formatted version.
- Plain formulas are preceded and followed by `%%%' signs by default.
- This notation has the advantage that the `%' character begins a comment
- in TeX and LaTeX, so if your formula is embedded in a TeX or LaTeX
- document its plain version will be invisible in the final printed copy.
- Certain major modes have different delimiters to ensure that the
- "plain" version will be in a comment for those modes, also. See *note
- Customizing Embedded Mode:: to see how to change the "plain" formula
- delimiters.
- There are several notations which Calc's parser for "big" formatted
- formulas can't yet recognize. In particular, it can't read the large
- symbols for `sum', `prod', and `integ', and it can't handle `=>' with
- the righthand argument omitted. Also, Calc won't recognize special
- formats you have defined with the `Z C' command (*note User-Defined
- Compositions::). In these cases it is important to use "plain" mode to
- make sure Calc will be able to read your formula later.
- Another example where "plain" mode is important is if you have
- specified a float mode with few digits of precision. Normally any
- digits that are computed but not displayed will simply be lost when you
- save and re-load your embedded buffer, but "plain" mode allows you to
- make sure that the complete number is present in the file as well as
- the rounded-down number.
- Embedded buffers remember active formulas for as long as they exist
- in Emacs memory. Suppose you have an embedded formula which is `pi' to
- the normal 12 decimal places, and then type `C-u 5 d n' to display only
- five decimal places. If you then type `d n', all 12 places reappear
- because the full number is still there on the Calc stack. More
- surprisingly, even if you exit Embedded mode and later re-enter it for
- that formula, typing `d n' will restore all 12 places because each
- buffer remembers all its active formulas. However, if you save the
- buffer in a file and reload it in a new Emacs session, all
- non-displayed digits will have been lost unless you used "plain" mode.
- In some applications of Embedded mode, you will want to have a
- sequence of copies of a formula that show its evolution as you work on
- it. For example, you might want to have a sequence like this in your
- file (elaborating here on the example from the "Getting Started"
- chapter):
- The derivative of
- ln(ln(x))
- is
- (the derivative of ln(ln(x)))
- whose value at x = 2 is
- (the value)
- and at x = 3 is
- (the value)
- The `C-x * d' (`calc-embedded-duplicate') command is a handy way to
- make sequences like this. If you type `C-x * d', the formula under the
- cursor (which may or may not have Embedded mode enabled for it at the
- time) is copied immediately below and Embedded mode is then enabled for
- that copy.
- For this example, you would start with just
- The derivative of
- ln(ln(x))
- and press `C-x * d' with the cursor on this formula. The result is
- The derivative of
- ln(ln(x))
- ln(ln(x))
- with the second copy of the formula enabled in Embedded mode. You can
- now press `a d x <RET>' to take the derivative, and `C-x * d C-x * d'
- to make two more copies of the derivative. To complete the
- computations, type `3 s l x <RET>' to evaluate the last formula, then
- move up to the second-to-last formula and type `2 s l x <RET>'.
- Finally, you would want to press `C-x * e' to exit Embedded mode,
- then go up and insert the necessary text in between the various
- formulas and numbers.
- The `C-x * f' (`calc-embedded-new-formula') command creates a new
- embedded formula at the current point. It inserts some default
- delimiters, which are usually just blank lines, and then does an
- algebraic entry to get the formula (which is then enabled for Embedded
- mode). This is just shorthand for typing the delimiters yourself,
- positioning the cursor between the new delimiters, and pressing `C-x *
- e'. The key sequence `C-x * '' is equivalent to `C-x * f'.
- The `C-x * n' (`calc-embedded-next') and `C-x * p'
- (`calc-embedded-previous') commands move the cursor to the next or
- previous active embedded formula in the buffer. They can take positive
- or negative prefix arguments to move by several formulas. Note that
- these commands do not actually examine the text of the buffer looking
- for formulas; they only see formulas which have previously been
- activated in Embedded mode. In fact, `C-x * n' and `C-x * p' are a
- useful way to tell which embedded formulas are currently active. Also,
- note that these commands do not enable Embedded mode on the next or
- previous formula, they just move the cursor.
- The `C-x * `' (`calc-embedded-edit') command edits the embedded
- formula at the current point as if by ``' (`calc-edit'). Embedded mode
- does not have to be enabled for this to work. Press `C-c C-c' to
- finish the edit, or `C-x k' to cancel.
- File: calc, Node: Assignments in Embedded Mode, Next: Mode Settings in Embedded Mode, Prev: More About Embedded Mode, Up: Embedded Mode
- 18.3 Assignments in Embedded Mode
- =================================
- The `:=' (assignment) and `=>' ("evaluates-to") operators are
- especially useful in Embedded mode. They allow you to make a
- definition in one formula, then refer to that definition in other
- formulas embedded in the same buffer.
- An embedded formula which is an assignment to a variable, as in
- foo := 5
- records `5' as the stored value of `foo' for the purposes of Embedded
- mode operations in the current buffer. It does _not_ actually store
- `5' as the "global" value of `foo', however. Regular Calc operations,
- and Embedded formulas in other buffers, will not see this assignment.
- One way to use this assigned value is simply to create an Embedded
- formula elsewhere that refers to `foo', and to press `=' in that
- formula. However, this permanently replaces the `foo' in the formula
- with its current value. More interesting is to use `=>' elsewhere:
- foo + 7 => 12
- *Note Evaluates-To Operator::, for a general discussion of `=>'.
- If you move back and change the assignment to `foo', any `=>'
- formulas which refer to it are automatically updated.
- foo := 17
- foo + 7 => 24
- The obvious question then is, _how_ can one easily change the
- assignment to `foo'? If you simply select the formula in Embedded mode
- and type 17, the assignment itself will be replaced by the 17. The
- effect on the other formula will be that the variable `foo' becomes
- unassigned:
- 17
- foo + 7 => foo + 7
- The right thing to do is first to use a selection command (`j 2'
- will do the trick) to select the righthand side of the assignment.
- Then, `17 <TAB> <DEL>' will swap the 17 into place (*note Selecting
- Subformulas::, to see how this works).
- The `C-x * j' (`calc-embedded-select') command provides an easy way
- to operate on assignments. It is just like `C-x * e', except that if
- the enabled formula is an assignment, it uses `j 2' to select the
- righthand side. If the enabled formula is an evaluates-to, it uses `j
- 1' to select the lefthand side. A formula can also be a combination of
- both:
- bar := foo + 3 => 20
- in which case `C-x * j' will select the middle part (`foo + 3').
- The formula is automatically deselected when you leave Embedded mode.
- Another way to change the assignment to `foo' would simply be to
- edit the number using regular Emacs editing rather than Embedded mode.
- Then, we have to find a way to get Embedded mode to notice the change.
- The `C-x * u' (`calc-embedded-update-formula') command is a convenient
- way to do this.
- foo := 6
- foo + 7 => 13
- Pressing `C-x * u' is much like pressing `C-x * e = C-x * e', that
- is, temporarily enabling Embedded mode for the formula under the cursor
- and then evaluating it with `='. But `C-x * u' does not actually use
- `C-x * e', and in fact another formula somewhere else can be enabled in
- Embedded mode while you use `C-x * u' and that formula will not be
- disturbed.
- With a numeric prefix argument, `C-x * u' updates all active `=>'
- formulas in the buffer. Formulas which have not yet been activated in
- Embedded mode, and formulas which do not have `=>' as their top-level
- operator, are not affected by this. (This is useful only if you have
- used `m C'; see below.)
- With a plain `C-u' prefix, `C-u C-x * u' updates only in the region
- between mark and point rather than in the whole buffer.
- `C-x * u' is also a handy way to activate a formula, such as an `=>'
- formula that has freshly been typed in or loaded from a file.
- The `C-x * a' (`calc-embedded-activate') command scans through the
- current buffer and activates all embedded formulas that contain `:=' or
- `=>' symbols. This does not mean that Embedded mode is actually turned
- on, but only that the formulas' positions are registered with Embedded
- mode so that the `=>' values can be properly updated as assignments are
- changed.
- It is a good idea to type `C-x * a' right after loading a file that
- uses embedded `=>' operators. Emacs includes a nifty "buffer-local
- variables" feature that you can use to do this automatically. The idea
- is to place near the end of your file a few lines that look like this:
- --- Local Variables: ---
- --- eval:(calc-embedded-activate) ---
- --- End: ---
- where the leading and trailing `---' can be replaced by any suitable
- strings (which must be the same on all three lines) or omitted
- altogether; in a TeX or LaTeX file, `%' would be a good leading string
- and no trailing string would be necessary. In a C program, `/*' and
- `*/' would be good leading and trailing strings.
- When Emacs loads a file into memory, it checks for a Local Variables
- section like this one at the end of the file. If it finds this
- section, it does the specified things (in this case, running `C-x * a'
- automatically) before editing of the file begins. The Local Variables
- section must be within 3000 characters of the end of the file for Emacs
- to find it, and it must be in the last page of the file if the file has
- any page separators. *Note Local Variables in Files: (emacs)File
- Variables.
- Note that `C-x * a' does not update the formulas it finds. To do
- this, type, say, `M-1 C-x * u' after `C-x * a'. Generally this should
- not be a problem, though, because the formulas will have been
- up-to-date already when the file was saved.
- Normally, `C-x * a' activates all the formulas it finds, but any
- previous active formulas remain active as well. With a positive
- numeric prefix argument, `C-x * a' first deactivates all current active
- formulas, then actives the ones it finds in its scan of the buffer.
- With a negative prefix argument, `C-x * a' simply deactivates all
- formulas.
- Embedded mode has two symbols, `Active' and `~Active', which it puts
- next to the major mode name in a buffer's mode line. It puts `Active'
- if it has reason to believe that all formulas in the buffer are active,
- because you have typed `C-x * a' and Calc has not since had to
- deactivate any formulas (which can happen if Calc goes to update an
- `=>' formula somewhere because a variable changed, and finds that the
- formula is no longer there due to some kind of editing outside of
- Embedded mode). Calc puts `~Active' in the mode line if some, but
- probably not all, formulas in the buffer are active. This happens if
- you activate a few formulas one at a time but never use `C-x * a', or
- if you used `C-x * a' but then Calc had to deactivate a formula because
- it lost track of it. If neither of these symbols appears in the mode
- line, no embedded formulas are active in the buffer (e.g., before
- Embedded mode has been used, or after a `M-- C-x * a').
- Embedded formulas can refer to assignments both before and after them
- in the buffer. If there are several assignments to a variable, the
- nearest preceding assignment is used if there is one, otherwise the
- following assignment is used.
- x => 1
- x := 1
- x => 1
- x := 2
- x => 2
- As well as simple variables, you can also assign to subscript
- expressions of the form `VAR_NUMBER' (as in `x_0'), or `VAR_VAR' (as in
- `x_max'). Assignments to other kinds of objects can be represented by
- Calc, but the automatic linkage between assignments and references works
- only for plain variables and these two kinds of subscript expressions.
- If there are no assignments to a given variable, the global stored
- value for the variable is used (*note Storing Variables::), or, if no
- value is stored, the variable is left in symbolic form. Note that
- global stored values will be lost when the file is saved and loaded in
- a later Emacs session, unless you have used the `s p'
- (`calc-permanent-variable') command to save them; *note Operations on
- Variables::.
- The `m C' (`calc-auto-recompute') command turns automatic
- recomputation of `=>' forms on and off. If you turn automatic
- recomputation off, you will have to use `C-x * u' to update these
- formulas manually after an assignment has been changed. If you plan to
- change several assignments at once, it may be more efficient to type `m
- C', change all the assignments, then use `M-1 C-x * u' to update the
- entire buffer afterwards. The `m C' command also controls `=>'
- formulas on the stack; *note Evaluates-To Operator::. When you turn
- automatic recomputation back on, the stack will be updated but the
- Embedded buffer will not; you must use `C-x * u' to update the buffer
- by hand.
- File: calc, Node: Mode Settings in Embedded Mode, Next: Customizing Embedded Mode, Prev: Assignments in Embedded Mode, Up: Embedded Mode
- 18.4 Mode Settings in Embedded Mode
- ===================================
- The mode settings can be changed while Calc is in embedded mode, but by
- default they will revert to their original values when embedded mode is
- ended. However, the modes saved when the mode-recording mode is `Save'
- (see below) and the modes in effect when the `m e'
- (`calc-embedded-preserve-modes') command is given will be preserved
- when embedded mode is ended.
- Embedded mode has a rather complicated mechanism for handling mode
- settings in Embedded formulas. It is possible to put annotations in
- the file that specify mode settings either global to the entire file or
- local to a particular formula or formulas. In the latter case,
- different modes can be specified for use when a formula is the enabled
- Embedded mode formula.
- When you give any mode-setting command, like `m f' (for Fraction
- mode) or `d s' (for scientific notation), Embedded mode adds a line
- like the following one to the file just before the opening delimiter of
- the formula.
- % [calc-mode: fractions: t]
- % [calc-mode: float-format: (sci 0)]
- When Calc interprets an embedded formula, it scans the text before
- the formula for mode-setting annotations like these and sets the Calc
- buffer to match these modes. Modes not explicitly described in the
- file are not changed. Calc scans all the way to the top of the file,
- or up to a line of the form
- % [calc-defaults]
- which you can insert at strategic places in the file if this backward
- scan is getting too slow, or just to provide a barrier between one
- "zone" of mode settings and another.
- If the file contains several annotations for the same mode, the
- closest one before the formula is used. Annotations after the formula
- are never used (except for global annotations, described below).
- The scan does not look for the leading `% ', only for the square
- brackets and the text they enclose. In fact, the leading characters
- are different for different major modes. You can edit the mode
- annotations to a style that works better in context if you wish. *Note
- Customizing Embedded Mode::, to see how to change the style that Calc
- uses when it generates the annotations. You can write mode annotations
- into the file yourself if you know the syntax; the easiest way to find
- the syntax for a given mode is to let Calc write the annotation for it
- once and see what it does.
- If you give a mode-changing command for a mode that already has a
- suitable annotation just above the current formula, Calc will modify
- that annotation rather than generating a new, conflicting one.
- Mode annotations have three parts, separated by colons. (Spaces
- after the colons are optional.) The first identifies the kind of mode
- setting, the second is a name for the mode itself, and the third is the
- value in the form of a Lisp symbol, number, or list. Annotations with
- unrecognizable text in the first or second parts are ignored. The
- third part is not checked to make sure the value is of a valid type or
- range; if you write an annotation by hand, be sure to give a proper
- value or results will be unpredictable. Mode-setting annotations are
- case-sensitive.
- While Embedded mode is enabled, the word `Local' appears in the mode
- line. This is to show that mode setting commands generate annotations
- that are "local" to the current formula or set of formulas. The `m R'
- (`calc-mode-record-mode') command causes Calc to generate different
- kinds of annotations. Pressing `m R' repeatedly cycles through the
- possible modes.
- `LocEdit' and `LocPerm' modes generate annotations that look like
- this, respectively:
- % [calc-edit-mode: float-format: (sci 0)]
- % [calc-perm-mode: float-format: (sci 5)]
- The first kind of annotation will be used only while a formula is
- enabled in Embedded mode. The second kind will be used only when the
- formula is _not_ enabled. (Whether the formula is "active" or not,
- i.e., whether Calc has seen this formula yet, is not relevant here.)
- `Global' mode generates an annotation like this at the end of the
- file:
- % [calc-global-mode: fractions t]
- Global mode annotations affect all formulas throughout the file, and
- may appear anywhere in the file. This allows you to tuck your mode
- annotations somewhere out of the way, say, on a new page of the file,
- as long as those mode settings are suitable for all formulas in the
- file.
- Enabling a formula with `C-x * e' causes a fresh scan for local mode
- annotations; you will have to use this after adding annotations above a
- formula by hand to get the formula to notice them. Updating a formula
- with `C-x * u' will also re-scan the local modes, but global modes are
- only re-scanned by `C-x * a'.
- Another way that modes can get out of date is if you add a local
- mode annotation to a formula that has another formula after it. In
- this example, we have used the `d s' command while the first of the two
- embedded formulas is active. But the second formula has not changed
- its style to match, even though by the rules of reading annotations the
- `(sci 0)' applies to it, too.
- % [calc-mode: float-format: (sci 0)]
- 1.23e2
- 456.
- We would have to go down to the other formula and press `C-x * u' on
- it in order to get it to notice the new annotation.
- Two more mode-recording modes selectable by `m R' are available
- which are also available outside of Embedded mode. (*note General Mode
- Commands::.) They are `Save', in which mode settings are recorded
- permanently in your Calc init file (the file given by the variable
- `calc-settings-file', typically `~/.emacs.d/calc.el') rather than by
- annotating the current document, and no-recording mode (where there is
- no symbol like `Save' or `Local' in the mode line), in which
- mode-changing commands do not leave any annotations at all.
- When Embedded mode is not enabled, mode-recording modes except for
- `Save' have no effect.
- File: calc, Node: Customizing Embedded Mode, Prev: Mode Settings in Embedded Mode, Up: Embedded Mode
- 18.5 Customizing Embedded Mode
- ==============================
- You can modify Embedded mode's behavior by setting various Lisp
- variables described here. These variables are customizable (*note
- Customizing Calc::), or you can use `M-x set-variable' or `M-x
- edit-options' to adjust a variable on the fly. (Another possibility
- would be to use a file-local variable annotation at the end of the file;
- *note Local Variables in Files: (emacs)File Variables.) Many of the
- variables given mentioned here can be set to depend on the major mode
- of the editing buffer (*note Customizing Calc::).
- The `calc-embedded-open-formula' variable holds a regular expression
- for the opening delimiter of a formula. *Note Regular Expression
- Search: (emacs)Regexp Search, to see how regular expressions work.
- Basically, a regular expression is a pattern that Calc can search for.
- A regular expression that considers blank lines, `$', and `$$' to be
- opening delimiters is `"\\`\\|^\n\\|\\$\\$?"'. Just in case the
- meaning of this regular expression is not completely plain, let's go
- through it in detail.
- The surrounding `" "' marks quote the text between them as a Lisp
- string. If you left them off, `set-variable' or `edit-options' would
- try to read the regular expression as a Lisp program.
- The most obvious property of this regular expression is that it
- contains indecently many backslashes. There are actually two levels of
- backslash usage going on here. First, when Lisp reads a quoted string,
- all pairs of characters beginning with a backslash are interpreted as
- special characters. Here, `\n' changes to a new-line character, and
- `\\' changes to a single backslash. So the actual regular expression
- seen by Calc is `\`\|^ (newline) \|\$\$?'.
- Regular expressions also consider pairs beginning with backslash to
- have special meanings. Sometimes the backslash is used to quote a
- character that otherwise would have a special meaning in a regular
- expression, like `$', which normally means "end-of-line," or `?', which
- means that the preceding item is optional. So `\$\$?' matches either
- one or two dollar signs.
- The other codes in this regular expression are `^', which matches
- "beginning-of-line," `\|', which means "or," and `\`', which matches
- "beginning-of-buffer." So the whole pattern means that a formula
- begins at the beginning of the buffer, or on a newline that occurs at
- the beginning of a line (i.e., a blank line), or at one or two dollar
- signs.
- The default value of `calc-embedded-open-formula' looks just like
- this example, with several more alternatives added on to recognize
- various other common kinds of delimiters.
- By the way, the reason to use `^\n' rather than `^$' or `\n\n',
- which also would appear to match blank lines, is that the former
- expression actually "consumes" only one newline character as _part of_
- the delimiter, whereas the latter expressions consume zero or two
- newlines, respectively. The former choice gives the most natural
- behavior when Calc must operate on a whole formula including its
- delimiters.
- See the Emacs manual for complete details on regular expressions.
- But just for your convenience, here is a list of all characters which
- must be quoted with backslash (like `\$') to avoid some special
- interpretation: `. * + ? [ ] ^ $ \'. (Note the backslash in this
- list; for example, to match `\[' you must use `"\\\\\\["'. An exercise
- for the reader is to account for each of these six backslashes!)
- The `calc-embedded-close-formula' variable holds a regular
- expression for the closing delimiter of a formula. A closing regular
- expression to match the above example would be `"\\'\\|\n$\\|\\$\\$?"'.
- This is almost the same as the other one, except it now uses `\''
- ("end-of-buffer") and `\n$' (newline occurring at end of line, yet
- another way of describing a blank line that is more appropriate for this
- case).
- The `calc-embedded-word-regexp' variable holds a regular expression
- used to define an expression to look for (a "word") when you type `C-x
- * w' to enable Embedded mode.
- The `calc-embedded-open-plain' variable is a string which begins a
- "plain" formula written in front of the formatted formula when `d p'
- mode is turned on. Note that this is an actual string, not a regular
- expression, because Calc must be able to write this string into a
- buffer as well as to recognize it. The default string is `"%%% "'
- (note the trailing space), but may be different for certain major modes.
- The `calc-embedded-close-plain' variable is a string which ends a
- "plain" formula. The default is `" %%%\n"', but may be different for
- different major modes. Without the trailing newline here, the first
- line of a Big mode formula that followed might be shifted over with
- respect to the other lines.
- The `calc-embedded-open-new-formula' variable is a string which is
- inserted at the front of a new formula when you type `C-x * f'. Its
- default value is `"\n\n"'. If this string begins with a newline
- character and the `C-x * f' is typed at the beginning of a line, `C-x *
- f' will skip this first newline to avoid introducing unnecessary blank
- lines in the file.
- The `calc-embedded-close-new-formula' variable is the corresponding
- string which is inserted at the end of a new formula. Its default
- value is also `"\n\n"'. The final newline is omitted by `C-x * f' if
- typed at the end of a line. (It follows that if `C-x * f' is typed on
- a blank line, both a leading opening newline and a trailing closing
- newline are omitted.)
- The `calc-embedded-announce-formula' variable is a regular
- expression which is sure to be followed by an embedded formula. The
- `C-x * a' command searches for this pattern as well as for `=>' and
- `:=' operators. Note that `C-x * a' will not activate just anything
- surrounded by formula delimiters; after all, blank lines are considered
- formula delimiters by default! But if your language includes a
- delimiter which can only occur actually in front of a formula, you can
- take advantage of it here. The default pattern is `"%Embed\n\\(%
- .*\n\\)*"', but may be different for different major modes. This
- pattern will check for `%Embed' followed by any number of lines
- beginning with `%' and a space. This last is important to make Calc
- consider mode annotations part of the pattern, so that the formula's
- opening delimiter really is sure to follow the pattern.
- The `calc-embedded-open-mode' variable is a string (not a regular
- expression) which should precede a mode annotation. Calc never scans
- for this string; Calc always looks for the annotation itself. But this
- is the string that is inserted before the opening bracket when Calc
- adds an annotation on its own. The default is `"% "', but may be
- different for different major modes.
- The `calc-embedded-close-mode' variable is a string which follows a
- mode annotation written by Calc. Its default value is simply a
- newline, `"\n"', but may be different for different major modes. If
- you change this, it is a good idea still to end with a newline so that
- mode annotations will appear on lines by themselves.
- File: calc, Node: Programming, Next: Copying, Prev: Embedded Mode, Up: Top
- 19 Programming
- **************
- There are several ways to "program" the Emacs Calculator, depending on
- the nature of the problem you need to solve.
- 1. "Keyboard macros" allow you to record a sequence of keystrokes and
- play them back at a later time. This is just the standard Emacs
- keyboard macro mechanism, dressed up with a few more features such
- as loops and conditionals.
- 2. "Algebraic definitions" allow you to use any formula to define a
- new function. This function can then be used in algebraic
- formulas or as an interactive command.
- 3. "Rewrite rules" are discussed in the section on algebra commands.
- *Note Rewrite Rules::. If you put your rewrite rules in the
- variable `EvalRules', they will be applied automatically to all
- Calc results in just the same way as an internal "rule" is applied
- to evaluate `sqrt(9)' to 3 and so on. *Note Automatic Rewrites::.
- 4. "Lisp" is the programming language that Calc (and most of Emacs)
- is written in. If the above techniques aren't powerful enough, you
- can write Lisp functions to do anything that built-in Calc commands
- can do. Lisp code is also somewhat faster than keyboard macros or
- rewrite rules.
- Programming features are available through the `z' and `Z' prefix
- keys. New commands that you define are two-key sequences beginning
- with `z'. Commands for managing these definitions use the shift-`Z'
- prefix. (The `Z T' (`calc-timing') command is described elsewhere;
- *note Troubleshooting Commands::. The `Z C'
- (`calc-user-define-composition') command is also described elsewhere;
- *note User-Defined Compositions::.)
- * Menu:
- * Creating User Keys::
- * Keyboard Macros::
- * Invocation Macros::
- * Algebraic Definitions::
- * Lisp Definitions::
- File: calc, Node: Creating User Keys, Next: Keyboard Macros, Prev: Programming, Up: Programming
- 19.1 Creating User Keys
- =======================
- Any Calculator command may be bound to a key using the `Z D'
- (`calc-user-define') command. Actually, it is bound to a two-key
- sequence beginning with the lower-case `z' prefix.
- The `Z D' command first prompts for the key to define. For example,
- press `Z D a' to define the new key sequence `z a'. You are then
- prompted for the name of the Calculator command that this key should
- run. For example, the `calc-sincos' command is not normally available
- on a key. Typing `Z D s sincos <RET>' programs the `z s' key sequence
- to run `calc-sincos'. This definition will remain in effect for the
- rest of this Emacs session, or until you redefine `z s' to be something
- else.
- You can actually bind any Emacs command to a `z' key sequence by
- backspacing over the `calc-' when you are prompted for the command name.
- As with any other prefix key, you can type `z ?' to see a list of
- all the two-key sequences you have defined that start with `z'.
- Initially, no `z' sequences (except `z ?' itself) are defined.
- User keys are typically letters, but may in fact be any key.
- (<META>-keys are not permitted, nor are a terminal's special function
- keys which generate multi-character sequences when pressed.) You can
- define different commands on the shifted and unshifted versions of a
- letter if you wish.
- The `Z U' (`calc-user-undefine') command unbinds a user key. For
- example, the key sequence `Z U s' will undefine the `sincos' key we
- defined above.
- The `Z P' (`calc-user-define-permanent') command makes a key binding
- permanent so that it will remain in effect even in future Emacs
- sessions. (It does this by adding a suitable bit of Lisp code into
- your Calc init file; that is, the file given by the variable
- `calc-settings-file', typically `~/.emacs.d/calc.el'.) For example, `Z
- P s' would register our `sincos' command permanently. If you later
- wish to unregister this command you must edit your Calc init file by
- hand. (*Note General Mode Commands::, for a way to tell Calc to use a
- different file for the Calc init file.)
- The `Z P' command also saves the user definition, if any, for the
- command bound to the key. After `Z F' and `Z C', a given user key
- could invoke a command, which in turn calls an algebraic function,
- which might have one or more special display formats. A single `Z P'
- command will save all of these definitions. To save an algebraic
- function, type `'' (the apostrophe) when prompted for a key, and type
- the function name. To save a command without its key binding, type
- `M-x' and enter a function name. (The `calc-' prefix will
- automatically be inserted for you.) (If the command you give implies a
- function, the function will be saved, and if the function has any
- display formats, those will be saved, but not the other way around:
- Saving a function will not save any commands or key bindings associated
- with the function.)
- The `Z E' (`calc-user-define-edit') command edits the definition of
- a user key. This works for keys that have been defined by either
- keyboard macros or formulas; further details are contained in the
- relevant following sections.
- File: calc, Node: Keyboard Macros, Next: Invocation Macros, Prev: Creating User Keys, Up: Programming
- 19.2 Programming with Keyboard Macros
- =====================================
- The easiest way to "program" the Emacs Calculator is to use standard
- keyboard macros. Press `C-x (' to begin recording a macro. From this
- point on, keystrokes you type will be saved away as well as performing
- their usual functions. Press `C-x )' to end recording. Press
- shift-`X' (or the standard Emacs key sequence `C-x e') to execute your
- keyboard macro by replaying the recorded keystrokes. *Note Keyboard
- Macros: (emacs)Keyboard Macros, for further information.
- When you use `X' to invoke a keyboard macro, the entire macro is
- treated as a single command by the undo and trail features. The stack
- display buffer is not updated during macro execution, but is instead
- fixed up once the macro completes. Thus, commands defined with keyboard
- macros are convenient and efficient. The `C-x e' command, on the other
- hand, invokes the keyboard macro with no special treatment: Each
- command in the macro will record its own undo information and trail
- entry, and update the stack buffer accordingly. If your macro uses
- features outside of Calc's control to operate on the contents of the
- Calc stack buffer, or if it includes Undo, Redo, or last-arguments
- commands, you must use `C-x e' to make sure the buffer and undo list
- are up-to-date at all times. You could also consider using `K'
- (`calc-keep-args') instead of `M-<RET>' (`calc-last-args').
- Calc extends the standard Emacs keyboard macros in several ways.
- Keyboard macros can be used to create user-defined commands. Keyboard
- macros can include conditional and iteration structures, somewhat
- analogous to those provided by a traditional programmable calculator.
- * Menu:
- * Naming Keyboard Macros::
- * Conditionals in Macros::
- * Loops in Macros::
- * Local Values in Macros::
- * Queries in Macros::
- File: calc, Node: Naming Keyboard Macros, Next: Conditionals in Macros, Prev: Keyboard Macros, Up: Keyboard Macros
- 19.2.1 Naming Keyboard Macros
- -----------------------------
- Once you have defined a keyboard macro, you can bind it to a `z' key
- sequence with the `Z K' (`calc-user-define-kbd-macro') command. This
- command prompts first for a key, then for a command name. For example,
- if you type `C-x ( n <TAB> n <TAB> C-x )' you will define a keyboard
- macro which negates the top two numbers on the stack (<TAB> swaps the
- top two stack elements). Now you can type `Z K n <RET>' to define this
- keyboard macro onto the `z n' key sequence. The default command name
- (if you answer the second prompt with just the <RET> key as in this
- example) will be something like `calc-User-n'. The keyboard macro will
- now be available as both `z n' and `M-x calc-User-n'. You can
- backspace and enter a more descriptive command name if you wish.
- Macros defined by `Z K' act like single commands; they are executed
- in the same way as by the `X' key. If you wish to define the macro as
- a standard no-frills Emacs macro (to be executed as if by `C-x e'),
- give a negative prefix argument to `Z K'.
- Once you have bound your keyboard macro to a key, you can use `Z P'
- to register it permanently with Emacs. *Note Creating User Keys::.
- The `Z E' (`calc-user-define-edit') command on a key that has been
- defined by a keyboard macro tries to use the `edmacro' package edit the
- macro. Type `C-c C-c' to finish editing and update the definition
- stored on the key, or, to cancel the edit, kill the buffer with `C-x k'.
- The special characters `RET', `LFD', `TAB', `SPC', `DEL', and `NUL'
- must be entered as these three character sequences, written in all
- uppercase, as must the prefixes `C-' and `M-'. Spaces and line breaks
- are ignored. Other characters are copied verbatim into the keyboard
- macro. Basically, the notation is the same as is used in all of this
- manual's examples, except that the manual takes some liberties with
- spaces: When we say `' [1 2 3] <RET>', we take it for granted that it
- is clear we really mean `' [1 <SPC> 2 <SPC> 3] <RET>'.
- The `C-x * m' (`read-kbd-macro') command reads an Emacs "region" of
- spelled-out keystrokes and defines it as the current keyboard macro.
- It is a convenient way to define a keyboard macro that has been stored
- in a file, or to define a macro without executing it at the same time.
- File: calc, Node: Conditionals in Macros, Next: Loops in Macros, Prev: Naming Keyboard Macros, Up: Keyboard Macros
- 19.2.2 Conditionals in Keyboard Macros
- --------------------------------------
- The `Z [' (`calc-kbd-if') and `Z ]' (`calc-kbd-end-if') commands allow
- you to put simple tests in a keyboard macro. When Calc sees the `Z [',
- it pops an object from the stack and, if the object is a non-zero
- value, continues executing keystrokes. But if the object is zero, or
- if it is not provably nonzero, Calc skips ahead to the matching `Z ]'
- keystroke. *Note Logical Operations::, for a set of commands for
- performing tests which conveniently produce 1 for true and 0 for false.
- For example, `<RET> 0 a < Z [ n Z ]' implements an absolute-value
- function in the form of a keyboard macro. This macro duplicates the
- number on the top of the stack, pushes zero and compares using `a <'
- (`calc-less-than'), then, if the number was less than zero, executes
- `n' (`calc-change-sign'). Otherwise, the change-sign command is
- skipped.
- To program this macro, type `C-x (', type the above sequence of
- keystrokes, then type `C-x )'. Note that the keystrokes will be
- executed while you are making the definition as well as when you later
- re-execute the macro by typing `X'. Thus you should make sure a
- suitable number is on the stack before defining the macro so that you
- don't get a stack-underflow error during the definition process.
- Conditionals can be nested arbitrarily. However, there should be
- exactly one `Z ]' for each `Z [' in a keyboard macro.
- The `Z :' (`calc-kbd-else') command allows you to choose between two
- keystroke sequences. The general format is `COND Z [ THEN-PART Z :
- ELSE-PART Z ]'. If COND is true (i.e., if the top of stack contains a
- non-zero number after COND has been executed), the THEN-PART will be
- executed and the ELSE-PART will be skipped. Otherwise, the THEN-PART
- will be skipped and the ELSE-PART will be executed.
- The `Z |' (`calc-kbd-else-if') command allows you to choose between
- any number of alternatives. For example, `COND1 Z [ PART1 Z : COND2 Z
- | PART2 Z : PART3 Z ]' will execute PART1 if COND1 is true, otherwise
- it will execute PART2 if COND2 is true, otherwise it will execute PART3.
- More precisely, `Z [' pops a number and conditionally skips to the
- next matching `Z :' or `Z ]' key. `Z ]' has no effect when actually
- executed. `Z :' skips to the next matching `Z ]'. `Z |' pops a number
- and conditionally skips to the next matching `Z :' or `Z ]'; thus, `Z
- [' and `Z |' are functionally equivalent except that `Z [' participates
- in nesting but `Z |' does not.
- Calc's conditional and looping constructs work by scanning the
- keyboard macro for occurrences of character sequences like `Z:' and
- `Z]'. One side-effect of this is that if you use these constructs you
- must be careful that these character pairs do not occur by accident in
- other parts of the macros. Since Calc rarely uses shift-`Z' for any
- purpose except as a prefix character, this is not likely to be a
- problem. Another side-effect is that it will not work to define your
- own custom key bindings for these commands. Only the standard
- shift-`Z' bindings will work correctly.
- If Calc gets stuck while skipping characters during the definition
- of a macro, type `Z C-g' to cancel the definition. (Typing plain `C-g'
- actually adds a `C-g' keystroke to the macro.)
- File: calc, Node: Loops in Macros, Next: Local Values in Macros, Prev: Conditionals in Macros, Up: Keyboard Macros
- 19.2.3 Loops in Keyboard Macros
- -------------------------------
- The `Z <' (`calc-kbd-repeat') and `Z >' (`calc-kbd-end-repeat')
- commands pop a number from the stack, which must be an integer, then
- repeat the keystrokes between the brackets the specified number of
- times. If the integer is zero or negative, the body is skipped
- altogether. For example, `1 <TAB> Z < 2 * Z >' computes two to a
- nonnegative integer power. First, we push 1 on the stack and then swap
- the integer argument back to the top. The `Z <' pops that argument
- leaving the 1 back on top of the stack. Then, we repeat a
- multiply-by-two step however many times.
- Once again, the keyboard macro is executed as it is being entered.
- In this case it is especially important to set up reasonable initial
- conditions before making the definition: Suppose the integer 1000 just
- happened to be sitting on the stack before we typed the above
- definition! Another approach is to enter a harmless dummy definition
- for the macro, then go back and edit in the real one with a `Z E'
- command. Yet another approach is to type the macro as written-out
- keystroke names in a buffer, then use `C-x * m' (`read-kbd-macro') to
- read the macro.
- The `Z /' (`calc-kbd-break') command allows you to break out of a
- keyboard macro loop prematurely. It pops an object from the stack; if
- that object is true (a non-zero number), control jumps out of the
- innermost enclosing `Z <' ... `Z >' loop and continues after the `Z >'.
- If the object is false, the `Z /' has no effect. Thus `COND Z /' is
- similar to `if (COND) break;' in the C language.
- The `Z (' (`calc-kbd-for') and `Z )' (`calc-kbd-end-for') commands
- are similar to `Z <' and `Z >', except that they make the value of the
- counter available inside the loop. The general layout is `INIT FINAL Z
- ( BODY STEP Z )'. The `Z (' command pops initial and final values from
- the stack. It then creates a temporary internal counter and
- initializes it with the value INIT. The `Z (' command then repeatedly
- pushes the counter value onto the stack and executes BODY and STEP,
- adding STEP to the counter each time until the loop finishes.
- By default, the loop finishes when the counter becomes greater than
- (or less than) FINAL, assuming INITIAL is less than (greater than)
- FINAL. If INITIAL is equal to FINAL, the body executes exactly once.
- The body of the loop always executes at least once. For example, `0 1
- 10 Z ( 2 ^ + 1 Z )' computes the sum of the squares of the integers
- from 1 to 10, in steps of 1.
- If you give a numeric prefix argument of 1 to `Z (', the loop is
- forced to use upward-counting conventions. In this case, if INITIAL is
- greater than FINAL the body will not be executed at all. Note that
- STEP may still be negative in this loop; the prefix argument merely
- constrains the loop-finished test. Likewise, a prefix argument of -1
- forces downward-counting conventions.
- The `Z {' (`calc-kbd-loop') and `Z }' (`calc-kbd-end-loop') commands
- are similar to `Z <' and `Z >', except that they do not pop a count
- from the stack--they effectively create an infinite loop. Every `Z {'
- ... `Z }' loop ought to include at least one `Z /' to make sure the loop
- doesn't run forever. (If any error message occurs which causes Emacs
- to beep, the keyboard macro will also be halted; this is a standard
- feature of Emacs. You can also generally press `C-g' to halt a running
- keyboard macro, although not all versions of Unix support this feature.)
- The conditional and looping constructs are not actually tied to
- keyboard macros, but they are most often used in that context. For
- example, the keystrokes `10 Z < 23 <RET> Z >' push ten copies of 23
- onto the stack. This can be typed "live" just as easily as in a macro
- definition.
- *Note Conditionals in Macros::, for some additional notes about
- conditional and looping commands.
- File: calc, Node: Local Values in Macros, Next: Queries in Macros, Prev: Loops in Macros, Up: Keyboard Macros
- 19.2.4 Local Values in Macros
- -----------------------------
- Keyboard macros sometimes want to operate under known conditions
- without affecting surrounding conditions. For example, a keyboard
- macro may wish to turn on Fraction mode, or set a particular precision,
- independent of the user's normal setting for those modes.
- Macros also sometimes need to use local variables. Assignments to
- local variables inside the macro should not affect any variables
- outside the macro. The `Z `' (`calc-kbd-push') and `Z ''
- (`calc-kbd-pop') commands give you both of these capabilities.
- When you type `Z `' (with a backquote or accent grave character),
- the values of various mode settings are saved away. The ten "quick"
- variables `q0' through `q9' are also saved. When you type `Z '' (with
- an apostrophe), these values are restored. Pairs of `Z `' and `Z ''
- commands may be nested.
- If a keyboard macro halts due to an error in between a `Z `' and a
- `Z '', the saved values will be restored correctly even though the
- macro never reaches the `Z '' command. Thus you can use `Z `' and `Z
- '' without having to worry about what happens in exceptional conditions.
- If you type `Z `' "live" (not in a keyboard macro), Calc puts you
- into a "recursive edit." You can tell you are in a recursive edit
- because there will be extra square brackets in the mode line, as in
- `[(Calculator)]'. These brackets will go away when you type the
- matching `Z '' command. The modes and quick variables will be saved
- and restored in just the same way as if actual keyboard macros were
- involved.
- The modes saved by `Z `' and `Z '' are the current precision and
- binary word size, the angular mode (Deg, Rad, or HMS), the
- simplification mode, Algebraic mode, Symbolic mode, Infinite mode,
- Matrix or Scalar mode, Fraction mode, and the current complex mode
- (Polar or Rectangular). The ten "quick" variables' values (or lack
- thereof) are also saved.
- Most mode-setting commands act as toggles, but with a numeric prefix
- they force the mode either on (positive prefix) or off (negative or
- zero prefix). Since you don't know what the environment might be when
- you invoke your macro, it's best to use prefix arguments for all
- mode-setting commands inside the macro.
- In fact, `C-u Z `' is like `Z `' except that it sets the modes
- listed above to their default values. As usual, the matching `Z ''
- will restore the modes to their settings from before the `C-u Z `'.
- Also, `Z `' with a negative prefix argument resets the algebraic mode
- to its default (off) but leaves the other modes the same as they were
- outside the construct.
- The contents of the stack and trail, values of non-quick variables,
- and other settings such as the language mode and the various display
- modes, are _not_ affected by `Z `' and `Z ''.
- File: calc, Node: Queries in Macros, Prev: Local Values in Macros, Up: Keyboard Macros
- 19.2.5 Queries in Keyboard Macros
- ---------------------------------
- The `Z #' (`calc-kbd-query') command prompts for an algebraic entry
- which takes its input from the keyboard, even during macro execution.
- All the normal conventions of algebraic input, including the use of `$'
- characters, are supported. The prompt message itself is taken from the
- top of the stack, and so must be entered (as a string) before the `Z #'
- command. (Recall, as a string it can be entered by pressing the `"'
- key and will appear as a vector when it is put on the stack. The
- prompt message is only put on the stack to provide a prompt for the `Z
- #' command; it will not play any role in any subsequent calculations.)
- This command allows your keyboard macros to accept numbers or formulas
- as interactive input.
- As an example, `2 <RET> "Power: " <RET> Z # 3 <RET> ^' will prompt
- for input with "Power: " in the minibuffer, then return 2 to the
- provided power. (The response to the prompt that's given, 3 in this
- example, will not be part of the macro.)
- *Note Keyboard Macro Query: (emacs)Keyboard Macro Query, for a
- description of `C-x q' (`kbd-macro-query'), the standard Emacs way to
- accept keyboard input during a keyboard macro. In particular, you can
- use `C-x q' to enter a recursive edit, which allows the user to perform
- any Calculator operations interactively before pressing `C-M-c' to
- return control to the keyboard macro.
- File: calc, Node: Invocation Macros, Next: Algebraic Definitions, Prev: Keyboard Macros, Up: Programming
- 19.3 Invocation Macros
- ======================
- Calc provides one special keyboard macro, called up by `C-x * z'
- (`calc-user-invocation'), that is intended to allow you to define your
- own special way of starting Calc. To define this "invocation macro,"
- create the macro in the usual way with `C-x (' and `C-x )', then type
- `Z I' (`calc-user-define-invocation'). There is only one invocation
- macro, so you don't need to type any additional letters after `Z I'.
- From now on, you can type `C-x * z' at any time to execute your
- invocation macro.
- For example, suppose you find yourself often grabbing rectangles of
- numbers into Calc and multiplying their columns. You can do this by
- typing `C-x * r' to grab, and `V R : *' to multiply columns. To make
- this into an invocation macro, just type `C-x ( C-x * r V R : * C-x )',
- then `Z I'. Then, to multiply a rectangle of data, just mark the data
- in its buffer in the usual way and type `C-x * z'.
- Invocation macros are treated like regular Emacs keyboard macros;
- all the special features described above for `Z K'-style macros do not
- apply. `C-x * z' is just like `C-x e', except that it uses the macro
- that was last stored by `Z I'. (In fact, the macro does not even have
- to have anything to do with Calc!)
- The `m m' command saves the last invocation macro defined by `Z I'
- along with all the other Calc mode settings. *Note General Mode
- Commands::.
- File: calc, Node: Algebraic Definitions, Next: Lisp Definitions, Prev: Invocation Macros, Up: Programming
- 19.4 Programming with Formulas
- ==============================
- Another way to create a new Calculator command uses algebraic formulas.
- The `Z F' (`calc-user-define-formula') command stores the formula at
- the top of the stack as the definition for a key. This command prompts
- for five things: The key, the command name, the function name, the
- argument list, and the behavior of the command when given non-numeric
- arguments.
- For example, suppose we type `' a+2b <RET>' to push the formula `a +
- 2*b' onto the stack. We now type `Z F m' to define this formula on the
- `z m' key sequence. The next prompt is for a command name, beginning
- with `calc-', which should be the long (`M-x') form for the new
- command. If you simply press <RET>, a default name like `calc-User-m'
- will be constructed. In our example, suppose we enter `spam <RET>' to
- define the new command as `calc-spam'.
- If you want to give the formula a long-style name only, you can press
- <SPC> or <RET> when asked which single key to use. For example `Z F
- <RET> spam <RET>' defines the new command as `M-x calc-spam', with no
- keyboard equivalent.
- The third prompt is for an algebraic function name. The default is
- to use the same name as the command name but without the `calc-'
- prefix. (If this is of the form `User-m', the hyphen is removed so it
- won't be taken for a minus sign in algebraic formulas.) This is the
- name you will use if you want to enter your new function in an
- algebraic formula. Suppose we enter `yow <RET>'. Then the new
- function can be invoked by pushing two numbers on the stack and typing
- `z m' or `x spam', or by entering the algebraic formula `yow(x,y)'.
- The fourth prompt is for the function's argument list. This is used
- to associate values on the stack with the variables that appear in the
- formula. The default is a list of all variables which appear in the
- formula, sorted into alphabetical order. In our case, the default
- would be `(a b)'. This means that, when the user types `z m', the
- Calculator will remove two numbers from the stack, substitute these
- numbers for `a' and `b' (respectively) in the formula, then simplify
- the formula and push the result on the stack. In other words, `10
- <RET> 100 z m' would replace the 10 and 100 on the stack with the
- number 210, which is `a + 2 b' with `a=10' and `b=100'. Likewise, the
- formula `yow(10, 100)' will be evaluated by substituting `a=10' and
- `b=100' in the definition.
- You can rearrange the order of the names before pressing <RET> to
- control which stack positions go to which variables in the formula. If
- you remove a variable from the argument list, that variable will be left
- in symbolic form by the command. Thus using an argument list of `(b)'
- for our function would cause `10 z m' to replace the 10 on the stack
- with the formula `a + 20'. If we had used an argument list of `(b a)',
- the result with inputs 10 and 100 would have been 120.
- You can also put a nameless function on the stack instead of just a
- formula, as in `<a, b : a + 2 b>'. *Note Specifying Operators::. In
- this example, the command will be defined by the formula `a + 2 b'
- using the argument list `(a b)'.
- The final prompt is a y-or-n question concerning what to do if
- symbolic arguments are given to your function. If you answer `y', then
- executing `z m' (using the original argument list `(a b)') with
- arguments `10' and `x' will leave the function in symbolic form, i.e.,
- `yow(10,x)'. On the other hand, if you answer `n', then the formula
- will always be expanded, even for non-constant arguments: `10 + 2 x'.
- If you never plan to feed algebraic formulas to your new function, it
- doesn't matter how you answer this question.
- If you answered `y' to this question you can still cause a function
- call to be expanded by typing `a "' (`calc-expand-formula'). Also,
- Calc will expand the function if necessary when you take a derivative
- or integral or solve an equation involving the function.
- Once you have defined a formula on a key, you can retrieve this
- formula with the `Z G' (`calc-user-define-get-defn') command. Press a
- key, and this command pushes the formula that was used to define that
- key onto the stack. Actually, it pushes a nameless function that
- specifies both the argument list and the defining formula. You will get
- an error message if the key is undefined, or if the key was not defined
- by a `Z F' command.
- The `Z E' (`calc-user-define-edit') command on a key that has been
- defined by a formula uses a variant of the `calc-edit' command to edit
- the defining formula. Press `C-c C-c' to finish editing and store the
- new formula back in the definition, or kill the buffer with `C-x k' to
- cancel the edit. (The argument list and other properties of the
- definition are unchanged; to adjust the argument list, you can use `Z
- G' to grab the function onto the stack, edit with ``', and then
- re-execute the `Z F' command.)
- As usual, the `Z P' command records your definition permanently. In
- this case it will permanently record all three of the relevant
- definitions: the key, the command, and the function.
- You may find it useful to turn off the default simplifications with
- `m O' (`calc-no-simplify-mode') when entering a formula to be used as a
- function definition. For example, the formula `deriv(a^2,v)' which
- might be used to define a new function `dsqr(a,v)' will be "simplified"
- to 0 immediately upon entry since `deriv' considers `a' to be constant
- with respect to `v'. Turning off default simplifications cures this
- problem: The definition will be stored in symbolic form without ever
- activating the `deriv' function. Press `m D' to turn the default
- simplifications back on afterwards.
- File: calc, Node: Lisp Definitions, Prev: Algebraic Definitions, Up: Programming
- 19.5 Programming with Lisp
- ==========================
- The Calculator can be programmed quite extensively in Lisp. All you do
- is write a normal Lisp function definition, but with `defmath' in place
- of `defun'. This has the same form as `defun', but it automagically
- replaces calls to standard Lisp functions like `+' and `zerop' with
- calls to the corresponding functions in Calc's own library. Thus you
- can write natural-looking Lisp code which operates on all of the
- standard Calculator data types. You can then use `Z D' if you wish to
- bind your new command to a `z'-prefix key sequence. The `Z E' command
- will not edit a Lisp-based definition.
- Emacs Lisp is described in the GNU Emacs Lisp Reference Manual.
- This section assumes a familiarity with Lisp programming concepts; if
- you do not know Lisp, you may find keyboard macros or rewrite rules to
- be an easier way to program the Calculator.
- This section first discusses ways to write commands, functions, or
- small programs to be executed inside of Calc. Then it discusses how
- your own separate programs are able to call Calc from the outside.
- Finally, there is a list of internal Calc functions and data structures
- for the true Lisp enthusiast.
- * Menu:
- * Defining Functions::
- * Defining Simple Commands::
- * Defining Stack Commands::
- * Argument Qualifiers::
- * Example Definitions::
- * Calling Calc from Your Programs::
- * Internals::
- File: calc, Node: Defining Functions, Next: Defining Simple Commands, Prev: Lisp Definitions, Up: Lisp Definitions
- 19.5.1 Defining New Functions
- -----------------------------
- The `defmath' function (actually a Lisp macro) is like `defun' except
- that code in the body of the definition can make use of the full range
- of Calculator data types. The prefix `calcFunc-' is added to the
- specified name to get the actual Lisp function name. As a simple
- example,
- (defmath myfact (n)
- (if (> n 0)
- (* n (myfact (1- n)))
- 1))
- This actually expands to the code,
- (defun calcFunc-myfact (n)
- (if (math-posp n)
- (math-mul n (calcFunc-myfact (math-add n -1)))
- 1))
- This function can be used in algebraic expressions, e.g., `myfact(5)'.
- The `myfact' function as it is defined above has the bug that an
- expression `myfact(a+b)' will be simplified to 1 because the formula
- `a+b' is not considered to be `posp'. A robust factorial function
- would be written along the following lines:
- (defmath myfact (n)
- (if (> n 0)
- (* n (myfact (1- n)))
- (if (= n 0)
- 1
- nil))) ; this could be simplified as: (and (= n 0) 1)
- If a function returns `nil', it is left unsimplified by the
- Calculator (except that its arguments will be simplified). Thus,
- `myfact(a+1+2)' will be simplified to `myfact(a+3)' but no further.
- Beware that every time the Calculator reexamines this formula it will
- attempt to resimplify it, so your function ought to detect the
- returning-`nil' case as efficiently as possible.
- The following standard Lisp functions are treated by `defmath': `+',
- `-', `*', `/', `%', `^' or `expt', `=', `<', `>', `<=', `>=', `/=',
- `1+', `1-', `logand', `logior', `logxor', `logandc2', `lognot'. Also,
- `~=' is an abbreviation for `math-nearly-equal', which is useful in
- implementing Taylor series.
- For other functions FUNC, if a function by the name `calcFunc-FUNC'
- exists it is used, otherwise if a function by the name `math-FUNC'
- exists it is used, otherwise if FUNC itself is defined as a function it
- is used, otherwise `calcFunc-FUNC' is used on the assumption that this
- is a to-be-defined math function. Also, if the function name is quoted
- as in `('integerp a)' the function name is always used exactly as
- written (but not quoted).
- Variable names have `var-' prepended to them unless they appear in
- the function's argument list or in an enclosing `let', `let*', `for',
- or `foreach' form, or their names already contain a `-' character.
- Thus a reference to `foo' is the same as a reference to `var-foo'.
- A few other Lisp extensions are available in `defmath' definitions:
- * The `elt' function accepts any number of index variables. Note
- that Calc vectors are stored as Lisp lists whose first element is
- the symbol `vec'; thus, `(elt v 2)' yields the second element of
- vector `v', and `(elt m i j)' yields one element of a Calc matrix.
- * The `setq' function has been extended to act like the Common Lisp
- `setf' function. (The name `setf' is recognized as a synonym of
- `setq'.) Specifically, the first argument of `setq' can be an
- `nth', `elt', `car', or `cdr' form, in which case the effect is to
- store into the specified element of a list. Thus, `(setq (elt m i
- j) x)' stores `x' into one element of a matrix.
- * A `for' looping construct is available. For example, `(for ((i 0
- 10)) body)' executes `body' once for each binding of `i' from zero
- to 10. This is like a `let' form in that `i' is temporarily bound
- to the loop count without disturbing its value outside the `for'
- construct. Nested loops, as in `(for ((i 0 10) (j 0 (1- i) 2))
- body)', are also available. For each value of `i' from zero to 10,
- `j' counts from 0 to `i-1' in steps of two. Note that `for' has
- the same general outline as `let*', except that each element of
- the header is a list of three or four things, not just two.
- * The `foreach' construct loops over elements of a list. For
- example, `(foreach ((x (cdr v))) body)' executes `body' with `x'
- bound to each element of Calc vector `v' in turn. The purpose of
- `cdr' here is to skip over the initial `vec' symbol in the vector.
- * The `break' function breaks out of the innermost enclosing
- `while', `for', or `foreach' loop. If given a value, as in
- `(break x)', this value is returned by the loop. (Lisp loops
- otherwise always return `nil'.)
- * The `return' function prematurely returns from the enclosing
- function. For example, `(return (+ x y))' returns `x+y' as the
- value of a function. You can use `return' anywhere inside the
- body of the function.
- Non-integer numbers (and extremely large integers) cannot be included
- directly into a `defmath' definition. This is because the Lisp reader
- will fail to parse them long before `defmath' ever gets control.
- Instead, use the notation, `:"3.1415"'. In fact, any algebraic formula
- can go between the quotes. For example,
- (defmath sqexp (x) ; sqexp(x) == sqrt(exp(x)) == exp(x*0.5)
- (and (numberp x)
- (exp :"x * 0.5")))
- expands to
- (defun calcFunc-sqexp (x)
- (and (math-numberp x)
- (calcFunc-exp (math-mul x '(float 5 -1)))))
- Note the use of `numberp' as a guard to ensure that the argument is
- a number first, returning `nil' if not. The exponential function could
- itself have been included in the expression, if we had preferred:
- `:"exp(x * 0.5)"'. As another example, the multiplication-and-recursion
- step of `myfact' could have been written
- :"n * myfact(n-1)"
- A good place to put your `defmath' commands is your Calc init file
- (the file given by `calc-settings-file', typically
- `~/.emacs.d/calc.el'), which will not be loaded until Calc starts. If
- a file named `.emacs' exists in your home directory, Emacs reads and
- executes the Lisp forms in this file as it starts up. While it may
- seem reasonable to put your favorite `defmath' commands there, this has
- the unfortunate side-effect that parts of the Calculator must be loaded
- in to process the `defmath' commands whether or not you will actually
- use the Calculator! If you want to put the `defmath' commands there
- (for example, if you redefine `calc-settings-file' to be `.emacs'), a
- better effect can be had by writing
- (put 'calc-define 'thing '(progn
- (defmath ... )
- (defmath ... )
- ))
- The `put' function adds a "property" to a symbol. Each Lisp symbol has
- a list of properties associated with it. Here we add a property with a
- name of `thing' and a `(progn ...)' form as its value. When Calc
- starts up, and at the start of every Calc command, the property list
- for the symbol `calc-define' is checked and the values of any
- properties found are evaluated as Lisp forms. The properties are
- removed as they are evaluated. The property names (like `thing') are
- not used; you should choose something like the name of your project so
- as not to conflict with other properties.
- The net effect is that you can put the above code in your `.emacs'
- file and it will not be executed until Calc is loaded. Or, you can put
- that same code in another file which you load by hand either before or
- after Calc itself is loaded.
- The properties of `calc-define' are evaluated in the same order that
- they were added. They can assume that the Calc modules `calc.el',
- `calc-ext.el', and `calc-macs.el' have been fully loaded, and that the
- `*Calculator*' buffer will be the current buffer.
- If your `calc-define' property only defines algebraic functions, you
- can be sure that it will have been evaluated before Calc tries to call
- your function, even if the file defining the property is loaded after
- Calc is loaded. But if the property defines commands or key sequences,
- it may not be evaluated soon enough. (Suppose it defines the new
- command `tweak-calc'; the user can load your file, then type `M-x
- tweak-calc' before Calc has had chance to do anything.) To protect
- against this situation, you can put
- (run-hooks 'calc-check-defines)
- at the end of your file. The `calc-check-defines' function is what
- looks for and evaluates properties on `calc-define'; `run-hooks' has
- the advantage that it is quietly ignored if `calc-check-defines' is not
- yet defined because Calc has not yet been loaded.
- Examples of things that ought to be enclosed in a `calc-define'
- property are `defmath' calls, `define-key' calls that modify the Calc
- key map, and any calls that redefine things defined inside Calc.
- Ordinary `defun's need not be enclosed with `calc-define'.
- File: calc, Node: Defining Simple Commands, Next: Defining Stack Commands, Prev: Defining Functions, Up: Lisp Definitions
- 19.5.2 Defining New Simple Commands
- -----------------------------------
- If a `defmath' form contains an `interactive' clause, it defines a
- Calculator command. Actually such a `defmath' results in _two_
- function definitions: One, a `calcFunc-' function as was just
- described, with the `interactive' clause removed. Two, a `calc-'
- function with a suitable `interactive' clause and some sort of wrapper
- to make the command work in the Calc environment.
- In the simple case, the `interactive' clause has the same form as
- for normal Emacs Lisp commands:
- (defmath increase-precision (delta)
- "Increase precision by DELTA." ; This is the "documentation string"
- (interactive "p") ; Register this as a M-x-able command
- (setq calc-internal-prec (+ calc-internal-prec delta)))
- This expands to the pair of definitions,
- (defun calc-increase-precision (delta)
- "Increase precision by DELTA."
- (interactive "p")
- (calc-wrapper
- (setq calc-internal-prec (math-add calc-internal-prec delta))))
- (defun calcFunc-increase-precision (delta)
- "Increase precision by DELTA."
- (setq calc-internal-prec (math-add calc-internal-prec delta)))
- where in this case the latter function would never really be used! Note
- that since the Calculator stores small integers as plain Lisp integers,
- the `math-add' function will work just as well as the native `+' even
- when the intent is to operate on native Lisp integers.
- The `calc-wrapper' call invokes a macro which surrounds the body of
- the function with code that looks roughly like this:
- (let ((calc-command-flags nil))
- (unwind-protect
- (save-current-buffer
- (calc-select-buffer)
- _body of function_
- _renumber stack_
- _clear_ Working _message_)
- _realign cursor and window_
- _clear Inverse, Hyperbolic, and Keep Args flags_
- _update Emacs mode line_))
- The `calc-select-buffer' function selects the `*Calculator*' buffer
- if necessary, say, because the command was invoked from inside the
- `*Calc Trail*' window.
- You can call, for example, `(calc-set-command-flag 'no-align)' to
- set the above-mentioned command flags. Calc routines recognize the
- following command flags:
- `renum-stack'
- Stack line numbers `1:', `2:', and so on must be renumbered after
- this command completes. This is set by routines like `calc-push'.
- `clear-message'
- Calc should call `(message "")' if this command completes normally
- (to clear a "Working..." message out of the echo area).
- `no-align'
- Do not move the cursor back to the `.' top-of-stack marker.
- `position-point'
- Use the variables `calc-position-point-line' and
- `calc-position-point-column' to position the cursor after this
- command finishes.
- `keep-flags'
- Do not clear `calc-inverse-flag', `calc-hyperbolic-flag', and
- `calc-keep-args-flag' at the end of this command.
- `do-edit'
- Switch to buffer `*Calc Edit*' after this command.
- `hold-trail'
- Do not move trail pointer to end of trail when something is
- recorded there.
- Calc reserves a special prefix key, shift-`Y', for user-written
- extensions to Calc. There are no built-in commands that work with this
- prefix key; you must call `define-key' from Lisp (probably from inside
- a `calc-define' property) to add to it. Initially only `Y ?' is
- defined; it takes help messages from a list of strings (initially
- `nil') in the variable `calc-Y-help-msgs'. All other undefined keys
- except for `Y' are reserved for use by future versions of Calc.
- If you are writing a Calc enhancement which you expect to give to
- others, it is best to minimize the number of `Y'-key sequences you use.
- In fact, if you have more than one key sequence you should consider
- defining three-key sequences with a `Y', then a key that stands for
- your package, then a third key for the particular command within your
- package.
- Users may wish to install several Calc enhancements, and it is
- possible that several enhancements will choose to use the same key. In
- the example below, a variable `inc-prec-base-key' has been defined to
- contain the key that identifies the `inc-prec' package. Its value is
- initially `"P"', but a user can change this variable if necessary
- without having to modify the file.
- Here is a complete file, `inc-prec.el', which makes a `Y P I'
- command that increases the precision, and a `Y P D' command that
- decreases the precision.
- ;;; Increase and decrease Calc precision. Dave Gillespie, 5/31/91.
- ;; (Include copyright or copyleft stuff here.)
- (defvar inc-prec-base-key "P"
- "Base key for inc-prec.el commands.")
- (put 'calc-define 'inc-prec '(progn
- (define-key calc-mode-map (format "Y%sI" inc-prec-base-key)
- 'increase-precision)
- (define-key calc-mode-map (format "Y%sD" inc-prec-base-key)
- 'decrease-precision)
- (setq calc-Y-help-msgs
- (cons (format "%s + Inc-prec, Dec-prec" inc-prec-base-key)
- calc-Y-help-msgs))
- (defmath increase-precision (delta)
- "Increase precision by DELTA."
- (interactive "p")
- (setq calc-internal-prec (+ calc-internal-prec delta)))
- (defmath decrease-precision (delta)
- "Decrease precision by DELTA."
- (interactive "p")
- (setq calc-internal-prec (- calc-internal-prec delta)))
- )) ; end of calc-define property
- (run-hooks 'calc-check-defines)
- File: calc, Node: Defining Stack Commands, Next: Argument Qualifiers, Prev: Defining Simple Commands, Up: Lisp Definitions
- 19.5.3 Defining New Stack-Based Commands
- ----------------------------------------
- To define a new computational command which takes and/or leaves
- arguments on the stack, a special form of `interactive' clause is used.
- (interactive NUM TAG)
- where NUM is an integer, and TAG is a string. The effect is to pop NUM
- values off the stack, resimplify them by calling `calc-normalize', and
- hand them to your function according to the function's argument list.
- Your function may include `&optional' and `&rest' parameters, so long
- as calling the function with NUM parameters is valid.
- Your function must return either a number or a formula in a form
- acceptable to Calc, or a list of such numbers or formulas. These
- value(s) are pushed onto the stack when the function completes. They
- are also recorded in the Calc Trail buffer on a line beginning with TAG,
- a string of (normally) four characters or less. If you omit TAG or use
- `nil' as a tag, the result is not recorded in the trail.
- As an example, the definition
- (defmath myfact (n)
- "Compute the factorial of the integer at the top of the stack."
- (interactive 1 "fact")
- (if (> n 0)
- (* n (myfact (1- n)))
- (and (= n 0) 1)))
- is a version of the factorial function shown previously which can be
- used as a command as well as an algebraic function. It expands to
- (defun calc-myfact ()
- "Compute the factorial of the integer at the top of the stack."
- (interactive)
- (calc-slow-wrapper
- (calc-enter-result 1 "fact"
- (cons 'calcFunc-myfact (calc-top-list-n 1)))))
- (defun calcFunc-myfact (n)
- "Compute the factorial of the integer at the top of the stack."
- (if (math-posp n)
- (math-mul n (calcFunc-myfact (math-add n -1)))
- (and (math-zerop n) 1)))
- The `calc-slow-wrapper' function is a version of `calc-wrapper' that
- automatically puts up a `Working...' message before the computation
- begins. (This message can be turned off by the user with an `m w'
- (`calc-working') command.)
- The `calc-top-list-n' function returns a list of the specified number
- of values from the top of the stack. It resimplifies each value by
- calling `calc-normalize'. If its argument is zero it returns an empty
- list. It does not actually remove these values from the stack.
- The `calc-enter-result' function takes an integer NUM and string TAG
- as described above, plus a third argument which is either a Calculator
- data object or a list of such objects. These objects are resimplified
- and pushed onto the stack after popping the specified number of values
- from the stack. If TAG is non-`nil', the values being pushed are also
- recorded in the trail.
- Note that if `calcFunc-myfact' returns `nil' this represents "leave
- the function in symbolic form." To return an actual empty list, in the
- sense that `calc-enter-result' will push zero elements back onto the
- stack, you should return the special value `'(nil)', a list containing
- the single symbol `nil'.
- The `interactive' declaration can actually contain a limited
- Emacs-style code string as well which comes just before NUM and TAG.
- Currently the only Emacs code supported is `"p"', as in
- (defmath foo (a b &optional c)
- (interactive "p" 2 "foo")
- BODY)
- In this example, the command `calc-foo' will evaluate the expression
- `foo(a,b)' if executed with no argument, or `foo(a,b,n)' if executed
- with a numeric prefix argument of `n'.
- The other code string allowed is `"m"' (unrelated to the usual `"m"'
- code as used with `defun'). It uses the numeric prefix argument as the
- number of objects to remove from the stack and pass to the function.
- In this case, the integer NUM serves as a default number of arguments
- to be used when no prefix is supplied.
- File: calc, Node: Argument Qualifiers, Next: Example Definitions, Prev: Defining Stack Commands, Up: Lisp Definitions
- 19.5.4 Argument Qualifiers
- --------------------------
- Anywhere a parameter name can appear in the parameter list you can also
- use an "argument qualifier". Thus the general form of a definition is:
- (defmath NAME (PARAM PARAM...
- &optional PARAM PARAM...
- &rest PARAM)
- BODY)
- where each PARAM is either a symbol or a list of the form
- (QUAL PARAM)
- The following qualifiers are recognized:
- `complete'
- The argument must not be an incomplete vector, interval, or
- complex number. (This is rarely needed since the Calculator
- itself will never call your function with an incomplete argument.
- But there is nothing stopping your own Lisp code from calling your
- function with an incomplete argument.)
- `integer'
- The argument must be an integer. If it is an integer-valued float
- it will be accepted but converted to integer form. Non-integers
- and formulas are rejected.
- `natnum'
- Like `integer', but the argument must be non-negative.
- `fixnum'
- Like `integer', but the argument must fit into a native Lisp
- integer, which on most systems means less than 2^23 in absolute
- value. The argument is converted into Lisp-integer form if
- necessary.
- `float'
- The argument is converted to floating-point format if it is a
- number or vector. If it is a formula it is left alone. (The
- argument is never actually rejected by this qualifier.)
- `PRED'
- The argument must satisfy predicate PRED, which is one of the
- standard Calculator predicates. *Note Predicates::.
- `not-PRED'
- The argument must _not_ satisfy predicate PRED.
- For example,
- (defmath foo (a (constp (not-matrixp b)) &optional (float c)
- &rest (integer d))
- BODY)
- expands to
- (defun calcFunc-foo (a b &optional c &rest d)
- (and (math-matrixp b)
- (math-reject-arg b 'not-matrixp))
- (or (math-constp b)
- (math-reject-arg b 'constp))
- (and c (setq c (math-check-float c)))
- (setq d (mapcar 'math-check-integer d))
- BODY)
- which performs the necessary checks and conversions before executing the
- body of the function.
- File: calc, Node: Example Definitions, Next: Calling Calc from Your Programs, Prev: Argument Qualifiers, Up: Lisp Definitions
- 19.5.5 Example Definitions
- --------------------------
- This section includes some Lisp programming examples on a larger scale.
- These programs make use of some of the Calculator's internal functions;
- *note Internals::.
- * Menu:
- * Bit Counting Example::
- * Sine Example::
- File: calc, Node: Bit Counting Example, Next: Sine Example, Prev: Example Definitions, Up: Example Definitions
- 19.5.5.1 Bit-Counting
- .....................
- Calc does not include a built-in function for counting the number of
- "one" bits in a binary integer. It's easy to invent one using `b u' to
- convert the integer to a set, and `V #' to count the elements of that
- set; let's write a function that counts the bits without having to
- create an intermediate set.
- (defmath bcount ((natnum n))
- (interactive 1 "bcnt")
- (let ((count 0))
- (while (> n 0)
- (if (oddp n)
- (setq count (1+ count)))
- (setq n (lsh n -1)))
- count))
- When this is expanded by `defmath', it will become the following Emacs
- Lisp function:
- (defun calcFunc-bcount (n)
- (setq n (math-check-natnum n))
- (let ((count 0))
- (while (math-posp n)
- (if (math-oddp n)
- (setq count (math-add count 1)))
- (setq n (calcFunc-lsh n -1)))
- count))
- If the input numbers are large, this function involves a fair amount
- of arithmetic. A binary right shift is essentially a division by two;
- recall that Calc stores integers in decimal form so bit shifts must
- involve actual division.
- To gain a bit more efficiency, we could divide the integer into
- N-bit chunks, each of which can be handled quickly because they fit
- into Lisp integers. It turns out that Calc's arithmetic routines are
- especially fast when dividing by an integer less than 1000, so we can
- set N = 9 bits and use repeated division by 512:
- (defmath bcount ((natnum n))
- (interactive 1 "bcnt")
- (let ((count 0))
- (while (not (fixnump n))
- (let ((qr (idivmod n 512)))
- (setq count (+ count (bcount-fixnum (cdr qr)))
- n (car qr))))
- (+ count (bcount-fixnum n))))
- (defun bcount-fixnum (n)
- (let ((count 0))
- (while (> n 0)
- (setq count (+ count (logand n 1))
- n (lsh n -1)))
- count))
- Note that the second function uses `defun', not `defmath'. Because
- this function deals only with native Lisp integers ("fixnums"), it can
- use the actual Emacs `+' and related functions rather than the slower
- but more general Calc equivalents which `defmath' uses.
- The `idivmod' function does an integer division, returning both the
- quotient and the remainder at once. Again, note that while it might
- seem that `(logand n 511)' and `(lsh n -9)' are more efficient ways to
- split off the bottom nine bits of `n', actually they are less efficient
- because each operation is really a division by 512 in disguise;
- `idivmod' allows us to do the same thing with a single division by 512.
- File: calc, Node: Sine Example, Prev: Bit Counting Example, Up: Example Definitions
- 19.5.5.2 The Sine Function
- ..........................
- A somewhat limited sine function could be defined as follows, using the
- well-known Taylor series expansion for `sin(x)':
- (defmath mysin ((float (anglep x)))
- (interactive 1 "mysn")
- (setq x (to-radians x)) ; Convert from current angular mode.
- (let ((sum x) ; Initial term of Taylor expansion of sin.
- newsum
- (nfact 1) ; "nfact" equals "n" factorial at all times.
- (xnegsqr :"-(x^2)")) ; "xnegsqr" equals -x^2.
- (for ((n 3 100 2)) ; Upper limit of 100 is a good precaution.
- (working "mysin" sum) ; Display "Working" message, if enabled.
- (setq nfact (* nfact (1- n) n)
- x (* x xnegsqr)
- newsum (+ sum (/ x nfact)))
- (if (~= newsum sum) ; If newsum is "nearly equal to" sum,
- (break)) ; then we are done.
- (setq sum newsum))
- sum))
- The actual `sin' function in Calc works by first reducing the problem
- to a sine or cosine of a nonnegative number less than `pi/4'. This
- ensures that the Taylor series will converge quickly. Also, the
- calculation is carried out with two extra digits of precision to guard
- against cumulative round-off in `sum'. Finally, complex arguments are
- allowed and handled by a separate algorithm.
- (defmath mysin ((float (scalarp x)))
- (interactive 1 "mysn")
- (setq x (to-radians x)) ; Convert from current angular mode.
- (with-extra-prec 2 ; Evaluate with extra precision.
- (cond ((complexp x)
- (mysin-complex x))
- ((< x 0)
- (- (mysin-raw (- x))) ; Always call mysin-raw with x >= 0.
- (t (mysin-raw x))))))
- (defmath mysin-raw (x)
- (cond ((>= x 7)
- (mysin-raw (% x (two-pi)))) ; Now x < 7.
- ((> x (pi-over-2))
- (- (mysin-raw (- x (pi))))) ; Now -pi/2 <= x <= pi/2.
- ((> x (pi-over-4))
- (mycos-raw (- x (pi-over-2)))) ; Now -pi/2 <= x <= pi/4.
- ((< x (- (pi-over-4)))
- (- (mycos-raw (+ x (pi-over-2))))) ; Now -pi/4 <= x <= pi/4,
- (t (mysin-series x)))) ; so the series will be efficient.
- where `mysin-complex' is an appropriate function to handle complex
- numbers, `mysin-series' is the routine to compute the sine Taylor
- series as before, and `mycos-raw' is a function analogous to
- `mysin-raw' for cosines.
- The strategy is to ensure that `x' is nonnegative before calling
- `mysin-raw'. This function then recursively reduces its argument to a
- suitable range, namely, plus-or-minus `pi/4'. Note that each test, and
- particularly the first comparison against 7, is designed so that small
- roundoff errors cannot produce an infinite loop. (Suppose we compared
- with `(two-pi)' instead; if due to roundoff problems the modulo
- operator ever returned `(two-pi)' exactly, an infinite recursion could
- result!) We use modulo only for arguments that will clearly get
- reduced, knowing that the next rule will catch any reductions that this
- rule misses.
- If a program is being written for general use, it is important to
- code it carefully as shown in this second example. For quick-and-dirty
- programs, when you know that your own use of the sine function will
- never encounter a large argument, a simpler program like the first one
- shown is fine.
- File: calc, Node: Calling Calc from Your Programs, Next: Internals, Prev: Example Definitions, Up: Lisp Definitions
- 19.5.6 Calling Calc from Your Lisp Programs
- -------------------------------------------
- A later section (*note Internals::) gives a full description of Calc's
- internal Lisp functions. It's not hard to call Calc from inside your
- programs, but the number of these functions can be daunting. So Calc
- provides one special "programmer-friendly" function called `calc-eval'
- that can be made to do just about everything you need. It's not as
- fast as the low-level Calc functions, but it's much simpler to use!
- It may seem that `calc-eval' itself has a daunting number of
- options, but they all stem from one simple operation.
- In its simplest manifestation, `(calc-eval "1+2")' parses the string
- `"1+2"' as if it were a Calc algebraic entry and returns the result
- formatted as a string: `"3"'.
- Since `calc-eval' is on the list of recommended `autoload'
- functions, you don't need to make any special preparations to load Calc
- before calling `calc-eval' the first time. Calc will be loaded and
- initialized for you.
- All the Calc modes that are currently in effect will be used when
- evaluating the expression and formatting the result.
- 19.5.6.1 Additional Arguments to `calc-eval'
- ............................................
- If the input string parses to a list of expressions, Calc returns the
- results separated by `", "'. You can specify a different separator by
- giving a second string argument to `calc-eval': `(calc-eval "1+2,3+4"
- ";")' returns `"3;7"'.
- The "separator" can also be any of several Lisp symbols which
- request other behaviors from `calc-eval'. These are discussed one by
- one below.
- You can give additional arguments to be substituted for `$', `$$',
- and so on in the main expression. For example, `(calc-eval "$/$$" nil
- "7" "1+1")' evaluates the expression `"7/(1+1)"' to yield the result
- `"3.5"' (assuming Fraction mode is not in effect). Note the `nil' used
- as a placeholder for the item-separator argument.
- 19.5.6.2 Error Handling
- .......................
- If `calc-eval' encounters an error, it returns a list containing the
- character position of the error, plus a suitable message as a string.
- Note that `1 / 0' is _not_ an error by Calc's standards; it simply
- returns the string `"1 / 0"' which is the division left in symbolic
- form. But `(calc-eval "1/")' will return the list `(2 "Expected a
- number")'.
- If you bind the variable `calc-eval-error' to `t' using a `let' form
- surrounding the call to `calc-eval', errors instead call the Emacs
- `error' function which aborts to the Emacs command loop with a beep and
- an error message.
- If you bind this variable to the symbol `string', error messages are
- returned as strings instead of lists. The character position is
- ignored.
- As a courtesy to other Lisp code which may be using Calc, be sure to
- bind `calc-eval-error' using `let' rather than changing it permanently
- with `setq'.
- 19.5.6.3 Numbers Only
- .....................
- Sometimes it is preferable to treat `1 / 0' as an error rather than
- returning a symbolic result. If you pass the symbol `num' as the
- second argument to `calc-eval', results that are not constants are
- treated as errors. The error message reported is the first `calc-why'
- message if there is one, or otherwise "Number expected."
- A result is "constant" if it is a number, vector, or other object
- that does not include variables or function calls. If it is a vector,
- the components must themselves be constants.
- 19.5.6.4 Default Modes
- ......................
- If the first argument to `calc-eval' is a list whose first element is a
- formula string, then `calc-eval' sets all the various Calc modes to
- their default values while the formula is evaluated and formatted. For
- example, the precision is set to 12 digits, digit grouping is turned
- off, and the Normal language mode is used.
- This same principle applies to the other options discussed below.
- If the first argument would normally be X, then it can also be the list
- `(X)' to use the default mode settings.
- If there are other elements in the list, they are taken as
- variable-name/value pairs which override the default mode settings.
- Look at the documentation at the front of the `calc.el' file to find
- the names of the Lisp variables for the various modes. The mode
- settings are restored to their original values when `calc-eval' is done.
- For example, `(calc-eval '("$+$$" calc-internal-prec 8) 'num a b)'
- computes the sum of two numbers, requiring a numeric result, and using
- default mode settings except that the precision is 8 instead of the
- default of 12.
- It's usually best to use this form of `calc-eval' unless your
- program actually considers the interaction with Calc's mode settings to
- be a feature. This will avoid all sorts of potential "gotchas";
- consider what happens with `(calc-eval "sqrt(2)" 'num)' when the user
- has left Calc in Symbolic mode or No-Simplify mode.
- As another example, `(equal (calc-eval '("$<$$") nil a b) "1")'
- checks if the number in string `a' is less than the one in string `b'.
- Without using a list, the integer 1 might come out in a variety of
- formats which would be hard to test for conveniently: `"1"', `"8#1"',
- `"00001"'. (But see "Predicates" mode, below.)
- 19.5.6.5 Raw Numbers
- ....................
- Normally all input and output for `calc-eval' is done with strings.
- You can do arithmetic with, say, `(calc-eval "$+$$" nil a b)' in place
- of `(+ a b)', but this is very inefficient since the numbers must be
- converted to and from string format as they are passed from one
- `calc-eval' to the next.
- If the separator is the symbol `raw', the result will be returned as
- a raw Calc data structure rather than a string. You can read about how
- these objects look in the following sections, but usually you can treat
- them as "black box" objects with no important internal structure.
- There is also a `rawnum' symbol, which is a combination of `raw'
- (returning a raw Calc object) and `num' (signaling an error if that
- object is not a constant).
- You can pass a raw Calc object to `calc-eval' in place of a string,
- either as the formula itself or as one of the `$' arguments. Thus
- `(calc-eval "$+$$" 'raw a b)' is an addition function that operates on
- raw Calc objects. Of course in this case it would be easier to call
- the low-level `math-add' function in Calc, if you can remember its name.
- In particular, note that a plain Lisp integer is acceptable to Calc
- as a raw object. (All Lisp integers are accepted on input, but
- integers of more than six decimal digits are converted to "big-integer"
- form for output. *Note Data Type Formats::.)
- When it comes time to display the object, just use `(calc-eval a)'
- to format it as a string.
- It is an error if the input expression evaluates to a list of
- values. The separator symbol `list' is like `raw' except that it
- returns a list of one or more raw Calc objects.
- Note that a Lisp string is not a valid Calc object, nor is a list
- containing a string. Thus you can still safely distinguish all the
- various kinds of error returns discussed above.
- 19.5.6.6 Predicates
- ...................
- If the separator symbol is `pred', the result of the formula is treated
- as a true/false value; `calc-eval' returns `t' or `nil', respectively.
- A value is considered "true" if it is a non-zero number, or false if it
- is zero or if it is not a number.
- For example, `(calc-eval "$<$$" 'pred a b)' tests whether one value
- is less than another.
- As usual, it is also possible for `calc-eval' to return one of the
- error indicators described above. Lisp will interpret such an
- indicator as "true" if you don't check for it explicitly. If you wish
- to have an error register as "false", use something like `(eq
- (calc-eval ...) t)'.
- 19.5.6.7 Variable Values
- ........................
- Variables in the formula passed to `calc-eval' are not normally
- replaced by their values. If you wish this, you can use the `evalv'
- function (*note Algebraic Manipulation::). For example, if 4 is stored
- in Calc variable `a' (i.e., in Lisp variable `var-a'), then `(calc-eval
- "a+pi")' will return the formula `"a + pi"', but `(calc-eval
- "evalv(a+pi)")' will return `"7.14159265359"'.
- To store in a Calc variable, just use `setq' to store in the
- corresponding Lisp variable. (This is obtained by prepending `var-' to
- the Calc variable name.) Calc routines will understand either string
- or raw form values stored in variables, although raw data objects are
- much more efficient. For example, to increment the Calc variable `a':
- (setq var-a (calc-eval "evalv(a+1)" 'raw))
- 19.5.6.8 Stack Access
- .....................
- If the separator symbol is `push', the formula argument is evaluated
- (with possible `$' expansions, as usual). The result is pushed onto
- the Calc stack. The return value is `nil' (unless there is an error
- from evaluating the formula, in which case the return value depends on
- `calc-eval-error' in the usual way).
- If the separator symbol is `pop', the first argument to `calc-eval'
- must be an integer instead of a string. That many values are popped
- from the stack and thrown away. A negative argument deletes the entry
- at that stack level. The return value is the number of elements
- remaining in the stack after popping; `(calc-eval 0 'pop)' is a good
- way to measure the size of the stack.
- If the separator symbol is `top', the first argument to `calc-eval'
- must again be an integer. The value at that stack level is formatted
- as a string and returned. Thus `(calc-eval 1 'top)' returns the
- top-of-stack value. If the integer is out of range, `nil' is returned.
- The separator symbol `rawtop' is just like `top' except that the
- stack entry is returned as a raw Calc object instead of as a string.
- In all of these cases the first argument can be made a list in order
- to force the default mode settings, as described above. Thus
- `(calc-eval '(2 calc-number-radix 16) 'top)' returns the second-to-top
- stack entry, formatted as a string using the default instead of current
- display modes, except that the radix is hexadecimal instead of decimal.
- It is, of course, polite to put the Calc stack back the way you
- found it when you are done, unless the user of your program is actually
- expecting it to affect the stack.
- Note that you do not actually have to switch into the `*Calculator*'
- buffer in order to use `calc-eval'; it temporarily switches into the
- stack buffer if necessary.
- 19.5.6.9 Keyboard Macros
- ........................
- If the separator symbol is `macro', the first argument must be a string
- of characters which Calc can execute as a sequence of keystrokes. This
- switches into the Calc buffer for the duration of the macro. For
- example, `(calc-eval "vx5\rVR+" 'macro)' pushes the vector
- `[1,2,3,4,5]' on the stack and then replaces it with the sum of those
- numbers. Note that `\r' is the Lisp notation for the carriage-return,
- <RET>, character.
- If your keyboard macro wishes to pop the stack, `\C-d' is safer than
- `\177' (the <DEL> character) because some installations may have
- switched the meanings of <DEL> and `C-h'. Calc always interprets `C-d'
- as a synonym for "pop-stack" regardless of key mapping.
- If you provide a third argument to `calc-eval', evaluation of the
- keyboard macro will leave a record in the Trail using that argument as
- a tag string. Normally the Trail is unaffected.
- The return value in this case is always `nil'.
- 19.5.6.10 Lisp Evaluation
- .........................
- Finally, if the separator symbol is `eval', then the Lisp `eval'
- function is called on the first argument, which must be a Lisp
- expression rather than a Calc formula. Remember to quote the
- expression so that it is not evaluated until inside `calc-eval'.
- The difference from plain `eval' is that `calc-eval' switches to the
- Calc buffer before evaluating the expression. For example, `(calc-eval
- '(setq calc-internal-prec 17) 'eval)' will correctly affect the
- buffer-local Calc precision variable.
- An alternative would be `(calc-eval '(calc-precision 17) 'eval)'.
- This is evaluating a call to the function that is normally invoked by
- the `p' key, giving it 17 as its "numeric prefix argument." Note that
- this function will leave a message in the echo area as a side effect.
- Also, all Calc functions switch to the Calc buffer automatically if not
- invoked from there, so the above call is also equivalent to
- `(calc-precision 17)' by itself. In all cases, Calc uses
- `save-excursion' to switch back to your original buffer when it is done.
- As usual the first argument can be a list that begins with a Lisp
- expression to use default instead of current mode settings.
- The result of `calc-eval' in this usage is just the result returned
- by the evaluated Lisp expression.
- 19.5.6.11 Example
- .................
- Here is a sample Emacs command that uses `calc-eval'. Suppose you have
- a document with lots of references to temperatures on the Fahrenheit
- scale, say "98.6 F", and you wish to convert these references to
- Centigrade. The following command does this conversion. Place the
- Emacs cursor right after the letter "F" and invoke the command to
- change "98.6 F" to "37 C". Or, if the temperature is already in
- Centigrade form, the command changes it back to Fahrenheit.
- (defun convert-temp ()
- (interactive)
- (save-excursion
- (re-search-backward "[^-.0-9]\\([-.0-9]+\\) *\\([FC]\\)")
- (let* ((top1 (match-beginning 1))
- (bot1 (match-end 1))
- (number (buffer-substring top1 bot1))
- (top2 (match-beginning 2))
- (bot2 (match-end 2))
- (type (buffer-substring top2 bot2)))
- (if (equal type "F")
- (setq type "C"
- number (calc-eval "($ - 32)*5/9" nil number))
- (setq type "F"
- number (calc-eval "$*9/5 + 32" nil number)))
- (goto-char top2)
- (delete-region top2 bot2)
- (insert-before-markers type)
- (goto-char top1)
- (delete-region top1 bot1)
- (if (string-match "\\.$" number) ; change "37." to "37"
- (setq number (substring number 0 -1)))
- (insert number))))
- Note the use of `insert-before-markers' when changing between "F"
- and "C", so that the character winds up before the cursor instead of
- after it.
|