Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
07-07-2019, 08:45 PM (This post was last modified: 07-07-2019 08:46 PM by Namir.)
Post: #1 Namir Senior Member Posts: 837 Joined: Dec 2013
Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
Hi All,

I have a presentation for HHC2019 that Richard Nelson asked me to do. It is a multi-variable solver. Meaning that given an equation with N variables, you can solve for any variable given fixed values for the remaining N-1 variables.

I would like an RPL version (see teh HP-71B and HP-4C versions that solve for any variable in simple financial equation FV=PV*(1+i)^n).

I will give credit to the author of the author of the version I will use in my presentation. I will also mention that author in my presentation that will appear on YouTube.

Here is the HP-71B Listing

Code:
10 REM SOLVER FOR ANY VARIABLE 20 DIM X(20) 30 READ N, K, T 40 DATA 4, 1, 1E-7 50 FOR I=1 TO N 60 IF I=K THE DISP "GUESS FOR "; 70 DISP "X(";I;")"; @ INPUT X(I) 80 NEXT I 90 H = 0.01*(1 + ABS(X(K))) 100 GOSUB 1000 @ F0 = F 110 X0=X(K) @ X(K) = X0 + H 120 GOSUB 1000 130 D = H * F0 /(F - F0) 140 X(K) = X0 - D 150 IF ABS(D) > T THEN 90 160 DISP "ROOT = ";X(K) 1780 END 1000 REM CALCULATE F(X)=0 1001 REM X(1) = FV = PV*(1+I)^N 1002 REM X(2) = PV 1003 REM X(3) = I 1004 REM X(4) N 1010 F = X(1)-X(2)*(1+X(3))^X(4) 1020 RETURN

For an HP-41C Code, here is the memory map:

Code:
R00 = I R01 = X(1) R02 = X(2) .... R20 = X(20) R21 = N R22 = K R23 = Toler R24 = h R25 = F0 R26 = D R27 = X0

And here is the HP-41C Listing:

Code:
LBL "MVSOLV" LBL A "N?" PROMPT STO 21 1E3 / 1 + STO 00 "K?" PROMPT STO 22 "TOLER?" PROMPT STO 23 LBL 00        # Input variables RCL 22 RCL 00 INT CLA X#Y? "GUESS " |-"X<" FIX 0 ARCL X |-">?" FIX 5 PROMPT STO IND 00 ISG 00 GTO 00        # end of input loop LBL 01 RCL IND 22 ABS 1 + 0.01 * STO 24        # calculate and store h XEQ E STO 25        # calculate F0 RCL IND 22 STO 27        # X0 = X(K) RCL 24 STO+ IND 22    # X(K) = X(K) + h XEQ E RCL 25 - 1/X RCL 25 * RCL 24 * STO 26        # Diff = X(K) - f(X(K)) / f'(X(K)) RCL 27 - CHS STO IND 22    # X(K) = X(K) - Diff RCL 26 ABS RCL 23 X<Y?        # Tolerance less than absolute difference in X(K)? GTO 01        # resume iterations "ROOT=" RCL IND 22 ARCL X PROMPT RTN LBL E 1 RCL 03 + RCL 04 Y^X RCL 02 * RCL 01 - RTN
07-08-2019, 01:16 PM
Post: #2
 Claudio L. Senior Member Posts: 1,844 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
(07-07-2019 08:45 PM)Namir Wrote:  Hi All,

I have a presentation for HHC2019 that Richard Nelson asked me to do. It is a multi-variable solver. Meaning that given an equation with N variables, you can solve for any variable given fixed values for the remaining N-1 variables.

I would like an RPL version (see teh HP-71B and HP-4C versions that solve for any variable in simple financial equation FV=PV*(1+i)^n).

I will give credit to the author of the author of the version I will use in my presentation. I will also mention that author in my presentation that will appear on YouTube.

The "white menu" solver in the 48/50 series does exactly what you are looking for, and with the best (in my opinion) open UI you can get for a solver: just assign values to some variables and solve for others, clean and simple, and no RPL code needed.
The other numerical solver in the 50g can also do that with a different UI (more visual, in my opinion less practical to assign values to variables quickly), also no RPL code needed at all. There are some programmatic ways of using the same built-in solvers, but honestly with two different user interfaces, it's hard to justify writing a program to do it.
You also have available the multiple equation solver, for multiple variables in multiple equations so there's even less need for RPL code. If you still want RPL code, it only needs to store the equation and call the proper menu number to activate the "white menu" solver:
Code:
 << 'FV=PV*(1+i)^n' 'EQ' STO 30 MENU >>

