MNES v2.0 Multi Nonlinear Equation Solver by Daniel Lopez Sancho 14-March-1996 DISCLAIMERS The library is provided 'as it' and is subject to change without notice. No warranty of any kind is made with regard to the software or documentation. The author shall not be liable for any incidental error or consequential damages in connection with the software and/or the documentation. Permission to freely distribute this software is granted provided this manual is distributed with it without any modification. MNES v2.0 can't be used for any commercial purpose without written permission from the author. This implies the user should not be charged for the use of MNES v2.0 in any way. Please excuse all the linguistic errors in this text. English is not my native language (Spanish). INTRODUCTION MNES works very close to MES (a multiple equation solver by HEWLETT PACKARD included in G series and in the Equation Library card for S series). It has almost the same commands and utilities than MES but with more features (you can have more than one unknown per equation, you can solve systems,...) and you can use it in both 48's series (S or G). It can be used as a solver for a nonlinear system of n equations with n unknowns and it can also solve linear systems without having to deal with matrices. MNES will solve as many unknowns as MES and it will usually solve more than MES (look at the EXAMPLES part). This occurs because the first that the solver does is exactly the same than MES does (trying to solve all the equations with only one unknown), and after that, the solver tries to solve the rest of equations with two or more unknowns. MNES can work with complex but cannot hold units (well, in fact, MNES can work with units as long as *all* the equations have only one unknown and the corresponding unit as initial value, but when it solves systems, units are not allowed). MNES includes a visualizer to know the state and value of every variable involved in the present ensemble of equations. INSTALLING THE LIBRARY 1. Upload to your 48 the file MNES20.lib with Kermit, Usend, XYModem or any other transfer protocol. Remember to use binary transfer. 2. Recall the contents of MNES20.lib to the stack ( 'MNES20.LIB' [RCL] ). 3. Purge MNES20.lib to save memory. 4. Press 0 (or any other port number you can access) and [STO]. 5. Turn off and on your machine (or restart it by pressing [ON]+[C]). Now your LIBRARY menu will contain the next label: [MNES] HOW TO USE MNES v2.0 First of all, you need to create a list with all the equations of your system. The equations can be introduced in two different ways: - 'x+y^2=3' - 'x+y^2-3' Both equations mean the same for MNES. You can put in the list as many equations as you want, and you can put just one if you want to. Then you have to store the list in a variable called 'EQ'. Now you must press the [MInit] key in the library menu. This stores some information in a variable called 'MPar'. Attention: you can't start the solver if this variable doesn't exist!. If you want to keep one system to use it several times, you just have to keep a copy of 'MPar' (you don't need to keep 'EQ'), and you can keep one 'MPar' per directory (but you can keep as many as you want just changing its name, and assigning it to 'MPar' when starting to solve). This variable can't be edited or modified directly by the user because it's a Library Data object, not an user-defined object. It can only be modified indirectly, by the use of the commands [MItm] and [MUser] (look at the LIBRARY COMMANDS part for more explanations about this). You can start now the solver by pressing [MSolvr]. This command uses the information stored in 'MPar' to configure the Solving Menu. This menu contains all the unknowns existing in the equations of 'EQ' and another menu label ([ALL]). Initially, all menu labels are in the solver menu label way (white) except [ALL], that takes the standard black menu label. You can have three types of variables in the Solving Menu: - Unknown: the variable you're trying to solve for. Its contents are used as initial values. If it's not defined as variable (it doesn't content anything) the value used as initial is 1. It's better to have the same or less number of unknowns than of equations. If you have more unknowns than equations, the solver will try to find as many solutions as possible. White menu label. - Constant: it doesn't change during solving. Black menu label. - Solution: it's a solved unknown. If you assign a value to any variable, the solutions will change to the unknown type to prevent incompatibilities between solutions. Black menu label with a white box in it. This table resumes the functions of the menu keys in the Solving Menu: - [x]: if necessary, it creates a variable, stores a value in it, declares 'x' as a constant and changes the color of the menu label to black. - [LS][x]: if necessary, it creates a variable and stores a value in it (this value will be used as initial value). - [RS][x]: recalls contents of the variable 'x'. - [ALL]: converts all variables to undefined variables without changing their values. - [LS][ALL]: starts the solver for all unknowns. - [RS][ALL]: shows information about all variables in Solving Menu. It starts a small visualizer with the next key definitions: - [VALUE]: shows values of the variables - [TYPE]: shows the type of every variable - [ABOUT]: shows a little message about MNES - [EXIT]: do you guess? - [ON]: same than [EXIT] - [RS][ON]: OFF - [UP], [LS][UP], [RS][UP], [DOWN], [LS][DOWN], [RS][DOWN] move up & down for 1 line, 1 page and top/bottom The visualizer begins showing the values of the variables, but you can change it by pressing [TYPE]. All the values corresponding to a 'solution' type will be marked with an small black box. THE SOLVER It uses a 'cubic backtracing linesearch' algorithm from Dennis & Schnabel to solve systems of equations. This method is a numerical one, so you can't be sure to get what you expected. It will depend very much of the initial values you give. This method has some kind of global convergence, so it will usually give you a solution, no matter if the initial values are far from it. The solver uses the firsts derivatives of the equations, so you must be sure that all the functions have derivative. If you have nondifferentiable functions in your equations (XROOT, SIGN, !, etc...) you will be able to solve them too, because MNES can approximate the functions to their deriva- tives. To do this you will have to set flag 3 (3 ENTER SF ENTER). If flag 3 is set, the solver will always approximate the derivatives, if not, the solver will use the exact derivatives (which is more numerically stable). It also uses the internal solver to solve equations with only one unknown (as well as MES does). The internal solver has great convergence and it will always (almost!) give you a solution (unless it doesn't exist). It's important to remember that a nonlinear system of equations can have more than one solution and the solution given by MNES may not be the one you are looking for. It can also occur that the system converges to a point that it's not a solution of our system. In these cases it's important to introduce accurate initial values, in order to get the desired solution. The solver works as follows: 1. It makes exactly the same than MES, trying to solve all the equations with only one unknown. 2. If there is still any unknown, the solver tries to find any compatible sub-system that can be solved, starting from 2x2 until 5x5 sub-systems using the first five equations still unsolved. For this reason, it will be a good idea to put the equations with less variables first in the list of equations, in order to solve as much as possible within the first five equations. In fact, if the solver can't solve anything within the first five equations still unsolved, it won't solve anything at all (except the solutions found in pass 1). When you're solving a system of equations, the solver will use all the equations in 'EQ' and not just the first five. Look at the HINTS part to know more about solving systems. As the solver can solve for different numbers of variables, when it starts to solve, a message like: "Solving for x1, x2,...,xn" appears in the top of the display, to know which variables are being solved. As you can solve different systems in different times, changing some variables each time, some of the previous values may not be compatible with the last solutions (as well as occurs with MES). For this reason, every time you solve a system, a list with all the variables involved in the process (constant, unknown or solution, no matter which type every variable is) is left on the first level of the stack. This way you can know the variables that belong to an ensemble of compatible solutions. LIBRARY COMMANDS - [MSolvr]: starts the Solving Menu (that holds the whole solver). - [MInit]: initializes 'MPar'. This is not an option: you MUST run [MInit] before you use any of the other commands (except ABOUTMNES)!!. - [MItm]: changes 'MPar'. It accepts as arguments a string character in level two and a list of variables in level one. The list must contain *all* the variables. The title of the equations will be the character string and the order of the menu labels will be the same as the order of the variables in the list. The string can have a maximun of 22 characters. You can introduce a "blank label" with "". - [MUser]: changes 'MPar'. This command is used to change the type of the variables. It accepts as argument a list containing the variables which type you want to change. Each time you press [MUser], it changes the type of the variable in the next way: Unknown -> Constant -> Solution -> Unknown If you want to change the type of a variable from 'unknown' to 'solution', you have to press [MUser] twice. To press it several times you can do: [Muser] [ARG] [MUser] [ARG] ... - [ABOUTMNES]: shows a little information about the library ERROR MESSAGES - Bad Guess(es): when the method has convergence to a point but it's not a solution of the system. Try to change the initial values and start the solver again. - Undefined Name: when there is a nondifferentiable function in any of the equations. Set flag 3 and start the solver again. - Unable to Solve System: there are two possible causes: 1. the system is incompatible 2. a division 'per zero' has happened (1/0, 0/0) If the cause is the second one, try to change the initial values and restart the solver. - Too Many Unknowns: there aren't enough constants defined as to solve any unknown. Introduce more constants and try again. - All Variables Known: there's nothing else to solve. - Invalid MPar: it exists a problem with MPar: it doesn't exist or it has any incorrect value. Press [MInit] and try again. - Inconsistent Units: MNES doesn't support units (when solving systems). EXAMPLES If you own a 48G/GX, you can try any of the Equation Library (remember to choice one without CONST, UBASE, TDELTA, GMOL or any other function involving units). You just have to choice, press [->STK], then STEQ, [MInit] and [MSolvr]. If you don't own a G, you can try the next examples (some are from the Equation Library). Example 1: (from Equation Library, Forces and Energy, Linear Mechanics) We have 8 equations: - F=m*a - Ki=1/2*m*vi^2 - Kf=1/2*m*vf^2 - W=F*x - W=Kf-Ki - P=F*v - Pavg=W/t - vf=vi+a*t Put them in a list and store it in 'EQ'. Press [MInit] and [MSolvr]. Now if you want to give a title and an order to the variables you can do it with [MItm]. We'll change it to the same order and title than the Equation Library: 4: 3: 2: "LINEAR MECHANICS" 1: { m a v vi vf x t F Ki Kf "" "" W P Pavg } Now type MItm in the command line. Store the next values: 1 [M], 5 [A], 8 [V], 10 [VI], 1 [VF] (constants) Press [NXT], [NXT] and LS [ALL] (we don't introduce initial values) As the result you'll have: 9: F: 5 8: Ki: 50 7: Kf: 0.5 6: W: -49.5 5: P: 40 4: t: -1.8 3: x: -9.89999999999 2: Pavg: 27.5 1: { F m a Ki vi Kf vf W P v t x Pavg } The negative values of W, t and x mean that the constants we gave are incorrect, but it doesn't matter for this example. - The list in the first level contains all the variables involved in the process (in this case all the variables). - To enter the visualizer: RS [ALL] - Note that these are exactly the same results than MES provides because there weren't more unknowns to solve. Now we'll do another solve: Press [ALL] and assign the values solved before to F, Ki, Kf, t and P 5 [F], 50 [KI], 0.5 [KF], -1.8 [T], 40 [P] Press [NXT] and LS [ALL] As the result you'll have: 9: W: -49.5 8: v: 8 7: Pavg: 27.5 6: x: -9.89999999999 5: m: 1 4: a: 5 3: vi: 10 2: vf: 1 1: { W Kf Ki P F v Pavg t x m a vi vf } - The list in the first level contains all the variables involved in the process (in this case all the variables). - To enter the visualizer: RS [ALL] - Note that these results are different than MES's results. MES solves W, v, Pavg and x. MNES solves W, v, Pavg, x, m, a, vi, and vf (all the unknowns are solved). Example 2: (from Equation Library, Forces and Energy, 1D Elastic Collisions). We have two equations: - v1f=(m1-m2)/(m1+m2)*v1i - v2f=2*m1/(m1+m2)*v1i Put them in a list and store it in 'EQ'. Press [MInit] and [MSolvr]. Now if you want to give a title and an order to the variables you can do it with [MItm]. We'll change it to the same order and title than the Equation Library: 4: 3: 2: "1D ELASTIC COLLISIONS" 1: { m1 m2 v1i v1f v2f } Now type MItm in the command line. Store the next values: 10 [M1], -2 [V1F], 8 [V2F] (constants) Press LS [ALL] As the result you'll have: 3: m2: 15 2: v1i: 10 1: { vif m1 m2 v1i v2f } - The list in the first level contains all the variables involved in the process (in this case all the variables). - To enter the visualizer: RS [ALL] - Note that these results are different than MES's results. MES doesn't solve any unknown. MNES solves m2 and v1i (all the unknowns are solved). Example 3: (solving a 2x2 nonlinear system) We have two equations: - x-0.7*sin(x)-0.2*cos(y)=0 - y-0.7*cos(x)+0.2*sin(y)=0 Be sure you're in DEG mode. Put them in a list and store it in 'EQ'. Press [MInit] and [MSolvr]. If you want to solve the whole system directly (without trying to solve equation per equation) press LS [ALL] or change the initial values without introduce any constant. In this case it's not necessary to change the initial values because it will converge anyway. As the result you'll have: 3: x: 0.202458671924 2: y: 0.697560743674 1: { x y } HINTS - Solving systems with flag 3 cleared (using derivatives) is better than use differential approximations (user flag 3 set) because first method uses exact derivatives and it's more numerically stable. First method has faster iterations, but it takes more time to start the iterations because it has to calculate symbolic derivatives and this is quite slow. If the system is 5x5 it has to calculate 25 derivatives and this can take a long time (much more if the equations are very 'complicated'). The second method starts iterating instantly and although it has slower iterations, it's preferred when solving a big system (8x8, 10x10, etc...) because it doesn't make you wait, it let you know something about the process at the moment and it is usually faster. - It's better to put the smallest equations (less number of unknowns) first in the list, in order to solve the more as possible. - While the solver is solving a system, the error is shown to know what's going on inside the machine. Sometimes this error grows and grows because it doesn't converge. In this cases the best is stop the solver (by pressing [ON]), change the initial values and restart the solver. - If you want to solve a system, introduce the equations, press [MInit] [MSolvr], introduce accurate initial values (this is optional) and [LS][ALL] (without declaring any constant). This way, the program starts the solver for the whole system and not equation per equation. FINAL REMARKS - The library has been developed on a HP48SX with the RPL48 v1.12b DEVELOPMENT PACKAGE, the DEBUGGER 1.0b and ED. It is completely written in Sys-RPL and ML. It makes use of many "unsupported" entries. Use it at your own risk. It has been working for months on a HP48SX revision J and on a HP48G revision R and nothing wrong has happened. However, remember to backup your memory before using it. - Library is ID 1550. Its size is 6301 bytes and its checksum is #37E2h. - As you should know by now, all the library commands (even the title) are very close to those in MES (in the name and also in the usage). Just see and compare: MES -> MNES MSOLVR -> MSolvr MINIT -> MInit MITM -> MItm MUSER -> MUser Mpar -> MPar This has been done to simplify the usage to the MES users. I hope there will be no flames in Corvallis for this ;-) ACKNOWLEDGEMENTS I would like to thank the following persons: - Detlef Mueller and Raymond Hellstern for RPL48 - Mika Heiskanen for DEBUGGER and ED - DJ MURDOCK for many talks about solving routines - Cesar Figa for letting me his HP48G (R) for a complete month - Sune Bredahl for his patience and help - HP for HP48, TOOLS and MES As I explained in the DISCLAIMERS part, this software is freeware, but many hours (and days...) of programming and debugging have been invested in developing this library. So, the author will be much more than satisfied if someone tells him that he appreciates the library and he uses it a lot. Author will also be glad to solve (or at least, try to...) all the problems that you can find using MNES. For this reason, you can contact me by: POST: Daniel Lopez Sancho c/ Gran Via Carlos III, 67 4º2ª 08028 BARCELONA SPAIN PHONE: SPAIN - 93 - 330 78 42 FAX: SPAIN - 93 - 377 15 14 E-mail: corma@sefes.es I will try to answer all doubts I receive.