Aller au contenu

La suite aux deux limites

Note

Les deux exercices ci-dessous illustrent les différences de calcul avec des int ou avec des float. Ils constituent des exercices facultatifs d'entraînement.

Une suite u est définie par u(0)=\frac{3}{2}, u(1)=\frac{5}{3} et pour tout entier naturel n:

u(n+2) = 13- \frac{32}{u(n+1)} +\frac{20}{u(n)\times u(n+1)}

Exercice

  • Écrire un code possible pour le corps de la fonction suivante:
def u(n):
    """
    n -- entier naturel

    renvoie le flottant u(n) où u est définie dans l'énoncé.
    """
  • Quelles sont les valeurs obtenues pour u(100), u(1000), u(10000)...?
Un code possible
def u(n):
    """
    n -- entier naturel

    renvoie le flottant u(n) où u est définie dans l'énoncé.
    """
    a, b = 3/2, 5/3
    if n == 0 : return a
    for k in range(2, n+1) :
        a, b = b, 13- 32/b + 20/(a*b)
    return b
Conjecture sur la limite

Quelques essais:

>>> u(100)
10.0
>>> u(1000)
10.0
>>> u(10000)
10.0
>>> u(10**8)
10.0

Conjecture: la suite semble converger vers 10.

Exercice

Avec le module fractions

from fractions import Fraction
def u(n):
    """
    n -- entier naturel

    renvoie la fraction u(n) où u est définie dans l'énoncé.
    """
un code avec le module fractions
from fractions import Fraction

def u(n):
    """
    n -- entier naturel

    renvoie la fraction u(n) où u est définie dans l'énoncé.
    """
    a, b = Fraction('3/2'), Fraction('5/3')
    if n == 0 : return a
    for k in range(2, n+1) :
        a, b = b, Fraction('13')- Fraction(32, b) + Fraction(20, a*b)
    return b
  • Quelles sont les valeurs obtenues pour u(100), u(1000), u(10000)...?
Conjecture sur la limite

Le code

for n in (10, 100, 1000, 10000):
    print(f"Pour n = {n}, la valeur calculée de u(n) est {u(n)},\n soit approximativement {float(u(n))}.")

donne

Pour n = 10, la valeur calculée de u(n) est 2049/1025,
 soit approximativement 1.9990243902439024.
Pour n = 100, la valeur calculée de u(n) est 2535301200456458802993406410753/1267650600228229401496703205377,
 soit approximativement 2.0.
Pour n = 1000, la valeur calculée de u(n) est 21430172143725346418968500981200036211228096234110672148875007767407021022498722449863967576313917162551893458351062936503742905713846280871969155149397149607869135549648461970842149210124742283755908364306092949967163882534797535118331087892154125829142392955373084335320859663305248773674411336138753/10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069377,
 soit approximativement 2.0.
