Maximilian Fernaldy - C2B1702
To evaluate the Maclaurin expansions, we first need to define it. The Maclaurin series is an approximation of a function that can be defined as follows:
Since we're going to use factorials, we should also define the factorial as a function, as it's not included in the <math.h>
header file:
int factorial(int number) {
if (number < 1) { // if zero is passed, return 1 as the factorial
return 1;
}
for (int i = number-1; i > 1; i--) {
number *= i; // multiplies number by i and assigns that new value to number
}
return number;
}
Note that this function does not error handle factorials of integers less than 0 (it still returns 1 as the factorial, even though factorials of negative integers are undefined), but since we are going to use it four our own purposes, it's not a problem.
Using the newly-defined function factorial
, we can define the coefficients to use in the Maclaurin series.
In poly_sin3.c:
double c[N] = {sin(0)/factorial(0), cos(0)/factorial(1), -sin(0)/factorial(2), -cos(0)/factorial(3)};
and in poly_sin5.c:
double c[N] = {sin(0)/factorial(0), // evaluates to 0
cos(0)/factorial(1), // evaluates to 1
-sin(0)/factorial(2), // evaluates to 0
-cos(0)/factorial(3), // evaluates to 1/6
sin(0)/factorial(4), // evaluates to 1/24
cos(0)/factorial(5)}; // evaluates to 1/120
Even though it is possible to just use the evaluated values of the coefficients, it is good practice to define where the coefficients come from, for better code readability and comprehension.
After setting the coefficients, we use the following formula for the Maclaurin series of degree :
translating this formula to code, we have
/**** (2) processing contents ****/
for(x = -M_PI; x <= M_PI; x += M_PI/100){
for(y = c[N-1], i = N-2; i >= 0; --i) {
y = y * x + c[i];
}
printf("%f %f\n", x, y);
}
the x
level for
loop iterates through the linear space of the -axis, giving the function an -value to work with. The y
level for
loop is being used to sum the terms of the formula. We can see that at the first iteration, y = c[N-1]
which corresponds to gets multiplied by x
and added by c[i]
, which corresponds to . Then the whole of this corresponds to , and it all gets multiplied by and added by c[i]
again in the next iteration, but now c[i]
corresponds to . The operation will repeat itself, changing c[i]
until it is c[0]
, before printing the result for the specific value of , and continuing with the next value of . This will happen until the x
level for
loop also ends, ending the whole program.
Since we want to plot the values using matplotlib later, we should modify the program to print out the x and y values separated by a comma and space.
/**** (2) processing contents ****/
printf("x values:\n");
for(x = -M_PI; x <= M_PI; x += M_PI/100){
printf("%f, ", x);
}
printf("\ny values:\n");
for(x = -M_PI; x <= M_PI; x += M_PI/100){
for(y = c[N-1], i = N-2; i >= 0; --i) {
y = y * x + c[i];
}
printf("%f, ", y);
}
The first for
loop iterates from to in increments and prints out the -values. The second calculates the -values and prints them out. This part of the code stays the same for whichever degree of polynomial we are using.
Compiling and running poly_sin3.c gives:
and poly_sin5.c gives:
We can use the data from the output and plug it into an array in python (see last page for python code) to plot it and see how close they are to the actual sin function.
Clearly, the 5th degree Maclaurin series approximates better than the 3rd degree series, as it stays close to the real function further from . It's still not a viable option for -values higher than or lower than though, as we can see that it deviates quite severely after that point.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.font_manager as font_manager
from scipy.stats import binom
# Actual sin function
lowerlimit = -np.pi; upperlimit = np.pi
x_values = list(np.arange(lowerlimit, upperlimit, np.pi/100))
print(x_values)
y_values = [np.sin(x) for x in x_values]
# Data obtained from poly_sin3
c_program_x_range=[-3.141593, -3.110177, -3.078761, -3.047345, -3.015929, -2.984513, -2.953097, -2.921681, -2.890265, -2.858849, -2.827433, -2.796017, -2.764602, -2.733186, -2.701770, -2.670354, -2.638938, -2.607522, -2.576106, -2.544690, -2.513274, -2.481858, -2.450442, -2.419026, -2.387610, -2.356194, -2.324779, -2.293363, -2.261947, -2.230531, -2.199115, -2.167699, -2.136283, -2.104867, -2.073451, -2.042035, -2.010619, -1.979203, -1.947787, -1.916372, -1.884956, -1.853540, -1.822124, -1.790708, -1.759292, -1.727876, -1.696460, -1.665044, -1.633628, -1.602212, -1.570796, -1.539380, -1.507964, -1.476549, -1.445133, -1.413717, -1.382301, -1.350885, -1.319469, -1.288053, -1.256637, -1.225221, -1.193805, -1.162389, -1.130973, -1.099557, -1.068142, -1.036726, -1.005310, -0.973894, -0.942478, -0.911062, -0.879646, -0.848230, -0.816814, -0.785398, -0.753982, -0.722566, -0.691150, -0.659734, -0.628319, -0.596903, -0.565487, -0.534071, -0.502655, -0.471239, -0.439823, -0.408407, -0.376991, -0.345575, -0.314159, -0.282743, -0.251327, -0.219911, -0.188496, -0.157080, -0.125664, -0.094248, -0.062832, -0.031416, -0.000000, 0.031416, 0.062832, 0.094248, 0.125664, 0.157080, 0.188496, 0.219911, 0.251327, 0.282743, 0.314159, 0.345575, 0.376991, 0.408407, 0.439823, 0.471239, 0.502655, 0.534071, 0.565487, 0.596903, 0.628319, 0.659734, 0.691150, 0.722566, 0.753982, 0.785398, 0.816814, 0.848230, 0.879646, 0.911062, 0.942478, 0.973894, 1.005310, 1.036726, 1.068142, 1.099557, 1.130973, 1.162389, 1.193805, 1.225221, 1.256637, 1.288053, 1.319469, 1.350885, 1.382301, 1.413717, 1.445133, 1.476549, 1.507964, 1.539380, 1.570796, 1.602212, 1.633628, 1.665044, 1.696460, 1.727876, 1.759292, 1.790708, 1.822124, 1.853540, 1.884956, 1.916372, 1.947787, 1.979203, 2.010619, 2.042035, 2.073451, 2.104867, 2.136283, 2.167699, 2.199115, 2.230531, 2.261947, 2.293363, 2.324779, 2.356194, 2.387610, 2.419026, 2.450442, 2.481858, 2.513274, 2.544690, 2.576106, 2.607522, 2.638938, 2.670354, 2.701770, 2.733186, 2.764602, 2.796017, 2.827433, 2.858849, 2.890265, 2.921681, 2.953097, 2.984513, 3.015929, 3.047345, 3.078761, 3.110177, 3.141593]
sin3data=[2.026120, 1.904050, 1.785049, 1.669087, 1.556133, 1.446155, 1.339122, 1.235005, 1.133771, 1.035389, 0.939829, 0.847060, 0.757050, 0.669769, 0.585185, 0.503268, 0.423986, 0.347309, 0.273205, 0.201644, 0.132595, 0.066026, 0.001906, -0.059795, -0.119109, -0.176066, -0.230697, -0.283035, -0.333108, -0.380950, -0.426589, -0.470059, -0.511389, -0.550610, -0.587754, -0.622852, -0.655934, -0.687032, -0.716177, -0.743399, -0.768730, -0.792200, -0.813841, -0.833684, -0.851759, -0.868098, -0.882731, -0.895691, -0.907006, -0.916710, -0.924832, -0.931404, -0.936457, -0.940021, -0.942128, -0.942809, -0.942094, -0.940016, -0.936603, -0.931889, -0.925903, -0.918678, -0.910242, -0.900629, -0.889869, -0.877992, -0.865030, -0.851013, -0.835974, -0.819942, -0.802950, -0.785027, -0.766204, -0.746514, -0.725986, -0.704653, -0.682544, -0.659691, -0.636125, -0.611876, -0.586977, -0.561457, -0.535349, -0.508682, -0.481488, -0.453798, -0.425643, -0.397054, -0.368061, -0.338697, -0.308992, -0.278976, -0.248682, -0.218139, -0.187379, -0.156434, -0.125333, -0.094108, -0.062791, -0.031411, -0.000000, 0.031411, 0.062791, 0.094108, 0.125333, 0.156434, 0.187379, 0.218139, 0.248682, 0.278976, 0.308992, 0.338697, 0.368061, 0.397054, 0.425643, 0.453798, 0.481488, 0.508682, 0.535349, 0.561457, 0.586977, 0.611876, 0.636125, 0.659691, 0.682544, 0.704653, 0.725986, 0.746514, 0.766204, 0.785027, 0.802950, 0.819942, 0.835974, 0.851013, 0.865030, 0.877992, 0.889869, 0.900629, 0.910242, 0.918678, 0.925903, 0.931889, 0.936603, 0.940016, 0.942094, 0.942809, 0.942128, 0.940021, 0.936457, 0.931404, 0.924832, 0.916710, 0.907006, 0.895691, 0.882731, 0.868098, 0.851759, 0.833684, 0.813841, 0.792200, 0.768730, 0.743399, 0.716177, 0.687032, 0.655934, 0.622852, 0.587754, 0.550610, 0.511389, 0.470059, 0.426589, 0.380950, 0.333108, 0.283035, 0.230697, 0.176066, 0.119109, 0.059795, -0.001906, -0.066026, -0.132595, -0.201644, -0.273205, -0.347309, -0.423986, -0.503268, -0.585185, -0.669769, -0.757050, -0.847060, -0.939829, -1.035389, -1.133771, -1.235005, -1.339122, -1.446155, -1.556133, -1.669087, -1.785049, -1.904050, -2.026120]
# Data obtained from poly_sin5
sin5data=[-0.524044, -0.521131, -0.520097, -0.520826, -0.523202, -0.527114, -0.532453, -0.539115, -0.546995, -0.555995, -0.566017, -0.576967, -0.588753, -0.601286, -0.614481, -0.628253, -0.642523, -0.657211, -0.672242, -0.687543, -0.703043, -0.718674, -0.734371, -0.750069, -0.765709, -0.781232, -0.796580, -0.811702, -0.826544, -0.841058, -0.855195, -0.868912, -0.882166, -0.894914, -0.907120, -0.918745, -0.929756, -0.940120, -0.949806, -0.958785, -0.967030, -0.974517, -0.981223, -0.987125, -0.992204, -0.996444, -0.999826, -1.002337, -1.003965, -1.004697, -1.004525, -1.003440, -1.001436, -0.998508, -0.994652, -0.989867, -0.984151, -0.977505, -0.969932, -0.961434, -0.952017, -0.941686, -0.930449, -0.918313, -0.905288, -0.891386, -0.876616, -0.860994, -0.844531, -0.827243, -0.809146, -0.790257, -0.770593, -0.750173, -0.729016, -0.707143, -0.684574, -0.661332, -0.637439, -0.612918, -0.587793, -0.562089, -0.535830, -0.509044, -0.481755, -0.453992, -0.425780, -0.397148, -0.368125, -0.338738, -0.309017, -0.278991, -0.248690, -0.218143, -0.187381, -0.156434, -0.125333, -0.094108, -0.062791, -0.031411, -0.000000, 0.031411, 0.062791, 0.094108, 0.125333, 0.156434, 0.187381, 0.218143, 0.248690, 0.278991, 0.309017, 0.338738, 0.368125, 0.397148, 0.425780, 0.453992, 0.481755, 0.509044, 0.535830, 0.562089, 0.587793, 0.612918, 0.637439, 0.661332, 0.684574, 0.707143, 0.729016, 0.750173, 0.770593, 0.790257, 0.809146, 0.827243, 0.844531, 0.860994, 0.876616, 0.891386, 0.905288, 0.918313, 0.930449, 0.941686, 0.952017, 0.961434, 0.969932, 0.977505, 0.984151, 0.989867, 0.994652, 0.998508, 1.001436, 1.003440, 1.004525, 1.004697, 1.003965, 1.002337, 0.999826, 0.996444, 0.992204, 0.987125, 0.981223, 0.974517, 0.967030, 0.958785, 0.949806, 0.940120, 0.929756, 0.918745, 0.907120, 0.894914, 0.882166, 0.868912, 0.855195, 0.841058, 0.826544, 0.811702, 0.796580, 0.781232, 0.765709, 0.750069, 0.734371, 0.718674, 0.703043, 0.687543, 0.672242, 0.657211, 0.642523, 0.628253, 0.614481, 0.601286, 0.588753, 0.576967, 0.566017, 0.555995, 0.546995, 0.539115, 0.532453, 0.527114, 0.523202, 0.520826, 0.520097, 0.521131, 0.524044]
fontprop=font_manager.FontProperties(family="CMU Serif", size=12)
plt.plot(x_values, y_values, label="sin(x)")
plt.xlabel("x", fontname="CMU Serif")
plt.ylabel("sin(x)", fontname="CMU Serif")
plt.plot(c_program_x_range, sin3data, label="Maclaurin degree 3")
plt.plot(c_program_x_range, sin5data, label="Maclaurin degree 5")
plt.xticks(fontname="CMU Serif")
plt.yticks(fontname="CMU Serif")
plt.title("Maclaurin Approximations of sin(x)", fontname="CMU Serif")
plt.legend(prop=fontprop)
plt.show()