REDUCE

7.2 Mathematical Functions

REDUCE knows that the following represent mathematical functions that can take arbitrary scalar expressions as their argument(s).

7.2.1 Elementary Functions

Trigonometric, hyperbolic and exponential functions:

    sin cos tan cot csc sec sinh  
    cosh tanh coth csch sech exp

Their inverse functions:

    asin acos atan acot acsc asec asinh acosh  
    atanh acoth acsch asech log log10 logb

where log is the natural logarithm, log10 is the logarithm to base 10, and logb has two arguments of which the second is the logarithmic base. Note on the CSL GUI and other graphical interfaces the inverse trig and hyperbolic functions are output as arcsin etc.

Miscellaneous functions:

    sqrt  hypot  atan2

The function hypot takes two arguments x and y and returns the value ∘ -------
  x2 + y2 but, when the switch ROUNDED is ON, problems with rounding and possible overflow for large numerical arguments are reduced.

The function atan2 also takes two arguments y and x respectively and returns a value of arctan(y∕x) in the range (π,π] taking account of the signs of its two arguments and avoiding an error if x = 0.

REDUCE knows various elementary identities and properties of these functions. For example:

      cos(-x) = cos(x)        sin(-x) = -sin(x)  
      cos(n*pi) = (-1)^n      sin(n*pi) = 0  
      log(e) = 1              e^(i*pi/2) = i  
      log(1) = 0              e^(i*pi) = -1  
      log(e^x) = x            e^(3*i*pi/2) = -i  
      sin(asin(x) = x         atan(0) = 0  
      atan2(0, -1) = pi       atan2(1, 0) = pi/2

The derivatives of all the elementary functions except hypot are also known to the system. Beside these identities, there are a lot of simplifications for elementary functions defined in REDUCE as rulelists. In order to view these, the SHOWRULES operator can be used, e.g.

      SHOWRULES tan;  
 
{tan(~n*arbint(~i)*pi + ~~x) => tan(x) when fixp(n),  
 
 tan(~x) => trigquot(sin(x),cos(x)) when knowledge_about(sin,x,tan),  
 
      ~x + ~~k*pi              x                 k  
 tan(-------------) =>  - cot(--- + i*pi*impart(---))  
          ~~d                  d                 d  
                                                     k     1  
                                    when abs(repart(---))=---,  
                                                     d     2  
 
      ~~w + ~~k*pi           w      k                k  
 tan(--------------) => tan(--- + (--- - fix(repart(---)))*pi)  
          ~~d                d      d                d  
 
                                                         k  
  when ((ratnump(rp) and abs(rp)>=1) where rp => repart(---)),  
                                                         d  
 
 tan(atan(~x)) => x,  
 
                             2  
 df(tan(~x),~x) => 1 + tan(x) }

For further simplification, especially of expressions involving trigonometric functions, see the TRIGSIMP package (chapter 16.78) documentation.

Functions not listed above may be defined in the special functions package SPECFN.

The user can add further rules for the reduction of expressions involving these operators by using the LET command.

In many cases it is desirable to expand product arguments of logarithms, or collect a sum of logarithms into a single logarithm. Since these are inverse operations, it is not possible to provide rules for doing both at the same time and preserve the REDUCE concept of idempotent evaluation. As an alternative, REDUCE provides two switches EXPANDLOGS and COMBINELOGS to carry out these operations. Both are off by default, and are subject to the value of the switch PRECISE. This switch is on by default and prevents modifications that may be false in a complex domain. Thus to expand LOG(3*Y) into a sum of logs, one can say

        ON EXPANDLOGS; LOG(3*Y);

whereas to expand LOG(X*Y) into a sum of logs, one needs to say

        OFF PRECISE; ON EXPANDLOGS; LOG(X*Y);

To combine this sum into a single log:

        OFF PRECISE; ON COMBINELOGS; LOG(X) + LOG(Y);

These switches affect the logarithmic functions LOG10 (base 10) and LOGB (arbitrary base) as well.

At the present time, it is possible to have both switches on at once, which could lead to infinite recursion. However, an expression is switched from one form to the other in this case. Users should not rely on this behavior, since it may change in the future.

The current version of REDUCE does a poor job of simplifying surds. In particular, expressions involving the product of variables raised to non-integer powers do not usually have their powers combined internally, even though they are printed as if those powers were combined. For example, the expression

        x^(1/3)*x^(1/6);

will print as

        SQRT(X)

but will have an internal form containing the two exponentiated terms. If you now subtract sqrt(x) from this expression, you will not get zero. Instead, the confusing form

        SQRT(X) - SQRT(X)

will result. To combine such exponentiated terms, the switch COMBINEEXPT should be turned on.

The square root function can be input using the name SQRT, or the power operation ^(1/2). On output, unsimplified square roots are normally represented by the operator SQRT rather than a fractional power. With the default system switch settings, the argument of a square root is first simplified, and any divisors of the expression that are perfect squares taken outside the square root argument. The remaining expression is left under the square root. Thus the expression

        sqrt(-8a^2*b)

becomes

        2*a*sqrt(-2*b).

Note that such simplifications can cause trouble if A is eventually given a value that is a negative number. If it is important that the positive property of the square root and higher even roots always be preserved, the switch PRECISE should be set on (the default value). This causes any non-numerical factors taken out of surds to be represented by their absolute value form. With PRECISE on then, the above example would become

        2*abs(a)*sqrt(-2*b).

However, this is incorrect in the complex domain, where √ ---
  x2 is not identical to |x|. To avoid the above simplification, the switch PRECISE_COMPLEX should be set on (default is off). For example:

on precise_complex; sqrt(-8a^2*b);

yields the output

             2  
2*sqrt( - 2*a *b)

If the switch ROUNDED is on, any of the elementary functions

    acos acosh acot acoth acsc acsch asec asech  
    asin asinh atan atanh atan2 cos cosh cot coth  
    csc csch exp hypot log logb log10 sec sech  
    sin sinh sqrt tan tanh

when given a numerical argument has its value calculated to the current degree of floating point precision. In addition, real (non-integer valued) powers of numbers will also be evaluated.

If the COMPLEX switch is turned on in addition to ROUNDED, these functions will also calculate a real or complex result, again to the current degree of floating point precision, if given complex arguments. For example, with on rounded,complex;

    2.3^(5.6i)  ->  -0.0480793490914 - 0.998843519372*I  
    cos(2+3i)   ->  -4.18962569097 - 9.10922789376*I

For log and the inverse trigonometric and hyperbolic functions which are multi-valued, the principal value is returned. The branch cuts chosen (except for acot) are now those recommended by W. Kahan (Branch Cuts for Complex Elementary Functions, or Much Ado About Nothing’s Sign Bit, in The State of the Art in Numerical Analysis, A. Iserles, M.J.D. Powell Eds., Clarendon Press, Oxford, 1987).

The exception for acot is necessary as elsewhere in REDUCE acot(z) is taken to be π acot(z) rather than acot(z). The branch cuts are:

log, sqrt: {rr r < 0}
asin, acos: {rr (r > 1 r < 1)}
acsc, asec: {rr r0 r > 1 r < 1}
atan, acot:{r ir (r > 1 r < 1)}
asinh: {r ir (r 1 r ≤−1)}
acsch: {r ir r0 r ≥−1 r 1}
acosh: {rr r < 1}
asech: {rr (r > 1 r < 0)}
atanh: {rr (r > 1 r < 1)}
acoth: {rr r > 1 r < 1}

7.2.2 Special Functions

The functions in this section are either built-in or are autoloading functions from the package SPECFN. On the CSL GUI and other graphical interfaces many of the functions will be output in standard form; for example BesselJ(nu,x) will be output as Jν(x) and Jacobisn(u,k) as sn(u,k). For most of the non-unary special functions in this section (Lerch_Phi is an exception), the last parameter is the ‘main’ variable and the earlier parameters are the order (or orders) usually rendered in the literature as subscipts and/or superscripts.

The information provided below is fairly rudimentary; more complete information may be found in the SPECFN package. Quick Reference Tables are also available.

Integral Functions:

    Ei Li Si Ci Shi Chi Erf Fresnel_S Fresnel_C

All these functions are unary; the first six are the exponential, logarithmic, sine and cosine integrals and their hyperbolic counterparts. Erf, Fresnel_S and Fresnel_C are the error function and the Fresnel sine and cosine integrals respectively.

Beta, Gamma and Related Functions:

    Beta ibeta Gamma igamma psi Polygamma

The Gamma function is unary whilst Beta is binary. The binary function igamma and ternary function ibeta are the (normalised) incomplete Gamma and Beta functions respectively. The unary function psi is sometimes known as the Digamma function and the binary function Polygamma with integer first parameter n is the nth derivative of the function psi.

Bessel and Related Functions:

    BesselJ BesselY BesselI BesselK Hankel1 Hankel2

All of these functions are binary, their first argument being the order of the function.

For the special functions below, a second Quick Reference Table is available.

Airy Functions:

    Airy_Ai Airy_Aiprime Airy_Bi Airy_Biprime

These are all unary functions.

Kummer, Lommel, Struve and Whittaker Functions:

    KummerM KummerU Lommel1 Lommel2  
    StruveH StruveL WhittakerM WhittakerW

The Struve functions are both binary whilst the remaining ones are all ternary.

Riemann Zeta and Lambert’s W Function:

    zeta  Lambert_W

These are both unary functions.

PolyLogarithms and Related Functions

    dilog Polylog Lerch_Phi

These take one, two and three arguments respectively.

Associated Legendre functions:

    SphericalHarmonicY SolidHarmonicY

These functions take four and six arguments respectively.

Jacobi Elliptic Functions:

    Jacobisn Jacobicn Jacobidn

and their three reciprocals

    Jacobins Jacobinc Jacobind

and six quotients

    Jacobisc Jacobisd Jacobicd  
    Jacobics Jacobids Jacobidc

All are binary functions with the second argument being the modulus. The binary function Jacobiam is the amplitude.

Complete and Incomplete Elliptic Integrals of the First & Second Kinds:

    EllipticK EllipticE EllipticF EllipticE  
    JacobiE JacobiZeta

The function EllipticE may take one or two arguments to denote the complete and Legendre’s form of the incomplete elliptic integrals of the second kind respectively. The complete integral of the first kind EllipticK is unary whilst EllipticF, JacobiE and JacobiZeta are binary and represent the incomplete integral of the first kind, Jacobi’s form of the incomplete elliptic integral of the second kind and Jacobi’s Zeta function respectively.

Jacobi’s Theta Functions:

    EllipticTheta1 EllipticTheta2  
    EllipticTheta3 EllipticTheta4

are all binary functions with the second argument being the nome.

For the elliptic functions above a Quick Reference Table is available.

7.2.3 Polynomial Functions

The polynomial functions below are from the non-core package SPECFN and for the most part are not autoloading. This package needs to be loaded before they may be used with the command:

    load_package specfn;

The names of the REDUCE operators for the polynomial functions below are mostly built by adding a P to the name of the polynomial, e.g. EulerP implements the Euler polynomials.

The information in this subsection is fairly rudimentary; more complete information may be found in the SPECFN package.
A Quick Reference Table is available for all the polynomial functions below.

Orthogonal Polynomials

Some well-known orthogonal polynomials are available:

The first three of these functions are binary and the first argument should be an integer specifying the order of the required polynomial. The functions LegendreP and LaguerreP may be used either as binary operators or ternary ones and represent the corresponding ‘basic’ and associated functions respectively. Finally the Gegenbauer polynomials are ternary whilst the Jacobi polynomials are quaternary.

Most definitions are equivalent to those in [AS72], except for the ternary associated Legendre functions:

                           dmP  (x)
P (nm)(x) = (− 1)m(1 − x2)m∕2---nm---.
                             dx

These are sometimes mistakenly referred to as associated Legendre polynomials, but they are only polynomial when m is even.

Other Polynomial Functions

Fibonacci Polynomials are computed by the binary operator FibonacciP, where FibonacciP(n,x) returns the nth Fibonacci polynomial in the variable x. If n is an integer, it will be evaluated using the recursive definition:

F0(x) = 0;    F1(x) = 1;    Fn(x) = xFn−1(x) + Fn−2(x).

Euler Polynomials are computed by the binary operator EulerP, where EulerP(n,x) returns the nth Euler polynomial in the variable x.

Bernoulli Polynomials are computed by the binary operator BernoulliP, where BernoulliP(n,x) returns the nth Bernoulli polynomial in the variable x.