Pour n = 10000, la valeur calculée de u(n) est 39901262337615167697674843253671701676469936637723849097040178997058877660443893263839923368072389195798662258846418248543112982698827562235187571864192647915711460093587589053530493102532119791041100173836386623085017216921236209371018149732179249776180979789676018507883266515701243136618947805113824776130450193287748882093519743253970906445737076323388631551259281525673761521464457070183282952367912762917938927798821681921072535642129242854666788073051131299061206285360469938800671868633302918595546559331551212345164062815988396359214756491367524560074605770974503801668929162909301115859202829667843231469176278514190759538238555601653915471348888246124037515672651005456647578541420747605732786062856266482803248391343381148122839308684649277602497712294610414863984519223592500261985720483416681615211864640322536984576992511682625688123073477902974228512630222179491028406627640405863281915192929512020811691683132144089925734033030123841262008372844551817341801149212835713903822912110136502500812015039684523796118474236108889576145812790485096678443965414808946324753521693226067557412079606826394266987309245401126339874911016483561945621966582628807143755049537019714553875852866443198799753773321616737675676055286565550344547315145489568224588779467621723214846506583949626240395208356563931394951796329062516868271919725568260256370812566953298177381042095161765231647923971540244814088661166151738078639209206809946313166417344211826601807505646831079490788795430514910581020424621894643221506949651481550547972696596996681513875911293277243749138998558033144207402728866271634428623582796445967691694668880541928365702010145855496729101157269002201705975624778947857399081668692317614087918237971630291558354287239397456262918967566404162949964343716022778142456501811653634872441154951842835307431375451229809165809984922057260163071166616260203975351712468687077910818351246801689775052325287137297667038927440754586480188912493846508700801356054547675510752813453797272482074982821933437114101518196200493579760356543851906762564843908056605518816897910029353336779395993772483272626752787806746911602815273483755422110768451478998220372936439393163302970260988444739895429526138310936435365752400725554515447562730663222393622561585338963774402597287321537103279721069204595743115035894770492738893846175788531896434016102240644730992576338071478242736676787183512837467701021940543227830879181983196309308834672623313872062244499875939998453563464716046223725289150598271516350016399678472569230499762177920464488724347543236172714030936968117244659585707751246973112881073925244037927142057624723135025086676606540058195337301137114315011033455037798388259422675380299832362630343088015457301146379114901840660370609694227636630814648106638076924168072843527407823101279578001485707344392561806955949066640936737591737160475904437258240161485639102635896315248896597036923019409776054549443149376263189500819464230160996380911606833653899574282632126421372783023363548609585193418753/19950631168807583848837421626835850838234968318861924548520089498529438830221946631919961684036194597899331129423209124271556491349413781117593785932096323957855730046793794526765246551266059895520550086918193311542508608460618104685509074866089624888090489894838009253941633257850621568309473902556912388065225096643874441046759871626985453222868538161694315775629640762836880760732228535091641476183956381458969463899410840960536267821064621427333394036525565649530603142680234969400335934316651459297773279665775606172582031407994198179607378245683762280037302885487251900834464581454650557929601414833921615734588139257095379769119277800826957735674444123062018757836325502728323789270710373802866393031428133241401624195671690574061419654342324638801248856147305207431992259611796250130992860241708340807605932320161268492288496255841312844061536738951487114256315111089745514203313820202931640957596464756010405845841566072044962867016515061920631004186422275908670900574606417856951911456055068251250406007519842261898059237118054444788072906395242548339221982707404473162376760846613033778706039803413197133493654622700563169937455508241780972810983291314403571877524768509857276937926433221599399876886660808368837838027643282775172273657572744784112294389733810861607423253291974813120197604178281965697475898164531258434135959862784130128185406283476649088690521047580882615823961985770122407044330583075869039319604603404973156583208672105913300903752823415539745394397715257455290510212310947321610753474825740775273986348298498340756937955646638621874569499279016572103701364433135817214311791398222983845847334440270964182851005072927748364550578634501100852987812389473928699540834346158807043959118985815145779177143619698728131459483783202081474982171858011389071228250905826817436220577475921417653715687725614904582904992461028630081535583308130101987675856234343538955409175623400844887526162643568648833519463720377293240094456246923254350400678027273837755376406726898636241037491410966718557050759098100246789880178271925953381282421954028302759408448955014676668389697996886241636313376393903373455801407636741877711055384225739499110186468219696581651485130494222369947714763069155468217682876200362777257723781365331611196811280792669481887201298643660768551639860534602297871557517947385246369446923087894265948217008051120322365496288169035739121368338393591756418733850510970271613915439590991598154654417336311656936031122249937969999226781732358023111862644575299135758175008199839236284615249881088960232244362173771618086357015468484058622329792853875623486556440536962622018963571028812361567512543338303270029097668650568557157505516727518899194129711337690149916181315171544007728650573189557450920330185304847113818315407324053319038462084036421763703911550639789000742853672196280903477974533320468368795868580237952218629120080742819551317948157624448298518461509704888027274721574688131594750409732115080498190455803416826949787141316063210686391511681774304792596709377,
 soit approximativement 2.0.

On conjecture maintenant une limite de 2... !!!???

Compléments: sans le module fractions

On donne ci-dessous des solutions pour le calcul de fractions sans le module fractions.

Sans le module fractions, avec listes

On représente ici une fraction par une liste [numérateur, dénominateur]. On peut écrire quasiment le même code en choisissant de représenter une fraction par un tuple.

"""
Dans ce code, on représente une fraction par une liste de deux entiers. 
Le premier entier est le numérateur, 
le second entier est le dénominateur.
"""

from math import gcd

def addition(f1, f2):
    """
    f1 -- [entier, entier]
    f2 -- [entier, entier]

    renvoie la fraction f1 + f2 (réduite)
    """
    num = f1[0] * f2[1] + f2[0] * f1[1]
    den = f1[1] * f2[1]
    pgcd = gcd(num, den)
    num, den = num//pgcd, den//pgcd
    return [num, den]

