Exercise 03.1

Compare the computed values of

$$ d_0 = a \cdot b + a \cdot c $$

and

$$ d_1 = a \cdot (b + c) $$

when $a = 100$, $b = 0.1$ and $c = 0.2$. Try check for equality, e.g. print(d0 == d1).


In [1]:
# Initializa a, b and c
a = 100
b = 0.1
c = 0.2

# Compute the two values
d_0 = a*b + a*c
d_1 = a*(b + c)

print(d_0)
print(d_1)
print(d_0 == d_1)


30.0
30.000000000000004
False

Exercise 03.2

For the polynomial

\begin{align} f(x, y) &= (x + y)^{6} \\ &= x^6 + 6x^{5}y + 15x^{4}y^{2} + 20x^{3}y^{3} + 15x^{2}y^{4} + 6xy^{5} + y^{6} \end{align}

compute $f$ using: (a) the compact form $(x + y)^{6}$; and (b) the expanded form for:

  • $x = 10$ and $y = 10.1$
  • $x = 10$ and $y = -10.1$

and compare the number of significant digits for which the answers are the same. For the second case compare the computed and analytical solutions.

Which approach would you recommend for computing this expression?

I would choose the compact form since, containing less terms, it minimizes the possibility of errors due to the floating point representation of numbers


In [2]:
# Initialize x and y
x, y = 10, 10.1
print('x and y values:' ,x, y)

# Calculate the two expressions
f1 = (x + y)**6
f2 = x**6 + 6*x**5*y + 15*x**4*y**2 + 20*x**3*y**3 + 15*x**2*y**4 + 6*x*y**5 + y**6

print('Compact form:', f1, '\nExpanded form:', f2, '\nDifference:', f1-f2)

print('\n---------------------------------------------------------\n')

# Initialize x and y
x, y = 10, -10.1
print('x and y values:' ,x, y)

# Calculate the two expressions
f1 = (x + y)**6
f2 = x**6 + 6*x**5*y + 15*x**4*y**2 + 20*x**3*y**3 + 15*x**2*y**4 + 6*x*y**5 + y**6

print('Compact form:', f1, '\nExpanded form:', f2, '\nDifference:', f1-f2)


x and y values: 10 10.1
Compact form: 65944160.60120103 
Expanded form: 65944160.601201 
Difference: 2.9802322387695312e-08

---------------------------------------------------------

x and y values: 10 -10.1
Compact form: 9.999999999999788e-07 
Expanded form: 9.958166629076004e-07 
Difference: 4.183337092378376e-09

Exercise 03.3

Consider the expression

$$ f = \frac{1}{\sqrt{x^2 - 1} - x} $$

When $x$ is very large, the denominator approaches zero, which can cause problems.

Try rephrasing the problem and eliminating the fraction by multiplying the numerator and denominator by $\sqrt{x^2 - 1} + x$ and evaluate the two versions of the expression when:

  • $x = 1 \times 10^{7}$
  • $x = 1 \times 10^{9}$ (You may get a Python error for this case. Why?)

In [3]:
# Import math to compute square root
import math

The expression obtained by multiplying the numerator and denominator by $\sqrt{x^2 - 1} + x$ is

$$ f = -\sqrt{x^2 - 1} - x. $$

Let's try the first value $1 \times 10^{7}$


In [4]:
# Initialize x
x = 1e7

# Compute the two expressions
f1 = 1 / (math.sqrt(x**2-1) - x)
f2 = -math.sqrt(x**2-1) - x

print('Result of the first expression:', f1, '\nResult of the second expression:', f2)


Result of the first expression: -19884107.85185185 
Result of the second expression: -19999999.999999948

The second expression is more precise; moreover it avoids the risk of a division by zero error:


In [5]:
# Initialize x
x = 1e9

# This gives division by zero error
f1 = 1 / (math.sqrt(x**2-1) - x)

print('Result of the first expression:', f1)


---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-5-b89dd747f70c> in <module>()
      3 
      4 # This gives division by zero error
----> 5 f1 = 1 / (math.sqrt(x**2-1) - x)
      6 
      7 print('Result of the first expression:', f1)

ZeroDivisionError: float division by zero

In [6]:
# Initialize x
x = 1e9

# This doesn't
f2 = (math.sqrt(x**2-1) + x)

print('Result of the second expression:', f2)


Result of the second expression: 2000000000.0