-- | Chebysev polynomials
-- 
-- See <https://en.wikipedia.org/wiki/Chebyshev_polynomials>

{-# LANGUAGE DataKinds, TypeSynonymInstances, FlexibleContexts, FlexibleInstances, BangPatterns, ScopedTypeVariables #-}
module Math.Algebra.Polynomial.Univariate.Chebysev
  ( chebysevT
  , chebysevU
  , integralChebysevT 
  , integralChebysevU
  ) 
  where

--------------------------------------------------------------------------------

import Data.List
import Data.Ratio

import Data.Semigroup
import Data.Monoid

import GHC.TypeLits

import qualified Math.Algebra.Polynomial.FreeModule as ZMod
import Math.Algebra.Polynomial.FreeModule ( FreeMod , FreeModule(..) , ZMod , QMod )

import Math.Algebra.Polynomial.Univariate

import Math.Algebra.Polynomial.Class
import Math.Algebra.Polynomial.Pretty
import Math.Algebra.Polynomial.Misc

--------------------------------------------------------------------------------

chebysevT :: (Ring c, KnownSymbol v) => Int -> Univariate c v
chebysevT :: Int -> Univariate c v
chebysevT = Univariate Integer v -> Univariate c v
forall c (v :: Symbol).
(Ring c, KnownSymbol v) =>
Univariate Integer v -> Univariate c v
fromZUni (Univariate Integer v -> Univariate c v)
-> (Int -> Univariate Integer v) -> Int -> Univariate c v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Univariate Integer "x" -> Univariate Integer v
forall c (var1 :: Symbol) (var2 :: Symbol).
Univariate c var1 -> Univariate c var2
renameUniVar (Univariate Integer "x" -> Univariate Integer v)
-> (Int -> Univariate Integer "x") -> Int -> Univariate Integer v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Univariate Integer "x"
integralChebysevT

chebysevU :: (Ring c, KnownSymbol v) => Int -> Univariate c v
chebysevU :: Int -> Univariate c v
chebysevU = Univariate Integer v -> Univariate c v
forall c (v :: Symbol).
(Ring c, KnownSymbol v) =>
Univariate Integer v -> Univariate c v
fromZUni (Univariate Integer v -> Univariate c v)
-> (Int -> Univariate Integer v) -> Int -> Univariate c v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Univariate Integer "x" -> Univariate Integer v
forall c (var1 :: Symbol) (var2 :: Symbol).
Univariate c var1 -> Univariate c var2
renameUniVar (Univariate Integer "x" -> Univariate Integer v)
-> (Int -> Univariate Integer "x") -> Int -> Univariate Integer v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Univariate Integer "x"
integralChebysevU

--------------------------------------------------------------------------------

x, twox :: Univariate Integer "x"
x :: Univariate Integer "x"
x    = VarP (Univariate Integer "x") -> Univariate Integer "x"
forall p. AlmostPolynomial p => VarP p -> p
variableP ()
twox :: Univariate Integer "x"
twox = MonomP (Univariate Integer "x")
-> CoeffP (Univariate Integer "x") -> Univariate Integer "x"
forall p. AlmostPolynomial p => MonomP p -> CoeffP p -> p
monomP'   (Int -> U "x"
forall (var :: Symbol). Int -> U var
U Int
1) CoeffP (Univariate Integer "x")
2

integralChebysevT :: Int -> Univariate Integer "x"
integralChebysevT :: Int -> Univariate Integer "x"
integralChebysevT = ((Int -> Univariate Integer "x") -> Int -> Univariate Integer "x")
-> Int -> Univariate Integer "x"
forall a. ((Int -> a) -> Int -> a) -> Int -> a
intCache (Int -> Univariate Integer "x") -> Int -> Univariate Integer "x"
forall a.
(Eq a, Num a) =>
(a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute where
  compute :: (a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute a -> Univariate Integer "x"
recur a
n = case a
n of 
    a
0 -> Univariate Integer "x"
1
    a
1 -> Univariate Integer "x"
x
    a
n -> Univariate Integer "x"
twox Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
* a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
- a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
2)

integralChebysevU :: Int -> Univariate Integer "x"
integralChebysevU :: Int -> Univariate Integer "x"
integralChebysevU = ((Int -> Univariate Integer "x") -> Int -> Univariate Integer "x")
-> Int -> Univariate Integer "x"
forall a. ((Int -> a) -> Int -> a) -> Int -> a
intCache (Int -> Univariate Integer "x") -> Int -> Univariate Integer "x"
forall a.
(Eq a, Num a) =>
(a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute where
  compute :: (a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute a -> Univariate Integer "x"
recur a
n = case a
n of 
    a
0 -> Univariate Integer "x"
1
    a
1 -> Univariate Integer "x"
twox
    a
n -> Univariate Integer "x"
twox Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
* a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
- a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
2)

--------------------------------------------------------------------------------