Here is a reworked version of Laplace for the G/GX ONLY !! It uses the PROOT and PCOEFF commands of the G/GX. It is much smaller than the S/SX version. I also tightened up some of the SysRPL coding to shorten it up. It should run the same, but let me know if you find a bug. I'm working on improvements that I hope to post sometime in the next several months. John Edry JEEjohn@aol.com Here is John Meissner's original document file: Item: 1357 by meissner@triton.unm.edu [John Meissner] Subj: Lalpace_jm -- New Version. Date: 04 Jul 1992 [Note: John makes several references to Wayne Scott's POLY software. Details about POLY can be found on Goodies Disks 1 and 7. -jkh-] These routines are an upgrade to my previous Laplace transform utility. Many of the new programs have been rewritten in SYSTEM-RPL. As always, system RPL can cause some unpredictable things to happen -- including MEMORY LOST errors. I have strived to do my best to make the routines safe, but I am new to syystem-RPL programming and there are undoubtedly some bugs still left in the routines. I am posting these routine to comp.sys.hp48 so that these bugs can be tested and corrected over the next few weeks so that I can release some kind of a final product. VERY IMPORTANT! DO NOT USE THESE ROUTINES UNLESS YOU ARE WILLING TO SUFFER A MEMORY LOST! I have not had any of these types of problems for a month or so, but they can happen so beware. I have tested these routines somewhat extensively and have no trobel to reoprt. If problems do arise of aby kind a would appreciate people dropping me a line and letting me fix them. After a few weeks I will post a more finalized version to comp.sources.hp48. In the interim, keep the bug reports rolling in. Summary of changes in these routines: 1) system-RPL, these routines run 5 to 10 times faster. 2) Remove flags [0-5] usage. 3) Fixed bugs in & and RT-> that caused incorrect transforms. 4) install a patch that allows 't' to exists elsewhere in the PATH. 5) Remove 'e^t' notation. 6) Recognizes and handles correctly the 'SQ()' function. 7) Many changes in how the routines work that speed up or otherwise enhance their performance. The origional routines used Wanye Scotts polinomial routines for most of the grunt work. I don't think any of Wayne's routines are still in this package, but he deserves credit for the notation and ultimately these routines since I never would have bothered without his work. Also, Bill Wickes' port of a polynomial root finder is included in these routines. Thank you Bill for the efforts. The remainder of this article is an edited version of my original post. The following programs are released to the public domain provided that no money exchange hands (unless of course my hands are involved) A few disclaimers are in order. 1) The routines in this directory use Wayne Scott's polynomial root finder routines extensively. Beware -- if you already have these routines and use them, then you need to read all of these documents to determine what effects might surface. For the most part, these routines are entirely different even though they do accomplish some of the same tasks. 2) If you are unfamiliar with the format of the polynomials used by Wayne's routines, here is a brief refresher: the polynomial : x^4 - 3*x^3 - 2*x -1 is represented as: { 1 -3 0 -2 -1 } This is to say the first element of the list is the coefficient for the x^4 term and so on through the equation. It is customary to use 's' for the Laplace variable, so from here on, I will use 's' in my examples. Some of the routines require two polynomials on the stack. For example, the ratio of the two polynomials representing this expression: 3*s^5 - 3*s^3 + 5*s^2 - 2 --------------------------------------- s^5 - 7*s^4 + 15*s^3 - 5*s^2 -16*s + 12 would be represented on the stack as: 2: {3 0 -3 5 0 -2} 1: {1 -7 15 -5 -16 12} Another method of representing the same ratio is: 2: {3 0 -3 5 0 -2) 1: {3 2 2 1 -1} where level 2 contains the same list as the previous example. However, level 1 contains the roots of the denominator. Hopefully, these examples are clear enough for you to get the picture. The following are descriptions and examples of each of the functions in the LAPLACE directory: t This variable returns an unevaluated copy of itself. I allows the routines to operate when ther is another 't' defined in the current path. It is also useful for keying is formulae. Since the independant variable for these routines must be 't' ->L This program takes an algebraic object and returns its Laplace Transform. The input function must be a function of 't' that is to say that the only independent variable in the function must be lower case t. The functions that it recognizes are constants, exponentials, sines, cosines, and polynomials. The program should allow any combinations of multiplication, addition, subtraction, and integer exponents. Division by non constants is not supported however. For example: 1: 'COS(2*t)^2' ->L after a pause will return : 2: { 1 0 8 } ; numerator [was given as {1 0 2} - JE] 1: { (0,4) (0,0) (0,-4) } ; roots of the denominator This represent the transform. With this as an input, the inverse transform function returns : L-> 1: '1/2 + 1/2*COS(4*t)' This doesn't look the same as the original function; but, the answer is correct. COS(t)^2 = 1/2 + 1/2*COS(2+t) is a trigonometric identity. Kinda nifty eh? Another interesting result of the transformation is integration. Integration in the time domain is division by s in the s domain. So, take the function: 1: 'EXP(-2*t)*COS(t)^2' ->L Returns: 2: {1 4 6 } 1: { (-2,2) (-2,0) (-2,-2) } The list on level one is the roots of the denominator. If you add a zero to the list ( edit the list or just put a zero on the stack and press the + key ) you are effectively multiplying the denominator by s. This is the same as dividing the fraction by s. The result in the time domain, after the inverse transform is done, is the integration of the original function between the limits of 0 and 't.' For example: 2: { 1 4 6 } 1: { (-2,2) (-2,0) (-2,-2) 0 } ->L Returns: 1: '3/8-1/8*EXP(-(2*t))*COS(2*t)+1/8*EXP(-(2*t))*SIN(2* t)-1/4*EXP(-(2*t))' [ this last term had EXP(2*t)' - JE] This is the integral of the original function evaluated between 0 and t. In many cases the general solution can be obtained by replacing the constant (in this case 3/8) with a general constant of integration. Needless to say, this method of integration was a little easier than looking in the integral tables. The description of the inverse Laplace Transformer follows. L-> This program takes the numerator, level 2, and the denominator, level 1 (factored), and returns its inverse Laplace Transform. The factors of the denominator need not be grouped together as Wayne's routines require since they are sorted before anything is done to them. I originally wrote this routine and uploaded it to hpcvbbs, but I did not include much for documentation. Since then I have seen it posted a few times and have heard of some bugs that I am unable to duplicate. This may be because the users are using Wayne's routines with this one, or, I fixed the bugs and don't remember. Either way here is the latest version. The routine should correctly transform the ratio of any two polynomials with real coefficients. The only limitation i know of is that the numerator should be of lower order than the denominator. You may still get the correct answer if this condition is not met but there are no guarantees. I have found absolutely no problems with this routine. In fact, I have found 2 errors in the transform tables of the "CRC Handbook of Mathematical Formulas.' I am not willing to say that there are no bugs because I am sure they exist. Please let me know as they become apparent. I have been truly amazed with the results this program returns; Wayne did a good job with his routines. He did almost all of the work. Here is and example: 2: { 2 0 4 } 1: { 1 1 0 4 } L-> Returns: 1:'-1 - 2*t*EXP(t) + EXP(4*t)' RT-> The results of this routine are different depending on the number of lists on the stack. If there are 2 lists of numbers on the stack, the routine will assume that the represent a fraction and the numerator is divided by the coefficient of the highest order term in the denominator. This is necessary to keep the ratio correct since this term is lost in the expasion. In the event that the stack contains only one list this program returns the roots of that list sorted. 1: { 1 -6 1 24 -20 } RT-> returns: 1: { 1 2 -2 5 } FADD This routine adds two partial fractions. They must be in the form: 4: list (numerator) 3: list (denominator roots) 2: list (second nemerator) 1: list (second denominator roots) & This routine convolves (sp?) Two partial fractions. It is used by the routine ->L. It either does a partial fraction expansion of one of the two terms and then does an 's' shifted summation of the terms, or is does a straight multiplication of the terms -- depending on which is appropriate. It is still written in user-RPL since there was no real speed increase when I rewrote it. I believe that user-RPL should be used whenever possible to avoid as many headaches as possible. SORT Fairly self explanatory. Not the bubble variety. It is much smaller than the bubble sorts that I tried and is a little faster for lists that are shorter than about 20 elements. The sort order is largest to smallest with weighting on the real value. This means that the unstable roots will be at the begining of the list if they exist. RED This routine uses PDIV to remove any common roots in the numerator and denominator. It is slow but necessary if you are working with complex transforms. Q This routine takes an object from the stack and attempts to rationalize it to within 5 digits of accuracy. In other words, if you have a nomber like 5.200004543 and want to round it to the nearest fraction then Q is your program. It is necessary because the roots returned by the root finder are not exact. And the calculator drops digits here and there when dividing or finding roots. The routine will also accept lists, algebraics, complex numbers, and combinations of any of the above. PMUL This routine take two polynomials and returns their products. I have completely rewritten this program to speed it up and slightly change the function. The objects do not have to be lists. The routine will now multiply a list by a constant. It should function identically to wayne's routines other than this change. IRT This routine take the roots of the polynomial and multiplies them to find the polynomial. PADD This routine takes two polynomials and adds them. In addition, if the object on level 1 is a number (real or complex), the routine adds the number to each of the elements in the list in the other stack level. These changes were made in the interest of speed. TRIM This routine takes a list and performs Q and then strips the leading zeros. It works identically to the original I believe. PDIV This routine is NOT the same a Wayne's. This routines accepts a list, representing a polinomial, and a number, representing a root of the polinomial, and returns the list with that root divided out and the remainder which is also the value of the polinomial evaluated at that root. Example 2: { 1 -2 1 } 1: 1 PDIV (returns) 2: 0 1: { 1 -1 } RDER This routine takes two lists (numerator,denominator) and returns the numerator of the derivative of the ratio. PDER Same as above except just for one polynomial and returns the derivative of that polynomial. PF Does partial fraction expansion of the ratio (numerator, roots) on the stack. Please let me know id this program is in any way useful to amy of you. Also please let me know of any suggestions or bugs that occur. Good luck, John Meissner