web-dev-qa-db-fra.com

Quelle est la meilleure façon de calculer une dérivée numérique dans MATLAB?

(Remarque: ceci est destiné à être un wiki de communauté.)

Supposons que j'ai un ensemble de points xi = { x0 , x1 , x2 , ... xn } et les valeurs de fonction correspondantes fi = f(xi { f0 , f1 , f2 , ..., fn }, où f ( x ) est, en général, une fonction inconnue.) == (Dans certaines situations, nous pourrions savoir f ( x ) à l’avance, mais nous voulons le faire en général, car nous avons souvent pas savoir f ( x ) à l'avance.) Quel bon moyen d'approcher la dérivée de f ( x ) à chaque point xi ? C'est-à-dire Comment puis-je estimer les valeurs de dfi == d/d x fi == d f ( xi )/d x à chacun des points xi ?

Malheureusement, MATLAB n’a pas une très bonne routine de différenciation numérique polyvalente. Cela s’explique en partie par le fait que choisir une bonne routine peut être difficile!

Alors, quels types de méthodes existe-t-il? Quelles routines existent? Comment pouvons-nous choisir une bonne routine pour un problème particulier?

Il y a plusieurs considérations à prendre en compte lors du choix de la différenciation dans MATLAB:

  1. Avez-vous une fonction symbolique ou un ensemble de points?
  2. Votre réseau est-il espacé de manière égale ou inégale?
  3. Votre domaine est-il périodique? Pouvez-vous assumer des conditions aux limites périodiques?
  4. Quel niveau de précision recherchez-vous? Avez-vous besoin de calculer les dérivés dans une tolérance donnée?
  5. Cela vous importe-t-il que votre dérivé soit évalué sur les mêmes points que votre fonction est définie?
  6. Avez-vous besoin de calculer plusieurs ordres de dérivés?

Quelle est la meilleure façon de procéder?

16
jvriesem

These are just some quick-and-dirty suggestions. Hopefully somebody will find them helpful!

1. Do you have a symbolic function or a set of points?

  • If you have a symbolic function, you may be able to calculate the derivative analytically. (Chances are, you would have done this if it were that easy, and you would not be here looking for alternatives.)
  • If you have a symbolic function and cannot calculate the derivative analytically, you can always evaluate the function on a set of points, and use some other method listed on this page to evaluate the derivative.
  • In most cases, you have a set of points (xi,fi), and will have to use one of the following methods....

2. Is your grid evenly or unevenly spaced?

  • If your grid is evenly spaced, you probably will want to use a finite difference scheme (see either of the Wikipedia articles here or here), unless you are using periodic boundary conditions (see below). Here is a decent introduction to finite difference methods in the context of solving ordinary differential equations on a grid (see especially slides 9-14). These methods are generally computationally efficient, simple to implement, and the error of the method can be simply estimated as the truncation error of the Taylor expansions used to derive it.
  • If your grid is unevenly spaced, you can still use a finite difference scheme, but the expressions are more difficult and the accuracy varies very strongly with how uniform your grid is. If your grid is very non-uniform, you will probably need to use large stencil sizes (more neighboring points) to calculate the derivative at a given point. People often construct an interpolating polynomial (often the Lagrange polynomial) and differentiate that polynomial to compute the derivative. See for instance, this StackExchange question. It is often difficult to estimate the error using these methods (although some have attempted to do so: here and here). Fornberg's method is often very useful in these cases....
  • Care must be taken at the boundaries of your domain because the stencil often involves points that are outside the domain. Some people introduce "ghost points" or combine boundary conditions with derivatives of different orders to eliminate these "ghost points" and simplify the stencil. Another approach is to use right- or left-sided finite difference methods.
  • Here's an excellent "cheat sheet" of finite difference methods, including centered, right- and left-sided schemes of low orders. I keep a printout of this near my workstation because I find it so useful.

3. Is your domain periodic? Can you assume periodic boundary conditions?

  • If your domain is periodic, you can compute derivatives to a very high order accuracy using Fourier spectral methods. This technique sacrifices performance somewhat to gain high accuracy. In fact, if you are using N points, your estimate of the derivative is approximately N^th order accurate. For more information, see (for example) this WikiBook.
  • Fourier methods often use the Fast Fourier Transform (FFT) algorithm to achieve roughly O(N log(N)) performance, rather than the O(N^2) algorithm that a naively-implemented discrete Fourier transform (DFT) might employ.
  • If your function and domain are not periodic, you should not use the Fourier spectral method. If you attempt to use it with a function that is not periodic, you will get large errors and undesirable "ringing" phenomena.
  • Computing derivatives of any order requires 1) a transform from grid-space to spectral space (O(N log(N))), 2) multiplication of the Fourier coefficients by their spectral wavenumbers (O(N)), and 2) an inverse transform from spectral space to grid space (again O(N log(N))).
  • Care must be taken when multiplying the Fourier coefficients by their spectral wavenumbers. Every implementation of the FFT algorithm seems to have its own ordering of the spectral modes and normalization parameters. See, for instance, the answer to this question on the Math StackExchange, for notes about doing this in MATLAB.

4. What level of accuracy are you looking for? Do you need to compute the derivatives within a given tolerance?

  • For many purposes, a 1st or 2nd order finite difference scheme may be sufficient. For higher precision, you can use higher order Taylor expansions, dropping higher-order terms.
  • If you need to compute the derivatives within a given tolerance, you may want to look around for a high-order scheme that has the error you need.
  • Often, the best way to reduce error is reducing the grid spacing in a finite difference scheme, but this is not always possible.
  • Be aware that higher-order finite difference schemes almost always require larger stencil sizes (more neighboring points). This can cause issues at the boundaries. (See the discussion above about ghost points.)

