# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3.6
#     language: python
#     name: python36
# ---

# + [markdown] slideshow={"slide_type": "slide"}
# # Polynomials

# + [markdown] slideshow={"slide_type": "subslide"}
# ##### Overview:
# - **Teaching:** 5 min
# - **Exercises:** 15 min
#
# **Questions**
# - What else can numpy do for me?
#
# **Objectives**
# - Know that `Numpy` and `SciPy` provide a huge range of functionality
# - Know that `Polynomial` exist

# + [markdown] slideshow={"slide_type": "slide"}
# ## Lectures on Numpy, Scipy
#
# As well as a huge range of functionality there also exist lectures on use case for [Numpy](https://scipy-lectures.org/intro/numpy/index.html) and the whole of [Scipy](https://scipy-lectures.org/intro/).  If you want to now want explore this material please do so.  There is little value in trying to reproduce it here.
#
# One example we will explore however is the polynomial as it gives an example of how `numpy` can help us produce very powerful efficient code efficiently.  First what is numpy Polynomial module?
# -

# ## Information: 
#
# ## Polynomials
#
# We can represent polynomials with the `numpy` class `Polynomial` from `numpy.polynomial.Polynomial`
#
# * `Polynomial([a, b, c, d, e])` creates a polynomial  $p(x) = a\,+\,b\,x \,+\,c\,x^2\,+\,d\,x^3\,+\,e\,x^4$.
#
# For example:
#
# * `Polynomial([1,2,3])` creates $p(x) = 1\,+\,2\,x \,+\,3\,x^2$
#   
# * `Polynomial([0,1,0,2,0,3])` creates $p(x) = x \,+\,2\,x^3\,+\,3\,x^5 $</p>
#   
# Let's import the class and have a quick play:

from numpy.polynomial import Polynomial as poly

my_poly = poly([1,2,3])
print(my_poly)
my_poly

# Once created we can use help/autocompletion to explore/access the various functions available.  We can access find the derivative of our polynomial:

my_poly.deriv()

# If we assign this to a variable the the object is another polynomial:

my_deriv = my_poly.deriv()
print(my_deriv)
my_deriv

my_integ = my_poly.integ()
print(my_integ)
my_integ

# Note that even `numpy` can't know the value of the constant when you integrate, though you can set it:

help(my_poly.integ)

# ## Exercise: Calculting $\pi$ again
#
# The Taylor series expansion for the trigonometric function $\arctan(y)$ is :
#
# $$\arctan ( y) \, = \,y - \frac{y^3}{3} + \frac{y^5}{5}  - \frac{y^7}{7}  + \dots $$
#
# Now, $\arctan(1) = \pi/4 $, so
#
# $$ \pi = 4 \, \Big( 1- \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + ... \Big) $$
#
# We can represent the series expansion using a numpy `Polynomial`, with coefficients:
#
# $$0, +1, 0, -1/3, 0, +1/5, 0, -1/7,\ldots\,$$ and use it to approximate $\pi$.
#
# Using this, write a code to estimate $\pi$.  How does your code perform, how does it compare with the Monte Carlo approach?

# + [markdown] slideshow={"slide_type": "slide"}
# ## Key Points:
# - Numpy and Scipy lectures are a valuable resource for learning to use their functionality
# - Making use of existing functionality will help you write correct, performant code more efficiently

StarcoderdataJupyterScriptsDedupFiltered