Creating a summation function in C# isn’t difficult in itself. After all, it is perfectly reasonable to create functions that consist of more than one line. What is interesting is abstracting it so that any function can become a summation function.
Here is the Madhava-Leibniz function for pi:

Here’s how we can define the inner function:
Func<Int32, Double> f = k => 4 * (Math.Pow(-1, k) / ((2.0 * k) + 1));
What we want to be able to do is call f.Sum(). This will generate a summation function that calculates pi. Here’s how we accomplish that task.
public static Func<Int32, Double> Sum(this Func<Int32, Double> func, int start = 0)
{
return end =>
{
Double result = default(Double);
for (int k = start; k <= end; k++)
{
result += func(k);
}
return result;
};
}
We need to accumulate the results of every pass into the function. The resulting summation function will still require a parameter representing the upper bound. This is because we actually do need to return at some point in time to inspect the result.
Here’s the test to prove this works.
[TestMethod]
public void Pi()
{
Func<Int32, Double> f = k => 4 * (Math.Pow(-1, k) / ((2.0 * k) + 1));
var calculatePi = f.Sum();
Assert.AreEqual(3.14159, calculatePi(200000), 7);
}
With 200,000 passes, we can ensure an accuracy of 7. Leibniz didn’t rediscover the most efficient way of calculating pi, but it works for a test of the Sum extension method.
If we switch context to VB, we can even use this with a query expression! A couple of things. 1) VB 10 has a bug and can’t handle the optional parameter… change it to a traditional overload and 2) we need a Cast method.
I’ll let you figure out how to make a traditional overload. The cast method won’t actually do anything (because it will break the function), but we need it because the query expression will try to use it.
public static Func<T, TResult> Cast<TCast, T, TResult>(this Func<T, TResult> func)
{
return func;
}
Here’s the VB test that uses LINQ!
<TestMethod()>
Public Sub Pi()
Dim f As Func(Of Integer, Double) = Function(k) 4 * (Math.Pow(-1, k) / ((2.0 * k) + 1))
Dim calculatePi = Aggregate x In f Into Sum()
Assert.AreEqual(3.14159, calculatePi(200000), 7)
End Sub
I think it’s easier to just call f.Sum(), but this should give you a taste of where I will be taking things with future articles.
Download the source code from CodePlex!