)abbrev package ELFUTS EllipticFunctionsUnivariateTaylorSeries
)boot $tryRecompileArguments := nil
++ Elliptic functions expanded as Taylor series
++ Author: Bill Burge, Clifton J. Williamson
++ Date Created: 1986
++ Keywords: elliptic function, Taylor series
++ Examples:
++ References:
++ Description: The elliptic functions sn, sc and dn are expanded as
++ Taylor series.
EllipticFunctionsUnivariateTaylorSeries(Coef, UTS):
 Exports == Implementation where
  Coef : Field
  UTS  : UnivariateTaylorSeriesCategory Coef

  L   ==> List
  I   ==> Integer
  RN  ==> Fraction Integer
  ST  ==> Stream Coef
  STT ==> StreamTaylorSeriesOperations Coef
  YS  ==> Y$ParadoxicalCombinatorsForStreams(Coef)

  Exports ==> with
    jacobiSn : (UTS, Coef) -> UTS
      ++\spad{jacobiSn(z, m)} expands the elliptic function sn as a Taylor
      ++ series in z.
    jacobiCn : (UTS, Coef) -> UTS
      ++\spad{jacobiCn(z, m)} expands the elliptic function cn as a Taylor
      ++ series in z.
    jacobiDn : (UTS, Coef) -> UTS
      ++\spad{jacobiDn(z, m)} expands the elliptic function dn as a Taylor
      ++ series in z.
    if Coef has Algebra(RN) then
        ellipticE : (UTS, Coef) -> UTS
          ++ ellipticE(z, m) expands the elliptic integral E as a Taylor
          ++ series in z.
        ellipticF : (UTS, Coef) -> UTS
          ++ ellipticF(z, m) expands the elliptic integral F as a Taylor
          ++ series in z.
        ellipticPi : (UTS, Coef, Coef) -> UTS
          ++ ellipticPi(z, n, m) expands the elliptic integral Pi as a Taylor
          ++ series in z.
    sncndn : (ST, Coef) -> L ST
       ++\spad{sncndn(s, c)} is used internally.

  Implementation ==> add
    import from StreamTaylorSeriesOperations Coef
    UPS==> StreamTaylorSeriesOperations Coef
    lint ==> lazyIntegrate

    SPFCN : Boolean := Coef has SpecialFunctionCategory

    sncndnre : (Coef, Coef, Coef, Coef, L ST, ST, Coef) -> L ST
    sncndnre(m, s0, c0, d0, scd, dx, sign) ==
            [lint(s0,      scd.2*$UPS scd.3*$UPS dx),  _
             lint(c0, sign*scd.1*$UPS scd.3*$UPS dx),  _
             lint(d0, sign*m*$UPS scd.1*$UPS scd.2*$UPS dx)]

    sncndn(z, m) ==
      empty? z => [0 :: ST, 1 :: ST, 1::ST]
      (z0 := frst z) = 0 => YS(x +-> sncndnre(m, 0, 1, 1, x, deriv z, -1), 3)
      SPFCN =>
          scd := YS(x +-> sncndnre(m, 0, 1, 1, x, deriv z, -1), 3)
          sn0 : Coef := jacobiSn(z0, m)
          cn0 : Coef := jacobiCn(z0, m)
          dn0 : Coef := jacobiDn(z0, m)
          c1 := m*sn0^2
          -- onelst : List Coef := [1]
          invden := recip(1::ST - c1*$UPS scd.1 *$UPS scd.1)::ST
          sn1 : ST := invden *$UPS (cn0*dn0*scd.1 + sn0*scd.2 *$UPS scd.3)
          cn1 : ST := invden *$UPS (cn0*scd.2 - sn0*dn0*scd.1 *$UPS scd.3)
          dn1 : ST := invden *$UPS (dn0*scd.3 - m*sn0*cn0*scd.1 *$UPS scd.2)
          [sn1, cn1, dn1]
      error "ELFUTS:sncndn: constant coefficient should be 0"
    jacobiSn(z, m)  == series sncndn.(coefficients z, m).1
    jacobiCn(z, m)  == series sncndn.(coefficients z, m).2
    jacobiDn(z, m)  == series sncndn.(coefficients z, m).3

    if Coef has Algebra(RN) then

        ellipticE(z, m) ==
            cz : ST := coefficients z
            empty? cz => 0
            dz := differentiate(z)
            s1 := sqrt(1 - m*z^2)
            s2 := (1 - z^2)^(-1/2)
            (z0 := coefficient(z, 0)) = 0 =>
                integrate(s1*s2*dz)
            SPFCN =>
                c0 : Coef := ellipticE(z0, m)
                c0::UTS + integrate(s1*s2*dz)
            error "ELFUTS:ellipticE: constant coefficient should be 0"

        ellipticF(z, m) ==
            cz : ST := coefficients z
            empty? cz => 0
            dz := differentiate(z)
            s1 := (1 - m*z^2)^(-1/2)
            s2 := (1 - z^2)^(-1/2)
            (z0 := coefficient(z, 0)) = 0 =>
                integrate(s1*s2*dz)
            SPFCN =>
                c0 : Coef := ellipticF(z0, m)
                c0::UTS + integrate(s1*s2*dz)
            error "ELFUTS:ellipticF: constant coefficient should be 0"

        ellipticPi(z, n, m) ==
            cz : ST := coefficients z
            empty? cz => 0
            dz := differentiate(z)
            s1 := (1 - m*z^2)^(-1/2)
            s2 := (1 - z^2)^(-1/2)
            ss : UTS := (1 - n*z^2)^(-1@RN)*s1*s2*dz
            (z0 := coefficient(z, 0)) = 0 =>
                integrate(ss)
            SPFCN =>
                c0 : Coef := ellipticPi(z0, n, m)
                c0::UTS + integrate(ss)
            error "ELFUTS:ellipticPi: constant coefficient should be 0"
)boot $tryRecompileArguments := true

--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in
--      the documentation and/or other materials provided with the
--      distribution.
--
--    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