5. Does it matter to you that your derivative is evaluated on the same points as your function is defined?

  • MATLAB provides the diff function to compute differences between adjacent array elements. This can be used to calculate approximate derivatives via a first-order forward-differencing (or forward finite difference) scheme, but the estimates are low-order estimates. As described in MATLAB's documentation of diff (link), if you input an array of length N, it will return an array of length N-1. When you estimate derivatives using this method on N points, you will only have estimates of the derivative at N-1 points. (Note that this can be used on uneven grids, if they are sorted in ascending order.)
  • In most cases, we want the derivative evaluated at all points, which means we want to use something besides the diff method.

6. Do you need to calculate multiple orders of derivatives?

  • One can set up a system of equations in which the grid point function values and the 1st and 2nd order derivatives at these points all depend on each other. This can be found by combining Taylor expansions at neighboring points as usual, but keeping the derivative terms rather than cancelling them out, and linking them together with those of neighboring points. These equations can be solved via linear algebra to give not just the first derivative, but the second as well (or higher orders, if set up properly). I believe these are called combined finite difference schemes, and they are often used in conjunction with compact finite difference schemes, which will be discussed next.
  • Compact finite difference schemes (link). In these schemes, one sets up a design matrix and calculates the derivatives at all points simultaneously via a matrix solve. They are called "compact" because they are usually designed to require fewer stencil points than ordinary finite difference schemes of comparable accuracy. Because they involve a matrix equation that links all points together, certain compact finite difference schemes are said to have "spectral-like resolution" (e.g. Lele's 1992 paper--excellent!), meaning that they mimic spectral schemes by depending on all nodal values and, because of this, they maintain accuracy at all length scales. In contrast, typical finite difference methods are only locally accurate (the derivative at point #13, for example, ordinarily doesn't depend on the function value at point #200).
  • A current area of research is how best to solve for multiple derivatives in a compact stencil. The results of such research, combined, compact finite difference methods, are powerful and widely applicable, though many researchers tend to tune them for particular needs (performance, accuracy, stability, or a particular field of research such as fluid dynamics).

Ready-to-Go Routines

  • As described above, one can use the diff function (link to documentation) to compute rough derivatives between adjacent array elements.
  • MATLAB's gradient routine (link to documentation) is a great option for many purposes. It implements a second-order, central difference scheme. It has the advantages of computing derivatives in multiple dimensions and supporting arbitrary grid spacing. (Thanks to @thewaywewalk for pointing out this glaring omission!)

  • I used Fornberg's method (see above) to develop a small routine (nderiv_fornberg) to calculate finite differences in one dimension for arbitrary grid spacings. I find it easy to use. It uses sided stencils of 6 points at the boundaries and a centered, 5-point stencil in the interior. It is available at the MATLAB File Exchange here.

Conclusion

The field of numerical differentiation is very diverse. For each method listed above, there are many variants with their own set of advantages and disadvantages. This post is hardly a complete treatment of numerical differentiation.

Every application is different. Hopefully this post gives the interested reader an organized list of considerations and resources for choosing a method that suits their own needs.

This community wiki could be improved with code snippets and examples particular to MATLAB.

18
jvriesem

Je crois qu'il y a plus dans ces questions particulières. J'ai donc approfondi le sujet comme suit:

(4) Q: Quel niveau de précision recherchez-vous? Avez-vous besoin de calculer les dérivés dans une tolérance donnée?

R: L'exactitude de la différenciation numérique est subjective pour l'application de l'intérêt. En règle générale, si vous utilisez le problème de ND dans le transfert pour approcher les dérivées afin d’estimer les entités à partir du signal d’intérêt, vous devez être conscient des perturbations de bruit. Habituellement, de tels artefacts contiennent des composants haute fréquence et, par la définition du différenciateur, l’effet de bruit sera amplifié dans l’ordre de grandeur de $ i Omega. Donc, augmenter la précision du différenciateur (augmenter la précision polynomiale) ne sera d'aucune aide. Dans ce cas, vous devriez pouvoir annuler l'effet du bruit pour la différenciation. Cela peut être fait dans l’ordre suivant: lisser d’abord le signal, puis différencier. Mais une meilleure façon de procéder consiste à utiliser "Lowpass Differentiator". Un bon exemple de bibliothèque MATLAB peut être trouvé ici .

Toutefois, si ce n'est pas le cas et que vous utilisez ND dans des problèmes inverses, tels que des PDE solvign, la précision globale du différentiateur est très importante. Selon le type de condition bounady (BC) qui convient à votre problème, la conception sera adaptée en conséquence. La règle de frappe est d'augmenter la précision numérique connue est le différentiateur de bande complète. Vous devez concevoir une matrice dérivée prenant en charge le gilet approprié. Vous pouvez trouver des solutions complètes à ces conceptions en utilisant le lien ci-dessus.

(5) Cela vous importe-t-il que votre dérivée soit évaluée sur les mêmes points que votre fonction est définie? A: Oui, absolument. L'évaluation du ND sur les mêmes points de la grille s'appelle des schémas "centralisés" et des points "échelonnés". Notez qu'en utilisant un ordre impair des dérivées, le ND centralisé déviera de la précision de la réponse en fréquence du différentiateur. Par conséquent, si vous utilisez une telle conception dans des problèmes inverses, cela perturbera votre approximation. De même, le contraire s’applique au cas de l’ordre uniforme de différenciation utilisé par les systèmes échelonnés. Vous pouvez trouver des explications complètes sur ce sujet en utilisant le lien ci-dessus.

(6) Avez-vous besoin de calculer plusieurs ordres de dérivés? Cela dépend totalement de votre application. Vous pouvez vous référer au même lien que j'ai fourni et gérer plusieurs conceptions dérivées.

1
Mahdi S. Hosseini