<jupyter_start><jupyter_text>***<NAME>***  ***Question 1***<jupyter_code>n = int(input("Please enter an integer n: ")) #This code right here will as the user to enter the number n

#The for loop will iterate n number of times
for i in range(n):
    print(i*" "+'*'*(n-i)) #This print statement will create spaces i number of times and shift the start n-i to the right
                             #meaning we are going substract number iteration(n) to iteration elements<jupyter_output>Please enter an integer n: 10
**********
 *********
  ********
   *******
    ******
     *****
      ****
       ***
        **
         *<jupyter_text>***Question 2***<jupyter_code>import numpy as np #This code will import the library numpy that we can use different functions like the array of zeros.

n = int(input("Enter an integer which is greater than 2: ")) #This code asks the user to input the number n so it will iterate.

x = np.zeros(n, dtype=int) #This code creates an array of zeros with type integers so that we append it with all xi evaluations.
x[0]=1 #We initialise our second variable to be equal to 1, we are told this from our problem statement.
x[1]=1 #We initialise the third to equal to 1, from the problem statement.
print("  i \t  xi") #This will print out our nice looking table like with a tab in between to create space.
print("----------------") #This is just a line to separate our variables to the actual values.
print("  ", end="")   #This is just a line to separate our variables to the actual values.
print(x[2],x[1],sep =7*" ") #Since we assigned the second and third element this chuck of code prints the elements we initialsed
print("  ", end="") #This code creates spaces so that we can have a nice aligned table like shape in the desired output.
print(x[0],x[1],sep =7*" ") #This code prints out the first two elements in our zero array.
for i in range(2,n): #This loop creates the sequence x_n which starts from 2 as the statement instructed us to do so.
    x[i]=3*x[i-1]-x[i-2] #This is just a simple pluging the equation x_n which will assisted by for loop to update the value of x_n
    print("  ", end="") #This code just creates spaces so that we have a nice table like shape
    print(i,x[i], sep=7*" ") #This chuck will print the iterative i and the continuously updated x[i]<jupyter_output>Enter an integer which is greater than 2: 10
  i 	  xi
----------------
  0       1
  1       1
  2       2
  3       5
  4       13
  5       34
  6       89
  7       233
  8       610
  9       1597<jupyter_text>***Question 3***<jupyter_code>import matplotlib.pyplot as plt          #This code import a library matplotlib so that we can use it to visualise our graphs
import numpy as np                       #This code will a library numpy which is used for mathematical functions like pi, sin, cos etc


x=np.linspace(-6,6)                      #This chuck of code for the interval [-6,6] on the grid

color_change = ["c","y","k","b","g","m"] #This chuck of code is a list of different color of the graphs I want plot using different colors so the alphabets represent different colors
Title_change = ["$f_{t=-3}~(x)$","$f_{t=-2}~(x)$","$f_{t=-1}~(x)$","$f_{t=0}~(x)$","$f_{t=1}~(x)$","$f_{t=2}~(x)$"] #This we will excute our graph for different values of t so chuck gives the title of our graphs for diffirent t values

for t in range(-3,3):                    #This loop is for different type of t from -3 to 2 and we know the range fucntion is exclusive, it won`t excute the last part
    y=np.exp(-1*(x-3*t)**2) *np.sin((np.pi*3)*(x-t)) #This is our given fuction where we change different value of t which taken of by the loop
    
    plt.figure                           #This code will show us our different figures 
    plt.subplot(2,3,t+4)                 #Since we have to code subplots, we must introduce the variable t but since our t does not start from 1 we had to plus it by 4
    plt.plot(x,y, color_change[t])       #This chuck of code plots our graph and changes the colors of the graph from our defined color list on the top and it taking the advantage of the loop when it iterate it updates the color
    plt.grid()
    plt.xlabel("$x-axis$")               #This part just sets x - axis as the for loop iterates
    
    plt.ylabel("$y-axis$")               #This part just sets y - axis as the for loop iterates
    plt.title(Title_change[t+3])

    plt.legend(["$f_t(x) = e^{-(x-3t)^{2}}sin(3\pi(x-t))$"]) #This set our legends so that we see what graph are we plotting
    plt.rcParams["figure.figsize"]=[25,20]
    fig = plt.gcf()                      #allows you to get a reference to the current figure
    fig.set_size_inches(20, 15)          #This will give us the size inches of the plot
    fig.savefig('Musawenkosi plots.png', dpi=100)# This code saves my figure to the given name
    plt.subplots_adjust(wspace=0.3,hspace=0.5) #This fixes the spaces in between the plots.<jupyter_output><empty_output><jupyter_text>Graph comment: If look the graph you can see that it resemble a pulse at different times. If you look at the first graph you can see that it is the start of the pulse and the last graph is the end of the pulse.  ***Question 4***  ***a)***<jupyter_code>import random       #This chuck of code here imports the library random so that we can use it to N random points
