Exponential Moving Average with different kernels - c#

I am trying to replicate some formulas but am having trouble translating the math to code.
Here is the simple Exponential Moving Average
In c#:
out[1] = values[1];
for (i in 2:N(X)) {
tmp = (times[i] - times[i-1]) / tau;
w = exp(-tmp);
w2 = (1 - w) / tmp;
out[i] = out[i-1] * w + values[i] * (1 - w2) + values[i-1] * (w2 - w);
}
In Python:
mu = numpy.exp ((ts[1] - ts[0]) / self.tau)
nu = 1.0 - mu
return numpy.array ([
mu * el + nu * arr[0] for el, arr in zip (last, arrays)
])
I want to be able to specify different kernels and am not sure how to go about it as described here:
This is all done so I can eventually recreate this moving differential given here:
Thanks for any help given

One possible approach here is to have a method that returns the kernel.
From what I am able to see, inputs to this method would be kerneltype, i, and otherInputs.
A simple approach would be:
for(int i = 1; i < values.length(); i++)
{
tmp = (times[i] - times[i-1]) / tau;
//w = exp(-tmp);
//w2 = (1 - w) / tmp;
List<Object> kernelInputsInital = new List<Object>();
kernelInputsInitial.Add(tmp); //takes in the first argument
kernelInputsInitial.Add(true); //expected to calculate the first
w = GetKernel(KernelType.Exponential, i, kernelInputsInitial);
List<Object> kernelInputsSecondTerm = new List<Object>();
kernelInputsSecondTerm.Add(w); //takes in the first argument
kernelInputsSecondTerm.Add(false); //expected to calculate the first
w2 = GetKernel(KernelType.Exponential, i, kernelInputsInitial);
out[i] = out[i-1] * w + values[i] * (1 - w2) + values[i-1] * (w2 - w);
....
}
This is of course terribly, terribly rough, and a lot of improvement can be made, but it is intended to merely get the point across.
I would use an interface to represent a kernel, and have classes derived per kernel. In my experience, that produces sufficiently readable and maintainable code, but there's always room for improvement.

Related

C# trigonometric functions / math functions

I'm writing a class which should calculate angles (in degrees), after long trying I don't get it to work.
When r = 45 & h = 0 sum should be around 77,14°
but it returns NaN - Why? I know it must be something with the Math.Atan-Method and a not valid value.
My code:
private int r = 0, h = 0;
public Schutzwinkelberechnung(int r, int h)
{
this.r = r;
this.h = h;
}
public double getSchutzwinkel()
{
double sum = 0;
sum = 180 / Math.PI * Math.Atan((Math.Sqrt(2 * h * r - (h * h)) - r * Math.Sin(Math.Asin((Math.Sqrt(2 * h * r)) / (2 * r)))) / (h - r + r * (Math.Cos(Math.Asin(Math.Sqrt(2 * h * r) / (2 * r))))));
return sum;
}
Does someone see my mistake? I got the formula from an excel sheet.
EDIT: Okay, my problem was that I had a parsing error while creating the object or getting the user input, apparently solved it by accident. Ofc I have to add a simple exception, as Nick Dechiara said. Thank you very much for the fast reply, I appreciate it.
EDIT2: The exception in my excel sheet is:
if(h < 2) {h = 2}
so that's explaining everything and I wasn't paying attention at all. Thanks again for all answers.
int r = 45, h = 2;
sum = 77.14°
A good approach to debugging these kinds of issues is to break the equation into smaller pieces, so it is easier to debug.
double r = 45;
double h = 0;
double sqrt2hr = Math.Sqrt(2 * h * r);
double asinsqrt2hr = Math.Asin((sqrt2hr) / (2 * r));
double a = (Math.Sqrt(2 * h * r - (h * h)) - r * Math.Sin(asinsqrt2hr));
double b = (h - r + r * (Math.Cos(asinsqrt2hr)));
double sum = 180 / Math.PI * Math.Atan(a / b);
Now if we put a breakpoint at sum and let the code run, we see that both a and b are equal to zero. This gives us a / b = 0 / 0 = NaN in the final line.
Now we can ask, why is this happening? Well in the case of b you have h - r + r which is 0 - 45 + 45, evaluates to 0, so b becomes 0. You probably have an error in your math there.
In the case of a, we have 2 * h * r - h * h, which also evaluates to 0.
You probably either A) have an error in your equation, or B) need to include a special case for when h = 0, as that is breaking your math here.
Definitely break up the expression something like
var a = Asin(Sqrt(2 * h * r) / (2 * r));
var b = Sqrt(2 * h * r - h * h) - r * Sin(a);
var c = h - r + r * Cos(a);
var sum = 180 / PI * Atan(b / c);
and you will find b=0 and c=0. You might consider changing the last expression into
var sum = 180 / PI * Atan2(b , c);
which will return a value when b=0 and c=0.
PS. Also, use using static System.Math; in the beginning of the code to shorten such math expressions.