By the way, if it's only the financial equation you are interested in solving, the 50g has the full TVM solver, just setting the payment amounts to 0 you end up with the equation above. That also has a nice UI built-in.
07-08-2019, 06:26 PM
Post: #3
 DavidM Senior Member Posts: 905 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
Namir, if you're simply wanting an RPL version of the same program logic that you're using in the other supplied programs, then the following may provide a starting point.

This is meant to mimic your 71B structure/flow as closely as possible, and uses the same variable names that you specified in that version. As Claudio has mentioned, the built-in solver would be better to use, but I'm guessing you simply want to have an RPL equivalent to the other programs. That's what I've attempted to do here.

Code:
\<<    0. 20. NDUPN \->ARRY          @ X[]    4.                            @ N    1.                            @ K    1E-7                          @ T    'X(1)-X(2)*(1.+X(3))^X(4)'    @ F    0. DUPDUP DUP                 @ F0, X0, H, D    \-> X N K T F F0 X0 H D    \<<       @ obtain X values       1. N FOR index          "X("          IF             index K SAME          THEN             "Guess for " SWAP +          END          index R\->I \->STR +          "):" +          "" INPUT STR\->          'X' index ROT PUT       NEXT       @ repeat until current delta within specified tolerance       DO          X K GET ABS 1. + 0.01 *          'H' STO          F \->NUM          'F0' STO          X K GET          'X0' STO          'X' K          X0 H +          PUT          H F0 * F \->NUM F0 - /          'D' STO          'X' K          X0 D -          PUT       UNTIL          D ABS T \<=       END       @ output X(K)       X K GET "Root" \->TAG    \>> \>>

No attribution needed, you (and everyone else) should feel free to make improvements or modify however you like. My goal in this case was to replicate the same logic flow as the other programs as opposed to focusing on code size, speed, or special RPL features. I used an algebraic for F in this case to make the coding a closer match to the 71B version.

If logic flow parity wasn't your intended target for this, please ignore and move on. Hope this helps!
- David
07-08-2019, 09:25 PM (This post was last modified: 07-08-2019 09:26 PM by Namir.)
Post: #4 Namir Senior Member Posts: 837 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
Thank you David. Your ode will beautifully do the job!!!

Richard Nelson wanted a geneal RPL code that would also work with the HP-48GX.

Namir
07-08-2019, 09:45 PM
Post: #5
 DavidM Senior Member Posts: 905 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
(07-08-2019 09:25 PM)Namir Wrote:  ...that would also work with the HP-48GX.

Oops! I wrote that code with a 50g target, and I know of at least one command it uses (R→I) that isn't applicable to the 48 series. I'm also not sure if array indexing with subscripts works the same way on a 48, so I may need to adjust that as well. I'll redo this and post an update after I've had a moment to go through it with the 48GX as a target (hopefully later this evening).
07-08-2019, 11:52 PM
Post: #6
 DavidM Senior Member Posts: 905 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
So there were actually 3 commands not supported on a 48GX, and I was right about the array subscripts (which are not supported on the 48 series). Also, one additional layer of locals is now needed since the function F references locals from the array that have to already have been declared and in-scope -- being able to define it as an algebraic in the previous example worked around that issue.

I also rearranged the input loop a bit to make it easier to read (IMHO).

It's always surprising to me how often I use commands and features that didn't come into play until the 49-50 series. It doesn't "feel" like I do it that often when I'm coding, but on those rare occasions when I write 48-series code I see the evidence firsthand. Code:
\<<    { 20 } 0 CON                  @ X[]    4                             @ N    1                             @ K    1E-7                          @ T    0 DUP DUP DUP                 @ F0, X0, H, D    \-> X N K T F0 X0 H D    \<<       \<<                        @ F          @ X(1)-X(2)*(1+X(3))^X(4)          X 1 GET          X 2 GET          X 3 GET 1 +          X 4 GET ^          * -       \>>       \-> F       \<<          @ obtain X values          1 N FOR index             "X(" index \->STR + "):" +             IF                index K SAME             THEN                "Guess for " SWAP +             END             "" INPUT STR\->             'X' index ROT PUT          NEXT          @ repeat until current delta within specified tolerance          DO             X K GET ABS 1 + 0.01 *             'H' STO             F EVAL             'F0' STO             X K GET             'X0' STO             'X' K             X0 H +             PUT             H F0 * F EVAL F0 - /             'D' STO             'X' K             X0 D -             PUT          UNTIL             D ABS T \<=          END          @ output X(K)          X K GET "Root" \->TAG       \>>    \>> \>>

