Precision upto n decimal points

P

Pp

I am writing power series expansion programs.

For eg.
e^x = 1 + x + x^2/2! + x^3/3! + .....

Depending on how much precision I need, how do I stop the expansion.

For eg. if I need up to precision 5 then my loop will run in the form


double ex;
double newterm;
// new term is 1 in first iteration
// is x in 2nd iteration
// is x^2/2! in 3rd iteration & so on.

do
{

calculate newterm;

ex = ex + newterm;

} while (newterm > 1.0e-5);

Is the right way to do it or is there a better way do this?

What about for expansions for stuff like cos(x), sin(x) where negative
terms are involved?
 
N

Nick Keighley

I am writing power series expansion programs.

For eg.
e^x = 1 + x + x^2/2! + x^3/3! + .....

Depending on how much precision I need, how do I stop the expansion.

when you've reached the required precision
For eg. if I need up to precision 5 then my loop will run in the form

double ex;
double newterm;
// new term is 1 in first iteration
// is x in 2nd iteration
// is x^2/2! in 3rd iteration & so on.

do
{
        calculate newterm;
        ex = ex + newterm;
} while (newterm > 1.0e-5);

Is the right way to do it or is there a better way do this?

given that IANA Numerical Analalyst, yes looks fine to me

What about for expansions for stuff like cos(x), sin(x) where negative
terms are involved?
} while (fabs(newterm) > 1.0e-5);

perhaps?
 
T

Tim Prince

I am writing power series expansion programs.

For eg.
e^x = 1 + x + x^2/2! + x^3/3! + .....

Depending on how much precision I need, how do I stop the expansion.

For eg. if I need up to precision 5 then my loop will run in the form


double ex;
double newterm;
// new term is 1 in first iteration
// is x in 2nd iteration
// is x^2/2! in 3rd iteration & so on.

do
{

calculate newterm;

ex = ex + newterm;

} while (newterm > 1.0e-5);

Is the right way to do it or is there a better way do this?

What about for expansions for stuff like cos(x), sin(x) where negative
terms are involved?
When you have performed range reduction (taking advantage of the
periodicity), so that your series covers at most 2 quadrants, you can
figure out ahead of time the number of terms you require, and apply
Horner evaluation. Methods such as Chebyshev economization will improve
the convergence rate of the series on the fixed interval.
 
B

Barry Schwarz

I am writing power series expansion programs.

For eg.
e^x = 1 + x + x^2/2! + x^3/3! + .....

Depending on how much precision I need, how do I stop the expansion.

For eg. if I need up to precision 5 then my loop will run in the form


double ex;
double newterm;
// new term is 1 in first iteration
// is x in 2nd iteration
// is x^2/2! in 3rd iteration & so on.

do
{

calculate newterm;

ex = ex + newterm;

} while (newterm > 1.0e-5);

This only works if the fabs(final value) < 10.

If x is 15, then the answer to five significant digits is 3.2690e+6
and, using your philosophy, you should stop when newterm < 1e+5.

Basically, the limit you test against needs to be scaled by both the
number of significant digits and the base 10 log of the final value.
Is the right way to do it or is there a better way do this?

In your example, let us assume that newterm falls below the test limit
in iteration N. You now have a five digit value ABCDE and some
indication of where to insert the decimal point. It is still possible
that executing the loop another dozen (or hundred) times will update
the value to ABCDF. You need to understand how Numerical Analysis is
capable of determining the maximum error after a particular iteration.
What about for expansions for stuff like cos(x), sin(x) where negative
terms are involved?

Still part of Numerical Analysis.
 
E

Eric Sosman

I am writing power series expansion programs.

For eg.
e^x = 1 + x + x^2/2! + x^3/3! + .....

Depending on how much precision I need, how do I stop the expansion.

For eg. if I need up to precision 5 then my loop will run in the form


double ex;
double newterm;
// new term is 1 in first iteration
// is x in 2nd iteration
// is x^2/2! in 3rd iteration & so on.

do
{

calculate newterm;

ex = ex + newterm;

} while (newterm > 1.0e-5);

Is the right way to do it or is there a better way do this?

This will work for the series you mention, and for many others.
It might fail for some peculiar kinds of series, like x^3*e^x (the
expansion consists of the series you show, but with three zeroes
tacked on at the start; your criterion would stop at the first zero
and never evaluate the remaining terms).

