473,883 Members | 1,763 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Fast sincos routine

Hello,

Does anyone have any suggestions for where to find a good sincos
routine (i.e. a routine that calculates both the sin and cos of a
given argument) written in c?

Thanks,

Oc**********@ya hoo.com
Nov 14 '05
45 9441
Allan Bruce wrote:
but sqrt of a positive number can be positive or negative

e.g. sqrt(4) = +/- 2


But the result of the standard C library function sqrt(double) cannot.

It's not difficult to implement though to get the correct answer.


This is the comp.lang.c newsgroup.

Please show us the implementation in C.

Nov 14 '05 #11
"E. Robert Tisdale" wrote:
Allan Bruce wrote:
but sqrt of a positive number can be positive or negative

e.g. sqrt(4) = +/- 2

But the result of the standard C library function sqrt(double)
cannot.


It's not difficult to implement though to get the correct answer.


This is the comp.lang.c newsgroup.
Please show us the implementation in C.


You are not overly intelligent, are you?

negroot = -(posroot = sqrt(x));

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 14 '05 #12

"CBFalconer " <cb********@yah oo.com> wrote in message
news:40******** *******@yahoo.c om...
"E. Robert Tisdale" wrote:
Allan Bruce wrote:
> but sqrt of a positive number can be positive or negative
>
> e.g. sqrt(4) = +/- 2

But the result of the standard C library function sqrt(double)
cannot.

It's not difficult to implement though to get the correct answer.


This is the comp.lang.c newsgroup.
Please show us the implementation in C.


You are not overly intelligent, are you?

negroot = -(posroot = sqrt(x));


Thank you. I thought he was taking the mickey asking for an implementation!
Allan
Nov 14 '05 #13
In article <c2**********@n ews.freedom2sur f.net> "Allan Bruce" <al*****@TAKEAW AYf2s.com> writes:
"Eric Sosman" <Er*********@su n.com> wrote in message
news:40******** *******@sun.com ...
CBFalconer wrote:
void sincos(const double x, double *sinval, double *cosval)
{
*sinval = sin(x);
*cosval = sqrt(1.0 - *sinval * *sinval);
}


Alas, this tells me that the cosine of pi (180 degrees)
is positive, when any schoolchild knows it's negative.


but sqrt of a positive number can be positive or negative

e.g. sqrt(4) = +/- 2


Not in mathematics or in C. The above is valid for x in [-pi/2,pi/2],
but a more precise implementation is:
*cosval = sqrt((1.0 - *sinval) * (1.0 + *sinval));
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #14
CBFalconer wrote:

"E. Robert Tisdale" wrote:
Allan Bruce wrote:
> but sqrt of a positive number can be positive or negative
>
> e.g. sqrt(4) = +/- 2

But the result of the standard C library function sqrt(double)
cannot.

It's not difficult to implement though to get the correct answer.


This is the comp.lang.c newsgroup.
Please show us the implementation in C.


You are not overly intelligent, are you?

negroot = -(posroot = sqrt(x));


Good, but not yet good enough. One additional bit
of information needs to be computed: Which of `posroot'
and `negroot' is *the* cosine of `x'?

One way to choose the sign would be to use fmod()
to determine how many multiples of pi/2 are present, but
it's rather difficult to form an exact representation of
pi/2 in C's native arithmetic types ... As Plauger says
somewhere in "The Standard C Library," the library's
trig functions are likely to do a better job than the
caller can of throwing out extraneous multiples of pi.
(Elsewhere, this has been called "pi throwing.") The
upshot is that the library's best answer to the O.P.'s
request is probably

void sincos(double x, double *psin, double *pcos) {
*psin = sin(x);
*pcos = cos(x);
}

.... which I imagine the O.P. would find unsatisfactory.

--
Er*********@sun .com
Nov 14 '05 #15

"Eric Sosman" <Er*********@su n.com> wrote in message
news:40******** *******@sun.com ...
CBFalconer wrote:
The
upshot is that the library's best answer to the O.P.'s
request is probably

void sincos(double x, double *psin, double *pcos) {
*psin = sin(x);
*pcos = cos(x);
}

... which I imagine the O.P. would find unsatisfactory.

Unless using a compiler which automatically optimizes this combination.
Another possibility, which political correctness probably forbids
mentioning, is to look up the specific capabilities of the platform in use.
Nov 14 '05 #16
Thanks to everyone who has posted in response to my original message.

Perhaps I should clarify what I am asking. I have a suite of
numerical codes that I recently profiled and found that the standard
sin and cos routines are a huge percentage of my total run time (which
is many days). A colleague told me that the standard math libraries
are optimized for size, not speed, and that since I always call sin
and cos of the same argument, I should look for a speed optimized
sincos routine which shouldn't take much more time than either a sin
or cos take individually while maintaining the same level of accuracy.
BTW, I'm using Borland C++ Builder 6.0 on a Pentium IV in Win2k.

