1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781 |
- COMMENT REDUCE INTEGRATION PACKAGE WITHOUT ALGEBRAIC EXTENSIONS;
- COMMENT Messages look better if one does OFF RAISE;
- OFF ECHO;
- SYMBOLIC;
-
- FLAG('(INTERR),'TRANSFER); %For the compiler;
- COMMENT SMACRO's needed to support Cambridge LISP constructs;
- SMACRO PROCEDURE EVENP X; REMAINDER(X,2)=0;
- SMACRO PROCEDURE GCD(U,V); GCDN(U,V);
- INFIX IEQUAL;
- SYMBOLIC SMACRO PROCEDURE U IEQUAL V; EQN(U,V);
- SMACRO PROCEDURE READCLOCK; TIME();
- SMACRO PROCEDURE REVERSEWOC U; REVERSIP U;
- SMACRO PROCEDURE SUPERPRINT U; PRETTYPRINT U;
- %the next two are needed since arguments may not be numbers;
- SMACRO PROCEDURE ONEP U; U=1;
- SMACRO PROCEDURE ZEROP U; U=0;
- COMMENT The following three smacros can be used if there is a reason
- for not using actual vectors;
- %SMACRO PROCEDURE MKVECT N; %MKNILL(N+1);
- %SMACRO PROCEDURE PUTV(U,N,V); %CAR RPLACA(PNTH(U,N+1),V);
- %SMACRO PROCEDURE GETV(U,N); %NTH(U,N+1);
- COMMENT End of Cambridge LISP compatibility section;
- FLUID '(LORDER SILLIESLIST VARLIST);
- GLOBAL '(GENSYMCOUNT);
- SYMBOLIC SMACRO PROCEDURE !*F2POL U;
- %U is a standard form;
- %Value is a polynomial form after power substitutions made;
- %If a quotient results from substitutions, an error occurs;
- !*Q2F SUBS2F U;
- SYMBOLIC SMACRO PROCEDURE !*MULTF!*(U,V); MULTF(U,V);
- SYMBOLIC PROCEDURE FLATTEN U;
- IF NULL U THEN NIL
- ELSE IF ATOM U THEN LIST U
- ELSE IF ATOM CAR U THEN CAR U . FLATTEN CDR U
- ELSE NCONC(FLATTEN CAR U,FLATTEN CDR U);
- SYMBOLIC PROCEDURE GENSYM1 U;
- << GENSYMCOUNT:=GENSYMCOUNT+1;
- COMPRESS APPEND(EXPLODE U,EXPLODE GENSYMCOUNT) >>;
- SYMBOLIC SMACRO PROCEDURE PRINTC X; PRIN2T X;
- SYMBOLIC PROCEDURE MKNILL N;
- IF N=0 THEN NIL ELSE NIL . MKNILL(N-1);
- SYMBOLIC PROCEDURE SQRT N;
- % return sqrt of n if same is exact, or something non-numeric
- % otherwise;
- IF NOT NUMBERP N THEN 'NONNUMERIC
- ELSE IF N<0 THEN 'NEGATIVE
- ELSE IF FLOATP N THEN SQRT!-FLOAT N
- ELSE IF N<2 THEN N
- ELSE NR(N,(N+1)/2);
- SYMBOLIC PROCEDURE NR(N,ROOT);
- % root is an overestimate here. nr moves downwards to root;
- BEGIN
- SCALAR W;
- W:=ROOT*ROOT;
- IF N=W THEN RETURN ROOT;
- W:=(ROOT+N/ROOT)/2;
- IF W>=ROOT THEN RETURN !*P2F MKSP(MKSQRT N,1);
- RETURN NR(N,W)
- END;
- GLOBAL '(SQRT!-FLOAT!-TOLERANCE);
- SQRT!-FLOAT!-TOLERANCE := 0.00001;
- SYMBOLIC PROCEDURE SQRT!-FLOAT N;
- % Simple Newton-Raphson floating point square root calculator.
- % Not warranted against truncation errors, etc;
- BEGIN INTEGER SCALE; SCALAR ANS;
- IF N<0.0 THEN REDERR "SQRT!-FLOAT GIVEN NEGATIVE ARGUMENT";
- % Scale argument to within 1e-10 to 1e+10;
- SCALE := 0;
- WHILE N > 1E+10 DO <<
- SCALE := SCALE + 1;
- N := N/1E+10 >>;
- WHILE N < 1E-10 DO <<
- SCALE := SCALE - 1;
- N := N*1E-10 >>;
- ANS := IF N>2.0 THEN (N+1)/2
- ELSE IF N<0.5 THEN 2/(N+1)
- ELSE N;
- WHILE ABS(ANS**2/N - 1.0) > SQRT!-FLOAT!-TOLERANCE DO
- ANS := 0.5*(ANS+N/ANS);
- RETURN ANS*10**(5*SCALE)
- END;
- COMMENT Kludge to define derivative of an integral;
- SYMBOLIC PUT('DF,'OPMTCH,'(((INT !&Y !&X) !&X) (NIL . T)
- (EVL!* !&Y) NIL) . GET('DF,'OPMTCH));
- GLOBAL '(FRLIS!*);
- SYMBOLIC FRLIS!* := '!&X . '!&Y . FRLIS!*;
- SYMBOLIC IF NOT GETD 'MODBIND
- THEN <<PUT('EVL!*,'OPMTCH,'(((!&X) (NIL . T) !&X NIL)));
- PUT('EVL!*,'SIMPFN,'SIMPIDEN)>>;
- % MKOP 'SQRT>>;
- %distinguish between mode and non-mode system;
- ALGEBRAIC;
- %FOR ALL X LET SQRT X**2=X;
- SYMBOLIC;
- COMMENT support for module use;
- GLOBAL '(EXPORTSLIST!* IMPORTSLIST!* !*MODULEP);
- DEFLIST('((EXPORTS RLIS) (IMPORTS RLIS) (MODULE RLIS)
- (ENDMODULE ENDSTAT)),'STAT);
- SYMBOLIC PROCEDURE EXPORTS U;
- BEGIN
- EXPORTSLIST!* := UNION(U,EXPORTSLIST!*);
- END;
- SYMBOLIC PROCEDURE IMPORTS U;
- BEGIN
- IMPORTSLIST!* := UNION(U,IMPORTSLIST!*);
- END;
- SYMBOLIC PROCEDURE MODULE U;
- %Sets up a module definition;
- BEGIN
- !*MODULEP := T;
- END;
- SYMBOLIC PROCEDURE ENDMODULE;
- BEGIN
- EXPORTSLIST!* := NIL;
- IMPORTSLIST!* := NIL;
- !*MODULEP := NIL
- END;
- %**********************************************************************;
- % SET REDUCE AND LISP OPTIONS ONCE AND FOR ALL;
- %ON COMP;
- % ALL FLUID VARIABLES ARE DECLARED HERE;
- FLUID '(CONTENT SQFR ZLIST INDEXLIST SQRTLIST )$
- FLUID '(!*MCD !*GCD !*EXP !*SQRT !*STRUCTURE);
- FLUID '( PT ULIST
- REDUCTIONEQ LOGLIST CLIST CCOUNT CVAL CMAP TANLIST LHS
- BADPART CUBEROOTFLAG VARLIST CLOGFLAG EXPRESSION RESIDUE
- VARIABLE ORDEROFELIM CMATRIX DENOMINATOR TAYLORVARIABLE
- !*PURERISCH !*NOLNR);
- %FLAGS TO BE SET USING 'ON' AND 'OFF' STATEMENTS;
- GLOBAL '(!*RATINTSPECIAL !*TRINT !*SEPLOGS !*FAILHARD !*TRDIV
- !*STATISTICS !*NUMBER!* !*SPSIZE!*
- BTRLEVEL !*GENSYMLIST!*);
- BTRLEVEL:=5; %DEFAULT TO A REASONABLY FULL BACKTRACE;
- ON SEPLOGS;%,OVERLAYMODE;
- %TOPLEVELCODE:='(COMPILER RLISP APROC);
- %**********************************************************************;
- SMACRO PROCEDURE FIRSTSUBS U;
- CAR U;
- % THE FIRST SUBSTITUTION IN A SUBSTITUTION LIST;
- SMACRO PROCEDURE RSUBS U;
- CDR U;
- SMACRO PROCEDURE LSUBS U;
- CAR U;
- % THE ABOVE TWO FUNCTIONS DEFINE LEFT AND RIGHT HALVES OF A
- % SUBSTITUTION RULE;
- SMACRO PROCEDURE LFIRSTSUBS U;
- CAAR U;
- SMACRO PROCEDURE RFIRSTSUBS U;
- CDAR U;
- % SOME COMBINATIONS OF THE ABOVE;
- SMACRO PROCEDURE ARGOF U;
- CADR U;
- % THE ARGUMENT OF A UNARY FUNCTION;
- FLAG ('(ATAN DILOG ERF EXPINT EXPT LOG TAN),'TRANSCENDENTAL);
- ALGEBRAIC;
- %Patterns for integration of various logarithmic cases;
- %FOR ALL X,A,B,C,D LET INT(LOG(A*X+B)/(C*X+D),X)=
- % LOG(C*X+D)*LOG(B*C-A*D)/C - LOG C*LOG(C*X+D)/C
- % - DILOG((A*C*X+B*C)/(B*C-A*D))/C;
- %% A=1;
- %FOR ALL X,B,C,D LET INT(LOG(X+B)/(C*X+D),X)=
- % LOG(C*X+D)*(LOG(B*C-D)-LOG C)/C -DILOG((C*X+B*C)/(B*C-D))/C;
- %% B=0;
- %FOR ALL X,A,C,D LET INT(LOG(A*X)/(C*X+D),X)=
- % LOG(C*X+D)*(LOG(-1)+LOG(A)+LOG(D)-LOG C)/C - DILOG(-C*X/D)/C;
- %% C=1;
- %FOR ALL X,A,B,D LET INT(LOG(A*X+B)/(X+D),X)=
- % LOG(X+D)*LOG(B-A*D)-DILOG((A*X+B)/(B-A*D));
- %% D=0;
- %FOR ALL X,A,B,C LET INT(LOG(A*X+B)/(C*X),X)=
- % LOG(C*X)*LOG(B)/C - DILOG((A*X+B)/B)/C;
- %% A=1, B=0;
- %FOR ALL X,C,D LET INT(LOG(X)/(C*X+D),X)=
- % LOG(C*X+D)*(LOG(-1)+LOG(D)-LOG(C))/C - DILOG(-C*X/D)/C;
- %% A=1, C=1;
- %FOR ALL X,B,D LET INT(LOG(X+B)/(X+D),X)=
- % LOG(X+D)*LOG(B-D) - DILOG((X+B)/(B-D));
- %% A=1, D=0;
- %FOR ALL X,B,C LET INT(LOG(X+B)/(C*X),X)=
- % LOG(C*X)*LOG(B)/C - DILOG((X+B)/B)/C;
- %% B=0, C=1;
- %FOR ALL X,A,D LET INT(LOG(A*X)/(X+D),X)=
- % LOG(X+D)*(LOG(-1)+LOG(A)+LOG(D)) - DILOG(-X/D);
- %% C=1, D=0;
- %FOR ALL X,A,B LET INT(LOG(A*X+B)/X,X)=
- % LOG(X+D)*(LOG(-1)+LOG(D)) - DILOG(-X/D);
- %% A=1, C=1, D=0;
- %FOR ALL X,B LET INT(LOG(X+B)/X,X)=
- % LOG(X)*LOG(B) - DILOG((X+B)/B);
- %% A=1, B=0, C=1;
- %FOR ALL X,D LET INT(LOG(X)/(X+D),X)=
- % LOG(X+D)*(LOG(-1)+LOG(D)) - DILOG(-X/D);
- %
- LISP;
- !*NOLNR:=NIL;
- MODULE CONTENTS;
- EXPORTS CONTENTS,CONTENTSMV,DFNUMR,DIFFLOGS,FACTORLISTLIST,MULTSQFREE,
- MULTUP,SQFREE,SQMERGE;
- IMPORTS INT!-FAC,FQUOTF,GCDF,INTERR,!*MULTF!*,PARTIALDIFF,QUOTF,ORDOP,
- ADDF,NEGF,DOMAINP,DIFFF,MKSP,NEGSQ,INVSQ,ADDSQ,MULTSQ,DIFFSQ;
- COMMENT we assume that no power substitution is necessary in
- this module;
- SYMBOLIC PROCEDURE CONTENTS(P,V);
- % FIND THE CONTENTS OF THE POLYNOMIAL P WRT VARIABLE V;
- % NOTE THAT V MAY NOT BE THE MAIN VARIABLE OF P;
- IF DOMAINP(P) THEN P
- ELSE IF V=MVAR P THEN CONTENTSMV(P,V,NIL)
- ELSE IF ORDOP(V,MVAR P) THEN P
- ELSE CONTENTSMV(MAKEMAINVAR(P,V),V,NIL);
- SYMBOLIC PROCEDURE CONTENTSMV(P,V,SOFAR);
- % FIND CONTENTS OF POLYNOMIAL P;
- % V IS MAIN VARIABLE OF P;
- % SOFAR IS PARTIAL RESULT;
- IF SOFAR=1 THEN 1
- ELSE IF DOMAINP P THEN GCDF(P,SOFAR)
- ELSE IF NOT V=MVAR P THEN GCDF(P,SOFAR)
- ELSE CONTENTSMV(RED P,V,GCDF(LC P,SOFAR));
- SYMBOLIC PROCEDURE MAKEMAINVAR(P,V);
- % BRING V UP TO BE THE MAIN VARIABLE IN POLYNOMIAL P;
- % NOTE THAT THE RECONSTRUCTED P MUST BE USED WITH CARE SINCE;
- % IT DOES NOT CONFORM TO THE NORMAL REDUCE ORDERING RULES;
- IF DOMAINP P THEN P
- ELSE IF V=MVAR P THEN P
- ELSE MERGEADD(MULCOEFFSBY(MAKEMAINVAR(LC P,V),LPOW P,V),
- MAKEMAINVAR(RED P,V),V);
- SYMBOLIC PROCEDURE MULCOEFFSBY(P,POW,V);
- % MULTIPLY EACH COEFFICIENT IN P BY THE STANDARD POWER POW;
- IF NULL P THEN NIL
- ELSE IF DOMAINP P OR NOT V=MVAR P THEN ((POW .* P) .+ NIL)
- ELSE (LPOW P .* ((POW .* LC P) .+ NIL)) .+ MULCOEFFSBY(RED P,POW,V);
- SYMBOLIC PROCEDURE MERGEADD(A,B,V);
- % ADD POLYNOMIALS A AND B GIVEN THAT THEY HAVE SAME MAIN VARIABLE V;
- IF DOMAINP A OR NOT V=MVAR A THEN
- IF DOMAINP B OR NOT V=MVAR B THEN ADDF(A,B)
- ELSE LT B .+ MERGEADD(A,RED B,V)
- ELSE IF DOMAINP B OR NOT V=MVAR B THEN
- LT A .+ MERGEADD(RED A,B,V)
- ELSE (LAMBDA XC;
- IF XC=0 THEN (LPOW A .* ADDF(LC A,LC B)) .+
- MERGEADD(RED A,RED B,V)
- ELSE IF XC>0 THEN LT A .+ MERGEADD(RED A,B,V)
- ELSE LT B .+ MERGEADD(A,RED B,V))
- (TDEG LT A-TDEG LT B);
- SYMBOLIC PROCEDURE SQFREE(P,VL);
- IF (NULL VL) OR (DOMAINP P) THEN
- <<CONTENT:=P; NIL>>
- ELSE BEGIN SCALAR W,V,DP,GG,PG,DPG,P1,W1;
- W:=CONTENTS(P,CAR VL); % CONTENT OF P ;
- P:=QUOTF(P,W); % MAKE P PRIMITIVE;
- W:=SQFREE(W,CDR VL); % PROCESS CONTENT BY RECURSION;
- IF P=1 THEN RETURN W;
- V:=CAR VL; % PICK OUT VARIABLE FROM LIST;
- WHILE NOT (P=1) DO <<
- DP:=PARTIALDIFF(P,V);
- GG:=GCDF(P,DP);
- PG:=QUOTF(P,GG);
- DPG:=NEGF PARTIALDIFF(PG,V);
- P1:=GCDF(PG,ADDF(QUOTF(DP,GG),DPG));
- W1:=P1.W1;
- P:=GG>>;
- RETURN SQMERGE(REVERSE W1,W,T)
- END;
- SYMBOLIC PROCEDURE SQMERGE(W1,W,SIMPLEW1);
- % W AND W1 ARE LISTS OF FACTORS OF EACH POWER. IF SIMPLEW1 IS TRUE
- % THEN W1 CONTAINS ONLY SINGLE FACTORS FOR EACH POWER. ;
- IF NULL W1 THEN W
- ELSE IF NULL W THEN IF CAR W1=1 THEN NIL.SQMERGE(CDR W1,W,SIMPLEW1)
- ELSE (IF SIMPLEW1 THEN LIST CAR W1 ELSE CAR W1).
- SQMERGE(CDR W1,W,SIMPLEW1)
- ELSE IF CAR W1=1 THEN (CAR W).SQMERGE(CDR W1,CDR W,SIMPLEW1) ELSE
- APPEND(IF SIMPLEW1 THEN LIST CAR W1 ELSE CAR W1,CAR W).
- SQMERGE(CDR W1,CDR W,SIMPLEW1);
- SYMBOLIC PROCEDURE MULTUP L;
- % L IS A LIST OF S.F.'S. RESULT IS S.Q. FOR PRODUCT OF ELEMENTS OF L;
- BEGIN SCALAR RES;
- RES:=1 ./ 1;
- WHILE NOT NULL L DO <<
- RES:=MULTSQ(RES,(CAR L) ./ 1);
- L:=CDR L >>;
- RETURN RES
- END;
- SYMBOLIC PROCEDURE DIFLIST(L,CL,X,RL);
- % DIFFERENTIATES L (LIST OF S.F.'S) WRT X TO PRODUCE THE SUM OF;
- % TERMS FOR THE DERIVATIVE OF NUMR OF 1ST PART OF ANSWER. CL IS;
- % COEFFICIENT LIST (S.F.'S) & RL IS LIST OF DERIVATIVES WE HAVE;
- % DEALT WITH SO FAR;
- % RESULT IS S.Q.;
- IF NULL L THEN NIL ./ 1
- ELSE BEGIN SCALAR TEMP;
- TEMP:=MULTSQ(MULTUP RL,MULTUP CDR L);
- TEMP:=MULTSQ(DIFFF(CAR L,X),TEMP);
- TEMP:=MULTSQ(TEMP,(CAR CL) ./ 1);
- RETURN ADDSQ(TEMP,DIFLIST(CDR L,CDR CL,X,(CAR L).RL))
- END;
- SYMBOLIC PROCEDURE MULTSQFREE W;
- % W IS LIST OF SQFREE FACTORS. RESULT IS PRODUCT OF EACH LIST IN W
- % TO GIVE ONE POLYNOMIAL FOR EACH SQFREE POWER;
- IF NULL W THEN NIL
- ELSE (!*Q2F MULTUP CAR W).MULTSQFREE CDR W;
- SYMBOLIC PROCEDURE L2LSF L;
- % L IS A LIST OF KERNELS. RESULT IS A LIST OF SAME MEMBERS AS S.F.'S;
- IF NULL L THEN NIL
- ELSE ((MKSP(CAR L,1) .* 1) .+ NIL).L2LSF CDR L;
- SYMBOLIC PROCEDURE DFNUMR(X,DL);
- % GIVES THE DERIVATIVE OF THE NUMR OF THE 1ST PART OF ANSWER.;
- % DL IS LIST OF ANY EXPONENTIAL OR 1+TAN**2 THAT OCCUR IN INTEGRAND;
- % DENR. THESE ARE DIVIDED OUT FROM RESULT BEFORE HANDING IT BACK.;
- % RESULT IS S.Q., READY FOR PRINTING;
- BEGIN SCALAR TEMP1,TEMP2,COEFLIST,QLIST,COUNT;
- IF NOT NULL SQFR THEN <<
- COUNT:=0;
- QLIST:=CDR SQFR;
- COEFLIST:=NIL;
- WHILE NOT NULL QLIST DO <<
- COUNT:=COUNT+1;
- COEFLIST:=COUNT.COEFLIST;
- QLIST:=CDR QLIST >>;
- COEFLIST:=REVERSE COEFLIST >>;
- TEMP1:=MULTSQ(DIFLIST(L2LSF ZLIST,L2LSF INDEXLIST,X,NIL),
- MULTUP SQFR);
- IF NOT NULL SQFR AND NOT NULL CDR SQFR THEN <<
- TEMP2:=MULTSQ(DIFLIST(CDR SQFR,COEFLIST,X,NIL),
- MULTUP L2LSF ZLIST);
- TEMP2:=MULTSQ(TEMP2,(CAR SQFR) ./ 1) >>
- ELSE TEMP2:=NIL ./ 1;
- TEMP1:=ADDSQ(TEMP1,NEGSQ TEMP2);
- TEMP2:=CDR TEMP1;
- TEMP1:=CAR TEMP1;
- QLIST:=NIL;
- WHILE NOT NULL DL DO <<
- IF NOT CAR DL MEMBER QLIST THEN QLIST:=(CAR DL).QLIST;
- DL:=CDR DL >>;
- WHILE NOT NULL QLIST DO <<
- TEMP1:=QUOTF(TEMP1,CAR QLIST);
- QLIST:=CDR QLIST >>;
- RETURN TEMP1 ./ TEMP2
- END;
- SYMBOLIC PROCEDURE DIFFLOGS(LL,DENM1,X);
- % LL IS LIST OF LOG TERMS (WITH COEFFTS), DEN IS COMMON DENOMINATOR;
- % OVER WHICH THEY ARE TO BE PUT. RESULT IS S.Q. FOR DERIVATIVE OF ALL;
- % THESE WRT X;
- IF NULL LL THEN NIL ./ 1
- ELSE BEGIN SCALAR TEMP,QU,CVAR,LOGORATAN,ARG;
- LOGORATAN:=CAAR LL;
- CVAR:=CADAR LL;
- ARG:=CDDAR LL;
- TEMP:=MULTSQ(CVAR ./ 1,DIFFSQ(ARG,X));
- IF LOGORATAN='IDEN THEN QU:=1 ./ 1
- ELSE IF LOGORATAN='LOG THEN QU:=ARG
- ELSE IF LOGORATAN='ATAN THEN QU:=ADDSQ(1 ./ 1,MULTSQ(ARG,ARG))
- ELSE INTERR "LOGORATAN=? IN DIFFLOGS";
- %NOTE CALL TO SPECIAL DIVISION ROUTINE;
- QU:=FQUOTF(!*F2POL !*MULTF!*(!*MULTF!*(DENM1,NUMR TEMP),
- DENR QU),NUMR QU);
- %*MUST* GO EXACTLY;
- TEMP:=MULTSQ(INVSQ (DENR TEMP ./ 1),QU);
- %RESULT OF FQUOTF IS A S.Q;
- RETURN SUBS2Q ADDSQ(TEMP,DIFFLOGS(CDR LL,DENM1,X))
- END;
- SYMBOLIC PROCEDURE FACTORLISTLIST (W,CLOGFLAG);
- % W IS LIST OF LISTS OF SQFREE FACTORS IN S.F. RESULT IS LIST OF LOG;
- % TERMS REQUIRED FOR INTEGRAL ANSWER. THE ARGUMENTS FOR EACH LOG FN;
- % ARE IN S.Q.;
- BEGIN SCALAR RES,X,Y;
- WHILE NOT NULL W DO <<
- X:=CAR W;
- WHILE NOT NULL X DO <<
- Y:=FACBYPP(CAR X,VARLIST);
- WHILE NOT NULL Y DO <<
- RES:=APPEND(INT!-FAC CAR Y,RES);
- Y:=CDR Y >>;
- X:=CDR X >>;
- W:=CDR W >>;
- RETURN RES
- END;
- SYMBOLIC PROCEDURE FACBYPP(P,VL);
- %USE CONTENTS/PRIMITIVE PARTS TO TRY TO FACTOR P;
- IF NULL VL THEN LIST P
- ELSE BEGIN SCALAR PRINCILAP!-PART,CO;
- CO:=CONTENTS(P,CAR VL);
- VL:=CDR VL;
- IF CO=1 THEN RETURN FACBYPP(P,VL); %THIS VAR NO HELP;
- PRINCILAP!-PART:=QUOTF(P,CO); %PRIMITIVE PART;
- IF PRINCILAP!-PART=1 THEN RETURN FACBYPP(P,VL); %AGAIN NO HELP;
- RETURN NCONC(FACBYPP(PRINCILAP!-PART,VL),FACBYPP(CO,VL))
- END;
- ENDMODULE;
- MODULE CSOLVE;
- EXPORTS BACKSUBST4CS,CREATECMAP,FINDPIVOT,PRINTSPREADC,PRINTVECSQ,
- SPREADC,SUBST4ELIMINATEDS;
- IMPORTS NTH,INTERR,!*MULTF!*,PRINTSF,PRINTSQ,QUOTF,PUTV,NEGF,INVSQ,
- NEGSQ,ADDSQ,MULTSQ,MKSP,ADDF,DOMAINP,PNTH;
- % routines to do with the C constants;
- SYMBOLIC PROCEDURE FINDPIVOT CVEC;
- % Finds first non-zero element in CVEC and returns its cell number.;
- % If no such element exists, result is nil.;
- BEGIN SCALAR I,X;
- I:=1;
- X:=GETV(CVEC,I);
- WHILE I<CCOUNT AND NULL X DO
- << I:=I+1;
- X:=GETV(CVEC,I) >>;
- IF NULL X THEN RETURN NIL;
- RETURN I
- END;
- SYMBOLIC PROCEDURE SUBST4ELIMINATEDCS(NEWEQN,SUBSTORDER,CEQNS);
- % Substitutes into NEWEQN for all the C's that have been eliminated so;
- % far. These are given by CEQNS. SUBSTORDER gives the order of;
- % substitution as well as the constant multipliers. Result is the;
- % transformed NEWEQN.;
- IF NULL SUBSTORDER THEN NEWEQN
- ELSE BEGIN SCALAR NXT,ROW,CVAR,TEMP;
- ROW:=CAR CEQNS;
- NXT:=CAR SUBSTORDER;
- IF NULL (CVAR:=GETV(NEWEQN,NXT)) THEN
- RETURN SUBST4ELIMINATEDCS(NEWEQN,CDR SUBSTORDER,CDR CEQNS);
- NXT:=GETV(ROW,NXT);
- FOR I:=0 : CCOUNT DO
- << TEMP:=!*MULTF!*(NXT,GETV(NEWEQN,I));
- TEMP:=ADDF(TEMP,NEGF !*MULTF!*(CVAR,GETV(ROW,I)));
- PUTV(NEWEQN,I,!*F2POL TEMP) >>;
- RETURN SUBST4ELIMINATEDCS(NEWEQN,CDR SUBSTORDER,CDR CEQNS)
- END;
- SYMBOLIC PROCEDURE BACKSUBST4CS(CS2SUBST,CS2SOLVE,CMATRIX);
- % Solves the C-eqns and sets vector CVAL to the C-constant values;
- % CMATRIX is a list of matrix rows for C-eqns after Gaussian ;
- % elimination has been performed. CS2SOLVE is a list of the remaining;
- % C's to evaluate and CS2SUBST are the C's we have evaluated already.;
- IF NULL CMATRIX THEN NIL
- ELSE BEGIN SCALAR EQNN,CVAR,ALREADY,SUBSTLIST,TEMP,TEMP2;
- EQNN:=CAR CMATRIX;
- CVAR:=CAR CS2SOLVE;
- ALREADY:=NIL ./ 1; % The S.Q. nil ;
- SUBSTLIST:=CS2SUBST;
- % NOW SUBSTITUTE FOR PREVIOUSLY EVALUATED C'S:;
- WHILE NOT NULL SUBSTLIST DO
- << TEMP:=CAR SUBSTLIST;
- IF NOT NULL GETV(EQNN,TEMP) THEN
- ALREADY:=ADDSQ(ALREADY,MULTSQ(GETV(EQNN,TEMP) ./ 1,
- GETV(CVAL,TEMP)));
- SUBSTLIST:=CDR SUBSTLIST >>;
- % NOW SOLVE FOR THE C GIVEN BY CVAR (ANY REMAINING C'S ASSUMED ZERO);
- TEMP:=NEGSQ ADDSQ(GETV(EQNN,0) ./ 1,ALREADY);
- IF NOT NULL (TEMP2:=QUOTF(NUMR TEMP,GETV(EQNN,CVAR))) THEN
- TEMP:=TEMP2 ./ DENR TEMP
- ELSE TEMP:=MULTSQ(TEMP,INVSQ(GETV(EQNN,CVAR) ./ 1));
- IF NOT NULL NUMR TEMP THEN PUTV(CVAL,CVAR,
- RESIMP ROOTEXTRACTSQ SUBS2Q TEMP);
- BACKSUBST4CS(REVERSEWOC(CVAR . REVERSEWOC CS2SUBST),
- CDR CS2SOLVE,CDR CMATRIX)
- END;
- %**********************************************************************;
- % Routines to deal with linear equations for the constants C;
- %**********************************************************************;
- SYMBOLIC PROCEDURE CREATECMAP;
- %Sets LOGLIST to list of things of form (LOG C-constant f), where f is;
- % function linear in one of the z-variables and C-constant is in S.F.;
- % When creating these C-constant names, the CMAP is also set up and ;
- % returned as the result.;
- BEGIN SCALAR I,L,C;
- L:=LOGLIST;
- I:=1;
- WHILE NOT NULL L DO <<
- C:=(GENSYM1('C) . I) . C;
- I:=I+1;
- RPLACD(CAR L,((MKSP(CAAR C,1) .* 1) .+ NIL) . CDAR L);
- L:=CDR L >>;
- IF !*TRINT THEN PRINTC ("Constants Map" . C);
- RETURN C
- END;
- SYMBOLIC PROCEDURE SPREADC(EQNN,CVEC1,W);
- %SETS A VECTOR 'CVEC1' TO COEFFICIENTS OF C<I> IN EQNN;
- IF DOMAINP EQNN THEN PUTV(CVEC1,0,ADDF(GETV(CVEC1,0),
- !*F2POL !*MULTF!*(EQNN,W)))
- ELSE BEGIN SCALAR MV,T1,T2;
- SPREADC(RED EQNN,CVEC1,W);
- MV:=MVAR EQNN;
- T1:=ASSOC(MV,CMAP); %TESTS IF IT IS A C VAR;
- IF NOT NULL T1 THEN RETURN <<
- T1:=CDR T1; %LOC IN VECTOR FOR THIS C;
- IF NOT (TDEG LT EQNN=1) THEN INTERR "NOT LINEAR IN C EQN";
- T2:=ADDF(GETV(CVEC1,T1),!*MULTF!*(W,LC EQNN));
- PUTV(CVEC1,T1,!*F2POL T2) >>;
- T1:=((LPOW EQNN) .* 1) .+ NIL; %THIS MAIN VAR AS SF;
- SPREADC(LC EQNN,CVEC1,!*F2POL !*MULTF!*(W,T1))
- END;
- SYMBOLIC PROCEDURE PRINTSPREADC CVEC1;
- BEGIN
- FOR I:=0 : CCOUNT DO <<
- PRIN2 I;
- PRINTC ":";
- PRINTSF(GETV(CVEC1,I)) >>;
- PRINTC "END OF PRINTSPREADC OUTPUT"
- END;
- %SYMBOLIC PROCEDURE PRINTVECSQ CVEC;
- %% PRINT CONTENTS OF CVEC WHICH CONTAINS S.Q.'S (NOT S.F.'S);
- %% STARTS FROM CELL 1 NOT 0 AS ABOVE ROUTINE (PRINTSPREADC);
- % BEGIN
- % FOR I:=1 : CCOUNT DO <<
- % PRIN2 I;
- % PRINTC ":";
- % IF NULL GETV(CVEC,I) THEN PRINTC "0"
- % ELSE PRINTSQ(GETV(CVEC,I)) >>;
- % PRINTC "END OF PRINTVECSQ OUTPUT"
- % END;
- ENDMODULE;
- MODULE CUBEROOT;
- EXPORTS CUBEROOTDF;
- IMPORTS CONTENTSMV,GCDF,!*MULTF!*,NROOTN,PARTIALDIFF,PRINTDF,QUOTF,VP2,
- MKSP,MK!*SQ,DOMAINP;
- %CUBE-ROOT OF STANDARD FORMS;
- SYMBOLIC PROCEDURE CUBEROOTSQ A;
- CUBEROOTF NUMR A ./ CUBEROOTF DENR A;
- SYMBOLIC PROCEDURE CUBEROOTF P;
- BEGIN SCALAR IP,QP;
- IF NULL P THEN RETURN NIL;
- IP:=CUBEROOTF1 P;
- QP:=CDR IP;
- IP:=CAR IP; %RESPECTABLE AND NASTY PARTS OF THE CUBEROOT;
- IF ONEP QP THEN RETURN IP; %EXACT ROOT FOUND;
- QP:=LIST('EXPT,PREPF QP,'(QUOTIENT 1 3));
- CUBEROOTFLAG:=T; %SYMBOLIC CUBE-ROOT INTRODUCED;
- QP:=(MKSP(QP,1).* 1) .+ NIL;
- RETURN !*F2POL !*MULTF!*(IP,QP)
- END;
- SYMBOLIC PROCEDURE CUBEROOTF1 P;
-
- %RETURNS A . B WITH P=A**2*B;
- %does this need power reduction??;
- IF DOMAINP P THEN NROOTN(P,3)
- ELSE BEGIN SCALAR CO,PPP,G,PG;
- CO:=CONTENTSMV(P,MVAR P,NIL); %CONTENTS OF P;
- PPP:=QUOTF(P,CO); %PRIMITIVE PART;
- %NOW CONSIDER PPP=P1*P2**2*P3**3*P4**4*...;
- CO:=CUBEROOTF1(CO); %PROCESS CONTENTS VIA RECURSION;
- G:=GCDF(PPP,PARTIALDIFF(PPP,MVAR PPP));
- %G=P2*P3**2*P4**3*...;
- IF NOT DOMAINP G THEN <<
- PG:=QUOTF(PPP,G);
- %PG=P1*P2*P3*P4*...;
- G:=GCDF(G,PARTIALDIFF(G,MVAR G));
- % G=G3*G4**2*G5**3*...;
- G:=GCDF(G,PG)>>; %A TRIPLE FACTOR OF PPP;
- IF DOMAINP G THEN PG:=1 . PPP
- ELSE <<
- PG:=QUOTF(PPP,!*MULTF!*(G,!*MULTF!*(G,G))); %WHAT'S LEFT;
- PG:=CUBEROOTF1(!*F2POL PG); %SPLIT THAT UP;
- RPLACA(PG,!*MULTF!*(CAR PG,G))>>;
- %PUT IN THE THING FOUND HERE;
- RPLACA(PG,!*F2POL !*MULTF!*(CAR PG,CAR CO));
- RPLACD(PG,!*F2POL !*MULTF!*(CDR PG,CDR CO));
- RETURN PG
- END;
- ENDMODULE;
- MODULE DEPEND;
- EXPORTS DEPENDSPL,DEPENDSP,INVOLVESQ,INVOLVSF;
- IMPORTS TAYLORP,DOMAINP;
- SYMBOLIC PROCEDURE DEPENDSP(X,V);
- IF NULL V THEN T
- ELSE IF ATOM X THEN IF X EQ V THEN X ELSE NIL
- ELSE IF CAR X = '!*SQ
- THEN INVOLVESQ(CADR X,V)
- ELSE IF TAYLORP X
- THEN IF V EQ TAYLORVARIABLE THEN TAYLORVARIABLE ELSE NIL
- ELSE BEGIN
- SCALAR W;
- IF X=V THEN RETURN V;
- % CHECK IF A PREFIX FORM EXPRESSION DEPENDS ON THE VARIABLE V;
- % NOTE THAT THIS ASSUMES THE FORM X IS IN NORMAL PREFIX NOTATION;
- W := X; % preserve the dependency;
- X:=CDR X; % READY TO RECURSIVELY CHECK ARGUMENTS;
- SCAN: IF NULL X THEN RETURN NIL; % NO DEPENDENCY FOUND;
- IF DEPENDSP(CAR X,V) THEN RETURN W;
- X:=CDR X;
- GO TO SCAN
- END;
- SYMBOLIC PROCEDURE TAYLORP U; NIL; %dummy for now;
- SYMBOLIC PROCEDURE INVOLVESQ(SQ,TERM);
- INVOLVESF(NUMR SQ,TERM) OR INVOLVESF(DENR SQ,TERM);
- SYMBOLIC PROCEDURE INVOLVESF(SF,TERM);
- IF DOMAINP SF OR NULL SF
- THEN NIL
- ELSE IF DEPENDSP(MVAR SF,TERM)
- THEN T
- ELSE INVOLVESF(LC SF,TERM) OR
- INVOLVESF(RED SF,TERM);
- ENDMODULE;
- MODULE DF2Q;
- EXPORTS DF2Q;
- IMPORTS ADDF,GCDF,MKSP,!*MULTF!*,QUOTF;
- COMMENT This module converts distributed forms to standard forms.
- We assume that results already have reduced powers, so
- that no power substitution is necessary;
- %TRIAL REPLACEMENT FOR DF2Q;
- SYMBOLIC PROCEDURE DF2Q P;
- % Converts distributed form P to standard quotient;
- BEGIN SCALAR N,D,GG,W;
- IF NULL P THEN RETURN NIL ./ 1;
- D:=DENR LC P;
- W:=RED P;
- WHILE NOT NULL W DO <<
- GG:=GCDF(D,DENR LC W); %GET DENOMINATOR OF ANSWER...;
- D:=!*MULTF!*(D,QUOTF(DENR LC W,GG));
- %..AS LCM OF DENOMS IN INPUT;
- W:=RED W >>;
- N:=NIL; %PLACE TO BUILD NUMERATOR OF ANSWER;
- WHILE NOT NULL P DO <<
- N:=ADDF(N,!*MULTF!*(XL2F(LPOW P,ZLIST,INDEXLIST),
- !*MULTF!*(NUMR LC P,QUOTF(D,DENR LC P))));
- P:=RED P >>;
- RETURN N ./ D
- END;
- SYMBOLIC PROCEDURE XL2F(L,Z,IL);
- % L is an exponent list from a D.F., Z is the Z-list,
- % IL is the list of indices.
- % Value is L converted to standard form. ;
- IF NULL Z THEN 1
- ELSE IF CAR L=0 THEN XL2F(CDR L,CDR Z,CDR IL)
- ELSE IF NOT ATOM CAR L THEN
- BEGIN SCALAR TEMP;
- IF CAAR L=0 THEN TEMP:= CAR IL
- ELSE TEMP:=LIST('PLUS,CAR IL,CAAR L);
- TEMP:=MKSP(LIST('EXPT,CAR Z,TEMP),1);
- RETURN !*MULTF!*(((TEMP .* 1) .+ NIL),
- XL2F(CDR L,CDR Z,CDR IL))
- END
- % ELSE IF MINUSP CAR L THEN ;
- % MULTSQ(INVSQ (((MKSP(CAR Z,-CAR L) .* 1) .+ NIL)), ;
- % XL2F(CDR L,CDR Z,CDR IL)) ;
- ELSE !*MULTF!*((MKSP(CAR Z,CAR L) .* 1) .+ NIL,
- XL2F(CDR L,CDR Z,CDR IL));
- ENDMODULE;
- MODULE DISTRIB;
- EXPORTS DFPRINTFORM,MULTBYARBPOWERS,NEGDF,QUOTDFCONST,SUB1IND,VP1,
- VP2,PLUSDF,MULTDF,MULTDFCONST,ORDDF;
- IMPORTS INTERR,ADDSQ,NEGSQ,EXPTSQ,SIMP,DOMAINP,MK!*SQ,ADDF,
- MULTSQ,INVSQ,MINUSP,MKSP,SUB1;
- %***********************************************************************
- % ROUTINES FOR MANIPULATING DISTRIBUTED FORMS.
- % NOTE:
- % THE EXPRESSIONS LT,RED,LC,LPOW HAVE BEEN USED ON DISTRIBUTED
- % FORMS AS THE LATTER'S STRUCTURE IS SUFFICIENTLY SIMILAR TO
- % S.F.'S. HOWEVER LC DF IS A S.Q. NOT A S.F. AND LPOW DF IS A
- % LIST OF THE EXPONENTS OF THE VARIABLES. THIS ALSO MAKES
- % LT DF DIFFERENT. RED DF IS D.F. AS EXPECTED.
- %**********************************************************************;
- SYMBOLIC PROCEDURE PLUSDF(U,V);
- % U and V are D.F.'s. Value is D.F. for U+V;
- IF NULL U THEN V
- ELSE IF NULL V THEN U
- ELSE IF LPOW U=LPOW V THEN
- (LAMBDA(X,Y); IF NULL NUMR X THEN Y ELSE (LPOW U .* X) .+ Y)
- (ADDSQ(LC U,LC V),PLUSDF(RED U,RED V))
- ELSE IF ORDDF(LPOW U,LPOW V) THEN LT U .+ PLUSDF(RED U,V)
- ELSE (LT V) .+ PLUSDF(U,RED V);
- SYMBOLIC PROCEDURE ORDDF(U,V);
- % U and V are the LPOW of a D.F. - i.e. the list of exponents ;
- % Value is true if LPOW U '>' LPOW V and false otherwise ;
- IF NULL U THEN IF NULL V THEN INTERR "ORDDF = CASE"
- ELSE INTERR "ORDDF V LONGER THAN U"
- ELSE IF NULL V THEN INTERR "ORDDF U LONGER THAN V"
- ELSE IF EXPTCOMPARE(CAR U,CAR V) THEN T
- ELSE IF EXPTCOMPARE(CAR V,CAR U) THEN NIL
- ELSE ORDDF(CDR U,CDR V);
- SYMBOLIC PROCEDURE EXPTCOMPARE(X,Y);
- IF ATOM X THEN IF ATOM Y THEN X>Y ELSE NIL
- ELSE IF ATOM Y THEN T
- ELSE CAR X > CAR Y;
- SYMBOLIC PROCEDURE NEGDF U;
- IF NULL U THEN NIL
- ELSE (LPOW U .* NEGSQ LC U) .+ NEGDF RED U;
- SYMBOLIC PROCEDURE MULTDF(U,V);
- % U and V are D.F.'s. Value is D.F. for U*V;
- % reduces squares of square-roots as it goes;
- IF NULL U OR NULL V THEN NIL
- ELSE BEGIN SCALAR Y;
- %use (a+b)*(c+d) = (a*c) + a*(c+d) + b*(c+d);
- Y:=MULTERM(LT U,LT V); %leading terms;
- Y:=PLUSDF(Y,MULTDF(RED U,V));
- Y:=PLUSDF(Y,MULTDF((LT U) .+ NIL,RED V));
- RETURN Y
- END;
- SYMBOLIC PROCEDURE MULTERM(U,V);
- %multiply two terms to give a D.F.;
- BEGIN SCALAR COEF;
- COEF:= SUBS2Q MULTSQ(CDR U,CDR V); %coefficient part;
- RETURN MULTDFCONST(COEF,MULPOWER(CAR U,CAR V))
- END;
- SYMBOLIC PROCEDURE MULPOWER(U,V);
- % u and v are exponent lists. multiply corresponding forms;
- BEGIN SCALAR R,S;
- R:=ADDEXPTSDF(U,V);
- IF NOT NULL SQRTLIST THEN S:=REDUCEROOTS(R,ZLIST);
- R:=(R .* (1 ./ 1)) .+ NIL;
- IF NOT (S=NIL) THEN R:=MULTDF(R,S);
- RETURN R
- END;
- SYMBOLIC PROCEDURE REDUCEROOTS(R,ZL);
- BEGIN SCALAR S;
- WHILE NOT NULL R DO <<
- IF EQCAR(CAR ZL,'SQRT) THEN
- S:=TRYREDUCTION(R,CAR ZL,S);
- R:=CDR R; ZL:=CDR ZL >>;
- RETURN S
- END;
- SYMBOLIC PROCEDURE TRYREDUCTION(R,VAR,S);
- BEGIN SCALAR X;
- X:=CAR R; %CURRENT EXPONENT;
- IF NOT ATOM X THEN << R:=X; X:=CAR R >>; %NUMERIC PART;
- IF (X=0) OR (X=1) THEN RETURN S; %NO REDUCTION POSSIBLE;
- X:=DIVIDE(X,2);
- RPLACA(R,CDR X); %REDUCE EXPONENT AS REDORDED;
- X:=CAR X;
- VAR:=SIMP CADR VAR; %SQRT ARG AS A S Q;
- VAR:=EXPTSQ(VAR,X);
- X:=MULTDFCONST(1 ./ DENR VAR,F2DF NUMR VAR); %DISTRIBUTE;
- IF S=NIL THEN S:=X
- ELSE S:=MULTDF(S,X);
- RETURN S
- END;
- SYMBOLIC PROCEDURE ADDEXPTSDF(X,Y);
- % X and Y are LPOW's of D.F. Value is list of sum of exponents;
- IF NULL X THEN IF NULL Y THEN NIL ELSE INTERR "X TOO LONG"
- ELSE IF NULL Y THEN INTERR "Y TOO LONG"
- ELSE EXPTPLUS(CAR X,CAR Y).ADDEXPTSDF(CDR X,CDR Y);
- SYMBOLIC PROCEDURE EXPTPLUS(X,Y);
- IF ATOM X THEN IF ATOM Y THEN X+Y ELSE LIST (X+CAR Y)
- ELSE IF ATOM Y THEN LIST (CAR X +Y)
- ELSE INTERR "BAD EXPONENT SUM";
- SYMBOLIC PROCEDURE MULTDFCONST(X,U);
- % X is S.Q. not involving Z variables of D.F. U. Value is D.F.;
- % for X*U;
- IF (NULL U) OR (NULL NUMR X) THEN NIL
- ELSE LPOW U .* SUBS2Q MULTSQ(X,LC U) .+ MULTDFCONST(X,RED U);
- SYMBOLIC PROCEDURE F2DF P;
- % P is standard form. Value is P in D.F.;
- IF DOMAINP P THEN DFCONST(P ./ 1)
- ELSE IF MVAR P MEMBER ZLIST THEN
- PLUSDF(MULTDF(VP2DF(MVAR P,TDEG LT P,ZLIST),F2DF LC P),
- F2DF RED P)
- ELSE PLUSDF(MULTDFCONST(((LPOW P .* 1) .+ NIL) ./ 1,F2DF LC P),
- F2DF RED P);
- SYMBOLIC PROCEDURE VP1(VAR,DEGG,Z);
- % Takes VAR and finds it in Z (=list), raises it to power DEGG and puts;
- % the result in exponent list form for use in a distributed form.;
- IF NULL Z THEN INTERR "VAR NOT IN Z-LIST AFTER ALL"
- ELSE IF VAR=CAR Z THEN DEGG.VP2 CDR Z
- ELSE 0 . VP1(VAR,DEGG,CDR Z);
- SYMBOLIC PROCEDURE VP2 Z;
- % Makes exponent list of zeroes;
- IF NULL Z THEN NIL
- ELSE 0 . VP2 CDR Z;
- SYMBOLIC PROCEDURE VP2DF(VAR,EXPRN,Z);
- % Makes VAR**EXPRN into exponent list and then converts the resulting
- % power into a distributed form.
- % special care with square-roots;
- IF EQCAR(VAR,'SQRT) AND EXPRN>1 THEN
- MULPOWER(VP1(VAR,EXPRN,Z),VP2 Z)
- ELSE (VP1(VAR,EXPRN,Z) .* (1 ./ 1)) .+ NIL;
- SYMBOLIC PROCEDURE DFCONST Q;
- % Makes a distributed form from standard quotient constant Q;
- IF NUMR Q=NIL THEN NIL
- ELSE ((VP2 ZLIST) .* Q) .+ NIL;
- %DF2Q MOVED TO A SECTION OF ITS OWN;
- SYMBOLIC PROCEDURE DF2PRINTFORM P;
- %CONVERT TO A STANDARD FORM GOOD ENOUGH FOR PRINTING;
- IF NULL P THEN NIL
- ELSE BEGIN
- SCALAR MV,CO;
- MV:=XL2Q(LPOW P,ZLIST,INDEXLIST);
- IF MV=(1 ./ 1) THEN <<
- CO:=LC P;
- IF DENR CO=1 THEN RETURN ADDF(NUMR CO,
- DF2PRINTFORM RED P);
- CO:=MKSP(MK!*SQ CO,1);
- RETURN (CO .* 1) .+ DF2PRINTFORM RED P >>;
- CO:=LC P;
- IF NOT (DENR CO=1) THEN MV:=MULTSQ(MV,1 ./ DENR CO);
- MV:=MKSP(MK!*SQ MV,1) .* NUMR CO;
- RETURN MV .+ DF2PRINTFORM RED P
- END;
- SYMBOLIC PROCEDURE XL2Q(L,Z,IL);
- % L is an exponent list from a D.F., Z is the Z-list,
- % IL is the list of indices.
- % Value is L converted to standard quotient. ;
- IF NULL Z THEN 1 ./ 1
- ELSE IF CAR L=0 THEN XL2Q(CDR L,CDR Z,CDR IL)
- ELSE IF NOT ATOM CAR L THEN
- BEGIN SCALAR TEMP;
- IF CAAR L=0 THEN TEMP:= CAR IL
- ELSE TEMP:=LIST('PLUS,CAR IL,CAAR L);
- TEMP:=MKSP(LIST('EXPT,CAR Z,TEMP),1);
- RETURN MULTSQ(((TEMP .* 1) .+ NIL) ./ 1,
- XL2Q(CDR L,CDR Z,CDR IL))
- END
- ELSE IF MINUSP CAR L THEN
- MULTSQ(INVSQ (((MKSP(CAR Z,-CAR L) .* 1) .+ NIL) ./ 1),
- XL2Q(CDR L,CDR Z,CDR IL))
- ELSE MULTSQ(((MKSP(CAR Z,CAR L) .* 1) .+ NIL) ./ 1,
- XL2Q(CDR L,CDR Z,CDR IL));
- SYMBOLIC PROCEDURE MULTBYARBPOWERS U;
- % Multiplies the ordinary D.F., U, by arbitrary powers
- % of the z-variables;
- % i-1 j-1 k-1
- % i.e. x z z ... so result is D.F. with the exponent list
- % 1 2
- % appropriately altered to contain list elements instead of numeric
- % ones;
- IF NULL U THEN NIL
- ELSE ((ADDARBEXPTSDF LPOW U) .* LC U) .+ MULTBYARBPOWERS RED U;
- SYMBOLIC PROCEDURE ADDARBEXPTSDF X;
- % Adds the arbitrary powers to powers in exponent list, X, to produce
- % new exponent list. e.g. 3 -> (2) to represent x**3 now becoming:
- % 3 i-1 i+2
- % x * x = x . ;
- IF NULL X THEN NIL
- ELSE LIST EXPTPLUS(CAR X,-1) . ADDARBEXPTSDF CDR X;
- ENDMODULE;
- MODULE DIVIDE;
- EXPORTS FQUOTF,TESTDIVDF,DFQUOTDF;
- IMPORTS DF2Q,F2DF,GCDF,INTERR,MULTDF,NEGDF,PLUSDF,PRINTDF,PRINTSF,
- QUOTF,MULTSQ,INVSQ,NEGSQ;
- %EXACT DIVISION OF STANDARD FORMS TO GIVE A STANDARD QUOTIENT;
- %INTENDED FOR DIVIDING OUT KNOWN FACTORS AS PRODUCED BY THE;
- %INTEGRATION PROGRAM. HORRIBLE AND SLOW, I EXPECT!!;
- SYMBOLIC PROCEDURE DFQUOTDF(A,B);
- BEGIN SCALAR RESIDUE;
- IF (!*TRINT OR !*TRDIV) THEN <<
- PRINTC "DFQUOTDF CALLED ON ";
- PRINTDF A; PRINTDF B>>;
- A:=DFQUOTDF1(A,B);
- IF (!*TRINT OR !*TRDIV) THEN << PRINTC "QUOTIENT GIVEN AS ";
- PRINTDF A >>;
- IF NOT NULL RESIDUE THEN BEGIN
- SCALAR GRES,W;
- IF !*TRINT OR !*TRDIV THEN <<
- PRINTC "RESIDUE IN DFQUOTDF =";
- PRINTDF RESIDUE;
- PRINTC "WHICH SHOULD BE ZERO";
- W:=RESIDUE;
- GRES:=NUMR LC W; W:=RED W;
- WHILE NOT NULL W DO <<
- GRES:=GCDF(GRES,NUMR LC W);
- W:=RED W >>;
- PRINTC "I.E. THE FOLLOWING VANISHES";
- PRINTSF GRES>>;
- INTERR "NON-EXACT DIVISION DUE TO A LOG TERM"
- END;
- RETURN A
- END;
- SYMBOLIC PROCEDURE FQUOTF(A,B);
- % INPUT: A AND B STANDARD QUOTIENTS WITH (A/B) AN EXACT;
- % DIVISION WITH RESPECT TO THE VARIABLES IN ZLIST, ;
- % BUT NOT NECESSARILY OBVIOUSLY SO. THE 'NON-OBVIOUS' PROBLEMS;
- % WILL BE BECAUSE OF (E.G.) SQUARE-ROOT SYMBOLS IN B;
- % OUTPUT: STANDARD QUOTIENT FOR (A/B);
- % (PRINTS MESSAGE IF REMAINDER IS NOT 'CLEARLY' ZERO;
- % A MUST NOT BE ZERO;
- BEGIN SCALAR T1;
- IF NULL A THEN INTERR "A=0 IN FQUOTF";
- T1:=QUOTF(A,B); %TRY IT THE EASY WAY;
- IF NOT NULL T1 THEN RETURN T1 ./ 1; %OK;
- RETURN DF2Q DFQUOTDF(F2DF A,F2DF B)
- END;
- SYMBOLIC PROCEDURE DFQUOTDF1(A,B);
- BEGIN SCALAR Q;
- IF NULL B THEN INTERR "ATTEMPT TO DIVIDE BY ZERO";
- Q:=SQRTLIST; %REMOVE SQRTS FROM DENOMINATOR, MAYBE;
- WHILE NOT NULL Q DO BEGIN
- SCALAR CONJ;
- CONJ:=CONJSQRT(B,CAR Q); %CONJUGATE WRT GIVEN SQRT;
- IF NOT (B=CONJ) THEN <<
- A:=MULTDF(A,CONJ);
- B:=MULTDF(B,CONJ) >>;
- Q:=CDR Q END;
- Q:=DFQUOTDF2(A,B);
- RESIDUE:=REVERSEWOC RESIDUE;
- RETURN Q
- END;
- SYMBOLIC PROCEDURE DFQUOTDF2(A,B);
- %AS ABOVE BUT A AND B ARE DISTRIBUTED FORMS, AS IS THE RESULT;
- IF NULL A THEN NIL
- ELSE BEGIN SCALAR XD,LCD;
- XD:=XPDIFF(LPOW A,LPOW B);
- IF XD='FAILED THEN <<
- XD:=LT A; A:=RED A;
- RESIDUE:=XD .+ RESIDUE;
- RETURN DFQUOTDF2(A,B) >>;
- LCD:=SUBS2Q MULTSQ(LC A,INVSQ LC B);
- IF NULL NUMR LCD THEN RETURN DFQUOTDF2(RED A,B);
- LCD := XD .* LCD;
- XD:=PLUSDF(A,MULTDF(NEGDF (LCD .+ NIL),B));
- IF XD AND (LPOW XD = LPOW A
- OR XPDIFF(LPOW XD,LPOW B) = 'FAILED)
- THEN <<IF !*TRINT OR !*TRDIV
- THEN <<PRINTC "DFQUOTDF TROUBLE:"; PRINTDF XD>>;
- XD := ROOTEXTRACTDF XD;
- IF !*TRINT OR !*TRDIV THEN PRINTDF XD>>;
- RETURN LCD .+ DFQUOTDF2(XD,B)
- END;
- SYMBOLIC PROCEDURE ROOTEXTRACTDF U;
- IF NULL U THEN NIL
- ELSE BEGIN SCALAR V;
- V := RESIMP ROOTEXTRACTSQ LC U;
- RETURN IF NULL NUMR V THEN ROOTEXTRACTDF RED U
- ELSE (LPOW U .* V) .+ ROOTEXTRACTDF RED U
- END;
- SYMBOLIC PROCEDURE ROOTEXTRACTSQ U;
- IF NULL NUMR U THEN U
- ELSE ROOTEXTRACTF NUMR U ./ ROOTEXTRACTF DENR U;
- SYMBOLIC PROCEDURE ROOTEXTRACTF V;
- IF DOMAINP V THEN V
- ELSE BEGIN SCALAR U,R,C,X,P;
- U := MVAR V; P := LDEG V;
- R := ROOTEXTRACTF RED V;
- C := ROOTEXTRACTF LC V;
- IF NULL C THEN RETURN R
- ELSE IF ATOM U THEN RETURN (LPOW V .* C) .+ R
- ELSE IF CAR U EQ 'SQRT
- OR CAR U EQ 'EXPT AND EQCAR(CADDR U,'QUOTIENT)
- AND CAR CDADDR U = 1 AND NUMBERP CADR CDADDR U
- THEN <<P := DIVIDE(P,IF CAR U EQ 'SQRT THEN 2
- ELSE CADR CDADDR U);
- IF CAR P = 0
- THEN RETURN IF NULL C THEN R ELSE (LPOW V .* C) .+ R
- ELSE IF NUMBERP CADR U
- THEN <<C := MULTD(CADR U ** CAR P,C); P := CDR P>>
- ELSE <<X := SIMPEXPT LIST(CADR U,CAR P);
- IF DENR X = 1
- THEN <<C := MULTF(NUMR X,C); P := CDR P>>>>>>;
- RETURN IF P=0 THEN ADDF(C,R)
- ELSE IF NULL C THEN R
- ELSE ((U TO P) .* C) .+ R
- END;
- PUT('DF,'SIMPFN,'SIMPDF!*);
- SYMBOLIC PROCEDURE SIMPDF!* U;
- BEGIN SCALAR V,V1;
- V:=SIMPDF U;
- V1:=ROOTEXTRACTSQ V;
- IF NOT(V1=V) THEN RETURN RESIMP V1
- ELSE RETURN V
- END;
- SYMBOLIC PROCEDURE XPDIFF(A,B);
- %RESULT IS LIST A-B, OR 'FAILED' IF A MEMBER OF THIS WOULD BE NEGATIVE;
- IF NULL A THEN IF NULL B THEN NIL
- ELSE INTERR "B TOO LONG IN XPDIFF"
- ELSE IF NULL B THEN INTERR "A TOO LONG IN XPDIFF"
- ELSE IF CAR B>CAR A THEN 'FAILED
- ELSE (LAMBDA R;
- IF R='FAILED THEN 'FAILED
- ELSE (CAR A-CAR B) . R) (XPDIFF(CDR A,CDR B));
- SYMBOLIC PROCEDURE CONJSQRT(B,VAR);
- %SUBST(VAR=-VAR,B);
- IF NULL B THEN NIL
- ELSE CONJTERM(LPOW B,LC B,VAR) .+ CONJSQRT(RED B,VAR);
-
- SYMBOLIC PROCEDURE CONJTERM(XL,COEF,VAR);
- %DITTO BUT WORKING ON A TERM;
- IF INVOLVESP(XL,VAR,ZLIST) THEN XL .* NEGSQ COEF
- ELSE XL .* COEF;
-
- SYMBOLIC PROCEDURE INVOLVESP(XL,VAR,ZL);
- %CHECK IF EXPONENT LIST HAS NON-ZERO POWER FOR VARIABLE;
- IF NULL XL THEN INTERR "VAR NOT FOUND IN INVOLVESP"
- ELSE IF CAR ZL=VAR THEN (NOT ZEROP CAR XL)
- ELSE INVOLVESP(CDR XL,VAR,CDR ZL);
- ENDMODULE;
- MODULE DRIVER;
- EXPORTS INTEGRATESQ,SIMPINT,PURGE,SIMPINT1;
- IMPORTS ALGEBRAICCASE,ALGFNPL,FINDZVARS,GETVARIABLES,INTERR,PRINTSQ,
- TRANSCENDENTALCASE,VARSINLIST,KERNP,SIMPCAR,PREPSQ,MKSQ,SIMP,
- OPMTCH,FORMLNR;
- %FORM IS INT(EXPR,VAR,X1,X2,...);
- %MEANING IS INTEGRATE EXPR WRT VAR, GIVEN THAT THE RESULT MAY;
- %CONTAIN LOGS OF X1,X2,...;
- % X1, ETC ARE INTENDED FOR USE WHEN THE SYSTEM HAS TO BE HELPED;
- % IN THE CASE THAT EXPR IS ALGEBRAIC;
- SYMBOLIC PROCEDURE SIMPINT U;
- % Simplify an integral, links up with general prefix mode system;
- BEGIN SCALAR EXPRESSION,VARIABLE,TT,LOGLIST,W,!*GCD,!*MCD,!*EXP,
- !*PURERISCH,!*SQRT,!*STRUCTURE;
- % ARGUMENT IS A LIST OF TWO ELEMENTS, WHICH ARE PREFIX FORMS;
- % OF THE INTEGRAND AND VARIABLE OF INTEGRATION;
- !*GCD:=T;
- !*MCD:=T;
- !*EXP:=T;
- !*SQRT:=T;
- !*STRUCTURE := T;
- VARIABLE:=CDR U;
- EXPRESSION:=SIMPP CAR U; %CONVERT INTEGRAND INTO A SQ;
- IF NULL VARIABLE THEN GO TO NOTENOUGHARGS;
- W:=CDR VARIABLE;
- VARIABLE:= !*Q2K SIMPP CAR VARIABLE; %CONVERT VARIABLE;
- %NOW ARGUMENTS HAVE BEEN CHECKED. START WORK;
- LOGLIST:=MAPCAR(W,FUNCTION SIMPP);
- U:=ERRORSET('(INTEGRATESQ EXPRESSION VARIABLE LOGLIST),
- NIL,!*BACKTRACE);
- IF NOT ATOM U THEN RETURN CAR U; %INTEGRATION OK;
- RETURN SIMPINT1(EXPRESSION . VARIABLE.W);
- % LEAVE IT FORMAL & LINEARISED;
- NOTENOUGHARGS: INTERR "NOT ENOUGH ARGS FOR INT";
- TOOMANYARGS: INTERR "TOO MANY ARGS FOR INT"
- END;
- SYMBOLIC PROCEDURE SIMPP U;
- %converts U to canonical form. Resimplifies if U is a *sq form;
- IF EQCAR(U,'!*SQ) THEN RESIMP CADR U ELSE SIMP U;
- PUT('INT,'SIMPFN,'SIMPINT);
- SYMBOLIC PROCEDURE INTEGRATESQ(INTEGRAND,VAR,XLOGS);
- BEGIN SCALAR VARLIST,ZLIST;
- IF !*TRINT THEN <<
- PRINTC "INTEGRAND IS...";
- PRINTSQ INTEGRAND >>;
- VARLIST:=GETVARIABLES INTEGRAND;
- VARLIST:=VARSINLIST(XLOGS,VARLIST); %IN CASE MORE EXIST IN XLOGS;
- ZLIST:=FINDZVARS(VARLIST,LIST VAR,VAR,NIL); %%IMPORTSANT KERNELS;
- %the next section causes problems with nested exponentials or logs;
- BEGIN SCALAR OLDZLIST;
- WHILE OLDZLIST NEQ ZLIST DO <<
- OLDZLIST:=ZLIST;
- FOREACH ZZ IN OLDZLIST DO
- ZLIST:=FINDZVARS(PSEUDODIFF(ZZ,VAR),ZLIST,VAR,T) >>
- END;
- IF !*TRINT THEN <<
- PRINTC "WITH 'NEW' FUNCTIONS :";
- PRINT ZLIST >>;
- IF !*PURERISCH AND NOT ALLOWEDFNS ZLIST
- THEN RETURN SIMPINT1 (INTEGRAND . VAR.NIL);
- % IF IT IS NOT SUITABLE FOR RISCH;
- VARLIST:=PURGE(ZLIST,VARLIST);
- % NOW ZLIST IS LIST OF THINGS THAT DEPEND ON X, AND VARLIST IS LIST;
- % OF CONSTANT KERNELS IN INTEGRAND;
- RETURN TRANSCENDENTALCASE(INTEGRAND,VAR,XLOGS,ZLIST,VARLIST)
- END;
- SYMBOLIC PROCEDURE PSEUDODIFF(A,VAR);
- IF ATOM A THEN NIL
- ELSE IF CAR A MEMQ '(EXPT PLUS TIMES QUOTIENT LOG SQRT)
- THEN BEGIN SCALAR AA,BB;
- FOREACH ZZ IN CDR A DO <<
- BB:=PSEUDODIFF(ZZ,VAR);
- IF AA THEN AA:=BB . AA ELSE BB >>;
- RETURN AA
- END
- ELSE LIST PREPSQ SIMPDF(LIST(A,VAR));
- MKOP 'INT!*;
- SYMBOLIC PROCEDURE SIMPINT1 U;
- BEGIN SCALAR V,!*SQRT;
- U := 'INT . PREPSQ CAR U . CDR U;
- IF (V := FORMLNR U) NEQ U
- THEN IF !*NOLNR THEN <<
- V:= SIMP SUBST('INT!*,'INT,V);
- RETURN REMAKESF NUMR V ./ REMAKESF DENR V>>
- ELSE <<!*NOLNR:= NIL . !*NOLNR;
- U:=ERRORSET(LIST('SIMP,MKQUOTE V),NIL,!*BACKTRACE);
- IF PAIRP U THEN V:=CAR U;
- !*NOLNR:= CDR !*NOLNR;
- RETURN V>>;
- RETURN IF (V := OPMTCH U) THEN SIMP V ELSE MKSQ(U,1)
- END;
- SYMBOLIC PROCEDURE REMAKESF U;
- %remakes standard form U, substituting operator INT for INT!*;
- IF DOMAINP U THEN U
- ELSE ADDF(MULTPF(IF EQCAR(MVAR U,'INT!*)
- THEN MKSP('INT . CDR MVAR U,LDEG U)
- ELSE LPOW U,REMAKESF LC U),
- REMAKESF RED U);
- SYMBOLIC PROCEDURE ALLOWEDFNS U;
- IF NULL U
- THEN T
- ELSE IF ATOM CAR U OR
- FLAGP(CAAR U,'TRANSCENDENTAL)
- THEN ALLOWEDFNS CDR U
- ELSE NIL;
- SYMBOLIC PROCEDURE PURGE(A,B);
- IF NULL A THEN B
- ELSE IF NULL B THEN NIL
- ELSE PURGE(CDR A,DELETE(CAR A,B));
- ENDMODULE;
- MODULE D3D4;
- EXPORTS CUBIC,QUARTIC;
- IMPORTS COVECDF,CUBEROOTF,NTH,FORCEAZERO,MAKEPOLYDF,MULTDF,MULTDFCONST,
- !*MULTF!*,NEGDF,PLUSDF,PRINTDF,PRINTSF,QUADRATIC,SQRTF,VP1,VP2,ADDF,
- NEGF;
- %SPLITTING OF CUBICS AND QUARTICS;
- SYMBOLIC PROCEDURE CUBIC(POL,VAR,RES);
- %SPLIT THE UNIVARIATE (WRT Z-VARS) CUBIC POL, AT LEAST IF A;
- %CHANGE OF ORIGIN PUTS IT IN THE FORM (X-A)**3-B=0;
- BEGIN SCALAR A,B,C,D,V,SHIFT,P,Q,DSC;
- V:=COVECDF(POL,VAR,3);
- SHIFT:=FORCEAZERO(V,3); %MAKE COEFF X**2 VANISH;
- %ALSO CHECKS UNIVARIATE;
- % IF SHIFT='FAILED THEN GO TO PRIME;
- A:=GETV(V,3); B:=GETV(V,2); %=0, I HOPE!;
- C:=GETV(V,1); D:=GETV(V,0);
- IF !*TRINT THEN << PRINTC "CUBIC HAS COEFFICIENTS";
- PRINTSF A; PRINTSF B;
- PRINTSF C; PRINTSF D >>;
- IF NOT NULL C THEN <<
- PRINTC "CUBIC TOO HARD TO SPLIT";
- GO TO EXIT >>;
- A:=CUBEROOTF(A); %CAN'T EVER FAIL;
- D:=CUBEROOTF(D);
- IF !*TRINT THEN << PRINTC "CUBE ROOTS OF A AND D ARE";
- PRINTSF A; PRINTSF D>>;
- %NOW A*(X+SHIFT)+D IS A FACTOR OF POL;
- %CREATE X+SHIFT IN P;
- P:=(VP2 ZLIST .* SHIFT) .+ NIL;
- P:=(VP1(VAR,1,ZLIST) .* (1 ./ 1)) .+ P; %(X+SHIFT);
- B:=NIL;
- B:=(VP2 ZLIST .* (D ./ 1)) .+ B;
- B:=PLUSDF(B,MULTDFCONST(A ./ 1,P));
- B:=MAKEPOLYDF B; %GET RID OF DENOMINATOR;
- IF !*TRINT THEN << PRINTC "ONE FACTOR OF THE CUBIC IS";
- PRINTDF B >>;
- RES:=('LOG . B) . RES;
- %NOW FORM THE (QUADRATIC) COFACTOR;
- B:=(VP2 ZLIST .* (!*F2POL !*MULTF!*(D,D) ./ 1)) .+ NIL;
- B:=PLUSDF(B,MULTDFCONST(NEGF !*F2POL !*MULTF!*(A,D) ./ 1,P));
- B:=PLUSDF(B,MULTDFCONST(!*F2POL !*MULTF!*(A,A) ./ 1,
- MULTDF(P,P)));
- RETURN QUADRATIC(MAKEPOLYDF B,VAR,RES); %DEAL WITH WHAT IS LEFT;
- PRIME:
- PRINTC "THE FOLLOWING CUBIC DOES NOT SPLIT";
- EXIT:
- PRINTDF POL;
- RETURN ('LOG . POL) . RES
- END;
- FLUID '(KNOWNDISCRIMSIGN);
- SYMBOLIC PROCEDURE QUARTIC(POL,VAR,RES);
- %SPLITS UNIVARIATE (WRT Z-VARS) QUARTICS THAT CAN BE WRITTEN;
- %IN THE FORM (X-A)**4+B*(X-A)**2+C;
- BEGIN SCALAR A,B,C,D,E,V,SHIFT,P,Q,P1,P2,DSC;
- V:=COVECDF(POL,VAR,4);
- SHIFT:=FORCEAZERO(V,4); %MAKE COEFF X**3 VANISH;
- % IF SHIFT='FAILED THEN GO TO PRIME;
- A:=GETV(V,4); B:=GETV(V,3); %=0, I HOPE!;
- C:=GETV(V,2); D:=GETV(V,1);
- E:=GETV(V,0);
- IF !*TRINT THEN << PRINTC "QUARTIC HAS COEFFICIENTS";
- PRINTSF A; PRINTSF B;
- PRINTSF C; PRINTSF D;
- PRINTSF E >>;
- IF NOT NULL D THEN << PRINTC "QUARTIC TOO HARD TO SPLIT";
- GO TO EXIT >>;
- B:=C; C:=E; %SQUASH UP THE NOTATION;
- IF KNOWNDISCRIMSIGN EQ 'NEGATIVE THEN GO TO COMPLEX;
- DSC := !*F2POL ADDF(MULTF(B,B),MULTF(-4,MULTF(A,C)));
- P2 := MINUSF C;
- IF NOT P2 AND MINUSF DSC THEN GO TO COMPLEX;
- P1 := NULL B OR MINUSF B;
- IF NOT P1 THEN IF P2 THEN P1 := T ELSE P2 := T;
- P1 := IF P1 THEN 'POSITIVE ELSE 'NEGATIVE;
- P2 := IF P2 THEN 'NEGATIVE ELSE 'POSITIVE;
- A := SQRTF A;
- DSC := SQRTF DSC;
- E := INVSQ(ADDF(A,A) ./ 1);
- D := MULTSQ(ADDF(B,NEGF DSC) ./ 1,E);
- E := MULTSQ(ADDF(B,DSC) ./ 1,E);
- IF !*TRINT
- THEN <<PRINTC "QUADRATIC FACTORS WILL HAVE COEFFICIENTS";
- PRINTSF A; PRINT 0; PRINTSQ D;
- PRINTC "OR"; PRINTSQ E>>;
- P := (VP2 ZLIST .* SHIFT) .+ NIL;
- P := (VP1(VAR,1,ZLIST) .* (1 ./ 1)) .+ P; %(X+SHIFT);
- Q := MULTDF(P,P); %SQUARE OF SAME;
- Q := MULTDFCONST(A ./ 1,Q);
- P := PLUSDF(Q,(VP2 ZLIST .* D) .+ NIL);
- Q := PLUSDF(Q,(VP2 ZLIST .* E) .+ NIL);
- IF !*TRINT
- THEN <<PRINTC "ALLOWING FOR CHANGE OF ORIGIN:";
- PRINTDF P; PRINTDF Q>>;
- KNOWNDISCRIMSIGN := P1;
- RES := QUADRATIC(P,VAR,RES);
- KNOWNDISCRIMSIGN := P2;
- RES := QUADRATIC(Q,VAR,RES);
- GO TO QUARTICDONE;
- COMPLEX:
- A:=SQRTF(A);
- C:=SQRTF(C);
- B:=ADDF(!*F2POL !*MULTF!*(2,!*MULTF!*(A,C)),NEGF B);
- B:=SQRTF B;
- %NOW A*(X+SHIFT)**2 (+/-) B*(X+SHIFT) + C IS A FACTOR;
- IF !*TRINT
- THEN << PRINTC "QUADRATIC FACTORS WILL HAVE COEFFICIENTS";
- PRINTSF A; PRINTSF B; PRINTSF C>>;
- P:=(VP2 ZLIST .* SHIFT) .+ NIL;
- P:=(VP1(VAR,1,ZLIST) .* (1 ./ 1)) .+ P; %(X+SHIFT);
- Q:=MULTDF(P,P); %SQUARE OF SAME;
- P:=MULTDFCONST(B ./ 1,P);
- Q:=MULTDFCONST(A ./ 1,Q);
- Q:=PLUSDF(Q,(VP2 ZLIST .* (C ./ 1)) .+ NIL);
- IF !*TRINT THEN <<
- PRINTC "ALLOWING FOR CHANGE OF ORIGIN, P (+/-) Q WITH P,Q=";
- PRINTDF P; PRINTDF Q>>;
- %NOW P+Q AND P-Q ARE THE FACTORS OF THE QUARTIC;
- KNOWNDISCRIMSIGN := 'NEGATIVE;
- RES:=QUADRATIC(PLUSDF(Q,P),VAR,RES);
- RES:=QUADRATIC(PLUSDF(Q,NEGDF P),VAR,RES);
- QUARTICDONE:
- KNOWNDISCRIMSIGN := NIL;
- IF !*TRINT THEN PRINTC "QUARTIC DONE";
- RETURN RES;
- PRIME:
- PRINTC "THE FOLLOWING QUARTIC DOES NOT SPLIT";
- EXIT:
- PRINTDF POL;
- RETURN ('LOG . POL) . RES
- END;
- ENDMODULE;
- MODULE FACTR;
- EXPORTS INT!-FAC,VAR2DF;
- IMPORTS CUBIC,DF2Q,F2DF,INTERR,MULTDF,PRINTDF,QUADRATIC,QUARTIC,UNIFAC,
- UNIFORM,VP1,VP2,SUB1;
- SYMBOLIC PROCEDURE INT!-FAC X;
- %INPUT: PRIMITIVE, SQUARE-FREE POLYNOMIAL (S.FORM);
- %OUTPUT:
- % LIST OF 'FACTORS' WRT ZLIST;
- % EACH ITEM IN THIS LIST IS EITHER;
- % LOG . SQ;
- % OR ATAN . SQ;
- % AND THESE LOGS AND ARCTANS ARE ALL THAT IS NEEDED IN THE;
- % INTEGRATION OF 1/(ARGUMENT);
- BEGIN SCALAR RES,POL,DSET,VAR,DEGREE,VARS;
- POL:=F2DF X; %CONVERT TO DISTRIBUTED FORM;
- DSET:=DEGREESET(POL);
- %NOW EXTRACT FACTORS OF THE FORM 'X' OR 'LOG(X)' ETC;
- %THESE CORRESPOND TO ITEMS IN DSET WITH A NON-ZERO CDR;
- BEGIN SCALAR ZL,DS;
- ZL:=ZLIST; DS:=DSET;
- WHILE NOT NULL DS DO <<
- IF ONEP CDAR DS THEN <<
- RES:=('LOG . VAR2DF(CAR ZL,1,ZLIST)) . RES;
- %RECORD IN ANSWER;
- POL:=MULTDF(VAR2DF(CAR ZL,-1,ZLIST),POL);
- %DIVIDE OUT;
- IF !*TRINT THEN << PRINTC "TRIVIAL FACTOR FOUND";
- PRINTDF CDAR RES>>;
- RPLACA(DS,SUB1 CAAR DS . CDAR DS) >>
- ELSE IF NULL ZEROP CDAR DS THEN
- INTERR "REPEATED TRIVIAL FACTOR IN ARG TO FACTOR";
- ZL:=CDR ZL; DS:=CDR DS >>;
- END; %SINGLE TERM FACTORS ALL REMOVED NOW;
- DSET:=MAPCAR(DSET,FUNCTION CAR); %GET LOWER BOUNDS;
- IF !*TRINT
- THEN PRINTC ("UPPER BOUNDS OF REMAINING FACTORS ARE NOW: " .
- DSET);
- IF DSET=VP2 ZLIST THEN GO TO FINISHED; %THING LEFT IS CONSTANT;
- BEGIN SCALAR DS,ZL;
- VAR:=CAR ZLIST; DEGREE:=CAR DSET;
- IF NOT ZEROP DEGREE THEN VARS:=VAR . VARS;
- DS:=CDR DSET; ZL:=CDR ZLIST;
- WHILE NOT NULL DS DO <<
- IF NOT ZEROP CAR DS THEN <<
- VARS:=CAR ZL . VARS;
- IF ZEROP DEGREE OR DEGREE>CAR DS THEN <<
- VAR:=CAR ZL; DEGREE:=CAR DS >> >>;
- ZL:=CDR ZL; DS:=CDR DS >>
- END;
- % NOW VAR IS VARIABLE THAT THIS POLY INVOLVES TO LOWEST DEGREE;
- % DEGREE IS THE DEGREE OF THE POLY IN SAME VARIABLE;
- IF !*TRINT
- THEN PRINTC ("BEST VAR IS " . VAR . "WITH EXPONENT " .
- DEGREE);
- IF ONEP DEGREE THEN <<
- RES:=('LOG . POL) . RES; %CERTAINLY IRREDUCIBLE;
- IF !*TRINT
- THEN << PRINTC "THE FOLLOWING IS CERTAINLY IRREDUCIBLE";
- PRINTDF POL>>;
- GO TO FINISHED >>;
- IF DEGREE=2 THEN <<
- IF !*TRINT THEN << PRINTC "QUADRATIC";
- PRINTDF POL>>;
- RES:=QUADRATIC(POL,VAR,RES);
- GO TO FINISHED >>;
- DSET:=UNIFORM(POL,VAR);
- IF NOT (DSET='FAILED) THEN <<
- IF !*TRINT THEN << PRINTC "UNIVARIATE POLYNOMIAL";
- PRINTDF POL >>;
- RES:=UNIFAC(DSET,VAR,DEGREE,RES);
- GO TO FINISHED >>;
- IF NOT NULL CDR VARS THEN GO TO NASTY; %ONLY TRY UNIVARIATE NOW;
- IF DEGREE=3 THEN <<
- IF !*TRINT THEN << PRINTC "CUBIC";
- PRINTDF POL>>;
- RES:=CUBIC(POL,VAR,RES);
- % IF !*OVERLAYMODE
- % THEN EXCISE 'D3D4;
- GO TO FINISHED >>;
- IF DEGREE=4 THEN <<
- IF !*TRINT THEN << PRINTC "QUARTIC";
- PRINTDF POL>>;
- RES:=QUARTIC(POL,VAR,RES);
- % IF !*OVERLAYMODE
- % THEN EXCISE 'D3D4;
- GO TO FINISHED>>;
- %ELSE ABANDON HOPE AND HAND BACK SOME RUBBISH.;
- NASTY:
- RES:=('LOG . POL) . RES;
- PRINTC
- "THE FOLLOWING POLYNOMIAL HAS NOT BEEN PROPERLY FACTORED";
- PRINTDF POL;
- GO TO FINISHED;
- FINISHED: %RES IS A LIST OF D.F. S AS REQUIRED;
- POL:=NIL; %CONVERT BACK TO STANDARD FORMS;
- WHILE NOT NULL RES DO
- BEGIN SCALAR TYPE,ARG;
- TYPE:=CAAR RES; ARG:=CDAR RES;
- ARG:=DF2Q ARG;
- IF TYPE='LOG THEN RPLACD(ARG,1);
- POL:=(TYPE . ARG) . POL;
- RES:=CDR RES END;
- RETURN POL
- END;
- SYMBOLIC PROCEDURE VAR2DF(VAR,N,ZLIST);
- ((VP1(VAR,N,ZLIST) .* (1 ./ 1)) .+ NIL);
- SYMBOLIC PROCEDURE DEGREESET POL;
- %FINDS DEGREE BOUNDS FOR ALL VARS IN DISTRIBTED FORM POLY;
- DEGREESUB(DBL LPOW POL,RED POL);
- SYMBOLIC PROCEDURE DBL X;
- % CONVERTS LIST OF X INTO LIST OF (X . X);
- IF NULL X THEN NIL
- ELSE (CAR X . CAR X) . DBL CDR X;
- SYMBOLIC PROCEDURE DEGREESUB(CUR,POL);
- % UPDATE DEGREE BOUNDS 'CUR' TO INCLUDE INFO ABOUT POL;
- <<
- WHILE NOT NULL POL DO <<
- CUR:=DEGREESUB1(CUR,LPOW POL);
- POL:=RED POL >>;
- CUR >>;
- SYMBOLIC PROCEDURE DEGREESUB1(CUR,NXT);
- %MERGE INFORMATION FROM EXPONENT SET NEXT INTO CUR;
- IF NULL CUR THEN NIL
- ELSE DEGREESUB2(CAR CUR,CAR NXT) . DEGREESUB1(CDR CUR,CDR NXT);
- SYMBOLIC PROCEDURE DEGREESUB2(TWO,ONE);
- MAX(CAR TWO,ONE) . MIN(CDR TWO,ONE);
- ENDMODULE;
- MODULE IBASICS;
- EXPORTS PARTIALDIFF,PRINTDF,PRINTSQ,RATIONALINTEGRATE,PRINTSF,INTERR;
- IMPORTS DF2PRINTFORM,SQPRINT,VARSINSF,TERPRI!*,ADDSQ,MULTSQ,MULTD,MKSP;
- %PRINT STANDARD QUOTIENT (RATIONAL FUNCTION);
- % CRUDE EQUIVALENT TO PRINTSF NUMR U: "/": PRINTSF DENO U;
- SYMBOLIC PROCEDURE PRINTSQ U;
- BEGIN
- TERPRI!*(T); %START ON A NEW LINE;
- SQPRINT U; %LOGICAL PRINT ROUTINE;
- TERPRI!*(T)
- END;
- % PRINT STANDARD FORM (POLYNOMIAL);
- FLUID '(U!*); %NEEDED BECAUSE OF THE ERRORSET;
- SYMBOLIC PROCEDURE PRINTSF U!*;
- IF NULL U!* THEN PRINT 0
- ELSE BEGIN SCALAR W;
- W:=ERRORSET('(PROG NIL (TERPRI!* T)
- (XPRINF U!* NIL NIL) (TERPRI!* T)),2,!*BACKTRACE);
- IF NOT ATOM W THEN RETURN CAR W;
- PRINTC "REDUCE PRINTING FAILED ON STANDARD FORM";
- PRINT U!*;
- TERPRI!*(T);
- RETURN U!*
- END;
- UNFLUID '(U!*);
- SYMBOLIC PROCEDURE PRINTDF U;
- % PRINT DISTRIBUTED FORM VIA CHEAP CONVERSION TO REDUCE STRUCTURE;
- BEGIN SCALAR !*GCD;
- PRINTSF DF2PRINTFORM U;
- END;
- SYMBOLIC PROCEDURE INTERR MESS;
- BEGIN
- PRINTC "INTEGRATION PACKAGE ERROR";
- PRINTC MESS;
- ERROR1()
- END;
- SYMBOLIC PROCEDURE RATIONALINTEGRATE(X,VAR);
- BEGIN SCALAR N,D;
- N:=NUMR X; D:=DENR X;
- IF NOT VAR MEMBER VARSINSF(D,NIL) THEN
- RETURN SUBS2Q MULTSQ(POLYNOMIALINTEGRATE(N,VAR),1 ./ D);
- INTERR "RATIONAL INTEGRATION NOT CODED YET"
- END;
- % INTEGRATE STANDARD FORM. RESULT IS STANDARD QUOTIENT;
- SYMBOLIC PROCEDURE POLYNOMIALINTEGRATE(X,V);
- IF NULL X THEN NIL ./ 1
- ELSE IF ATOM X THEN ((MKSP(V,1) .* 1) .+ NIL) ./ 1
- ELSE BEGIN SCALAR R;
- R:=POLYNOMIALINTEGRATE(RED X,V); % DEAL WITH REDUCTUM;
- IF V=MVAR X THEN BEGIN SCALAR DEGREE,NEWLT;
- DEGREE:=1+TDEG LT X;
- NEWLT:=((MKSP(V,DEGREE) .* LC X) .+ NIL) ./ 1; % UP EXPONENT;
- R:=ADDSQ(MULTSQ(NEWLT,1 ./ DEGREE),R)
- END
- ELSE BEGIN SCALAR NEWTERM;
- NEWTERM:=(((LPOW X) .* 1) .+ NIL) ./ 1;
- NEWTERM:=MULTSQ(NEWTERM,POLYNOMIALINTEGRATE(LC X,V));
- R:=ADDSQ(R,NEWTERM)
- END;
- RETURN SUBS2Q R
- END;
- % PARTIAL DIFFERENTIATION OF P WRT V - P IS S.F. AS IS RESULT;
- SYMBOLIC PROCEDURE PARTIALDIFF(P,V);
- IF ATOM P THEN NIL
- ELSE
- IF V=MVAR P THEN
- (LAMBDA X; IF X=1 THEN LC P
- ELSE ((MKSP(V,X-1) .* MULTD(X,LC P))
- .+ PARTIALDIFF(RED P,V)))
- (TDEG LT P)
- ELSE
- (LAMBDA X; IF NULL X THEN PARTIALDIFF(RED P,V)
- ELSE ((LPOW P .* X) .+ PARTIALDIFF(RED P,V)))
- (PARTIALDIFF(LC P,V));
- PUT('PDIFF,'SIMPFN,'SIMPPDIFF);
- ENDMODULE;
- MODULE JPATCHES;
- EXPORTS !*MULTF!*;
- IMPORTS !*MULTF!*SQRT,SIMPSQRTI,RETIMES,MULTSQ,SIMPEXPT,INVSQ,MKSQ,XN,
- FLATTEN,MKSPM,MKSP,EXPTF,SIMP,GCDN,ADDF,ORDOP,NONCOMP,MKSFPF,
- MULTD,DOMAINP;
- %SYMBOLIC PROCEDURE SIMPX1(U,M,N);
- % %U,M AND N ARE PREFIX EXPRESSIONS;
- % %VALUE IS THE STANDARD QUOTIENT EXPRESSION FOR U**(M/N);
- % BEGIN SCALAR FLG,Z;
- % IF NULL FRLIS!* OR NULL XN(FRLIS!*,FLATTEN (M . N))
- % THEN GO TO A;
- % EXPTP!* := T;
- % RETURN !*K2Q LIST('EXPT,U,IF N=1 THEN M
- % ELSE LIST('QUOTIENT,M,N));
- % A: IF NUMBERP M AND FIXP M THEN GO TO E
- % ELSE IF ATOM M THEN GO TO B
- % ELSE IF CAR M EQ 'MINUS THEN GO TO MNS
- % ELSE IF CAR M EQ 'PLUS THEN GO TO PLS
- % ELSE IF CAR M EQ 'TIMES AND NUMBERP CADR M AND FIXP CADR M
- % AND NUMBERP N
- % THEN GO TO TMS;
- % B: Z := 1;
- % C: IF ATOM U AND NOT NUMBERP U THEN FLAG(LIST U,'USED!*);
- % U := LIST('EXPT,U,IF N=1 THEN M ELSE LIST('QUOTIENT,M,N));
- % IF NOT U MEMBER EXPTL!* THEN EXPTL!* := U . EXPTL!*;
- % D: RETURN MKSQ(U,IF FLG THEN -Z ELSE Z); %U IS ALREADY IN LOWEST
- % %TERMS;
- % E: IF NUMBERP N AND FIXP N THEN GO TO INT;
- % Z := M;
- % M := 1;
- % GO TO C;
- % MNS: M := CADR M;
- % IF !*MCD THEN RETURN INVSQ SIMPX1(U,M,N);
- % FLG := NOT FLG;
- % GO TO A;
- % PLS: Z := 1 ./ 1;
- % PL1: M := CDR M;
- % IF NULL M THEN RETURN Z;
- % Z := MULTSQ(SIMPEXPT LIST(U,
- % LIST('QUOTIENT,IF FLG THEN LIST('MINUS,CAR M)
- % ELSE CAR M,N)),
- % Z);
- % GO TO PL1;
- % TMS: Z := GCDN(N,CADR M);
- % N := N/Z;
- % Z := CADR M/Z;
- % M := RETIMES CDDR M;
- % GO TO C;
- % INT:Z := DIVIDE(M,N);
- % IF CDR Z<0 THEN Z:= (CAR Z - 1) . (CDR Z+N);
- % IF CDR Z=0
- % THEN RETURN SIMPEXPT LIST(U,CAR Z);
- % IF N=2 AND !*SQRT
- % THEN RETURN MULTSQ(SIMPEXPT LIST(U,CAR Z),
- % SIMPSQRTI U);
- % RETURN MULTSQ(SIMPEXPT LIST(U,CAR Z),
- % MKSQ(LIST('EXPT,U,LIST('QUOTIENT,1,N)),CDR Z))
- % END;
- ENDMODULE;
- MODULE KRON;
- EXPORTS LINFAC,QUADFAC;
- IMPORTS EVALAT,LINETHROUGH,QUADTHROUGH,TESTDIV;
- %KRONEKER FACTORIZATION FOR UNIVARIATE POLYS OVER THE INTEGERS;
- %ONLY LINEAR AND QUADRATIC FACTORS ARE FOUND HERE;
- SYMBOLIC PROCEDURE LINFAC(W);
- TRYKR(W,'(0 1));
- SYMBOLIC PROCEDURE QUADFAC(W);
- TRYKR(W,'(-1 0 1));
- SYMBOLIC PROCEDURE TRYKR(W,POINTS);
- %LOOK FOR FACTOR OF W BY EVALUATION AT (POINTS) AND USE OF;
- % INTERPOLATE. RETURN (FAC . COFAC) WITH FAC=NIL IF NONE;
- %FOUND AND COFAC=NIL IF NOTHING WORTHWHILE IS LEFT;
- BEGIN SCALAR VALUES,ATTEMPT;
- IF NULL W THEN RETURN NIL . NIL;
- IF (LENGTH POINTS > CAR W) THEN RETURN W . NIL;
- %THAT SAYS IF W IS ALREADY TINY, IT IS ALREADY FACTORED;
- VALUES:=MAPCAR(POINTS,FUNCTION (LAMBDA X;
- EVALAT(W,X)));
- IF !*TRINT THEN << PRINTC ("AT X= " . POINTS);
- PRINTC ("P(X)= " . VALUES)>>;
- IF 0 MEMBER VALUES THEN GO TO LUCKY; %(X-1) IS A FACTOR!;
- VALUES:=MAPCAR(VALUES,FUNCTION ZFACTORS);
- RPLACD(VALUES,MAPCAR(CDR VALUES,FUNCTION (LAMBDA Y;
- APPEND(Y,MAPCAR(Y,FUNCTION MINUS)))));
- IF !*TRINT THEN <<PRINTC "POSSIBLE FACTORS GO THROUGH SOME OF";
- PRINT VALUES>>;
- ATTEMPT:=SEARCH4FAC(W,VALUES,NIL);
- IF NULL ATTEMPT THEN ATTEMPT:=NIL . W;
- RETURN ATTEMPT;
- LUCKY: %HERE (X-1) IS A FACTOR BECAUSE P(0) OR P(1) OR P(-1);
- %VANISHED AND CASES P(0), P(-1) WILL HAVE BEEN REMOVED;
- %ELSEWHERE;
- ATTEMPT:='(1 1 -1); %THE FACTOR;
- RETURN ATTEMPT . TESTDIV(W,ATTEMPT)
- END;
- SYMBOLIC PROCEDURE SEARCH4FAC(W,VALUES,CV);
- %COMBINATORIAL SEARCH. CV GETS CURRENT SELECTED VALUE-SET;
- %RETURNS NIL IF FAILS, ELSE FACTOR . COFACTOR;
- IF NULL VALUES THEN TRYFACTOR(W,CV)
- ELSE BEGIN SCALAR FF,Q;
- FF:=CAR VALUES; %TRY ALL VALUES HERE;
- LOOP: IF NULL FF THEN RETURN NIL; %NO FACTOR FOUND;
- Q:=SEARCH4FAC(W,CDR VALUES,(CAR FF) . CV);
- IF NULL Q THEN << FF:=CDR FF; GO TO LOOP>>;
- RETURN Q
- END;
- SYMBOLIC PROCEDURE TRYFACTOR(W,CV);
- %TESTS IF CV REPRESENTS A FACTOR OF W;
- BEGIN SCALAR FF,Q;
- IF NULL CDDR CV THEN FF:=LINETHROUGH(CADR CV,CAR CV)
- ELSE FF:=QUADTHROUGH(CADDR CV,CADR CV,CAR CV);
- IF FF='FAILED THEN RETURN NIL; %IT DOES NOT INTERPOLATE;
- Q:=TESTDIV(W,FF);
- IF Q='FAILED THEN RETURN NIL; %NOT A FACTOR;
- RETURN FF . Q
- END;
- ENDMODULE;
- MODULE LOWDEG;
- EXPORTS FORCEAZERO,MAKEPOLYDF,QUADRATIC,COVECDF,EXPONENTDF;
- IMPORTS DFQUOTDF,GCDF,INTERR,MINUSDFP,MULTDF,MULTDFCONST,!*MULTF!*,
- NEGSQ,MINUSP,PRINTSQ,MULTSQ,INVSQ,PNTH,NTH,MKNILL,
- NEGDF,PLUSDF,PRINTDF,PRINTSQ,QUOTF,SQRTDF,VAR2DF,VP2,ADDSQ,SUB1;
- %SPLITTING OF LOW DEGREE POLYNOMIALS;
- SYMBOLIC PROCEDURE COVECDF(POL,VAR,DEGREE);
- %EXTRACT COEFFICIENTS OF POLYNOMIAL WRT VAR, GIVEN A DEGREE-BOUND
- % DEGREE;
- %RESUL IS A LISP VECTOR;
- BEGIN SCALAR I,V,X,W;
- W:=POL;
- V:=MKVECT(DEGREE);
- WHILE NOT NULL W DO <<
- X:=EXPONENTOF(VAR,LPOW W,ZLIST);
- IF (X<0) OR (X>DEGREE) THEN INTERR "BAD DEGREE IN COVECDF";
- PUTV(V,X,LT W . GETV(V,X));
- W:=RED W >>;
- FOR I:=0:DEGREE DO PUTV(V,I,MULTDF(REVERSEWOC GETV(V,I),
- VAR2DF(VAR,-I,ZLIST)));
- RETURN V
- END;
- SYMBOLIC PROCEDURE QUADRATIC(POL,VAR,RES);
- %ADD IN TO RES LOGS OR ARCTANS CORRESPONDING TO SPLITTING THE
- % POLYNOMIAL;
- % POL GIVEN THAT IT IS QUADRATIC WRT VAR;
- %;
- %DOES NOT ASSUME POL IS UNIVARIATE;
- BEGIN SCALAR A,B,C,W,DISCRIM;
- W:=COVECDF(POL,VAR,2);
- A:=GETV(W,2); B:=GETV(W,1); C:=GETV(W,0);
- % THAT SPLIT THE QUADRATIC UP TO FIND THE COEFFICIENTS A,B,C;
- IF !*TRINT THEN << PRINTC "A="; PRINTDF A;
- PRINTC "B="; PRINTDF B;
- PRINTC "C="; PRINTDF C>>;
- DISCRIM:=PLUSDF(MULTDF(B,B),
- MULTDFCONST((-4) . 1,MULTDF(A,C)));
- IF !*TRINT THEN << PRINTC "DISCRIMINANT IS";
- PRINTDF DISCRIM>>;
- IF NULL DISCRIM THEN INTERR "DISCRIM=0 IN QUADRATIC";
- IF KNOWNDISCRIMSIGN
- THEN <<IF KNOWNDISCRIMSIGN EQ 'NEGATIVE THEN GO TO ATANCASE>>
- ELSE IF (NOT CLOGFLAG) AND (MINUSDFP DISCRIM)
- THEN GO TO ATANCASE;
- DISCRIM:=SQRTDF(DISCRIM);
- IF DISCRIM='FAILED THEN GO TO NOFACTORS;
- IF !*TRINT THEN << PRINTC "SQUARE-ROOT IS";
- PRINTDF DISCRIM>>;
- W:=VAR2DF(VAR,1,ZLIST);
- W:=MULTDF(W,A);
- B:=MULTDFCONST(1 ./ 2,B);
- DISCRIM:=MULTDFCONST(1 ./ 2,DISCRIM);
- W:=PLUSDF(W,B); %A*X+B/2;
- A:=PLUSDF(W,DISCRIM); B:=PLUSDF(W,NEGDF(DISCRIM));
- IF !*TRINT THEN << PRINTC "FACTORS ARE";
- PRINTDF A; PRINTDF B>>;
- RETURN ('LOG . A) . ('LOG . B) . RES;
- ATANCASE:
- DISCRIM:=SQRTDF NEGDF DISCRIM; %SQRT(4*A*C-B**2) THIS TIME!;
- IF DISCRIM='FAILED THEN GO TO NOFACTORS; %SQRT DID NOT EXIST?;
- RES := ('LOG . POL) . RES; %ONE PART OF THE ANSWER;
- A:=MULTDF(A,VAR2DF(VAR,1,ZLIST));
- A:=PLUSDF(B,MULTDFCONST(2 ./ 1,A));
- A:=DFQUOTDF(A,DISCRIM); %ASSUMES DIVISION IS EXACT;
- RETURN ('ATAN . A) . RES;
- NOFACTORS:
- PRINTC "THE FOLLOWING QUADRATIC DOES NOT SEEM TO FACTOR";
- PRINTDF POL;
- RETURN ('LOG . POL) . RES
- END;
- SYMBOLIC PROCEDURE EXPONENTOF(VAR,L,ZL);
- IF NULL ZL THEN INTERR "VAR NOT FOUND IN EXPONENTOF"
- ELSE IF VAR=CAR ZL THEN CAR L
- ELSE EXPONENTOF(VAR,CDR L,CDR ZL);
- SYMBOLIC PROCEDURE DF2SF A;
- IF NULL A THEN NIL
- ELSE IF ((NULL RED A) AND
- (ONEP DENR LC A) AND
- (LPOW A=VP2 ZLIST)) THEN NUMR LC A
- ELSE INTERR "NASTY CUBIC OR QUARTIC";
- SYMBOLIC PROCEDURE MAKEPOLYDF P;
- %MULTIPLY DF BY LCM OF DENOMINATORS OF ALL COEFFICIENT DENOMINATORS;
- BEGIN SCALAR H,W;
- IF NULL(W:=P) THEN RETURN NIL; %POLY IS ZERO ALREADY;
- H:=DENR LC W; %A GOOD START;
- W:=RED W;
- WHILE NOT NULL W DO <<
- H:=QUOTF(!*MULTF!*(H,DENR LC W),GCDF(H,DENR LC W));
- W:=RED W >>;
- %H IS NOW LCM OF DENOMINATORS;
- RETURN MULTDFCONST(!*F2POL H ./ 1,P)
- END;
- SYMBOLIC PROCEDURE FORCEAZERO(P,N);
- %SHIFT POLYNOMIAL P SO THAT COEFF OF X**(N-1) VANISHES;
- %RETURN THE AMOUNT OF THE SHIFT, UPDATE (VECTOR) P;
- BEGIN SCALAR R,I,W;
- FOR I:=0:N DO PUTV(P,I,DF2SF GETV(P,I)); %CONVERT TO POLYS;
- R:=GETV(P,N-1);
- IF NULL R THEN RETURN NIL ./ 1; %ALREADY ZERO;
- R:= SUBS2Q MULTSQ(R ./ 1,INVSQ(!*MULTF!*(N,GETV(P,N)) ./ 1));
- %THE SHIFT AMOUNT;
- %NOW I HAVE TO SET P:=SUBST(X-R,X,P) AND THEN REDUCE TO SF AGAIN;
- IF !*TRINT THEN << PRINTC "SHIFT IS BY ";
- PRINTSQ R>>;
- W:=MKVECT(N); %WORKSPACE VECTOR;
- FOR I:=0:N DO PUTV(W,I,NIL ./ 1); %ZERO IT;
- I:=N;
- WHILE NOT MINUSP I DO <<
- MULVECBYXR(W,NEGSQ R,N); %W:=(X-R)*W;
- PUTV(W,0,ADDSQ(GETV(W,0),GETV(P,I) ./ 1));
- I:=I-1 >>;
- IF !*TRINT THEN << PRINTC "SQ SHIFTED POLY IS";
- PRINT W>>;
- FOR I:=0:N DO PUTV(P,I,GETV(W,I));
- W:=DENR GETV(P,0);
- FOR I:=1:N DO W:=QUOTF(!*MULTF!*(W,DENR GETV(P,I)),
- GCDF(W,DENR GETV(P,I)));
- FOR I:=0:N DO PUTV(P,I,NUMR SUBS2Q MULTSQ(GETV(P,I),W ./ 1));
- W:=GETV(P,0);
- FOR I:=1:N DO W:=GCDF(W,GETV(P,I));
- IF NOT (W=1) THEN
- FOR I:=0:N DO PUTV(P,I,QUOTF(GETV(P,I),W));
- IF !*TRINT THEN << PRINTC "FINAL SHIFTED POLY IS ";
- PRINT P>>;
- RETURN R
- END;
- SYMBOLIC PROCEDURE MULVECBYXR(W,R,N);
- %W IS A VECTOR REPRESENTING A POLY OF DEGREE N;
- %MULTIPLY IT BY (X+R);
- BEGIN SCALAR I,IM1;
- I:=N;
- IM1:=SUB1 I;
- WHILE NOT MINUSP IM1 DO <<
- PUTV(W,I,SUBS2Q ADDSQ(GETV(W,IM1),MULTSQ(R,GETV(W,I))));
- I:=IM1; IM1:=SUB1 I >>;
- PUTV(W,0,SUBS2Q MULTSQ(GETV(W,0),R));
- RETURN W
- END;
- ENDMODULE;
- MODULE REFORM;
- EXPORTS LOGSTOSQ,SUBSTINULIST;
- IMPORTS PREPSQ,MKSP,NTH,MULTSQ,ADDSQ,DOMAINP,INVSQ,PLUSDF;
- SYMBOLIC PROCEDURE SUBSTINULIST ULIST;
- % Substitutes for the C-constants in the values of the U's given in;
- % ULIST. Result is a D.F.;
- IF NULL ULIST THEN NIL
- ELSE BEGIN SCALAR TEMP,LCU;
- LCU:=LC ULIST;
- TEMP:=EVALUATEUCONST NUMR LCU;
- IF NULL NUMR TEMP THEN TEMP:=NIL
- ELSE TEMP:=((LPOW ULIST) .*
- SUBS2Q MULTSQ(TEMP,INVSQ(DENR LCU ./ 1))) .+ NIL;
- RETURN PLUSDF(TEMP,SUBSTINULIST RED ULIST)
- END;
- SYMBOLIC PROCEDURE EVALUATEUCONST COEFFT;
- % Substitutes for the C-constants into COEFFT (=S.F.). Result is S.Q.;
- IF NULL COEFFT OR DOMAINP COEFFT THEN COEFFT ./ 1
- ELSE BEGIN SCALAR TEMP;
- IF NULL(TEMP:=ASSOC(MVAR COEFFT,CMAP)) THEN
- TEMP:=(!*P2F LPOW COEFFT) ./ 1
- ELSE TEMP:=GETV(CVAL,CDR TEMP);
- TEMP:=MULTSQ(TEMP,EVALUATEUCONST(LC COEFFT));
- RETURN SUBS2Q ADDSQ(TEMP,EVALUATEUCONST(RED COEFFT))
- END;
- SYMBOLIC PROCEDURE LOGSTOSQ;
- % Converts LOGLIST to sum of the log terms as a S.Q.;
- BEGIN SCALAR LGLST,LOGSQ,I,TEMP;
- I:=1;
- LGLST:=LOGLIST;
- LOGSQ:=NIL ./ 1;
- LOOP: IF NULL LGLST THEN RETURN LOGSQ;
- TEMP:=CDDR CAR LGLST;
- IF !*TRINT
- THEN << PRINTC "Standard Form ARG FOR ADDITIONAL LOG ETC =";
- PRINT TEMP >>;
- IF NOT (CAAR LGLST='IDEN) THEN <<
- TEMP:=PREPSQ TEMP; %CONVERT TO PREFIX FORM;
- TEMP:=LIST(CAAR LGLST,TEMP); %FUNCTION NAME;
- TEMP:=((MKSP(TEMP,1) .* 1) .+ NIL) ./ 1 >>;
- TEMP:=MULTSQ(TEMP,GETV(CVAL,I));
- LOGSQ:= SUBS2Q ADDSQ(TEMP,LOGSQ);
- LGLST:=CDR LGLST;
- I:=I+1;
- GO TO LOOP
- END;
- ENDMODULE;
- MODULE SIMPLOG;
- EXPORTS SIMPLOG,SIMPLOGSQ;
- IMPORTS QUOTF,PREPF,MKSP,SIMP!*,MULTSQ,SIMPTIMES,ADDSQ,MINUSF,NEGF,
- ADDF,COMFAC,NEGSQ,MK!*SQ,CARX;
- SYMBOLIC PROCEDURE SIMPLOG(EXXPR);
- SIMPLOGI(CARX(EXXPR,'LOG));
- SYMBOLIC PROCEDURE SIMPLOGI(SQ);
- BEGIN
- IF ATOM SQ
- THEN GO TO SIMPLIFY;
- IF CAR SQ EQ 'TIMES
- THEN RETURN ADDSQ(SIMPLOGI CADR SQ,SIMPLOGI CADDR SQ);
- IF CAR SQ EQ 'QUOTIENT
- THEN RETURN ADDSQ(SIMPLOGI CADR SQ,
- NEGSQ SIMPLOGI CADDR SQ);
- IF CAR SQ EQ 'EXPT
- THEN RETURN SIMPTIMES LIST(CADDR SQ,
- MK!*SQ SIMPLOGI CADR SQ);
- IF CAR SQ = '!*SQ
- THEN RETURN SIMPLOGSQ CADR SQ;
- SIMPLIFY:
- SQ:=SIMP!* SQ;
- RETURN SIMPLOGSQ SQ
- END;
- SYMBOLIC PROCEDURE SIMPLOGSQ SQ;
- ADDSQ((SIMPLOG2 NUMR SQ),NEGSQ(SIMPLOG2 DENR SQ));
- SYMBOLIC PROCEDURE SIMPLOG2(SF);
- IF ATOM SF
- THEN IF NULL SF
- THEN REDERR "LOG 0 FORMED"
- ELSE IF NUMBERP SF
- THEN IF SF IEQUAL 1
- THEN NIL ./ 1
- ELSE IF SF IEQUAL 0
- THEN REDERR "LOG 0 FORMED"
- ELSE((MKSP(LIST('LOG,SF),1) .* 1) .+ NIL) ./ 1
- ELSE FORMLOG(SF)
- ELSE BEGIN
- SCALAR FORM;
- FORM:=COMFAC SF;
- IF NOT NULL CAR FORM
- THEN RETURN ADDSQ(FORMLOG(FORM .+ NIL),
- SIMPLOG2 QUOTF(SF,FORM .+ NIL));
- % WE HAVE KILLED COMMON POWERS;
- FORM:=CDR FORM;
- IF FORM NEQ 1
- THEN RETURN ADDSQ(SIMPLOG2 FORM,
- SIMPLOG2 QUOTF(SF,FORM));
- % REMOVE A COMMON FACTOR FROM THE SF;
- RETURN (FORMLOG SF)
- END;
- SYMBOLIC PROCEDURE FORMLOG(SF);
- IF (NULL RED SF)
- THEN IF EQCAR(MVAR SF,'EXPT)
- THEN ADDSQ(SIMPLOG2 LC SF,
- SUBS2Q MULTSQ(SIMPLOGI MVAR SF,SIMP!* LDEG SF))
- ELSE IF (LC SF IEQUAL 1) AND (LDEG SF IEQUAL 1)
- THEN ((MKSP(LIST('LOG,MVAR SF),1) .* 1) .+ NIL) ./ 1
- ELSE ADDSQ(SIMPTIMES LIST(LIST('LOG,MVAR SF),LDEG SF),
- SIMPLOG2 LC SF)
- ELSE IF MINUSF SF
- THEN ADDF((MKSP(LIST('LOG,-1),1) .* 1) .+ NIL,
- FORMLOG2 NEGF SF) ./ 1
- ELSE (FORMLOG2 SF) ./ 1;
- SYMBOLIC PROCEDURE FORMLOG2 SF;
- ((MKSP(LIST('LOG,PREPF SF),1) .* 1) .+ NIL);
- ENDMODULE;
- MODULE SIMPSQRT;
- SYMBOLIC PROCEDURE SIMPSQRTSQ SQ;
- (SIMPSQRT2 NUMR SQ) ./ (SIMPSQRT2 DENR SQ);
- SYMBOLIC PROCEDURE SIMPSQRT2(SF);
- IF ATOM SF
- THEN IF NULL SF
- THEN NIL
- ELSE IF NUMBERP SF
- THEN IF MINUSP SF
- THEN !*F2POL !*MULTF!*(SIMPSQRT2 (-SF),
- (MKSP(MKSQRT(-1),1) .* 1) .+ NIL)
- ELSE BEGIN
- SCALAR N;
- N:=SQRT SF;
- IF IDP N
- THEN RETURN (MKSP(MKSQRT!* SF,1) .* 1) .+ NIL
- ELSE RETURN N
- END
- ELSE FORMSQRT(SF)
- ELSE BEGIN
- SCALAR FORM;
- FORM:=COMFAC SF;
- IF NOT NULL CAR FORM
- THEN RETURN !*F2POL !*MULTF!*(FORMSQRT(FORM .+ NIL),
- SIMPSQRT2 QUOTF(SF,FORM .+ NIL));
- % WE HAVE KILLED COMMON POWERS;
- FORM:=CDR FORM;
- IF FORM NEQ 1
- THEN RETURN !*F2POL !*MULTF!*(SIMPSQRT2 FORM,
- SIMPSQRT2 QUOTF(SF,FORM));
- % REMOVE A COMMON FACTOR FROM THE SF;
- RETURN FORMSQRT SF
- END;
- SYMBOLIC PROCEDURE FORMSQRT(SF);
- %Is *F2POL really necessary here??;
- IF (NULL RED SF)
- THEN IF (LC SF IEQUAL 1) AND (LDEG SF IEQUAL 1)
- THEN (MKSP(MKSQRT!* MVAR SF,1) .* 1) .+ NIL
- ELSE !*F2POL
- !*MULTF!*(NUMR SIMPEXPT(LIST(MKSQRT!* MVAR SF,LDEG SF)),
- SIMPSQRT2 LC SF)
- ELSE (MKSP(MKSQRT!* SF,1) .* 1) .+ NIL;
- SYMBOLIC PROCEDURE MKSQRT!* U;
- IF SFP U THEN MKSQRT !*F2A U ELSE MKSQRT U;
- ALGEBRAIC;
- % OPERATOR SQRT;
- SYMBOLIC;
- % DEFLIST ('((SQRT (((X) QUOTIENT (SQRT X) (TIMES 2 X))))),'DFN);
- SYMBOLIC PROCEDURE SIMPSQRTI SQ;
- BEGIN
- IF ATOM SQ
- THEN IF NUMBERP SQ
- THEN RETURN (SIMPSQRT2 SQ) ./ 1
- ELSE RETURN ((MKSP(MKSQRT SQ,1) .* 1) .+ NIL) ./ 1;
- IF CAR SQ EQ 'TIMES
- THEN RETURN SUBS2Q MULTSQ(SIMPSQRTI CADR SQ,SIMPSQRTI CADDR SQ);
- IF CAR SQ EQ 'QUOTIENT
- THEN RETURN SUBS2Q MULTSQ(SIMPSQRTI CADR SQ,
- INVSQ SIMPSQRTI CADDR SQ);
- IF CAR SQ EQ 'EXPT
- THEN RETURN SIMPEXPT
- LIST(MK!*SQ SIMPSQRTI CADR SQ,CADDR SQ);
- IF CAR SQ = '!*SQ
- THEN RETURN SIMPSQRTSQ CADR SQ;
- RETURN SIMPSQRTSQ SIMP!* SQ
- END;
- ENDMODULE;
- MODULE SOLVE;
- EXPORTS SOLVE!-FOR!-U;
- IMPORTS NTH,FINDPIVOT,GCDF,GENSYM1,MKVECT,INTERR,MULTDFCONST,
- !*MULTF!*,NEGDF,ORDDF,PLUSDF,PRINTDF,PRINTSF,PRINTSPREADC,PRINTSQ,
- QUOTF,PUTV,SPREADC,SUBST4ELIMINATEDCS,MKNILL,PNTH,DOMAINP,ADDF,
- INVSQ,MULTSQ;
- %***********************************************************************
- % ROUTINES FOR SOLVING THE FINAL REDUCTION EQUATION:
- %**********************************************************************;
- SYMBOLIC PROCEDURE UTERM(POWU,RHS);
- % Finds the contribution from RHS of reduction equation, of the;
- % U-coefficient given by POWU. Result is in D.F.;
- IF NULL RHS THEN NIL
- ELSE BEGIN SCALAR COEF,POWER;
- POWER:=ADDINDS(POWU,LPOW RHS);
- COEF:=EVALUATECOEFFTS(NUMR LC RHS,POWU);
- IF NULL COEF THEN RETURN UTERM(POWU,RED RHS);
- COEF:=COEF ./ DENR LC RHS;
- RETURN PLUSDF((POWER .* COEF) .+ NIL,UTERM(POWU,RED RHS))
- END;
- SYMBOLIC PROCEDURE SOLVE!-FOR!-U(RHS,LHS,ULIST);
- % Solves the reduction eqn LHS = RHS. Returns list of U-coefficients;
- % and their values (ULIST are those we have so far), and a list of;
- % C-equations to be solved (CLIST are the eqns we have so far);
- IF NULL LHS THEN ULIST
- ELSE BEGIN SCALAR U,LPOWLHS;
- LPOWLHS:=LPOW LHS;
- BEGIN SCALAR LL,MM,CHGE; LL:=MAXORDER(RHS,ZLIST,0);
- MM:=LORDER;
- WHILE MM DO << IF CAR LL < CAR MM THEN
- << CHGE:=T; RPLACA(MM,CAR LL) >>;
- LL:=CDR LL; MM:=CDR MM >>;
- IF !*TRINT AND CHGE THEN << PRINT ("Maxorder now ".LORDER) >>
- END;
- U:=PICKUPU(RHS,LPOW LHS,T);
- IF NULL U THEN
- << IF !*TRINT THEN << PRINTC "****** C-EQUATION TO SOLVE:";
- PRINTSF NUMR LC LHS;
- PRINTC " = 0";
- PRINTC " ">>;
- % Remove a zero constant from the lhs, rather than use
- % Gauss Elim;
- IF GAUSSELIMN(NUMR LC LHS,LT LHS) THEN
- LHS:=SQUASHCONSTANTS(RED LHS)
- ELSE LHS:=RED LHS >>
- ELSE
- << ULIST:=(CAR U .
- SUBS2Q MULTSQ(COEFDF(LHS,LPOWLHS),INVSQ CDR U)).ULIST;
- IF !*STATISTICS THEN !*NUMBER!*:=!*NUMBER!*+1;
- IF !*TRINT THEN << PRINTC ("**** U(".CAR U);
- PRINTC " =";
- PRINTSQ MULTSQ(COEFDF(LHS,LPOWLHS),INVSQ CDR U);
- PRINTC " ">>;
- LHS:=PLUSDF(LHS,
- NEGDF MULTDFCONST(CDAR ULIST,UTERM(CAR U,RHS))) >>;
- IF !*TRINT THEN << PRINTC ".... LHS is now:";
- PRINTDF LHS;
- PRINTC " ">>;
- RETURN SOLVE!-FOR!-U(RHS,LHS,ULIST)
- END;
- SYMBOLIC PROCEDURE SQUASHCONSTANTS(EXPRESS);
- BEGIN SCALAR CONSTLST,II,XP,CL,SUBBY,CMT,XX;
- CONSTLST:=REVERSE CMAP;
- CMT:=CMATRIX;
- XXX: XX:=CAR CMT; % Look at next row of Cmatrix;
- CL:=CONSTLST; % and list of the names;
- II:=1; % will become index of removed constant;
- WHILE NOT GETV(XX,II) DO
- << II:=II+1; CL:=CDR CL >>;
- SUBBY:=CAAR CL; %II is now index, and SUBBY the name;
- IF MEMBER(SUBBY,SILLIESLIST) THEN
- <<CMT:=CDR CMT; GO TO XXX>>; %This loop must terminate;
- % This is because at least one constant remains;
- XP:=PREPSQ !*F2Q GETV(XX,0); % start to build up the answer;
- CL:=CDR CL;
- IF NOT (CCOUNT=II) THEN FOR JJ=II+1:CCOUNT DO <<
- IF GETV(XX,JJ) THEN
- XP:=LIST('PLUS,XP,
- LIST('TIMES,CAAR CL,
- PREPSQ !*F2Q GETV(XX,JJ)));
- CL:=CDR CL >>;
- XP:=LIST('QUOTIENT,LIST('MINUS,XP),
- PREPSQ !*F2Q GETV(XX,II));
- IF !*TRINT THEN << PRIN2 "Replace "; PRIN2 SUBBY;
- PRIN2 " by "; PRINTSQ SIMP XP >>;
- SILLIESLIST:=SUBBY . SILLIESLIST;
- RETURN SUBDF(EXPRESS,XP,SUBBY)
- END;
- SYMBOLIC PROCEDURE CHECKU(ULIST,U);
- % Checks that U is not already in ULIST - ie. that this u-coefficient;
- % has not already been given a value;
- IF NULL ULIST THEN NIL
- ELSE IF (CAR U) = CAAR ULIST THEN T
- ELSE CHECKU(CDR ULIST,U);
- SYMBOLIC PROCEDURE CHECKU1(POWU,RHS);
- %Checks that use of a particular U-term will not cause trouble;
- %by introducing negative exponents into lhs when it is used;
- BEGIN
- TOP:
- IF NULL RHS THEN RETURN NIL;
- IF NEGIND(POWU,LPOW RHS) THEN
- IF NOT NULL EVALUATECOEFFTS(NUMR LC RHS,POWU) THEN RETURN T;
- RHS:=RED RHS;
- GO TO TOP
- END;
- SYMBOLIC PROCEDURE NEGIND(PU,PR);
- %check if substituting index values in power gives rise to -ve
- % exponents;
- IF NULL PU THEN NIL
- ELSE IF (CAR PU+CAAR PR)<0 THEN T
- ELSE NEGIND(CDR PU,CDR PR);
- SYMBOLIC PROCEDURE EVALUATECOEFFTS(COEFFT,INDLIST);
- % Substitutes the values of the i,j,k,...'s that appear in the S.F. ;
- % COEFFT (=coefficient of r.h.s. of reduction equation). Result is S.F.;
- IF NULL COEFFT OR DOMAINP COEFFT THEN
- IF ZEROP COEFFT THEN NIL ELSE COEFFT
- ELSE BEGIN SCALAR TEMP;
- IF MVAR COEFFT MEMBER INDEXLIST THEN
- TEMP:=VALUECOEFFT(MVAR COEFFT,INDLIST,INDEXLIST)
- ELSE TEMP:=!*P2F LPOW COEFFT;
- TEMP:=!*MULTF!*(TEMP,EVALUATECOEFFTS(LC COEFFT,INDLIST));
- RETURN ADDF(!*F2POL TEMP,EVALUATECOEFFTS(RED COEFFT,INDLIST))
- END;
- SYMBOLIC PROCEDURE VALUECOEFFT(VAR,INDVALUES,INDLIST);
- % Finds the value of VAR, which should be in INDLIST, given INDVALUES;
- % - the corresponding values of INDLIST variables;
- IF NULL INDLIST THEN INTERR "VALUECOEFFT - NO VALUE"
- ELSE IF VAR EQ CAR INDLIST THEN
- IF ZEROP CAR INDVALUES THEN NIL
- ELSE CAR INDVALUES
- ELSE VALUECOEFFT(VAR,CDR INDVALUES,CDR INDLIST);
- SYMBOLIC PROCEDURE ADDINDS(POWU,POWRHS);
- % Adds indices in POWU to those in POWRHS. Result is LPOW of D.F.;
- IF NULL POWU THEN IF NULL POWRHS THEN NIL
- ELSE INTERR "POWRHS TOO LONG"
- ELSE IF NULL POWRHS THEN INTERR "POWU TOO LONG"
- ELSE (CAR POWU + CAAR POWRHS).ADDINDS(CDR POWU,CDR POWRHS);
- SYMBOLIC PROCEDURE PICKUPU(RHS,POWLHS,FLG);
- % Picks up the 'lowest' U coefficient from RHS if it exists and returns;
- % it in the form of LT of D.F.;
- % returns NIL if no legal term in RHS can be found;
- % POWLHS is the power we want to match (LPOW of D.F);
- % and COEFFU is the list of previous coefficients that must be zero;
- BEGIN SCALAR COEFFU,U;
- PT:=RHS;
- TOP:
- IF NULL PT THEN RETURN NIL; %no term found - failed;
- U:=NEXTU(LT PT,POWLHS); %check this term...;
- IF NULL U THEN GO TO NOTTHISONE;
- IF NOT TESTORD(CAR U,LORDER) THEN GO TO NEVERTHISONE;
- IF NOT CHECKCOEFFTS(COEFFU,CAR U) THEN GO TO NOTTHISONE;
- %that inhibited clobbering things already passed over;
- IF CHECKU(ULIST,U) THEN GO TO NOTTHISONE;
- %that avoided redefining a u value;
- IF CHECKU1(CAR U,RHS) THEN GO TO NEVERTHISONE;
- %avoid introduction of negative exponents;
- IF FLG THEN
- U:=PATCHUPTAN(LIST U,POWLHS,RED PT,RHS);
- RETURN U;
- NEVERTHISONE:
- COEFFU:=(LC PT) . COEFFU;
- NOTTHISONE:
- PT:=RED PT;
- GO TO TOP
- END;
- SYMBOLIC PROCEDURE PATCHUPTAN(U,POWLHS,RPT,RHS);
- BEGIN
- SCALAR UU,CC,DD,TANLIST,REDU,REDU1;
- PT:=RPT;
- WHILE PT DO <<
- IF (UU:=PICKUPU(PT,POWLHS,NIL))
- AND TESTORD(CAR UU,LORDER) THEN <<
- % Nasty found, patch it up;
- CC:=(GENSYM1('!C).CAAR U).CC;
- % CC is an alist of constants;
- IF !*TRINT THEN << PRINTC ("****** U(".CAAR U);
- PRINTC " =";
- PRINT CAAR CC >>;
- REDU:=PLUSDF(REDU,
- MULTDFCONST(!*K2Q CAAR CC,UTERM(CAAR U,RHS)));
- U:=UU.U
- >>;
- IF PT THEN PT:=RED PT >>;
- REDU1:=REDU;
- WHILE REDU1 DO BEGIN SCALAR XX; XX:=CAR REDU1;
- IF !*TRINT THEN << PRIN2 "Introduced RESIDUE "; PRINT XX >>;
- IF (NOT TESTORD(CAR XX,LORDER)) THEN <<
- IF !*TRINT THEN <<
- PRINTSQ CDR XX; PRINTC " = 0" >>;
- IF DD:=KILLSINGLES(CADR XX,CC) THEN <<
- REDU:=SUBDF(REDU,0,CAR DD);
- REDU1:=SUBDF(REDU1,0,CAR DD);
- ULIST:=((CDR DD).(NIL ./ 1)).ULIST;
- U:=RMVE(U,CDR DD);
- CC:=PURGECONST(CC,DD) >>
- ELSE REDU1:=CDR REDU1 >>
- ELSE REDU1:=CDR REDU1 END;
- FOREACH XX IN REDU DO <<
- IF (NOT TESTORD(CAR XX,LORDER)) THEN <<
- WHILE CC DO <<
- ADDCTOMAP(CAAR CC);
- ULIST:=((CDAR CC).(!*K2Q CAAR CC))
- . ULIST;
- IF !*STATISTICS
- THEN !*NUMBER!*:=!*NUMBER!*+1;
- CC:=CDR CC >>;
- GAUSSELIMN(NUMR LC REDU,LT REDU)>> >>;
- IF REDU THEN << WHILE CC DO << ADDCTOMAP(CAAR CC);
- ULIST:=((CDAR CC).(!*K2Q CAAR CC)).ULIST;
- IF !*STATISTICS THEN !*NUMBER!*:=!*NUMBER!*+1;
- CC:=CDR CC >>;
- LHS:=PLUSDF(LHS,NEGDF REDU) >>;
- RETURN CAR U
- END;
- SYMBOLIC PROCEDURE KILLSINGLES(XX,CC);
- IF ATOM XX THEN NIL
- ELSE IF NOT (CDR XX EQ NIL) THEN NIL
- ELSE BEGIN SCALAR DD;
- DD:=ASSOC(CAAAR XX,CC);
- IF DD THEN RETURN DD;
- RETURN KILLSINGLES(CDAR XX,CC)
- END;
- SYMBOLIC PROCEDURE RMVE(L,X);
- IF CAAR L=X THEN CDR L ELSE CONS(CAR L,RMVE(CDR L,X));
- SYMBOLIC PROCEDURE SUBDF(A,B,C);
- % SUBSTITUTE B FOR C INTO THE DF A;
- % Used to get rid of silly constants introduced;
- IF A=NIL THEN NIL ELSE
- BEGIN SCALAR X;
- X:=SUBF(NUMR LC A,LIST (C . B)) ;
- IF X=(NIL . 1) THEN RETURN SUBDF(RED A,B,C)
- ELSE RETURN PLUSDF(
- LIST ((LPOW A).((CAR X).MULTF(CDR X,DENR LC A))),
- SUBDF(RED A,B,C))
- END;
- SYMBOLIC PROCEDURE TESTORD(A,B);
- % Test order of two DF's in recursive fashion;
- IF NULL A THEN T
- ELSE IF CAR A LEQ CAR B THEN TESTORD(CDR A,CDR B)
- ELSE NIL;
- SYMBOLIC PROCEDURE TANFROM(RHS,Z,NN);
- % We notice that in all bad cases we have (j-num)tan**j...;
- % Extract the num;
- BEGIN SCALAR N,ZZ,R,RR;
- R:=RHS;
- N:=0; ZZ:=ZLIST;
- WHILE CAR ZZ NEQ Z DO << N:=N+1; ZZ:=CDR ZZ >>;
- WHILE R DO <<
- RR:=CAAR R; % The list of powers;
- FOR I=1:N DO RR:=CDR RR;
- IF FIXP CAAR RR THEN IF CAAR RR>0 THEN <<
- RR:=NUMR CDAR R;
- IF NULL RED RR THEN RR:=NIL ./ 1
- ELSE IF FIXP (RR:=QUOTF(RED RR,LC RR))
- THEN RR:=-RR ELSE RR:=0>>;
- IF ATOM RR THEN RETURN RR;
- R:=CDR R >>;
- IF NULL R THEN RETURN MAXFROM(LHS,NN)+1;
- RETURN MAX(RR,MAXFROM(LHS,NN)+1)
- END;
- SYMBOLIC PROCEDURE COEFDF(Y,U);
- IF Y=NIL THEN NIL
- ELSE IF LPOW Y=U THEN LC Y
- ELSE COEFDF(RED Y,U);
- SYMBOLIC PROCEDURE PURGECONST(A,B);
- % Remove a const from and expression. May be the same as DELETE?;
- IF NULL A THEN NIL
- ELSE IF CAR A=B THEN PURGECONST(CDR A,B)
- ELSE CONS(CAR A,PURGECONST(CDR A,B));
- SYMBOLIC PROCEDURE MAXORDER(RHS,Z,N);
- % Find a limit on the order of terms, theis is ad hoc;
- IF NULL Z THEN NIL
- ELSE IF EQCAR(CAR Z,'SQRT) THEN
- CONS(1,MAXORDER(RHS,CDR Z,N+1))
- ELSE IF (ATOM CAR Z) OR (CAAR Z NEQ 'TAN) THEN
- CONS(MAXFROM(LHS,N)+1,MAXORDER(RHS,CDR Z,N+1))
- ELSE CONS(TANFROM(RHS,CAR Z,N),MAXORDER(RHS,CDR Z,N+1));
- SYMBOLIC PROCEDURE MAXFROM(L,N);
- % Largest order in the nth varable;
- IF NULL L THEN 0
- ELSE MAX(NTH(CAAR L,N+1),MAXFROM(CDR L,N));
- SYMBOLIC PROCEDURE COPY U;
- IF ATOM U THEN U
- ELSE CONS(COPY CAR U,COPY CDR U);
- SYMBOLIC PROCEDURE ADDCTOMAP CC;
- BEGIN
- SCALAR NCVAL;
- CCOUNT:=CCOUNT+1;
- NCVAL:=MKVECT(CCOUNT);
- FOR I=0:(CCOUNT-1) DO PUTV(NCVAL,I,GETV(CVAL,I));
- PUTV(NCVAL,CCOUNT,NIL ./ 1);
- CVAL:=NCVAL;
- CMAP:=(CC . CCOUNT).CMAP;
- IF !*TRINT THEN << PRIN2 "Constant Map CHANGED TO "; PRINT CMAP >>;
- CMATRIX:=MAPCAR(CMATRIX,FUNCTION ADDTOVECTOR);
- END;
- SYMBOLIC PROCEDURE ADDTOVECTOR V;
- BEGIN SCALAR VV;
- VV:=MKVECT(CCOUNT);
- FOR I=0:(CCOUNT-1) DO PUTV(VV,I,GETV(V,I));
- PUTV(VV,CCOUNT,NIL);
- RETURN VV
- END;
- SYMBOLIC PROCEDURE CHECKCOEFFTS(CL,INDV);
- % checks to see that the coefficients in CL (coefficient list - S.Q.s);
- % are zero when the i,j,k,... are given values in INDV (LPOW of;
- % D.F.). if so the result is true else NIL=false;
- IF NULL CL THEN T
- ELSE BEGIN SCALAR RES;
- RES:=EVALUATECOEFFTS(NUMR CAR CL,INDV);
- IF NOT(NULL RES OR RES=0) THEN RETURN NIL
- ELSE RETURN CHECKCOEFFTS(CDR CL,INDV)
- END;
- SYMBOLIC PROCEDURE NEXTU(LTRHS,POWLHS);
- % picks out the appropriate U coefficients for term: LTRHS to match the;
- % powers of the z-variables given in POWLHS (= exponent list of D.F.). ;
- % return this coefficient in form LT of D.F. If U coefficient does;
- % not exist then result is NIL. If it is multiplied by a zero then;
- % result is NIL;
- IF NULL LTRHS THEN NIL
- ELSE BEGIN SCALAR INDLIST,UCOEFFT;
- INDLIST:=SUBTRACTINDS(POWLHS,CAR LTRHS,NIL);
- IF NULL INDLIST THEN RETURN NIL;
- UCOEFFT:=EVALUATECOEFFTS(NUMR CDR LTRHS,INDLIST);
- IF NULL UCOEFFT OR UCOEFFT=0 THEN RETURN NIL;
- RETURN INDLIST .* (UCOEFFT ./ DENR CDR LTRHS)
- END;
- SYMBOLIC PROCEDURE SUBTRACTINDS(POWLHS,L,SOFAR);
- % subtract the indices in list L from those in POWLHS to find;
- % appropriate values for i,j,k,... when equating coefficients of terms;
- % on lhs of reduction eqn. SOFAR is the resulting value list we;
- % have constructed so far. if any i,j,k,... value is -ve then result;
- % is NIL;
- IF NULL L THEN REVERSEWOC SOFAR
- ELSE IF ((CAR POWLHS)-(CAAR L))<0 THEN NIL
- ELSE SUBTRACTINDS(CDR POWLHS,CDR L,
- ((CAR POWLHS)-(CAAR L)) . SOFAR);
- SYMBOLIC PROCEDURE GAUSSELIMN(EQUATION,TOKILL);
- % Performs Gaussian elimination on the matrix for the c-equations;
- % as each c-equation is found. EQUATION is the next one to deal with;
- BEGIN SCALAR NEWROW,PIVOT;
- IF ZEROP CCOUNT THEN GO TO NOWAY; %FAILURE;
- NEWROW:=MKVECT(CCOUNT);
- SPREADC(EQUATION,NEWROW,1);
- SUBST4ELIMINATEDCS(NEWROW,REVERSE ORDEROFELIM,REVERSE CMATRIX);
- PIVOT:=FINDPIVOT NEWROW;
- IF NULL PIVOT THEN GO TO NOPIVOTFOUND;
- ORDEROFELIM:=PIVOT . ORDEROFELIM;
- NEWROW:=MAKEPRIM NEWROW; %REMOVE HCF FROM NEW EQUATION;
- CMATRIX:=NEWROW . CMATRIX;
- % IF !*TRINT THEN PRINTSPREADC NEWROW;
- RETURN T;
- NOPIVOTFOUND:
- IF NULL GETV(NEWROW,0) THEN <<
- IF !*TRINT THEN PRINTC "Already included";
- RETURN NIL>>; %EQUATION WAS 0=0;
- NOWAY:
- BADPART:=TOKILL . BADPART; %NON-INTEGRABLE TERM;
- IF !*TRINT THEN PRINTC "Inconsistent";
- RETURN NIL
- END;
- SYMBOLIC PROCEDURE MAKEPRIM ROW;
- BEGIN SCALAR I,G;
- G:=GETV(ROW,0);
- FOR I:=1:CCOUNT DO G:=GCDF(G,GETV(ROW,I));
- IF G NEQ 1 THEN
- FOR I:=0:CCOUNT DO PUTV(ROW,I,QUOTF(GETV(ROW,I),G));
- FOR I := 0:CCOUNT DO
- <<G := GETV(ROW,I);
- IF G AND NOT DOMAINP G
- THEN PUTV(ROW,I,NUMR RESIMP((ROOTEXTRACTF G) ./ 1))>>;
- RETURN ROW
- END;
- ENDMODULE;
- MODULE SQRTF;
- EXPORTS MINUSDFP,SQRTDF,NROOTN,DOMAINP,MINUSF;
- IMPORTS CONTENTSMV,GCDF,INTERR,!*MULTF!*,PARTIALDIFF,PRINTDF,QUOTF,
- SIMPSQRT2,VP2;
- %SQUARE-ROOT OF STANDARD FORMS;
- SYMBOLIC PROCEDURE MINUSDFP A;
- %TEST SIGN OF LEADING COEDD OF D.F;
- IF NULL A THEN INTERR "MINUSDFP 0 ILLEGAL"
- ELSE MINUSF NUMR LC A;
- SYMBOLIC PROCEDURE SQRTDF L;
- %TAKES SQUARE ROOT OF D.F.;
- IF NULL L THEN NIL
- ELSE IF NOT NULL RED L THEN 'FAILED
- ELSE BEGIN SCALAR C;
- IF LPOW L=VP2 ZLIST THEN GO TO OK;
- PRINTC "SQRTDF NOT COMPLETE";
- PRINTDF L;
- RETURN 'FAILED;
- OK: RETURN (LPOW L .* SQRTSQ LC L) .+ NIL
- END;
- SYMBOLIC PROCEDURE SQRTSQ A;
- SQRTF NUMR A ./ SQRTF DENR A;
- SYMBOLIC PROCEDURE SQRTF P;
- BEGIN SCALAR IP,QP;
- IF NULL P THEN RETURN NIL;
- IP:=SQRTF1 P;
- QP:=CDR IP;
- IP:=CAR IP; %RESPECTABLE AND NASTY PARTS OF THE SQRT;
- IF ONEP QP THEN RETURN IP; %EXACT ROOT FOUND;
- QP:=SIMPSQRT2 QP;
- RETURN !*F2POL !*MULTF!*(IP,QP)
- END;
- SYMBOLIC PROCEDURE SQRTF1 P;
- %RETURNS A . B WITH P=A**2*B;
- IF DOMAINP P THEN NROOTN(P,2)
- ELSE BEGIN SCALAR CO,PP,G,PG;
- CO:=CONTENTSMV(P,MVAR P,NIL); %CONTENTS OF P;
- PP:=QUOTF(P,CO); %PRIMITIVE PART;
- CO:=SQRTF1(CO); %PROCESS CONTENTS VIA RECURSION;
- G:=GCDF(PP,PARTIALDIFF(PP,MVAR PP));
- PG:=QUOTF(PP,G);
- G:=GCDF(G,PG); %A REPEATED FACTOR OF PP;
- IF G=1 THEN PG:=1 . PP
- ELSE <<
- PG:= !*F2POL QUOTF(PP,!*MULTF!*(G,G)); %WHAT IS STILL LEFT;
- PG:=SQRTF1(PG); %SPLIT THAT UP;
- RPLACA(PG,!*MULTF!*(CAR PG,G))>>;
- %PUT IN THE THING FOUND HERE;
- RPLACA(PG,!*F2POL !*MULTF!*(CAR PG,CAR CO));
- RPLACD(PG,!*F2POL !*MULTF!*(CDR PG,CDR CO));
- RETURN PG
- END;
- % NROOTN removed as in REDUCE base;
- ENDMODULE;
- MODULE TDIFF;
- EXPORTS !-!-SIMPDF;
- IMPORTS SIMPCAR,KERNP,DIFFSQ,PREPSQ,MSGPRI;
- FLAG('(!-!-SIMPDF),'LOSE);
- %TDF(EXPR,VAR) DIFFERENTIATES BUT WITH TIMING SERVICE;
- SYMBOLIC PROCEDURE !-!-SIMPDF U;
- %U IS A LIST OF FORMS, THE FIRST AN EXPRESSION AND THE REMAINDER
- %KERNELS AND NUMBERS.
- %VALUE IS DERIVATIVE OF FIRST FORM WRT REST OF LIST;
- BEGIN SCALAR V,X,Y,TT;
- TT := TIME(); %start the clock;
- V := CDR U;
- U := SIMPCAR U;
- A: IF NULL V OR NULL NUMR U THEN GO TO EXIT;
- X := IF NULL Y OR Y=0 THEN SIMPCAR V ELSE Y;
- IF NULL KERNP X THEN GO TO E;
- X := CAAAAR X;
- V := CDR V;
- IF NULL V THEN GO TO C;
- Y := SIMPCAR V;
- IF NULL NUMR Y THEN GO TO D
- ELSE IF NOT DENR Y=1 OR NOT NUMBERP NUMR Y THEN GO TO C;
- Y := CAR Y;
- V := CDR V;
- B: IF Y=0 THEN GO TO A;
- U := DIFFSQ(U,X);
- Y := Y-1;
- GO TO B;
- C: U := DIFFSQ(U,X);
- GO TO A;
- D: Y := NIL;
- V := CDR V;
- GO TO A;
- EXIT:
- PRINT LIST('TIME,TIME()-TT);
- RETURN U;
- E: MSGPRI("DIFFERENTIATION WRT",PREPSQ X,"NOT ALLOWED",NIL,T)
- END;
- PUT('TDF,'SIMPFN,'!-!-SIMPDF);
- ENDMODULE;
- MODULE TIDYSQRT;
-
- EXPORTS SQRT2TOP;
- %GENERAL TIDYING UP ABOUT SQUARE ROOTS;
-
- %SYMBOLIC PROCEDURE TIDYSQRTDF A;
- % IF NULL A THEN NIL
- % ELSE BEGIN SCALAR TT,R;
- % TT:=TIDYSQRT LC A;
- % R:=TIDYSQRTDF RED A;
- % IF NULL NUMR TT THEN RETURN R;
- % RETURN ((LPOW A) .* TT) .+ R
- % END;
- %
- %SYMBOLIC PROCEDURE TIDYSQRT Q;
- % BEGIN SCALAR NN,DD;
- % NN:=TIDYSQRTF NUMR Q;
- % IF NULL NN THEN NIL ./ 1; %ANSWER IS ZERO;
- % DD:=TIDYSQRTF DENR Q;
- % RETURN MULTSQ(NN,INVSQ DD)
- % END;
- %
- %
- %SYMBOLIC PROCEDURE TIDYSQRTF P;
- %%INPUT - STANDARD FORM;
- %%OUTPUT - STANDARD QUOTIENT;
- %% SIMPLIFIES SQRT(A)**N WITH N>1;
- % IF DOMAINP P THEN P ./ 1
- % ELSE BEGIN SCALAR V,W;
- % V:=LPOW P;
- % IF CAR V='I THEN V:=MKSP('(SQRT -1),CDR V); %I->SQRT(-1);
- % IF EQCAR(CAR V,'SQRT) AND NOT ONEP CDR V THEN BEGIN SCALAR X;
- % %HERE WE HAVE A REDUCTION TO APPLY;
- % X:=DIVIDE(CDR V,2); %HALVE EXPONENT;
- % W:=EXPTSQ(SIMP CADAR V,CAR X); %RATIONAL PART OF ANSWER;
- % IF NOT ZEROP CDR X THEN W:=MULTSQ(W,
- % ((MKSP(CAR V,1) .* 1) .+ NIL) ./ 1);
- % %THE NEXT LINE ALLOWS FOR THE HORRORS OF NESTED SQRTS;
- % W:=TIDYSQRT W
- % END
- % ELSE W:=((V .* 1) .+ NIL) ./ 1;
- % V:=MULTSQ(W,TIDYSQRTF LC P);
- % RETURN ADDSQ(V,TIDYSQRTF RED P)
- % END;
- %
- %
- %MOVE SQRTS IN A SQ TO THE NUMERATOR;
-
- SYMBOLIC PROCEDURE MULTOUTDENR Q;
- BEGIN SCALAR N,D,ROOT,CONJ;
- N:=NUMR Q;
- D:=DENR Q;
- LOOP:ROOT:=FINDSQUAREROOT D; %SEARCH DENOM;
- IF NULL ROOT THEN RETURN (N . D);
- %NOTHING TO BE DONE;
- CONJ:=CONJUGATEWRT(D,ROOT);
- N:=!*F2POL !*MULTF!*(N,CONJ);
- D:=!*F2POL !*MULTF!*(D,CONJ);
- GO TO LOOP
- END;
-
-
- SYMBOLIC PROCEDURE SQRT2TOP Q;
- BEGIN
- SCALAR N,D;
- N:=MULTOUTDENR Q;
- D:=DENR N;
- N:=NUMR N;
- IF D EQ DENR Q
- THEN RETURN Q;%NO CHANGE;
- IF D IEQUAL 1
- THEN RETURN (N ./ 1);
- Q:=GCDCOEFFSOFSQRTS N;
- IF Q IEQUAL 1
- THEN IF MINUSF D
- THEN RETURN (NEGF N ./ NEGF D)
- ELSE RETURN (N ./ D);
- Q:=GCDF(Q,D);
- N:=QUOTF(N,Q);
- D:=QUOTF(D,Q);
- IF MINUSF D
- THEN RETURN (NEGF N ./ NEGF D)
- ELSE RETURN (N ./ D)
- END;
-
-
- %SYMBOLIC PROCEDURE DENRSQRT2TOP Q;
- %BEGIN
- % SCALAR N,D;
- % N:=MULTOUTDENR Q;
- % D:=DENR N;
- % N:=NUMR N;
- % IF D EQ DENR Q
- % THEN RETURN D; %NO CHANGES;
- % IF D IEQUAL 1
- % THEN RETURN 1;
- % Q:=GCDCOEFFSOFSQRTS N;
- % IF Q IEQUAL 1
- % THEN RETURN D;
- % Q:=GCDF(Q,D);
- % IF Q IEQUAL 1
- % THEN RETURN D
- % ELSE RETURN QUOTF(D,Q)
- % END;
-
- SYMBOLIC PROCEDURE FINDSQUAREROOT P;
- %LOCATE A SQRT SYMBOL IN POLY P;
- IF DOMAINP P THEN NIL
- ELSE BEGIN SCALAR W;
- W:=MVAR P; %CHECK MAIN VAR FIRST;
- IF ATOM W
- THEN RETURN NIL; %WE HAVE PASSED ALL SQRTS;
- IF EQCAR(W,'SQRT) THEN RETURN W;
- W:=FINDSQUAREROOT LC P;
- IF NULL W THEN W:=FINDSQUAREROOT RED P;
- RETURN W
- END;
-
- SYMBOLIC PROCEDURE CONJUGATEWRT(P,VAR);
- % VAR -> -VAR IN FORM P;
- IF DOMAINP P THEN P
- ELSE IF MVAR P=VAR THEN BEGIN
- SCALAR X,C,R;
- X:=TDEG LT P; %DEGREE;
- C:=LC P; %COEFFICIENT;
- R:=RED P; %REDUCTUM;
- X:=REMAINDER(X,2); %NOW JUST 0 OR 1;
- IF X=1 THEN C:=NEGF C; %-COEFFICIENT;
- RETURN (LPOW P .* C) .+ CONJUGATEWRT(R,VAR) END
- ELSE IF ORDOP(VAR,MVAR P) THEN P
- ELSE (LPOW P .* CONJUGATEWRT(LC P,VAR)) .+
- CONJUGATEWRT(RED P,VAR);
-
- SYMBOLIC PROCEDURE GCDCOEFFSOFSQRTS U;
- IF ATOM U
- THEN IF NUMBERP U AND MINUSP U
- THEN -U
- ELSE U
- ELSE IF EQCAR(MVAR U,'SQRT)
- THEN BEGIN
- SCALAR V;
- V:=GCDCOEFFSOFSQRTS LC U;
- IF V IEQUAL 1
- THEN RETURN V
- ELSE RETURN GCDF(V,GCDCOEFFSOFSQRTS RED U)
- END
- ELSE BEGIN
- SCALAR ROOT;
- ROOT:=FINDSQUAREROOT U;
- IF NULL ROOT
- THEN RETURN U;
- U:=MAKEMAINVAR(U,ROOT);
- ROOT:=GCDCOEFFSOFSQRTS LC U;
- IF ROOT IEQUAL 1
- THEN RETURN 1
- ELSE RETURN GCDF(ROOT,GCDCOEFFSOFSQRTS RED U)
- END;
- ENDMODULE;
- MODULE TRCASE;
- EXPORTS TRANSCENDENTALCASE;
- IMPORTS BACKSUBST4CS,COUNTZ,CREATECMAP,CREATEINDICES,DF2Q,DFNUMR,
- DIFFLOGS,FSDF,FACTORLISTLIST,FINDSQRTS,FINDTRIALDIVS,GCDF,MKVECT,
- INTERR,LOGSTOSQ,MERGIN,MULTBYARBPOWERS,!*MULTF!*,MULTSQFREE,
- PRINTDF,PRINTFACTORS,PRINTSQ,QUOTF,RATIONALINTEGRATE,PUTV,
- SIMPINT1,SOLVE!-FOR!-U,SQFREE,SQMERGE,SQRT2TOP,SUBSTINULIST,TRIALDIV,
- MERGEIN,NEGSQ,ADDSQ,F2DF,MKNILL,PNTH,INVSQ,MULTSQ,DOMAINP,MK!*SQ,
- MKSP,PRETTYPRINT,PREPSQ;
- FLUID '(DENBAD VAR XLOGS); % For the ERRORSET below;
- SYMBOLIC
- PROCEDURE TRANSCENDENTALCASE(INTEGRAND,VAR,XLOGS,ZLIST,VARLIST);
- BEGIN SCALAR DIVLIST,W,JHD!-CONTENT,CONTENT,PRIM,SQFR,DFU,INDEXLIST,
- % JHD!-CONTENT is local, while CONTENT is free (set in SQFREE);
- SILLIESLIST,ORIGINALORDER,ORIGINALLHS,WRONGWAY,
- SQRTLIST,TANLIST,LOGLIST,DFLOGS,EPRIM,DFUN,UNINTEGRAND,
- SQRTFLAG,BADPART,RHS,LHS,GCDQ,CMAP,CVAL,ORDEROFELIM,CMATRIX;
- SCALAR CUBEROOTFLAG,CCOUNT,DENOMINATOR,RESULT,DENBAD;
- GENSYMCOUNT:=0;
- INTEGRAND:=SQRT2TOP INTEGRAND; % Move the sqrts to the numerator;
- IF !*TRINT THEN << PRINTC "EXTENSION VARIABLES Z<I> ARE";
- PRINT ZLIST>>;
- IF !*RATINTSPECIAL AND NULL CDR ZLIST THEN
- RETURN RATIONALINTEGRATE(INTEGRAND,VAR);
- % *** NOW UNNORMALIZE INTEGRAND, MAYBE *** ;
- BEGIN SCALAR W,Z,GG;
- GG:=1;
- FOREACH Z IN ZLIST DO <<
- W:=DIFFSQ(SIMP Z,VAR);
- GG:=MULTF(GG,QUOTF(DENR W,GCDF(DENR W,GG))) >>;
- GG:=QUOTF(GG,GCDF(GG,DENR INTEGRAND));
- UNINTEGRAND:=(MULTF(GG,NUMR INTEGRAND)
- ./ MULTF(GG,DENR INTEGRAND));
- IF !*TRINT THEN <<
- PRINTC "UNNORMALIZED INTEGRAND =";
- PRINTSQ UNINTEGRAND >> END;
- DIVLIST:=FINDTRIALDIVS ZLIST;
- %ALSO PUTS SOME THINGS ON LOGLIST SOMETIMES;
- % IF !*TRINT THEN << PRINTC "EXPONENTIALS AND TANS TO TRY DIVIDING:";
- % PRINT DIVLIST>>;
- SQRTLIST:=FINDSQRTS ZLIST;
- % IF !*TRINT THEN << PRINTC "SQUARE-ROOT Z-VARIABLES";
- % PRINT SQRTLIST >>;
- DIVLIST:=TRIALDIV(DENR UNINTEGRAND,DIVLIST);
- % IF !*TRINT THEN << PRINTC "DIVISORS:";
- % PRINT CAR DIVLIST;
- % PRINT CDR DIVLIST>>;
- %N.B. THE NEXT LINE ALSO SETS 'CONTENT' AS A FREE VARIABLE;
- % Since SQFREE may be used later, we copy it into JHD!-CONTENT;
- PRIM:=SQFREE(CDR DIVLIST,ZLIST);
- JHD!-CONTENT:=CONTENT;
- PRINTFACTORS(PRIM,NIL);
- EPRIM:=SQMERGE(COUNTZ CAR DIVLIST,PRIM,NIL);
- PRINTFACTORS(EPRIM,T);
- % IF !*TRINT THEN << TERPRI();
- % PRINTSF DENOMINATOR;
- % TERPRI();
- % PRINTC "...CONTENT IS:";
- % PRINTSF JHD!-CONTENT>>;
- SQFR:=MULTSQFREE EPRIM;
- % IF !*TRINT THEN << PRINTC "...SQFR IS:";
- % SUPERPRINT SQFR>>;
- INDEXLIST:=CREATEINDICES ZLIST;
- % IF !*TRINT THEN << PRINTC "...INDICES ARE:";
- % SUPERPRINT INDEXLIST>>;
- DFU:=DFNUMR(VAR,CAR DIVLIST);
- % IF !*TRINT THEN << TERPRI();
- % PRINTC "************ DERIVATIVE OF U IS:";
- % PRINTSQ DFU>>;
- LOGLIST:=APPEND(LOGLIST,FACTORLISTLIST (PRIM,NIL));
- LOGLIST:=MERGEIN(XLOGS,LOGLIST);
- LOGLIST:=MERGEIN(TANLIST,LOGLIST);
- CMAP:=CREATECMAP();
- CCOUNT:=LENGTH CMAP;
- IF !*TRINT THEN << PRINTC "LOGLIST ";
- PRINT LOGLIST >>;
- DFLOGS:=DIFFLOGS(LOGLIST,DENR UNINTEGRAND,VAR);
- IF !*TRINT THEN << PRINTC "************ 'DERIVATIVE' OF LOGS IS:";
- PRINTSQ DFLOGS>>;
- DFLOGS:=ADDSQ((NUMR UNINTEGRAND) ./ 1,NEGSQ DFLOGS);
- % Put everything in reduction eqn over common denominator: ;
- GCDQ:=GCDF(DENR DFLOGS,DENR DFU);
- DFUN:= !*F2POL !*MULTF!*(NUMR DFU,
- DENBAD:=QUOTF(DENR DFLOGS,GCDQ));
- DENBAD:=!*MULTF!*(DENR DFU,DENBAD);
- DENBAD:= !*F2POL !*MULTF!*(DENR UNINTEGRAND,DENBAD);
- DFLOGS:= !*F2POL !*MULTF!*(NUMR DFLOGS,QUOTF(DENR DFU,GCDQ));
- DFU:=DFUN;
- % Now DFU and DFLOGS are S.F.s;
- RHS:=MULTBYARBPOWERS F2DF DFU;
- IF !*TRINT THEN << PRINTC "Distributed Form of U is:";
- PRINTDF RHS>>;
- LHS:=F2DF DFLOGS;
- IF !*TRINT THEN << PRINTC "Distributed Form of l.h.s. is:";
- PRINTDF LHS;
- TERPRI()>>;
- CVAL:=MKVECT(CCOUNT);
- FOR I:=0 : CCOUNT DO PUTV(CVAL,I,NIL ./ 1);
- LORDER:=MAXORDER(RHS,ZLIST,0);
- ORIGINALORDER:=LORDER;
- ORIGINALLHS:=LHS;
- IF !*TRINT THEN << PRINTC "Maximum order determined as ";
- PRINT LORDER >>;
- IF !*STATISTICS THEN << !*NUMBER!*:=0;
- !*SPSIZE!*:=1;
- FOREACH XX IN LORDER DO
- !*SPSIZE!*:=!*SPSIZE!* * (XX+1) >>;
- % That calculates the largest U that can appear;
- DFUN:=SOLVE!-FOR!-U(RHS,LHS,NIL);
- BACKSUBST4CS(NIL,ORDEROFELIM,CMATRIX);
- % IF !*TRINT THEN IF NOT (CCOUNT=0) THEN PRINTVECSQ CVAL;
- IF !*STATISTICS THEN << PRIN2 !*NUMBER!*; PRIN2 " used out of ";
- PRINTC !*SPSIZE!* >>;
- BADPART:=SUBSTINULIST BADPART;
- %SUBSTITUTE FOR C<I> STILL IN BADPART;
- DFUN:=DF2Q SUBSTINULIST DFUN;
- % IF !*TRINT THEN SUPERPRINT DFUN;
- RESULT:= SUBS2Q MULTSQ(DFUN,INVSQ(DENOMINATOR ./ 1));
- RESULT:= SUBS2Q MULTSQ(RESULT,INVSQ(JHD!-CONTENT ./ 1));
- % IF !*TRINT THEN SUPERPRINT RESULT;
- DFLOGS:=LOGSTOSQ();
- IF NOT NULL NUMR DFLOGS
- THEN RESULT:=ADDSQ(RESULT,DFLOGS);
- IF !*TRINT THEN << SUPERPRINT RESULT;
- TERPRI();
- PRINTC
- "*****************************************************";
- PRINTC
- "************ THE INTEGRAL IS : **********************";
- PRINTC
- "*****************************************************";
- TERPRI();
- PRINTSQ RESULT;
- TERPRI()>>;
- IF NOT NULL BADPART THEN <<
- IF !*TRINT THEN PRINTC "PLUS A BAD PART";
- LHS:=BADPART;
- LORDER:=MAXORDER(RHS,ZLIST,0);
- WHILE LORDER DO <<
- IF CAR LORDER > CAR ORIGINALORDER THEN
- WRONGWAY:=T;
- LORDER:=CDR LORDER;
- ORIGINALORDER:=CDR ORIGINALORDER >>;
- DFUN:=DF2Q BADPART;
- IF !*TRINT
- THEN <<PRINTSQ DFUN; PRINTC "DENBAD = "; PRINTSF DENBAD>>;
- DFUN:= SUBS2Q MULTSQ(DFUN,INVSQ(DENBAD ./ 1));
- IF WRONGWAY THEN << RESULT:= NIL ./ 1; DFUN:=INTEGRAND >>;
- IF ROOTCHECKP(UNINTEGRAND,VAR) THEN
- RETURN SIMPINT1(INTEGRAND . VAR.NIL)
- ELSE IF !*PURERISCH OR ALLOWEDFNS ZLIST THEN
- DFUN:=SIMPINT1 (DFUN . VAR.NIL)
- ELSE << !*PURERISCH:=T;
- IF !*TRINT
- THEN <<PRINTC " [Transforming ..."; PRINTSQ DFUN>>;
- DENBAD:=TRANSFORM(DFUN,VAR);
- IF DENBAD=DFUN
- THEN DFUN:=SIMPINT1(DFUN . VAR.NIL)
- ELSE <<DENBAD:=ERRORSET('(INTEGRATESQ DENBAD VAR XLOGS),
- NIL,!*BACKTRACE);
- IF NOT ATOM DENBAD THEN DFUN:=UNTAN CAR DENBAD
- ELSE DFUN:=SIMPINT1(DFUN . VAR.NIL) >> >>;
- IF !*TRINT THEN PRINTSQ DFUN;
- IF !*FAILHARD THEN INTERR "FAILHARD SWITCH SET";
- RESULT:=ADDSQ(RESULT,DFUN) >>;
- % IF !*OVERLAYMODE
- % THEN EXCISE TRANSCODE;
- RETURN SQRT2TOP RESULT
- END;
- %UNFLUID '(DFUN VAR XLOGS);
- ENDMODULE;
- MODULE HALFANGLE;
- EXPORTS HALFANGLE,UNTAN;
- SYMBOLIC PROCEDURE TRANSFORM(U,X);
- % Transform the SQ U to remove the 'bad' functions sin, cos, cot etc
- % in favor of half angles;
- HALFANGLE(U,X);
- % Rest of this page is due to Harrington;
- %PROCEDURES FOR CONVERSION TO HALF ANGLE TANGENTS;
- % SOME NEWRED PROCEDURES THAT IM USED TO;
- SYMBOLIC PROCEDURE QUOTQQ(U1,V1);
- MULTSQ(U1, INVSQ(V1));
- SYMBOLIC PROCEDURE !*SUBTRQ(U1,V1);
- ADDSQ(U1, NEGSQ(V1));
- SYMBOLIC PROCEDURE !*INT2QM(U1);
- IF U1=0 THEN NIL . 1 ELSE U1 . 1;
- SYMBOLIC PROCEDURE HALFANGLE(R,X);
- % TOP LEVEL PROCEDURE FOR CONVERTING;
- % R IS A RATIONAL EXPRESSION TO BE CONVERTED,
- % X THE INTEGRATION VARIABLE;
- % A RATIONAL EXPRESSION IS RETURNED;
- QUOTQQ(HFAGLF(NUMR(R),X), HFAGLF(DENR(R),X));
- SYMBOLIC PROCEDURE HFAGLF(P,X);
- % CONVERTING POLYNOMIALS, A RATIONAL EXPRESSION IS RETURNED;
- IF DOMAINP(P) THEN !*F2Q(P)
- ELSE SUBS2Q ADDSQ(MULTSQ(EXPTSQ(HFAGLK(MVAR(P),X), LDEG(P)),
- HFAGLF(LC(P),X)),
- HFAGLF(RED(P),X));
- SYMBOLIC PROCEDURE HFAGLK(K,X);
- % CONVERTING KERNELS, A RATIONAL EXPRESSION IS RETURNED;
- BEGIN
- SCALAR KT;
- IF ATOM K OR NOT MEMBER(X,FLATTEN(CDR(K))) THEN RETURN !*K2Q K;
- K := CAR(K) . HFAGLARGS(CDR(K), X);
- KT := SIMP LIST('TAN, LIST('QUOTIENT, CADR(K), 2));
- RETURN IF CAR(K) = 'SIN
- THEN QUOTQQ(MULTSQ(!*INT2QM(2),KT), ADDSQ(!*INT2QM(1),
- EXPTSQ(KT,2)))
- ELSE IF CAR(K) = 'COS
- THEN QUOTQQ(!*SUBTRQ(!*INT2QM(1), EXPTSQ(KT,2)), ADDSQ(!*INT2QM(1),
- EXPTSQ(KT,2)))
- ELSE IF CAR(K) = 'TAN
- THEN QUOTQQ(MULTSQ(!*INT2QM(2),KT), !*SUBTRQ(!*INT2QM(1),
- EXPTSQ(KT,2)))
- ELSE IF CAR(K) = 'SINH THEN
- QUOTQQ(!*SUBTRQ(EXPTSQ(!*K2Q('EXPT.('E. CDR K)),2),
- !*INT2QM(1)), MULTSQ(!*INT2QM(2), !*K2Q('EXPT . ('E . CDR(K)))))
- ELSE IF CAR(K) = 'COSH THEN
- QUOTQQ(ADDSQ(EXPTSQ(!*K2Q('EXPT.('E. CDR K)),2),
- !*INT2QM(1)), MULTSQ(!*INT2QM(2), !*K2Q('EXPT . ('E . CDR(K)))))
- ELSE IF CAR(K) = 'TANH THEN
- QUOTQQ(!*SUBTRQ(EXPTSQ(!*K2Q('EXPT.('E. CDR K)),2),
- !*INT2QM(1)), ADDSQ(EXPTSQ(!*K2Q ('EXPT.('E.CDR(K))),2),
- !*INT2QM(1)))
- ELSE !*K2Q(K); % ADDITIONAL TRANSFORMATION MIGHT BE ADDED HERE;
- END;
- SYMBOLIC PROCEDURE HFAGLARGS(L,X);
- %CONVERSION OF ARGUMENT LIST;
- IF NULL L THEN NIL
- ELSE PREPSQ(HFAGLK(CAR(L),X)) . HFAGLARGS(CDR(L), X);
- SYMBOLIC PROCEDURE UNTANF X;
- BEGIN SCALAR Y,Z,W;
- IF DOMAINP X THEN RETURN X . 1;
- Y := MVAR X;
- IF EQCAR(Y,'INT) THEN ERROR(99,NIL); %assume all is hopeless;
- Z := LDEG X;
- W := 1 . 1;
- Y :=
- IF ATOM Y THEN !*K2Q Y
- ELSE IF CAR Y EQ 'TAN
- THEN IF REMAINDER(Z,2)=0
- THEN <<Z := Z/2;
- SIMP LIST('QUOTIENT,
- LIST('PLUS,
- LIST('MINUS,
- LIST('COS,
- 'TIMES
- . (2 . CDR Y))),
- 1),LIST('PLUS,
- LIST('COS,
- 'TIMES
- . (2 . CDR Y)),
- 1))>>
- ELSE IF Z=1
- THEN SIMP LIST('QUOTIENT,
- LIST('PLUS,
- LIST('MINUS,
- LIST('COS,
- 'TIMES . (2 . CDR Y))),
- 1),LIST('SIN,
- 'TIMES . (2 . CDR Y)))
- ELSE <<Z := (Z - 1)/2;
- W :=
- SIMP LIST('QUOTIENT,
- LIST('PLUS,
- LIST('MINUS,
- LIST('COS,
- 'TIMES
- . (2 . CDR Y))),
- 1),LIST('SIN,
- 'TIMES
- . (2 . CDR Y)));
- SIMP LIST('QUOTIENT,
- LIST('PLUS,
- LIST('MINUS,
- LIST('COS,
- 'TIMES
- . (2 . CDR Y))),
- 1),LIST('PLUS,
- LIST('COS,
- 'TIMES
- . (2 . CDR Y)),
- 1))>>
- ELSE SIMP Y;
- RETURN ADDSQ(MULTSQ(MULTSQ(EXPTSQ(Y,Z),UNTANF LC X),W),
- UNTANF RED X)
- END;
- SYMBOLIC PROCEDURE UNTANLIST(Y);
- IF NULL Y THEN NIL ELSE (PREPSQ (UNTAN(SIMP CAR Y)) . UNTANLIST(CDR Y));
- SYMBOLIC PROCEDURE UNTAN(X);
- COMMENT EXPECTS X TO BE CANONICAL QUOTIENT;
- BEGIN SCALAR Y;
- Y:=COSSQCHK SINSQRDCHK MULTSQ(UNTANF(NUMR X), INVSQ UNTANF(DENR X));
- RETURN IF LENGTH FLATTEN Y>LENGTH FLATTEN X THEN X ELSE Y
- END;
- SYMBOLIC PROCEDURE SINSQRDCHK(X);
- MULTSQ(SINSQCHKF(NUMR X), INVSQ SINSQCHKF(DENR X));
- SYMBOLIC PROCEDURE SINSQCHKF(X);
- BEGIN
- SCALAR Y,Z,W;
- IF DOMAINP X THEN RETURN X . 1;
- Y := MVAR X;
- Z := LDEG X;
- W := 1 . 1;
- Y := IF EQCAR(Y,'SIN) THEN IF REMAINDER(Z,2) = 0
- THEN <<Z := QUOTIENT(Z,2);
- SIMP LIST('PLUS,1,LIST('MINUS,
- LIST('EXPT,('COS . CDR(Y)),2)))>>
- ELSE IF Z = 1 THEN !*K2Q Y
- ELSE << Z := QUOTIENT(DIFFERENCE(Z,1),2); W := !*K2Q Y;
- SIMP LIST('PLUS,1,LIST('MINUS,
- LIST('EXPT,('COS . CDR(Y)),2)))>>
- ELSE !*K2Q Y;
- RETURN ADDSQ(MULTSQ(MULTSQ(EXPTSQ(Y,Z),SINSQCHKF(LC X)),W),
- SINSQCHKF(RED X));
- END;
- SYMBOLIC PROCEDURE COSSQCHKF(X);
- BEGIN
- SCALAR Y,Z,W,X1,X2;
- IF DOMAINP X THEN RETURN X . 1;
- Y := MVAR X;
- Z := LDEG X;
- W := 1 . 1;
- X1 := COSSQCHKF(LC X);
- X2 := COSSQCHKF(RED X);
- X := ADDSQ(MULTSQ(!*P2Q LPOW X,X1),X2);
- Y := IF EQCAR(Y,'COS) THEN IF REMAINDER(Z,2) = 0
- THEN <<Z := QUOTIENT(Z,2);
- SIMP LIST('PLUS,1,LIST('MINUS,
- LIST('EXPT,('SIN . CDR(Y)),2)))>>
- ELSE IF Z = 1 THEN !*K2Q Y
- ELSE << Z := QUOTIENT(DIFFERENCE(Z,1),2); W := !*K2Q Y;
- SIMP LIST('PLUS,1,LIST('MINUS,
- LIST('EXPT,('SIN . CDR(Y)),2)))>>
- ELSE !*K2Q Y;
- Y := ADDSQ(MULTSQ(MULTSQ(EXPTSQ(Y,Z),W),X1),X2);
- RETURN IF LENGTH(Y) > LENGTH(X) THEN X ELSE Y;
- END;
- SYMBOLIC PROCEDURE COSSQCHK(X);
- BEGIN
- SCALAR GCD1;
- GCD1 := !*GCD;
- !*GCD := T;
- X := MULTSQ(COSSQCHKF(NUMR X), INVSQ COSSQCHKF(DENR X));
- !*GCD := GCD1;
- RETURN X;
- END;
- SYMBOLIC PROCEDURE LROOTCHK(L,X);
- % CHECKS EACH MEMBER OF LIST L FOR A ROOT;
- IF NULL L THEN NIL ELSE KROOTCHK(CAR L, X) OR LROOTCHK(CDR L, X);
- SYMBOLIC PROCEDURE KROOTCHK(F,X);
- % CHECKS A KERNEL TO SEE IF IT IS A ROOT;
- IF ATOM F THEN NIL
- ELSE IF CAR(F) = 'SQRT
- AND MEMBER(X, FLATTEN CDR F) THEN T
- ELSE IF CAR(F) = 'EXPT
- AND NOT ATOM CADDR(F)
- AND CAADDR(F) = 'QUOTIENT
- AND MEMBER(X, FLATTEN CADR F) THEN T
- ELSE LROOTCHK(CDR F, X);
- SYMBOLIC PROCEDURE ROOTCHK1P(F,X);
- % CHECKS POLYNOMIAL FOR A ROOT;
- IF DOMAINP F THEN NIL
- ELSE KROOTCHK(MVAR F,X) OR ROOTCHK1P(LC F, X) OR ROOTCHK1P(RED F, X);
- SYMBOLIC PROCEDURE ROOTCHECKP(F,X);
- % CHECKS RATIONAL (STANDARD QUOTIENT) FOR A ROOT;
- ROOTCHK1P(NUMR F, X) OR ROOTCHK1P(DENR F, X);
- ENDMODULE;
- MODULE TRIALDIV;
- EXPORTS COUNTZ,FINDSQRTS,FINDTRIALDIVS,PRINTFACTORS,TRIALDIV,SIMP,MKSP;
- IMPORTS !*MULTF!*,PRINTSF,QUOTF;
- SYMBOLIC PROCEDURE COUNTZ DL;
- % DL is a list of S.F.s;
- BEGIN SCALAR S,N,RL;
- LOOP2: IF NULL DL THEN RETURN ARRANGELISTZ RL;
- N:=1;
- LOOP1: N:=N+1;
- S:=CAR DL;
- DL:=CDR DL;
- IF NOT NULL DL AND (S EQ CAR DL) THEN
- GO TO LOOP1
- ELSE RL:=(S.N).RL;
- GO TO LOOP2
- END;
- SYMBOLIC PROCEDURE ARRANGELISTZ D;
- BEGIN SCALAR N,S,RL,R;
- N:=1;
- IF NULL D THEN RETURN RL;
- LOOPD: IF (CDAR D)=N THEN S:=(CAAR D).S
- ELSE R:=(CAR D).R;
- D:=CDR D;
- IF NOT NULL D THEN GO TO LOOPD;
- D:=R;
- RL:=S.RL;
- S:=NIL;
- R:=NIL;
- N:=N+1;
- IF NOT NULL D THEN GO TO LOOPD;
- RETURN REVERSEWOC RL
- END;
- SYMBOLIC PROCEDURE PRINTFACTORS(W,PRDENOM);
- % W is a list of factors to each power. If PRDENOM is true ;
- % this prints denominator of answer, else prints square-free ;
- % decomposition. ;
- BEGIN SCALAR I,WX;
- I:=1;
- IF PRDENOM THEN <<
- DENOMINATOR:=1;
- IF !*TRINT
- THEN PRINTC "DENOMINATOR OF 1ST PART OF ANSWER IS:";
- IF NOT NULL W THEN W:=CDR W >>;
- LOOPX: IF W=NIL THEN RETURN;
- IF !*TRINT THEN PRINTC ("FACTORS OF MULTIPLICITY".I);
- WX:=CAR W;
- WHILE NOT NULL WX DO <<
- IF !*TRINT THEN PRINTSF CAR WX;
- FOR J:=1 : I DO
- DENOMINATOR:= !*F2POL !*MULTF!*(CAR WX,DENOMINATOR);
- %this call of F2POL is probably not necessary??;
- WX:=CDR WX >>;
- I:=I+1;
- W:=CDR W;
- GO TO LOOPX
- END;
- SYMBOLIC PROCEDURE FINDTRIALDIVS ZL;
- %ZL IS LIST OF KERNELS FOUND IN INTEGRAND. RESULT IS A LIST;
- %GIVING THINGS TO BE TREATED SPECIALLY IN THE INTEGRATION;
- %VIZ: EXPS AND TANS;
- %RESULT IS LIST OF FORM ((A . B) ...);
- % WITH A A KERNEL AND CAR A=EXPT OR TAN;
- % AND B A STANDARD FORM FOR EITHER EXPT OR (1+TAN**2);
- BEGIN SCALAR DLISTS1,ARGS1;
- WHILE NOT NULL ZL DO <<
- IF EXPORTAN CAR ZL THEN <<
- IF CAAR ZL='TAN
- THEN << ARGS1:=(MKSP(CAR ZL,2) .* 1) .+ 1;
- TANLIST:=(ARGS1 ./ 1) . TANLIST>>
- ELSE ARGS1:=!*K2F CAR ZL;
- DLISTS1:=(CAR ZL . ARGS1) . DLISTS1>>;
- ZL:=CDR ZL >>;
- RETURN DLISTS1
- END;
- SYMBOLIC PROCEDURE EXPORTAN DL;
- IF ATOM DL THEN NIL
- ELSE BEGIN
- % EXTRACT EXP OR TAN FNS FROM THE Z-LIST;
- IF EQ(CAR DL,'TAN) THEN RETURN T;
- NXT: IF NOT EQ(CAR DL,'EXPT) THEN RETURN NIL;
- DL:=CADR DL;
- IF ATOM DL THEN RETURN T;
- GO TO NXT
- END;
- SYMBOLIC PROCEDURE FINDSQRTS Z;
- BEGIN SCALAR R;
- WHILE NOT NULL Z DO <<
- IF EQCAR(CAR Z,'SQRT) THEN R:=(CAR Z) . R;
- Z:=CDR Z >>;
- RETURN R
- END;
- SYMBOLIC PROCEDURE TRIALDIV(X,DL);
- BEGIN SCALAR QLIST,Q;
- WHILE NOT NULL DL DO
- IF NOT NULL(Q:=QUOTF(X,CDAR DL)) THEN <<
- IF (CAAAR DL='TAN) AND NOT EQCAR(QLIST,CDAR DL) THEN
- LOGLIST:=('IDEN . SIMP CADR CAAR DL) . LOGLIST;
- %TAN FIDDLE!;
- QLIST:=(CDAR DL).QLIST;
- X:=Q >>
- ELSE DL:=CDR DL;
- RETURN QLIST.X
- END;
- ENDMODULE;
- MODULE UNIFAC;
- EXPORTS EVALAT,LINETHROUGH,QUADTHROUGH,TESTDIV,UNIFAC,ZFACTORS;
- IMPORTS CUBIC,LINFAC,PRINTDF,QUADFAC,QUADRATIC,QUARTIC,VP1,ZFACTOR,
- GCD,MINUSP,PRETTYPRINT;
- %UNIVARIATE FACTORIZATION FOR INTEGRATION;
- SYMBOLIC PROCEDURE ZFACTORS N;
- %PRODUCES A LIST OF ALL (POSITIVE) INTEGER FACTORS OF THE ;
- %INTEGER N;
- IF N=0 THEN LIST 0
- ELSE IF (N:=ABS N)=1 THEN LIST 1
- ELSE COMBINATIONTIMES ZFACTOR N;
- SYMBOLIC PROCEDURE ZFACTOR N;
- % INPUT N A POSITIVE INTEGER;
- % OUTPUT A LIST ((PRIME . EXPONENT) ...) GIVING FACTORS OF N;
- BEGIN SCALAR FL,Q,W,C;
- C:=0; %MULTIPLICITY;
- TRY2: Q:=DIVIDE(N,2); %PULL OUT FACTORS OF 2;
- IF ZEROP CDR Q THEN <<
- C:=C+1;
- N:=CAR Q;
- GO TO TRY2 >>;
- IF NOT ZEROP C THEN FL:=(2 . C) . FL;
- W:=3; C:=0;
- TRYW: Q:=DIVIDE(N,W);
- IF ZEROP CDR Q THEN <<
- C:=C+1;
- N:=CAR Q;
- GO TO TRYW >>;
- IF NOT ZEROP C THEN FL:=(W . C) . FL;
- IF REMAINDER(W,3)=1 THEN W:=W+4
- ELSE W:=W+2;
- C:=0;
- IF NOT ((W*W)>N) THEN GO TO TRYW;
- IF NOT ONEP N THEN FL:=(N . 1) . FL;
- RETURN FL
- END;
- SYMBOLIC PROCEDURE COMBINATIONTIMES FL;
- IF NULL FL THEN LIST 1
- ELSE BEGIN SCALAR N,C,RES,PR;
- N:=CAAR FL; C:=CDAR FL;
- PR:=COMBINATIONTIMES CDR FL;
- WHILE NOT MINUSP C DO <<
- RES:=PUTIN(EXPT(N,C),PR,RES);
- C:=C-1 >>;
- RETURN RES
- END;
- SYMBOLIC PROCEDURE PUTIN(N,L,W);
- IF NULL L THEN W
- ELSE PUTIN(N,CDR L,(N*CAR L) . W);
- SYMBOLIC PROCEDURE UNIFAC(POL,VAR,DEGREE,RES);
- BEGIN SCALAR W,Q,C;
- W:=POL;
- IF !*TRINT THEN SUPERPRINT W;
- %NOW TRY LOOKING FOR LINEAR FACTORS;
- TRYLIN: Q:=LINFAC(W);
- IF NULL CAR Q THEN GO TO NOMORELIN;
- RES := ('LOG . BACK2DF(CAR Q,VAR)) . RES;
- W:=CDR Q;
- GO TO TRYLIN;
- NOMORELIN:
- Q:=QUADFAC(W);
- IF NULL CAR Q THEN GO TO NOMOREQUAD;
- RES := QUADRATIC(BACK2DF(CAR Q,VAR),VAR,RES);
- W:=CDR Q;
- GO TO NOMORELIN;
- NOMOREQUAD:
- IF NULL W THEN RETURN RES; %ALL DONE;
- DEGREE:=CAR W; %DEGREE OF WHAT IS LEFT;
- C:=BACK2DF(W,VAR);
- IF DEGREE=3 THEN RES:=CUBIC(C,VAR,RES)
- ELSE IF DEGREE=4 THEN RES:=QUARTIC(C,VAR,RES)
- ELSE IF ZEROP REMAINDER(DEGREE,2) AND
- PAIRP (Q := HALFPOWER CDDR W)
- THEN <<W := (DEGREE/2) . (CADR W . Q);
- W := UNIFAC(W,VAR,CAR W,NIL);
- RES := PLUCKFACTORS(W,VAR,RES)>>
- ELSE <<
- PRINTC "THE FOLLOWING HAS NOT BEEN SPLIT";
- PRINTDF C;
- RES:=('LOG . C) . RES>>;
- RETURN RES
- END;
- SYMBOLIC PROCEDURE HALFPOWER W;
- IF NULL W THEN NIL
- ELSE IF CAR W=0
- THEN (LAMBDA R;
- IF R EQ 'FAILED THEN R ELSE CADR W . R) HALFPOWER CDDR W
- ELSE 'FAILED;
- SYMBOLIC PROCEDURE PLUCKFACTORS(W,VAR,RES);
- BEGIN SCALAR S,P,Q,R,KNOWNDISCRIMSIGN;
- WHILE W DO
- <<P := CAR W;
- IF CAR P EQ 'ATAN THEN NIL
- ELSE IF CAR P EQ 'LOG
- THEN <<Q := DOUBLEPOWER CDR P . Q;
- %PRIN2 "Q="; %PRINTDF CAR Q;
- >>
- ELSE INTERR "BAD FORM";
- W := CDR W>>;
- WHILE Q DO
- <<P := CAR Q;
- IF CAAAR P=4
- THEN <<KNOWNDISCRIMSIGN := 'NEGATIVE;
- RES := QUARTIC(P,VAR,RES);
- KNOWNDISCRIMSIGN := NIL>>
- ELSE IF CAAAR P=2
- THEN RES := QUADRATIC(P,VAR,RES)
- ELSE RES := ('LOG . P) . RES;
- Q := CDR Q>>;
- RETURN RES
- END;
- SYMBOLIC PROCEDURE DOUBLEPOWER R;
- IF NULL R THEN NIL
- ELSE (LIST(2*CAAAR R) . CDAR R) . DOUBLEPOWER CDR R;
- SYMBOLIC PROCEDURE BACK2DF(P,V);
- %UNDO THE EFFECT OF UNIFORM;
- BEGIN SCALAR R,N;
- N:=CAR P;
- P:=CDR P;
- WHILE NOT MINUSP N DO <<
- IF NOT ZEROP CAR P THEN R:=
- (VP1(V,N,ZLIST) .* (CAR P ./ 1)) .+ R;
- P:=CDR P;
- N:=N-1 >>;
- RETURN REVERSEWOC R
- END;
- SYMBOLIC PROCEDURE EVALAT(P,N);
- %EVALUATE POLYNOMIAL AT INTEGER POINT N;
- BEGIN SCALAR R;
- R:=0;
- P:=CDR P;
- WHILE NOT NULL P DO <<
- R:=N*R+CAR P;
- P:=CDR P >>;
- RETURN R
- END;
- SYMBOLIC PROCEDURE TESTDIV(A,B);
- % QUOTIENT A/B OR FAILED;
- BEGIN SCALAR Q;
- Q:=TESTDIV1(CDR A,CAR A,CDR B,CAR B);
- IF Q='FAILED THEN RETURN Q;
- RETURN (CAR A-CAR B) . Q
- END;
- SYMBOLIC PROCEDURE TESTDIV1(A,DA,B,DB);
- IF DA<DB THEN BEGIN
- CHECK0: IF NULL A THEN RETURN NIL
- ELSE IF NOT ZEROP CAR A THEN RETURN 'FAILED;
- A:=CDR A;
- GO TO CHECK0
- END
- ELSE BEGIN SCALAR Q;
- Q:=DIVIDE(CAR A,CAR B);
- IF ZEROP CDR Q THEN Q:=CAR Q
- ELSE RETURN 'FAILED;
- A:=TESTDIV1(AMBQ(CDR A,CDR B,Q),DA-1,B,DB);
- IF A='FAILED THEN RETURN A;
- RETURN Q . A
- END;
- SYMBOLIC PROCEDURE AMBQ(A,B,Q);
- % A-B*Q WITH Q AN INTEGER;
- IF NULL B THEN A
- ELSE ((CAR A)-(CAR B)*Q) . AMBQ(CDR A,CDR B,Q);
- SYMBOLIC PROCEDURE LINETHROUGH(Y0,Y1);
- BEGIN SCALAR A;
- A:=Y1-Y0;
- IF ZEROP A THEN RETURN 'FAILED;
- IF A<0 THEN <<A:=-A; Y0:=-Y0 >>;
- IF ONEP GCDN(A,Y0) THEN RETURN LIST(1,A,Y0);
- RETURN 'FAILED
- END;
- SYMBOLIC PROCEDURE QUADTHROUGH(YM1,Y0,Y1);
- BEGIN SCALAR A,B,C;
- A:=DIVIDE(YM1+Y1,2);
- IF ZEROP CDR A THEN A:=(CAR A)-Y0
- ELSE RETURN 'FAILED;
- IF ZEROP A THEN RETURN 'FAILED; %LINEAR THINGS ALREADY DONE;
- C:=Y0;
- B:=DIVIDE(Y1-YM1,2);
- IF ZEROP CDR B THEN B:=CAR B
- ELSE RETURN 'FAILED;
- IF NOT ONEP GCDN(A,GCD(B,C)) THEN RETURN 'FAILED;
- IF A<0 THEN <<A:=-A; B:=-B; C:=-C>>;
- RETURN LIST(2,A,B,C)
- END;
- ENDMODULE;
- MODULE UNIFORM;
- EXPORTS UNIFORM;
- IMPORTS EXPONENTOF;
- SYMBOLIC PROCEDURE UNIFORM(P,V);
- %CONVERT FROM D.F. IN ONE VARIABLE (V) TO A SIMPLE LIST OF;
- %COEFFS (WITH DEGREE CONSED ONTO FRONT);
- %FAILS IF COEFFICIENTS ARE NOT ALL SIMPLE INTEGERS;
- IF NULL P THEN 0 . (0 . NIL)
- ELSE BEGIN SCALAR A,B,C,D;
- A:=EXPONENTOF(V,LPOW P,ZLIST);
- B:=LC P;
- IF NOT ONEP DENR B THEN RETURN 'FAILED;
- B:=NUMR B;
- IF NULL B THEN B:=0
- ELSE IF NOT NUMBERP B THEN RETURN 'FAILED;
- IF A=0 THEN RETURN A . (B . NIL); %CONSTANT TERM;
- C:=UNIFORM(RED P,V);
- IF C='FAILED THEN RETURN 'FAILED;
- D:=CAR C;
- C:=CDR C;
- D:=D+1;
- WHILE NOT (A=D) DO <<
- C:=0 . C;
- D:=D+1>>;
- RETURN A . (B . C)
- END;
- ENDMODULE;
- MODULE MAKEVARS;
- EXPORTS GETVARIABLES,VARSINLIST,VARSINSQ,VARSINSF,FINDZVARS,
- CREATEINDICES,MERGEIN;
- IMPORTS DEPENDSP,UNION;
- % Note that 'i' is already maybe committed for sqrt(-1);
- %also 'l' and 'o' are not used as the print badly on certain;
- %terminals etc and may lead to confusion;
- !*GENSYMLIST!* := '(! j ! k ! l ! m ! n ! o ! p ! q ! r ! s
- ! t ! u ! v ! w ! x ! y ! z);
- %MAPC(!*GENSYMLIST!*,FUNCTION REMOB); %REMOB protection;
- SYMBOLIC PROCEDURE VARSINLIST(L,VL);
- %L IS A LIST OF S.Q. - FIND ALL VARIABLES MENTIONED;
- %GIVEN THAL VL IS A LIST ALREADY KNOWN ABOUT;
- BEGIN WHILE NOT NULL L DO <<
- VL:=VARSINSF(NUMR CAR L,VARSINSF(DENR CAR L,VL));
- L:=CDR L >>;
- RETURN VL
- END;
- SYMBOLIC PROCEDURE GETVARIABLES SQ;
- VARSINSF(NUMR SQ,VARSINSF(DENR SQ,NIL));
- SYMBOLIC PROCEDURE VARSINSF(FORM,L);
- IF ATOM FORM THEN L
- ELSE BEGIN
- WHILE NOT ATOM FORM DO <<
- L:=VARSINSF(LC FORM,UNION(L,LIST MVAR FORM));
- FORM:=RED FORM >>;
- RETURN L
- END;
- SYMBOLIC PROCEDURE FINDZVARS(VL,ZL,VAR,FLG);
- BEGIN SCALAR V;
- % VL is the crude list of variables found in the original integrand;
- % ZL must have merged into it all EXP, LOG etc terms from this;
- % If FLG is true then ignore DF as a function;
- SCAN: IF NULL VL THEN RETURN ZL;
- V:=CAR VL; % NEXT VARIABLE;
- VL:=CDR VL;
- % at present items get put onto ZL if they are non-atomic;
- % and they depend on the main variable. The arguments of;
- % functions are decomposed by recursive calls to findzvar;
- %give up if V has been declared dependent on other things;
- IF ASSOC(V,DEPL!*) THEN ERROR1()
- ELSE IF NOT ATOM V AND (NOT V MEMBER ZL) AND DEPENDSP(V,VAR)
- THEN IF CAR V MEMQ '(TIMES QUOTIENT PLUS MINUS DIFFERENCE INT)
- OR (((CAR V) EQ 'EXPT) AND FIXP CADDR V)
- THEN
- ZL:=FINDZVARS(CDR V,ZL,VAR,FLG)
- ELSE IF FLG AND CAR V='DF THEN
- << !*PURERISCH:=T; RETURN ZL >> % TRY AND STOP IT;
- ELSE ZL:=V.FINDZVARS(CDR V,ZL,VAR,FLG);
- % SCAN ARGUMENTS OF FN;
- GO TO SCAN
- END;
- SYMBOLIC PROCEDURE CREATEINDICES ZL;
- % Produces a list of unique indices, each associated with a ;
- % different Z-variable;
- REVERSEWOC CRINDEX1(ZL,!*GENSYMLIST!*);
-
- SYMBOLIC PROCEDURE CRINDEX1(ZL,GL);
- BEGIN IF NULL ZL THEN RETURN NIL;
- IF NULL GL THEN << GL:=LIST GENSYM1 'i; %new symbol needed;
- NCONC(!*GENSYMLIST!*,GL) >>;
- RETURN (CAR GL) . CRINDEX1(CDR ZL,CDR GL) END;
- SYMBOLIC PROCEDURE RMEMBER(A,B);
- IF NULL B THEN NIL
- ELSE IF A=CDAR B THEN CAR B
- ELSE RMEMBER(A,CDR B);
- SYMBOLIC PROCEDURE MERGEIN(DL,LL);
- %ADJOIN LOGS OF THINGS IN DL TO EXISTING LIST LL;
- IF NULL DL THEN LL
- ELSE IF RMEMBER(CAR DL,LL) THEN MERGEIN(CDR DL,LL)
- ELSE MERGEIN(CDR DL,('LOG . CAR DL) . LL);
- ENDMODULE;
- MODULE VECTOR;
- EXPORTS MKIDENM,MKVEC2,MKVEC;
- IMPORTS MKNILL,PNTH;
- SYMBOLIC PROCEDURE MKVEC(L);
- BEGIN
- SCALAR V,I;
- V:=MKVECT(-1+LENGTH L);
- I:=0;
- WHILE L DO <<
- PUTV(V,I,(CAR L) ./ 1);
- I:=I+1;
- L:=CDR L >>;
- RETURN V
- END;
- ENDMODULE;
- END;
|