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 2 }              ; numerator 
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 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