Ideally, this fast sincos would be something already written that has
been speed optimized (without sacrificing accuracy) by people much
smarter about this issue than myself...

Thanks again,

Oc**********@ya hoo.com
Nov 14 '05 #17
In article <e2************ **************@ posting.google. com>,
Oc**********@ya hoo.com (OcelotIguana) wrote:
Thanks to everyone who has posted in response to my original message.

Perhaps I should clarify what I am asking. I have a suite of
numerical codes that I recently profiled and found that the standard
sin and cos routines are a huge percentage of my total run time (which
is many days). A colleague told me that the standard math libraries
are optimized for size, not speed, and that since I always call sin =============== ==============

Usually they are optimised for accuracy.
and cos of the same argument, I should look for a speed optimized
sincos routine which shouldn't take much more time than either a sin
or cos take individually while maintaining the same level of accuracy.
BTW, I'm using Borland C++ Builder 6.0 on a Pentium IV in Win2k.


Have you looked at reducing the number of calls to sin and cos? For
example, consecutive values of sin (a + k * b), for k = 0, 1, 2, 3, etc.
can be calculated very easily with a single multiplication and addition.
Anything doing 3D graphics can usually be done with hardly any
trigonometric functions at all.

Do you have values that are very close together?

sin (x + eps) = sin (x) * cos (eps) + sin (eps) * cos (x)
cos (x + eps) = cos (x) * cos (eps) - sin (eps) * sin (x)

(You better check these)

If eps is small enough then you can replace cos (eps) with 1, sin (eps)
with eps and get

sin (x + eps) = sin (x) + eps * cos (x)
cos (x + eps) = cos (x) - eps * sin (x)

Grab the source of an existing implementation of sin and cos. They all
do two steps, for example for sin (x):

Step 1: Given x, find k such that abs (x - k * pi/2) <= pi/4.
Step 2: Let y = x - k * pi/2.
Step 3: Calculate one of sin(y), cos (y), -sin(y), -cos(y),
depending on the last two bits of k, using a polynomial.

By calculating sin and cos simultaneously, you know both will have the
same k and y. You also will have to calculate both sin(y) and cos(y)
using two polynomials, then just pick the right results and apply the
sign. So you win by just merging two such implementations .

If you have many calls, chances are the arguments are close together, so
many consecutive arguments will use the same value k. Try writing a
vectorised function:

void vec_sincos (double s[], double c[], double x[], size_t n);

where you will lose lots of the overhead and give the compiler a chance
of optimising.

BTW. Profilers have been known to lie, especially for small function
calls. Just write a test program that does a billion calls to sin and
cos, profile it, and compare the results with stopwatch results to make
sure you are not going down the wrong path.
Nov 14 '05 #18
OcelotIguana wrote:

Thanks to everyone who has posted in response to my original message.

Perhaps I should clarify what I am asking. I have a suite of
numerical codes that I recently profiled and found that the standard
sin and cos routines are a huge percentage of my total run time (which
is many days). A colleague told me that the standard math libraries
are optimized for size, not speed, and that since I always call sin
and cos of the same argument, I should look for a speed optimized
sincos routine which shouldn't take much more time than either a sin
or cos take individually while maintaining the same level of accuracy.
BTW, I'm using Borland C++ Builder 6.0 on a Pentium IV in Win2k.

Ideally, this fast sincos would be something already written that has
been speed optimized (without sacrificing accuracy) by people much
smarter about this issue than myself...

Thanks again,

Oc**********@ya hoo.com


If you don't need lots of precision, you can use table lookup. (basically,
you hash into the tables) as follows: suppose your basic range is

0 to +pi/4 = 45 deg ;

divide that range into--say--91 steps of 0.5 deg, as in Abramowitz & Stegun's
tables. The first thing you do is fill the sin and cos tables. Then, after
converting the angle to fit in the range, multiply by an appropriate factor
(2 in this case) and extract the integer part to get an integer in the range
0 to 89, call it k, plus a fraction x between 0 and 1. Then you evaluate

sin(k) * (1-x) + sin(k+1) * x

and

cos(k) * (1-x) + cos(k+1) * x

for linear interpolation. On modern machines it is best to increase the
number of stored values to increase precision, rather than performing an
interpolation of higher degree. (You are trading space for speed, as usual.)
Julian V. Noble
Professor Emeritus of Physics
jv*@lessspam.vi rginia.edu
^^^^^^^^
http://galileo.phys.virginia.edu/~jvn/

"For there was never yet philosopher that could endure the toothache
patiently." -- Wm. Shakespeare, Much Ado about Nothing. Act v. Sc. 1.
Nov 14 '05 #19
Thanks to everyone!
Nov 14 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.