5 - sympy

Sympy er en veldig nyttig pakke innenfor samfunnsøkonomi. Med den kan vi regne analytisk, det vil si med symboler. I samfunnsøkonomi bruker vi mye matematikk som denne pakken kan hjelpe oss med. Vi starter med et eksempel på utregning av profittmaksimum:

Eksempel med optimal mengde arbeidskraft

Anta at du er bedriftsleder, og lurer på hvor mange medarbeidere du skal ansette. For en gitt mengde arbeidskraft produseres

Eksempel 1:

def f(L,a):
    return 60*L**a

a definerer produktiviteten til de ansatte. Desto høyere a er, desto mer produktive er de ansatte. Vi kan plotte denne funksjonen:

Eksempel 2:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,5,100)

plt.plot(x,f(x,0.5))
plt.xlabel('Arbeidskraft')
plt.ylabel('Produksjon')
Text(0, 0.5, 'Produksjon')

Som vi ser er produktiviteten avtakende, kurven stiger mindre utover i diagrammet. Det er fordi a er mindre enn én. (Forsøk med andre tall for a!)

Når produktfunksjonen er definert, kan vi definere fortjenesten til bedriften, eller “profittfunksjonen” som vi gjerne kaller det i samfunnsøkonomi. La oss si at bedriften betaler hver arbeider w tusen kroner, og at faste kostnader er K.

Fortenesten er pris ganger solgt mengde, p*f(L,a) og kostnadene er lønnskostnader w*L og faste utgifter K. Profittfunksjonen blir da

Eksempel 3:

def profit(L,a,w,p,K):
    return p*f(L,a)-w*L-K

La oss se på den grafisk. Dersom prisen per enhet er hundre kroner, lønna er 2 500 per dag og bedriften har 300 000 i faste utgifter per dag, så ser profittfunksjonen slik ut:

Eksempel 4:

import matplotlib.pyplot as plt
import numpy as np


import matplotlib.pyplot as plt
import numpy as np

#creating the plot
x = np.linspace(0,5000,100)
fig,ax=plt.subplots()
ax.set_ylabel('kroner')
ax.set_xlabel('Antall ansatte')


#plotting the function
plt.plot(x,profit(x,0.9,2500,100,300000),label='Fortjeneste')
ax.legend(loc='lower right',frameon=False)
<matplotlib.legend.Legend at 0x12a65fd3a10>

Vi bruker metoden med fig,ax=plt.subplots(), siden vi skal bygge på denne grafen.

Vi skal nå begynne å bruke sympy. Det første vi må gjøre er å definere hvilke symboler som skal behandles analytisk (altså som symboler og ikke flyttall). Det gjør vi slik:

Eksempel 5:

import sympy as sp
L,a,w,p,K=sp.symbols("L a w p K")

Med symbolene definert, vil nå vår profittfunksjon vises analytisk når vi bruker de definere symbolene:

Eksempel 6:

profit(L,a,w,p,K)

\(\displaystyle - K - L w + 60 L^{a} p\)

Vi ønsker å finne ut for hvilken arbeidskraft fortjenesten er størst. Det er det høyeste punktet i figuren fra Eksempel 3. På dette punktet har profittfunksjonen ingen stigning, slik at den deriverte er null. For å finne dette punktet må vi først finne den deriverte. Det gjør vi i sympy med funksjonen diff(). Den tar to argumenter. Det første er funksjonen, det andre er den variabel vi ønsker å derivere med hensyn til.

Som vi ser av figuren i Eksempel 3, så har vi arbeidskraft L langs x-aksen, så det er denne variabelen vi ønsker å derivere med hensyn til. Den deriverte av profitt() med hensyn til L er dermed:

Eksempel 7:

d_profitt=sp.diff(profit(L,a,w,p,K),L)
d_profitt

\(\displaystyle - w + \frac{60 L^{a} a p}{L}\)

For å finne punktet der denne deriverte er null, setter vi opp en ligning der den deriverte er null, og løser for den L som tilfredstiller ligningen. En slik ligning kalles “førsteordensbetingelse”, eller “first order condition” på engelsk. Vi forkorter den derfor til “foc”:

Eksempel 8:

foc=sp.Eq(d_profitt,0)
foc

\(\displaystyle - w + \frac{60 L^{a} a p}{L} = 0\)

