Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!news.cs.indiana.edu!noose.ecn.purdue.edu!en.ecn.purdue.edu!wscott From: wscott@en.ecn.purdue.edu (Wayne H Scott) Newsgroups: comp.sys.handhelds Subject: Re: Finding roots of Tertiary and above equations? Message-ID: <1991Apr12.123709.1397@en.ecn.purdue.edu> Date: 12 Apr 91 12:37:09 GMT References: <25744@hydra.gatech.EDU> <26780001@hpuamsa.neth.hp.com> Organization: Purdue University Engineering Computer Network Lines: 502 In article <26780001@hpuamsa.neth.hp.com> tonl@hpuamsa.neth.hp.com (Ton 't Lam CRC) writes: >I use the program of Wayne Scott. It is a neat program indeed. > >Regards, >Ton 't Lam. > > You have posted an old version of these routines. Here is a newer one, Article 1164 of comp.sys.handhelds: Newsgroups: comp.sys.handhelds Path: en.ecn.purdue.edu!wscott From: wscott@ecn.purdue.edu (Wayne H Scott) Subject: polynomial routines ver 3.2 Message-ID: <1990Sep3.153439.4558@ecn.purdue.edu> Organization: Purdue University Engineering Computer Network Date: Mon, 3 Sep 90 15:34:39 GMT Here it is, my polynomial routines version 3.2 Changes from version 3.1: - Faster PMUL - RT now works with complex cooeffients - various bug fixes These routines are in the public domain, but I ask that if you use any of them in one of your programs you give me credit. I am also not responsible for any damage caused by these programs. This package include the following programs. TRIM Strip leading zeros from polynomial object. IRT Invert root program. Given n roots it return a nth degree polynomial. PDER Derivative of a polynomial. RDER Derivative of a rational function. PF Partial Fractions. (Handles multiple roots!) FCTP Factor polynomial RT Find roots of any polynomial L2A Convert a list to an array and back. PADD Add two polynomials PMUL Multiply two polynomials. PDIV Divide two polynomials. EVPLY Evalulate a polynomial at a point. COEF Given an equation return a polynomial list. These programs are for the HP-48sx. I have a version of them that works correctly on the HP-28. Send me mail if you want it. I think people will find these very useful and work as I say, but if you find any bugs please send me E-Mail. Comments are also welcome. Some of these routines could be faster (PF, PMUL, ...) tell me if you know how to speed them up. _______________________________________________________________________________ Wayne Scott | INTERNET: wscott@en.ecn.purdue.edu Electrical Engineering | BITNET: wscott%ea.ecn.purdue.edu@purccvm Purdue University | UUCP: {purdue, pur-ee}!en.ecn.purdue.edu!wscott _______________________________________________________________________________ These programs all work on polynomials in the follows form: 3*X^3-7*X^2+5 is entered as { 3 -7 0 5 } Reasons why I use lists instead of arrays include: * lists look better on the stack. (multi-line) * The interactive stack can quickly put serveral items in a list. * Hitting EVAL will quickly return the elements on a list. * the '+' key will add a element to the end or beginning of a list or concat two lists * Internally the main program that needs to be fast (BAIRS) does 100% stack maniplations so speed of arrays vs. lists was not a major issue. * It would be easier for later releases to include symbolic polynomials. so going down the list... The first program is FCTP. (factor polynomial) When it is passed the cooeficients of a polynomial in a list it returns the factor of that polynomal. ex: 1: { 1 -17.8 99.41 -261.218 352.611 -134.106 } FCTP 3: { 1 -4.2 2.1 } 2: { 1 -3.3 6.2 } 1: { 1 -10.3 } This tells us that X^5-17.8*X^4+99.41*X^3-261.218*X^2+352.611*X-134.106 factors to (X^2-4.2*X+2.1)*(X^2-3.3*X+6.2)*(X-10.3) Neat! The next program is RT. (Roots) If given a polynmoial it return its roots. ex: 1: { 1 -17.8 99.41 -261.218 352.611 -134.106 } RT 5: 3.61986841536 4: .58013158464 3: (1.65, 1.8648056199) 2: (1.65, -1.8648056199) 1: 10.3 Very Useful! RT with work with complex cooeffients in the polynomial. These programs use the BAIRS program which performs Bairstow's method of quadratic factors and QUD with does the quadratic equation. TRIM is used to strip the leading zeros from a polynomial list. {0 0 3 0 7 } TRIM => { 3 0 7 } RDER will give the derivative of a rational function. ie. d x + 4 -X^2 - 8*x + 31 -- ------------- = -------------------------------- dx x^2 - 7*x + 3 x^4 - 14*x^3 + 55*x^2 - 42*x + 9 2: { 1 4 } 1: { 1 -7 3 } RDER 2: { -1 -8 31 } 1: { 1 -14 55 -42 9 } I don't know about you but I think it's useful. IRT will return a polynomial whose roots you specify. ie. If a transfer function has zeros at -1, 1 and 5 the function is x^3 - 5*x^2 - x + 5 1: { -1 1 5 } IRT 1: { 1 -5 -1 5 } PDER will return the derivtive of a polynomial. .ie The d/dx (x^3 - 5*x^2 - x + 5) = 3*x^2 - 10*x - 1 1: { 1 -5 -1 5 } PDER 1: { 3 -10 -1 } PF will do a partial fraction expansion on a transfer function. .ie s + 5 1/18 5/270 2/3 1/9 2/27 ----------------- = ----- + ----- - ------- - ------- - ----- (s-4)(s+2)(s-1)^3 (s-4) (s+2) (s-1)^3 (s-1)^2 (s-1) 2: { 1 5 } 1: { 4 -2 1 1 1 } PF 1: { 5.5555e-2 1.85185e-2 -.6666 -.11111 -.074074 } This program expects the polynomial of the numerator to be on level 2 and a list with the poles to be on level 1. Repeated poles are suported but they must be listed in order. The output is a list of the values of the fraction in the same order as the poles were entered. PADD, PMUL, and PDIV are all obvious, they take two polynomial lists off the stack and perform the operation on them. PDIV returns the polynomial and the remainder polynomial. L2A converts a list to and array. (and back) 1: { 1 2 3 } L2A 1: [ 1 2 3 ] L2A 1: { 1 2 3 } EVPLY evalutates and polynomial at a point. x^3 - 3*x^2 +10*x - 5 | x=2.5 = 16.875 2: { 1 -3 10 -5 } 1: 2.5 EVPLY 1: 16.875 P.S. Many thanks to Mattias Dahl & Henrik Johansson for fixs they have made. %%HP: T(3)A(R)F(.); DIR PDIV \<< DUP SIZE 3 ROLLD OBJ\-> \->ARRY SWAP OBJ\-> \->ARRY \-> c b a \<< a b IF c 1 SAME THEN OBJ\-> DROP / OBJ\-> 1 GET \->LIST { 0 } ELSE WHILE OVER SIZE 1 GET c \>= REPEAT DIVV END DROP \-> d \<< a SIZE 1 GET c 1 - - IF DUP NOT THEN 1 END \->LIST d OBJ\-> OBJ\-> DROP \->LIST \>> END \>> \>> TRIM \<< OBJ\-> \-> n \<< n WHILE ROLL DUP ABS NOT n 1 - AND REPEAT DROP 'n' DECR END n ROLLD n \->LIST \>> \>> RDER \<< \-> F G \<< G F PDER PMUL G PDER { -1 } PMUL F PMUL PADD G G PMUL \>> \>> IRT \<< OBJ\-> \-> n \<< IF n 0 > THEN 1 n START n ROLL { 1 } SWAP NEG + NEXT ELSE { 1 } END IF n 1 > THEN 2 n START PMUL NEXT END \>> \>> PDER \<< OBJ\-> \-> n \<< 1 n FOR i n ROLL n i - * NEXT DROP IF n 1 == THEN { 0 } ELSE n 1 - \->LIST END \>> \>> PF \<< MAXR { } \-> Z P OLD LAST \<< 1 P SIZE FOR I P I GET \-> p1 \<< IF p1 OLD \=/ THEN Z p1 EVPLY 1 P SIZE FOR J IF P J GET P I GET \=/ THEN p1 P J GET - / END NEXT p1 'OLD' STO { } 'LAST' STO ELSE IF { } LAST SAME THEN 1 { } 1 P SIZE FOR K P K GET IF DUP p1 == THEN DROP ELSE + END NEXT IRT Z SWAP ELSE LAST OBJ\-> DROP END RDER DUP2 5 PICK 1 + 3 ROLLD 3 \->LIST 'LAST' STO p1 EVPLY SWAP p1 EVPLY SWAP / SWAP ! / END \>> NEXT P SIZE \->LIST \>> \>> FCTP \<< IF DUP SIZE 3 > THEN DUP BAIRS SWAP OVER PDIV DROP FCTP END \>> RT \<< TRIM DUP SIZE \-> n \<< IF n 3 > THEN DUP BAIRS SWAP OVER PDIV DROP \-> A B \<< A RT B RT \>> ELSE IF n 2 > THEN QUD ELSE LIST\-> DROP NEG SWAP / END END \>> \>> L\178A \<< IF DUP TYPE 5 == THEN OBJ\-> \->ARRY ELSE OBJ\-> 1 GET \->LIST END \>> PADD \<< DUP2 SIZE SWAP SIZE \-> A B nB nA \<< A L\178A B L\178A IF nA nB < THEN SWAP END IF nA nB \=/ THEN 1 nA nB - ABS START 0 NEXT END nA nB - ABS 1 + ROLL OBJ\-> 1 GET nA nB - ABS + \->ARRY + L\178A \>> \>> PMUL \<< DUP2 SIZE SWAP SIZE \-> X Y ny nx \<< 1 nx ny + 1 - FOR I 0 NEXT 1 nx FOR I 1 ny FOR J I J + 1 - ROLL X I GET Y J GET * + I J + 1 - ROLLD NEXT NEXT { } 1 nx ny + 1 - START SWAP + NEXT \>> \>> EVPLY \<< OVER IF DUP TYPE 5 == THEN SIZE ELSE SIZE 1 GET END \-> a r n \<< a 1 GET IF n 1 > THEN 2 n FOR i r * a i GET + NEXT END \>> \>> COEF \<< \-> E n \<< 0 n FOR I 0 'X' STO E EVAL 'X' PURGE E 'X' \.d 'E' STO I ! / NEXT 2 n 1 + FOR I I ROLL NEXT n 1 + \->LIST \>> \>> EQ 1 DIVV \<< DUP 1 GET \-> a b c \<< a 1 GET c / DUP b * a SIZE RDM a SWAP - OBJ\-> 1 GETI 1 - PUT \->ARRY SWAP DROP b \>> \>> QUD \<< LIST\-> \->ARRY DUP 1 GET / ARRY\-> DROP ROT DROP SWAP 2 / NEG DUP SQ ROT - \v/ DUP2 + 3 ROLLD - \>> BAIRS \<< OBJ\-> 1 1 \-> n R S \<< DO 0 n 1 + PICK 0 0 0 4 PICK 5 n + 7 FOR J J PICK R 7 PICK * + S 8 PICK * + 7 ROLL DROP DUP 6 ROLLD R 3 PICK * + S 4 PICK * + 5 ROLL DROP -1 STEP 3 PICK SQ 3 PICK 6 PICK * - IF DUP 0 == THEN DROP 1 1 ELSE 6 PICK 6 PICK * 5 PICK 9 PICK * - OVER / 4 PICK 9 PICK * 8 PICK 7 PICK * - ROT / END DUP 'S' STO+ SWAP DUP 'R' STO+ UNTIL (0,1) * + ABS .000000001 < 7 ROLLD 6 DROPN END n DROPN 1 R NEG S NEG 3 \->LIST \>> \>> END -- _______________________________________________________________________________ Wayne Scott | INTERNET: wscott@en.ecn.purdue.edu Electrical Engineering | BITNET: wscott%ea.ecn.purdue.edu@purccvm Purdue University | UUCP: {purdue, pur-ee}!en.ecn.purdue.edu!wscott -- _________________________________________________________________________ Wayne Scott | INTERNET: wscott@ecn.purdue.edu Electrical Engineering | BITNET: wscott%ecn.purdue.edu@purccvm Purdue University | UUCP: {purdue, pur-ee}!ecn.purdue.edu!wscott