RPL calculators never had a simultaneous equation solver until the

MSLV function on the 49 series. Recently I got an HP-28C and decided

to write one small enough to run on it. I wrote the code on the 48GX

and then keyed it in on the HP-28C. The 28C has some annoying

limitations like no storage arithmetic or GET/PUT on local

variables.I changed to using stack storage rather than local variables.

Surprisingly, all those ROLL and PICK operations use less memory

than local variables even though the text is longer. The program

after some optimization is 346 bytes on my 48GX. On the HP-28C I had

1274 bytes free after entering it. The 28C can solve useful systems

of nonlinear equations.The program is also useful on a 48G series machine or a 28S, and is

small and simple to use. It runs quite a bit faster on the 48GX than

on the 48GII, although the 48GII has a much faster editor.To enter the program on a 28C, bring up the STACK menu first,

because most of the keywords you will need are there. Make sure you

enter it correctly. You probably will not be able to edit it. You

may want to put a CLMF at the end so the display goes back to

normal. On a 48 this is not required.To use the solver:

Enter your expressions and save them in variables. They should be

expressions for which the calculator will find a zero. If you start

out with equations, put parens around both sides and change the = to

a - sign.Enter initial guesses and save them in the appropriate variables.

All the variables must exist, so the expressions will eval to

numbers.Enter four lines on the stack:

List of expressions to solve.

List of variables to solve for.

Acceptable error, indicating when to stop.

Delta (small number which is added to obtain slopes.)Run the solver. If you saved it as MSLV, enter MSLV CLMF

Example:

'2*X^3+Y+7*Z-96' 'E1' STO

'3*X+6*Y^3-2*Z-65' 'E2' STO

'-6*X+4*Y+2*Z^3-42' 'E3' STO

1 'X' STO

2 'Y' STO

3 'Z' STO

{ 'E1' 'E2' 'E3' }

{ 'X' 'Y' 'Z' }

1E-7

1E-7

MSLV CLMFIn 4 FIX:

X=3.3161

Y=2.1666

Z=2.9857After the first iteration, you will see two lines. The first shows

the iteration count starting at 1. The second shows the worst

residual. The first line will count up and the second will hopefully

move toward zero.If the equations are ill-behaved the program may generate an error.

Try a different set of initial guesses.The program evals each expression at the current guess and at guess

+ delta for each variable. It fills out a matrix of the slopes and a

vector of the values, uses the built-in linear algebra to solve the

linear system, subtracts the result from the guesses, and repeats

until the worst residual is less than the acceptable error.

%%HP: T(3)A(R)F(.);

\<< 4 PICK SIZE DUP

IDN DUP2 SWAP 1

\->LIST RDM 0 DUP

DO DROP 1 + 0 3

ROLL 1 6 PICK

FOR i 9 PICK i

GET DUP \->NUM 3 ROLL

i 1 \->LIST 3 PICK

PUT 3 ROLLD 1 8

PICK

FOR j 10 PICK

j GET 9 PICK DUP2

STO+ 8 ROLL i j 2

\->LIST 6 PICK \->NUM 6

PICK - 12 PICK /

PUT 8 ROLLD STO-

NEXT ABS 4

ROLL MAX 3 ROLLD

DROP

NEXT DUP 5 PICK

/ 1 7 PICK

FOR i 9 PICK i

GET OVER i 1 \->LIST

GET STO-

NEXT DROP 3

ROLLD OVER 1 DISP

DUP 2 DISP

UNTIL DUP 8 PICK

<

END 9 ROLLD 8

DROPN

\>>-- END --

Quote:

RPL calculators never had a simultaneous equation solver until the

MSLV function on the 49 series. Recently I got an HP-28C and decided

to write one small enough to run on it. I wrote the code on the 48GX

and then keyed it in on the HP-28C. The 28C has some annoying

limitations like no storage arithmetic or GET/PUT on local

variables.

OT, is there any MES or SES for the 42S?

*Edited: 20 Mar 2007, 4:52 p.m. *