Vi kan nå løse førsteordensbetingelsen med funksjonen solve, som ligger i modulen solversi sympy:

Eksempel 9:

from sympy.solvers import solve
L_max=solve(foc,L)[0]
L_max

\(\displaystyle \left(\frac{60 a p}{w}\right)^{- \frac{1}{a - 1}}\)

Legg merke til at resultatet ligger i en liste med lengde 1, så vi må hente ut element 0 i listen for å vise resultatet. Vi kan finne hva den analytiske verdien er i maksimum ved å sette L_maxinn i profittfunksjonen:

Eksempel 10:

profit_max=profit(L_max,a,w,p,K)
profit_max

\(\displaystyle - K + 60 p \left(\left(\frac{60 a p}{w}\right)^{- \frac{1}{a - 1}}\right)^{a} - w \left(\frac{60 a p}{w}\right)^{- \frac{1}{a - 1}}\)

Vi kan nå beregne de nummeriske verdiene ved å sette inn noen passende tall for de ukjente symbolene. Vi prøver med 0.5 for produktivitet a, 0.3 for lønn w, 1 for pris p og 1 for kapital K. Vi forteller sympy om at vi ønsker å bruke dise verdiene ved å lage et oppslag der hvert av symbolene er nøkkel til hver av de nummeriske verdiene:

Eksempel 11:

num_dict={a:0.9,w:2500,p:100,K:300000}
num_dict
{a: 0.9, w: 2500, p: 100, K: 300000}

Vi kan nå finne nummerisk hvor mye arbeidskraft som trengs for å oppnå maksimal fortjeneste:

Eksempel 12:

L_max.subs(num_dict)

\(\displaystyle 2210.73919720734\)

Om vi nå legger dette tallet inn for symbol L, kan vi finne hvor stor fortjenesten er i dette punktet. Vi starter med å legge inn verdien for L som gir maksimal fortjeneste:

Eksempel 13:

num_dict[L]=L_max.subs(num_dict)
num_dict
{a: 0.9, w: 2500, p: 100, K: 300000, L: 2210.73919720734}

Med det oppdaterte oppslaget blir fortjenesten

Eksempel 14:

profit_max_num=float(profit(L,a,w,p,K).subs(num_dict))
profit_max_num
314094.22144648153

Med modulene displayog Markdownfra IPython (pakken som driver Jupyter), kan vi sette dette in i en pen tabell:

Eksempel 15:

from IPython.display import Markdown

tbl=f"""
|                                 | Desimalverdi                             |  Analytisk verdi              | 
| :-------------------------------| :----------------------------------------| :-----------------------------| 
| Optimal mengde arbeidskraft:     | ${np.round(float(num_dict[L]),1)}$         |${sp.latex(L_max)}$            | 
| Maksimal profitt                | ${np.round(float(profit_max_num),1)}$    |${sp.latex(profit_max)}$       | 

"""
display(Markdown(tbl))
Desimalverdi Analytisk verdi
Optimal mengde arbeidskraft: \(2210.7\) \(\left(\frac{60 a p}{w}\right)^{- \frac{1}{a - 1}}\)
Maksimal profitt \(314094.2\) \(- K + 60 p \left(\left(\frac{60 a p}{w}\right)^{- \frac{1}{a - 1}}\right)^{a} - w \left(\frac{60 a p}{w}\right)^{- \frac{1}{a - 1}}\)

La oss nå plotte løstningen. Vi plotter her følgende, i rekkefølge: 1. Den opprinnelige profittfunksjonen 2. Den horisontale tangenten som tangerer i maksimumspunktet 3. En vertikal linje som viser mengden arbeidskraft i optimum.

Legg merke til at vi legger inn verdiene vi har definert i num_dict inn i profittfunksjonen. Generelt er det en god idé i programmering å “hardkode” tall minst mulig. Definer det heller tallet som en variabel eller element i en dictog referer til det senere.

Eksempel 16:


#Plotting the tangent
ax.plot(x,
        profit_max_num*np.ones(len(x)),
        label='tangent')

#Plotting the vertical line
ax.vlines(float(L_max.subs(num_dict)), #x-value
          -300000,                     #min y-value
          profit_max_num*1.1,          #max y-value
    #formatting:
          colors=['black'],
          linestyles='dashed',
          label='optimum')