def inverse(f):
    """
    f  -- [entier, entier]

    renvoie la fraction inverse
    """
    return [f[1], f[0]]

def oppose(f):
    """
    f  -- [entier, entier]

    renvoie la fraction opposée
    """
    return [(-1)*f[0], f[1]]

def multiplication(f1, f2):
    """
    f1 -- [entier, entier]
    f2 -- [entier, entier]

    renvoie la fraction f1 * f2 (réduite)
    """
    num, den = f1[0] * f2[0], f1[1] * f2[1]
    pgcd = gcd(num, den)
    num, den  = num//pgcd, den//pgcd
    return [num, den]

def u(n):
    """
    n -- entier naturel

    renvoie la fraction u(n) où u est définie dans l'énoncé.
    """
    a, b = [3, 2],[5, 3]
    if n == 0 : return a


    for k in range(2, n+1) :
        terme1 = [13, 1]
        terme2 = multiplication([32, 1], inverse(b))
        terme2 = oppose(terme2)
        terme3 = multiplication([20, 1], inverse(multiplication(a,b)))

        suivant = addition(terme1, terme2)
        suivant = addition(suivant, terme3)

        a, b = b, suivant
    return b


# Affichage de quelques calculs:
for n in (10, 100, 1000, 10000):
    terme = u(n)
    print(f"u({n}) = {terme[0]}/{terme[1]},\nsoit approximativement {terme[0]/terme[1]}.")
Sans le module fractions, avec chaînes de caractères
"""
Dans ce code, on représente une fraction 
par une chaîne de caractères "entier/entier". 
Le premier entier est le numérateur, 
le second entier est le dénominateur.
"""

from math import gcd

def num_den(f):
    """
    f -- chaîne "entier/entier"

    renvoie le couple d'entiers (numérateur, dénomiteur)
    """
    num = ''
    den = ''
    avantsep = True
    for c in f:
        if c == '/':
            avantsep = False
        else:
            if avantsep:
                num += c
            else:
                den += c
    return int(num), int(den)

def addition(f1, f2):
    """
    f1 -- chaîne "entier/entier"
    f2 -- chaîne "entier/entier"

    renvoie la fraction f1 + f2 (réduite)
    """
    num1, den1 = num_den(f1)
    num2, den2 = num_den(f2)
    num = num1 * den2 + num2 * den1
    den = den1 * den2
    pgcd = gcd(num, den)
    num, den = num//pgcd, den//pgcd
    return f"{num}/{den}"


def inverse(f):
    """
    f  -- chaîne "entier/entier"

    renvoie la fraction inverse
    """
    num, den = num_den(f)
    return f"{den}/{num}"



def oppose(f):
    """
    f  -- chaîne "entier/entier"

    renvoie la fraction opposée
    """
    num, den = num_den(f)
    num = (-1)*num
    return f"{num}/{den}"


def multiplication(f1, f2):
    """
    f1 -- chaîne "entier/entier"
    f2 -- chaîne "entier/entier"

    renvoie la fraction f1 * f2 (réduite)
    """
    num1, den1 = num_den(f1)
    num2, den2 = num_den(f2)
    num, den = num1 * num2, den1 * den2
    pgcd = gcd(num, den)
    num, den  = num//pgcd, den//pgcd
    return f"{num}/{den}"


def u(n):
    """
    n -- entier naturel

    renvoie la fraction u(n) où u est définie dans l'énoncé.
    """
    a, b = "3/2", "5/3"
    if n == 0 : return a


    for k in range(2, n+1) :
        terme1 = "13/1"
        terme2 = multiplication("32/1", inverse(b))
        terme2 = oppose(terme2)
        terme3 = multiplication("20/1", inverse(multiplication(a,b)))
        suivant = addition(terme1, terme2)
        suivant = addition(suivant, terme3)

        a, b = b, suivant
    return b


# Quelques calculs et affichages:
for n in (10, 100, 1000, 10000):
    terme = u(n)
    num, den = num_den(terme)
    print(f"Valeur u({n}) = {terme},\nsoit approximativement {num/den}.")
Sans le module fractions, avec dictionnaires

