# -*- coding: utf-8 -*- """ Created on Sun Dec 20 15:58:19 2020 @author: neil """ # In numerical (computer) work there is always a limit to the precision of any calculation # because real numbers can only be stored to some number of digits (in python the default # is 15 digits, but can be extended if needed) # Most common numerical errors propagate from simple subtraction! # this is an artificial example, but shows that the order of subtractions # can be very important if two numbers very close to each other are subtracted, # the answer will be very small, but the error will be the same size as the original # errors on the large numbers. In the worst case, the error can be as large or larger than # the answer! # subtracting 2 numbers that are large, with only a tiny difference # python only keeps approximatly 15 or so digits in any number a = 1.23456789 # a 'small' number b = 1.0e16 # a 'big' number c = -1.0e16 # we all know that in 'math' addition/subtraction is commutative, so: ans1 = (a+b)+c # (a+b) is subtracted by c, 2 big numbers only slightly different ans2 = a+(b+c) # (b+c) this subtraction is exactly 1, leaving ans2 equal to 'a' # we know the answer should be the small number exactly, by basic arithmatic print("#1 An example of truncation error enhancement by subtraction") print("incorrect answer for a+b+c = {0:f}".format(ans1) ) print("correct answer for a+(b+c) = {0:f}".format(ans2) ) print("The error is the same order of magnitude as 'a'! namely {0:e}".format(ans1-a)) # a more typical example would usually be harder to spot, print("\n\r#2 A harder to spot example") # the '\n\r' is a linefeed-cariage return (or newline) x = 1e-10 # again a 'small' number, which goes into a quadratic equation with a 'big' number y1 = 1 - (1+x)**2 # this leads to a significant error, but can be fixed by noticing # that (1+x)**2 could be written as 1+2*x+x**2 y2 = (1 - 1) - 2*x - x**2 # get rid of the 2 big numbers! print("the correct answer is {0:1.15e}".format(y2)) print("the incorrect is {0:1.15e}".format(y1)) print("the difference in the 2 answers is {0:e}".format(y1-y2))