ax.legend(loc='lower right',frameon=False)
ax.axhline(0, color='black',lw=0.1)
fig

Eksempel med tilbud og etterspørsel

I forelesning 3 definerte vi disse tilbuds og etterspørselsfunksjonene:

Eksempel 17:

def supply(x):
    return (x**2)*(1/250)
    
def demand(x):
    return 3000/(100+x)

Og vi tegnet dem slik:

Eksempel 18:

#drawing 100 points in the interval 0.0 to 100
q = np.linspace(1,100,100)

#creating the plot
fig,ax=plt.subplots()
ax.set_ylabel('Pris')
ax.set_xlabel('Enheter')


#drawing supply
ax.plot(q,supply(q),label='Tilbud')

#drawing demand
ax.plot(q,demand(q),color='green',label='Etterspørsel')

#adding legend:
ax.legend(loc='upper center',frameon=False)
<matplotlib.legend.Legend at 0x12a66059f90>

Vi løste da likevekten grafisk, ved å se sånn cirka hvor tilbud er lik etterspørsel. Med sympy kan vi la python regne ut dette, og konsument og produsentoverskudd. Vi gjør dette ved å definere mengde x som en eksogen variabel, og sette opp ligningen vi trenger, altså at tilbud skal være lik etterspørsel:

Eksempel 19:

x=sp.symbols('x')
eq_cond=sp.Eq(demand(x),supply(x))
eq_cond

\(\displaystyle \frac{3000}{x + 100} = 0.004 x^{2}\)

Vi kan nå løse dette med solve fra sympy, som i forrige eksempel:

Eksempel 20:

x_eq=solve(eq_cond,x)
x_eq
[67.0125415064549,
 -83.5062707532274 - 64.9510401355397*I,
 -83.5062707532274 + 64.9510401355397*I]

Bare én av disse løsningene er gyldige. De to siste i listen x_eqer såkalte “imaginære tall”, det ser vi av I’en. Vi går ikke lenger inn på hva dette er her, men nøyer oss med å si at en likevekt ikke kan være et imaginært tall. Løsningen er altså x_eq[0]. Vi kan sette denne inn i enten tilbuds eller etterspørselfunksjonen for å få likevektsprisen

Eksempel 21:

p_eq=demand(x_eq[0])
print(f"""
Likevektspris er {p_eq}
Likevektskvantum er {x_eq[0]}
""")

Likevektspris er 17.9627228766173
Likevektskvantum er 67.0125415064549

Etterspørselskurven kan ses på som en rekke med konsumenter med ulik betalingsvilje i fallende rekkefølge. Alle konsumentene som betaler p_eq har dermed et overskudd som er lik differansen mellom p_eq og konsumentens punkt på etterspørselskurven. Summen av alle konsumentenes overskudd kalles konsumentoverskuddet. Dette kan illustreres ved å legge et skravert område til figuren over

Eksempel 22:

q = np.linspace(0,float(x_eq[0]),100)
ax.fill_between(q,            #x-values
                float(p_eq),  #Eqilibrium price
                demand(q),    #y-values
        #formatting:
                color = "pink",alpha = 0.3,label='Konsumentoverskudd')
ax.legend(loc='upper center',frameon=False)
fig

Akkrat som at vi kan regnet ut skjæringspunktet med sympy, så kan vi regne ut det skraverte konsumentoverskuddet. Vi bruker da det vi har lært i matematikkurset; arealet under en funksjon er integralet til funksjonen. Vi skal finne arealet under etterspørselsfunksjonen demand(x), men kun ned til prisen p_eq, så vi integrer differansen demand(x)-p_eq. Dette gjør vi for alle omsatte enheter, altså frem til omsatt kvantum x_eq[0].

Vi skal altså integrere demand(x)-p_eq i intervalet 0 til x_eq[0]. Det kan vi gjøre i sympy slik:

Eksempel 23:

consumer_surplus=sp.integrate(demand(x)-float(p_eq),(x,0,x_eq[0]))
consumer_surplus

\(\displaystyle 334.968455011534\)

På samme måte er produsentoverskuddet arealet over tilbuskurven, opp til prisen, altså det gule området i figuren under

Eksempel 24:

