Une manière plus rapide et plus élégante de produire une séquence récursive de nombres rationnels [fermé]

Nov 24 2020

J'étudie une récursion ci-dessous:

$$B_{N,0}=1$$

$$B_{N,k}=-\binom{N+k}{k}^{-1}\sum_{j=0}^{k-1}\binom{N+k}{j}B_{N,j}$$

Maintenant, je ne suis pas doué pour écrire en Mathematica. Cela fait un moment que je ne l'ai pas utilisé. J'ai donc recherché de vieux travaux et suis tombé sur cette méthode dans Mathematica; c'est une propriété "mémoire" dans le code, ou c'est comme ça que je me souviens qu'elle m'a été décrite. Alors je l'ai fait et j'ai écrit le code ci-dessous.

 B[0]=1

 B[k]=B[k_]:=Simplify[-1/(Binomial[N+k,k])*Sum[Binomial[N+k,j]*B[j]],{j,0,k-1}]

Et il fonctionne! Pas génial. Donc, j'obtiens assez bien les quatre ou cinq premiers. Ce sont des fonctions rationnelles dans la variable$N$. Donc les 5 premiers, sont postés ci-dessous (j'ai utilisé Imgur, désolé)

Mais alors, le code se brise. Je suis sûr que la récursivité devient trop difficile car le calcul requis devient important. Les deux prochains nombres sont donnés comme (encore une fois, désolé pour l'image)

Et voici donc la question. Comment puis-je faire en sorte que le 6ème B [6], le 7ème B [7], ..., le kème nombre B [k], soient écrits ou sortis dans la forme pondérée élégante comme dans le 5 précédent, sans ce binôme maladroit fonction dans le dénominateur? Je m'intéresse à la distribution de la factorisation du dénominateur.

Réponses

10 N0va Nov 24 2020 at 10:08
ClearAll[B];    
B[k_]:=B[k]=Simplify[FunctionExpand[-1/(Binomial[n+k,k])*Sum[Binomial[n+k,j]*B[j],{j,0,k-1}]]]

Fonctionne bien pour moi:

Table[{"B[" <> ToString[k] <> "]=", B[k]}, {k, 0, 7}] // TableForm

Assurez-vous de le faire ClearAll[B]lorsque vous modifiez la définition car les valeurs sont mises en cache par B[k]:=B[k]. Calculer B[k]jusqu'à a k=7pris 0,02 seconde pour moi et jusqu'à k=4210,7 secondes. Cela me semble raisonnable.

6 yawnoc Nov 24 2020 at 20:54

Soulignant simplement la différence entre la définition de OP et celle de N0va:

Version incorrecte

B[k] = B[k_] := <RHS>

En lisant de gauche à droite, la première affectation est égale à simple (Set) tandis que la deuxième affectation est égale à deux points (SetDelayed). Notez que dans l'interface graphique, kapparaît en bleu (en supposant qu'il soit gratuit). En pseudocode:

  1. Mathematica voit d'abord B[k] = <expression1>et dit: «Je vais immédiatement évaluer <expression1>et attribuer le résultat B[k]».
  2. Mathematica voit alors <expression1>ce qui est B[k_] := <RHS>et dit: "Je vais maintenant définir B[k_]comme étant <RHS>, mais je retarderai l'évaluation de <RHS>jusqu'à ce que je reçoive une valeur réelle de k."

La deuxième étape revient Null, et c'est celle-ci Nullqui est immédiatement affectée B[k]. En fait, c'est la même chose que de faire

B[k_] := <RHS>
B[k] = Null

c'est-à-dire une définition non mémorisée suivie d'une affectation immédiate (mais plutôt inutile).

Version correcte

B[k_] := B[k] = <RHS>

En lisant de gauche à droite, la première affectation est égale à deux-points (SetDelayed) tandis que la deuxième affectation est simple-égale (Set). En pseudocode:

  1. Mathematica voit d'abord B[k_] := <expression2>et dit: "Je vais maintenant définir B[k_]comme étant <expression2>, mais je retarderai l'évaluation de <expression2>jusqu'à ce que je reçoive une valeur réelle de k."

OK, alors que se passe-t-il lorsqu'une valeur réelle de kest reçue?

  1. Mathematica évalue ensuite <expression2>, ce qui est B[k] = <RHS>, et dit: «Je vais maintenant évaluer <RHS> et attribuer immédiatement le résultat B[k]». C'est cette seconde mission qui réalise la mémorisation.