Skip to content

Commit

Permalink
Merge pull request #144 from jtzhanguw/HW8_branch
Browse files Browse the repository at this point in the history
HW8
  • Loading branch information
jakevdp committed Dec 2, 2014
2 parents fc9216a + 00228e7 commit 68a842c
Showing 1 changed file with 258 additions and 0 deletions.
258 changes: 258 additions & 0 deletions jtzhanguw/HW8.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
{
"metadata": {
"name": "",
"signature": "sha256:5bd0ba64ceca92c6049b68f2e268ea323e093d066f5c6e1dbd4233398295a611"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Homework\n",
"Below is a script taken from [scipy lectures](http:https://scipy-lectures.github.io/advanced/debugging/)\n",
"\n",
"It is meant to compare the performance of several root-finding algorithms within the ``scipy.optimize``\n",
"package, but it breaks. Use one or more of the above tools to figure out what's going on and to fix\n",
"the script.\n",
"\n",
"When you turn in this homework (via github pull request, of course), please **write a one to two paragraph summary**\n",
"of the process you used to debug this, including any dead ends (it may help to take notes as you go)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"``` python\n",
"\"\"\"\n",
"A script to compare different root-finding algorithms.\n",
"\n",
"This version of the script is buggy and does not execute. It is your task\n",
"to find an fix these bugs.\n",
"\n",
"The output of the script sould look like:\n",
"\n",
" Benching 1D root-finder optimizers from scipy.optimize:\n",
" brenth: 604678 total function calls\n",
" brentq: 594454 total function calls\n",
" ridder: 778394 total function calls\n",
" bisect: 2148380 total function calls\n",
"\"\"\"\n",
"from itertools import product\n",
"\n",
"import numpy as np\n",
"from scipy import optimize\n",
"\n",
"FUNCTIONS = (np.tan, # Dilating map\n",
" np.tanh, # Contracting map\n",
" lambda x: x**3 + 1e-4*x, # Almost null gradient at the root\n",
" lambda x: x+np.sin(2*x), # Non monotonous function\n",
" lambda x: 1.1*x+np.sin(4*x), # Fonction with several local maxima\n",
" )\n",
"\n",
"OPTIMIZERS = (optimize.brenth, optimize.brentq,\n",
" optimize.ridder, optimize.bisect)\n",
"\n",
"\n",
"def apply_optimizer(optimizer, func, a, b):\n",
" \"\"\" Return the number of function calls given an root-finding optimizer, \n",
" a function and upper and lower bounds.\n",
" \"\"\"\n",
" return optimizer(func, a, b, full_output=True)[1].function_calls,\n",
"\n",
"\n",
"def bench_optimizer(optimizer, param_grid):\n",
" \"\"\" Find roots for all the functions, and upper and lower bounds\n",
" given and return the total number of function calls.\n",
" \"\"\"\n",
" return sum(apply_optimizer(optimizer, func, a, b)\n",
" for func, a, b in param_grid)\n",
"\n",
"\n",
"def compare_optimizers(optimizers):\n",
" \"\"\" Compare all the optimizers given on a grid of a few different\n",
" functions all admitting a signle root in zero and a upper and\n",
" lower bounds.\n",
" \"\"\"\n",
" random_a = -1.3 + np.random.random(size=100)\n",
" random_b = .3 + np.random.random(size=100)\n",
" param_grid = product(FUNCTIONS, random_a, random_b)\n",
" print(\"Benching 1D root-finder optimizers from scipy.optimize:\")\n",
" for optimizer in OPTIMIZERS:\n",
" ncalls = bench_optimizer(optimizer, param_grid)\n",
" print('{name}: {ncalls} total function calls'.format(\n",
" name=optimizer.__name__, ncalls=ncalls))\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" compare_optimizers(OPTIMIZERS)\n",
"```"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from itertools import product\n",
"\n",
"import numpy as np\n",
"from scipy import optimize"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 19
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"FUNCTIONS = (np.tan, # Dilating map\n",
" np.tanh, # Contracting map\n",
" lambda x: x**3 + 1e-4*x, # Almost null gradient at the root\n",
" lambda x: x+np.sin(2*x), # Non monotonous function\n",
" lambda x: 1.1*x+np.sin(4*x), # Fonction with several local maxima\n",
" )"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 20
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"OPTIMIZERS = (optimize.brenth, optimize.brentq,\n",
" optimize.ridder, optimize.bisect)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 21
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def apply_optimizer(optimizer, func, a, b):\n",
" \"\"\" Return the number of function calls given an root-finding optimizer, \n",
" a function and upper and lower bounds.\n",
" \"\"\"\n",
" return optimizer(func, a, b, full_output=True)[1].function_calls\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 22
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def bench_optimizer(optimizer, param_grid):\n",
" \"\"\" Find roots for all the functions, and upper and lower bounds\n",
" given and return the total number of function calls.\n",
" \"\"\"\n",
" return sum(apply_optimizer(optimizer, func, a, b)\n",
" for func, a, b in param_grid)\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def compare_optimizers(optimizers):\n",
" \"\"\" Compare all the optimizers given on a grid of a few different\n",
" functions all admitting a signle root in zero and a upper and\n",
" lower bounds.\n",
" \"\"\"\n",
" random_a = -1.3 + np.random.random(size=100)\n",
" random_b = .3 + np.random.random(size=100)\n",
" print(\"Benching 1D root-finder optimizers from scipy.optimize:\")\n",
" for optimizer in OPTIMIZERS:\n",
" param_grid = product(FUNCTIONS, random_a, random_b)\n",
" ncalls = bench_optimizer(optimizer, param_grid)\n",
" print('{name}: {ncalls} total function calls'.format(\n",
" name=optimizer.__name__, ncalls=ncalls))\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" compare_optimizers(OPTIMIZERS)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Benching 1D root-finder optimizers from scipy.optimize:\n",
"brenth: 605758 total function calls"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"brentq: 594716 total function calls"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"ridder: 775608 total function calls"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"bisect: 2150110 total function calls"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 24
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When I ran the script, firstly it failed and showed that \"unsupported operand type(s) for +: 'int' and 'tuple'\", because the sum function in bench_optimizer cannot operate on tuples. It means that the type apply_optimizer function returns has a problem. I removed the comma at the end of \"optimizer(func, a, b, full_output=True)[1].function_calls\" in apply_optimizer function, then it worked, but only for brenth, not for the other brentq, ridder and bisect. \n",
"\n",
"Secondly, I moved the \"param_grid = product(FUNCTIONS, random_a, random_b)\n",
"\" into for loop and then it is working now."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}

0 comments on commit 68a842c

Please sign in to comment.