In [1]:
import Graphics.Dynamic.Plot.R2
import Data.Default.Class
import Data.VectorSpace
import Math.Polynomial
import Math.Polynomial.Legendre

type ℝ = Double

In [2]:
sawtooth :: ℝ -> ℝ
sawtooth x = x - fromIntegral (round x)

In [3]:
l2 :: (ℝ->ℝ) -> (ℝ->ℝ) -> ℝ
l2 f g = (f (-1)*g (-1) / 2
+ sum [ f x*g x
| x <- take (n-1) [2/n-1, 4/n-1 ..] ]
+ f 1*g 1 / 2
) / n
where n :: Num n=>n
n = 256

In [4]:
[l2 (evalLegendre i) (evalLegendre i) * (2*fromIntegral i+1) | i<-[0..5]]

[1.0,1.000030517578125,1.0001525864936411,1.0004272254496698,1.0009153918434208,1.0016778812350209]
In [5]:
coeffs :: [ℝ]
coeffs = [l2 sawtooth (evalLegendre i) * (2*fromIntegral i+1) | i<-[0..] ]

In [6]:
approxSaw :: Poly ℝ
approxSaw = (/10) . fromIntegral . round . (*10)
<$> sumV [legendre i ^* c | (i,c) <- zip [0..20] coeffs ]  In [7]: plotPrerender def [ continFnPlot sawtooth, continFnPlot$ evalPoly approxSaw
, forceXRange (-1,1), forceYRange (-3/4,3/4) ]

In [8]:
plotPrerender def [ continFnPlot sawtooth, continFnPlot $evalPoly approxSaw , forceXRange (-0.7,1.3), forceYRange (-1,0.4) ]  In [9]: {-# LANGUAGE OverloadedStrings #-} import Text.LaTeX import Text.LaTeX.Packages.AMSMath mathDisplay (sum [ fromRational (fromInteger (round$ c*10)/10) * "x"**fromIntegral i
| (i,c) <- zip [0..] \$ polyCoeffs LE approxSaw
, abs c > 0.1 ]
:: LaTeX)

$0+2.20000{x}^{1}+-81.70000{x}^{3}+1576.60000{x}^{5}+-12865.00000{x}^{7}+53760.40000{x}^{9}+-128928.60000{x}^{11}+185521.70000{x}^{13}+-158630.00000{x}^{15}+74398.90000{x}^{17}+-14754.50000{x}^{19}$
In [ ]: