# Finding cosine inverse without standard functions



## xfire (Oct 1, 2009)

Anyone has any program or method to find the cosine inverse of a value without using the cos tables or cos-1 function? I'm trying to program an 8051 micro processor so in short a program to find cosine inverse in assembly language.


----------



## FordGT90Concept (Oct 1, 2009)

Line 17 has the formula here: http://mathworld.wolfram.com/InverseCosine.html


----------



## xfire (Oct 1, 2009)

That should do Thanks a lot.


----------



## xfire (Oct 1, 2009)

any idea what (1/2) subscript n-1 stands for? I'm not able to figure out that part. It doesn't fit.
Edit: got it! that's (2 power n)-1. Thanks


----------



## W1zzard (Oct 1, 2009)

use a lookup table


----------



## xfire (Oct 1, 2009)

W1zzard said:


> use a lookup table



Like i mentioned without tables. I would have to program the entire table into the program. Waste of memory+size+time.


----------



## W1zzard (Oct 1, 2009)

check how many bytes your compiled code uses, vs. how many bytes your LUT uses. also look at cpu time


----------



## xfire (Oct 1, 2009)

I see the point, will let you know the difference in memory and time once code is completed in both. LUT is faster but formula is shorter and accurate.


----------



## W1zzard (Oct 1, 2009)

i doubt it is shorter, what kind of values are you working with ? int ?


----------



## xfire (Oct 1, 2009)

It doesn't have to be considered from 1 to infinity. as n tends to infinity the higher order terms can be ignored as they are very small. So you can consider up to say n=4 then the program is(in c cause i can do it faster)


> #include<stdio.h>
> #include<math.h>
> main()
> {
> ...


doing that in assembly could take a while.


----------



## W1zzard (Oct 1, 2009)

you use only integer values ? or floating point too? (in the microcontroller)


----------



## xfire (Oct 1, 2009)

It's only integer but can be manipulated into a float by dividing 8 bits into 4 bits for integer part and 4 bits for decimal. Works only with the input post which is bit addressable.


----------



## Tatty_One (Oct 1, 2009)

This is the site i use for all those "difficult" calculations...........

http://www.online-calculators.co.uk/functions/mathsfunctions.php


----------



## FordGT90Concept (Oct 1, 2009)

That site uses JavaScript functions (Math.cos, Math.acos, etc.).  It doesn't help much when those aren't available.


----------



## xfire (Oct 2, 2009)

I have a calculator that does all this. 
http://edu.casio.com/products/ntd/fx991es/
That's why I'm sure it can be programmed. Just need to get down to it.


----------



## qamulek (Oct 2, 2009)

I found this explanation of how to calculate a sine/cosine function to be interesting.  A quick glance shows that they are using multiple rotations of the vector (1,0) till the angle of the final rotation is close enough to the angle of the desired rotation.  Inside the description is a method that does this very fast, but I don't really understand that part fully yet(its late , i'm going to sleep, also I really don't care about it at this time).  

The interesting thing though is that a similar method can be used to find the inverse cosine.  First for simplicity assume the angle lies between 0 and Pi/2.  Take the initial vector at (1,0).  The idea is that at each iteration if the x component of the vector is larger then the given cosine(the input) then the vector is rotated counter clockwise, otherwise the vector is rotated clockwise.  Each iteration uses a rotation that is half as small as the previous rotation(the first rotation being Pi/4-counter clockwise), and the angle the vector is rotated must be kept track of as its the desired output(+ for counter clockwise rotations, -for clockwise rotations).  Do as many iterations as you want accuracy(considering round off errors, and that without using the techniques mentioned in that link that you would have to precalculate the cos(Pi/(2^n)) and sin(Pi/(2^n)) for a max of n-1 iterations), however I think you must also consider the problems of accuracy using integers for each method.

TBH I think a look up table using both the value for cos-1 as well as the first two derivatives of cos-1 for a second order series would be the easiest way to go.  Oh wait.....  I just looked and cos-1(x) is -1/sqrt(1-x^2) which goes to to -infinity as it approaches 1   Did a quick plot of the second order approximation compared to the cos-1 and found that the approximation itself doesn't last very long as the approximation is brought near 1.  At x0=.995 I found the approximation lasts reasonably till x=.9975.  At x0=.998 the approximation only lasted till about x=.999.  The rotation method is starting to look *A LOT* faster considering the singularity of the derivative of cos-1(x) at x=1.

EDIT:  In that link figure out wth those techniques are to speed up the rotations.  I can see how the method itself is sound, but using those techniques to speed up the rotations are probably very important(unless you don't care about speed).
EDIT#2:  The error(not including round off error) for the rotations method goes something like Pi/(2^(n+1)) where n is the number of iterations(n=1 being the Pi/4 rotation).  A method that converges that fast would be hard to pass up.


----------



## xfire (Oct 2, 2009)

qamulek said:


> I found this explanation of how to calculate a sine/cosine function to be interesting.  A quick glance shows that they are using multiple rotations of the vector (1,0) till the angle of the final rotation is close enough to the angle of the desired rotation.  Inside the description is a method that does this very fast, but I don't really understand that part fully yet(its late , i'm going to sleep, also I really don't care about it at this time).
> 
> The interesting thing though is that a similar method can be used to find the inverse cosine.  First for simplicity assume the angle lies between 0 and Pi/2.  Take the initial vector at (1,0).  The idea is that at each iteration if the x component of the vector is larger then the given cosine(the input) then the vector is rotated counter clockwise, otherwise the vector is rotated clockwise.  Each iteration uses a rotation that is half as small as the previous rotation(the first rotation being Pi/4-counter clockwise), and the angle the vector is rotated must be kept track of as its the desired output(+ for counter clockwise rotations, -for clockwise rotations).  Do as many iterations as you want accuracy(considering round off errors, and that without using the techniques mentioned in that link that you would have to precalculate the cos(Pi/(2^n)) and sin(Pi/(2^n)) for a max of n-1 iterations), however I think you must also consider the problems of accuracy using integers for each method.
> 
> ...


It's gone way over my head. It'll take me some time to understand but thanks


----------



## qamulek (Oct 2, 2009)

xfire said:


> It's gone way over my head. It'll take me some time to understand but thanks



It goes faster if you ask questions.  For instance I started writing a bunch of stuff about how you can calculate a sine/cosine by rotating the vector (1,0), but then I realized that most likely is not what you are having trouble understanding.

I read that link again this morning and found that for sine/cosine they were able to reduce the rotations to a bit shift and add operation at each iteration, and a final multiplication by essentially a constant.  Since a cos-1 function would need the value of the cosine at each iteration you would need the full bit shift, add operation, *and multiplication* for every iteration.

Before starting with the cos-1() you should probably start with trying to do cos() using the method in that link.  You can hammer out the problems of round off due to using integers while building the cos function, then tweak it a bit to make the cos-1 function.


----------

