De polynoom-functies
Contents
De polynoom-functies#
Om een polynoom te kunnen tekenen hebben we een lijst met polynoom-functiepunten nodig, bijvoorbeeld 200 punten in het interval -100..100. Elk punt bestaat uit een tupel \((x, f(x))\), waar \(x\) de x-waarde is en \(f(x)\) de bijbehorende waarde van de polynoom-functie. Deze lijst met functiepunten is de basis voor het tekenen van de grafiek met behulp van SVG.
We splitsen dit probleem in twee stappen (functies):
een functie
poly coefs xvoor het uitrekenen van een polynoom met coeëfficientencoefsin puntx.een functie
funcpoints f steps from to, die gegeven een functief, aantal stappensteps, en begin- en eindwaardenfromento, een lijst \((x, f x)\)-tupels oplevert:[(from, f from), ..., (to, f to)].
Opmerking Deze functies zijn niet specifiek voor dit probleem: je kunt de polynoom-functie overal gebruiken waar je polynomen nodig hebt; en de tweede functie voor het tekenen van allerlei functies, niet alleen polynomen. Het is een kunst om deelproblemen zo te formuleren dat je de oplossingen ook op andere plaatsen kunt gebruiken.
Hieronder werk je de functie poly uit. In een ander notebook werk je funcpoints uit.
Import en hulpfuncties
import List exposing (length, map, range)
expect : a -> a -> String
expect tst res =
if tst == res then "OK" else "Fail"
<function> : a -> a -> String
De functie pow#
Je gaat een recursieve functie pow maken, van type Float -> Int -> Float. De aanroep van deze functie pow x n heeft als resultaat \(x^n\). Je gebruikt deze functie later om polynomen van de vorm \(ax^2 + bx + c\) uit te rekenen. Daarom hoeft deze functie alleen voor gehele \(n \geq 0\) een resultaat op te leveren.
Vraag Welk resultaat verwacht je voor pow 2 3? Voor pow 3 2? Voor pow 0 3? En pow 3 0?
Gebruik voor de definitie van pow x n het volgende schema:
Fig. 1 Schema voor pow x n#
Opdracht. Werk hieronder de functie pow uit. Verderop staan enkele testen van deze functie. Controleer of je functie daaraan voldoet.
pow : Float -> Int -> Float
pow x m = 0 -- vervang door je eigen definitie
<function> : Float -> Int -> Float
Hieronder staat een aantal testen voor de pow functie. Voor het testen gebruiken we de functie expect die als de twee argumenten gelijk zijn, OK oplevert, anders Fail.
"Fail" : String
expect (pow 2 0) 1
"Fail" : String
expect (pow -1 2) 1
"Fail" : String
De functie poly#
Je gaat een (recursieve) functie poly maken die gegeven een lijst van polynoom-coëfficienten het polynoom in een punt uitrekent. Maak hierbij gebruik van de functie pow die je hierboven gedefinieerd hebt.
Hint de lengte van de lijst met coëfficienten bepaalt de macht (exponent) die je voor het eerste getal uit de lijst nodig hebt. Voorbeeld: voor het polynoom \(3x^2 + 4\) is de lijst met coëfficienten: \([3, 0, 4]\). De lengte van deze lijst is 3. Dit betekent dat je \(3\) moet vermenigvuldigen met \(x^2\), ofwel pow x 2.
Voor deze functie poly gebruik je het volgende schema:
als
coefs = []: 0als
coefs = c :: cs:c * (pow x exp) + poly cswaarin
exp = length cs
Opmerking:
voor het gevalsonderscheid op een lijst gebruik je bij voorkeur de
case-constructie.
Opdracht. Werk de functie poly hieronder uit. Controleer de werking met de gegeven testen
poly : List Float -> Float -> Float
poly coefs x = 0 -- vervang door je eigen definitie
<function> : List Float -> Float -> Float
poly [1,1,1] 3
0 : Float
expect (poly [1,1,1] 2) 7
"Fail" : String
expect (poly [1,0,-2] 3) 7
"Fail" : String
expect (poly [1,2,3,4] 3) 58
"Fail" : String
Gebruik van poly met 1 parameter#
De functie poly is van het type: List Float -> Float -> Float. Je leest dit als: List Float -> (Float -> Float). Met andere woorden: als je poly alleen de lijst met coëfficienten meegeeft, dan levert deze als resultaat een “gewone” functie Float -> Float op.
Kijk maar:
poly111 = poly [1,1,1]
<function> : Float -> Float
Deze functie kun je vervolgens een waarde voor “x” aanbieden:
poly111 2
0 : Float
Je kunt deze functie ook op een rij getallen loslaten:
numbers = map toFloat (range 0 10)
[0,1,2,3,4,5,6,7,8,9,10]
: List Float
map poly111 numbers
[0,0,0,0,0,0,0,0,0,0,0]
: List Float
Dit kun je later gebruiken bij het uitrekenen van poly coefs voor een reeks x-waarden, om deze polynoom te tekenen.
Notitie
Het principe om een functie met meerdere paramaters te zien als een functie met 1 parameter die een functie oplevert met een parameter minder, heet ook wel Currying, naar de wiskundige Haskell Curry.
Hieronder nog wat voorbeelden:
(+)
<function> : number -> number -> number
succ = (+) 1
<function> : number -> number
succ 3
4 : number
poly111map = map poly111
<function> : List Float -> List Float
poly111map numbers
[0,0,0,0,0,0,0,0,0,0,0]
: List Float