Numerical integration: Difference between revisions

Content added Content deleted
(Removed useless function f4 from the D code)
(Added C# implementation.)
Line 586:
}
}</lang>
=={{header|C sharp|C#}}==
<lang csharp>using System;
using System.Collections.Generic;
using System.Linq;
 
public class Interval
{
public Interval(double leftEndpoint, double size)
{
LeftEndpoint = leftEndpoint;
RightEndpoint = leftEndpoint + size;
}
 
public double LeftEndpoint
{
get;
set;
}
 
public double RightEndpoint
{
get;
set;
}
 
public double Size
{
get
{
return RightEndpoint - LeftEndpoint;
}
}
 
public double Center
{
get
{
return (LeftEndpoint + RightEndpoint) / 2;
}
}
 
public IEnumerable<Interval> Subdivide(int subintervalCount)
{
double subintervalSize = Size / subintervalCount;
return Enumerable.Range(0, subintervalCount).Select(index => new Interval(LeftEndpoint + index * subintervalSize, subintervalSize));
}
}
 
public class DefiniteIntegral
{
public DefiniteIntegral(Func<double, double> integrand, Interval domain)
{
Integrand = integrand;
Domain = domain;
}
 
public Func<double, double> Integrand
{
get;
set;
}
 
public Interval Domain
{
get;
set;
}
 
public double SampleIntegrand(ApproximationMethod approximationMethod, Interval subdomain)
{
switch (approximationMethod)
{
case ApproximationMethod.RectangleLeft:
return Integrand(subdomain.LeftEndpoint);
case ApproximationMethod.RectangleMidpoint:
return Integrand(subdomain.Center);
case ApproximationMethod.RectangleRight:
return Integrand(subdomain.RightEndpoint);
case ApproximationMethod.Trapezium:
return (Integrand(subdomain.LeftEndpoint) + Integrand(subdomain.RightEndpoint)) / 2;
case ApproximationMethod.Simpson:
return (Integrand(subdomain.LeftEndpoint) + 4 * Integrand(subdomain.Center) + Integrand(subdomain.RightEndpoint)) / 6;
default:
throw new NotImplementedException();
}
}
 
public double Approximate(ApproximationMethod approximationMethod, int subdomainCount)
{
return Domain.Size * Domain.Subdivide(subdomainCount).Sum(subdomain => SampleIntegrand(approximationMethod, subdomain)) / subdomainCount;
}
 
public enum ApproximationMethod
{
RectangleLeft,
RectangleMidpoint,
RectangleRight,
Trapezium,
Simpson
}
}
 
public class Program
{
private static void TestApproximationMethods(DefiniteIntegral integral, int subdomainCount)
{
foreach (DefiniteIntegral.ApproximationMethod approximationMethod in Enum.GetValues(typeof(DefiniteIntegral.ApproximationMethod)))
{
Console.WriteLine(integral.Approximate(approximationMethod, subdomainCount));
}
}
 
public static void Main()
{
TestApproximationMethods(new DefiniteIntegral(x => x * x * x, new Interval(0, 1)), 10000);
TestApproximationMethods(new DefiniteIntegral(x => 1 / x, new Interval(1, 99)), 1000);
TestApproximationMethods(new DefiniteIntegral(x => x, new Interval(0, 5000)), 500000);
TestApproximationMethods(new DefiniteIntegral(x => x, new Interval(0, 6000)), 6000000);
}
}</lang>
Output:
<lang>0.2499500025
0.24999999875
0.2500500025
0.250000002499999
0.25
4.65499105751468
4.60476254867838
4.55698105751468
4.60598605751468
4.60517038495713
12499975
12500000
12500025
12500000
12500000
17999997
18000000
18000003
18000000
18000000</lang>
=={{header|C++}}==