This is worth going to the Software Library. So far there's only one 28C/S program there. You might also consider submitting it to hpcalc.org.

Quote:

I changed to using stack storage rather than local variables.

Surprisingly, all those ROLL and PICK operations use less memory

than local variables even though the text is longer.

This technique also makes for faster programs, as you may have noticed. I used it on this simple prime-factorizer for the HP-28C/S, which lacks it. I initially used global variables, then local variables and finally the stack only. The program is not fast because of the simple algorithm I used, but it would have been even slower otherwise.

Since we're talking about equation solver, I'd like to present a linear equations system solver for the HP-28S. It was written by one of my classmates back in 1987 and it was very useful in Circuit Analysis classes:

%%HP: T(3)A(D)F(.);

DIR

\183\<-

\<< VARS 1 OVER

'\183\<-' POS 1 - SUB

PURGE

\>>

SYS

\<< DUP SIZE \-> l

n

\<< n \->LIST

'EQS' STO 0 n

FOR i 1 n

FOR j i j

== 1 0 IFTE l j GET

STO

NEXT 1 n

FOR j '

EQS(j)' \->NUM

NEXT n

\->ARRY i

IF NOT

THEN NEG

'VET' STO

ELSE VET

+ ARRY\-> DROP

END

NEXT { n n

} \->ARRY l PURGE TRN

CONJ 'MAT' STO VET

MAT / n 1

FOR i DUP i

GET l i GET STO -1

STEP VET

ARRY\-> DROP { n 1 }

\->ARRY 'VET' STO

DROP

\>>

\>>

END

Usage and examples in this old thread:

http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv015.cgi?read=82010

Unfortunately it doesn't work on the HP-49/50G. One possible reason is TRN (transpose) behaves differently on the 28/48 and on the 49/50 calculators. Could anyone please point out other reasons?

Regards,

Gerson.

*Edited: 22 Mar 2007, 7:24 a.m. *

Multiple equation solver now down to 333.5 bytes - this is fun!

%%HP: T(3)A(R)F(.);

\<< 4 PICK SIZE DUP IDN

DUP2 SWAP 1 \->LIST RDM

0 DUP DO DROP 1 + 0

ROT 1 6 PICK

FOR i 9 PICK i GET DUP

\->NUM ROT i 1 \->LIST

3 PICK PUT 3 ROLLD

1 8 PICK FOR j

10 PICK j GET 9 PICK DUP2

STO+ 8 ROLL i j 2 \->LIST

6 PICK \->NUM 6 PICK -

12 PICK / PUT 8 ROLLD STO-

NEXT ABS 4 ROLL MAX 3 ROLLD

DROP NEXT 4 PICK / 1 6 PICK

FOR i 8 PICK i GET OVER

i 1 \->LIST GET STO- NEXT

3 ROLLD DUP2 2 DISP 1 DISP

UNTIL DUP 8 PICK < END

9 ROLLD 8 DROPN \>>

Quote:

OT, is there any MES or SES for the 42S?

Here's a quick-and-dirty port of Mike's program to the HP-42S. It could use some work to give it a nice user interface -- entering the vectors with the function and parameter names is pretty awkward right now. See the TEST program for how to initialize the parameters etc.; it's basically identical to Mike's RPL program.

In case you want to run it on an emulator, save yourself the trouble of typing and load mes.raw instead; it contains all the five programs listed below.

- Thomas

00 { 221-Byte Prgm }

01>LBL "MES"

02 CF 21

03 STO 00

04 Rv

05 STO 01

06 Rv

07 STO "VARS"

08 Rv

09 STO "EQS"

10 STO "RES"

11 DIM?

12 Rv

13 ENTER

14 ENTER

15 NEWMAT

16 STO "DER"

17 Rv

18 1E3

19 ÷

20 1

21 +

22 STO 04

23 CLX

24 STO 02

25>LBL 00

26 1

27 STO+ 02

28 CLX

29 STO 03

30 RCL 04

31 STO 05

32>LBL 01

