FraserOfSmeg
FraserOfSmeg

Reputation: 1148

Optimisation of Law of Cosines in VB.net

I'm using the law of cosines in a program and it seems to be a slow point of my code. This is the line of code I have:

Ans = Math.Sqrt(A ^ 2 + B ^ 2 - 2 * A * B * Math.Cos(C - D))

Where A to D are double variables that change every time called. This function seems to take around 2000 ticks to run. I've looked at using the small angle approximation which is where if (C-D) is small enough you can use cos(C-D) = 1 - ((C-D)^2)/2. Unfortunately this turned out to be slower overall than the original code. I've looked at any sort of relationship that can be used to simplify the calculation but A and C are related in a complex way and B and D are related in the same way, there's no relationship between A and B or between C and D.

I've thought about using a lookup function for all the values of (C-D) but my accuracy is currently to at least 6 significant figures and I would prefer to stay at that level as that's the accuracy of my input data, in short this means around a million vaules in the look up and this is only 1 section of the function. I've thought about having a look up for all four values (A, B, C and D) but I'm not sure how to implement that.

I've also already multithreaded this application and attempted use of GPGPU (GPGPU ended up being slower due to the time spent loading in and out of GPU memory).

So, my question is how do I speed up this function.

Thanks in advanced!

Upvotes: 2

Views: 373

Answers (1)

Rob
Rob

Reputation: 3853

The following runs in less than 1/3 the time

ans = Math.Sqrt(a * a + b * b - 2 * a * b * Math.Cos(c - d))

Here's the code that proves it:

    Dim sw1 As New Stopwatch
    Dim sw2 As New Stopwatch

    Dim ans, a, b, c, d As Double
    a = 5
    b = 10
    c = 4
    d = 2

    sw1.Start()
    For x As Integer = 1 To 10000
        ans = Math.Sqrt(a ^ 2 + b ^ 2 - 2 * a * b * Math.Cos(c - d))
    Next
    sw1.Stop()

    sw2.Start()
    For y As Integer = 1 To 10000
        ans = Math.Sqrt(a * a + b * b - 2 * a * b * Math.Cos(c - d))
    Next
    sw2.Stop()

    Console.WriteLine(sw1.ElapsedTicks)
    Console.WriteLine(sw2.ElapsedTicks)

    Console.WriteLine(sw2.ElapsedTicks * 100 / sw1.ElapsedTicks)

Upvotes: 3

Related Questions