03.12.2012 Views

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

4.8. FUNCTORS 115<br />

Since we are using a template argument F we need to define the constraints that it has to satisfy.<br />

For this function, we need F to be a functor with one argument. This is called a UnaryFunctor.<br />

Formally, we can write this as follows:<br />

• Let f be of type F.<br />

• Let x be of type X, where X is the argument type of F.<br />

• f(x) calls f with one argument, and returns an object of the result type.<br />

In this example we also require that the argument type and result type of F are identical. We<br />

can remove this restriction if we establish a unique way to deduce the return type. This can be<br />

achieved by meta-programming or with the type deduction in the next C ++ standard.<br />

So far so good. We complained be<strong>for</strong>e that we cannot apply the finite differences on themselves<br />

to compute higher order derivatives. Actually, we still cannot. The problem is that the<br />

finite difference expects (amongst others) a unary functor and is itself a ternary function. So it<br />

cannot use itself as argument. The solution is to realize its functionality in a unary functor that<br />

we call derivative:<br />

template <br />

class derivative<br />

{<br />

public:<br />

derivative(const F& f, const T& h) : f(f), h(h) {}<br />

T operator()(const T& x) const<br />

{<br />

return ( f(x+h) − f(x) ) / h ;<br />

}<br />

private:<br />

const F& f;<br />

T h;<br />

};<br />

Now we can create an object that approximates the derivative from f(x) = sin(1 · x) + cos x:<br />

typedef derivative spc der 1;<br />

spc der 1 spc(sin 1, 0.001);<br />

The object spc can be used like a function and it approximates f ′ (x). In addition it is a unary<br />

functor. That means we can compute its derivative:<br />

typedef derivative spc der 2;<br />

spc der 2 spc scd(spc, 0.001);<br />

std::cout ≪ ”Second derivative of sin(0) + cos(0) is ” ≪ spc scd(0.0) ≪ ’\n’;<br />

The object spc scd is again a unary functor and aproximates f ′′ (x). We could again construct<br />

a functor <strong>for</strong> its derivative and continue this game eternally.<br />

Assume that we need second derivatives from different functions. Then it becomes annoying to<br />

define first the type of the first derivative constructing a functor from it <strong>for</strong> finally creating a<br />

functor the second one. According to Greg Wilson’s [?] 23 maxim “Whatever you use twice,<br />

automate!” we write a class that provides us the second derivative directly:<br />

23 This online course contains a gigantic collection of tips how to develop software successfully and avoid<br />

frustrating unproductivity. We highly recommend you reading this material.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!