ax.fill_between(q,supply(q),float(p_eq), color = "yellow",alpha = 0.3,label='Produsentoverskudd')
ax.vlines(float(x_eq[0]), 0, 25,colors=['black'],linestyles='dashed', label='x_eq[0]')
ax.legend(loc='upper center',frameon=False)
fig

Vi kan regne ut dette område også, som altså er integralet av differansen mellom prisen og tilbudskruven, frem til x_eq[0].

Eksempel 25:

producer_surplus=sp.integrate(p_eq-supply(x),(x,0,x_eq[0]))
producer_surplus

\(\displaystyle 802.485141558844\)

Summen av produsentoverskuddet og konsumentoversdkuddet kalles “velferdsgevinsten”. Vi kan finne den ved å legge sammen konsument- og produsentoverskudd:

Eksempel 26:

producer_surplus+consumer_surplus

\(\displaystyle 1137.45359657038\)

Eller ved å ta integralet av differansen mellom etterspørsel og tilbud:

Eksempel 27:

welfare_surplus=sp.integrate(demand(x)-supply(x),(x,0,x_eq[0]))
welfare_surplus

\(\displaystyle 1137.45359657038\)

Vi kan nå lage en tabell som oppsumerer resultatene:

Eksempel 28:

tbl=f"""
|                     | Verdi                                    |
| :-------------------| :----------------------------------------|
| Solgt mengde:       | ${np.round(float(x_eq[0]),1)}$           |
| Pris:               | ${np.round(float(p_eq),1)}$              |
| Verdiskapning/<br>velferdsgevinst:      | ${np.round(float(welfare_surplus),1)}$  |
| Konsumentoverskudd: | ${np.round(float(consumer_surplus),1)}$ | 
| Produsentoverskudd: | ${np.round(float(producer_surplus),1)}$ | 

"""
display(Markdown(tbl))
Verdi
Solgt mengde: \(67.0\)
Pris: \(18.0\)
Verdiskapning/
velferdsgevinst:
\(1137.5\)
Konsumentoverskudd: \(335.0\)
Produsentoverskudd: \(802.5\)

Løse flere ligninger med flere ukjente

I eksempel 20 hadde vi én ligning med én ukjent. Det er imidlertid enkelt å løse flere ligninger med flere ukjente. Forskjellen er bare at når det er flere ligninger, så setter vi hver av disse inn i en liste. Som dere vet må det være akkurat like mange ukjente som ligninger, så vi må også sette akkurat like mange variabler inn i en annen liste. Disse to listene utgjør så argumentene i solve() funksjonen. La oss ta et eksempel. Vi begynner med å definere to lister med henholdsvis tre variabler og tre ligninger:

Eksempel 29:

import sympy as sp

x,y,z=sp.symbols("x y z")
symbols=[x,y,z]
equations=[
    sp.Eq(2*x+8*y+3*z,7),
    sp.Eq(-3*x+15*y-14*z,-20),
    sp.Eq(11*x-6*y+7*z,35)
]

Vi setter så disse to listene inn i solve() akkurat som om det var én ligning og én ukjent, og finner svaret:

Eksempel 30

solve(equations,symbols)
{x: 3868/1463, y: -6/77, z: 1139/1463}

Oppgaver/Arbeidskrav:

Her skal dere løse matematikkoppgaver med Sympy, og bruke fordelene som programmering gir til å løse oppgavene så effektivt som mulig. I stedet for å løse hver oppgave individuelt, skal dere derfor lage funksjoner som tar uttrykkene som argumenter, og så løse hver oppgave.

Likningssett - faktoriseringsmetoden (klikk her for å laste ned oppgavene)

Lag en funksjon test_solve(eqs) der eqs er et Sympy ligningssett, og der du bruker solve(f) til å finne løsning på likhetene. Lag en test i funksjonen, ved å sette løsningen inn i likheten. Funksjonen skal returnere både svaret og resultatet av løsningen.

from sympy.solvers import solve
import sympy as sp
x,y,z=sp.symbols("x y z")

def test_solve(eqs):
    s = solve(eqs)
    #testing equation for each element in eqs
    tests = [eq.subs(s[0]) for eq in eqs]
    print(s, tests)
    return s, tests

test_solve([
    sp.Eq(x*y**2-x,0), 
    sp.Eq(x+y**2,16)  ])

