Post Reply 
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
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
Find all posts by this user
Quote this message in a reply
07-08-2019, 01:16 PM
Post: #2
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.
Find all posts by this user
Quote this message in a reply
07-08-2019, 06:26 PM
Post: #3
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. Smile

Hope this helps!
- David
Find all posts by this user
Quote this message in a reply
07-08-2019, 09:25 PM (This post was last modified: 07-08-2019 09:26 PM by Namir.)
Post: #4
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
Find all posts by this user
Quote this message in a reply
07-08-2019, 09:45 PM
Post: #5
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).
Find all posts by this user
Quote this message in a reply
07-08-2019, 11:52 PM
Post: #6
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. Smile

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?
Find all posts by this user
Quote this message in a reply
07-09-2019, 01:06 AM (This post was last modified: 07-09-2019 07:47 AM by Namir.)
Post: #7
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
Find all posts by this user
Quote this message in a reply
07-09-2019, 01:37 PM
Post: #8
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
      \>>
   \>>
\>>
Find all posts by this user
Quote this message in a reply
07-10-2019, 05:02 AM
Post: #9
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
Thanks David!!!!

Namir
Find all posts by this user
Quote this message in a reply
07-11-2019, 01:25 PM (This post was last modified: 07-12-2019 01:38 PM by DavidM.)
Post: #10
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
      \>>
   \>>
\>>
Find all posts by this user
Quote this message in a reply
07-12-2019, 03:55 PM
Post: #11
RE: Need help with RPL Listing for "SOLVER FOR ANY VARIABLE"
David,

Thanks for your good work. This one looks better.

Namir
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: