J'ai écrit un code qui utilise numériquement des polynômes légendres jusqu'à un certain N-ème ordre. Par exemple: si le vecteur est là pour dire ce qui sera le moyen le plus efficace de prendre une puissance d'un vecteur ?
Pouvez-vous expliquer pourquoi il y a une telle différence de performance? P> p> x code> est long, cela peut devenir lent. J'ai vu qu'il existe une différence de performance entre dire
x. ^ 4 code> et
x. * X. * X. X code> et pensé que je pourrais utiliser cela pour améliorer mon code. J'ai utilisé
Timeit code> et trouvé que pour: p>
f4 code> est
x. ^ 6 code> il y a très peu de différence entre
(x. * X. X). ^ 2 code> et
x. * X. * x. * x. * x. * x code> (tandis que toutes les autres options sont plus lentes). P>
3 Réponses :
Ce n'est pas une réponse exactement à votre question, mais cela peut résoudre votre problème:
x2 = x.*x; % or x.^2 or power(x,2), whichever is most efficient p = ((((6435*x2-12012)*x2+6930)*x2-1260)*x2+35)/128
Voici quelques pensées:
x. ^ 2. ^ 2 code> est probablement évalué comme suit: Prenez le carré de chaque élément (rapide) et prenez à nouveau le carré de celui-ci (à nouveau rapide). P> Il n'est pas si étrange de voir que 2 opérations rapides prennent moins de temps que 1 opération lente . Dommage que l'optimisation ne soit pas effectuée dans le boîtier de puissance 4, mais elle ne fonctionnera peut-être pas toujours à un coût (vérification des entrées, mémoire?). P> sur les timings: En fait, il y a beaucoup plus de différence qu'un facteur 2! P> Lorsque vous les appelez dans une fonction maintenant, la fonction de fonction est ajoutée dans chaque cas, rendant les différences relatives plus petites: p> donnera: puissance (x, 4) code> et
x. ^ 4 code> sont équivalents (juste lire le doc). P>
x. * x. * x. x x code> est probablement optimisé à quelque chose comme
x. ^ 2. ^ 2 code> p>
x. ^ 4 code> est probablement directement évalué comme suit: Prenez la quatrième puissance de chaque élément (lent). P>
Elapsed time is 0.034826 seconds.
Elapsed time is 0.029186 seconds.
Elapsed time is 0.003891 seconds.
Elapsed time is 0.003840 seconds.
L'optimisation qui est probablement faite sur x. * X. * X. X code> se comporte étrangement. J'ai essayé
x. * J'aurais attendu des bosses; Par exemple, le cas "8" (=>
x. ^ 2. ^ 2. ^ 2 code>: trois opérations de puissance) devrait prendre moins de temps que "7" (=> plus d'opérations de puissance)
@LUISMENDO Je ne sais pas comment vérifier, mais je pouvais imaginer que cela ne fait que 1 étape (aucune optimisation imbriquée). Pour 7, il réduirait alors quelque chose comme: x. ^ 2 * x. ^ 2 * x. ^ 2. * x code> qui ne serait pas plus lent que
x. ^ 2 * x. ^ 2 * x. ^ 2. * x. ^ 2 code> pour 8. Si cela faisait 8 ans était plus rapide que de faire 7 de cette façon, Mathworks aurait probablement impliqué ce type d'optimisation dans la fonction de puissance.
Oui, cela pourrait être l'explication: pas de nidification
@ Dennisjaharuddin, je pense que tu as raison. Consultez ma réponse (que je composait lorsque vous avez répondu) - La nidification est étonnamment 2 fois plus lente pour la 16ème puissance.
Il semble que Mathworks ait des carrés de boîtes spéciales dans sa fonction de puissance (malheureusement, tout est intégré à la source fermée que nous ne pouvons pas voir). Dans mes tests sur R2013B, il apparaît comme si pour cubes, l'histoire est différente. Ils ne sont plus spéciaux. Encore une fois, Sautons à la 16ème puissance pour voir comment ces algorithmes échelle: p> donc: comme prévu, augmentant la taille de Alors, morale de l'histoire? Lorsque vous utilisez des exposants entier scalaire, faites toujours la multiplication vous-même. Il y a beaucoup de smarts dans . ^ Code>,
alléaire code> et
realppow code> Utilisez le même algorithme. Pour les carrés, je crois qu'ils ont une bloquée spéciale pour être
x. * X code>.
. ^ Code>,
alléaire code> et
realppow code> Tous sont similaires, mais beaucoup plus lent cette fois: p>
. ^ code>,
CODE> et
REALLOW CODE> Tous courir dans une heure constante en ce qui concerne l'exposant, sauf s'il s'agissait d'une boîte spéciale (-1 semble également avoir été une boîte spéciale). Utilisation de l'expression
exp (n * journal (x)) code> Trick est également une durée constante en ce qui concerne l'exposant et plus vite. Le seul résultat que je ne comprends pas tout à fait pourquoi la quille répétée est plus lente que la multiplication. P>
x code> par un facteur de 100 augmente le temps de la même manière Pour tous les algorithmes. P>
puissance code> et amis (l'exposant peut être un point flottant, vecteur, etc.). Les seules exceptions sont les mêmes exceptions que Mathworks a effectué l'optimisation pour vous. En 2013b, il semble être
x ^ 2 code> et
x ^ (- 1) code>. Espérons qu'ils vont ajouter davantage au fil du temps. Mais, en général, l'exponentiation est difficile et la multiplication est facile. Dans le code sensible à la performance, je ne pense pas que vous puissiez vous tromper en tapant toujours
x. * X. * X x code>. (Bien sûr, dans votre cas, suivez les conseils de Luis et utilisez les résultats intermédiaires dans chaque terme!) P>
function powerTest(x)
f{1} = @() x.*x.*x.*x.*x.*x.*x.*x.*x.*x.*x.*x.*x.*x.*x.*x;
f{2} = @() x.^2.^2.^2.^2;
f{3} = @() exp(16.*log(x));
f{4} = @() x.^16;
f{5} = @() power(x,16);
f{6} = @() realpow(x,16);
for i = 1:length(f)
t(i) = timeit(f{i});
end
[t,idxs] = sort(t);
fcns = f(idxs);
for i = 1:length(fcns)
fprintf('%.1fx (%.1fms):\t%s\n',t(i)/t(1),t(i)*1e3,func2str(fcns{i}));
end