I am trying to implement Simpson's Rule using the math.net numerics library. The method that I would like to use takes four arguments, a Func (function pointer), intervalBegin, intervalEnd and partitionNumbers. Currently I am testing the method using Math.Sin, but can someone help me to understand how this Func should be implemented?
var test = MathNet.Numerics.Integration.SimpsonRule.IntegrateComposite(Math.Sin, 1, 4, 20);
Additional material:
Pic taken directly from math is fun.
You can have absolutely any mathematical function like the one char below represents.
Integration calculates area between the line that function draws and X axis.
The reason I say function you pass into Simpsons integration doesn't matter is because ANY function can be used as long as it fits "1 number in, 1 number out" format.
End of additional material.
Simpson's formula is an integration which means it needs a mathematical function to calculate with. Below is the rough formula of simpson's integration (using numbers you passed as arguments and a random function) if you are interested, if not skip this part .
intervalBegin = 1;
intervalEnd = 4;
partitionNumbers = 20;
f(x) = 3x^2;
deltaX = (intervalEnd - intervalBegin) / partitionNumbers;
SimpsonsIntegration = deltaX/3 * (f(intervalBegin) + 4*f(intervalBegin + deltaX*1)+ 2*f(intervalBegin + deltaX*2)+ 4*f(intervalBegin + deltaX*3)+ 2*f(intervalBegin + deltaX*4).....+4*f(intervalBegin + deltaX*19) +f(intervalEnd);
The function in Simpsons integration is ANY function that takes 1 numeric argument and returns one. (it might be type specific like float or double)
public double anyFunction(double number){
double result = [calculations];
return calculations;
}
Your call could look like this:
MathNet.Numerics.Integration.SimpsonRule.IntegrateComposite(anyFunction, 1, 4, 20);
Related
So I've got a nice convoluted piece of C# code that deals with substitution into mathematical equations. It's working almost perfectly. However, when given the equation (x - y + 1) / z and values x=2 y=0 z=5, it fails miserably and inexplicably.
The problem is not that the values are passed to the function wrong. That's fine. The problem is that no matter what type I use, C# seems to think that 3/5=0.
Here's the piece of code in question:
public static void TrapRule(string[] args)
{
// ...
string equation = args[0];
int ordinates = Convert.ToInt32(args[1]);
int startX = Convert.ToInt32(args[2]);
int endX = Convert.ToInt32(args[3]);
double difference = (endX - startX + 1) / ordinates;
// ...
}
It gets passed args as:
args[0] = Pow(6,[x])
args[1] = 5
args[2] = 0
args[3] = 2
(Using NCalc, by the way, so the Pow() function gets evaluated by that - which works fine.)
The result? difference = 0.
The same thing happens when using float, and when trying simple math:
Console.Write((3 / 5));
produces the same result.
What's going on?
The / operator looks at its operands and when it discovers that they are two integers it returns an integer. If you want to get back a double value then you need to cast one of the two integers to a double
double difference = (endX - startX + 1) / (double)ordinates;
You can find a more formal explanation in the C# reference
They're called integers. Integers don't store any fractional parts of a number. Moreover, when you divide an integer divided by another integer... the result is still an integer.
So when you take 3 / 5 in integer land, you can't store the .6 result. All you have left is 0. The fractional part is always truncated, never rounded. Most programming languages work this way.
For something like this, I'd recommend working in the decimal type, instead.
What is the best way to test something that does not equal exact values, like the great circle calculation:
/// <summary>
/// Get the great circle distance (shortest distance possible) between two points in km.
/// </summary>
/// <param name="endPoint">end point</param>
/// <returns>the great circle distance in km</returns>
public double GreatCircleDistanceInKm(IGeoPoint endPoint)
{
var earthRadius = Constants.EARTH_RADIUS_KM;
var diffLat = Utility.DegreesToRadians(endPoint.Latitude - this.Latitude);
var diffLong = Utility.DegreesToRadians(endPoint.Longitude - this.Longitude);
var a = Math.Sin(diffLat / 2) * Math.Sin(diffLat / 2) +
Math.Cos(Utility.DegreesToRadians(this.Latitude)) * Math.Cos(Utility.DegreesToRadians(endPoint.Latitude)) *
Math.Sin(diffLong / 2) * Math.Sin(diffLong / 2);
var c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
var d = earthRadius * c;
return d;
}
Currently my test is like this:
[TestMethod]
public void GeoPoint_GreatCircleDistanceInKm_IsCorrect()
{
// arrange
var startPoint = new GeoPoint(0, 45, 90); // id, lat, long
var endPoint1 = new GeoPoint(0, 45, 90);
var endPoint2 = new GeoPoint(0, 0, 0);
// act
var greatCircleDistanceZero = startPoint.GreatCircleDistanceInKm(endPoint1);
var greatCircleDistanceBig = startPoint.GreatCircleDistanceInKm(endPoint2);
// assert
Assert.AreEqual(0, greatCircleDistanceZero);
Assert.AreEqual(10007.543398010288, greatCircleDistanceBig);
}
But this seems wrong, I am finding the answer first then testing against it. How should such methods be tested? Should I go through the algorithm/calculation and try and find out how it works, so I can make it result in exact values?
Clarification:
My question is this the correct method of conducting a test for such things, ie. Should my test bound to the actual implementation (because as you see I am using a fine-grained expected value) or should it be more generic somehow?
You can use Assert.AreEqual(double expected, double actual, double delta). You should use a delta that is sufficiently small (e.g. 0.00000001). Using double.Epsilon isn't recommended here.
From MSDN:
Because Epsilon defines the minimum expression of a positive value whose range is near zero, the margin of difference between two similar values must be greater than Epsilon. Typically, it is many times greater than Epsilon. Because of this, we recommend that you do not use Epsilon when comparing Double values for equality.
To your other questions: Yes, such methods should be tested. But it is not a good idea to write tests after you inspected how the algorithm is implemented, because it may be implemented wrong. You need an overall idea what for example the method should be doing (in your case calculating the greate circle distance). Now you can specify test cases by specifying the input and the expected output. You can retrieve the expected output from another source (e.g. calculating it by hand).
A little side note: In TDD test cases are usually specified before the actual code is written. So there is no algorithm you can go through and find out how it works.
Maybe
Assert.IsTrue(Math.Abs(greatCircleDistanceZero - 0) < Double.Epsilon);
Assert.IsTrue(Math.Abs(greatCircleDistanceBig - 10007.543398010288) < Double.Epsilon);
The following table shows the distance between 2 points on the equator. As the latitude moves from the poles the NS distance is constant but EW distance decreases. As I assume using Great Circle Distance any accuracy greater than 2 decimal places in your results is redundant.
0 decimal places 1.0 = 111.32 km
1 decimal places 0.1 = 11.132 km
2 decimal places 0.01 = 1.1132 km
3 decimal places 0.001 = 111.32 m
4 decimal places 0.0001 = 11.132 m
5 decimal places 0.00001 = 1.1132 m
I have a grid of data points that I currently use Bilinear interpolation on to find the missing points in the grid. I was pointed in the directions of Kriging aka thee best linear unbiased estimator, but I was unable to find good source code or an algebraic explanation. Does anyone know of any other interpolation methods I could use?
--Update
#Sam Greenhalgh
I have considered Bicubic Interpolation but the results I received using the code example I found seemed off.
Here is the code example for Bicubic
Note I am coding in C# but I welcome examples from other languages as well.
//array 4
double cubicInterpolate(double[] p, double x)
{
return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
}
//array 4 4
public double bicubicInterpolate(double[][] p, double x, double y)
{
double[] arr = new double[4];
arr[0] = cubicInterpolate(p[0], y);
arr[1] = cubicInterpolate(p[1], y);
arr[2] = cubicInterpolate(p[2], y);
arr[3] = cubicInterpolate(p[3], y);
return cubicInterpolate(arr, x);
}
double[][] p = {
new double[4]{2.728562594,2.30599759,1.907579158,1.739559264},
new double[4]{3.254756633,2.760758022,2.210417411,1.979012766},
new double[4]{4.075740069,3.366434527,2.816093916,2.481060234},
new double[4]{5.430966401,4.896723504,4.219613391,4.004306461}
};
Console.WriteLine(CI.bicubicInterpolate(p, 2, 2));
One widely-used interpolation method is kriging (or Gaussian process regression).
However, the use of kriging is not advised when your data points are on a regular grid. The euclidian distances between data points are used to adjust the parameters of the model. But in a grid, there are much fewer values of distance than in, say, a randomly simulated set of points.
Nevertheless, even if your data points are regularly placed, it could be interesting to give it a try. If you are interested, you can use the following softwares:
DiceKriging package in R language (there exist others like kriging, gstat...)
DACE toolbox in Matlab
STK in Matlab/Octave
And many others (in python for example)...
NOTE: It can be interesting to note (I do not exactly in what context you want to apply kriging) that the kriging interpolation property can very easily be relaxed in order to take into account, for example, possible measurement errors.
If your data points are on a regular grid, I would recommend using a piecewise linear spline in two dimensions. You could fill the data for the rows (x-values) first, then fill the data for the columns (y-values.)
Math.NET Numerics has the piecewise linear spline function that you would need:
MathNet.Numerics.Interpolation.LinearSpline.InterpolateSorted
I'm performing simple linear regression with Math.NET.
I provided a common code sample below. Alternative to this example one can use the Fit class for simple linear regression.
What I additionally want is to specify additional constraints like a fixed y-intercept or force the fit to run throug a fixed point, e.g. (2, 2). How to achieve this in Math.NET?
var xdata = new double[] { 10, 20, 30 };
var ydata = new double[] { 15, 20, 25 };
var X = DenseMatrix.CreateFromColumns(new[] {new DenseVector(xdata.Length, 1), new DenseVector(xdata)});
var y = new DenseVector(ydata);
var p = X.QR().Solve(y);
var a = p[0];
var b = p[1];
You can modify your data set to reflect the constraint , and then use the standard math.Net linear regression
if (x0,y0) is the point through which the regression line must pass,
fit the model y−y0=β(x−x0)+ε, i.e., a linear regression with "no
intercept" on a translated data set.
see here : https://stats.stackexchange.com/questions/12484/constrained-linear-regression-through-a-specified-point
and here : http://en.wikipedia.org/wiki/Linear_least_squares_(mathematics)#Constrained_linear_least_squares
First of all, it you want to force the regression through the origin, you can use LineThroughOrigin or alternativelly LineThroughOriginFunc if what you want is the function itself.
To force the regression to have a desired intercept, I would perform a normal linear regression and get the intercept and slope (knowing these you know everything about your linear function).
With this information, you can compensate the intercept, for example:
If you made your regression in which
intercept = 2
slope = 1
Then you know that your equation would be y = x + 2.
If you want the same function to cross the y axis in 3 (y = x + 3), you would just need to add 1 to the intercept so that
intercept = 3
slope = 1
I'm trying to use the .Net Chart object to interactively define a spline function that I use to map from one range of values to another. In other words, I have a 0-4095 range (x axis) that I want to convert to a 0-100 range (y axis) using a spline. I've successfully set up a chart that plots a spline through a group of points. The user can interactively move the points to get the desired function shape. Works great.
Now...once I have the spline like the user wants, how can I (using the spline function), find the corresponding y value for any x value?
I can't seem to find a way to do that. I know that the chart object is doing the calculation somewhere since it's plotting the spline...maybe they don't provide access to that.
The alternative is to make the spline calculations myself...I don't want to go there unless absolutely necessary.
Thanks.
Bryan
You need to find the value of "t" (tension parameter) that produces the desired value of x. if you are using the range of 0 to 1 the parameter "t" value will be somewhere near to 0.5. Once you know t you can calculate the corresponding value of y. Solve a cubic equation which will generate 3 values for "t" that will result in same value of x. Check the link below.
http://algorithmist.wordpress.com/2009/09/28/cardinal-splines-part-2/
Cardinal splines specify the tangents at interior points based on the vector from previous point to subsequent point. Each tangent is parallel to this vector and some multiple of its length. For example, the tangent direction at point P1 is parallel to the vector P2 – P0, or we could simply write something like T1 = s(P2 – P0) where s is a real number.
Check this part of code below where xtarget is the input value x.
Code:
for (Double t = 0; t<=1; t += 0.01)
{
s = (1 - t) / 2;
P(t)x = s(-t3 + 2t2 – t)P1X + s(-t3 + t2)P2X + (2t3 – 3t2 + 1)P2X + s(t3 – 2t2 + t)P3X + (-2t3 + 3t2)P3X + s(t3 – t2)P4X
P(t)y = s(-t3 + 2t2 – t)P1Y + s(-t3 + t2)P2Y + (2t3 – 3t2 + 1)P2Y + s(t3 – 2t2 + t)P3Y+ (-2t3 + 3t2)P3Y + s(t3 – t2)P4Y
if(P(t)x=>xtarget)
{
return P(t)y;
}
}
The above method will give the approximate point P(t)y on the curve.