Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Skizz's answer is true when taken literally, but only a small change is required to make it possible to compute the derivative of a C++ function. We modify skizz's function <code>f</code> to</p> <pre><code>template&lt;class Float&gt; f (Float x) { return x * x + Float(4.0f) * x + Float(6.0f); // f(x) = x^2 + 4x + 6 } </code></pre> <p>It is now possible to write a C++ function to compute the derivative of f with respect to x. Here is a complete self-contained program to compute the derivative of f. It is exact (to machine precision) as it's not using an inaccurate method like finite differences. I explain how it works in a <a href="http://homepage.mac.com/sigfpe/paper.pdf" rel="nofollow noreferrer">paper</a> I wrote. It generalises to higher derivatives. Note that much of the work is done statically by the compiler. If you turn up optimization, and your compiler inlines decently, it should be as fast as anything you could write by hand for simple functions. (Sometimes faster! In particular, it's quite good at amortising the cost of computing f and f' simultaneously because it makes common subexpression elimination easier for the compiler to spot than if you write separate functions for f and f'.)</p> <pre><code>using namespace std; template&lt;class Float&gt; Float f(Float x) { return x * x + Float(4.0f) * x + Float(6.0f); } struct D { D(float x0, float dx0 = 0) : x(x0), dx(dx0) { } float x, dx; }; D operator+(const D &amp;a, const D &amp;b) { // The rule for the sum of two functions. return D(a.x+b.x, a.dx+b.dx); } D operator*(const D &amp;a, const D &amp;b) { // The usual Leibniz product rule. return D(a.x*b.x, a.x*b.dx+a.dx*b.x); } // Here's the function skizz said you couldn't write. float d(D (*f)(D), float x) { return f(D(x, 1.0f)).dx; } int main() { cout &lt;&lt; f(0) &lt;&lt; endl; // We can't just take the address of f. We need to say which instance of the // template we need. In this case, f&lt;D&gt;. cout &lt;&lt; d(&amp;f&lt;D&gt;, 0.0f) &lt;&lt; endl; } </code></pre> <p>It prints the results <code>6</code> and <code>4</code> as you should expect. Try other functions <code>f</code>. A nice exercise is to try working out the rules to allow subtraction, division, trig functions etc.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload