tags:

views:

185

answers:

2

Hey,

I've written a function in C# that does a numerical differentiation. It looks like this:

public double Diff(double x)
{
    double h = 0.0000001;

    return (Function(x + h) - Function(x)) / h;
}

I would like to be able to pass in any function, as in:

public double Diff(double x, function f)
{
    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;
}

I think this is possible with delegates (maybe?) but I'm not sure how to use them.

Any help would be greatly appreciated.

Thanks, Ash

+19  A: 

There are a couple generic types in .Net (v2 and later) that make passing functions around as delegates very easy.

For functions with return types, there is Func<> and for functions without return types there is Action<>.

Both Func and Action can be declared to take from 0 to 4 parameters. For example, Func < double, int > takes one double as a parameter and returns an int. Action < double, double, double > takes three doubles as parameters and returns nothing (void).

So you can declare your Diff function to take a Func:

public double Diff(double x, Func<double, double> f) {
    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;
}

And then you call it as so, simply giving it the name of the function that fits the signature of your Func or Action:

double result = Diff(myValue, Function);

You can even write the function in-line with lambda syntax:

double result = Diff(myValue, d => Math.Sqrt(d * 3.14));
qstarin
In .NET 4, both `Func` and `Action` have been updated to allow for [up to 16](http://msdn.microsoft.com/en-us/library/dd402862.aspx) parameters.
Joel Mueller
@Joel Mueller: thanks for adding that good to know info.
qstarin
A really cool thing to do would be to return a `Func<double, double>` that is the first-derivative of the input function, numerically calculated of course. `return x => (f(x + h) - f(x)) / h;` You could even write an overload that returned the `n` th derivative of the input function.
Ani
+3  A: 

Using the Func as mentioned above works but there are also delegates that do the same task and also define intent within the naming:

public delegate double MyFunction(double x);

public double Diff(double x, MyFunction f)
{
    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;
}

public double MyFunctionMethod(double x)
{
    // Can add more complicated logic here
    return x + 10;
}

public void Client()
{
    double result = Diff(1.234, x => x * 456.1234);
    double secondResult = Diff(2.345, MyFunctionMethod);
}
Ian Johnson
In 3.5 and later, Func<>s and delegates are interchangeable, and that means that anonymous delegates and lambdas (which are syntactic sugar for anonymous delegates) can also be used. So it doesn't really matter whether you specify the parameter as a Func<double,double> or a delegate that takes a double and returns a double. The only real advantage a named delegate gives you is the ability to add xml-doc comments; descriptive names are just as easy to implement as the parameter name instead of the type.
KeithS
I would argue that the method prototype still makes the code more readable than the Func<x, y> - it is not just the naming that makes code readable and as you say that does not stop you from passing lambdas into the code.
Ian Johnson
If the naming of the delegate type is so important to code clarity, I think in most cases I'd be leaning towards an interface and implementations.
qstarin
@qstarin it is not just the naming of the delegate but the naming of the arguments that the method must take, especially if they are just native types. You are right, mostly I use interfaces over delegates
Ian Johnson