MATH LIBRARY version 2.10 An almost complete math package for dealing with matrices and polynomials Written in SysRPL and Machine Language Library number 1211 By Cesar Augusto Rorato Crusius - 1994 NOTICE....................................................3 This program is Post-Cardware.........................3 ABOUT.....................................................4 LIMITATIONS and BUGS......................................5 BE CAREFUL............................................5 USER MODE.............................................5 GX COMPATIBILITY......................................5 MATH DATA TYPES...........................................6 VERSION DIFFERENCES.......................................7 Version 1.00 and 1.10.................................7 Version 1.10 and 1.20.................................7 Version 1.20 and 1.21.................................8 Version 1.21 and 1.30.................................8 Version 1.30 and 2.00.................................9 Version 2.00 and 2.10.................................10 SPEED MARKS (version 2.00)................................11 MATH speed versus HP speed :-)........................12 LIBRARY COMMANDS DESCRIPTION..............................14 MADD..................................................14 MSUB..................................................14 MMLT..................................................14 MDIV..................................................14 MPWR..................................................15 MRoot.................................................15 MFCTP.................................................15 MCOEF.................................................15 MEVL..................................................15 MDER..................................................16 ZTRIM.................................................16 MDET..................................................16 MINV..................................................16 MTRN..................................................17 MIDN..................................................17 A<->L.................................................17 PR|L..................................................17 FRPRC.................................................17 ADPOL.................................................19 STDL..................................................19 EVALUES...............................................20 SVALUES...............................................20 MADJ..................................................20 MINOR.................................................20 MGET..................................................21 MPUT..................................................21 Row-..................................................21 page 1 Row+..................................................22 Col-..................................................22 Col+..................................................23 RSwp..................................................23 CSwp..................................................23 MSIZE.................................................23 MTRACE................................................24 ABOUT.................................................24 UTILITY PROGRAMS..........................................25 MVID..................................................25 MFLAG.................................................25 APPLICATION NOTES.........................................26 MEVL hints and suggestions............................26 Interesting application of A<->L......................26 Rank of a matrix......................................27 Computing the determinant in a faster way.............27 Successive divisions..................................27 Ackermann's formula...................................27 SPLIT.................................................28 A NOTE ON THE METHODS.....................................29 THANKS TO.................................................30 page 2 NOTICE * The program MATH 2.10 and the documentation in this file are provided "as is", and are subject to change without notice. I give no warranty of any kind with regarded to the software or documentation, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. Cesar Augusto Rorato Crusius shall not be liable for any error or for incidental or consequential damages in connection with the furnishing, performance, or use of this software and documentation. * Sale of this material is not allowed without prior written permission of Cesar Augusto Rorato Crusius. * Non commercial distribution allowed, provided that the original documentation is preserved unchanged. * Modified versions are NOT allowed. * Use of any part of MATH library code is not allowed for any purpose, except, of course, when used directly from the MATH library. You cannot reproduce any part of MATH library code for any purpose without prior written permission of Cesar Augusto Rorato Crusius. Use of MATH library in commercial or shareware programs is not allowed. This program is Post-Cardware * If you use and enjoy this excellent program you MUST send me a post-card. It will not cost too much, and I'll appreciate a lot ! Send it to the following address: Cesar Crusius Caixa Postal 5193 Trindade - Florianopolis - SC ZIP CODE 88040-970 this address will work only 'til Jan 1996. So hurry up ! page 3 ABOUT As we know, many times we need to perform calculations only with numbers. Many times we need to do polynomial calculus (multiplication, division and so on). Then, if we go one step ahead, we will need to do the same calculations with symbolic polynomials. As we go deeper, we will need many more things: symbolic matrices, matrices of polynomials, matrices of symbolic polynomials, matrices of matrices, et cetera. MATH library is the way to do all those things! You can add a symbolic polynomial to a numerical matrix, and you'll get the correct answer: a symbolic matrix. Now you can get the inverse of the symbolic matrix, add a polynomial to this matrix and so on... Let's take an example. Let's do inv(sI-A) (familiar to engineers) in two ways (consider A=[[1 2][3 4]]): First method: using the symbol 'S' 2:'S' 1:{{'S-1' -2} 2:{{'S-4' 2} 1:[[1 2] MSUB {-3 'S-4'}} MINV {3 'S-1'}} [3 4]] 1:'(S-1)*(S-4)-6' The second method uses [1 0] as a polynomial for 'S': 2:[1 0] 1:{{[1 -1] -2} 2:{{[1 -4] 2} 1:[[1 2] MSUB {-3 [1 -4]}} MINV {3 [1 -1]}} [3 4]] 1:[1 -5 -2] As you can see, if you work with a lot of calculus THAT is the program you need. page 4 LIMITATIONS and BUGS This program is very difficult to debug because of its high complexity. You can do almost everything with the commands. If you try to do something you think is right and get a wrong answer, please notice me and I'll try to fix the bug. Any suggestions are welcome. BE CAREFUL There are times when the program has no way to discover what you are trying to do. As an example, take {{A 1 2}}. What is that? A 1x3 matrix or a zero-degree polynomial with the idependent coefficient equal to the symbolic polynomial {A 1 2}? There's no way to discover. The program will, in those cases, take the first choice. So DO NOT try to add {{A 1 2}} with {{1 2}}, because the program will think that you're trying to add two matrices. Do {0 {A 1 2}} + {0 {1 2}} instead. This will work correctly. USER MODE In the library commands description, sometimes I say that you can assign some command to some key. When I say that, I mean that you can STAY IN USER MODE and continue to use the keys as if none command were assigned to them if the arguments do not match those of the library command. GX COMPATIBILITY As discovered by Michael Guravage, MATH may not work correctly if installed on a RAM card that lies on the second slot of a GX calculator. So, if you have a GX, install MATH on the main memory or on the first slot. page 5 MATH DATA TYPES There are basically two kinds of data that you can use with MATH library: numerical and symbolic data. You represent numerical data with the "array" format of the HP48. Symbolic data is represented just replacing the "[]"s by "{}". Being that way, a numerical matrix for MATH have exactly the same format as for the calculator. Examples: numerical 2x2 matrix: [[ 1 2 ][ 3 4 ]] symbolic 2x2 matrix: {{ 1 2 }{ 3 A }} Polynomials are represented as vectors, and the vector elements are the coefficients of the polynomial. Example: the polynomial x^3+2*x+3, for MATH, is [1 0 2 3]. Note that the polynomial variable is unknown! If you have symbolic coefficients you must use the symbolic format. Example: x^3+A*x^2+2*x+3 is represented as { 1 A 2 3 }. page 6 VERSION DIFFERENCES Version 1.00 and 1.10 Now the library is GX compatible! When the program detects that it's being used on a GX, MRoot dispatches to the GX own PROOT. In version 1.0 MINV did not work correctly for 1x1 matrices. Now it does. The program A<->L now works correctly when there are complex numbers involved. Some differences in MEVL, e.g. it can be used as PR|L for matrices. It also dispatches to the system EVAL when arguments are not matching. Many commands now dispatch to some system commands when arguments are not matching. Here are the list of the commands: MRoot dispatches to SQRT, MEVL dispatches to EVAL, MFCTP dispatches to XROOT and MDER dispatches to "delta". I made this so I can assign these commands to the corresponding system keys and I can stay in user mode to perform normal calculations. ADPOL accepts any combination of lists/polynomials and execute MFCTP on the arguments that are polynomials. When MFCTP receives a list it does nothing. A lot of changes in FRPRC. You better read the command description. Version 1.10 and 1.20 MMLT and MDIV now works normally, i.e., there are no more "element-by-element" product and MDIV does not accept that Matrix/Array stuff. MMLT now can multiply a symbolic polynomial by a matrix. In earlier versions this was not allowed. MDIV now can divide a symbolic matrix by anything but an array. When dividing a polynomial by a zero-degree polynomial the answer is a single polynomial. If the remainder of a polynomial division is a zero-degree polynomial, then the remainder is only a number, and not a single-element array. A correction to the old version manual brings up a new capability of MEVL (it was already implemented in page 7 version 1.10, but I forgot to mention it on the old version manual :-). If you have a matrix of polynomials you can execute MEVL exactly as if you have a polynomial, i.e., every polynomial in the matrix will be evaluated for the given point (and the point can be anything: a matrix, another polynomial and so on). EVECT and EVALUES commands added. MADD and MSUB return numerical arrays when you add or subtract a complex number from a matrix. In earlier versions they return symbolic matrices. Now the following commands test the matrix dimensions: MADD, MSUB, MMLT, MDET and MINV. The test is not complete, but make this commands much safer to use. MEVL now treats a real number as a zero-degree polynomial. ZTRIM is now transparent to objects that are not polynomials. When used on a zero-degree polynomial, the answer is the zero-degree coefficient. ZTRIM can also be used on a matrix. Version 1.20 and 1.21 Some machine code added. A<->L now accepts a list with symbolic elements. The program computes the numerical value of the symbolic elements before the transformation. Version 1.21 and 1.30 MADJ command added, so now you don't need to invert a matrix in order to compute its adjoint. MINOR command added to compute the minor matrix. Some utility commands added: MGET, MPUT, Row-, Row+, Col- and Col+. These commands follows the same syntax as for SX/GX GET and PUT, and Row+- & Col+- follows the same syntax as for GX ROW+- and COL+-, so now you can make a LOT of programs to deal with symbolic matrices. MINV is now much faster, because now the matrix determinant is computed in a very fast way. In fact, the determinant of the matrix M is equal to the first row of adj(M) times the first column of M! page 8 Version 1.30 and 2.00 SPEED! Now MATH is the fastest polynomial math program for the HP48 series! A lot of numerical polynomial tasks are performed 99% in machine language. The speed is improved by 1000% in many operations, such as MADD and MMLT (take a look at MPWR). Because of the internal representation for polynomials (arrays of long complexes), the precision is greater too! BELIEVE IT OR NOT, MATH's MEVL running under a version D HP48-SX is MUCH FASTER THAN HP48-G's PEVAL !!! MADD for arrays is FASTER THAN HP'S "+" !!! SIZE! MATH 2.00 keeps almost the same size as MATH 1.30, thanks to the new MRoot program. The new MRoot is a little bit slower than the old one (the old and good PROOT), but it's a good roots program too, and memory is at a premium in my "dinosaur" HP48-SX version D. The new MRoot can take the roots of polynomials with complex coefficients! If you have a G(X), then MRoot will dispatch to PROOT and change the output format to a list. MEVL can evaluate the nth-derivative (for any "n") of a polynomial as well! New commands added for numerical and symbolic matrices: RSwp, CSwp, MSIZE and MTRACE. EVECT has gone, and SVALUES (singular values) takes its place. Some corrections on Row+ and Col+. MGET is now user- proof (i think :-). MDET internally improved. It will test for zero pivots, so if your matrix have many zeros on the first row the program will execute A LOT faster. MDIV now divides complex coefficient polynomials. Some polynomial tasks will return simplified polynomials, if possible, by transforming complex polynomials into real ones. Example: If you execute MADD with [ (1,1) (0,0) ] and [ (1,-1) (2,0) ], you will get [ 2 2 ] instead of [ (2,0) (2,0) ]. MROOT now is MRoot (there is a MROOT command in G series). But don't worry, your programs will keep working, 'cause the XLIB number remains the same. MGET and MPUT now accepts lists with symbolic elements. The programs will compute the numerical value of the symbolic elements. page 9 Version 2.00 and 2.10 Bug in SVALUES fixed, and now it works :-) MEVL now can compute the nth derivative of a symbolic polynomial too. MDER now passes automatically through symbolic matrices. MDIV now can divide a numerical polynomial by a symbolic element, and can divide complex coefficients polynomials. Col+ now returns a numerical matrix if the input arguments are two numerical matrices. All commands ( except PR|L ) now works correctly with LASTARG. MEVL will keep only the first element of the stack. However, this feature eated more than a half kbyte of your precious memory. page 10 SPEED MARKS (version 2.00) I made some speed measures to compare MATH 1.30 and 2.00, and here are the results. The tests were made on my HP48 version D with 32k. Only MATH was on the calc, so there were about 20k free. All LAST flags were enabled (thus slowing the speed). When two lines are presented for the same test, then the first line contains the results for real polynomial tests, and the second contains the results for complex polynomial tests. Note that my calculator is an SX, so if you have a GX you'll be even faster! +----------------+---------+---------+-----------+ | command | v1.30 | v2.00 | improv (%)| +----------------+---------+---------+-----------+ | V2 V1 MADD | 1.870 | 0.096 | 1847.92 | | | 2.084 | 0.101 | 1963.37 | +----------------+---------+---------+-----------+ | V2 V1 MSUB | 1.948 | 0.173 | 1026.01 | | | 2.181 | 0.188 | 1060.17 | +----------------+---------+---------+-----------+ | V2 V1 MMLT | 34.405 | 1.004 | 3326.79 | | | 48.726 | 1.202 | 3953.74 | +----------------+---------+---------+-----------+ | V2 V1 MDIV | 23.925 | 3.093 | 673.52 | | | xxxxxx | 7.130 | xxxxxx | +----------------+---------+---------+-----------+ | V1 2 MPWR | 103.658 | 0.575 | 17927.47 | | | 145.514 | 0.820 | 17645.61 | | [1 1] 10 MPWR | 25.690 | 0.617 | 4063.70 | +----------------+---------+---------+-----------+ | V2 (1+j) MEVL | 1.709 | 0.177 | 865.54 | | | 1.803 | 0.172 | 948.26 | +----------------+---------+---------+-----------+ | V2 MDER | 1.033 | 0.707 | 46.11 | +----------------+---------+---------+-----------+ | FRPRC | 87.067 | 18.385 | 373.57 | +----------------+---------+---------+-----------+ | V1 MRoot | 10.051 | 11.151 | -9.86 | | | xxxxxx | 32.799 | xxxxx | +----------------+---------+---------+-----------+ | V1 MFCTP | 10.278 | 11.388 | -9.75 | +----------------+---------+---------+-----------+ | V1roots MCOEF | 11.757 | 0.849 | 1284.81 | +----------------+---------+---------+-----------+ | M1 MDET | 181.594 | 71.468 | 154.09 | +----------------+---------+---------+-----------+ | M1 MINV | 903.567 | 196.638 | 359.74 | +----------------+---------+---------+-----------+ | M2 EVALUES | 189.759 | 27.816 | 617.06 | +----------------+---------+---------+-----------+ page 11 The vectors and matrices used for the test were: V1real = [ 1 2 3 4 5 6 7 8 9 10 ] V1comp = (1,1)*V1real V2 = V1 ^ 2 [[ 1 2 0 4 0] [ 5 3 4 0 6] M2 = [ 0 2 5 6 2] [ 0 3 2 -1 -1] [-5 3 1 -2 8]] M1 = [ 1 0 ] - M2 FRPRC test: in normal mode, numerator = [ 100 0 ] and denominator = { [ 1 2 5 ] 3 [ 1 1 ] 3 [ 1 2 ] } Speed improvement = 100*( 1.30/2.00 - 1 ) MATH speed versus HP speed :-) Just kidding, I love HP calcs, but you must look at this! Here are some speed comparsions between MATH commands and the similar HP commands. The HP used for the test was a version R HP48-G. The polynomials used were: real: P=[1 1] 40 MPWR cmplx: C=[1 1] 40 MPWR (1,1) * All results are in seconds. Take a special look at the comparsion between PEVAL and MEVL. +-------+-------+ | HP48G | MATH | +-----------------------+-------+-------+ | P P + vs MADD | 0.275 | 0.134 | +-----------------------+-------+-------+ | C C + vs MADD | 0.649 | 0.147 | +-----------------------+-------+-------+ | P (1,1) PEVAL vs MEVL | 1.080 | 0.218 | +-----------------------+-------+-------+ | C (1,1) PEVAL vs MEVL | 1.338 | 0.227 | +-----------------------+-------+-------+ Please note two things: i. MATH's MADD is faster AND more versatile than HP's command "+" for vectors: when adding two complex vectors (polynomials for MATH), MADD will return a real one if possible. ii. MATH's MEVL is faster AND more versatile than HP's command PEVAL: MEVL can evaluate the polynomial page 12 derivatives AND will return a real value if possible (i.e. if the imaginary part of the result is zero). page 13 LIBRARY COMMANDS DESCRIPTION In this section a complete description of the library commands will be given. You can use any of the library commands to make your own programs in user or SysRPL. What I'm trying to say is that I will NOT change the library ID or the XLIB numbers. The only command that can have it's XLIB number changed is ABOUT. MADD Takes two arguments and try to add them. If one argument is a matrix M and the other is anything but a matrix (x), the program will perform the sum xI+M. If x is a real number and M is a numerical matrix, the answer will be a numerical matrix, as expected. Anything is allowed (matrices of matrices of matrices of polynomials, and so on...). If you assign this program to the "+" key, be aware that the following operation won't be carried out in the USER mode: { 1 2 3 } 3 + ---> { 1 2 3 3 } Instead, you'll get { 1 2 6 }. MSUB Takes two arguments and try to subtract them. If one argument is a matrix M and the other is anything but a matrix (x), the program will perform xI-M or M-xI (it will do what you asked for). Anything is allowed. This program can be assigned to the key "-". MMLT Multiplication in numerical/symbolic form. You can do almost anything you want, e.g. multiply a numerical matrix by a symbolic polynomial, or a numerical polynomial by a symbolic polynomial. This program can be assigned to the key "*". MDIV Divides level 2 object by level 1 object. You cannot divide a matrix by an array, and level 1 object cannot be a symbolic matrix. If the arguments are not matching, the command dispatches to the HP own "/". When dividing a polynomial by another, the answer will be the result of the division on level 2 and the remainder on level 1. If the remainder is a zero-degree polynomial, it will be given as a number. If you divide a polynomial by a zero- page 14 degree polynomial, the answer will be a single polynomial (obviously the remainder will be zero). MPWR Takes an object in level 2 and raises it to the nth power, where n is the value of the real number in level 1. This program can be assigned to the user key "y^x" and you won't need to leave the user mode for the normal operation of the key. MRoot Takes a numerical polynomial in level 1 with real or complex coefficients and returns a list with the polynomial roots. If the polynomial have zero degree, then MRoot returns an empty list. You can assign this command to the user key SQRT. MFCTP Takes a polynomial (like MRoot, but only real coefficients are allowed) in level 1 and factorizes it, returning the list of the polynomials. If the argument is a list the program will simply do nothing. Note that the leading coefficient of the factored polynomial will be ONE no matter the value of the leading coefficient of the original polynomial. You can assign this command to the key XROOT. MCOEF Takes a list of roots in level 1 and returns the polynomial that have these roots. All the roots must be numerical, and they must correspond to a real coefficient polynomial. The leading coefficient of the resulting polynomial will be always one. MEVL Takes a polynomial (or a matrix of polynomials) P in level 2 (matrices of matrices of polynomials are allowed, and so on) and any object x in level 1 and computes P(x). P can be symbolic or numerical, and x can be anything (another polynomial or even a matrix). If the object on level 2 is a real number, MEVL will simply drop the level 1 object. If you want to evaluate the nth-derivative of a polynomial, add a hex-string with the value of "n" in the arguments. Example: page 15 3: [ 1 2 3 4 5 ] 2: 12 1: # 3d MEVAL will compute the value of the 3rd derivative of the polynomial [ 1 2 3 4 5 ] at the point 12. It will return, in this case, 1: 300 You can assign this command to the key EVAL, but be aware -> this is a "strange" command. Strange things can happen if you try to use MEVL as the HP EVAL when there are more than one element in the stack (e.g., a list of variables on level 2 and anything on level 1), because MEVL will think that the list is a polynomial, and so on... If you have a G(X), please note that MEVL is FASTER THAN PEVAL. MDER Takes a polynomial in level 1 and computes its derivative. The polynomial can be symbolic. You can assign this command to the derivative key. ZTRIM Removes the left zeros of a polynomial or a matrix of polynomials. If the object is not a polynomial, nothing happens. If the result is a zero-degree polynomial, then ZTRIM will return only the first element of this polynomial. MDET Calculate the determinant of a square matrix. The matrix can contain anything: polynomials, symbolic elements or even matrices(!). MINV Calculate the inverse of a square matrix. You can have anything on the matrix. The program returns a numerical matrix if the input is a numerical matrix. If the input is a symbolic matrix, the program returns, in level 2, the adjoint matrix and, in level 1, the determinant. As we know, the inverse is: adjoint matrix divided by the determinant. Uses Faddeev method for symbolic matrices. You can assign this command to the key "1/x". page 16 MTRN Calculate the transposed matrix. The matrix can be either symbolic or numerical. MIDN Creates an identity matrix with the dimension of level 1 and with the diagonal elements equal to the level 2 element. A<->L Transform a symbolic/numerical poly/matrix into a numerical/symbolic poly/matrix. The program will pass the HP-command ->NUM to every element on a symbolic representation, so now you can do things like { 1 '1/3' } ---> A<->L ---> [ 1 .3333... ] PR|L Given a list on level 2 and a program on level 1, executes the program on every element of the list. This program has a maximum depth of 2. What does it means? The "depth" of PR|L is the "maximum recursivity depth" of the program. So a "depth" of 2 means that PR|L will pass the program through lists that are in the original lists, but not through lists into these ones. See the following examples: { 2 } << 2 + >> PR|L { 4 } {{ 2 }} << 2 + >> PR|L {{ 4 }} {{{ 2 }}} << 2 + >> PR|L {{{ 2 2 }}} If you want to override this depth limit, simply add one more parameter (a binary integer or a hex string) containing the maximum depth wanted. Example: {{{ 2 }}} << 2 + >> #3 PR|L {{{ 4 }}} FRPRC There are two types of partial fractions: the normal type and the "Z-type". In the normal type, the numerators' degrees are smaller than the denominators' degrees. In the "Z-type", the numerators can have the same degree as the denominators (very useful for Z- transforms). User flag 31 control the current mode of operation. If flag 31 is SET, then the normal type is used, otherwise "Z-type" is used. page 17 Level 1 can be a numerical polynomial or a list of numerical polynomials representing Q. Example: if Q=(x+1)(x+2)x^2 the list of level 1 could be: { [ 1 1 ] [ 1 2 ] [ 1 0 ] 2 } or [ 1 3 2 0 0 ] You must note that the leading coefficient of the denominator polynomial MUST BE ONE! If this is not the case, you must re-arrange the polynomials to get the correct denominator polynomial. Complete example in normal type (don't forget to set flag 31): calculate the partial fractions of (x+1)/((x+4)^2 * (x+2) * x) 2: [ 1 1 ] 1: { [ 1 4 ] 2 [ 1 2 ] [ 1 0 ] } the output of FRPRC is 1: {{ [ -.15625 ] [ 1 4 ] 1 } { [ -.375 ] [ 1 4 ] 2 } { [ .125 ] [ 1 2 ] 1 } { [ .03125 ] [ 1 0 ] 1 }} so the answer is -.15625 .375 .125 .03125 -------- - -------- + ----- + ------ (x+4) (x+4)^2 x+2 x If you want to use the "Z-type" partial fractions, you must first clear flag 31. To use this mode of operation there is one constraint to the numerator: it must have a degree higher than zero, and the zero-order coefficient must be zero. If you think that that's too bad, remember that when you calculate the step response in Z you must multiply the numerator by Z. So, if you use this mode to work in Z-domain, this constraint will be not a problem at all. The answer will always have its numerators with the zero-order coefficients equal to zero (better for inverse Z-transforms). Complete example: calculate the partial fractions of z/(z-1)(z-.5) With flag 31 cleared, the stack must be 2: [ 1 0 ] 1: { [1 -1] [1 -.5] } The program FRPRC will give you the answer: page 18 1: {{ [ 2 0 ] [ 1 -1 ] 1 } { [ -2 0 ] [ 1 -.5 ] 1 }} So the answer is 2z 2z ---- - ---- z-1 z-.5 SOME DIFFERENCES FROM MATH 1.00: If you already have MATH 1.00, you'll soon notice that complete answers are always given. I did that because it seems to be better for the user and certainly it is better to make programs that use FRPRC. The old style FRPRC that takes a binary integer in level 1 is not allowed anymore. A bug or a limitation? :-) Try to, whenever possible, use the list format for the denominator. If you don't, *strange* things may happen, as discovered by Tyson Leistiko. Example: try to perform, in the normal mode, the following partial fractions: (a) -> [ 1 ] / [ 1 8 13 6 ] (b) -> [ 1 ] / { [ 1 6 ] [ 1 1 ] 2 } As you will note, the answers are different. Why? Because MRoot isn't precise enough to identify the multiple roots in -1 in the polynomial [ 1 8 13 6 ]. ADPOL Make a FRPRC list from lists/polynomials. Examples: 2: { [ 1 0 ] } 1: [ 1 0 ] -> ADPOL -> 1: { [ 1 0 ] 2 } 2: [ 1 2 1 ] 1: [ 1 2 5 ] -> ADPOL -> 1: { [ 1 2 5 ] 1 [ 1 1 ] 2 } Note: one argument at least must be a numerical polynomial. STDL Prepares a list to be used by FRPRC (the program FRPRC automatically calls this program, so you will only use it if you will build your own programs). Example: 1: { [ 1 0 ] [ 1 2 ] 2 [ 1 0 ] 3 [ 1 2 ] 5 [ 1 4 ] } page 19 STDL gives 1: { [ 1 0 ] 4 [ 1 2 ] 7 [ 1 4 ] 1 } EVALUES Takes a numerical square matrix (real or complex) on level 1 and returns the list of the Eigenvalues of the matrix. Example: 1: [[ 3 -1 1 ] [ -1 5 -1 ] [ 1 -1 3 ]] EVALUES will return 1: { 2 3 6 } This program uses Faddeev's method to find the characteristic polynomial of the matrix and then executes MRoot. This program is slower than GX's EGVL. So, if you have a GX, you may want to use GX's own command. The fact is that an SX owner can build his programs using MATH's EVALUES and the programs will run without modification on any GX with MATH 1.20 or newer installed. SVALUES Takes a numerical matrix (real or complex) on level 1 and returns the list of the singular values of the matrix. Example: 1: [[ 3 -1 1 ] [ -1 5 -1 ]] SVALUES will return 1: { 2.63787896258 5.57149841414 } MADJ Computes the adjoint matrix. One more time, the input matrix can have anything as its elements. Uses Faddeev's method. MINOR Computes the minor matrix. You must put in level 3 the matrix, in level 2 the row and in level 1 the column to be removed. Example: page 20 3: { { 1 2 } { c d } { f 5 } } 2: 2 1: 2 MINOR will give you 1: { { 1 } { f } } MGET Pick an element from a matrix/polynomial. As in MPUT, symbolic matrices can have ANY NUMBER OF dimensions! The command follows the same syntax as the HP command GET. Example: 2: { { { { A B } } { { C D } } } } 1: { 1 2 } MGET will give 1: { { C D } } MPUT Puts an element into a matrix/polynomial. Note that only numbers can be putted into numerical matrices. Another important thing to note is that symbolic matrices can have ANY NUMBER OF dimensions, and not only two! The command follows the same syntax as the HP command PUT. Let's do an example with a symbolic matrix with four dimensions: 3: { { { { 1 2 } } { { 3 4 } } } } 2: { 1 2 1 2 } 1: A MPUT will give 1: { { { { 1 2 } } { { 3 A } } } } WARNING: In this version MPUT does not perform ANY tests on the giving index! If you give an invalid index you may (and certainly will) loose your memory! Row- Removes a row from a matrix. The program returns in level 2 the modified matrix and, in level 1, the removed row. If the original matrix has only one row, the program will return the unity matrix [[1]] or {{1}}. Example: page 21 2: { { A B } { C D } { E F } } 1: 2 Row- will give you 2: { { A B } { E F } } 1: { C D } Row+ Puts one or more rows into a matrix. You must put in level 3 the original matrix, in level 2 the row (or matrix of rows) and in level 1 the line where the rows will be inserted. If the number in level 1 is greater than the matrix dimensions, then the row(s) will be inserted at the end of the matrix. Example: 3: [ [ 1 2 ] [ 3 4 ] ] 2: { A B } 1: 2 Row+ will give 1: { { 1 2 } { A B } { 3 4 } } Another example: 3: { { 1 2 } { C 4 } { x y } } 2: { { a b } { c d } } 1: 3 Row+ will give 1: { { 1 2 } { C 4 } { a b } { c d } { x y } } Note that any combination of symbolic/numerical matrices are allowed. Col- Removes a column from a matrix. The program returns in level 2 the modified matrix and, in level 1, the removed column. If the original matrix has only one column, the program will return the unity matrix [[1]] or {{1}}. Example: 2: { { A B } { C D } { E F } } 1: 2 Col- will give you page 22 2: { { A } { C } { E } } 1: { B D F } Col+ Puts one or more columns into a matrix. You must put in level 3 the original matrix, in level 2 the column (or matrix of columns) and in level 1 the line where the columns will be inserted. If the number in level 1 is greater than the matrix dimensions, then the column(s) will be inserted at the end of the matrix. Example: 3: [ [ 1 2 ] [ 3 4 ] ] 2: { A B } 1: 2 Col+ will give 1: { { 1 A 2 } { 3 B 4 } } Another example: 3: { { 1 2 } { C 4 } { x y } } 2: { { a b } { c d } { e f } } 1: 3 Col+ will give 1: { { 1 2 a b } { C 4 c d } { x y e f } } Note that any combination of symbolic/numerical matrices are allowed. RSwp Exchange (swap) two rows of a matrix. The level 3 must contain the matrix and the levels 2 and 1 the index of the rows to be swapped. CSwp Exchange (swap) two columns of a matrix. The level 3 must contain the matrix and the levels 2 and 1 the index of the columns to be swapped. MSIZE No more SIZE EVAL for polynomials and vectors! MSIZE will give you the size of the object in level 1. If the object is a polynomial (or a vector), then it will return just a number. If it is a matrix, MSIZE will return a list with the number of rows and columns. page 23 MTRACE Computes the trace of a square matrix, i.e., the sum of the elements of the matrix diagonal. Of course it will work for symbolic matrices ;-) ABOUT Shows my name !!! :-) page 24 UTILITY PROGRAMS Included with the package are some utility programs. Here is the description: MVID If you do not use my Control Package, then this program can be useful. Execute CNVID once or twice, until "(S/Z)MOD" appear on the top of the screen. The annunciators indicate what is the current type of partial fractions and the current MATH version. MFLAG Use MFLAG to change the type of partial fractions performed without have to (re)set the flag 31 by hand. Again, if you have Control Package you'll not need this program. page 25 APPLICATION NOTES MEVL hints and suggestions This program can be used as PR|L if you have a symbolic matrix in level 2 and a program in level 1. In this case, the program will be evaluated for every matrix element, just as PR|L does. This program can be very useful for other tasks. Example: if you have the polynomial x^3 + 2*x^2 + 3 and want to make the variable substitution x=s+1, you can get the polynomial in s by typing: 2: [ 1 2 0 3 ] 1: [ 1 1 ] Now you execute MEVL (evaluates the polynomial when x is another polynomial) and get the answer: 1: [ 0 1 5 7 6 ] Of course you can get the polynomial in x back by evaluating the s polynomial at [ 1 -1 ] 1: [ 0 0 1 2 0 3 ] The leading zeros appears due to the evaluating algorithm. The answer is right anyway... Another thing that you can do with MEVL is to transform a numerical polynomial into a symbolic polynomial. Example: 2: [ 1 2 3 ] 1: 'S' MEVL will return '(S+2)*S+3'. Beside the fact that that's an "unusual" format for symbolic polynomials, the answer is right. And, as you see, this format is faster to evaluate and give better results than the "standard" format. Interesting application of A<->L A suggestion: when you get the inverse of some matrix, use A<->L and evaluate the program << ->Q >> over it (if you have a G series calculator you can simply execute the command ->Q). As an example, try to do this with the matrix [[3 1][-4 1]]. The symbolic matrix will be much better to visualize. page 26 As you may note, the inverse procedure can be useful when entering matrices like [[ 1/3 1 ] [ 0 1/7 ]]. Simply enter {{ '1/3' 1 }{ 0 '1/7' }} (some may prefer the matrix editor to this method). After that, use A<->L and get the numerical matrix. Rank of a matrix If you have a GX you have a command to compute the rank. But if you haven't, you can compute the rank by checking the number of non-zero singular values of the matrix. The following program will return the rank of a matrix: << SVALUES ZTRIM SIZE >> Computing the determinant in a faster way MDET now tests for zero pivots. So, if you have, on your matrix, a row with many zeros, swap (using RSwp) this row and the first. The determinant will be computed in a faster way. But don't forget to negate the result accordingly ! Successive divisions This program is very useful, for example, if you want to simulate a digital system. It takes the numerator from the 3rd level, the denominator from the 2nd level and the number of divisions to carry out in the first level. The program will return a list with the values of the divisions. << OVER SIZE [ 0 ] SWAP RDM 4 ROLL MADD -> Q N P << { } 1 N START P Q MDIV [ 1 0 ] MMLT 'P' STO 1 GET DUP 1 DISP + NEXT >> >> Ackermann's formula Suppose you have a SISO system dx=Ax+Bu and you want to use the control law u=Kx to place the poles of the closed-loop system at a certain location. Then you can use Ackermann's formula to compute the gain matrix K. This program computes this gain matrix using Ackermann's formula and the following data: 3: A 2: B 1: { desired poles (MCOEF format) } page 27 The program will give you the gain matrix K: << MCOEF -> A B P << B DUP 2 A SIZE 1 GET START A ROT * SWAP OVER 1000 Col+ NEXT INV P A MEVL * SWAP TRN 0 * DUP SIZE -1 PUT SWAP * >> >> SPLIT The following program, "SPLIT", is a perfect example of how much work can be saved by using MATH and a little programming. Suppose you have the polynomial fraction P(s)/Q(s). Now you make s=jw, and you want to split the original fraction into the real and imaginary parts, Pr(w)/Qr(w) + j*Pi(w)/Qi(w). The following program will do the task: it takes P and Q from the stack and returns on level two the list { Pr Qr } and on level one the list { Pi Qi } << [ (0;1) (0;0) ] ROT OVER MEVL ROT ROT MEVL ZTRIM DUP CONJ ROT OVER MMLT ROT ROT MMLT RE OVER RE ZTRIM OVER 2 ->LIST ROT IM ZTRIM ROT 2 ->LIST >> Example: P(s)/Q(s) = 1/s(s+1)^2 2: [ 1 ] 1: [ 1 2 1 0 ] After SPLIT you'll get 2: { [ -2 0 0 ] [ 1 0 2 0 1 0 0 ] } 1: { [ 1 0 -1 0 ] [ 1 0 2 0 1 0 0 ] } So the decomposition is: P(jw) -2 w^2 - 1 ----- = --------------- + j*--------------- Q(jw) w^4 + 2*w^2 + 1 w^5 + 2*w^3 + w page 28 A NOTE ON THE METHODS MRoot uses Laguerre's method only. It works VERY well for polynomials with distinct roots, and is satisfactory for polynomials with multiple roots. If you want to know more about this method try the book "A SURVEY OF NUMERICAL MATHEMATICS", by Young and Gregory. If you are using a G(X), then MRoot is simply your PROOT with some modifications for interfacing with MATH. I use Faddeev's method a lot of times in the program. The method can be used to compute a lot of things of a matrix: the characteristic polynomial, the adjoint, the determinant and all the Eigenvectors. If you want to know more about Faddeev's method try the book "MATRIX THEORY", by Gantmacher. page 29 THANKS TO I want to thank the following people for their support and suggestions: Andre Hentz (andre@lcmi.ufsc.br) Arie Leib Bukinsky (bukinsky@jct.al.il) David Peterson (18084DEP@msu.edu) Hoa Van Lai (imach@cc.utexas.edu) Joe Horn (joehorn@hpcvbbs.external.hp.com) Keith Maddock (madd0118@nova.gmi.edu) Marcelo Rodrigues (marcelor@acs.bu.edu) Marcus Kindel (kindel@inf.ufrgs.br) Mario Mozgy (mozgy@diana.zems.etf.hr) Michael Guravage (Michael.Guravage@cwi.nl) Mika Heiskanen (mheiskan@delta.hu.fi) Sean McNamee (seanmc@u.washington.edu) Tyson Leistiko (eleistik@elee.calpoly.edu) Vinicius Vasconcellos (cello@vortex.ufrgs.br) page 30