{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "*This notebook contains material for CBE 20258 Numerical and Statistical Analysis taught at the University of Notre Dame. (c) Professors Alexander Dowling, Ryan McClarren, and Yamil Colón. This collection of notebooks [cbe-xx258](https://ndcbe.github.io/cbe-xx258) is available [on Github](https://github.com/ndcbe/cbe-xx258).*\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [1.8 Manipulating Data with Pandas](https://ndcbe.github.io/cbe-xx258/01.08-Pandas.html) | [Contents](toc.html) | [1.10 Testing and Debugging in Python](https://ndcbe.github.io/cbe-xx258/01.10-Testing-and-Debugging.html) >
"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "rG3kq9V5BPoN",
"nbpages": {
"level": 1,
"link": "[1.9 Functions as Arguments](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9-Functions-as-Arguments)",
"section": "1.9 Functions as Arguments"
}
},
"source": [
"# 1.9 Functions as Arguments"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 1,
"link": "[1.9 Functions as Arguments](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9-Functions-as-Arguments)",
"section": "1.9 Functions as Arguments"
}
},
"source": [
"**Reference**: Chapter 5 of *Computational Nuclear Engineering and Radiological Science Using Python*, R. McClarren (2018)"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[1.9.1 Learning Objectives](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.1-Learning-Objectives)",
"section": "1.9.1 Learning Objectives"
}
},
"source": [
"## 1.9.1 Learning Objectives\n",
"\n",
"After studying this notebook, completing the activities, and asking questions in class, you should be able to:\n",
"* Pass a function as an argument to a function\n",
"* Define and use lambda functions"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "am_-pu3qBPou",
"nbpages": {
"level": 2,
"link": "[1.9.2 Functions passed to Functions](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2-Functions-passed-to-Functions)",
"section": "1.9.2 Functions passed to Functions"
}
},
"source": [
"## 1.9.2 Functions passed to Functions"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[1.9.2 Functions passed to Functions](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2-Functions-passed-to-Functions)",
"section": "1.9.2 Functions passed to Functions"
}
},
"source": [
"Functions can also use other functions. In the example below, the function my_g takes my_f as an input. Try and predict its output before you run the cell.\n",
"\n",
"$$g(x) = f(x)^2 + 1$$"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"nbpages": {
"level": 2,
"link": "[1.9.2 Functions passed to Functions](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2-Functions-passed-to-Functions)",
"section": "1.9.2 Functions passed to Functions"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"101.0\n"
]
}
],
"source": [
"def my_f(x):\n",
" return (x/3)*5\n",
"\n",
"def my_g(f,x):\n",
" return f(x)**2+1\n",
"\n",
"print (my_g(my_f,6))"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "djEUym1CBPo1",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
}
},
"source": [
"### 1.9.2.1 Motivating Example: Midpoint Integration"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "KLzhDxTqBPo2",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
}
},
"source": [
"Recall the Midpoint formula for approximating an integral.\n",
"\n",
"With only one element:\n",
"\n",
"$$\\int_{a}^{b} f(x) dx \\approx f\\left(\\frac{a + b}{2}\\right) (b - a)$$\n",
"\n",
"With $N$ elements:\n",
"\n",
"$$\\int_{a}^{b} f(x) dx \\approx \\Delta x \\sum_{i=0}^{N-1} f(m_i) ~~,$$\n",
"\n",
"where $$\\Delta x = \\frac{b - a}{N} ~~,$$ and $$m_i = i \\cdot \\Delta x +\\frac{\\Delta x}{2} + a ~~.$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "qCTvbbeBBPo3",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
}
},
"source": [
"We want to integrate an **arbitrary function** using the midpoint rule. To do this, we need to evaluate the function at several values to calculate the midpoint sum.\n",
"\n",
"In the following Python code, argument ``f`` is a **function** with a scalar input and scalar output.\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 238
},
"colab_type": "code",
"executionInfo": {
"elapsed": 253,
"status": "ok",
"timestamp": 1548850752838,
"user": {
"displayName": "Alexander Dowling",
"photoUrl": "https://lh3.googleusercontent.com/-LChdQ2m5OQE/AAAAAAAAAAI/AAAAAAAAAA0/JeXJe4vQJ7M/s64/photo.jpg",
"userId": "00988067626794866502"
},
"user_tz": 300
},
"id": "qRpk6buBBPo4",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
},
"outputId": "e9b3a315-28ad-4385-9b82-d9149d9f4764"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function midpoint_rule in module __main__:\n",
"\n",
"midpoint_rule(f, a, b, num_intervals)\n",
" integrate function f using the midpoint rule\n",
" \n",
" Args:\n",
" f: function to be integrated, it must take one argument\n",
" a: lower bound of integral range\n",
" b: upper bound of integral range\n",
" num_intervals: the number of intervals to break [a,b] into\n",
" Returns:\n",
" estimate of the integral\n",
"\n"
]
}
],
"source": [
"def midpoint_rule(f,a,b,num_intervals):\n",
" \"\"\"integrate function f using the midpoint rule\n",
"\n",
" Args:\n",
" f: function to be integrated, it must take one argument\n",
" a: lower bound of integral range\n",
" b: upper bound of integral range\n",
" num_intervals: the number of intervals to break [a,b] into\n",
" Returns:\n",
" estimate of the integral\n",
" \"\"\"\n",
" L = (b-a) #how big is the range\n",
" dx = L/num_intervals #how big is each interval\n",
" #midpoints are a+dx/2, a+3dx/2, ..., b-dx/2\n",
" midpoints = np.arange(num_intervals)*dx+0.5*dx+a\n",
" integral = 0\n",
" for point in midpoints:\n",
" integral += f(point)\n",
" return integral*dx\n",
"\n",
"help(midpoint_rule)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
},
"colab_type": "code",
"executionInfo": {
"elapsed": 220,
"status": "ok",
"timestamp": 1548776116828,
"user": {
"displayName": "Alexander Dowling",
"photoUrl": "https://lh3.googleusercontent.com/-LChdQ2m5OQE/AAAAAAAAAAI/AAAAAAAAAA0/JeXJe4vQJ7M/s64/photo.jpg",
"userId": "00988067626794866502"
},
"user_tz": 300
},
"id": "FqzOO4bwPpW0",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
},
"outputId": "262bdf4f-7109-4599-f814-b20eb9384d10"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5 10.5]\n"
]
}
],
"source": [
"import numpy as np\n",
"a = 1.0\n",
"dx = 1.0\n",
"midpoints = np.arange(10)*dx+0.5*dx+a\n",
"\n",
"print(midpoints)"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "djdVleBxBPo6",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
}
},
"source": [
"Thus ``midpoint_rule`` is a function that takes another function, ``f``, as an argument (input)."
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "4ISlt7bMBPo7",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
}
},
"source": [
"Now we will approximate:\n",
"\n",
"$$\\int_0^\\pi \\sin x ~ dx$$\n",
"\n",
"using $N=10$ and the midpoint rule. The analytic solution (correct answer) is 2."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
},
"colab_type": "code",
"executionInfo": {
"elapsed": 212,
"status": "ok",
"timestamp": 1548776222243,
"user": {
"displayName": "Alexander Dowling",
"photoUrl": "https://lh3.googleusercontent.com/-LChdQ2m5OQE/AAAAAAAAAAI/AAAAAAAAAA0/JeXJe4vQJ7M/s64/photo.jpg",
"userId": "00988067626794866502"
},
"user_tz": 300
},
"id": "w_ncqQsGBPo8",
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
},
"outputId": "7b778762-97c3-4b27-fb50-5de7c2862671"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2.0082484079079745\n"
]
}
],
"source": [
"print(midpoint_rule(np.sin,0,np.pi,10))"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 3,
"link": "[1.9.2.1 Motivating Example: Midpoint Integration](https://ndcbe.github.io/cbe-xx258/01.09-Functions-as-Arguments.html#1.9.2.1-Motivating-Example:-Midpoint-Integration)",
"section": "1.9.2.1 Motivating Example: Midpoint Integration"
}
},
"source": [
"
"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [
"EjPprXYjBPog",
"JKLdQ1x6BPom"
],
"name": "L5-Dictionaries-and-Functions-as-Arguments.ipynb",
"provenance": [],
"version": "0.3.2"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}