Note: I'm just transcoding here, so I'm not asserting that this program is fully debugged and operational. I haven't done much testing -- just a couple of basic scenarios which seem to work.

Question: Have you insured in the algorithm that the indefinite loop exit condition is guaranteed to occur? In other words, is it possible that some inputs might cause the "delta" to always be greater than the tolerance value?
07-09-2019, 01:06 AM (This post was last modified: 07-09-2019 07:47 AM by Namir.)
Post: #7 Namir Senior Member Posts: 837 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
Quote:Question: Have you insured in the algorithm that the indefinite loop exit condition is guaranteed to occur? In other words, is it possible that some inputs might cause the "delta" to always be greater than the tolerance value?

Good point. Here is the HP-71B BASIC listing using a new variable M to control the maximum number of iterations:
Code:
 10 REM SOLVER FOR ANY VARIABLE 20 DIM X(20) 30 READ N, K, T, M 40 DATA 4, 1, 1E-7, 50 50 FOR I=1 TO N 60 IF I=K THE DISP "GUESS FOR "; 70 DISP "X(";I;")"; @ INPUT X(I) 80 NEXT I 90 H = 0.01*(1 + ABS(X(K))) 100 GOSUB 1000 @ F0 = F 110 X0=X(K) @ X(K) = X0 + H 120 GOSUB 1000 130 D = H * F0 /(F - F0) 140 X(K) = X0 - D 145 M = M - 1 150 IF ABS(D) > T AND M > 0 THEN 90 160 DISP "ROOT = ";X(K) 1780 END 1000 REM CALCULATE F(X)=0 1001 REM X(1) = FV = PV*(1+I)^N 1002 REM X(2) = PV 1003 REM X(3) = I 1004 REM X(4) N 1010 F = X(1)-X(2)*(1+X(3))^X(4) 1020 RETURN

Here is the update memory map for the HP-41C to include R28 to store the maximum number of iterations.

Code:
R00 = I R01 = X(1) R02 = X(2) .... R20 = X(20) R21 = N R22 = K R23 = Toler R24 = h R25 = F0 R26 = D R27 = X0 R28 = MAX_ITERS

And here is the HP-41C listing that uses register R28 to control the maximum number of iterations:

Code:
LBL "MVSOLV" LBL A "N?" PROMPT STO 21 1E3 / 1 + STO 00 "K?" PROMPT STO 22 "TOLER?" PROMPT STO 23 "MAXITERS?" PROMPT STO 28 LBL 00        # Input variables RCL 22 RCL 00 INT CLA X#Y? "GUESS " |-"X<" FIX 0 ARCL X |-">?" FIX 5 PROMPT STO IND 00 ISG 00 GTO 00        # end of input loop LBL 01 RCL IND 22 ABS 1 STO- 28        # MAX_ITRER = MAX_ITET - 1 + 0.01 * STO 24        # calculate and store h XEQ E STO 25        # calculate F0 RCL IND 22 STO 27        # X0 = X(K) RCL 24 STO+ IND 22    # X(K) = X(K) + h XEQ E RCL 25 - 1/X RCL 25 * RCL 24 * STO 26        # Diff = X(K) - f(X(K)) / f'(X(K)) RCL 27 - CHS STO IND 22    # X(K) = X(K) - Diff RCL 26 ABS RCL 23 RCL 28 X=0? GTO 02 RDN X<Y?        # Tolerance less than absolute difference in X(K)? GTO 01        # resume iterations LBL 02 "ROOT=" RCL IND 22 ARCL X PROMPT RTN LBL E 1 RCL 03 + RCL 04 Y^X RCL 02 * RCL 01 - RTN

Can you plese update the HP48GX (and also the HP-50G) listing to use the maximum number of iterations of 55?????

with many thanks!

Namir
07-09-2019, 01:37 PM
Post: #8
 DavidM Senior Member Posts: 905 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
(07-09-2019 01:06 AM)Namir Wrote:  Can you plese update the HP48GX (and also the HP-50G) listing to use the maximum number of iterations of 55?????

Your question above indicated 55 for M, but the 71B code used 50. Since my focus is matching the 71B code as much as possible, I used 50.

