Contact Us!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Avatar for stephanie's main branch.

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

| Download

"Guiding Future STEM Leaders through Innovative Research Training" ~ thinkingbeyond.education

Views: 1074
Image: ubuntu2204
Kernel: Python 3

Open In Colab

#Summary of code

The purpose of this code is to create a piecewise constant function that the user can interact with, to aid understanding of how a piecewise constant function can approximate a continuous function. The user can choose the continuous function being approximated out of 3 choices. When the functions are plotted, the user can change the number of sections in the piecewise function to see that when the number of sections increases, the approximation improves.

#Installing packages

!pip install numpy==1.23.5 !pip install matplotlib==3.7.1 !pip install ipywidgets==8.1.0 !pip install ipython==8.15.0
(Output Hidden)

Importing packages

import numpy as np import matplotlib.pyplot as plt from ipywidgets import interact import ipywidgets as widgets from IPython.display import display import math

#Defining a function which applies the chosen function

This function allows us to use the same code to calculate the outputs of the continuous function regardless of the function chosen.

def function(input): if chosen_func == 1: return math.sin(6*input) elif chosen_func == 2: return 0.05*((7*input-2)**2)*((7*input-6)**2) elif chosen_func == 3: return (math.e)**(input-1)

#Defining a function which creates a list of outputs for the piecewise function

For i from 0 to n_sections (the number of sections that the piecewise function has), if each xx in the list of inputs ParseError: KaTeX parse error: Expected 'EOF', got '_' at position 17: …frac{i}{\text{n_̲sections}}\leq …, then the output of the piecewise function for this input x is ParseError: KaTeX parse error: Expected 'EOF', got '_' at position 19: …frac{i}{\text{n_̲sections}}), where ff is the continuous function chosen.

y_1[999] = function(1)

ensures that the last value is not missed, otherwise this will result in a value of 0 for the final output value. All the outputs are stored in an array y_1 which the function returns.

def piecewise_function(x, n_sections): y_1 = np.piecewise(x, [((i / n_sections) <= x) & (x < ((i + 1) / n_sections)) for i in range(n_sections)], [lambda x, i=i: function(i/n_sections) for i in range(n_sections)]) y_1[999] = function(1) return y_1

#Defining a function which plots both functions

This functions defines the input space, which is 1000 points equally spaced from 0 to 1. Then, it uses the piecewise_function function to define the outputs for the piecwise function. Then, it plots both functions. The outputs for the continuous function is defined simply but applying the continuous function chosen to all values in x.

def plot_piecewise(n_sections): x = np.linspace(0, 1, 1000) y = piecewise_function(x, n_sections) plt.figure(figsize=(8, 4)) ax = plt.gca() ax.set_facecolor('#17282A') plt.plot(x, y, label=f'{n_sections} sections', color="#F5F5DD") plt.plot(x, [function(i) for i in x], color='#93C280') plt.title("Approximation Using a Piecewise Constant Function in 2D") plt.xlabel("x") plt.ylabel("y") plt.grid() plt.legend() plt.show()

#Defining functions for when a function is chosen (by clicking one of three buttons)

Each of these functions are called when the corresponding button is pressed. They set the value of chosen_func to represent the correct function, which stores the choice of function. Then they call the function to plot the piecewise and continuous function, with a slider allowing the user to control the number of sections in the function.

def sin_clicked(b): global chosen_func chosen_func = 1 interact(plot_piecewise, n_sections=(1, 100, 1)) def quartic_clicked(b): global chosen_func chosen_func = 2 interact(plot_piecewise, n_sections=(1, 100, 1)) def exp_clicked(b): global chosen_func chosen_func = 3 interact(plot_piecewise, n_sections=(1, 100, 1))

#Creating buttons for choosing a continuous function

This code creates buttons for each function. When each button is pressed, it calls its corresponding function, which in turn calls a function which plots the correct graphs.

sin_button = widgets.Button(description="y=sin(6x)", layout=widgets.Layout(width='200px', height='50px'), style=widgets.ButtonStyle( button_color='black', color='black', font_weight='bold')) sin_button.on_click(sin_clicked) quartic_button = widgets.Button(description="y=0.05(7x-2)^2(7x-6)^2", layout=widgets.Layout(width='200px', height='50px'), style=widgets.ButtonStyle( button_color='black', font_weight='bold')) quartic_button.on_click(quartic_clicked) exp_button = widgets.Button(description="y=e^(x-1)", layout=widgets.Layout(width='200px', height='50px'), style=widgets.ButtonStyle( button_color='black', font_weight='bold')) exp_button.on_click(exp_clicked)

#Displaying the buttons

Finally, the buttons are displayed.

display(sin_button) display(quartic_button) display(exp_button)
Button(description='y=sin(6x)', layout=Layout(height='50px', width='200px'), style=ButtonStyle(button_color='b…
Button(description='y=0.05(7x-2)^2(7x-6)^2', layout=Layout(height='50px', width='200px'), style=ButtonStyle(bu…
Button(description='y=e^(x-1)', layout=Layout(height='50px', width='200px'), style=ButtonStyle(button_color='b…
interactive(children=(IntSlider(value=50, description='n_sections', min=1), Output()), _dom_classes=('widget-i…