33 INDEX "EQS"

34 RCL 05

35 1

36 STOIJ

37 RCLEL

38 STO 07

39 INDEX "RES"

40 RCL 05

41 1

42 STOIJ

43 XEQ IND 07

44 STOEL

45 ABS

46 RCL 03

47 X<>Y

48 X>Y?

49 STO 03

50 RCL 04

51 STO 06

52>LBL 02

53 INDEX "VARS"

54 RCL 06

55 1

56 STOIJ

57 RCLEL

58 STO 08

59 RCL 00

60 STO+ IND 08

61 XEQ IND 07

62 RCL 00

63 STO- IND 08

64 INDEX "RES"

65 RCL 05

66 1

67 STOIJ

68 R^

69 RCLEL

70 -

71 RCL÷ 00

72 INDEX "DER"

73 RCL 05

74 RCL 06

75 STOIJ

76 Rv

77 Rv

78 STOEL

79 ISG 06

80 GTO 02

81 ISG 05

82 GTO 01

83 RCL "DER"

84 STO÷ "RES"

85 RCL 04

86 STO 05

87>LBL 03

88 INDEX "RES"

89 RCL 05

90 1

91 STOIJ

92 RCLEL

93 INDEX "VARS"

94 RCL 05

95 1

96 STOIJ

97 RCLEL

98 R^

99 STO- IND ST Y

100 ISG 05

101 GTO 03

102 CLA

103 RCL 02

104 AIP

105 |-"\LF"

106 ARCL 03

107 AVIEW

108 RCL 01

109 RCL 03

110 X>=Y?

111 GTO 00

112 CLD

113 END00 { 37-Byte Prgm }

01>LBL "E1"

02 MVAR "X"

03 MVAR "Y"

04 MVAR "Z"

05 2

06 RCL "X"

07 3

08 Y^X

09 ×

10 RCL+ "Y"

11 7

12 RCL× "Z"

13 +

14 96

15 -

16 END00 { 40-Byte Prgm }

01>LBL "E2"

02 MVAR "X"

03 MVAR "Y"

04 MVAR "Z"

05 3

06 RCL× "X"

07 6

08 RCL "Y"

09 3

10 Y^X

11 ×

12 +

13 2

14 RCL× "Z"

15 -

16 65

17 -

18 END00 { 41-Byte Prgm }

01>LBL "E3"

02 MVAR "X"

03 MVAR "Y"

04 MVAR "Z"

05 -6

06 RCL× "X"

07 4

08 RCL× "Y"

09 +

10 2

11 RCL "Z"

12 3

13 Y^X

14 ×

15 +

16 42

17 -

18 END00 { 89-Byte Prgm }

01>LBL "TEST"

02 1

03 STO "X"

04 2

05 STO "Y"

06 3

07 STO "Z"

08 3

09 1

10 NEWMAT

11 ENTER

12 EDIT

13 "E1"

14 ASTO ST X

15 ->

16 "E2"

17 ASTO ST X

18 ->

19 "E3"

20 ASTO ST X

21 EXITALL

22 X<>Y

23 EDIT

24 "X"

25 ASTO ST X

26 ->

27 "Y"

28 ASTO ST X

29 ->

30 "Z"

31 ASTO ST X

32 EXITALL

33 1E-7

34 1E-7

35 XEQ "MES"

36 .END.

*Edited: 24 Mar 2007, 3:29 a.m. *

Thanks! I will give this a try.

Thomas, this is great!

You know, I am embarrassed to say that prior to this I didn't know that alphanumerics could be stored in matrices and vectors on the 42S. I thought you had real matrices and complex matrices, and that was it.

Les

Thomas, for my own purposes I added SF 21 and VIEW "X", etc., to the test routine so I could either see or print the solution rather than search it out in my variable directory.

Les

Printing the solution is a nice improvement, and there are a few others that come to mind: an easier way to enter the list of functions and parameters, and using a VARMENU to let the user set initial values...

I'll try to find some time to spiff up the MES program a little bit next week.

- Thomas