test_solve([
    sp.Eq(x**2+y**2,0), 
    sp.Eq(x**2*y-36*y,0)  ])

test_solve([
    sp.Eq(x*y**2-49*x,0), 
    sp.Eq(x**2+y**2,58)  ])

test_solve([
    sp.Eq(x**2+y**2,5/4), 
    sp.Eq(2*x*y+y,0)  ])
[{x: 0, y: -4}, {x: 0, y: 4}, {x: 15, y: -1}, {x: 15, y: 1}] [True, True]
[{x: -6, y: -6*I}, {x: -6, y: 6*I}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 6, y: -6*I}, {x: 6, y: 6*I}] [True, True]
[{x: -3, y: -7}, {x: -3, y: 7}, {x: 0, y: -sqrt(58)}, {x: 0, y: sqrt(58)}, {x: 3, y: -7}, {x: 3, y: 7}] [True, True]
[{x: -1.11803398874989, y: 0.0}, {x: -0.500000000000000, y: -1.00000000000000}, {x: -0.500000000000000, y: 1.00000000000000}, {x: 1.11803398874989, y: 0.0}] [False, True]
([{x: -1.11803398874989, y: 0.0},
  {x: -0.500000000000000, y: -1.00000000000000},
  {x: -0.500000000000000, y: 1.00000000000000},
  {x: 1.11803398874989, y: 0.0}],
 [False, True])

Grunnleggende derivasjonsregler (klikk her for å laste ned oppgavene)

Løs alle oppgavene med Sympy i én celle. Bruk diff()-funksjonen for å derivere, og gjør koden så kort som mulig (i antall tegn, ikke antall linjer).

for f in [x**5, 
          x+12,
          x**3+4*x**2, 
          2*x**3+36**0.5,
          x**0.5+5**2,
          x**3+x**-1, 
          x**3-x**2+x/4, 
          1/x+6*x**6, 
          -x+(x**3)/2,
          x*(x**2+2*x-3)
         ]:
    print(sp.diff(f))
5*x**4
1
3*x**2 + 8*x
6*x**2
0.5/x**0.5
3*x**2 - 1/x**2
3*x**2 - 2*x + 1/4
36*x**5 - 1/x**2
3*x**2/2 - 1
x**2 + x*(2*x + 2) + 2*x - 3

Produkt og brøkregelen (klikk her for å laste ned oppgavene)

1)

Forenkl uttrykkene i Oppgavene 1 a)-d) med færrest mulig tegn. Kommenter hvilke av oppgavene som lar seg forenkle.

for f in [x**(12/3), (x**2+4)**(8/2), sp.sqrt(x)*x**(3/2), ((x+2)**(1/2))**(4/2)]:
    print(sp.simplify(f))
x**4.0
(x**2 + 4)**4.0
x**2.0
(x + 2)**1.0

Kommentar: forenklingsfunksjonen i sympy gir oss egentlig ikke så mye her

2)

Lag to funksjoner f_deriv_prod(f, g) og f_deriv_frac(f, g) som bruker henholdsvis produktregelen og brøkregelen til å derivere et uttrykk. Argumenter skal være de to delene i produktet. Om produktet for eksempel er \(\sqrt{3x-1}\cdot(1+x)\) skal argumentene være \(\sqrt{3x-1}\) og \((1+x)\). Funksjonen skal returnere den deriverte av produktet.

Deriver alle utrykene i e)-m) med disse funksjonene, men velg først ut alle produktene og deriver de, før du i neste omgang deriverer brøkene.

def f_deriv_prod(f,g):
    df = sp.diff(f)
    dg = sp.diff(g)
    
    return df*g + f*dg

def f_deriv_frac(f,g):
    df = sp.diff(f)
    dg = sp.diff(g)
    
    return df/g - f*dg/g**2

#product rule
for f,g in [
        (x**4,         x**5), 
        (x,            sp.sqrt(x)), 
        (sp.sqrt(x),   x**6), 
        (x,            x*(x**2+1)), 

         ]:
    print(f"derivative: {f_deriv_prod(f,g)}\t\t\ttest: {sp.simplify(f_deriv_prod(f,g)-sp.diff(f*g))} " )
    
    
#fraction rule

