diff --git a/book/_toc.yml b/book/_toc.yml index 5b4429f..758d4a2 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -37,8 +37,6 @@ parts: - file: features/jupyterlite/including-jupyterlite - file: features/custom_toc.md - file: features/custom_download.md - - file: features/h5p_examples.md - - file: features/theory_questions.md - file: features/h5p.md - file: features/live_code.md sections: @@ -49,8 +47,11 @@ parts: - caption: Examples chapters: - file: examples/overview + - file: examples/h5p_examples.md + - file: examples/theory_questions.md - file: examples/interactive_templates.md sections: - file: examples/example_gumbel.ipynb - file: examples/example_quiz_interactive.ipynb + - file: examples/coding_theory_widgets.ipynb - file: examples/parametric_questions.ipynb \ No newline at end of file diff --git a/book/examples/coding_theory_widgets.ipynb b/book/examples/coding_theory_widgets.ipynb new file mode 100644 index 0000000..81c8255 --- /dev/null +++ b/book/examples/coding_theory_widgets.ipynb @@ -0,0 +1,333 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Combining coding theory with interactive questions and potential live coding\n", + "\n", + "This page shows an example of how to combine the introduction of a certain coding implementation with interactive questions. Automatic executation of the thebe live coding has been enables and the download button has been replaced by a custom notebook file." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```{custom_download_link} ./Unconstrained_optimization_stripped.ipynb\n", + ":replace_default: \"True\"\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example unconstrained optimization\n", + "\n", + "In this chapter, we'll cover how to apply `scipy.optimize.minimize` to unconstrained optimization problems. As a reminder, unconstrained optimization considers:\n", + "\n", + "```{math}\n", + ":label: unconstrained_optimizatino\n", + "\n", + "\\mathop {\\min }\\limits_x f\\left( x \\right)\n", + "```\n", + "with $x$ the design variable of length $n$ and $f$ the objective function.\n", + "\n", + "\n", + "### Method\n", + "In this course, we're making use of the function `scipy.optimize.minimize`. The documentation of this function is available here: \n", + "https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html. In this course we'll cover only the relevant parts.\n", + "\n", + "For unconstrained optimization we need to run at least `scipy.optimize.minimize(fun, x0, ...)` with:\n", + "- `fun`, the objective function $f(x)$ to be minimized. `fun` is a callable. The `scipy.optmize.minimize` function takes care of defining and inputing our design variable $x$.\n", + "- `x0`, the initial guess for our design variable $x$. It needs to be a `ndarray` with length $n$\n", + "\n", + "The function `scipy.optimize.minimize` outputs an object `scipy.optimize.OptimizeResult`. with:\n", + "- `scipy.optimize.OptimizeResult.x` the optimized solution of the design variable `x`. It is a `ndarray` with length $n$\n", + "- `scipy.optimize.OptimizeResult.success`, a indication whether or not the optimizer was executed succesfully. It is a `bool`, indicating `True` or `False`\n", + "- `scipy.optimize.OptimizeResult.message`, a message describing the cause of termination of the optimizatino algorithm. It is a `str`.\n", + "- `scipy.optimize.OptimizeResult.fun`, the values of the optimized objective function $f$. It is a `int` or `float`\n", + "- `scipy.optimize.OptimizeResult.nit`, the number of iteration performed by the optimizer. It is a `int`\n", + "\n", + ":::{card}\n", + "\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 1\n", + "\n", + "#### Problem\n", + "It is desired to determine the number of bathymetry maps $n$ of a local area that should be produced to maximize the profit of a company. The total cost of production and distribution is €$75$ per unit $n$. The revenues are proportional to the number of units multiplied by its price: $Revenues = n \\cdot Price $\n", + "\n", + "The demand depends on the price ($Price = 150 - 0.01n^2$), as shown in the graph:\n", + "\n", + "```{figure} ./coding_theory_widgets_images/output.png\n", + "---\n", + "width: 600px\n", + "name: demand with respect to pice\n", + "---\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The profit can be estimated as the revenues minus the total costs." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Model\n", + "The function for the profit can be found by combining the relations in the problem statement. However, this is the profit which should be maximized. To turn this into a minimization problem, the profit can be multiplied with $-1$. The final model of this problem results in:\n", + "\n", + "```{math}\n", + ":label: unconstrained_optimization_problem\n", + "\n", + "\\mathop {\\min }\\limits_n \\left(75n - \\left( 150 - 0.01n^2 \\right) n \\right)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::{card}\n", + "\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Method\n", + "\n", + "This model is described using `scipy.optimize.minimize`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Importing libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [ + "auto-execute-page", + "thebe-init" + ] + }, + "outputs": [], + "source": [ + "import scipy as sp \n", + "import numpy as np\n", + "import matplotlib.pylab as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Defining the variables\n", + "There are very few variables in this problem. In fact, the only variable we have to specify is the initial guess for the optimization algorithm. The objective function will be treated later.\n", + "The length of $n$ doesn't have to be specified." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [ + "thebe-init" + ] + }, + "outputs": [], + "source": [ + "n0 = 20" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::{card}\n", + "\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Defining the objective function\n", + "In the objective function, the formula given in the model description can be inserted. Or, each individual step can be calculated on a seperate line. Again, note that the profit is multiplied with $-1$ to maximize the profit in the minimization formulation.\n", + "This results in:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [ + "thebe-init" + ] + }, + "outputs": [], + "source": [ + "def negprofit(n):\n", + " price = 150 - 0.01 * n**2\n", + " revenues = price * n\n", + " totalcost = 75 * n\n", + " profit = revenues - totalcost\n", + " return -profit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Solving the problem\n", + "Now, the problem can be solved. The result is stored in the variables `result` which is printed." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [ + "thebe-init" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Optimization terminated successfully.\n", + " success: True\n", + " status: 0\n", + " fun: -2499.9999999998727\n", + " x: [ 5.000e+01]\n", + " nit: 8\n", + " jac: [ 0.000e+00]\n", + " hess_inv: [[ 3.503e-01]]\n", + " nfev: 22\n", + " njev: 11\n" + ] + } + ], + "source": [ + "result = sp.optimize.minimize(negprofit,n0)\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::{card}\n", + "\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Postprocessing\n", + "As this case is only one-dimensional and the potential range of values is limited, we can easily check this answer by an exhaustive search, evaluating all possible values for $n$. The plot below shows the $\\text{negative profit}$ for $0" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "n_range = np.linspace(0,100,100)\n", + "negprofit_result = negprofit(n_range)\n", + "plt.plot(n_range,negprofit_result)\n", + "plt.plot(result.x,result.fun,'o');\n", + "plt.xlabel('$n$')\n", + "plt.ylabel('Negative profit');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::{card}\n", + "\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercise\n", + "\n", + ":::{card}\n", + "Adapt the code to answer the following questions.\n", + "\n", + "\n", + "\n", + "\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.9.18" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/examples/example_gumbel.py b/book/examples/example_gumbel.py new file mode 100644 index 0000000..a2c1337 --- /dev/null +++ b/book/examples/example_gumbel.py @@ -0,0 +1,61 @@ +from grading import check +from math import isclose + +tolerance = 0.001 + +# Using rel_tol is more reliable in the face of aliasing, but to fit the instructions give we use abs_total +check_float = lambda a, b: isclose(a, b, rel_tol=0, abs_tol=tolerance) + +# We have to pass in the globals object since we need to have access to changes as well +@check +def check_example(glob): + mu, beta = glob["mu"], glob["beta"] + if (check_float(mu, -1.7461520011511888) and check_float(beta, 2.553428469837263)): + print(f"Part 1: you got the parameters right, well done! (checked with tolerance {tolerance})") + else: + print(f"Part 1: your parameters are incorrect. (checked with tolerance {tolerance})") + print(f" Other parts won't be graded until these are fixed. ") + return + + function = glob["find_x_with_probability_p"] + + test_inputs = [(1 - 0.001, 15.891029744351862), (1 - 0.2, 2.0838374640878863), (1 - 0.9, -3.875794191615308)] + failed = [] + + for x, out in test_inputs: + result = function(x) + if not check_float(result, out): + failed.append((x, out, result)) + + if len(failed) == 0: + print(f"Part 2: Well done, your inverse function is correct! (checked with tolerance {tolerance})") + else: + print(f"Part 2: Your function failed some tests. Keep in mind the tolerance is {tolerance}") + print(" --> Failed inputs:") + for case in failed: + print(f"{case[0]} gave {case[2]}, expected {case[1]}") + print(f" Other parts won't be graded until these are fixed.") + + x = glob["x"] + if check_float(x, 15.891029744351862): + print(f"Part 3: you got the value of x right, well done! (checked with tolerance {tolerance})") + else: + print(f"Part 3: your value of x is incorrect. (checked with tolerance {tolerance})") + return +""" +Task 0: +x_1 = 4 +p_1 = 1 - .1 +x_2 = 10 +p_2 = 1 - .01 + +Task 1: + beta = -(x_2 - x_1) / log(log(p_2) / log(p_1)) + mu = x_1 + beta * log(-log(p_1)) + +Task 2: +x = mu - beta * log(-log(p)) + +Task 3: +x = find_x_with_probability_p(1 - 0.001) +""" \ No newline at end of file diff --git a/book/features/h5p_examples.md b/book/examples/h5p_examples.md similarity index 100% rename from book/features/h5p_examples.md rename to book/examples/h5p_examples.md diff --git a/book/features/theory_questions.md b/book/examples/theory_questions.md similarity index 99% rename from book/features/theory_questions.md rename to book/examples/theory_questions.md index 0af474b..5f6aeba 100644 --- a/book/features/theory_questions.md +++ b/book/examples/theory_questions.md @@ -6,10 +6,6 @@ This page shows you how to combine theory with questions, so there's no coding i ``` ## Truss structures -```{contents} -:local: -``` - Truss structures are structures assembled of straight elements connected in nodes. These elements partly create triangles, which are of importance for its deformability. Of course, the structures you'll design shouldn't deform, so it's crucial to understand this topic. ### Examples truss structures diff --git a/book/features/theory_questions_images/Truss1.svg b/book/examples/theory_questions_images/Truss1.svg similarity index 100% rename from book/features/theory_questions_images/Truss1.svg rename to book/examples/theory_questions_images/Truss1.svg diff --git a/book/features/theory_questions_images/gifje.gif b/book/examples/theory_questions_images/gifje.gif similarity index 100% rename from book/features/theory_questions_images/gifje.gif rename to book/examples/theory_questions_images/gifje.gif diff --git a/book/features/theory_questions_images/pic0.jpg b/book/examples/theory_questions_images/pic0.jpg similarity index 100% rename from book/features/theory_questions_images/pic0.jpg rename to book/examples/theory_questions_images/pic0.jpg diff --git a/book/features/theory_questions_images/pic1.jpg b/book/examples/theory_questions_images/pic1.jpg similarity index 100% rename from book/features/theory_questions_images/pic1.jpg rename to book/examples/theory_questions_images/pic1.jpg diff --git a/book/features/theory_questions_images/rectangle.svg b/book/examples/theory_questions_images/rectangle.svg similarity index 100% rename from book/features/theory_questions_images/rectangle.svg rename to book/examples/theory_questions_images/rectangle.svg diff --git a/book/features/theory_questions_images/structure3.svg b/book/examples/theory_questions_images/structure3.svg similarity index 100% rename from book/features/theory_questions_images/structure3.svg rename to book/examples/theory_questions_images/structure3.svg diff --git a/book/features/theory_questions_images/triangle.svg b/book/examples/theory_questions_images/triangle.svg similarity index 100% rename from book/features/theory_questions_images/triangle.svg rename to book/examples/theory_questions_images/triangle.svg