import numpy as np  #Which are uniformly distributed
                    #The numpy library is used to generated convient mathematical functions  like sin,cos,exp and pi             
   
    
N=int(input('Enter the values: ')) #This code ask the user to enter a large number N and assign it to an integer
radius=1                           #we choose the radius to be 1 because place the circle in the origin the 

count_p_inside=0
x_p = np.random.uniform(0,2,(N))   #This code generates the N random points (x_i)
y_p = np.random.uniform(0,2,(N))   #This code generates the N random points (x_i)

for i in range(N):                 #In order to repeat N number of times we introduce a four loop which repeat the process N times
    x=x_p[i]                       #The randomly generated x_i codes are repeated in accordance with the for loop
    y=y_p[i]                       #The same thing will happen with y where we randomly generated y_i codes are repeated in accordance with the for loop
    
    if (x-1)**2+(y-1)**2<=radius**2: #In order to get the point inside the circle we have to restrict the points using a simple circle equation x**2+y**2 = r**2
        count_p_inside+=1            #So the points should satisfy that if the randomly generated (x_i,y_i) points should not be greater than radius r
print("Number of points inside the circle:",count_p_inside)#counting the numbers of  points falls inside the circle.
pi=4*count_p_inside/N                #This estimate pi using the given number of points inside the circle and N number of times
print('estimate value of pi: ',pi)            #This chuck code prints out the estimated pi<jupyter_output>Enter the values: 10000
Number of points inside the circle: 7857
estimate value of pi:  3.1428<jupyter_text>***(b)***  The (b) part where we count the number of times for points inside the circle is covered by **count_p_inside**  ***(c)*** The basic definition of probability of event to happen states that $ P(E) = \frac{Number~of~favourable ~outcomes}{Total~Number~of~outcomes} $, So in our case we wamt to count points inside the circle which can be represented by $A_c$. The cricle is inside the square therefore the total number of point are contained inside the square which can be represented by an area of $A_s$. Hence, we get the equation $p = \frac{A_c}{A_s}$.  ***(d)*** We know that the probability is given by $p = \frac{A_c}{A_s}$ we know that $A_c = \pi r^2$ and $A_s = 2r \times 2r = 4r^2$  \$\implies that ~ p = \frac{A_c}{A_s} = \frac{\pi r^2}{4r^2}$ \$p = \frac{\pi}{4}$ $\blacksquare$  ***(e)*** We can get or rather estimate the probability of the points falling inside circle by taking the total number of point(inside the circle) $n$ counts divided by the large number $N$ number of iteration. \$p = \frac{n}{N} \equiv p = \frac{\pi}{4}$ \$\implies \pi = \frac{4n}{N}$ from simple mathematical manipulation. $\blacksquare$  ***(f)***  from the code in **(a)** we can estimate $\pi$ by taking **count_p_inside** and **N**, thenafter, we use the equation $\pi = \frac{4n}{N}$  ***Question 5***  ***(a)***<jupyter_code>import random      #This chuck of code here imports the library random so that we can use it to N random points
import numpy as np # Which are uniformly distributed
                   #The numpy library is used to generated convient mathematical functions  like sin,cos,exp and pi

N = int(input("Please enter the number of iteration: ")) #This part asks the user to enter the number of iterations for the estimation
b = 2 #This initialise the upper integration bound
a = 0 #This initialise the lower integration bound

sum_f_bar = 0 #This code initialise the sum to be zero because we have not sum any iteration, this is f_bar
sum_f_bar_2 = 0 #This code initialise the sum to be zero because we have not sum any iteration, this is f_square_bar

for i in range(N):           #This for loop will iterate within the range(N)
    x = np.random.uniform(0,2) #This will generate the random uniform values between 0 and 2
    y = -(x**2/2)#This is just a simple convetion from the function f(x) = e**(-x**2/2)
    sum_f_bar += np.exp(y) #This will sum up all the value generated from the for loop iterations
    sum_f_bar_2 += np.exp(-(x**2)) #In order to get an accurate error bound we will have to sum all the number is f_square_bar

interval = b - a       #Since we have a line to integrate on interval bondouries is just the difference from lower and upper integration boundary
f_bar = sum_f_bar/N    #In the definition of f_bar from the monte carlo equation given in the question paper require us to divide the whole sum with 1/number of iterations(N)
f_bar_2 = sum_f_bar_2/N  #The equation f_square_bar needs to divide the whole sum with 1/number of iterations(N)