Rather than maintaining two separate versions, I've made one version which is compatible with the 48GX..50g. That required changing the input routine so that the prompt formatting would be consistent for each of those platforms. I also included radix marks on constants so that approximate (real) numbers would be forced on 49-or-later platforms (again for consistency).

Finally, I changed the ordering of the statements that use PUT in the indefinite loop so that they now follow the same pattern as the others (Line 1: operation, Line 2: STO/PUT). That required an additional command to be added for the PUTs (ROT), but I believe the consistency aids readability more than the cost of a couple extra commands.

Here's what I've got so far:
Code:
%%HP: T(3)A(R)F(.); \<<    @ setup local variables    { 20. } 0. CON                @ X(20)    4. 1. 1E-7 50.                @ N, K, T, M    0. DUP DUP DUP                @ F0, X0, H, D    RCLF                          @ flags    \-> X N K T M F0 X0 H D flags    \<<       @ setup function F       \<<          @ X(1)-X(2)*(1+X(3))^X(4)          X 1. GET          X 2. GET          X 3. GET 1. +          X 4. GET ^          * -       \>>       \-> F       \<<          @ obtain X(n) values from user          0. FIX          1. N FOR index             index K SAME "Guess for " "" IFTE             "X(" +             index \->STR             1. OVER SIZE OVER - SUB +             "):" +             "" INPUT STR\->             'X' index ROT PUT          NEXT          @ repeat until either:          @   1) current delta within specified tolerance, or          @   2) M passes have elapsed          DO             X K GET ABS 1. + 0.01 *             'H' STO             F EVAL             'F0' STO             X K GET             'X0' STO             X0 H +             'X' K ROT PUT             H F0 * F EVAL F0 - /             'D' STO             X0 D -             'X' K ROT PUT          UNTIL             D ABS T \<=             'M' DECR NOT             OR          END          @ output X(K)          X K GET "Root" \->TAG          @ restore flag settings          flags STOF       \>>    \>> \>>
07-10-2019, 05:02 AM
Post: #9 Namir Senior Member Posts: 837 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
Thanks David!!!!

Namir
07-11-2019, 01:25 PM (This post was last modified: 07-12-2019 01:38 PM by DavidM.)
Post: #10
 DavidM Senior Member Posts: 905 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
One more RPL version...

This one is a bit more of a traditional RPL approach. Instead of replicating the exact flow of the 71B steps, it uses the stack for holding the temporary variables F0, X0, H, and D while seeking the root. This makes better use of the calculator's resources (saves 116.5 bytes and executes faster), but also makes the source much harder to read and maintain (IMHO).

In many ways, this follows the usual pattern for RPL (and RPN) code: the more refined and efficient it is, the more fragile it becomes. Whereas in the previous version you could actually see the temporary variable modifications, holding the variables on the stack during execution makes it much harder to follow simply by looking at the code. If the comments are removed, it would be an arduous task to go back and make changes.

Code:
\<<    @ setup local variables    { 20. } 0. CON                @ X(20)    4. 1. 1E-7 50.                @ N, K, T, M    RCLF                          @ flags    \-> X N K T M flags    \<<       @ setup function F       \<<          @ X(1)-X(2)*(1+X(3))^X(4)          X 1. GET          X 2. GET          X 3. GET 1. +          X 4. GET ^          * -       \>>       \-> F       \<<          @ obtain X(n) values from user          0. FIX          1. N FOR index             index K SAME "Guess for " "" IFTE             "X(" +             index \->STR             1. OVER SIZE OVER - SUB +             "):" +             "" INPUT STR\->             'X' index ROT PUT          NEXT          @ repeat until either:          @   1) current delta within specified tolerance, or          @   2) M passes have elapsed          DO             F EVAL                        @ F0=F             X K GET                       @ X0=X(K)             DUP ABS 1. + 0.01 *           @ H=0.01*(1+ABS(X(K)))             DUP2 + 'X' K ROT PUT          @ X(K)=X0+H             ROT F EVAL OVER - / *         @ D=H*F0/(F-F0)             SWAP OVER - 'X' K ROT PUT     @ X(K)=X0-D          UNTIL             ABS T \<=             'M' DECR NOT             OR          END          @ output X(K)          X K GET "Root" \->TAG          @ restore flag settings          flags STOF       \>>    \>> \>>
07-12-2019, 03:55 PM
Post: #11 Namir Senior Member Posts: 837 Joined: Dec 2013
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
David,

Thanks for your good work. This one looks better.

Namir
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)