Also, note that "newterm is small" does not necessarily imply
that the sum is accurate. For example, consider the harmonic series
1, 1/2, 1/3, ... Your loop would stop after around ten thousand terms
and would announce that the series adds to about 9.79. Alas, the
harmonic series does not converge at all! The terms get smaller, yes,
but they do not get small "fast enough" for convergence. So, beware!
What about for expansions for stuff like cos(x), sin(x) where negative
terms are involved?

The fabs() function is your friend ...

Many iterative numerical calculations use two (or even more)
stopping criteria: They'll stop after the calculation converges to
a suitable accuracy, or they'll stop and announce failure if the
calculation just buzzes around and around and doesn't converge.
 
J

James Kuyper

I am writing power series expansion programs.

For eg.
e^x = 1 + x + x^2/2! + x^3/3! + .....

Depending on how much precision I need, how do I stop the expansion.

For eg. if I need up to precision 5 then my loop will run in the form


double ex;
double newterm;
// new term is 1 in first iteration
// is x in 2nd iteration
// is x^2/2! in 3rd iteration & so on.

do
{

calculate newterm;

ex = ex + newterm;

} while (newterm > 1.0e-5);

Is the right way to do it or is there a better way do this?

Other people have answered your direct question; I'll deal with a slight
different issue. You're targeting a fixed precision of 1e-5, which may
be entirely appropriate approach for a particular problem. However, it's
not uncommon, for a general purpose function, to want to achieve the
maximum precision that's possible. There's a very simple way to impose
that requirement:

double ex, newterm, last;

ex = initial_estimate;

do
{
last = ex;
// calculate newterm
ex = ex + newterm;
} while (ex != last);
What about for expansions for stuff like cos(x), sin(x) where negative
terms are involved?

With the approach I just outlined, it doesn't matter whether newterm is
positive or negative.
 
W

Weland

I am writing power series expansion programs.

For eg.
e^x = 1 + x + x^2/2! + x^3/3! + .....

Depending on how much precision I need, how do I stop the expansion.
[...]
What about for expansions for stuff like cos(x), sin(x) where negative
terms are involved?

Store two consecutive approximations and compute their difference? At least
that's how I saw it done most of the time.

So if e^x = s(1) + s(2) + ... + s(n) + ...

then two consecutive approximations would be

e^x_(k) = s(1) + s(2) + ... + s(k)
e^x_(k+1) = s(1) + s(2) + ... + s(k) + s(k+1)

and the stopping criteria would be

abs(e^x_(k)) - abs(e^x(k+1)) < some threshold

Feel free to jug the abs()s around depending on how you expect the series
expansion to go (e.g. depending on it being monotonically increasing or not,
or if you're expanding around a function's 0 point and you're concerned
about it swinging above and below 0).

Depending on what you're trying to achieve you might also be better
off checking against a relative error, not an absolute one.
 
L

Lauri Alanko

do
{
last = ex;
// calculate newterm
ex = ex + newterm;
} while (ex != last);

That seems dangerous. Depending on the calculation, ex might
eventually oscillate between two numbers. Comparing floats for
equality is in general a bad idea, unless you know really well what
you are doing.


Lauri
 
J

James Kuyper

That seems dangerous. Depending on the calculation, ex might
eventually oscillate between two numbers. Comparing floats for
equality is in general a bad idea, unless you know really well what
you are doing.

Yes, that approach requires that the sum of the series converges; a
novice shouldn't even attempt doing a partial sum of a non-convergent
series, and an expert needs to be very careful about determining the
best number of terms to use.
Also, a series that converges mathematically might not do so when using
floating point math on a computer - again, that's an issue for experts
to deal with, there's no easy solution for the novice to learn.
 
G

gwowen

do
{
        calculate newterm;
        ex = ex + newterm;
} while (newterm > 1.0e-5);

what if the nth term is 1.0e-6 for all n?
Is the right way to do it

No. The nth term being small does not guarantee that the sum of the
nth->infinity will be similarly small.
or is there a better way do this?

No. There is no general way to determine if a given series will
converge, let alone whether it *has* converged. For specific examples,
you may be able to bound the sum of the tail of the series and use
that bound.
 

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

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top