Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Precision upto n decimal points (http://www.velocityreviews.com/forums/t806579-precision-upto-n-decimal-points.html)

Pp 12-04-2011 10:57 AM

Precision upto n decimal points
 
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?


Nick Keighley 12-04-2011 11:37 AM

Re: Precision upto n decimal points
 
On Dec 4, 10:57*am, Pp <p...@ab.com> wrote:

> 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?




Tim Prince 12-04-2011 12:00 PM

Re: Precision upto n decimal points
 
On 12/4/2011 5:57 AM, Pp wrote:
> 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.

--
Tim Prince

Barry Schwarz 12-04-2011 01:02 PM

Re: Precision upto n decimal points
 
On Sun, 04 Dec 2011 16:27:37 +0530, Pp <pp@ab.com> wrote:

>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.

--
Remove del for email

Eric Sosman 12-04-2011 01:40 PM

Re: Precision upto n decimal points
 
On 12/4/2011 5:57 AM, Pp wrote:
> 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.

--
Eric Sosman
esosman@ieee-dot-org.invalid

James Kuyper 12-04-2011 03:14 PM

Re: Precision upto n decimal points
 
On 12/04/2011 05:57 AM, Pp wrote:
> 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.
--
James Kuyper

Weland 12-04-2011 03:18 PM

Re: Precision upto n decimal points
 
On 2011-12-04, Pp <pp@ab.com> wrote:
> 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.

--
weland@sdf.org
SDF Public Access UNIX System - http://sdf.org
% grep me no patterns and I'll tell you no lines

Lauri Alanko 12-04-2011 03:29 PM

Re: Precision upto n decimal points
 
In article <jbg2on$b8b$1@dont-email.me>,
James Kuyper <jameskuyper@verizon.net> wrote:
> 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

James Kuyper 12-04-2011 03:46 PM

Re: Precision upto n decimal points
 
On 12/04/2011 10:29 AM, Lauri Alanko wrote:
> In article <jbg2on$b8b$1@dont-email.me>,
> James Kuyper <jameskuyper@verizon.net> wrote:
>> 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.


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.
--
James Kuyper

gwowen 12-05-2011 01:54 PM

Re: Precision upto n decimal points
 
On Dec 4, 10:57*am, Pp <p...@ab.com> wrote:

> 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.


All times are GMT. The time now is 01:59 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.