I can't write a complex equation in code

I have been trying to turn this one conplex equation into code and it appears that I might have done something wrong. Here's the image of the equation:
Here's is the first code I tried using to convert the equation into code.
double answer = 1 - (Math.Pow(f, n) * ((s * l / f) + Math.Pow((20 / f), w) / Math.Pow(20, n)));
Here is the code that I used in my second attempt:
double answer = 1 - Math.Pow(f, n) * ((s * l) / f) + Math.Pow((20 / f), w) / Math.Pow(20, n);
If I assume that every variable of the equation is 2, than I get -.02. But when I ran the code, the first attempt code returned a value of -8, while the second attempt returned -6.75.
Is there anything I'm doing wrong in my code right now? And also sorry if I'm bad at explaining stuffs.
I tested this out and got the result of -0.02. Try splitting up the code to make it more legible. It might help you diagnose the syntax of your complex equation on one line.
double f = 2;
double n = 2;
double s = 2;
double w = 2;
double l = 2;
double A = Math.Pow(f, n);
double B = (s * l) / f;
double C = Math.Pow((20 / f), w);
double bottom = Math.Pow(20, n);
double top = A * (B + C);
double answer = 1 - top / bottom;
In both attempts you just got your brackets in the wrong spot.
Try this:
double answer =
1 - Math.Pow(f, n) * (s * l / f + Math.Pow((20 / f), w)) / Math.Pow(20, n);
Try to use the formula below instead :
double answer = (1 - Math.pow((Math.pow(f,n)*[s*l/f+20/f})),w)/Math.pow(20,f)

How to calculate the points between two given points and given distance?

