Example of MISO solver for WP 34s
|
05-22-2018, 09:29 AM
(This post was last modified: 05-22-2018 10:06 AM by gomefun2.)
Post: #1
|
|||
|
|||
Example of MISO solver for WP 34s
I will show an example of how to program a MISO (multiple input single output) solver mapped to a single button press for an equation. This is a MISO solver meaning that each time the program is run a different variable can be solved for, without having to rewrite the equation. This program will have named variables.
The equation the program will solve is Darcy's equation for Steady-State Flow. This is equation 6.4 on page 6.3 at http://infohost.nmt.edu/~petro/faculty/E...idflow.pdf This is a 10 variable equation, with a worked example (at the link) so you can test the code to see if it worked for you. 70 LINES (71 LINES including the final END) (NOTE: I use // for commenting the code) LBL A //using this label assigns the program to the physical 'A button' on the calculator CLα // clears the alpha registry 1 // puts 1 in the x registry STO 00 // stores 1 into R00. R00's only purpose is to act as a pointer to the memory location. storing 1 into R00 means that R00 will point to the registry R01 (see below for example). α's' // alpha's' puts s into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'Pe' // alpha'Pe' puts Pe into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'Pwf' // alpha'Pwf' puts Pwf into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'q' // alpha'q' puts q into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'Bo' // alpha'Bo' puts Bo into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'u' // alpha'u' puts u into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'k' // alpha'k' puts k into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'h' // alpha'h' puts h into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α're' // alpha're' puts re into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' α'rw' // alpha'rw' puts rw into the alpha registry XEQ'VAR' // calls and executes the code at LBL'VAR' RCL 99 // This recalls the location of output variable in memory (see the subfunctions below) STO 00 // This stores the location from R99 into R00 SLV'SSR' // This solves function at LBL'SSR' (steady-state radial) RTN // End of Main Function LBL 'SSR' // This is where the Equation is stored STO->00 // This stores whatever is in the X register to the location that is stored in R00. For example, if R00 contains 2, then the X register is stored to R02. The STO-> is different than STO (-> is for memory address location) // STO->00 has no impact on the equation. The reason it is used is that it tells the calculator which variable to solve for. Whichever variable appears first after LBL'SSR' is the variable the calculator will solve for. By storing 5 into R00, and calling STO->00 as the first line in the equation, the calculator will store a random number into R05. But since R05 appears first the calculator will also solve for this registry as the unknown. It basically tricks the calculator to solving for any variable in the equation. RCL 07 // recall k RCL 08 // recall h * // multiply them RCL 02 // recall Pe RCL 03 // recall Pwf - // subtract them * // multiply #002 // # is for small integers (0-255) this will put the number 2 into the x registry SDR 001 // shifts the decimal place once to the right turn 2 into 0.2 #141 // puts 141 into the x registry + // adds 0.2 and 141 to make 141.2 (the constant in the equation) RCL 06 // u * // multiply RCL 05 // Bo * // multiply RCL 09 // re RCL 10 // rw / // divide LN // natural logarithm RCL 01 // s + // addition * // multiply / // divide RCL 04 // q - // subtract (for the solver to work the equation must be equal to zero (f(x) = 0), so I subtracted q from both sides) RTN // End of the equation sub-function LBL'VAR' // The purpose of this subfunction is to help save space when storing data to registers (these are repetive steps). α'?' // alpha'?' adds a question mark to alpha register, this just makes the prompt look nicer RCL->00 // the -> means this is an address recall. So this line recalls the value stored in the register at the location stored in R00. For example if R00 contains 3, the value stored in R03 is recalled. The purpose of this is to show the user what is currently stored in each variable. PROMPT // This waits for user input (when running the program, key in a number and push R/S to enter the value) STO->00 // Similar to RCL->00 above the -> tells the calculator to store the value in the x register to the location stored in R00. x<0? // this is a test to see if the user input a negative number. The reason this is here is that all the numbers (aside from 's' in the equation must be positive. If a number is an input as negative then this tells the calculator to solve for that variable. It is just a way I decided to trick the calculator to solve for the correct variable. Since S can be negative I put it first, therefore the calculator will only solve for s (even if it is negative) only if all other variables are positive). x<0? is a conditional statement, if true, it will execute the next line of code, if false it will skip the next line of code. XEQ'UNK' // this line executes only if the user puts a negative number in for the current variable. This function stores which variable is the one that should be solved for. INC 00 // this increments R00, this puts a new value into R00, and since R00 is being used as the address locations in the memory this will increment the memory location to the next location. For example, if the program just stored a value into R02, this will increment the program so that the next iteration of the program will store a value into R03. CLα // Clears the alpha registry RTN // Ends the subfunction returns to the entry point in the main function LBL'UNK' // This subfunction stores into memory the variable that should be solved for. RCL 00 // Recalls the memory location stored in R00 STO 99 // Stores the location to R99. Since s is the first variable in the code, even if it is negative, the next iteration with a negative number (the one that actually wants to be solved for) will store its value here overtop the location of s. (s is the only number that could naturally be negative). s is only solved for if it is the only negative number. RTN // ends the subfunction END // Final End This code could probably be modified slightly to make a general purpose MISO solver. I might end up writing that code next. At any rate if anyone has a better way to do this code please let me know. I hope this helps at least one other person because it took me a while to figure this out. Thanks to Dieter on the forum for helping, and also the WP 34s manual. (NOTE: if it isn't clear from the code, the calculator solves for the variable whose initial guess is negative, since these variables are not naturally negative. That is how it decides). |
|||
05-22-2018, 05:40 PM
(This post was last modified: 05-22-2018 05:41 PM by Dieter.)
Post: #2
|
|||
|
|||
RE: Example of MISO solver for WP 34s
(05-22-2018 09:29 AM)gomefun2 Wrote: I will show an example of how to program a MISO (multiple input single output) solver mapped to a single button press for an equation. I'll be glad to look at the program and see how it can be improved, but... sorry, in my humble opinion this is completely unreadable. There is no need to comment each and every line. If there is a line with a "+" it is not required to explain this is an addition, or if there is a "1" noone needs to know that this puts a "1" into X. This is obvious, so please comment only the essential things. For instance you could add the equation that is solved here. Maybe you can provide a new listing, completely uncommented, and with a fixed-width font. Try the "code" box in the message editor. Maybe you can also add line numbers so that everyone who wants to comment on a specific piece of code can do so by referring to the respective line number. Here's a tip: type the program in Excel, add the line numbers in the column left of the code and then copy the result. I hope you do not mind these suggestions, but the way it is now the program is extremely hard to oversee and understand. The pure listing – along with a few explanations after (!) the code – would be very helpful. Edit: Ok, Ok, I did it myself: Code: 001 LBL A By the way: SLV works as a test. If no solution is found the next line is skipped! This way you can add your own error handler. And SLV expects two initial guesses in X and Y. How does your program handle this? Dieter |
|||
05-22-2018, 07:43 PM
(This post was last modified: 05-22-2018 10:08 PM by Dieter.)
Post: #3
|
|||
|
|||
RE: Example of MISO solver for WP 34s
(05-22-2018 09:29 AM)gomefun2 Wrote: I will show an example of how to program a MISO (multiple input single output) solver mapped to a single button press for an equation. OK, here is my very first, almost untested version, so try it at your own risk ;-) Code: 001 LBL A Some remarks:
I tried the formula in the PDF and solved for q first (result: q=1120,966). Then I changed q to 1000 and solved for µ which was then returned as µ=0,6105. So far for the moment. ;-) Dieter |
|||
05-23-2018, 05:47 PM
(This post was last modified: 05-24-2018 02:35 PM by burkhard.)
Post: #4
|
|||
|
|||
RE: Example of MISO solver for WP 34s
I had a little fun keying this (the original version) in on my lunch break and figuring out the syntax to get some of the characters to appear. Fortunately I purchased the WP-34s manual :-)
A couple of comments: 1. Nice job! Thanks for including the PDF ref with the example with numbers given. That made a nice check that everything went in OK. I'd like to see more programs that demonstrate the ropes of WP34s programming capability. It is really a pretty handy *small* calculator. 2. I had heard the acronym MISO before, but didn't know the meaning. I understand now and can appreciate the usefulness of being able to solve for any one of the variables. I also like that it can be run repeatedly in sequence, each time retaining the prior inputs as defaults. 3. Your using a negative number as a flag to mean ""Solve for me!" was clever and sensible for this specific example. One can't get away with that always, though... 4. While I agree with Dieter that one doesn't need to comment a simple addition operation, a lot of the comments within "VAR" and "SSR" subroutines were pretty useful and appreciated. Perhaps they aren't needed for an experienced master of keystroke programming, but they were helpful to me. Completely stripping them all out would be a loss. Maybe put them below the code as footnotes by step number so they can be referenced only if needed? 5. Monospaced font was a lot easier to read :-) Thanks again! |
|||
05-23-2018, 07:36 PM
Post: #5
|
|||
|
|||
RE: Example of MISO solver for WP 34s
(05-23-2018 05:47 PM)burkhard Wrote: 3. Your using a negative number as a flag to mean ""Solve for me!" was clever and sensible for this specific example. One can't get away with that always, though... I just noticed that even in the given example equation one of the variables (S) may be negative. So there has to be a workaround. The original program prompts for S as the first variable, and when the solver starts it does not check if a negative value has been entered (instead it solves for S). This is a possible solution for this particular case. My program version (which checks if the user has selected a variable) can not handle negative S values. It assumes that all data is non-negative. So there should be a better solution for flagging the variable to solve for. I have been thinking about several methods, but none is really convincing. Maybe someone has a better idea? Dieter |
|||
05-23-2018, 09:57 PM
Post: #6
|
|||
|
|||
RE: Example of MISO solver for WP 34s
I will take a look at these suggestions, just super busy until the weekend this week. Thanks.
|
|||
05-24-2018, 06:17 PM
(This post was last modified: 05-24-2018 06:59 PM by Dieter.)
Post: #7
|
|||
|
|||
RE: Example of MISO solver for WP 34s
(05-23-2018 07:36 PM)Dieter Wrote: So there should be a better solution for flagging the variable to solve for. I have been thinking about several methods, but none is really convincing. Maybe someone has a better idea? If the input can be essentially ...anything, there are two basic methods: - At the input prompt, press a key like B or C to continue at a different position in the program. This sounds nice ("simply press B at the input prompt when this is the variable you want to solve for"), but it will not work here as it pops the return stack. So the next RTN will not return from the pending subroutine call (LBL 99 or "VAR") to continue with the next variable input, instead the program will simply stop. However, this can be fixed by changing the XEQ calls into GTOs and then jump back to the next variable input with a GTO→J. Of course this requires ten additional labels 01...10. If you want to give it a try, here is the code. Press B when the variable to solve for shows up. Code: 001 LBL A - Use a flag. That's what the next version does. Here the program expects the user to set flag A when the prompt for the variable to solve for appears (press SF A). This turns on the big "=" sign in the display, so there is a visual feedback. Here is the code: Code: 001 LBL A In both cases the program also takes the input at this prompt as an estimate for the solution. It feeds 1/2x and 2x this value as the two initial guesses into the solver. So if you enter 100 the first two guesses are 50 and 200. Adjust this as you like with the two factors in line 049/051 or 039/041, respectively. Now try it and see if this works for you. ;-) Dieter |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 2 Guest(s)