{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Basic Julia Tutorial"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Running/Installing Julia\n",
"\n",
"This is a notebook. To run in you need Julia and jupyter or nteract (see below).\n",
"\n",
"1. To run Julia without a local installation, use (for instance) [CoCalc](https://cocalc.com).\n",
"\n",
"2. To install Julia on your machine, [download and install it](https://julialang.org/downloads/). \n",
"\n",
"3. You may also want to use [VS Code with the Julia extension](https://github.com/julia-vscode/julia-vscode) IDE. See also the [julia-vscode.org](https://www.julia-vscode.org/) for more information.\n",
"\n",
"4. To run notebooks with either jupyter or nteract from your local installation, see [IJulia](https://github.com/JuliaLang/IJulia.jl) for instructions. See also below for some hints.\n",
"\n",
"5. As an alternative to jupyter/nteract you can also run notebooks in VS Code (see above).\n",
"\n",
"\n",
"\n",
"## More Details on Installing jupyter and nteract\n",
"\n",
"1. If you want to use nteract do as follows: install IJulia, but do *not* call on `notebook()` to avoid the automatic Python installation. Then install nteract.\n",
"\n",
"2. After installing IJulia and issuing the command `notebook()` a new local Python installation will be made - unless IJulia finds an existing installation.\n",
"\n",
"3. If you already have a Python installation, run `ENV[\"JUPYTER\"] = \"C:\\\\Miniconda3\\\\Scripts\\\\jupyter.exe\"` (change the path as needed) before you install IJulia. The best is perhaps to add this to your startup.jl file (~/.julia/config/startup.jl, for instance, C:\\Users\\yourusername\\.julia\\config\\startup.jl if you are on Windows). You can test whether it works by running ```run(`$(ENV[\"JUPYTER\"]) --version`)``` from the Julia REPL.\n",
"\n",
"4. On Windows, it helps to allow the Python installer to add python to the system path."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Documentation and Help\n",
"\n",
"1. Cheat sheet at [QuantEcon](https://cheatsheets.quantecon.org/julia-cheatsheet.html)\n",
"2. [Wiki book](https://en.wikibooks.org/wiki/Introducing_Julia)\n",
"3. [Short tutorials](https://techytok.com/from-zero-to-julia/) \n",
"4. [ThinkJulia](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html) is a free on-line book\n",
"5. The [official Julia on-line manual](https://docs.julialang.org)\n",
"6. Discussion lists are found at\n",
" * https://discourse.julialang.org/\n",
" * https://stackoverflow.com/questions/tagged/julia-lang\n",
" * https://www.reddit.com/r/Julia/\n",
" * https://gitter.im/JuliaLang/julia\n",
"7. In Julia, do ```? cos``` to get help with the cos function "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# About Notebooks\n",
"\n",
"This cell is a \"Markdown\" cell. This is meant for comments and documentation, not computations.\n",
"\n",
"You can change a cell to \"Code\" or \"Markdown\" in the menu.\n",
"\n",
"Markdown cells can handle LaTeX. An example: $\\alpha = \\beta/2$. A Markdown cell can also contain some *formatting*, like lists of this kind\n",
"\n",
"1. To insert a new cell, use the menu. \n",
"\n",
"2. The next cell is \"Code\". You can run it. Text after a # sign is treated as a comment.\n",
"\n",
"3. The subsequent cell shows how to get help on a command."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = 2 #this is a comment\n",
" #run this cell by using the menu, or by Shift+Enter"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"search: \u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22m \u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22mh \u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22md \u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22mc \u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22mpi a\u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22m a\u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22mh a\u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22md sin\u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22m sin\u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22md sin\u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22m\u001b[0m\u001b[1ms\u001b[22mpi \u001b[0m\u001b[1mc\u001b[22m\u001b[0m\u001b[1mo\u001b[22mn\u001b[0m\u001b[1ms\u001b[22mt\n",
"\n"
]
},
{
"data": {
"text/latex": [
"\\begin{verbatim}\n",
"cos(x)\n",
"\\end{verbatim}\n",
"Compute cosine of \\texttt{x}, where \\texttt{x} is in radians.\n",
"\n",
"\\rule{\\textwidth}{1pt}\n",
"\\begin{verbatim}\n",
"cos(A::AbstractMatrix)\n",
"\\end{verbatim}\n",
"Compute the matrix cosine of a square matrix \\texttt{A}.\n",
"\n",
"If \\texttt{A} is symmetric or Hermitian, its eigendecomposition (\\href{@ref}{\\texttt{eigen}}) is used to compute the cosine. Otherwise, the cosine is determined by calling \\href{@ref}{\\texttt{exp}}.\n",
"\n",
"\\section{Examples}\n",
"\\begin{verbatim}\n",
"julia> cos(fill(1.0, (2,2)))\n",
"2×2 Matrix{Float64}:\n",
" 0.291927 -0.708073\n",
" -0.708073 0.291927\n",
"\\end{verbatim}\n"
],
"text/markdown": [
"```\n",
"cos(x)\n",
"```\n",
"\n",
"Compute cosine of `x`, where `x` is in radians.\n",
"\n",
"---\n",
"\n",
"```\n",
"cos(A::AbstractMatrix)\n",
"```\n",
"\n",
"Compute the matrix cosine of a square matrix `A`.\n",
"\n",
"If `A` is symmetric or Hermitian, its eigendecomposition ([`eigen`](@ref)) is used to compute the cosine. Otherwise, the cosine is determined by calling [`exp`](@ref).\n",
"\n",
"# Examples\n",
"\n",
"```jldoctest\n",
"julia> cos(fill(1.0, (2,2)))\n",
"2×2 Matrix{Float64}:\n",
" 0.291927 -0.708073\n",
" -0.708073 0.291927\n",
"```\n"
],
"text/plain": [
"\u001b[36m cos(x)\u001b[39m\n",
"\n",
" Compute cosine of \u001b[36mx\u001b[39m, where \u001b[36mx\u001b[39m is in radians.\n",
"\n",
" ────────────────────────────────────────────────────────────────────────────\n",
"\n",
"\u001b[36m cos(A::AbstractMatrix)\u001b[39m\n",
"\n",
" Compute the matrix cosine of a square matrix \u001b[36mA\u001b[39m.\n",
"\n",
" If \u001b[36mA\u001b[39m is symmetric or Hermitian, its eigendecomposition (\u001b[36meigen\u001b[39m) is used to\n",
" compute the cosine. Otherwise, the cosine is determined by calling \u001b[36mexp\u001b[39m.\n",
"\n",
"\u001b[1m Examples\u001b[22m\n",
"\u001b[1m ≡≡≡≡≡≡≡≡≡≡\u001b[22m\n",
"\n",
"\u001b[36m julia> cos(fill(1.0, (2,2)))\u001b[39m\n",
"\u001b[36m 2×2 Matrix{Float64}:\u001b[39m\n",
"\u001b[36m 0.291927 -0.708073\u001b[39m\n",
"\u001b[36m -0.708073 0.291927\u001b[39m"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"? cos #to get help on the cos() function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Load Packages and Extra Functions\n",
"\n",
"There are many packages for Julia, for instance, for plotting or statistical methods (see [JuliaHub](https://juliahub.com/) for a list). To install a package, you do either \n",
"\n",
"1. (works everywhere) run `import Pkg` and then `Pkg.add(\"Packagename\")`\n",
"\n",
"2. (works in the Julia console, REPL) enter the \"package manager mode\" by typing `]`, then run `add PackageName`. You leave the package manager mode by ctrl-c or backspace.\n",
"\n",
"Once a package is installed, you can use it by running\n",
"\n",
"```\n",
"using PackageName\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"printyellow (generic function with 1 method)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using Printf\n",
"\n",
"include(\"jlFiles/printmat.jl\") #just a function for prettier matrix printing"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"using Plots #this loads the Plots package\n",
"\n",
"#pyplot(size=(600,400)) #choice of plotting backend\n",
"gr(size=(480,320))\n",
"default(fmt = :svg) #try :png or :svg"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Scalars and Matrices\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create a Scalar and a Matrix"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"q is a scalar. To print, use println() or printlnPs()\n",
"1\n",
"\n",
"Q is a matrix. To print, use display() or printmat()\n",
" 1 2 3 \n",
" 4 5 6 \n",
"\n"
]
}
],
"source": [
"q = 1 #create a scalar\n",
"Q = [ 1 2 3; #create 2x3 matrix\n",
" 4 5 6 ] \n",
"println(\"q is a scalar. To print, use println() or printlnPs()\")\n",
"println(q)\n",
"\n",
"println(\"\\nQ is a matrix. To print, use display() or printmat()\")\n",
"printmat(Q) #case sensitive (q and Q are different)\n",
" #the \\n adds a line break"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Picking Out Parts of a Matrix"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"element [1,2] of Q: 2\n",
"\n",
"columns 2 and 3 of Q: \n",
" 2 3 \n",
" 5 6 \n",
"\n",
"\n",
"line 1 of Q (as a vector): \n",
" 1 \n",
" 2 \n",
" 3 \n",
"\n"
]
}
],
"source": [
"println(\"\\n\",\"element [1,2] of Q: \", #commands continue on\n",
" Q[1,2]) #the next line (until finished)\n",
"\n",
"println(\"\\ncolumns 2 and 3 of Q: \")\n",
"printmat(Q[:,2:3])\n",
"\n",
"println(\"\\nline 1 of Q (as a vector): \")\n",
"printmat(Q[1,:])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"Create a 2x2 matrix A\n",
"\n",
"```\n",
"10 10\n",
"21 22\n",
"```\n",
"\n",
"Print it\n",
"\n",
"Change the second row to `[1 2]`. Print again."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 10 10 \n",
" 21 22 \n",
"\n",
" 10 10 \n",
" 1 2 \n",
"\n"
]
}
],
"source": [
"A = [10 10;\n",
" 21 22]\n",
"printmat(A)\n",
"A[2,:] = [1 2]\n",
"printmat(A)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Basic Linear Algebra\n",
"\n",
"The syntax for linear algebra is similar to the standard text book approach. For instance, \n",
"* `Q'Q` (or `Q'*Q`) multiplies the transpose ($Q'$) with the matrix ($Q$)\n",
"* `A*B` does matrix multiplication\n",
"* `100*Q` multiplies each element of the matrix ($Q$) by 100. (You can also do `100Q`.)\n",
"\n",
"However, to add a scalar to each element of a matrix, use `100 .+ Q`. Notice the dot."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"transpose of Q:\n",
" 1 4 \n",
" 2 5 \n",
" 3 6 \n",
"\n",
"Q'Q:\n",
" 17 22 27 \n",
" 22 29 36 \n",
" 27 36 45 \n",
"\n",
"scalar * matrix:\n",
" 100 200 300 \n",
" 400 500 600 \n",
"\n",
"scalar .+ matrix:\n",
" 101 102 103 \n",
" 104 105 106 \n",
"\n"
]
}
],
"source": [
"println(\"transpose of Q:\")\n",
"printmat(Q')\n",
"\n",
"println(\"Q'Q:\")\n",
"printmat(Q'Q)\n",
"\n",
"println(\"scalar * matrix:\")\n",
"printmat(100*Q)\n",
"\n",
"println(\"scalar .+ matrix:\") #notice the dot\n",
"printmat(100 .+ Q)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"Consider the system of linear equations\n",
"\n",
"$\n",
"Ax = q\n",
"$, \n",
"\n",
"where \n",
"$ \n",
"q = \\begin{bmatrix} 1 \\\\2 \\end{bmatrix}\n",
"$\n",
"\n",
"You could solve it as\n",
"$\n",
"x = A^{-1}q\n",
"$\n",
"\n",
"\n",
"Solve (numrically) for the vector $x$. Hint: `inv()` Then check that $Ax$ indeed equals $q$"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" x\n",
" -1.800\n",
" 1.900\n",
"\n",
" A*x q\n",
" 1.000 1.000\n",
" 2.000 2.000\n",
"\n"
]
}
],
"source": [
"\n",
"\n",
"\n",
"q = [1,2]\n",
"x = inv(A)*q\n",
"printmat(x,colNames=[\"x\"])\n",
"\n",
"printmat([A*x q],colNames=[\"A*x\",\"q\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating a Sequence and a Vector"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"θ is a sequence: 1:10:21\n",
"\n",
"ρ is a vector: \n",
" 1 \n",
" 11 \n",
" 21 \n",
"\n"
]
}
],
"source": [
"θ = 1:10:21 #a range, type \\theta[TAB] to get this symbol\n",
"println(\"\\n\",\"θ is a sequence: \",θ)\n",
"\n",
"ρ = collect(θ) #make the sequence into a vector, \\rho[TAB]\n",
"println(\"\\n\",\"ρ is a vector: \")\n",
"printmat(ρ)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"Create a sequence $\\alpha$ which starts at 0 and ends at 1, taking 11 steps. (Hint: you can also use `range()`)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.000\n",
" 0.100\n",
" 0.200\n",
" 0.300\n",
" 0.400\n",
" 0.500\n",
" 0.600\n",
" 0.700\n",
" 0.800\n",
" 0.900\n",
" 1.000\n",
"\n"
]
}
],
"source": [
"α = 0:0.1:1\n",
"#α = range(0,1,length=11)\n",
"printmat(α)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Comparing Things\n",
"\n",
"To see if the scalar z <= 0, do \n",
"```\n",
"vv = z <= 0\n",
"```\n",
"to get a single output (true or false).\n",
"\n",
"Instead, if x is an array, do \n",
"```\n",
"vv = x .<= 0 #notice the dot.\n",
"```\n",
"to get an array of outputs (same dimension as x)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x values: \n",
" -1.500\n",
" -1.000\n",
" -0.500\n",
" 0.000\n",
" 0.500\n",
"\n",
"true if x is in (-1,0]: \n",
" 0 \n",
" 0 \n",
" 1 \n",
" 1 \n",
" 0 \n",
"\n",
"x values that are in (-1,0]: \n",
" -0.500\n",
" 0.000\n",
"\n"
]
}
],
"source": [
"x = [-1.5,-1.0,-0.5,0,0.5] #this is a vector\n",
"\n",
"println(\"x values: \")\n",
"printmat(x)\n",
"\n",
"vv = -1 .< x .<= 0 #true for x values (-1,0], vv is a vector\n",
"println(\"true if x is in (-1,0]: \")\n",
"printmat(vv)\n",
"\n",
"x2 = x[vv] #x values for which vv==true\n",
"println(\"x values that are in (-1,0]: \")\n",
"printmat(x2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"Which elements of $\\alpha$ are (weakly) between 0.6 and 0.99?"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" vv[-1.5, -1.0, -0.5, 0.0, 0.5]\n",
" 0 0.000\n",
" 0 0.100\n",
" 0 0.200\n",
" 0 0.300\n",
" 0 0.400\n",
" 0 0.500\n",
" 1 0.600\n",
" 1 0.700\n",
" 1 0.800\n",
" 1 0.900\n",
" 0 1.000\n",
"\n"
]
}
],
"source": [
"vv = 0.6 .<= α .<= 0.99\n",
"printmat(vv,α,colNames=[\"vv\",x])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Finding Things\n",
"\n",
"can be done by, for instance, `findfirst()`, `findall()` and `indexin()`. \n",
"\n",
"Instead, if you just need to check if the number `z` is in an array (or any collection) `x`, then use `in(z,x)`."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x values: \n",
" -1.500\n",
" -1.000\n",
" -0.500\n",
" 0.000\n",
" 0.500\n",
"\n",
"(first) index v in x such x[v]==0: 4\n",
"\n",
"all indices v in x such x[v]>=0: \n",
" 4 \n",
" 5 \n",
"\n",
"\n",
"indices in x so that x[v] equals the vector y=[-1.0, 0.0]: \n",
" 2 \n",
" 4 \n",
"\n",
"\n",
"testing if 0 is in x: true\n"
]
}
],
"source": [
"x = [-1.5,-1.0,-0.5,0,0.5] #this is a vector\n",
"\n",
"println(\"x values: \")\n",
"printmat(x)\n",
"\n",
"v1 = findfirst(x.==0)\n",
"println(\"(first) index v in x such x[v]==0: \",v1)\n",
"\n",
"v2 = findall(x.>=0)\n",
"println(\"\\nall indices v in x such x[v]>=0: \")\n",
"printmat(v2)\n",
"\n",
"y = [-1.0,0]\n",
"v3 = indexin(y,x)\n",
"println(\"\\nindices in x so that x[v] equals the vector y=$y: \")\n",
"printmat(v3)\n",
"\n",
"v4 = in(0,x)\n",
"println(\"\\ntesting if 0 is in x: \",v4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# if-else\n",
"\n",
"allows you to run different comman ddepending on a condition which you specify.\n",
"\n",
"(extra) There are also other (more compact) possibilities for `if-else` case\n",
"\n",
"1. `y = ifelse(z <= 2,z,2)` or \n",
"2. `z <= 2 ? y = z : y = 2`\n",
"(In this partcular case, `y=minimum(z,2)` also works.)\n",
"\n",
"You can also insert an `ifelse` command."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.05\n"
]
}
],
"source": [
"z = 1.05\n",
"\n",
"if z <= 2 #(a) if true, run the next command (y=z) and then jump to end\n",
" y = z\n",
"else #(b) if (a) is false, do this instead\n",
" y = 2\n",
"end\n",
"\n",
"#y = ifelse(z <= 2,z,2) #these two versions also work\n",
"#z <= 2 ? y = z : y = 2\n",
"\n",
"println(y)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.05\n"
]
}
],
"source": [
"if z < 1 #(a) if true, run the next command (y=1) and then jump to end\n",
" y = 1\n",
"elseif 1 <= z <= 2 #(b) if (a) is false, try this instead \n",
" y = z\n",
"else #(c) if also (b) is false, do this\n",
" y = 2\n",
"end\n",
"\n",
"println(y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"\n",
"Use `if-else` to calculate the tax paid by someone with an income of $X$. The tax schedule is progressive so the first 100 of the income pays 40% tax, while income above 100 has a marginal tax rate of 0.6 (that is, $X-100$ pays 60% if $X>100)$. What is the total tax paid and the average tax rate.\n",
"Report the results for an income of 150."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 70.000 0.467\n",
"\n"
]
}
],
"source": [
"X = 150\n",
"\n",
"if X <= 100\n",
" tax = 0.4*X\n",
"else\n",
" tax = 0.4*100 + 0.6*(X-100)\n",
"end\n",
"\n",
"avgtax = tax/X\n",
"printmat(tax,avgtax)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Loops\n",
"\n",
"The are two types of loops: \"for loops\" and \"while loops\". \n",
"\n",
"The *for loop* is best when you know how many times you want to loop (for instance, over all $m$ rows in a matrix). \n",
"\n",
"The *while loop* is best when you want to keep looping until something happens, for instance, that $x_0$ and $x_1$ get really close.\n",
"\n",
"The default behaviour in *IJulia*, *inside functions* and at the *REPL* promt is that assignments of `x` inside the loop overwrites `x` defined before the loop. To get the same behavior in scripts, you need to add `global x` somewhere inside the loop.\n",
"\n",
"To make sure that the `y` calculated inside the loop does not affect `y` outside the loop, add `local y`.\n",
"\n",
"A variable (here `z2`) that does not exist before the loop is local to the loop."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### A Simple \"for loop\"\n",
"\n",
"The \"for loop\" in the next cell makes 3 iterations and changes a global $x$ variable."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"i=3, x=3 and z2=-998\n",
"i=6, x=9 and z2=-998\n",
"i=9, x=18 and z2=-998\n",
"\n",
"After loop: x=18 and y=-999\n"
]
}
],
"source": [
"x = 0\n",
"y = -999\n",
"for i = 3:3:9 #or `i in 3:3:9`, or `v=[3,6,9]; i in v`\n",
" #global x #only needed in script\n",
" local y #don't overwrite y outside loop\n",
" x = x + i #adding i to the \"old\" x\n",
" y = i\n",
" z2 = -998 #notice: z2 has not been used before \n",
" println(\"i=$i, x=$x and z2=$z2\") #$x prints the value of x\n",
"end\n",
"\n",
"println(\"\\nAfter loop: x=$x and y=$y\")\n",
"#println(z2) #does not work: z2 is local to the loop"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"You have the following financial data\n",
"\n",
"```\n",
"P = [100;108;109] #price series, after dividends\n",
"D = [0;2;0] #dividends\n",
"```\n",
"\n",
"For each $t$, calculate the returns\n",
"\n",
"$\n",
"R_t = (P_t+D_t)/P_{t-1} - 1\n",
"$,\n",
"\n",
"by using a loop."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Return\n",
"period 2 0.100\n",
"period 3 0.009\n",
"\n"
]
}
],
"source": [
"P = [100;108;109] #price series, after dividends\n",
"D = [0;2;0] #dividends\n",
"\n",
"R = zeros(length(P)) #where to store the results\n",
"for t = 2:length(P) #P[2] is the 2nd element of P \n",
" R[t] = (P[t] + D[t])/P[t-1] - 1\n",
"end\n",
"R = R[2:end]\n",
"\n",
"printmat(R,colNames=[\"Return\"],rowNames=string.(\"period \",2:3))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### A Double \"for loop\"\n",
"\n",
"An example of a nested for for loop\n",
"\n",
"```\n",
"for j = 1:n, i = 1:m\n",
" #do something\n",
"end\n",
"```\n",
"\n",
"If you prefer, could also write a longer version to do the same thing\n",
"```\n",
"for j = 1:n \n",
" for i = 1:m\n",
" #do something\n",
" end \n",
"end\n",
"```\n",
"\n",
"The next cell uses a double loop to fill a matrix. "
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"new x matrix: \n",
"\n",
" 11 12 13 \n",
" 21 22 23 \n",
" 31 32 33 \n",
" 41 42 43 \n",
"\n"
]
}
],
"source": [
"(m,n) = (4,3) #same as m=4;n=3\n",
"x = fill(-999,(m,n)) #to put results in, initialized as -999\n",
"for i = 1:m, j = 1:n\n",
" x[i,j] = 10*i + j\n",
"end\n",
"\n",
"println(\"new x matrix: \\n\")\n",
"printmat(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A Simple \"while loop\"\n",
"\n",
"The \"while loop\" in the next cell iterates until two variables ($x_0$ and $x_1$) get close.\n",
"\n",
"The background to the example is that we want to solve a function $f(x)=x^2$ for the $x$ value that makes $f(x)=2$. The Newton-Raphson algorithm starts with a value $x_0$ and updates it to\n",
"$\n",
"x_1 = x_0 + (2-f(x_0))/f'(x_0)\n",
"$\n",
"where $f'(x_0)$ is the derivative of $f()$ evaluated at $x_0$. The algorithm iterates until $x_0$ and $x_1$ are close. Clearly, we are trying to find the square root of 2."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Solving x^2 = 2 with Newton-Raphson:\n",
"\n",
" 10 is changed to 5.100\n",
" 5.100 is changed to 2.746\n",
" 2.746 is changed to 1.737\n",
" 1.737 is changed to 1.444\n",
" 1.444 is changed to 1.415\n",
" 1.415 is changed to 1.414\n",
"\n",
"The result should be close to 1.414\n"
]
}
],
"source": [
"println(\"Solving x^2 = 2 with Newton-Raphson:\\n\")\n",
"\n",
"x₀ = Inf #x\\_0[TAB]\n",
"x₁ = 10\n",
"\n",
"while abs(x₁-x₀) > 0.001 #keep going until they get similar\n",
" #global x₀, x₁ #only needed in script\n",
" local y, dy #don't overwrite any y,dy outside loop\n",
" x₀ = x₁ #initial guess is taken from old guess\n",
" y = x₀^2 #value of function\n",
" dy = 2*x₀ #derivative of function\n",
" x₁ = x₀ + (2 - y)/dy #updating the guess, Newton-Raphson\n",
" printlnPs(x₀,\" is changed to \",x₁)\n",
"end\n",
"\n",
"printlnPs(\"\\nThe result should be close to \",sqrt(2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"Start at `x=1` and create a while loop that multiplies the previous $x$ by 1.1.(That is, you earn a 10% return each year.) Continue while `x<2`. Print the iterations (iteration number, `x`). So, how many years did it take to double the investment?"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 1 1.100\n",
" 2 1.210\n",
" 3 1.331\n",
" 4 1.464\n",
" 5 1.611\n",
" 6 1.772\n",
" 7 1.949\n",
" 8 2.144\n"
]
}
],
"source": [
"x = 1\n",
"iter = 0\n",
"while x < 2\n",
" x = x*1.1\n",
" iter = iter + 1 \n",
" printlnPs(iter,x)\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# A Simple Function\n",
"\n",
"The next cell defines a new function, `fn1()`. It takes a scalar input (`x`) and returns a scalar output (`y`).\n",
"\n",
"If you instead use a vector as the input, then the computation fails. (The reason is that you cannot do x^2 on a vector. You could on a square matrix, though.)\n",
"\n",
"However, using the \"dot\" syntax\n",
"```\n",
"y = fn1.(x)\n",
"```\n",
"gives an array as output where element `y[i,j] = fn1(x[i,j])`."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"fn1 (generic function with 1 method)"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function fn1(x) #define a new function \n",
" y = (x-1.1)^2 - 0.5\n",
" return y\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"result from fn1(1.5): -0.340\n",
"\n",
"result from fn1.(x): \n",
" -0.490\n",
" -0.340\n",
"\n"
]
}
],
"source": [
"y = fn1(1.5)\n",
"printlnPs(\"result from fn1(1.5): \",y)\n",
"\n",
"x = [1;1.5]\n",
"#y = fn1(x) #would give an error \n",
"y = fn1.(x) #calling on the function, dot. to do for each element in x\n",
"printlnPs(\"\\nresult from fn1.(x): \")\n",
"printmat(y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"Write a function to calculate \n",
"$B =\\exp{(-my)}$, \n",
"where $B$ is the price of a bond and $m$ is the time to maturity (measured in years) and $y$ is the (continously compounded) interest rate.\n",
"\n",
"If $y=0.103$ and $m=0.5$, what is $B$?"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.950\n"
]
}
],
"source": [
"BondPrice(y,m) = exp(-m*y) #B as fn of y\n",
"\n",
"printlnPs(BondPrice(0.103,0.5))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# A First Plot\n",
"\n",
"With the Plots package you create a a simple plot like this:\n",
"\n",
"1. Plot two curve by using the `plot([x1 x2],[y1 y2])` command\n",
"2. Configure curves by `linecolor =`, `linestyle =` etc\n",
"2. Add titles and labels by `title = `, `xlabel = `, etc\n",
"\n",
"Notice: the *first plot is slow*."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"x = -3:6/99:6 \n",
"\n",
"p1 = plot( [x x],[fn1.(x) cos.(x)],\n",
" linecolor = [:red :blue],\n",
" linestyle = [:solid :dash],\n",
" linewidth = [2 1],\n",
" label = [\"fn1()\" \"cos\"],\n",
" title = \"My Results\",\n",
" xlabel = \"x\",\n",
" ylabel = \"my output value\" )\n",
"display(p1) #not needed in notebook, but useful in script"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Task\n",
"\n",
"Consider different interest rates in the interval (-0.05,0.1). Plot the prices of 3-month and 10-year bonds as functions of the interest rate."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y = -0.05:0.001:0.10\n",
"\n",
"B3m = BondPrice.(y,3/12)\n",
"B10y = BondPrice.(y,10)\n",
"\n",
"plot([y y],[B3m B10y],label = [\"3m\" \"10y\"],xlabel=\"interest rate\",ylabel=\"Bond price\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Types: Integers, Floats, Bools and Others\n",
"\n",
"Julia has many different types of variables: signed integers (like 2 or -5), floating point numbers (2.0 and -5.1), bools (false/true), bitarrays (similar to bools, but with more efficient use of memory), strings (\"hello\"), Dates (2017-04-23) and many more types."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Integers and Floats"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Finding the type of a, b, A and B:\n",
"Int64 Float64 Vector{Int64} Vector{Float64}\n"
]
}
],
"source": [
"a = 2 #integer, Int (Int64 on most machines)\n",
"b = 2.0 #floating point, (Float64 on most machines)\n",
"A = [1,2]\n",
"B = [1.0,2.0]\n",
"\n",
"println(\"Finding the type of a, b, A and B:\")\n",
"println(typeof(a),\" \",typeof(b),\" \",typeof(A),\" \",typeof(B))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Bools and BitArrays\n",
"\n",
"Bools are \"true\" or \"false\". BitArrays are (more memory efficient) versions of this."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Finding the type of c and C:\n",
"Bool BitVector\n"
]
}
],
"source": [
"c = 2 > 1.1\n",
"C = A .> 1.5 #A is an array, so C is too\n",
"\n",
"println(\"Finding the type of c and C:\")\n",
"println(typeof(c),\" \",typeof(C))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Calculations with Mixed Types\n",
"\n",
"A calculation like \"integer\" + \"float\" works and the type of the result will be a float (the more flexible type). Similarly, \"bool\" + \"integer\" will give an integer. These promotion rules make it easy to have mixed types in calculations, and also provide a simple way of converting a variable from one type to another. (There are also an explicit convert() function that might be quicker.)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.0\n",
"3\n"
]
}
],
"source": [
"println(1+2.0) #integer + Float\n",
"println((1>0) + 2) #bool + integer"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"@webio": {
"lastCommId": null,
"lastKernelId": null
},
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Julia 1.6.3",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}