Charlie Lindgren, Doktorand i Mikrodata Analys
24 april 2017
Yacas är ett datoriserat algebra system (fritt översatt) och står för Yet Another Computer Algebra System. Ett sådant system kan manipulera symboliska uttryck och hitta gränsvärden, lösa ekvationer, derivera och integrera med mera.
Av denna orsak lämpar det sig väl för det som del 2 av kursen innehåller! R är som sagt ett statistiskt paket, men det finns även funktioner för derivator och integraler med mera. Dock kommer jag att i första hand förlita mig på Ryacas paketet där tillfälle ges då det är mer lättförståeligt och enhetligt.
Ryacas är ett R paket som för över funktionaliteten från Yacas till R (för den skarpsynte: Ryacas <-> R Yacas). Alltså kan man lösa ekvationer genom att skriva koden i R istället!
https://code.google.com/archive/p/ryacas/
Det finns även tillgängligt ett paket kallat rSymPy som överför liknande funktioner från Python programmeringsspråket. Men återigen så använder vi nu Ryacas istället.
Ni installerar Ryacas, öppnar paketet och hjälpfilen med följande kod.
install.packages("Ryacas")
library(Ryacas)
?`Ryacas-package`
De tidigare hemsidorna är väldigt hjälpsamma med den kod som krävs för att programmera. Men i kursen som ni går nu så skall vi begränsa funktionaliteten till de ändamål ni har och ni kommer därmed endast få ta del av grundläggande kod för att kunna använda Yacas till det viktigaste för er: Gränsvärden, Derivator och Integraler.
När ni börjar använda Ryacas så kan ni kalla funktionen yacas
yacas()
Inuti parantesen lägger ni sedan in den kod som behövs för att lösa ekvationer, derivera eller vad ni nu vill göra. Man kan även skriva koden som skall läggas in omgivet av funktionen expression för att ange att det är ett matematiskt uttryck man vill titta på
expression()
Alltså
yacas( expression( ) )
Ett ''problem'' för en nybörjare som skall lära sig använda Yacas är att koden kan se ut på många olika sätt men producera samma svar. Exempelvis ger
yacas(expression(Integrate(1/x, x)))
yacas("Integrate(x)1/x")
x <- Sym("x")
Integrate(1/x, x)
Alla samma svar
expression(log(x))
Jag har bestämt att två av sätten att skriva koden blir enklast för er att förstå. Ta tillexempel nedan formel som jag vill utveckla till ett polynom. Notera återigen att ni inte behöver öppna paketet varje gång utan det är bara del av min presentation. Det första sättet är
library(Ryacas)
yacas("Expand((x+1)^2)")
expression(x^2 + 2 * x + 1)
Nu har R, och närmare bestämt Yacas, utvecklat polynomet åt mig. Här användes situationstecken.
Det andra sättet är att helt och hållet gå in ett ett “yacas-läge” där man alltså kan skriva fritt utan att skriva yacas framför varje kommando.
library(Ryacas)
yacmode()
Sedan när ni är färdiga med att skriva kod kan ni gå ur detta läge med: stop, end, quit, exit eller e.
Slutligen så kan ni få en lite annorlunda och ibland tydligare utskrift med funktionen PrettyForm. Ni behöver inte ta hänsyn till koden under ekvationen.
library(Ryacas)
yacas("PrettyForm(Expand((x+1)^2))")
2
x + 2 * x + 1
<OMOBJ>
<OMS cd="logic1" name="true"/>
</OMOBJ>
Det samma gäller för funktionen EvalFormula
library(Ryacas)
yacas("EvalFormula(Expand((x+1)^2))")
/ 2 \ 2
Expand\ ( x + 1 ) / = x + 2 * x + 1
<OMOBJ>
<OMS cd="logic1" name="true"/>
</OMOBJ>
Vi kan hitta gränsvärden till funktioner genom att använda funktionen Limit. Vi skall börja med att titta på ett exempel med funktionen \( y = \frac{1}{x} \), eller som vi skulle kunna representera denna i R med
library(Ryacas)
yacas("1/x")
expression(1/x)
Vi plottar denna funktion.
curve(1/x)
Vad skulle möjliga gränsvärden för denna funktion vara? Kan ni säga det säkert från figuren?
Med vårt paket Ryacas så kan vi undersöka gränsvärdena när x går mot 0 samt när x går mot oändligheten åt höger och åt vänster. Som sagt så kan vi skriva detta på olika sätt, men jag väljer att skapa symbolen x för detta ändamål. Sedan använder jag funktionen Limit för att hitta gränsvärden.
library(Ryacas)
yacas("Limit(x, 0) 1/x")
expression(NaN)
yacas("Limit(x, Infinity) 1/x")
expression(0)
yacas("Limit(x, -Infinity) 1/x")
expression(0)
Tycker ni att detta stämmer överens med figuren?
Om gränsvärdet mot minus oändligheten och mot noll skiljer sig åt måste det betyda att x inte slutar vid noll i detta fall. Figuren antydde att när x går mot noll, så går y mot oändligheten, men det är inte heller fallet. Varför stämmer inget av detta?
Om vi istället låter x-axeln utökas så ser vi genast vad problemet är.
curve(1/x, xlim = c(-1, 1))
abline(v=0,h=0,lty="dashed")
När x går mot oändligheten (positiva värden) så går y mot noll som vi fick ut tidigare, och när x går mot minus oändligheten så går också y mot noll.
Men däremot när x går mot noll, så kommer resultatet bli motsägelsefullt!
Men vi ser ju att naturligtvis så verkar det finnas gränsvärden vid 0, men att dessa går åt olika håll. Vad gör vi åt detta då för att kunna beskriva detta matematiskt?
Vi kan ta gränsvärden då x går mot noll från höger och från vänster, på så sätt får vi ut de rätta gränsvärdena som då råkar vara motsägelsefulla.
yacas("Limit(x, 0,Left) 1/x")
expression(-Inf)
yacas("Limit(x, 0,Right) 1/x")
expression(Inf)
I förgående exempel så existerar gränsvärdet 0 därför de två olika gränsvärdena är motsägelsefulla. I exemplet nedan utökar jag x för att visa funktionen till höger.
\[ y = \frac{x^2 + 4x - 12}{x^2 - 2x} \]
Enligt koden
curve((x^2 + 4*x - 12)/(x^2 - 2*x),xlim=c(-5,5),ylab = expression((x^2 + 4*x - 12)/(x^2 - 2*x)))
abline(v=0,h=0,lty="dashed")
Är det fel på figuren till höger, den verkar brytas vid 2?
Vi zoomar in vid 2 för att titta närmare på funktionen och mycket riktigt bryts den vid 2, lägger vi in 2 i ekvationen så får vi \( \frac{0}{0} \) som är odefinierat, betyder det att gränsvärdet inte existerar?
Vi tar gränsvärdet för x som går mot 2
library(Ryacas)
yacas("Limit(x,2) (x^2 + 4*x - 12)/(x^2 - 2*x)")
expression(4)
Gränsvärdet existerar och är lika med 4, uppenbarligen så kan vi även se i figuren att detta borde vara fallet. Dessutom så behövde vi inte ta gränsvärden från höger eller vänster då gränsvärdet existerade.
Vi kan se detta genom att förenkla ekvationen. Vi kan faktorisera polynomen, både uppe och nere, använder ni funktionen PrettyForm så syns det enklast för er. Det övre och undre polynomen kan faktoriseras som
library(Ryacas)
yacas("Factors(x^2 + 4*x - 12)")
expression(list(list(x + 6, 1), list(x - 2, 1)))
library(Ryacas)
yacas("Factors(x^2 - 2*x)")
expression(list(list(x - 2, 1), list(x, 1)))
För att tyda koden som kommer ut i förgående slide betyder den att det övre polynomet kan skrivas som
\[ ( x - 2 ) * ( x + 6 ) \]
medan det undre polynomet kan skrivas som
\[ ( x - 2 ) * ( x ) \]
På så sätt ser vi att ekvationen som blir kvar är
\[ \frac{(x + 6)}{x} \]
Stoppar vi in 2 i denna ekvation så får vi
\[ \frac{(x + 6)}{x} = \{ x = 2 \} = \frac{8}{2} = 4 \]
vilket alltså ger oss exakta gränsvärdet även fast ekvationen innan vi skrev om den gav oss \( \frac{0}{0} \) som var obestämt. För att plotta funktionen korrekt krävs alltså att man lägger till gränsvärdet.
Derivatans definition kommer av ett gränsvärde
\[ f'(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} \]
deriveringsregler tar över efter att man har lärt sig hantera denna ekvation och dess funktion.
Vi kan ta ett exempel \( f(x) = 2x^2 - 16x +35 \)
\[ f'(x) = \lim_{h \to 0} \frac{2(x+h)^2 - 16(x+h) + 35 - (2x^2 - 16x + 35)}{h} \]
\[ f'(x) = \lim_{h \to 0} \frac{2x^2 + 4xh + 2h^2 - 16x-16h + 35 - 2x^2 + 16x - 35}{h} \]
\[ f'(x) = \lim_{h \to 0} \frac{4xh + 2h^2 -16h}{h} \]
\[ f'(x) = \lim_{h \to 0} \frac{h(4x + 2h -16)}{h} \]
\[ f'(x) = \lim_{h \to 0} 4x + 2h -16 \]
\[ f'(x) = 4x - 16 \]
Men det där var ju inte lite jobbigt… Vi kan låta datorn göra jobbet i R. Vi tar helt enkelt gränsvärdet!
library(Ryacas)
yacas("Limit(h,0) (2*(x+h)^2 - 16*(x+h) + 35 - (2*x^2 - 16*x + 35))/h")
expression(4 * x - 16)
så får vi genast ut gränsvärdet vi sökte, och därmed också derivatan.
Men vi vill kunna derivera utan att behöva ange derivatans definition. Då kan vi istället använda en funktion i R för att derivera genast.
library(Ryacas)
yacas("Deriv(x) 2*x^2 - 16*x + 35")
expression(4 * x - 16)
Så fick vi genast ut derivatan. Självklart måste ni kunna ta derivatan själva utifrån de regler som finns tillgängliga.
Vi kan visa derivatan med ett exempel i R genom att rita kurvor. Ta tillexempel funktionen \( y = x^2 \), vi deriverar denna i R med
library(Ryacas)
yacas("Deriv(x) x^2")
expression(2 * x)
Vi kan samtidigt plotta denna funktion tillsammans med en tagent till kurvan med hjälp av derivatan.
Hur fick vi ut figuren på förgående sida? Om funktionen vi tittade på var \( y = f(x) = x^2 \) och derivatan var \( y' = f'(x) = 2x \) så kan vi använda en punkts formeln. Lutningen på kurvan \( k \) är alltså lika med derivatan i det här fallet och \( x_1 \) och \( y_1 \) är den punkt vi till titta på.
\[ (y - y_1) = k(x - x_1) \]
\[ (y - y_1) = y'(x-y_1) \]
\[ (y - y_1) = f'( x_1 ) (x-x_1) \]
\[ y = 2 x_1 x - 2 x_1 x_1 + y_1 \]
Lägger vi in \( x_1 = \frac{1}{2} \) och \( y_1 = x_1^2 = (\frac{1}{2})^2 = \frac{1}{4} \) så får vi
\[ y = 2 * \frac{1}{2} * x - 2 * \frac{1}{2} * \frac{1}{2} + \frac{1}{4} = x - \frac{1}{4} \]
Så för att få fram den graf jag fick fram förut använde jag koden
curve(x^2,xlim=c(-1,1),ylim=c(-1,1))
curve(x - 1/4,col="red",add=TRUE)
abline(v=0,h=0,lty="dashed")
Vi kan även enkelt integrera funktioner i R.
library(Ryacas)
yacas("Integrate(x) x^2")
expression(x^3/3)
Och deriverar vi integralen så ser vi att integralen är den primitiva funktionen till \( f(x) = x^2 \).
library(Ryacas)
yacas("Deriv(x) x^3/3")
expression(x^2)
Vill vi integrera mellan två värden kan vi också skriva in det enkelt.
yacas("Integrate(x,1,2) x^2")
Alltså får vi ut arean mellan kurvan och x-axeln när vi använder integralen ovan.
Vill vi istället beräkna integralen mellan två kurvor kan vi även göra det. Ta tillexempel \( y = x^{\frac{1}{2}} \) och \( y = \frac{x}{2} \) mellan värdena 0 och 4.
curve(x^(1/2),xlim=c(0,6))
curve(x/2,add=TRUE)
Vi kan få ut arean mellan dessa kurvor genom att ta integralen av mellanskillnaden i R. Formeln som vi löser är
\[ \int_{0}^{4} \bigg( x^{\frac{1}{2}} - \frac{x}{2} \bigg) dx \]
och i R
library(Ryacas)
yacas("Integrate(x,0,4) x^(1/2) - x/2")
expression(4/3)
Dessa areor räknas ut ovanför x-axeln, vilket är viktigt att komma ihåg. Tar vi däremot funktionen \( y = x^2 - 4 \)
curve(x^2-4,xlim=c(-4,4),ylim=c(-4,4))
abline(v=0,h=0,lty="dashed")
och vill få ut arean mellan \( x = -2 \) och \( x = 2 \), så kommer resultatet bli
library(Ryacas)
yacas("Integrate(x,-2,2) x^2 - 4")
expression(-32/3)
vilket är negativt. Detta gäller alltså för areor under kurvan.
Ta tillexempel de sammanlagda areorna för
curve(x^3 - 4*x, xlim = c(-3,3))
abline(v=0,h=0,lty="dashed")
Beräknar ni integralen
\[ \int_{-2}^{2} \bigg( x^3 - 4*x \bigg) dx \]
så får ni svaret till noll
library(Ryacas)
yacas("Integrate(x,-2,2) x^3 - 4*x")
expression(0)
Tar ni däremot det uppdelat som två integraler där ni VET att den ena är under x-axeln och sätter ett minustecken
\[ \int_{-2}^{0} \bigg( x^3 - 4*x \bigg) dx - \int_{0}^{2} \bigg( x^3 - 4*x \bigg) dx \]
så får ni fram den totala arean mellan x-axeln och kurvan över detta intervall
library(Ryacas)
yacas("(Integrate(x,-2,0) x^3 - 4*x) - (Integrate(x,0,2) x^3 - 4*x)")
expression(8)
Ett annat alternativ till att lösa samma problem är att vända på intervallgränserna istället för att sätta ett minustecken framför integralen.
\[ \int_{-2}^{0} \bigg( x^3 - 4*x \bigg) dx + \int_{2}^{0} \bigg( x^3 - 4*x \bigg) dx \]
så får ni också fram den totala arean mellan x-axeln och kurvan över detta intervall
library(Ryacas)
yacas("(Integrate(x,-2,0) x^3 - 4*x) - (Integrate(x,0,2) x^3 - 4*x)")
expression(8)
Slutligen, beräkna areorna mellan dessa två kurvor över intervallet -2 till 2
\[ y = x^3 - 4*x \]
\[ y = x^3 - 2*x \]