for f,g in [
        (2,                 x**3), 
        (x**2 - 2,          x**3), 
        (x*2 + 4,           x**3 - 1), 
        (x**2,              x**2 + 2*x), 
        (x**2 + 4*x + 2,    x - 2), 
        ]:
    print(f"derivative: {f_deriv_frac(f,g)}\t\t\ttest: {sp.simplify(f_deriv_frac(f,g)-sp.diff(f/g))} " )
derivative: 9*x**8          test: 0 
derivative: 3*sqrt(x)/2         test: 0 
derivative: 13*x**(11/2)/2          test: 0 
derivative: x*(x**2 + 1) + x*(3*x**2 + 1)           test: 0 
derivative: -6/x**4         test: 0 
derivative: 2/x**2 - 3*(x**2 - 2)/x**4          test: 0 
derivative: -3*x**2*(2*x + 4)/(x**3 - 1)**2 + 2/(x**3 - 1)          test: 0 
derivative: -x**2*(2*x + 2)/(x**2 + 2*x)**2 + 2*x/(x**2 + 2*x)          test: 0 
derivative: (2*x + 4)/(x - 2) - (x**2 + 4*x + 2)/(x - 2)**2         test: 0 
3)

Test at produktregelen fungerer ved å printe differansen mellom funksjonene over og derivering av hele uttrykket med sp.diff(). Du kan sette dette inn i koden over om du vil.

Kjerneregelen (klikk her for å laste ned oppgavene)

1)

Lag en funksjon f_deriv_chain(f, g) som bruker kjerneregelen til å derivere et uttrykk av typen \(f(g(x))\).

Har du for eksempel et uttrykk \(\sqrt{3x-1}\), så er \(f(y)=\sqrt{y}\) og \(g(x)=\sqrt{3x-1}\). Funksjonen skal da returnere \(f'(g(x))\cdot g'(x)=\frac{1}{2}\frac{1}{\sqrt{3x-1}}\cdot 3\)

Husk å bytt ut \(y\) med \(g(x)\) (i dette tilfelle \(3x-1\)) før svaret returneres.

def f_deriv_chain(f, g):
    df = sp.diff(f)
    dg = sp.diff(g)
    
    return df.subs({'y':g})*dg
2)
  1. Bruk f_deriv_chain(f, g) på uttrykkene i Oppgave 1 a), b), d), e) og Oppgave 2 a) og e).

  2. Bruk f_deriv_prod(f, g) i kombinasjon med f_deriv_chain(f(y), g(x)) og løs Oppgave 1 h) og Oppgave 2 b)

Test samtidig resultatene med sp.diff()), der du stter inn kjernen i funksjonen før du deriverer.

for f, g in [
        (y**5,     x**3 + 6*x), 
        (sp.sqrt(y),   2*x**2 + 5), 
        (y**(3/2),     2*x**4 + 9), 
        (sp.sqrt(y**4),   3*x**2 + 2*x)
        ]:
    
    print(f"derivative: {f_deriv_chain(f,g)}\t\t\ttest: {sp.simplify(f_deriv_chain(f,g)-sp.diff( f.subs({'y':g}) ))} " )
derivative: 5*(3*x**2 + 6)*(x**3 + 6*x)**4          test: 0 
derivative: 2*x/sqrt(2*x**2 + 5)            test: 0 
derivative: 12.0*x**3*(2*x**4 + 9)**0.5         test: 0 
derivative: 2*(6*x + 2)*sqrt((3*x**2 + 2*x)**4)/(3*x**2 + 2*x)          test: 0 

Derivasjon av logaritme og eksponentialfunksjoner (klikk her for å laste ned oppgavene)

Løs følgende oppgaver: Oppgave 1 a), b), f) og Oppgave 2 a) og b). Lag koden med så få tegn som mulig-

for f in [
        sp.log(5*x), 
        sp.exp(-2*x),
        sp.exp(4*x**2 + 8*x), 
        x**3 * sp.exp(2*x), 
        sp.log((x**2-1)/(x**2 + 1))
        ]:
    print(sp.diff(f))
    
1/x
-2*exp(-2*x)
(8*x + 8)*exp(4*x**2 + 8*x)
2*x**3*exp(2*x) + 3*x**2*exp(2*x)
(x**2 + 1)*(-2*x*(x**2 - 1)/(x**2 + 1)**2 + 2*x/(x**2 + 1))/(x**2 - 1)
< Forrige | Neste >