Un code possible sans le module fractions. On utilise ici des dictionnaires (type qu'il vous faut connaître en première NSI, voir le cours sur les dictionnaires)

from math import gcd


def addition(f1, f2):
    """
    f1 -- {'num': entier, 'den': entier}
    f2 -- {'num': entier, 'den': entier}

    renvoie le dictionnaire fraction f1 + f2 (réduite)
    """
    num = f1['num'] * f2['den'] + f2['num'] * f1['den']
    den = f1['den'] * f2['den']
    pgcd = gcd(num, den)
    num, den = num//pgcd, den//pgcd
    return {'num': num, 'den': den}


def inverse(f):
    """
    f  -- {'num': entier, 'den': entier}

    renvoie le dictionnaire fraction inverse
    """
    return {'num': f['den'], 'den': f['num']}



def oppose(f):
    """
    f  -- {'num': entier, 'den': entier}

    renvoie le dictionnaire fraction opposée
    """
    return {'num': (-1)*f['num'], 'den': f['den']}


def multiplication(f1, f2):
    """
    f1 -- {'num': entier, 'den': entier}
    f2 -- {'num': entier, 'den': entier}

    renvoie le dictionnaire fraction f1 * f2 (réduite)
    """
    num, den = f1['num'] * f2['num'], f1['den'] * f2['den']
    pgcd = gcd(num, den)
    num, den  = num//pgcd, den//pgcd
    return {'num': num, 'den': den}





def u(n):
    """
    n -- entier naturel

    renvoie la fraction u(n) où u est définie dans l'énoncé.
    """
    a, b = {'num': 3, 'den': 2}, {'num': 5, 'den': 3}
    if n == 0 : return a


    for k in range(2, n+1) :
        terme1 = {'num': 13, 'den': 1}
        terme2 = multiplication({'num': 32, 'den': 1}, inverse(b))
        terme2 = oppose(terme2)
        terme3 = multiplication({'num': 20, 'den': 1}, inverse(multiplication(a,b)))

        suivant = addition(terme1, terme2)
        suivant = addition(suivant, terme3)

        a, b = b, suivant
    return b



for n in (10, 100, 1000, 10000):
    terme = u(n)
    print(f"u({n}) = {terme['num']}/{terme['den']},\nsoit approximativement {terme['num']/terme['den']}.")
Avec une classe Fraction perso

Note

Paragraphe à ne lire que si vous voulez aller plus loin que le programme de première.

Le programme qui suit s'appuie sur la POO python. Ce n'est pas au programme de première, ces notions sont par contre au programme NSI en terminale.

Pour ceux qui aimeraient dès maintenant avoir une idée de ces notions:

from dataclasses import dataclass
from math import gcd


@dataclass
class Fraction:
    num: int  # numérateur
    den: int=1  # dénominateur

    def __neg__(self):
        """
        renvoie la fraction opposée.
        """
        return Fraction((-1) * self.num, self.den)


    def __add__(self, fraction):
        """
        renvoie la fraction somme (réduite) de l'instance en cours et de fraction
        """
        num = self.num * fraction.den + fraction.num * self.den
        den = self.den * fraction.den
        pgcd = gcd(num, den)
        num, den = num//pgcd, den//pgcd
        return Fraction(num, den)

    def __sub__(self, fraction):
        """
        renvoie la fraction différence (réduite) de l'instance en cours et de fraction
        """
        return self + (-fraction)   

    def __mul__(self, fraction):
        """        
        renvoie la fraction produit (réduite) de l'instance en cours et de fraction
        """

        num, den = self.num * fraction.num, self.den * fraction.den
        pgcd = gcd(num, den)
        num, den  = num//pgcd, den//pgcd
        return Fraction(num, den)

    def __floordiv__(self, fraction):
        """        
        renvoie la fraction quotient (réduite) self/fraction
        """
        return self * Fraction(fraction.den, fraction.num)


def u(n):
    """
    n -- entier naturel

    renvoie la fraction u(n) où u est définie dans l'énoncé.
    """
    a, b = Fraction(3, 2), Fraction(5, 3)
    if n == 0 : return a

    for k in range(2, n+1) :
        a, b = b, (Fraction(13) - (Fraction(32) // b)) + (Fraction(20) //  (a * b))
    return b




for n in (10,100, 1000):
    terme = u(n)
    print(f"u({n}) = {terme},\nsoit approximativement {terme.num/terme.den}.")

Pour mieux comprendre

Les valeurs obtenues dans l'exercice 2 sont des valeurs exactes (grâce à la capacité de python à travailler sur des entiers très longs), ce n'est pas le cas avec le calcul sur des flottants (exercice 1).

Pour mieux comprendre le problème soulevé dans les deux exercices précédents, vous lirez cet article.