Skip to content

Commit b39db29

Browse files
Update chapter 6 notebooks
1 parent c9b11e0 commit b39db29

7 files changed

+1249
-951
lines changed

notebooks/05/svm.ipynb

+129-161
Large diffs are not rendered by default.

notebooks/06/building-insulation.ipynb

+90-84
Large diffs are not rendered by default.

notebooks/06/economic-order-quantity.ipynb

+538-239
Large diffs are not rendered by default.

notebooks/06/kelly-criterion.ipynb

+45-44
Large diffs are not rendered by default.

notebooks/06/markowitz_portfolio_revisited.ipynb

+61-28
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,39 @@
2626
"\n",
2727
"This cell selects and verifies a global SOLVER for the notebook.\n",
2828
"\n",
29-
"If run on Google Colab, the cell installs Pyomo and ipopt, then sets SOLVER to \n",
30-
"use the ipopt solver. If run elsewhere, it assumes Pyomo and the Mosek solver\n",
31-
"have been previously installed and sets SOLVER to use the Mosek solver via the Pyomo \n",
32-
"SolverFactory. It then verifies that SOLVER is available."
29+
"If run on Google Colab, the cell installs Pyomo and ipopt, then sets SOLVER to use the ipopt solver. If run elsewhere, it assumes Pyomo and the Mosek solver\n",
30+
"have been previously installed and sets SOLVER to use the Mosek solver via the Pyomo SolverFactory. It then verifies that SOLVER is available."
3331
]
3432
},
3533
{
3634
"cell_type": "code",
37-
"execution_count": 45,
35+
"execution_count": 9,
3836
"id": "5da22c67-5c34-4c3a-90a4-61222899e855",
3937
"metadata": {
4038
"tags": []
4139
},
4240
"outputs": [],
4341
"source": [
4442
"import sys\n",
45-
"import os\n",
4643
"\n",
4744
"if 'google.colab' in sys.modules:\n",
4845
" !pip install idaes-pse --pre >/dev/null 2>/dev/null\n",
4946
" !idaes get-extensions --to ./bin \n",
5047
" os.environ['PATH'] += ':bin'\n",
51-
" SOLVER_CONIC = \"ipopt\"\n",
52-
" \n",
48+
" solver = \"ipopt\"\n",
5349
"else:\n",
54-
" SOLVER_CONIC = \"mosek_direct\"\n",
50+
" solver = \"mosek_direct\"\n",
5551
"\n",
5652
"import pyomo.environ as pyo\n",
57-
"if not pyo.SolverFactory(SOLVER_CONIC).available():\n",
58-
" print(f\"Solver {SOLVER_CONIC} is not available\")"
53+
"if not pyo.SolverFactory(solver).available():\n",
54+
" print(f\"Solver {solver} is not available\")\n",
55+
"else:\n",
56+
" SOLVER = pyo.SolverFactory(solver)"
5957
]
6058
},
6159
{
6260
"cell_type": "code",
63-
"execution_count": 41,
61+
"execution_count": 10,
6462
"id": "b13edf26",
6563
"metadata": {
6664
"tags": []
@@ -114,7 +112,7 @@
114112
},
115113
{
116114
"cell_type": "code",
117-
"execution_count": 42,
115+
"execution_count": 11,
118116
"id": "0e194e8d",
119117
"metadata": {
120118
"tags": []
@@ -158,7 +156,7 @@
158156
}
159157
],
160158
"source": [
161-
"# Specify the initial capital, the risk tolerance, and the guaranteed return rate. \n",
159+
"# Specify the initial capital, the risk tolerance, and the guaranteed return rate.\n",
162160
"C = 1\n",
163161
"alpha = 0.1\n",
164162
"R = 1.05\n",
@@ -172,7 +170,7 @@
172170
"assert np.all(np.linalg.eigvals(Sigma) >= 0)\n",
173171
"\n",
174172
"# If you want to change the covariance matrix Sigma, ensure you input a semi-definite positive one.\n",
175-
"# The easiest way to generate a random covariance matrix is first generating a random m x m matrix A \n",
173+
"# The easiest way to generate a random covariance matrix is first generating a random m x m matrix A\n",
176174
"# and then taking the matrix A^T A (which is always semi-definite positive)\n",
177175
"# m = 3\n",
178176
"# A = np.random.rand(m, m)\n",
@@ -184,8 +182,8 @@
184182
"# y=Ax, |y|^2 <= s,\n",
185183
"# corresponding to the mathematical formulation above.\n",
186184
"\n",
185+
"\n",
187186
"def markowitz_revisited(alpha, mu, Sigma):\n",
188-
" \n",
189187
" model = pyo.ConcreteModel(\"Markowitz portfolio optimization revisited\")\n",
190188
"\n",
191189
" model.xtilde = pyo.Var(domain=pyo.NonNegativeReals)\n",
@@ -194,7 +192,7 @@
194192
"\n",
195193
" @model.Objective(sense=pyo.maximize)\n",
196194
" def objective(m):\n",
197-
" return mu @ m.x + R * m.xtilde - alpha*m.s\n",
195+
" return mu @ m.x + R * m.xtilde - alpha * m.s\n",
198196
"\n",
199197
" @model.Constraint()\n",
200198
" def bounded_variance(m):\n",
@@ -204,20 +202,29 @@
204202
" def total_assets(m):\n",
205203
" return sum(m.x[i] for i in range(n)) + m.xtilde == C\n",
206204
"\n",
207-
" result = pyo.SolverFactory(SOLVER_CONIC).solve(model)\n",
208-
" \n",
205+
" result = SOLVER.solve(model)\n",
206+
"\n",
209207
" return result, model\n",
210208
"\n",
209+
"\n",
211210
"result, model = markowitz_revisited(alpha, mu, Sigma)\n",
212211
"\n",
213-
"display(Markdown(f\"**Solver status:** *{result.solver.status}, {result.solver.termination_condition}*\"))\n",
214-
"display(Markdown(f\"**Solution:** $\\\\tilde x = {model.xtilde.value:.3f}$, $x_1 = {model.x[0].value:.3f}$, $x_2 = {model.x[1].value:.3f}$, $x_3 = {model.x[2].value:.3f}$\"))\n",
212+
"display(\n",
213+
" Markdown(\n",
214+
" f\"**Solver status:** *{result.solver.status}, {result.solver.termination_condition}*\"\n",
215+
" )\n",
216+
")\n",
217+
"display(\n",
218+
" Markdown(\n",
219+
" f\"**Solution:** $\\\\tilde x = {model.xtilde.value:.3f}$, $x_1 = {model.x[0].value:.3f}$, $x_2 = {model.x[1].value:.3f}$, $x_3 = {model.x[2].value:.3f}$\"\n",
220+
" )\n",
221+
")\n",
215222
"display(Markdown(f\"**Maximizes objective value to:** ${model.objective():.2f}$\"))"
216223
]
217224
},
218225
{
219226
"cell_type": "code",
220-
"execution_count": 43,
227+
"execution_count": 12,
221228
"id": "9a2b00d7-433a-46c8-a4b6-c451244c9b0f",
222229
"metadata": {
223230
"tags": []
@@ -235,17 +242,43 @@
235242
}
236243
],
237244
"source": [
238-
"alpha_values = [0.005, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.25, 0.3, 0.4, 0.5]\n",
245+
"alpha_values = [\n",
246+
" 0.005,\n",
247+
" 0.01,\n",
248+
" 0.02,\n",
249+
" 0.03,\n",
250+
" 0.04,\n",
251+
" 0.05,\n",
252+
" 0.06,\n",
253+
" 0.07,\n",
254+
" 0.08,\n",
255+
" 0.09,\n",
256+
" 0.1,\n",
257+
" 0.11,\n",
258+
" 0.12,\n",
259+
" 0.13,\n",
260+
" 0.14,\n",
261+
" 0.15,\n",
262+
" 0.16,\n",
263+
" 0.17,\n",
264+
" 0.18,\n",
265+
" 0.19,\n",
266+
" 0.20,\n",
267+
" 0.25,\n",
268+
" 0.3,\n",
269+
" 0.4,\n",
270+
" 0.5,\n",
271+
"]\n",
239272
"objective = []\n",
240273
"\n",
241-
"plt.rcParams.update({'font.size': 14})\n",
274+
"plt.rcParams.update({\"font.size\": 14})\n",
242275
"for alpha in alpha_values:\n",
243276
" _, model = markowitz_revisited(alpha, mu, Sigma)\n",
244-
" objective.append(round(model.objective(),3))\n",
277+
" objective.append(round(model.objective(), 3))\n",
245278
"\n",
246279
"plt.plot(alpha_values, objective, color=plt.cm.tab20c(0))\n",
247-
"plt.xlabel(r'Risk tolerance $\\alpha$')\n",
248-
"plt.ylabel('Optimal objective value')\n",
280+
"plt.xlabel(r\"Risk tolerance $\\alpha$\")\n",
281+
"plt.ylabel(\"Optimal objective value\")\n",
249282
"plt.tight_layout()\n",
250283
"plt.show()"
251284
]
@@ -267,7 +300,7 @@
267300
"name": "python",
268301
"nbconvert_exporter": "python",
269302
"pygments_lexer": "ipython3",
270-
"version": "3.11.2"
303+
"version": "3.10.10"
271304
},
272305
"varInspector": {
273306
"cols": {

notebooks/06/optimal-growth-portfolios.ipynb

+274-263
Large diffs are not rendered by default.

notebooks/06/svm-conic.ipynb

+112-132
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)