I have point A (35.163 , 128.001) and point B (36.573 , 128.707)
I need to calculate the points lies within point A and point B
using the standard distance formula between 2 points, I found D = 266.3
each of the points lies within the line AB (the black point p1, p2, ... p8) are separated with equal distance of d = D / 8 = 33.3
How could I calculate the X and Y for p1 , p2, ... p8?
example of Java or C# language are welcomed
or just point me a formula or method will do.
Thank you.
**The above calculation is actually used to calculate the dummy point for shaded level in my map and working for shaded area interpolation purpose*
that's easy but you need some math knowledge.
PointF pointA, pointB;
var diff_X = pointB.X - pointA.X;
var diff_Y = pointB.Y - pointA.Y;
int pointNum = 8;
var interval_X = diff_X / (pointNum + 1);
var interval_Y = diff_Y / (pointNum + 1);
List<PointF> pointList = new List<PointF>();
for (int i = 1; i <= pointNum; i++)
{
pointList.Add(new PointF(pointA.X + interval_X * i, pointA.Y + interval_Y*i));
}
Straitforward trigonometric solution could be something like that:
// I've used Tupple<Double, Double> to represent a point;
// You, probably have your own type for it
public static IList<Tuple<Double, Double>> SplitLine(
Tuple<Double, Double> a,
Tuple<Double, Double> b,
int count) {
count = count + 1;
Double d = Math.Sqrt((a.Item1 - b.Item1) * (a.Item1 - b.Item1) + (a.Item2 - b.Item2) * (a.Item2 - b.Item2)) / count;
Double fi = Math.Atan2(b.Item2 - a.Item2, b.Item1 - a.Item1);
List<Tuple<Double, Double>> points = new List<Tuple<Double, Double>>(count + 1);
for (int i = 0; i <= count; ++i)
points.Add(new Tuple<Double, Double>(a.Item1 + i * d * Math.Cos(fi), a.Item2 + i * d * Math.Sin(fi)));
return points;
}
...
IList<Tuple<Double, Double>> points = SplitLine(
new Tuple<Double, Double>(35.163, 128.001),
new Tuple<Double, Double>(36.573, 128.707),
8);
Outcome (points):
(35,163, 128,001) // <- Initial point A
(35,3196666666667, 128,079444444444)
(35,4763333333333, 128,157888888889)
(35,633, 128,236333333333)
(35,7896666666667, 128,314777777778)
(35,9463333333333, 128,393222222222)
(36,103, 128,471666666667)
(36,2596666666667, 128,550111111111)
(36,4163333333333, 128,628555555556)
(36,573, 128,707) // <- Final point B
Subtract A from B, component-wise, to get the vector from A to B. Multiply that vector by the desired step value and add it to A. (Note that with eight intermediate steps as you've illustrated, the step distance is 1.0 / 9.0.) Something like this, assuming you really want seven points:
vec2 A = vec2 (35.163, 128.001);
vec2 B = vec2 (36.573, 128.707);
vec2 V = B - A;
for (i = 1; i < 8; i++) {
vec2 p[i] = A + V * (float)i / 8.0;
}
(Sorry, don't know any Java or C#.)
let A be point (xa, ya), and B be point (xb, yb)
alpha = tan-1((yb - ya)/(xb - xa))
p1 = (xa + d * cos(alpha), ya + d * sin(alpha))
pk = (xa + kd * cos(alpha), ya + kd * sin(alpha)), k = 1 to 7
(An equivalent way would be to use vector arithmetic)
At first find the slope of AB line. Get help and formula from here: http://www.purplemath.com/modules/slope.htm
Then consider a triangle of Ap1E(think there is a point E which is right to A and below to p1).
You already know the angle AEp1 is 90degree. and you have calculated angle p1AE(from the slope of AB).
Now find AE and Ep1.
Xp1=Xa+AE and Yp1=Ya+Ep1
This will not be very difficult in C# or java.
Once you understand the logic, you will find pleasure implementing on your own way.

Which way is more accurate?

I need to divide a numeric range to some segments that have same length. But I can't decide which way is more accurate. For example:
double r1 = 100.0, r2 = 1000.0, r = r2 - r1;
int n = 30;
double[] position = new double[n];
for (int i = 0; i < n; i++)
{
position[i] = r1 + (double)i / n * r;
// position[i] = r1 + i * r / n;
}
It's about (double)int1 / int2 * double or int1 * double / int2. Which way is more accurate? Which way should I use?
Update
The following code will show the difference:
double r1 = 1000.0, r2 = 100000.0, r = r2 - r1;
int n = 300;
double[] position = new double[n];
for (int i = 0; i < n; i++)
{
double v1 = r1 + (double)i / n * r;
double v2 = position[i] = r1 + i * r / n;
if (v1 != v2)
{
Console.WriteLine(v2 - v1);
}
}
Disclaimer: All numbers I am going to give as examples are not exact, but show the principle of what's happening behind the scenes.
Let's examine two cases:
(1) int1 = 1000, int2= 3, double = 3.0
The first method will give you: (1000.0 / 3) * 3 == 333.33333 * 3.0 == 999.999...
While the second will give (1000 * 3.0) / 3 == 3000 / 3 == 1000
In this scenario - the second method is more accurate.
(2) int1 = 2, int2 = 2, double = Double.MAX_VALUE
The first will yield (2.0 / 2) * Double.MAX_VALUE == 1 * Double.MAX_VALUE == Double.MAX_VALUE
While the second will give (2 * Double.MAX_VALUE) / 2 - which will cause (in Java) to be Infinity, I am not sure what the double standard says about this cases, if it might overflow or is it always infinity - but it is definetly an issue.
So, in this case - the first method is more accurate.
The things might go more complicated if the integers are longs or the double is float, since there are long values that cannot be represented by doubles, so loss of accuracy might happen for large double values in this case, and in any case - large double values are less accurate.
Conclusion: Which is better is domain specific. In some cases the first method should be better and in some the first. It really depends on the values of int1,int2, and double.
However- AFAIK, the general rule of thumb with double precision ops is keep the calculations as small as possible (Don't create huge numbers and then decrease them back, keep them small as longest as you can). This issue is known as loss of significant digits.
Neither is particularly faster, since the compiler or the JIT process may reorder the operation for efficiency anyway.
Maybe I misunderstand your requirement but why do any division/multiplication inside the loop at all? Maybe this would get the same results:
decimal r1 = 100.0m, r2 = 1000.0m, r = r2 - r1;
int n = 30;
decimal[] position = new double[n];
decimal diff = r / n;
decimal current = r1;
for (int i = 0; i < n; i++)
{
position[i] = current;
current += diff;
}

.NET math calculation performances

I asked a question about having the Excel's BetaInv function ported to .NET: BetaInv function in SQL Server
now I managed to write that function in pure dependency less C# code and I do get the same results than in MS Excel up to 6 or 7 digits after comma, results are fine for us, the problem is that such code is embedded in a SQL CLR Function and gets called thousands of time from a stored procedure and makes the execution of the whole procedure about 50% slower, from 30 seconds up to a minute if I use that function or not.
here some code of it, I am not asking a deep analysis but is there anybody who sees any major performance issue in the way I am doing this calculations? like for example usage of other data types instead of doubles or whatsoever... ?
private static double betacf(double a, double b, double x)
{
int m, m2;
double aa, c, d, del, h, qab, qam, qap;
qab = a + b;
qap = a + 1.0;
qam = a - 1.0;
c = 1.0; // First step of Lentz’s method.
d = 1.0 - qab * x / qap;
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
d = 1.0 / d;
h = d;
for (m = 1; m <= MAXIT; ++m)
{
m2 = 2 * m;
aa = m * (b - m) * x / ((qam + m2) * (a + m2));
d = 1.0 + aa * d; //One step (the even one) of the recurrence.
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
c = 1.0 + aa / c;
if (System.Math.Abs(c) < FPMIN)
{
c = FPMIN;
}
d = 1.0 / d;
h *= d * c;
aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
d = 1.0 + aa * d; // Next step of the recurrence (the odd one).
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
c = 1.0 + aa / c;
if (System.Math.Abs(c) < FPMIN)
{
c = FPMIN;
}
d = 1.0 / d;
del = d * c;
h *= del;
if (System.Math.Abs(del - 1.0) < EPS)
{
// Are we done?
break;
}
}
if (m > MAXIT)
{
return 0;
}
else
{
return h;
}
}
private static double gammln(double xx)
{
double x, y, tmp, ser;
double[] cof = new double[] { 76.180091729471457, -86.505320329416776, 24.014098240830911, -1.231739572450155, 0.001208650973866179, -0.000005395239384953 };
y = xx;
x = xx;
tmp = x + 5.5;
tmp -= (x + 0.5) * System.Math.Log(tmp);
ser = 1.0000000001900149;
for (int j = 0; j <= 5; ++j)
{
y += 1;
ser += cof[j] / y;
}
return -tmp + System.Math.Log(2.5066282746310007 * ser / x);
}
The only thing that stands out for me, and is usually a performance hit, is memory allocation. I don't know how often gammln is called but you might want to move the double[] cof = new double[] {} to a static one time only allocation.
double is usually the best type. Especially since the functions in Math take doubles. Unfortunately I see no obvious improvements to make on your code.
It might be possible to use look up tables to get a better first estimate on which you iterate, but since I don't know the Math behind what you're doing I don't know if that's possible in this specific case.
Obviously larger epsilons will improve performance. So choose it as large as possible while fulfilling your accuracy demands.
If the function gets called repeatedly with the same parameters you might be able to cache results.
One thing that looks odd is the way you force small values for c, d,... to FPMIN. My instinct is that this might lead to suboptimal step sizes.
All I've got is unrolling the j loop in gammln, but it'll make at most a tiny difference.
A more radical thought would be to rewrite in pure T-SQL, since it has everything you use: + - * / abs log are all available.

Categories

Resources