{-# LANGUAGE RebindableSyntax #-}
module MathObj.PowerSeries2.Core where

import qualified MathObj.PowerSeries as PS
import qualified MathObj.PowerSeries.Core as PSCore

import qualified Algebra.Differential   as Differential
import qualified Algebra.Vector         as Vector
import qualified Algebra.Field          as Field
import qualified Algebra.Ring           as Ring
import qualified Algebra.Additive       as Additive

import NumericPrelude.Base


type T a = [[a]]


lift0fromPowerSeries :: [PS.T a] -> T a
lift0fromPowerSeries :: [T a] -> T a
lift0fromPowerSeries = (T a -> [a]) -> [T a] -> T a
forall a b. (a -> b) -> [a] -> [b]
map T a -> [a]
forall a. T a -> [a]
PS.coeffs

lift1fromPowerSeries ::
   ([PS.T a] -> [PS.T a]) -> (T a -> T a)
lift1fromPowerSeries :: ([T a] -> [T a]) -> T a -> T a
lift1fromPowerSeries [T a] -> [T a]
f T a
x0 =
   (T a -> [a]) -> [T a] -> T a
forall a b. (a -> b) -> [a] -> [b]
map T a -> [a]
forall a. T a -> [a]
PS.coeffs ([T a] -> [T a]
f (([a] -> T a) -> T a -> [T a]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> T a
forall a. [a] -> T a
PS.fromCoeffs T a
x0))

lift2fromPowerSeries ::
   ([PS.T a] -> [PS.T a] -> [PS.T a]) -> (T a -> T a -> T a)
lift2fromPowerSeries :: ([T a] -> [T a] -> [T a]) -> T a -> T a -> T a
lift2fromPowerSeries [T a] -> [T a] -> [T a]
f T a
x0 T a
x1 =
   (T a -> [a]) -> [T a] -> T a
forall a b. (a -> b) -> [a] -> [b]
map T a -> [a]
forall a. T a -> [a]
PS.coeffs ([T a] -> [T a] -> [T a]
f (([a] -> T a) -> T a -> [T a]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> T a
forall a. [a] -> T a
PS.fromCoeffs T a
x0) (([a] -> T a) -> T a -> [T a]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> T a
forall a. [a] -> T a
PS.fromCoeffs T a
x1))


{- * Series arithmetic -}

add, sub :: (Additive.C a) => T a -> T a -> T a
add :: T a -> T a -> T a
add = T a -> T a -> T a
forall a. C a => [a] -> [a] -> [a]
PSCore.add
sub :: T a -> T a -> T a
sub = T a -> T a -> T a
forall a. C a => [a] -> [a] -> [a]
PSCore.sub

negate :: (Additive.C a) => T a -> T a
negate :: T a -> T a
negate = T a -> T a
forall a. C a => [a] -> [a]
PSCore.negate


scale :: Ring.C a => a -> T a -> T a
scale :: a -> T a -> T a
scale = ([a] -> [a]) -> T a -> T a
forall a b. (a -> b) -> [a] -> [b]
map (([a] -> [a]) -> T a -> T a)
-> (a -> [a] -> [a]) -> a -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [a] -> [a]
forall (v :: * -> *) a. (C v, C a) => a -> v a -> v a
(Vector.*>)

mul :: Ring.C a => T a -> T a -> T a
mul :: T a -> T a -> T a
mul = ([T a] -> [T a] -> [T a]) -> T a -> T a -> T a
forall a. ([T a] -> [T a] -> [T a]) -> T a -> T a -> T a
lift2fromPowerSeries [T a] -> [T a] -> [T a]
forall a. C a => [a] -> [a] -> [a]
PSCore.mul


divide :: (Field.C a) =>
   T a -> T a -> T a
divide :: T a -> T a -> T a
divide = ([T a] -> [T a] -> [T a]) -> T a -> T a -> T a
forall a. ([T a] -> [T a] -> [T a]) -> T a -> T a -> T a
lift2fromPowerSeries [T a] -> [T a] -> [T a]
forall a. C a => [a] -> [a] -> [a]
PSCore.divide


sqrt :: (Field.C a) =>
   (a -> a) -> T a -> T a
sqrt :: (a -> a) -> T a -> T a
sqrt a -> a
fSqRt =
   ([T a] -> [T a]) -> T a -> T a
forall a. ([T a] -> [T a]) -> T a -> T a
lift1fromPowerSeries (([T a] -> [T a]) -> T a -> T a) -> ([T a] -> [T a]) -> T a -> T a
forall a b. (a -> b) -> a -> b
$
   (T a -> T a) -> [T a] -> [T a]
forall a. C a => (a -> a) -> [a] -> [a]
PSCore.sqrt (a -> T a
forall a. a -> T a
PS.const (a -> T a) -> (T a -> a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\[a
x] -> a -> a
fSqRt a
x) ([a] -> a) -> (T a -> [a]) -> T a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> [a]
forall a. T a -> [a]
PS.coeffs)

pow :: (Field.C a) =>
   (a -> a) -> a -> T a -> T a
pow :: (a -> a) -> a -> T a -> T a
pow a -> a
fPow a
expon =
   ([T a] -> [T a]) -> T a -> T a
forall a. ([T a] -> [T a]) -> T a -> T a
lift1fromPowerSeries (([T a] -> [T a]) -> T a -> T a) -> ([T a] -> [T a]) -> T a -> T a
forall a b. (a -> b) -> a -> b
$
   (T a -> T a) -> T a -> [T a] -> [T a]
forall a. C a => (a -> a) -> a -> [a] -> [a]
PSCore.pow (a -> T a
forall a. a -> T a
PS.const (a -> T a) -> (T a -> a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\[a
x] -> a -> a
fPow a
x) ([a] -> a) -> (T a -> [a]) -> T a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> [a]
forall a. T a -> [a]
PS.coeffs) (a -> T a
forall a. a -> T a
PS.const a
expon)


swapVariables :: T a -> T a
swapVariables :: T a -> T a
swapVariables = ([a] -> [a]) -> T a -> T a
forall a b. (a -> b) -> [a] -> [b]
map [a] -> [a]
forall a. [a] -> [a]
reverse


differentiate0 :: (Ring.C a) => T a -> T a
differentiate0 :: T a -> T a
differentiate0 =
   T a -> T a
forall a. T a -> T a
swapVariables (T a -> T a) -> (T a -> T a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> T a
forall a. C a => T a -> T a
differentiate1 (T a -> T a) -> (T a -> T a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> T a
forall a. T a -> T a
swapVariables

differentiate1 :: (Ring.C a) => T a -> T a
differentiate1 :: T a -> T a
differentiate1 = ([T a] -> [T a]) -> T a -> T a
forall a. ([T a] -> [T a]) -> T a -> T a
lift1fromPowerSeries (([T a] -> [T a]) -> T a -> T a) -> ([T a] -> [T a]) -> T a -> T a
forall a b. (a -> b) -> a -> b
$ (T a -> T a) -> [T a] -> [T a]
forall a b. (a -> b) -> [a] -> [b]
map T a -> T a
forall a. C a => a -> a
Differential.differentiate

integrate0 :: (Field.C a) => [a] -> T a -> T a
integrate0 :: [a] -> T a -> T a
integrate0 [a]
cs =
   T a -> T a
forall a. T a -> T a
swapVariables (T a -> T a) -> (T a -> T a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> T a -> T a
forall a. C a => [a] -> T a -> T a
integrate1 [a]
cs (T a -> T a) -> (T a -> T a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> T a
forall a. T a -> T a
swapVariables

integrate1 :: (Field.C a) => [a] -> T a -> T a
integrate1 :: [a] -> T a -> T a
integrate1 = (a -> [a] -> [a]) -> [a] -> T a -> T a
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> [a] -> [a]
forall a. C a => a -> [a] -> [a]
PSCore.integrate



{- |
Since the inner series must start with a zero,
the first term is omitted in y.
-}
compose :: (Ring.C a) => [a] -> T a -> T a
compose :: [a] -> T a -> T a
compose = ([T a] -> [T a]) -> T a -> T a
forall a. ([T a] -> [T a]) -> T a -> T a
lift1fromPowerSeries (([T a] -> [T a]) -> T a -> T a)
-> ([a] -> [T a] -> [T a]) -> [a] -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [T a] -> [T a] -> [T a]
forall a. C a => [a] -> [a] -> [a]
PSCore.compose ([T a] -> [T a] -> [T a])
-> ([a] -> [T a]) -> [a] -> [T a] -> [T a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> T a) -> [a] -> [T a]
forall a b. (a -> b) -> [a] -> [b]
map a -> T a
forall a. a -> T a
PS.const