<jupyter_start><jupyter_text>Demo: Interpolator *This script provides a few examples on using the Interpolator class.Last updated: April 14, 2015.Copyright (C) 2014 <NAME>Licensed under the MIT license, see LICENSE.txt* *Interpolator* is a subclass of *Basis*.  * A *Basis* object contains data to compute the interpolation matrix $\Phi(x)$ at arbitrary values of $x$ (within the interpolation box).* An *Interpolator* is used to interpolate a given function $f(x)$, when the value of $f$ is known at the basis nodes. It adds methods to the *Basis* class to compute interpolation coefficients $c$ and to interpolate $f$ at arbitrary $x$.Evaluation of this objects is straighforward:* If B is a Basis, then  B(x, k) computes the interpolating matrix $D^{(k)}\Phi(x)$, the k-derivative of $\Phi$* If V is an Interpolator, then  V(x, k) interpolates $D^{(k)}f(x)$, the k-derivative of $f$.<jupyter_code>%matplotlib notebook
import numpy as np
from compecon import Basis, Interpolator
import matplotlib.pyplot as plt
import seaborn as sns
import time

np.set_printoptions(precision=3, suppress=True)
#sns.set(style='whitegrid')<jupyter_output><empty_output><jupyter_text>EXAMPLE 1:Using BasisChebyshev to interpolate a 1-D function with a Chebyshev basis**PROBLEM:** Interpolate the function $y = f(x) = 1 + sin(2x)^2$ on the domain $[0,\pi]$, using 5 Gaussian nodes. There are two ways to create an *Interpolator* object. * Defining the basis first, then the interpolator with known function values at nodes<jupyter_code>f = lambda x: (1 + np.sin(2*x)**2)
B = Basis(5,0,np.pi)
V = Interpolator(B, y=f(B.nodes))<jupyter_output><empty_output><jupyter_text>We are goint to make the same plot several times, so define it with a function<jupyter_code>xx = np.linspace(0,np.pi,120)
def plot(P):
    plt.figure()
    plt.plot(xx,f(xx))
    plt.plot(xx,P(xx))
    plt.scatter(P.nodes,P(),color='red') #add nodes<jupyter_output><empty_output><jupyter_text>Plot the interpolation at a refined grid. Notice how the interpolation is exact at the nodes.<jupyter_code>plot(V)<jupyter_output><empty_output><jupyter_text>* The second option is to create the *Interpolator* just as a regular *Basis*, adding the known function values at the next step. The difference is that we end up with only one object.<jupyter_code>S = Interpolator(5,0,np.pi)
S.y = f(S.nodes)
plot(S)<jupyter_output><empty_output><jupyter_text>* When we have a callable object (like the lambda f) we can pass it directly to the constructor, which will evaluate it at the nodes:<jupyter_code>U = Interpolator(5,0,np.pi, y = f)
plot(U)<jupyter_output><empty_output><jupyter_text>Let's time it Interpolate the first derivative of $S$ at the $xx$ values, repeat $10^4$ times.<jupyter_code>t0 = time.time()
for k in range(10000):
    S(xx, 1)
    
time.time() - t0<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11334037310806054, 'fraction_numerical': 0.014783526927138331, 'mean_word_length': 5.702830188679245, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '14716', 'license': 'MIT', 'n_tokens_mistral': 1003, 'n_tokens_neox': 951, 'n_words': 337, 'path': 'notebooks/old notebooks/dem03_interpolator.ipynb', 'repo_name': 'snowdj/CompEcon-python', 'size': '2857'}