under_the_sqrt = np.sqrt(f_bar_2-f_bar**2/float(N)) #Just to make coding easier I have calculated operation under the square root separately so that no mistake can be made

integral_est_plus_error = interval*(f_bar + under_the_sqrt) #This code estimates the integral where we add the error bound as it written in the question paper
integral_est_minus_error = interval*(f_bar - under_the_sqrt) #This code estimates the integral where we minus the error bound as it written in the question paper

print("The estimate of the integral estimate + error:",integral_est_plus_error) #This just prints the integral estimate(plus an error bound) which changes everytime with number of iteration.
print("The estimate of the integral estimate - error :",integral_est_minus_error) #This just prints the integral estimate(minus an error bound) which changes everytime with number of iteration.<jupyter_output>Please enter the number of iteration: 1000
The estimate of the integral estimate + error: 2.518976029776856
The estimate of the integral estimate - error : -0.13287683291814556<jupyter_text>***b)***<jupyter_code>import random      #This chuck of code here imports the library random so that we can use it to N random points
import numpy as np ##Which are uniformly distributed
                   #The numpy library is used to generated convient mathematical functions  like sin,cos,exp and pi

N = int(input("Please enter the number of iterations: ")) #This part asks the user to enter the number of iterations for the estimation

sum_f_bar_b = 0   #This code initialise the sum to be zero because we have not sum any iteration, this is f_bar
sum_f_bar_2_b = 0 #This code initialise the sum to be zero because we have not sum any iteration, this is f_square_bar
number_zeros = 0 #This code will count the number of zeros the condition chose.



for i in range(N):                           #This for loop will iterate within the range(N)
    x = np.cos(np.random.uniform(0,np.pi*2)) #This is just convesion from cartisian co-ordinates to polar where x = rcos(theta) and our radius bound 0<= r <= 1 so choose it to equal to r=1
    y = np.sin(np.random.uniform(0,np.pi*2)) #This is just convesion from cartisian co-ordinates to polar where x = rsin(theta)
    r = 1                 
    #This define so that we sastify the domain x**2 + y**2 < r where our r = 1
    if x**2 + y**2 < r**2:                   #This conditional statement checks if x and y sastify the
        sum_f_bar_b += np.exp(r**2)          #if the random points of x and y sastify the condition it will sum up for every iteration
        sum_f_bar_2_b +=np.exp(2*(r**2))     #In order to get an accurate error bound we will have to sum all the number is f_square_bar
    else:                                    #if the condition is not met it will just print zero
        number_zeros +=1
        
interval_r = 2*np.pi                        #We had two bounds here where we had (2pi-0)(1-0) from convectining the cartisian co-ordinates to polar
f_bar_b = sum_f_bar_b/N                     #interval a to b and multiplying by the length of the interval.#In other words, we are finding the area of a rectangle with width = interval width and height = expected value of f(x) but this we had two bounds
f_bar_2_b = sum_f_bar_2_b/N 

under_the_sqrt_b = np.sqrt(f_bar_2_b-f_bar_b**2/float(N)) #Just to make coding easier I have calculated operation under the square root separately so that no mistake can be made

integral_est_plus_error_b = interval_r*(f_bar_b + under_the_sqrt_b) #This code estimates the integral where we add the error bound as it written in the question paper
integral_est_minus_error_b = interval_r*(f_bar_b - under_the_sqrt_b) #This code estimates the integral where we minus the error bound as it written in the question paper

print("The number of zeros chosen are:",number_zeros)
print("The estimate of the integral estimate + error :",integral_est_plus_error_b) #This just prints the integral estimate(plus an error bound) which changes everytime with number of iteration.
print("The estimate of the integral estimate - error :",integral_est_minus_error_b) #This just prints the integral estimate(minus an error bound) which changes everytime with number of iteration.<jupyter_output>Please enter the number of iterations: 100
The number of zeros chosen are: 44
The estimate of the integral estimate + error : 22.309768850038477
The estimate of the integral estimate - error : -3.1807641912496853
{'fraction_non_alphanumeric': 0.08571428571428572, 'fraction_numerical': 0.018773552586502228, 'mean_word_length': 3.4083358501963152, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '383709', 'license': 'MIT', 'n_tokens_mistral': 4352, 'n_tokens_neox': 4148, 'n_words': 2049, 'path': 'musawenkosi-python-assignment-2.ipynb', 'repo_name': 'musawenkosikhulu/Python-assignments-and-projects', 'size': '14606'}