mirror of
https://github.com/fverdugo/XM_40017.git
synced 2025-11-08 22:04:24 +01:00
1758 lines
111 KiB
Plaintext
1758 lines
111 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "faecad82",
|
||
"metadata": {},
|
||
"source": [
|
||
"<img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/VU_logo.png/800px-VU_logo.png?20161029201021\" width=\"350\">\n",
|
||
"\n",
|
||
"### Programming large-scale parallel systems\n",
|
||
"\n",
|
||
"\n",
|
||
"# Julia basics"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0f54a3f8",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Contents\n",
|
||
"\n",
|
||
"In this notebook, we will cover the basic parts of Julia needed later to learn parallel computing. In particular, we will learn about:\n",
|
||
"\n",
|
||
"- Variables\n",
|
||
"- Functions\n",
|
||
"- Arrays\n",
|
||
"\n",
|
||
"For a more general introduction to Julia see the nice tutorials made available by JuliaAcademy [here](https://github.com/JuliaAcademy/JuliaTutorials/) or the official Julia educational resources [here](https://julialang.org/learning/).\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "a23a48f4",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Using Jupyter notebooks in Julia\n",
|
||
"\n",
|
||
"We are going to use Jupyter notebooks in this and other lectures. You provably have worked with notebooks (in Python). If not, here are the basic concepts you need to know to follow the lessons.\n",
|
||
"\n",
|
||
"<div class=\"alert alert-block alert-info\">\n",
|
||
"<b>Tip:</b> Did you know that Jupyter stands for Julia, Python and R?\n",
|
||
"</div>\n",
|
||
"\n",
|
||
"### How to start a Jupyter notebook in Julia\n",
|
||
"\n",
|
||
"To run a Julia Jupyter notebook, open a Julia REPL and type\n",
|
||
"\n",
|
||
"```julia\n",
|
||
"julia> ]\n",
|
||
"pkg> add IJulia\n",
|
||
"julia> using IJulia\n",
|
||
"julia> notebook()\n",
|
||
"```\n",
|
||
"A new browser window will open. Navigate to the corresponding notebook and open it.\n",
|
||
"\n",
|
||
"<div class=\"alert alert-block alert-warning\">\n",
|
||
"<b>Warning:</b> Make sure that the notebook is using the same Julia version as the one you used to launch `IJulia`. If it is not the same, go to Kernel > Change Kernel and choose the right version (see figure below).\n",
|
||
"</div>\n",
|
||
"\n",
|
||
"\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"attachments": {
|
||
"figkernel.png": {
|
||
"image/png": "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"
|
||
}
|
||
},
|
||
"cell_type": "markdown",
|
||
"id": "928ae06c",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div>\n",
|
||
"<img src=\"attachment:figkernel.png\">\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "bcefe994",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Running a cell\n",
|
||
"To run a cell, click on a cell and press `Shift` + `Enter`. You can also use the \"Run\" button in the toolbar above."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "4eae9070",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"1+3\n",
|
||
"4*5"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0a02fb75",
|
||
"metadata": {},
|
||
"source": [
|
||
"As you can see from the output of previous cell, the value of the last line is displayed. We can suppress the output with a semicolon. Try it. Execute next cell."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3923b7a5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"1+3\n",
|
||
"4*5;"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "ffd3a444",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Cell order is important\n",
|
||
"\n",
|
||
"Running the two cells below in reverse order won't work (try it). "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f7597471",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"foo() = \"Well done!\""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "4a5d4f50",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"foo()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "d18e679d",
|
||
"metadata": {},
|
||
"source": [
|
||
"### A very easy first exercise\n",
|
||
"\n",
|
||
"Run the following cell. It contains definitions used later in the notebook."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "81678b3d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function why_q1()\n",
|
||
" msg = \"\"\"\n",
|
||
" In the first line, we assign a variable to a value. In the second line, we assign another variable to the same value. Thus, we have 2 variables associated with the same value. In line 3, we associate y to a new value (re-assignment). Thus, we have 2 variables associated with 2 different values. Variable x is still associated with its original value. Thus, the value at the final line is x=1.\n",
|
||
" \"\"\"\n",
|
||
" println(msg)\n",
|
||
"end\n",
|
||
"function why_q2()\n",
|
||
" msg = \"\"\"\n",
|
||
" It will be 1 for very similar reasons as in the previous questions: we are reassigning a local variable, not the global variable defined outside the function.\n",
|
||
" \"\"\"\n",
|
||
" println(msg)\n",
|
||
"end\n",
|
||
"function why_q3()\n",
|
||
" msg = \"\"\"\n",
|
||
" It will be 6. In the returned function f2, x is equal to 2. Thus, when calling f2(3) we compute 2*3.\n",
|
||
" \"\"\"\n",
|
||
" println(msg)\n",
|
||
"end\n",
|
||
"println(\"🥳 Well done! \")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "92112bd1",
|
||
"metadata": {},
|
||
"source": [
|
||
"### REPL modes\n",
|
||
"\n",
|
||
"This is particular to Julia notebooks. You can use package, help, and shell mode just like in the Julia REPL."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "9a445020",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"] add MPI"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "edefc54f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"? print"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e69fd5f1",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"; ls"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "8b94fc33",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Variables\n",
|
||
"\n",
|
||
"The usage of variables in Julia is pretty similar to Python and quite different from C/C++ and Fortran. However, there are also some differences with Python. \n",
|
||
"\n",
|
||
"### Creating a variable\n",
|
||
"\n",
|
||
"A variable is a name associated (bound) to a value. We associate variables with values with `=` as usual."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "149b7a62",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "77b557a8",
|
||
"metadata": {},
|
||
"source": [
|
||
"When assigning a variable, the value on the right hand side is not copied into the variable. It is just an association of a name with a value (much like in Python)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "ba08ea11",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Re-assign a variable\n",
|
||
"\n",
|
||
"We can re-assign a variable, even with a value of another type. However, avoid changing the variable type for performance reasons."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f62e49c9",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 2"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "86ac71ec",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 1.0"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e67d8480",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = \"Hi!\""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "767563a7",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Unreachable objects\n",
|
||
"\n",
|
||
"When an object is not associated with a variable any more, it cannot be reached by the user. This can happen, e.g., when we re-assign a variable. Another case is when local variables, e.g in a function, go out of scope. The following line allocates a large array and assigns it to variable a"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "202e222b",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
" a = zeros(300000000);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "35742a64",
|
||
"metadata": {},
|
||
"source": [
|
||
"If we re-assign the variable to another value, the large array will be inaccessible."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e6cd1c24",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = nothing"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "2883bf04",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Garbage collector\n",
|
||
"\n",
|
||
"Luckily, Julia has a garbage collector that deallocates unreachable objects. You don't need to bother about manual deallocation! Julia is not constantly looking for unreachable objects. Thus, garbage collection does not happen instantaneously, but it will happen at some point. You can also explicitly call the garbage collector, but it is almost never done in practice."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "89516ede",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"GC.gc()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "c110aa22",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Type declarations are optional\n",
|
||
"\n",
|
||
"Julia knows the type of the object associated with a variable."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c8d93d64",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 1\n",
|
||
"typeof(a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "df2e48c2",
|
||
"metadata": {},
|
||
"source": [
|
||
"We can annotate types if we want, but this will not improve performance (except in very special situations). Thus, annotating types is not done in practice."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "95fd3ef4",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"c::Int = 1\n",
|
||
"typeof(c)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "67883016",
|
||
"metadata": {},
|
||
"source": [
|
||
"If you annotate a variable with a type, then it cannot refer to objects of other types."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f3cdc27b",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"c = \"I am a string\""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "64f5aa94",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Variable names\n",
|
||
"\n",
|
||
"There is a great flexibility to choose variable names in Julia. See all the rules in the [manual](https://docs.julialang.org/en/v1/manual/variables/#man-allowed-variable-names) if you are interested."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "09eb4365",
|
||
"metadata": {},
|
||
"source": [
|
||
"We can use Unicode (UTF-8 encoding) characters in variables and function names."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "94667496",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"🐱 = \"I am a cat\"\n",
|
||
"🐶 = \"I am a dog\"\n",
|
||
"🐱 == 🐶"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "beaf9680",
|
||
"metadata": {},
|
||
"source": [
|
||
"We can also use Greek letters and other mathematical symbols. Just write the corresponding [LaTeX](https://oeis.org/wiki/List_of_LaTeX_mathematical_symbols) command and press `Tab`. For example: `ω` is written `\\omega` + `Tab`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "b9b3079e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"ω = 1.234\n",
|
||
"sin(ω)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "4f7de553",
|
||
"metadata": {},
|
||
"source": [
|
||
"In fact, some useful mathematical constants are predefined in Julia with math Greek letters."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "89d6d94e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"sin(π/2)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "d36ba0ae",
|
||
"metadata": {},
|
||
"source": [
|
||
"\n",
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<b>Question (NB1-Q1):</b> What will be the value of `x` in the last line ? (Think your answer before executing next cell to find out the result) \n",
|
||
"</div>\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f6f4e13e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = 1\n",
|
||
"y = x\n",
|
||
"y = 2\n",
|
||
"x"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "a2f94960",
|
||
"metadata": {},
|
||
"source": [
|
||
"Run next cell to get an explanation of this question."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "fc562337",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"why_q1()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "4d2cb752",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Functions\n",
|
||
"\n",
|
||
"Julia is very much a functional programming language. In consequence, Julia is more centered on functions than on types. This is in contrast to object-oriented languages, which are more centered on types (classes). For instance, you don't need to know the details of the Julia type system to learn parallel programming in Julia, but you need to have a quite advanced knowledge of how Julia functions work.\n",
|
||
"\n",
|
||
"### Defining functions\n",
|
||
"\n",
|
||
"Functions are defined as shown in next cell. The closing `end` is necessary. Do not forget it! However, the `return` is optional. The value of last line is returned by default. Indentation is recommended, but it is also optional. That's why the closing `end` is needed."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "266b0e1b",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function add(a,b)\n",
|
||
" return a + b \n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "de95c63c",
|
||
"metadata": {},
|
||
"source": [
|
||
"Once defined, a function can be called using bracket notation as you would expect."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "39b452a7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"add(1,3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "afceb0fc",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Broadcast syntax\n",
|
||
"\n",
|
||
"We can apply functions to arrays element by element using broadcast (dot) syntax."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e65be5e8",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = [1,2,3]\n",
|
||
"b = [4,5,6]\n",
|
||
"add.(a,b)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "e4ca76a4",
|
||
"metadata": {},
|
||
"source": [
|
||
"Mathematical operators can also be broadcasted (like in Matlab). Multiplying the vectors `a * b` directly won't work. If we want to multiply element by element, we can use the broadcasted version below."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "ae0b3f6d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a .* b"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "b131e208",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<b>Question (NB1-Q2):</b> What will be the value of `x` in the last line ?\n",
|
||
"</div>\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3d637d87",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function q(x)\n",
|
||
" x = 2\n",
|
||
" x\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "882d8e59",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = 1\n",
|
||
"y = q(x)\n",
|
||
"x"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "f69108c2",
|
||
"metadata": {},
|
||
"source": [
|
||
"Run next cell to get an explanation of this question."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "05c62aa3",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"why_q2()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "4fc5eb9b",
|
||
"metadata": {},
|
||
"source": [
|
||
"### References\n",
|
||
"\n",
|
||
"As you can see variables are passed \"by value\". Passing variables \"by reference\" is done using a reference.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6ef5fe2c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function q!(x)\n",
|
||
" x[] = 2\n",
|
||
" x\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "ba245808",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = Ref(1)\n",
|
||
"q!(x)\n",
|
||
"x[]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "d20bc3a4",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Defining functions (shorter way)\n",
|
||
"\n",
|
||
"For short functions, we can skip the `function` and `end` keywords as follows.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7815aea5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"add_short(a,b) = a+b"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7aa48db2",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"add_short(1,3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "f39c31c0",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Anonymous (lambda) functions\n",
|
||
"\n",
|
||
"Since we can assign function to variables, it is not needed for a function to have a function name in many cases. We can simply create an anonymous function (i.e., a function without name) and assign it to a variable."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "94ce2be7",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"add_anonymous = (a,b) -> a+b"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "b15b84d8",
|
||
"metadata": {},
|
||
"source": [
|
||
"We can call the function by using the variable name."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "96d80a59",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"add_anonymous(2.0,3.5)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "1723e4f1",
|
||
"metadata": {},
|
||
"source": [
|
||
"Note that `add_anonymous` is not a function name. It is just a variable associated with a function with no function name (well, it has a name technically, but with an arbitrary value)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "5bf111a0",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"nameof(add_anonymous)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7e23f9f8",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"nameof(add)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "e530acd3",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Functions are first-class objects\n",
|
||
"\n",
|
||
"We can work with Julia functions like with any other type of object. For instance, we can assign functions to variables."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e57fe028",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = add"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "7a8f4bb0",
|
||
"metadata": {},
|
||
"source": [
|
||
"Now, we can call the function using the variable name."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c7e4d4ec",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a(4,5)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "c01be92e",
|
||
"metadata": {},
|
||
"source": [
|
||
"We can also create an array of functions (this will not work in Python)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3837bf25",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"funs = [+,-,*]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0aac151b",
|
||
"metadata": {},
|
||
"source": [
|
||
"To call a specific function in the array, we index the array and then call the returned function"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "aab45992",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"funs[2](2,3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "f0c668c8",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Higher-order functions\n",
|
||
"\n",
|
||
"Higher order functions are functions that take and/or return other functions. And example is the `count` function in Julia.\n",
|
||
"\n",
|
||
"For instance, we can pass a user-defined function to count the number of even elements in an array."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "22115f82",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"func = i->i%2==0\n",
|
||
"a = [1,2,3,5,32,2,4]\n",
|
||
"count(func,a)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "0b352cdc",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Do-blocks\n",
|
||
"\n",
|
||
"There is yet another way to define anonymous functions. If a function takes a function in its first argument (like `count`) we can skip the first argument, when calling the function, and define the function we want to pass in a do-block. This is useful, e.g., if we want to define a multi-line anonymous function. The two next cells are equivalent."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "533a21f3",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function f(i)\n",
|
||
" m = i%2\n",
|
||
" m != 0\n",
|
||
"end\n",
|
||
"count(f,[1,2,3,5,32,2,4])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "68b5165a",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"count([1,2,3,5,32,2,4]) do i\n",
|
||
" m = i%2\n",
|
||
" m != 0\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "559a084d",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Returning multiple values\n",
|
||
"\n",
|
||
"Julia functions always return a single variable. To return multiple values, we can wrap them in a tuple.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "eba30561",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function divrem(a,b)\n",
|
||
" α = div(a,b)\n",
|
||
" β = rem(a,b)\n",
|
||
" (α,β)\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "1a6e9d0d",
|
||
"metadata": {},
|
||
"source": [
|
||
"The output is a tuple as expected, but we can recover the individual values by unpacking the tuple."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "cb0c2806",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"d,r = divrem(10,3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "31428737",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"d"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "76424bb5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"r"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "c73ae75b",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Variable number of input arguments\n",
|
||
"\n",
|
||
"Functions with multiple arguments are also supported. The following example iterates over the given arguments and prints them. `args` is just a tuple with all arguments."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "a7f94ff0",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function showargs(args...)\n",
|
||
" for (i,arg) in enumerate(args)\n",
|
||
" println(\"args[$i] = $arg\")\n",
|
||
" end\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "7828534e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"showargs(1,\"Hi!\",π)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f31fc3ff",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"showargs(6)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "dc47d83b",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Positional and keyword arguments\n",
|
||
"\n",
|
||
"Functions can combine positional and keyword arguments much like in Python, but keyword arguments start with semicolon `;` in Julia."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "37cd0314",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function foo(a,b;c,d)\n",
|
||
" println(\"Positional: a=$a, b=$b. Keyword: c=$c, d=$d\")\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "ee19db3d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"foo(3,4,d=2,c=1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "4919ef95",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Optional arguments\n",
|
||
"\n",
|
||
"We can provide default values to arguments to make them optional."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "650e6d67",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function bar(a,b=0;c,d=1)\n",
|
||
" println(\"Positional: a=$a, b=$b. Keyword: c=$c, d=$d\")\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "e5d03536",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"bar(1,c=2)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "94599fa3",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<b>Question (NB1-Q3):</b> Which will be the value of `x` below? \n",
|
||
"</div>\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "79bd84bd",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function hofun(x)\n",
|
||
" y -> x*y\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "a9a7b774",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"f2 = hofun(2)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f6606086",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = f2(3)\n",
|
||
"x"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "062ff145",
|
||
"metadata": {},
|
||
"source": [
|
||
"Run next cell to get an explanation of this question."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6bf7818e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"why_q3()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "bc8e9bcf",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Arrays\n",
|
||
"\n",
|
||
"Julia supports multi-dimensional arrays. They are very similar to Numpy arrays in Python. Let's learn the basics of Julia arrays.\n",
|
||
"\n",
|
||
"\n",
|
||
"### Array literals\n",
|
||
"\n",
|
||
"We can create (small) arrays from the given values using array literals.\n",
|
||
"\n",
|
||
"Next cell creates a vector with 3 integers. Note for Python users: there is no difference between vectors and lists in Julia."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "08652696",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"vec = [1,2,3]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "70f15e92",
|
||
"metadata": {},
|
||
"source": [
|
||
"We can create a matrix as follows."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "a3aacf71",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"mat = [1 2 3 4\n",
|
||
" 5 6 7 8\n",
|
||
" 9 10 11 12]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "e096b198",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Array initialization\n",
|
||
"\n",
|
||
"We can create arrays with all the entries equal to zero, to one, or to a specific given value. The value can be any Julia object, even a function!\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "9357edac",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"zeros(4)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "dfc88af3",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"zeros(Int,4)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "49e5a779",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"ones(2,3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6bbde94a",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"fill(5.0,3,4)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "d2c44cce",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"fill(add,3,4)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "495827bc",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Array comprehensions\n",
|
||
"\n",
|
||
"We can also create the items in the array using a loop within an array comprehension."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "4b3c56b4",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"squares = [ i^2 for i in 1:8 ]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "cee954ce",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Indexing\n",
|
||
"\n",
|
||
"We can get and set the items of an array by indexing the array."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "df901c08",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"squares[3]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "dc58cf4c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"squares[end]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "aa7936e0",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"squares[2:4]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6cf66ef0",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"squares[4] = 16"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "9125cbeb",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"squares[2:3] = [4,9]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "f64021ab",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Immutable element type"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "6650d6e7",
|
||
"metadata": {},
|
||
"source": [
|
||
"Note that once set, the type of the elements in the array cannot be changed. If we try to set an item with an object of a different type, Julia will try to do a conversion, which can fail depending on the passed value."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c79b297e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = [10,11,12,13]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "2694f3d4",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a[2] = \"Hi!\""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "92bae51d",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Arrays of any element type\n",
|
||
"\n",
|
||
"Arrays of fixed element type seem to be very rigid, right? Python list do not this limitation. However, we can use arrays of the `Any` type, which are as flexible as Python lists, or even more since they can also contain functions. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "d656b9ce",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = Any[10,11,12,13]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3d08e4ba",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a[3] = \"HI!\""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "92bf2cab",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "1c72351a",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Loops\n",
|
||
"\n",
|
||
"The loop in next cell visits the elements in `a` one after the other. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "72dfc0f2",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = [10,20,30,40]\n",
|
||
"for ai in a\n",
|
||
" @show ai\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "d4906337",
|
||
"metadata": {},
|
||
"source": [
|
||
"This loop visits the integers from 1 to the length of the array and indexes the array at each of these integers."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "75f5ab89",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"for i in 1:length(a)\n",
|
||
" ai = a[i]\n",
|
||
" @show (i,ai)\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "e7abfdd6",
|
||
"metadata": {},
|
||
"source": [
|
||
"This loop \"enumerates\" the items in the array."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "96dfab12",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"for (i,ai) in enumerate(a)\n",
|
||
" @show (i,ai)\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "b4747037",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Arrays indices are 1-based by default\n",
|
||
"\n",
|
||
"Be aware of this if you are a C or Python user."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "694ec903",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = [10,20,30,40]\n",
|
||
"a[0]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "a2ed5b01",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Slicing allocates a new array\n",
|
||
"\n",
|
||
"This is also different from Numpy in Python."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "961a82a3",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = [1 2 3\n",
|
||
" 4 5 6]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "1c9f2162",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"s = a[:,2]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "4664eeb7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"s[2] = 0"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c356e67d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "b75a2b83",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Array views\n",
|
||
"\n",
|
||
"If you want to modify the original array, use `view` instead."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3d8e2ab7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"v = view(a,:,2)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "329079bd",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"v[1] = 0"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "3b26a483",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "fef8495e",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Exercises"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "7d84ceaf",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Exercise 1\n",
|
||
"\n",
|
||
"Implement a function `ex1(a)` that finds the largest item in the array `a`. It should return the largest item and its corresponding position in the array. If there are multiple maximal elements, then the first one will be returned. Assume that the array is not empty. Implement the function in the next cell. Test your implementation with the other one."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "8e6c7091",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Implement here"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "370afcca",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"using Test\n",
|
||
"arr = [3,4,7,3,1,7,2]\n",
|
||
"@test ex1(arr) == (7,3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "7be19eb4",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Exercise 2\n",
|
||
"\n",
|
||
"Implement a function `ex2(f,g)` that takes two functions `f(x)` and `g(x)` and returns a new function `h(x)` representing the sum of `f` and `g`, i.e., `h(x)=f(x)+g(x)`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "331e90b6",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Implement here"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "9e86c981",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"h = ex2(sin,cos)\n",
|
||
"xs = LinRange(0,2π,100)\n",
|
||
"@test all(x-> h(x) == sin(x)+cos(x), xs)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "3324a991",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Exercise 3 (hard)\n",
|
||
"\n",
|
||
"Function `mandel` estimates if a given point `(x,y)` in the complex plane belongs to the [Mandelbrot set](https://en.wikipedia.org/wiki/Mandelbrot_set)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "0ac481c1",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"function mandel(x,y,max_iters)\n",
|
||
" z = Complex(x,y)\n",
|
||
" c = z\n",
|
||
" threshold=2\n",
|
||
" for n in 1:max_iters\n",
|
||
" if abs(z)>threshold\n",
|
||
" return n-1\n",
|
||
" end\n",
|
||
" z = z^2 +c\n",
|
||
" end\n",
|
||
" max_iters\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "86ea2591",
|
||
"metadata": {},
|
||
"source": [
|
||
"If the value of `mandel` is less than `max_iters`, the point is provably outside the Mandelbrot set. If `mandel` is equal to `max_iters`, then the point is provably inside the set. The larger `max_iters`, the better the quality of the estimate (the nicer will be your plot).\n",
|
||
"\n",
|
||
"Plot the value of function `mandel` for each pixel in a 2D grid of the box.\n",
|
||
"\n",
|
||
"$$(-1.7,0.7)\\times(-1.2,1.2).$$\n",
|
||
"\n",
|
||
"Use a grid resolution of at least 1000 points in each direction and `max_iters` at least 10. You can increase these values to get nicer plots. To plot the values use function `heatmap` from the Julia package `GLMakie`. Use `LinRange` to divide the horizontal and vertical axes into pixels. See the documentation of these functions for help. `GLMakie` is a GPU-accelerated plotting back-end for Julia. It is a large package and it can take some time to install and to generate the first plot. Be patient."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "33137ad9",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Implement here"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "357e0490",
|
||
"metadata": {},
|
||
"source": [
|
||
"# License\n",
|
||
"\n",
|
||
"This notebook is part of the course [Programming Large Scale Parallel Systems](https://www.francescverdugo.com/XM_40017/) at Vrije Universiteit Amsterdam and may be used under a [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license."
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Julia 1.10.0",
|
||
"language": "julia",
|
||
"name": "julia-1.10"
|
||
},
|
||
"language_info": {
|
||
"file_extension": ".jl",
|
||
"mimetype": "application/julia",
|
||
"name": "julia",
|
||
"version": "1.10.0"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|