Skip to content

Commit

Permalink
Merge pull request #32 from MichielStock/notebooks
Browse files Browse the repository at this point in the history
Notebooks
  • Loading branch information
Beramos authored Dec 18, 2019
2 parents a9c89d6 + c12559c commit 46e8c4f
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 100 deletions.
5 changes: 2 additions & 3 deletions 04-project-1DCA.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ nextstate(l::Bool, s::Bool, r::Bool, rule::Integer) = nextstate(l, s, r, Int8(ru
```julia;eval=false
rule = ...
```
```julia
```julia;eval=false
S = ...
```
```julia
```julia;eval=false
function nextstates(S, rule)
...
return states
Expand Down Expand Up @@ -110,7 +110,6 @@ end
```julia; eval=false
x₀ = ...


```

```julia
Expand Down
4 changes: 2 additions & 2 deletions notebooks/01-basics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1047,11 +1047,11 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.0.0"
"version": "1.0.4"
},
"kernelspec": {
"name": "julia-1.0",
"display_name": "Julia 1.0.0",
"display_name": "Julia 1.0.4",
"language": "julia"
}
},
Expand Down
4 changes: 2 additions & 2 deletions notebooks/02-collections.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -817,11 +817,11 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.0.5"
"version": "1.0.4"
},
"kernelspec": {
"name": "julia-1.0",
"display_name": "Julia 1.0.5",
"display_name": "Julia 1.0.4",
"language": "julia"
}
},
Expand Down
168 changes: 81 additions & 87 deletions notebooks/03-types.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,6 @@
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"eltype(A)"
],
"metadata": {},
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
Expand Down Expand Up @@ -133,7 +124,7 @@
"outputs": [],
"cell_type": "code",
"source": [
"a isa Int # int is concrete type Int64"
"a isa Int # Int is concrete type Int64"
],
"metadata": {},
"execution_count": null
Expand All @@ -142,7 +133,7 @@
"outputs": [],
"cell_type": "code",
"source": [
"a isa Integer # integer is abstract"
"a isa Integer # Integer is abstract"
],
"metadata": {},
"execution_count": null
Expand Down Expand Up @@ -229,7 +220,7 @@
{
"cell_type": "markdown",
"source": [
"# Methods and dispatch\n\nWhen a function is run for the first time with a particular combination of type inputs, it gets compiled by the LLVM compiler. Such a specific function is referred to as a `method`. Every time a function is run with a new combination of types of arguments, a suitable method is compiled. This is noticeable when measuring running time. Compare"
"# Methods and dispatch\n\nWhen a function is run for the first time with a particular combination of type inputs, it gets compiled by the LLVM compiler. Such a specific function is referred to as a `method`. Every time a function is run with a new combination of types of arguments, a suitable method is compiled. This is noticeable when measuring the running time. Compare"
],
"metadata": {}
},
Expand Down Expand Up @@ -281,94 +272,47 @@
{
"cell_type": "markdown",
"source": [
"The known methods can be found using the function `methods`. For example, check how many methods there are associated with the humble multiplication operator `*`.\n\nThe arguments a function can take can be restricted using the `::`-operator. Here, if we limit a function as `f(x::T)`, this means that `x` can be any type `<: T`. Can you explain the reasoning behind the following code? How does it process numbers? What does it do with strings?"
"The known methods can be found using the function `methods`. For example, check how many methods there are associated with the humble multiplication operator `*`."
],
"metadata": {}
},
{
"outputs": [],
"cell_type": "code",
"source": [
"twice(x::Number) = 2x"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"twice(x::String) = x * x"
"methods(*)"
],
"metadata": {},
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"So why use dispatch?\n\n1. Controls the **scope** of functions. For some types, there is no method, and we want an error if we use the wrong type.\n2. Because we wish functions to **behave differently** depending on the types you feed into them.\n\nNote that, generally seen, typing the functions is **not** needed to improve the performance of the functions.\n\n> **Exercise** Consider the following methods. Can you predict the outcome of the lines of code below it?"
"The arguments a function can take can be restricted using the `::`-operator. Here, if we limit a function as `f(x::T)`, this means that `x` can be any type `<: T`. Can you explain the reasoning behind the following code? How does it process numbers? What does it do with strings?"
],
"metadata": {}
},
{
"outputs": [],
"cell_type": "code",
"source": [
"f(x, y) = println(\"No life forms present\")"
"twice(x::Number) = 2x;\ntwice(x::String) = x * x;"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"f(x::T, y::T) where {T} = x * y # short for {T <: Any}"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"f(x::Integer, y::Real) = 2x + y"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"f(x::Int, y::Int) = 2x + 2y"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"f(x::Integer, y::Float64) = x + 2y"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"cell_type": "markdown",
"source": [
"f(x::Float64, y::Real) = x - y"
"So why use dispatch?\n\n1. Controls the **scope** of functions. For some types, there is no method, and we want an error if we use the wrong type.\n2. Because we wish functions to **behave differently** depending on the types you feed into them.\n\nNote that, generally seen, typing the functions is **not** needed to improve the performance of the functions.\n\n> **Exercise** Consider the following methods. Can you predict the outcome of the lines of code below it?"
],
"metadata": {},
"execution_count": null
"metadata": {}
},
{
"outputs": [],
"cell_type": "code",
"source": [
"f(x::Float64, y::Float64) = 2x - y"
"f(x, y) = println(\"No life forms present\");\nf(x::T, y::T) where {T} = x * y; # short for {T <: Any}\nf(x::Integer, y::Real) = 2x + y;\nf(x::Int, y::Int) = 2x + 2y;\nf(x::Integer, y::Float64) = x + 2y;\nf(x::Float64, y::Real) = x - y;\nf(x::Float64, y::Float64) = 2x - y;"
],
"metadata": {},
"execution_count": null
Expand Down Expand Up @@ -490,7 +434,7 @@
"outputs": [],
"cell_type": "code",
"source": [
"mycat = Cat(\"Appa\")\nhisdog = Dog(\"Storm\")"
"mycat = Cat(\"Appa\");\nhisdog = Dog(\"Storm\");"
],
"metadata": {},
"execution_count": null
Expand Down Expand Up @@ -524,7 +468,16 @@
"outputs": [],
"cell_type": "code",
"source": [
"meets(pet1::Cat, pet2::Dog) = println(\"$(pet1.name) hisses at $(pet2.name)\")\nmeets(pet1::Dog, pet2::Cat) = println(\"$(pet1.name) barks at $(pet2.name)\")\nmeets(pet1::Cat, pet2::Cat) = println(\"$(pet1.name) ignores $(pet2.name)\")\nmeets(pet1::Dog, pet2::Dog) = println(\"$(pet1.name) sniffs the but of $(pet2.name)\")\n\nmeets(mycat, hisdog)"
"meets(pet1::Cat, pet2::Dog) = println(\"$(pet1.name) hisses at $(pet2.name)\");\nmeets(pet1::Dog, pet2::Cat) = println(\"$(pet1.name) barks at $(pet2.name)\");\nmeets(pet1::Cat, pet2::Cat) = println(\"$(pet1.name) ignores $(pet2.name)\");\nmeets(pet1::Dog, pet2::Dog) = println(\"$(pet1.name) sniffs the but of $(pet2.name)\");"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"meets(mycat, hisdog)"
],
"metadata": {},
"execution_count": null
Expand Down Expand Up @@ -582,15 +535,40 @@
{
"cell_type": "markdown",
"source": [
"But what will happen if you evaluate `Point(1, 2.0)`?\n\nParametric types can be used in dispatch. For example, if we want to compute the norm of a Point, this would only make sense if Point is of type real."
"But what will happen if you evaluate `Point(1, 2.0)`?"
],
"metadata": {}
},
{
"outputs": [],
"cell_type": "code",
"source": [
"norm(p::Point{T} where {T<:Real}) = sqrt(p.x^2 + p.y^2)"
"Point(1, 2.0)"
],
"metadata": {},
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"Parametric types can be used in dispatch. For example, if we want to compute the norm of a Point, this would only make sense if Point is of type real."
],
"metadata": {}
},
{
"outputs": [],
"cell_type": "code",
"source": [
"norm(p::Point{T} where {T<:Real}) = sqrt(p.x^2 + p.y^2);"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"norm(p)"
],
"metadata": {},
"execution_count": null
Expand All @@ -606,7 +584,7 @@
"outputs": [],
"cell_type": "code",
"source": [
"Point(x::T, y::T) where {T<:Real} = Point{T}(x,y)"
"Point(x::T, y::T) where {T<:Real} = Point{T}(x,y);"
],
"metadata": {},
"execution_count": null
Expand All @@ -622,7 +600,7 @@
"outputs": [],
"cell_type": "code",
"source": [
"Point(x::Real, y::Real) = Point(promote(x, y)...)"
"Point(x::Real, y::Real) = Point(promote(x, y)...);"
],
"metadata": {},
"execution_count": null
Expand All @@ -647,16 +625,7 @@
"outputs": [],
"cell_type": "code",
"source": [
"Point(x) = Point(x, x)"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"Point(1)"
"Point(x) = Point(x, x);\n\nPoint(1)"
],
"metadata": {},
"execution_count": null
Expand Down Expand Up @@ -698,7 +667,7 @@
{
"cell_type": "markdown",
"source": [
"# Case study: the Strang matrix\n\nThe Strang matrix is a tridiagonal matrix with -2 at the diagonal and above and below the diagonal.\n\n$$\n\\begin{pmatrix}\n -2 & 1& \\cdots & 0 & 0 \\\\\n 1 & -2& \\cdots & 0 & 0\\\\\n \\vdots & \\vdots & \\ddots & \\vdots \\\\\n 0 &0 & \\cdots & -2 & 1\\\\\n0 &0 & \\cdots & 1 & -2\n \\end{pmatrix}\n$$\n\nThe specific structure makes computing with this matrix often more straightforward than for general matrices. Let us implement a `Strang` matrix type to work with this!"
"# Exercises\n\n## Case study: the Strang matrix\n\nThe Strang matrix is a tridiagonal matrix with -2 at the diagonal and above and below the diagonal.\n\n$$\n\\begin{pmatrix}\n -2 & 1& \\cdots & 0 & 0 \\\\\n 1 & -2& \\cdots & 0 & 0\\\\\n \\vdots & \\vdots & \\ddots & \\vdots \\\\\n 0 &0 & \\cdots & -2 & 1\\\\\n0 &0 & \\cdots & 1 & -2\n \\end{pmatrix}\n$$\n\nThe specific structure makes computing with this matrix often more straightforward than for general matrices. Let us implement a `Strang` matrix type to work with this!"
],
"metadata": {}
},
Expand Down Expand Up @@ -747,7 +716,16 @@
"outputs": [],
"cell_type": "code",
"source": [
"sum(S)\n\nv = [2.3, 1.4, 6.0, 9.0 , 1.7]\nS * v"
"sum(S)"
],
"metadata": {},
"execution_count": null
},
{
"outputs": [],
"cell_type": "code",
"source": [
"v = [2.3, 1.4, 6.0, 9.0 , 1.7]\nS * v"
],
"metadata": {},
"execution_count": null
Expand All @@ -767,6 +745,22 @@
],
"metadata": {},
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"## Wizarding currency\n\nThe British wizarding world uses Galleons, Sickles, and Knuts as a currency. There are 17 Sickles in a Galleon, and 29 Knuts in a Sickle, meaning there are 493 Knuts to a Galleon. We will make a structure `WizCur` to represent wizarding currency. This structure has three integer-valued fields: `galleons`, `sickles`, and `knuts`. The constructor should always create tidy representations, meaning that, for example, if the number of knuts is 29 or more, it just adds an appropriate number of sickles such that the number knuts is less than 29 (it's magical money). The same applies to the sickles, which can also never exceed 17.\n\nOverload `Base.show` such that Julia prints your currency as, for example, `7G, 2S, 9K`.\n\nAlso, overload the function `+` to add two instances of `WizCur` and the `>` and `<` operators to compare two instances of wizarding currency.\n\nThe piggy bank with Ron's life savings contains 19 Sickles and 732 Knuts. Harry has 3 Galleons, 1 Sickle, and 7 Knuts pocket change. Who has the most money? How many do they have together?\n\nHINT: you might find `%` and `div` useful here."
],
"metadata": {}
},
{
"outputs": [],
"cell_type": "code",
"source": [
"struct WizCur\n ...\nend\n\n..."
],
"metadata": {},
"execution_count": null
}
],
"nbformat_minor": 2,
Expand All @@ -775,11 +769,11 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.0.5"
"version": "1.0.4"
},
"kernelspec": {
"name": "julia-1.0",
"display_name": "Julia 1.0.5",
"display_name": "Julia 1.0.4",
"language": "julia"
}
},
Expand Down
Loading

0 comments on commit 46e8c4f

Please sign in to comment.