Sine function

  • Thread starter Thread starter Owkmann
  • Start date Start date
O

Owkmann

Can someone give me a rough idea how a value is obtained for a trigonometric
function like Math.Sin? What is the algorithm? I'm finding that putting a
large number in this function ( > 8000 ) really slows things down. Why is
that?

Thanks,

Owkmann
 
First of all, Math.Sin takes its argument in radians, not degrees, so
360 is the wrong denominator.

Second, the argument is a double, for which there is no modulo
operator, even if you could get a reasonably accurate value for 2p.
Not even Math.DivRem provides an overload for doubles.
 
Trust me to reply without thinking the logic through.

The angle is measured in radians, so it shouldn't be 360, but 2 pi.

Disclaimer:
Untested code.

jliu
johnliu.net
 
And Bruce's right. % or DivRem won't work.

I found double Math.IEEERemainder(double x, doubly y) though.

So the idea should be:

Math.Sin( Math.IEEERemainder( largeNumber, 2* Math.PI ));

Disclaimer:
Untested code.

jliu
johnliu.net
 
Jeez, instead of criticizing you could have been a little more helpful.

Math.Sin(Math.IEEERemainder(LargeNum, 6.28318))

Should do the trick. (Hint: provide a more accurate number of the number of
radians in a full circle to get a better answer).
 
Math.Sin(Math.IEEERemainder(LargeNum, 6.28318))

Actually to get a better number for this, you could use

Math.Sin(Math.IEEERemainder(LargeNum, (double)360 / (double)2 / Math.PI))

But that assumes the compiler is smart enough to not evaluate the equation
every time (or better yet, evaluate it at compile time)... It might be a
safe assumption to make these days, but just to make sure you might want to
turn that into a constant.
 
Tried this in snippet compiler, because I was worried about the error.
DateTime start = DateTime.Now;
WL("Math.Sin(10000) = {0}", Math.Sin(10000));
TimeSpan ts = DateTime.Now - start;
WL("Time Taken: {0}", ts);

DateTime start2 = DateTime.Now;
WL("Math.Sin(Math.IEEERemainder(10000, 2*Math.PI)) = {0}",
Math.Sin(Math.IEEERemainder(10000, 2*Math.PI)));
TimeSpan ts2 = DateTime.Now - start2;
WL("Time Taken: {0}", ts2);
RL();

Out:
Math.Sin(10000) = -0.305614388888252
Time Taken: 00:00:00
Math.Sin(Math.IEEERemainder(10000, 2*Math.PI)) = -0.305614388888028
Time Taken: 00:00:00

Math.Sin(1000000) = -0.349993502171292
Time Taken: 00:00:00
Math.Sin(Math.IEEERemainder(1000000, 2*Math.PI)) = -0.349993502093929
Time Taken: 00:00:00

There seems to be a increasing error as the number gets bigger. The
error may be too high to be acceptable in your situation.

I'm not seeing this slowness problem though. May be I need to run it
1000 times.

jliu
johnliu.net
 
Yup, a classical case of magnified errors due to scale vs precision... It
would be much smarter to get the number down to 0 >= x >= 360 before calling
the sine function...
 
I'm not seeing this slowness problem though. May be I need to run it
1000 times.

jliu
johnliu.net

Yah. 16384 times (2^14).

public static double[] SineWave(double frequency, double phase, double
magnitude, int N_samples, double SampleRate)
{
const double PI = Math.PI;
double[] Xreal = new double[N_samples]; // N_samples = 16384; Gets really
slow
double Freq = frequency;
double Phase = phase;
double Mag = magnitude;
double Sample_Rate = SampleRate;
double Operand = 2 * PI * Freq * 1 / Sample_Rate + Phase;

for (int i = 0; i < N_samples; i++)
{
// This equation returns an array of doubles that simulate
// an A/D sampling a sine wave at a given sample rate

Xreal = Mag * Math.Sin(Operand * i);
}
return Xreal;
}

That's why I was wondering how Math.Sin calculates its number.

There's got to be an easier way!

Owkmann
 
Jeez, instead of criticizing you could have been a little more helpful.
Math.Sin(Math.IEEERemainder(LargeNum, 6.28318))

Should do the trick.

I wasn't more helpful because I didn't know about IEEERemainder(). :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top