S'il vous plaît considérer:
{4.93, Null}
4 Réponses :
Voici un piratage qui peut permettre à votre code d'être rapide, mais je ne le garantis pas de toujours fonctionner correctement: en l'utilisant, nous obtenons: p> < Pré> xxx pré> L'idée est que, Je ne peux cependant pas garantir qu'il n'y a pas d'exemples où Bien sûr, une alternative plus sûre qui existe toujours est de redéfinir le coefficient code> Utilisation de Villegas - Gayley Trick, élargissement d'une expression à l'intérieur et l'appelant à nouveau: p> edit 2 strong> p> Ma première suggestion a eu un avantage que nous avons défini une macro modifié les propriétés des fonctions localement, mais inconvénient qu'il était dangereux. Ma deuxième suggestion est plus sûre mais modifie L'utilisation est similaire au premier cas: p> le coefficient principal coefficient code> utilise
binomial code> en interne pour estimer le nombre de termes, puis élargir (appels
développer CODE>) Si le nombre de termes est inférieur à
1000 code>, que vous pouvez vérifier à l'aide de
TRACE [..., TRACELInnernal-> true] code>. Et quand il ne se développe pas, il calcule beaucoup de sommes de grandes listes de coefficients dominées par les zéros, ce qui est apparemment plus lent que l'expansion, pour une gamme d'expressions. Ce que je fais, c'est d'imbécile
binomial code> dans le retour d'un petit nombre (
10 code>), mais j'ai également essayé de le faire de telle sorte qu'il n'affecte que le
binomial code> appelé interne par
coefficient code>: p>
binomial code> ailleurs Dans le code sera calculé de manière incorrecte. P>
coefficient code> globalement, il sera donc toujours em> développer jusqu'à ce que nous supprimions cette définition. Nous pouvons avoir le meilleur des deux mondes à l'aide de
Interne`inhéritedblock code>
, qui crée une copie locale d'une fonction donnée. Voici le code: p> La fonction code> reste non affectée cependant: p>
+1 Pour le travail et l'analyse d'ingénierie inverse, mais n'est-ce pas vraiment identique à l'expansion manuelle en premier, mais dangereux? Ou est-ce encore plus efficace de mémoire que cela (c'est-à-dire la décision interne de se développer ou non de se développer à l'ensemble de l'expression ou des pièces uniquement)?
@Szabolcs Je viens de modifier pour ajouter l'autre possibilité (expansion) avant de voir votre commentaire. C'est probablement la même mémoire - sage, et lorsque le coefficient se développe, il élargit toute expression (autant que je puisse dire). Ma première solution est plus pour une illustration. Je vais ajouter le second à partir de Gayley - Villegas Trick sous peu.
Cela peut également être plus rapide pour éviter l'expansion. Voici un exemple simple. P> coefficient code> ne se développera pas à moins qu'il ne le juge absolument nécessaire de le faire. Cela évite effectivement des explosions de la mémoire. Je crois que cela a été de cette façon depuis la version 3 (je pense que je travaillais autour de 1995 environ).
Coefficient[Expand[expr], x, 234]; // Timing
expr = Sum[x^i, {i, 15}]^30; scoeff[ex_, var_, n_] /; PolynomialQ[ex, var] := ex + O[var]^(n + 1) /. Verbatim[SeriesData][_, 0, c_List, nmin_, nmax_, 1] :> If[nmax - nmin != Length[c], 0, c[[-1]]]; Timing[scoeff[expr, x, 234]] seems quite fast, too.
+1. Il est en fait plusieurs fois plus rapide pour les expressions plus grandes, que des solutions basées sur l'élargissement d'une expression. De plus, il est considérablement plus rapide pour les coefficients à index plus petits, car il semble effectivement ne développer que la partie d'expression jusqu'à un terme déterminé (puissance).
SeriesData est vraiment très joliment mis en œuvre à Mathematica. Donc, tout ce que l'on peut faire avec SeriesData est flamboyant rapide (encore plus rapide que la forme ( Nikhef.nl/~Forme a>)).
Rolf Mertig, je suis obligé d'accepter cette réponse, car il est concis et efficace. Cependant, je ne comprends pas vraiment. Voulez-vous s'il vous plaît expliquer cela dans les termes les plus simples possibles?
Spécifiquement, je ne comprends pas: ex + o [var] ^ (n + 1) code>
C'est juste une expansion de Taylor qui a du sens ici puisque les puissances supérieures de X ne sont pas nécessaires. L'accélération provient du fait que SeriesData est implémentée efficacement dans Mathematica. Voir aussi: référence.wolfram.com/mathematica/ref/o.html
Merci. Pardonnez-moi pour l'ONU-Accepter votre réponse, mais je pense avoir trouvé une méthode plus facile, inspirée par la vôtre. J'attendrai l'examen par les pairs sur cette réponse.
Après une certaine expérimentation après la réponse de Rolf Mertig, cela semble être la méthode la plus rapide sur le type d'expression telle que somme [x ^ i, {i, 15}] ^ 30 code>:
Notez que cela répond quelque peu une question différente de ce que vous avez demandé à l'origine: Vous avez posé des questions sur les raisons pour lesquelles coefficient code> est lent (accent sur
coefficient code> et "pourquoi lentement"), pas ce que sont substituts rapides possibles pour cela.
@Leonid très bon point. J'avais oublié cela après avoir lu les diverses réponses. Je suppose que la réponse de Daniel est la plus directe; Devrais-je accepter ça? Aussi, que pensez-vous de cette méthode? Y a-t-il des problèmes évidents avec cela?
Désolé, je ne peux pas vous conseiller sur quelle réponse vous acceptez - c'est entièrement à vous de vous. La réponse de Daniel est très bonne, brève et au point. Quant à la méthode - je ne vois pas de problèmes évidents, mais hélas n'ont pas de temps en ce moment pour jouer avec elle.
@Leonid vous sonnez assez diplomatique. D'accord.
Peut-être
coefficient Code> S algorithme de la vitesse de l'espace pour pouvoir travailler sur des expressions avec une forme expansée extrêmement longue? BTW Votre ordinateur est 4,5 fois plus rapide que le mien.
@Szabolcs je suppose que cela a du sens; Je vais essayer de le tester. J'espère espérer un processus de sélection de méthode plus intelligent si c'est le cas. Si vous utilisez la version 8, pouvez-vous également essayer le test dans la version 7? Je soupçonne que au moins certaines choses sont plus lentes dans 8.
Je n'ai pas de V7 Installer à portée de main maintenant ..
@Szabolcs Il est également 4 fois plus lent sur le mien (V8), alors je suppose que c'est une différence de version.
@Szabolcs Je peux confirmer votre hypothèse, à l'aide de ce que
coefficient code> est beaucoup plus efficace de mémoire sur
(1 + x) ^ 50000 code>. Y a-t-il quelque chose de raisonnable que je puisse faire pour faire une fonction généralisée qui appelle
coefficient code> plus rapidement? Existe-t-il une sorte de formulaire semi-élargi, ou
méthode code> qui me donnerait un équilibre entre ces options?
Avec une situation d'expression plus grande est encore pire. Avec
expr = somme [x ^ i, {i, 30}] ^ 20; code> il y a un facteur de 670 entre eux. Je ne remarque pas beaucoup de différence en ce qui concerne l'utilisation de la mémoire, mais le moniteur système n'est pas très sensible.
@Sjoerd merci d'avoir testé. Veuillez essayer avec l'échantillon:
(1 + x) ^ 50000 code> ou similaire.
Avez-vous vu l'autre différence de version étrange (entre 8.0.x et 8.0.4), Ici ? La solution de Belisarius ne fonctionne pas comme - est sur 8.0.4, apparemment en raison d'une modification de
Radon [] code>
A obtenu 20% à 30% des résultats plus lents sur 8.0.4 par rapport à 7,0,1 (mais toujours la moitié de la vitesse de M.Wizard ...)