Introduction to Numerical Problem Solving TX00BY09-3007

Assignment: 03 Graphical analysis

Description: Solve the problem 8 from previous exercises 02. Solve the problems 1c, 2a, and 4a from exercises 03.

Author: Joonas Forsberg

This document has been prepared for the third assignment for the course "Introduction to Numerical Problem Solving". It contains code examples and explanations for the written code. In addition, I've included reasoning behind the behavior where acceptable.


In [2]:
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.pyplot import *
from numpy import *

Problem 08

The infinite series $$f(n) = \sum_{k=1}^{n}\frac{1}{k^4}$$ converges on a value of $f(n) = \pi^4/90$ as n approaches infinity. Write a program in single precision to calculate $f(n)$ for $n = 10,000$ by computing the sum from $k = 1$ to 10,000. Then repeat the calculation but reverse the order – that is, from k = 10, 000 to 1 using increments of −1. In each case, compute the true percent relative error. Explain the results.


In [3]:
def problem08(start, max_value, addition):
    
    true_val = pi**4/90
    total = 0
    
    i = start
    while i > max_value or i < max_value:
        
        # Always add float32 (single prec. value to total)
        total += np.float32(1/(i**4))
        
        i += addition
    
    # Numerical true error
    enum = np.float32(true_val) - np.float32(total)

    # True percent relative error
    eper = enum / true_val
    
    print("End result is {}, true percent relative error {} %".format(np.float32(total), eper * 100))

problem08(1, 10000, 1)
problem08(10000, 0, -1)


End result is 1.0823231935501099, true percent relative error 0.0 %
End result is 1.0823231935501099, true percent relative error 0.0 %

Results without specifying single precision (float32):
End result is 1.082323233710861, true percent relative error 2.558289554517808e-11 %
End result is 1.0823232337108049, true percent relative error 3.077333064776834e-11 %

In order to present the results in single precision, we need to cast the values to numpy.float32. By default the calculations are performed with double precision (numpy.float64), which means the results are more accurate. With single precision the results are less accurate and as the true percent relative error value is low enough, it's not shown when using single precision.

Problem 01

Obtain graphs of the following functions. Locate the roots, local minimums, and local maximums graphically within two significant numbers and mark them into the graphs.

(a) $y = 3x^3 - x^2 2x + 1$, when $-2 \leq x \leq 2$
(b) $y = x^4 + \frac{x^3}{3} - \frac{5x^2}{2} + x - 1$, when $ -3 \leq x \leq 2$
(c) $y = x^5 - x^2 + 2$, when $-2 \leq x \leq 2$


In [4]:
%matplotlib inline
def problem01(selection):
    
    if selection == "a":
        print("Matti")
    elif selection == "b":
        print("Teppo")
    elif selection == "c":
        
        # Create graph based on 
        x = np.arange(-2, 2, 0.001)
    
        y = x**5 - x**2 + 2
        
        # Create the graph
        plt.plot(x, y, marker=".", linestyle=":")
        
        # Mark known root
        plt.plot(0, 2.0, 'ro:')
        
        # Mark known minima
        plt.plot(0.737007, 1.67427, 'yo:')
        
        plt.grid()
        plt.show()
    else:
        print("Invalid selection")
    
#problem01("a")
#problem01("b")
problem01("c")


We can analyse the graph provided and find out the equation has only one root (y = 2.0)

Local maxima:
y = 1.67427, x = 0.737007

Local minima:
y = 2.0, x = -0.000997453

The local minima is essentially the root value so it's not plotted.

Problem 02

(a) Draw $y = x^3$ and $y = 4 − 2x$ using the same axes. Note the x coordinate of the point of intersection within three significant figures accuracy.
(b) Draw $y = x^3 + 2x − 4$. Note the coordinate of the point where the curve cuts the x axis. Compare your answer with that from (a). Explain your findings.


In [5]:
%matplotlib inline
def problem02(selection):
    
    if selection == "a":
        x = np.arange(-1, 3, 0.0001)
        
        y1 = x ** 3
        y2 = 4 - 2 * x
        
        plt.plot(x, y1)
        plt.plot(x, y2)

        idx = np.argwhere(np.diff(np.sign(y1 - y2)) != 0).reshape(-2) + 0
        plt.plot(x[idx], y1[idx], 'ro')
        
        print(x[idx])
        print(y1[idx])
        
        plt.grid()
        plt.show()
    elif selection == "b":
        x = np.arange(-1, 3, 0.001)
        
        y = x ** 3 + 2 * x - 4
        
        plt.plot(x, y)
        plt.grid()
        plt.show()
    else:
        print("Invalid selection")
        
problem02("a")
#problem02("b")


[ 1.1795]
[ 1.64094428]

Actual intersection:
x = 1.17951
y = 1.64098

Calculated values:
x = 1.1795
y = 1.64094428

The drawn point is slighly off the intersection but falls within the three significant figures of accuracy.

Ref: https://stackoverflow.com/questions/28766692/intersection-of-two-graphs-in-python-find-the-x-value

Problem 04

Draw the following rational functions. State any asymptotes and draw or mark them in the graphs.
(a) $f(x) = \frac{(2x + 1)}{(x - 3)} -4 \leq x \leq 4$
(b) $g(s) = \frac{s}{(s + 1)} -3 \leq x \leq 3$


In [6]:
%matplotlib inline
def problem03(selection):
    
    if selection == "a":
        
        x = np.arange(-4, 4, 0.01)
        y = (2 * x + 1)/(x - 3)
        
        # Infinites in graph, limit y
        ylim([-50,50])
        xlim([-4, 4])
        plt.plot(x, y)
        
        # Draw asymptones
        plt.plot((3, 3), (-100, 100), 'r-')
        plt.plot((-100, 100), (2, 2), 'r-')
        
        plt.grid()
        plt.show()
    elif selection == "b":
        print("No calculations")
    else:
        print("Invalid selection")
        
problem03("a")
#problem03("b")


Asymptotes have been marked with red lines. With -4 <= x <= 4 the graph doesn't continue towards infinity on x axis, but without limit the graph would continue towards infinity and asymptote would appear on x-axis as well, roughly at y = 2

Another asymptote appears at x = 3.