Skip to content

Instantly share code, notes, and snippets.

@simonbyrne
Last active May 10, 2017 10:12
Show Gist options
  • Save simonbyrne/dc2a18499fe5359a83ba61c3b3f9d671 to your computer and use it in GitHub Desktop.
Save simonbyrne/dc2a18499fe5359a83ba61c3b3f9d671 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<center><img src=\"julia.svg\" width=\"300\"></center>\n",
"\n",
"### <center>Simon Byrne - Julia Computing</center>"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"# What is Julia?\n",
"\n",
"Julia is a modern, high-performance, dynamic programming language for technical computing.\n",
"\n",
"- *modern*: based on the lessons of the past 60 years\n",
"- *high-performance*: as fast as traditional \"fast\" languages (Fortran/C/C++)\n",
"- *dynamic*: \"simple to use\" (Python/R/Matlab)\n",
"- *technical computing*: anything involving numbers\n",
"\n",
"## About me\n",
"\n",
"I've been using Julia ~4.5 years, and for the last 1.5 years have worked for Julia Computing.\n",
"\n",
"My background is in stats/machine learning, so some of my examples have a numerical bent."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"# Why Julia?\n",
"\n",
"* To write fast, efficient code in an easy, elegant dynamic language\n",
" - Avoids the *two language problem*:\n",
" \n",
"> My R/Python/Matlab code is too slow; I need to rewrite low-level routines in C/C++/Fortran\n",
"\n",
"* It is easy to \"peek under the hood\"\n",
" - Most of Julia is written Julia\n",
" - Can inspect various stages of the compilation process\n",
"* It's free (download at www.julialang.org)\n",
"* It's fun.\n",
"* Plays nicely with existing tools"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Starting Julia\n",
"\n",
"## Command line\n",
"\n",
"* `julia` will start the REPL (similar to the Python interpreter)\n",
"* `julia filename.jl` will run the script in `filename.jl`\n",
"\n",
"## Jupyter notebook\n",
"\n",
"`jupyter notebook` will start the Jupyter notebook interface\n",
"* Should be able to create Julia notebook (requires IJulia, which should be installed).\n",
"* Shift-enter will evaluate a cell"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello world\n"
]
}
],
"source": [
"println(\"Hello world\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Julia Version 0.5.1\n",
"Commit 6445c82 (2017-03-05 13:25 UTC)\n",
"Platform Info:\n",
" OS: macOS (x86_64-apple-darwin13.4.0)\n",
" CPU: Intel(R) Core(TM) i5-5287U CPU @ 2.90GHz\n",
" WORD_SIZE: 64\n",
" BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)\n",
" LAPACK: libopenblas64_\n",
" LIBM: libopenlibm\n",
" LLVM: libLLVM-3.7.1 (ORCJIT, broadwell)\n"
]
}
],
"source": [
"versioninfo()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"# \"Why is it slow...\"\n",
"\n",
"Julia is just-in-time (JIT) compiled: the first time you run a function with a specific combination of arguments, it is precompiled, then this code is run.\n",
"\n",
"- Since the REPL itself is written in Julia, you will notice this as well.\n",
"- Unfortunately, LLVM (the backend compiler) is quite slow on ARM, which makes this much more noticable.\n",
"\n",
"_Performance tip_:\n",
"\n",
"> Put large blocks of code inside a function, rather than run them in global scope."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Example: `logsumexp` function\n",
"\n",
"Suppose we want to compute:\n",
"\n",
"$$ y = \\log \\left( \\sum_{i=1}^n \\exp x_i \\right) $$ \n",
"\n",
"if $x_i$s are very large (or small), then the intermediate result may overflow (or underflow) giving erroneous results.\n",
"\n",
"For any $u$ we have can write\n",
"\n",
"$$ y = u + \\log \\left( \\sum_{i=1}^n \\exp (x_i-u) \\right) $$ \n",
"\n",
"A typical choice of $u$ is the maximum of $x_i$s."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"logsumexp (generic function with 1 method)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function logsumexp(X)\n",
" u = maximum(X)\n",
" t = 0.0\n",
" for i = 1:length(X)\n",
" t += exp(X[i]-u)\n",
" end\n",
" u + log(t)\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Basic differences from Python:\n",
"\n",
"* `function` instead of `def`\n",
"* explicit `end` vs. significant whitespace\n",
"* ranges are specified via `start:end` (or `start:step:end`)\n",
"* 1-based instead of 0-based arrays\n",
"* last statement has implicit `return`"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.033814 seconds (14.44 k allocations: 682.251 KB)\n"
]
},
{
"data": {
"text/plain": [
"9.750115107840267"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X = rand(10_000)\n",
"@time logsumexp(X)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.000218 seconds (5 allocations: 176 bytes)\n"
]
},
{
"data": {
"text/plain": [
"9.750115107840267"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@time logsumexp(X)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"# Getting Help\n",
"\n",
"`?functionname` gives the help for that function"
]
},
{
"cell_type": "code",
"execution_count": 144,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"search: \u001b[1mg\u001b[22m\u001b[1mc\u001b[22m\u001b[1md\u001b[22m \u001b[1mg\u001b[22m\u001b[1mc\u001b[22m\u001b[1md\u001b[22mx si\u001b[1mg\u001b[22mnifi\u001b[1mc\u001b[22man\u001b[1md\u001b[22m\n",
"\n"
]
},
{
"data": {
"text/markdown": [
"```\n",
"gcd(x,y)\n",
"```\n",
"\n",
"Greatest common (positive) divisor (or zero if `x` and `y` are both zero).\n"
],
"text/plain": [
"```\n",
"gcd(x,y)\n",
"```\n",
"\n",
"Greatest common (positive) divisor (or zero if `x` and `y` are both zero).\n"
]
},
"execution_count": 144,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?gcd"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Colouring by Julia\n",
"\n",
"Load the *Colors.jl* package:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"using Colors\n",
"using FixedPointNumbers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`using` is similar to Python `import`, but it also loads exported names into the current scope.\n",
"\n",
"If you really, don't like this, you can use `import` to get more python-ish behaviour\n",
"```\n",
"import Colors # just loads Colors module into scope\n",
"import Colors: RGB # loads Colors module, and Colors.RGB into scope\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
" width=\"25mm\" height=\"25mm\" viewBox=\"0 0 1 1\">\n",
" <rect width=\"1\" height=\"1\"\n",
" fill=\"#FF0000\" stroke=\"none\"/>\n",
"</svg>\n"
],
"text/plain": [
"RGB{Float64}(1.0,0.0,0.0)"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r = RGB(1.0,0.0,0.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Every Julia object has a _type_:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"Float64"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(1.0)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"ColorTypes.RGB{Float64}"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(r)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"`RGB` is a _parametric_ type with 3 fields, defined as:\n",
"\n",
"```julia\n",
"immutable RGB{T<:Fractional} <: AbstractRGB{T}\n",
" r::T # Red [0,1]\n",
" g::T # Green [0,1]\n",
" b::T # Blue [0,1]\n",
"end\n",
"```\n",
"\n",
"Making it parametric makes it easy to convert to _fixed point_, which is how RGB colours are usually stored/represented"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"FixedPointNumbers.Normed{UInt8,8}"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"N0f8"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
" width=\"25mm\" height=\"25mm\" viewBox=\"0 0 1 1\">\n",
" <rect width=\"1\" height=\"1\"\n",
" fill=\"#FF0000\" stroke=\"none\"/>\n",
"</svg>\n"
],
"text/plain": [
"RGB{N0f8}(1.0,0.0,0.0)"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rf = RGB{N0f8}(r)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"ColorTypes.RGB{FixedPointNumbers.Normed{UInt8,8}}"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typeof(rf)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"1.0N0f8"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rf.r # a \"Normalised\" fixed-point number: maps a UInt8 to [0,1]"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"0xff"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rf.r.i"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"\"FF0000\""
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hex(rf)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
" width=\"150.0mm\" height=\"100.0mm\"\n",
" shape-rendering=\"crispEdges\">\n",
"<rect x=\"0.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3A0000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9E0000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#560000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#CA0000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F30000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#120000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#030000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#300000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#570000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3E0000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3E0000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#950000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#2B0000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#260000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#CA0000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A60000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#110000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9D0000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#ED0000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EA0000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F00000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#2F0000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#7C0000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#BB0000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#260000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#C50000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#320000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#6F0000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FE0000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#220000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#990000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#5E0000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F50000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A40000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#1C0000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#270000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#C70000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3F0000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#590000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#ED0000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#D20000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#570000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EB0000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EC0000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#510000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#440000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#780000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#900000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#CA0000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EA0000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EF0000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#AB0000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#B70000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F80000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F90000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#ED0000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#160000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3C0000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#430000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#660000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#4E0000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9F0000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#E20000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#190000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#700000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#340000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#AC0000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#E80000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#340000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#C00000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FE0000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#280000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#840000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9E0000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#550000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#DD0000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#980000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#B20000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#120000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#240000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#B70000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FA0000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A10000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#D80000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#060000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#820000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#DE0000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3A0000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F00000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EF0000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#040000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EC0000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#2F0000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#060000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#800000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9C0000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#200000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#060000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#BF0000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#CA0000\" stroke=\"none\" />\n",
"</svg>"
],
"text/plain": [
"10×10 Array{ColorTypes.RGB{Float64},2}:\n",
" RGB{Float64}(0.229055,0.0,0.0) … RGB{Float64}(0.242541,0.0,0.0)\n",
" RGB{Float64}(0.243342,0.0,0.0) RGB{Float64}(0.916366,0.0,0.0)\n",
" RGB{Float64}(0.939744,0.0,0.0) RGB{Float64}(0.135015,0.0,0.0)\n",
" RGB{Float64}(0.60003,0.0,0.0) RGB{Float64}(0.930019,0.0,0.0)\n",
" RGB{Float64}(0.823185,0.0,0.0) RGB{Float64}(0.918825,0.0,0.0)\n",
" RGB{Float64}(0.936867,0.0,0.0) … RGB{Float64}(0.39993,0.0,0.0) \n",
" RGB{Float64}(0.307156,0.0,0.0) RGB{Float64}(0.754343,0.0,0.0)\n",
" RGB{Float64}(0.99677,0.0,0.0) RGB{Float64}(0.141569,0.0,0.0)\n",
" RGB{Float64}(0.717708,0.0,0.0) RGB{Float64}(0.937516,0.0,0.0)\n",
" RGB{Float64}(0.0155086,0.0,0.0) RGB{Float64}(0.791881,0.0,0.0)"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[RGB(rand(),0.0,0.0) for y in 1:10, x in 1:10]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you're using the REPL, you can use `imshow` from `ImageView.jl`:\n",
"```\n",
"Pkg.add(\"ImageView\") # install the package\n",
"using ImageView\n",
"imshow([RGB(rand(),0.0,0.0) for y in 1:10, x in 1:10])\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
" width=\"150.0mm\" height=\"100.0mm\"\n",
" shape-rendering=\"crispEdges\">\n",
"<rect x=\"0.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#600000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#420000\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#770000\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#CA0000\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EA0000\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#320000\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A10000\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#030000\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#CD0000\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A10000\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#66001C\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#D7001C\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#BE001C\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#77001C\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FE001C\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#48001C\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#59001C\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#87001C\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#42001C\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"10.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#5E001C\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#0A0039\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A50039\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#ED0039\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#680039\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#050039\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#310039\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FC0039\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A20039\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#930039\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"20.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#250039\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F60055\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#530055\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#340055\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9D0055\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#360055\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#240055\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#760055\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#690055\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#C80055\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"30.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#DF0055\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#4E0071\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#460071\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#080071\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#700071\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FD0071\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#040071\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FE0071\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#BC0071\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#B10071\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"40.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#8A0071\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#E5008E\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A0008E\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#4B008E\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#26008E\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#5D008E\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#E8008E\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A4008E\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#87008E\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#E5008E\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"50.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EF008E\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#8B00AA\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#AB00AA\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3000AA\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EE00AA\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#2700AA\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#F400AA\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FD00AA\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#CF00AA\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#4800AA\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"60.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#E900AA\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#A100C6\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#EF00C6\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#0800C6\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#0100C6\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#2200C6\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#FE00C6\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#7900C6\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#DB00C6\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#1500C6\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"70.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#7F00C6\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#0700E3\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#B100E3\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#D400E3\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3500E3\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9F00E3\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#3600E3\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#5300E3\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#0400E3\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#1500E3\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"80.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#1300E3\" stroke=\"none\" />\n",
"<rect x=\"0.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#DF00FF\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#7F00FF\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#1D00FF\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#5900FF\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#6D00FF\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#BD00FF\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#7000FF\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#1700FF\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#D000FF\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"90.0mm\"\n",
" width=\"14.0mm\" height=\"9.0mm\"\n",
" fill=\"#9700FF\" stroke=\"none\" />\n",
"</svg>"
],
"text/plain": [
"10×10 Array{ColorTypes.RGB{Float64},2}:\n",
" RGB{Float64}(0.375908,0.0,0.0) … RGB{Float64}(0.63012,0.0,0.0) \n",
" RGB{Float64}(0.401512,0.0,0.111111) RGB{Float64}(0.368022,0.0,0.111111) \n",
" RGB{Float64}(0.0395321,0.0,0.222222) RGB{Float64}(0.143143,0.0,0.222222) \n",
" RGB{Float64}(0.963814,0.0,0.333333) RGB{Float64}(0.872962,0.0,0.333333) \n",
" RGB{Float64}(0.307659,0.0,0.444444) RGB{Float64}(0.540095,0.0,0.444444) \n",
" RGB{Float64}(0.897997,0.0,0.555556) … RGB{Float64}(0.936984,0.0,0.555556) \n",
" RGB{Float64}(0.546146,0.0,0.666667) RGB{Float64}(0.912363,0.0,0.666667) \n",
" RGB{Float64}(0.629814,0.0,0.777778) RGB{Float64}(0.497711,0.0,0.777778) \n",
" RGB{Float64}(0.0283672,0.0,0.888889) RGB{Float64}(0.0752192,0.0,0.888889)\n",
" RGB{Float64}(0.87332,0.0,1.0) RGB{Float64}(0.59321,0.0,1.0) "
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# linspace(a,b,n) constructs a range of n steps that interpolates between a and b\n",
"[RGB(rand(),0.0,y) for y in linspace(0,1,10), x in 1:10]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Colors.jl does lots more than this:\n",
"- Conversion between colour spaces (RGB, HSV, HSL, XYZ, etc.)\n",
"- Colour scales"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
" width=\"150.0mm\" height=\"25.0mm\"\n",
" shape-rendering=\"crispEdges\">\n",
"<rect x=\"0.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#000000\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#FFFF62\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#FF9FFF\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#00D6FF\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#D74400\" stroke=\"none\" />\n",
"<rect x=\"75.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#008029\" stroke=\"none\" />\n",
"<rect x=\"90.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#005FD5\" stroke=\"none\" />\n",
"<rect x=\"105.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#930068\" stroke=\"none\" />\n",
"<rect x=\"120.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#FFCBB5\" stroke=\"none\" />\n",
"<rect x=\"135.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#A78600\" stroke=\"none\" />\n",
"</svg>"
],
"text/plain": [
"10-element Array{ColorTypes.RGB{FixedPointNumbers.Normed{UInt8,8}},1}:\n",
" RGB{N0f8}(0.0,0.0,0.0) \n",
" RGB{N0f8}(1.0,1.0,0.384) \n",
" RGB{N0f8}(1.0,0.624,1.0) \n",
" RGB{N0f8}(0.0,0.839,1.0) \n",
" RGB{N0f8}(0.843,0.267,0.0)\n",
" RGB{N0f8}(0.0,0.502,0.161)\n",
" RGB{N0f8}(0.0,0.373,0.835)\n",
" RGB{N0f8}(0.576,0.0,0.408)\n",
" RGB{N0f8}(1.0,0.796,0.71) \n",
" RGB{N0f8}(0.655,0.525,0.0)"
]
},
"execution_count": 110,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"D = distinguishable_colors(10)"
]
},
{
"cell_type": "code",
"execution_count": 141,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
" width=\"75.0mm\" height=\"25.0mm\"\n",
" shape-rendering=\"crispEdges\">\n",
"<rect x=\"0.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#FF9FFF\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#BFADFF\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#80BBFF\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#40C8FF\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#00D6FF\" stroke=\"none\" />\n",
"</svg>"
],
"text/plain": [
"5-element Array{ColorTypes.RGB{FixedPointNumbers.Normed{UInt8,8}},1}:\n",
" RGB{N0f8}(1.0,0.624,1.0) \n",
" RGB{N0f8}(0.749,0.678,1.0)\n",
" RGB{N0f8}(0.502,0.733,1.0)\n",
" RGB{N0f8}(0.251,0.784,1.0)\n",
" RGB{N0f8}(0.0,0.839,1.0) "
]
},
"execution_count": 141,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"linspace(D[3],D[4],5)"
]
},
{
"cell_type": "code",
"execution_count": 143,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"\n",
" width=\"75.0mm\" height=\"25.0mm\"\n",
" shape-rendering=\"crispEdges\">\n",
"<rect x=\"0.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#FF9FFF\" stroke=\"none\" />\n",
"<rect x=\"15.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#E1AFFF\" stroke=\"none\" />\n",
"<rect x=\"30.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#BCBDFF\" stroke=\"none\" />\n",
"<rect x=\"45.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#89CAFF\" stroke=\"none\" />\n",
"<rect x=\"60.0mm\" y=\"0.0mm\"\n",
" width=\"14.0mm\" height=\"25.0mm\"\n",
" fill=\"#00D6FF\" stroke=\"none\" />\n",
"</svg>"
],
"text/plain": [
"5-element Array{ColorTypes.XYZ{Float32},1}:\n",
" XYZ{Float32}(0.716867,0.532794,1.01096)\n",
" XYZ{Float32}(0.642872,0.537864,1.01584)\n",
" XYZ{Float32}(0.568877,0.542934,1.02071)\n",
" XYZ{Float32}(0.494882,0.548004,1.02558)\n",
" XYZ{Float32}(0.420887,0.553074,1.03045)"
]
},
"execution_count": 143,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"linspace(XYZ(D[3]),XYZ(D[4]),5) # the technically \"correct\" way"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The SenseHat.jl package contains some utilities for working with the Raspberry Pi Sense Hat.\n",
"\n",
"```julia\n",
"using SenseHat\n",
"\n",
"LED = led_matrix()\n",
"```\n",
"\n",
"will create an 8x8 array that is memory-mapped to the framebuffer. Assign colours to the coordinates (you can use any colour space, conversion is automatic).\n",
"\n",
"```julia\n",
"LED[1,4] = RGB(1,0,0) # assign a single pixel (note the change of axes).\n",
"LED[:] = SenseHat.JULIA_LOGO # copy the values from an existing matrix\n",
"led_clear() # a convenience function which sets all pixels to black\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exercise 1: The Mandelbrot set\n",
"\n",
"<center><img src=\"mandelbrot_set.jpg\" width=\"300\"></center>\n",
"\n",
"The Mandelbrot set is a defined as the set of complex numbers $c$ for which the recursion\n",
"\n",
"$$ z_n = \\begin{cases} \n",
" 0 & n = 0\\\\\n",
" z_{n-1}^2 + c & n = 1,2,\\ldots \n",
" \\end{cases} $$\n",
"\n",
"remains bounded.\n",
"\n",
"Tasks:\n",
"\n",
"1. Write a function `mandelbrot` which determines if a complex number is in the set:\n",
" - can construct a complex number by `complex(x,y)` or `x + im*y`\n",
" - can stop the recursion once $|z_n| > 2$, as the sequence is guaranteed to diverge.\n",
" - will need to choose a value to stop the recursion.\n",
"\n",
"2. Generate an image of it.\n",
" - A common rendering is to colour the outside values based on the \"speed\" of divergence, such as the number of iterations required for $|z_n| > 2$.\n",
" - Look at the different colour spaces\n",
" - If using Jupyter, don't make it too big! (start with 100&times;100: this is a limitation of HTML notebooks)\n",
"\n",
"3. Now display it on the Sense Hat LED matrix\n",
" - 8x8 pixels isn't great for showing a fractal, but try creating an animation that zooms in on a particular area\n",
" - `sleep` can be used to slow it down.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# A bit more about types and functions\n",
"\n",
"\n",
"## Generic functions and multiple dispatch\n",
"\n",
"Julia functions are *generic* in that different code paths can be called depending on the type arguments."
]
},
{
"cell_type": "code",
"execution_count": 169,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"f (generic function with 2 methods)"
]
},
"execution_count": 169,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(x::Float64) = \"$x is a float\"\n",
"f(x::Int) = \"$x is an integer\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* `f(...) = ...` is a short version of `function f(...) ... end`\n",
"* `::` is an optional *type specification*.\n",
"* `$` inside a string does variable interpolation"
]
},
{
"cell_type": "code",
"execution_count": 170,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"\"1.0 is a float\""
]
},
"execution_count": 170,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(1.0)"
]
},
{
"cell_type": "code",
"execution_count": 171,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"\"1 is an integer\""
]
},
"execution_count": 171,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Julia \"object oriented\" paradigm is a bit different than the \"dot-based\" approach of Python:\n",
" - functions don't \"belong\" to a type. \n",
" - the method is selected based on _all_ arguments: this is known as *multiple dispatch*"
]
},
{
"cell_type": "code",
"execution_count": 172,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"f (generic function with 5 methods)"
]
},
"execution_count": 172,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(x::Float64,y::Int) = \"$x is a float, but $y is an integer\"\n",
"f(x::Real,y::Real) = \"$x and $y are both some sort of real\" # Real is an abstract \"super\" type\n",
"f(x,y) = \"I don't know what $x and $y are\" # fallback"
]
},
{
"cell_type": "code",
"execution_count": 173,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"\"1.0 is a float, but 1 is an integer\""
]
},
"execution_count": 173,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(1.0,1)"
]
},
{
"cell_type": "code",
"execution_count": 174,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"\"1 and 1 are both some sort of real\""
]
},
"execution_count": 174,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(1,1)"
]
},
{
"cell_type": "code",
"execution_count": 175,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"\"I don't know what aaa and 2 are\""
]
},
"execution_count": 175,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f(\"aaa\",2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Where this is useful:\n",
"- `*` for matrix multiplication can dispatch on the most efficient method:\n",
" - BLAS for ordinary `Float32`/`Float64` matrices\n",
" - specialised methods for sparse, triangular, diagonal, tridiagonal\n",
" - generic fallback for other types (e.g. `Rational`, `BigFloat`)\n",
"- `show` for displaying objects based on MIME type supported:\n",
" - this is how Jupyter displays colours for `RGB` objects\n",
"- `convert` for converting between different types (often called implicitly, e.g. when assigning to an array)\n",
" - makes it easy to compose packages together"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can tell which method is called by the `@which` macro"
]
},
{
"cell_type": "code",
"execution_count": 178,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"gcd<i>{T<:Union{Int128,Int64,UInt128,UInt64}}</i>(a::<b>T</b>, b::<b>T</b>) at <a href=\"https://github.com/JuliaLang/julia/tree/6445c82d0060dbe82b88436f0f4371a4ee64d918/base/intfuncs.jl#L17\" target=\"_blank\">intfuncs.jl:17</a>"
],
"text/plain": [
"gcd{T<:Union{Int128,Int64,UInt128,UInt64}}(a::T, b::T) at intfuncs.jl:17"
]
},
"execution_count": 178,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@which gcd(10,3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See also `@less` and `@edit`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Just-in-time (JIT) compilation\n",
"\n",
"The first time you call a function with a specific _signature_ (i.e. a combination of argument types) it is just-in-time compiled. This does several steps, each of which can be inspected:\n",
"\n",
"### 1. Code lowering\n",
"This strips out syntactic sugar (e.g. `a += b` => `a = a + b`), expands macros, and simplifies loops to a \"goto\" style:"
]
},
{
"cell_type": "code",
"execution_count": 176,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"LambdaInfo template for gcd{T<:Union{Int128,Int64,UInt128,UInt64}}(a::T, b::T) at intfuncs.jl:17\n",
":(begin \n",
" nothing\n",
" NewvarNode(:(za))\n",
" NewvarNode(:(zb))\n",
" NewvarNode(:(k))\n",
" NewvarNode(:(u))\n",
" NewvarNode(:(v))\n",
" NewvarNode(:(r))\n",
" unless a == 0 goto 11\n",
" return (Base.abs)(b)\n",
" goto 11\n",
" 11: # line 18:\n",
" unless b == 0 goto 16\n",
" return (Base.abs)(a)\n",
" goto 16\n",
" 16: # line 19:\n",
" za = (Base.trailing_zeros)(a) # line 20:\n",
" zb = (Base.trailing_zeros)(b) # line 21:\n",
" k = (Base.min)(za,zb) # line 22:\n",
" u = (Base.unsigned)((Base.abs)(a >> za)) # line 23:\n",
" v = (Base.unsigned)((Base.abs)(b >> zb)) # line 24:\n",
" 28: \n",
" unless u != v goto 44 # line 25:\n",
" unless u > v goto 37 # line 26:\n",
" SSAValue(0) = v\n",
" SSAValue(1) = u\n",
" u = SSAValue(0)\n",
" v = SSAValue(1)\n",
" 37: # line 28:\n",
" v = v - u # line 29:\n",
" v = v >> (Base.trailing_zeros)(v)\n",
" 42: \n",
" goto 28\n",
" 44: # line 31:\n",
" r = u << k # line 33:\n",
" unless r > (Base.typemax)($(Expr(:static_parameter, 1))) goto 51\n",
" (Base.throw)((Base.OverflowError)())\n",
" goto 51\n",
" 51: # line 34:\n",
" return r % $(Expr(:static_parameter, 1))\n",
" end)"
]
},
"execution_count": 176,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@code_lowered gcd(10,3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2. Type inference\n",
"\n",
"Julia then tries to determine the type of each variable, based on the input type to each function call"
]
},
{
"cell_type": "code",
"execution_count": 179,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"LambdaInfo for gcd(::Int64, ::Int64)\n",
":(begin \n",
" NewvarNode(:(za))\n",
" NewvarNode(:(zb))\n",
" NewvarNode(:(k))\n",
" NewvarNode(:(u))\n",
" NewvarNode(:(v))\n",
" NewvarNode(:(r))\n",
" unless (a === 0)::Bool goto 9\n",
" return (Base.box)(Int64,(Base.flipsign_int)(b,b))\n",
" 9: # line 18:\n",
" unless (b === 0)::Bool goto 13\n",
" return (Base.box)(Int64,(Base.flipsign_int)(a,a))\n",
" 13: # line 19:\n",
" za = (Base.box)(Int64,(Base.cttz_int)(a)) # line 20:\n",
" zb = (Base.box)(Int64,(Base.cttz_int)(b)) # line 21:\n",
" k = (Base.select_value)((Base.slt_int)(zb,za)::Bool,zb,za)::Int64 # line 22:\n",
" SSAValue(2) = (Base.select_value)((Base.sle_int)(0,za)::Bool,(Base.box)(Int64,(Base.ashr_int)(a,(Base.box)(UInt64,za))),(Base.box)(Int64,(Base.shl_int)(a,(Base.box)(UInt64,(Base.box)(Int64,(Base.neg_int)(za))))))::Int64\n",
" u = (Base.box)(UInt64,(Base.box)(Int64,(Base.flipsign_int)(SSAValue(2),SSAValue(2)))) # line 23:\n",
" SSAValue(3) = (Base.select_value)((Base.sle_int)(0,zb)::Bool,(Base.box)(Int64,(Base.ashr_int)(b,(Base.box)(UInt64,zb))),(Base.box)(Int64,(Base.shl_int)(b,(Base.box)(UInt64,(Base.box)(Int64,(Base.neg_int)(zb))))))::Int64\n",
" v = (Base.box)(UInt64,(Base.box)(Int64,(Base.flipsign_int)(SSAValue(3),SSAValue(3)))) # line 24:\n",
" 27: \n",
" unless (Base.box)(Base.Bool,(Base.not_int)((u === v)::Bool)) goto 44 # line 25:\n",
" unless (Base.ult_int)(v,u)::Bool goto 36 # line 26:\n",
" SSAValue(0) = v\n",
" SSAValue(1) = u\n",
" u = SSAValue(0)\n",
" v = SSAValue(1)\n",
" 36: # line 28:\n",
" v = (Base.box)(UInt64,(Base.sub_int)(v,u)) # line 29:\n",
" SSAValue(4) = (Base.box)(Int64,(Base.check_top_bit)((Base.box)(UInt64,(Base.cttz_int)(v))))\n",
" v = (Base.select_value)((Base.sle_int)(0,SSAValue(4))::Bool,(Base.box)(UInt64,(Base.lshr_int)(v,(Base.box)(UInt64,SSAValue(4)))),(Base.box)(UInt64,(Base.shl_int)(v,(Base.box)(UInt64,(Base.box)(Int64,(Base.neg_int)(SSAValue(4)))))))::UInt64\n",
" 42: \n",
" goto 27\n",
" 44: # line 31:\n",
" r = (Base.select_value)((Base.sle_int)(0,k)::Bool,(Base.box)(UInt64,(Base.shl_int)(u,(Base.box)(UInt64,k))),(Base.box)(UInt64,(Base.lshr_int)(u,(Base.box)(UInt64,(Base.box)(Int64,(Base.neg_int)(k))))))::UInt64 # line 33:\n",
" SSAValue(5) = $(Expr(:invoke, LambdaInfo for typemax(::Type{Int64}), :(Base.typemax), :($(Expr(:static_parameter, 1)))))\n",
" unless (Base.box)(Base.Bool,(Base.or_int)((Base.slt_int)(SSAValue(5),0)::Bool,(Base.ult_int)((Base.box)(UInt64,SSAValue(5)),r)::Bool)) goto 51\n",
" (Base.throw)($(Expr(:new, :(Core.OverflowError))))::Union{}\n",
" 51: # line 34:\n",
" return (Base.box)(Int64,r)\n",
" end::Int64)"
]
},
"execution_count": 179,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@code_typed gcd(10,3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Note**: one reason for poor performance is when the type of a variable cannot be exactly inferred, typically because it changes (known as _type instability_), e.g.\n",
"```julia\n",
"x = 1 # Int\n",
"x += sqrt(x) # Float64\n",
"```\n",
"\n",
"This leads to certain compromises, e.g. Julia's integers overflow instead of promoting to arbitrary-precision"
]
},
{
"cell_type": "code",
"execution_count": 182,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"9223372036854775807"
]
},
"execution_count": 182,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typemax(Int)"
]
},
{
"cell_type": "code",
"execution_count": 183,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"-9223372036854775808"
]
},
"execution_count": 183,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"typemax(Int)+1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`@code_warntype` is similar to `@code_typed`, but highlights when instabilities arise"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. LLVM\n",
"\n",
"The Julia code is translated to LLVM intermediate representation (IR), and optimisations are applied"
]
},
{
"cell_type": "code",
"execution_count": 180,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"define i64 @julia_gcd_71903(i64, i64) #0 {\n",
"top:\n",
" %2 = icmp eq i64 %0, 0\n",
" br i1 %2, label %if, label %L\n",
"\n",
"L: ; preds = %top\n",
" %3 = icmp eq i64 %1, 0\n",
" br i1 %3, label %if7, label %L1\n",
"\n",
"L1: ; preds = %L\n",
" %4 = call i64 @llvm.cttz.i64(i64 %0, i1 false)\n",
" %5 = call i64 @llvm.cttz.i64(i64 %1, i1 false)\n",
" %6 = icmp ugt i64 %4, 63\n",
" %.v = select i1 %6, i64 63, i64 %4\n",
" %7 = ashr i64 %0, %.v\n",
" %8 = ashr i64 %7, 63\n",
" %9 = add i64 %8, %7\n",
" %10 = xor i64 %9, %8\n",
" %11 = icmp ugt i64 %5, 63\n",
" %.v12 = select i1 %11, i64 63, i64 %5\n",
" %12 = ashr i64 %1, %.v12\n",
" %13 = ashr i64 %12, 63\n",
" %14 = add i64 %13, %12\n",
" %15 = xor i64 %14, %13\n",
" %16 = icmp eq i64 %10, %15\n",
" br i1 %16, label %L5, label %if9.preheader\n",
"\n",
"if9.preheader: ; preds = %L1\n",
" br label %if9\n",
"\n",
"L5.loopexit: ; preds = %pass\n",
" br label %L5\n",
"\n",
"L5: ; preds = %L5.loopexit, %L1\n",
" %u.0.lcssa = phi i64 [ %10, %L1 ], [ %u.1, %L5.loopexit ]\n",
" %17 = icmp uge i64 %5, %4\n",
" %18 = select i1 %17, i64 %4, i64 %5\n",
" %19 = icmp ugt i64 %18, 63\n",
" %20 = shl i64 %u.0.lcssa, %18\n",
" %21 = select i1 %19, i64 0, i64 %20\n",
" %22 = icmp sgt i64 %21, -1\n",
" br i1 %22, label %L6, label %if11\n",
"\n",
"L6: ; preds = %L5\n",
" ret i64 %21\n",
"\n",
"if: ; preds = %top\n",
" %23 = ashr i64 %1, 63\n",
" %24 = add i64 %23, %1\n",
" %25 = xor i64 %24, %23\n",
" ret i64 %25\n",
"\n",
"if7: ; preds = %L\n",
" %26 = ashr i64 %0, 63\n",
" %27 = add i64 %26, %0\n",
" %28 = xor i64 %27, %26\n",
" ret i64 %28\n",
"\n",
"if9: ; preds = %if9.preheader, %pass\n",
" %storemerge14 = phi i64 [ %34, %pass ], [ %15, %if9.preheader ]\n",
" %u.013 = phi i64 [ %u.1, %pass ], [ %10, %if9.preheader ]\n",
" %29 = icmp ult i64 %storemerge14, %u.013\n",
" br i1 %29, label %if10, label %pass\n",
"\n",
"if10: ; preds = %if9\n",
" br label %pass\n",
"\n",
"pass: ; preds = %if10, %if9\n",
" %u.1 = phi i64 [ %storemerge14, %if10 ], [ %u.013, %if9 ]\n",
" %v.0 = phi i64 [ %u.013, %if10 ], [ %storemerge14, %if9 ]\n",
" %30 = sub i64 %v.0, %u.1\n",
" %31 = call i64 @llvm.cttz.i64(i64 %30, i1 false)\n",
" %32 = icmp ugt i64 %31, 63\n",
" %33 = lshr i64 %30, %31\n",
" %34 = select i1 %32, i64 0, i64 %33\n",
" %35 = icmp eq i64 %u.1, %34\n",
" br i1 %35, label %L5.loopexit, label %if9\n",
"\n",
"if11: ; preds = %L5\n",
" call void @jl_throw(%jl_value_t* inttoptr (i64 4467224192 to %jl_value_t*))\n",
" unreachable\n",
"}\n"
]
}
],
"source": [
"@code_llvm gcd(10,3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Machine code\n",
"\n",
"Finally LLVM is compiled to the native machine code for that platform"
]
},
{
"cell_type": "code",
"execution_count": 181,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\t.section\t__TEXT,__text,regular,pure_instructions\n",
"Filename: intfuncs.jl\n",
"\tpushq\t%rbp\n",
"\tmovq\t%rsp, %rbp\n",
"Source line: 17\n",
"\ttestq\t%rdi, %rdi\n",
"\tje\tL105\n",
"Source line: 18\n",
"\ttestq\t%rsi, %rsi\n",
"\tje\tL121\n",
"Source line: 19\n",
"\tbsfq\t%rdi, %r10\n",
"\tmovl\t$64, %eax\n",
"\tcmoveq\t%rax, %r10\n",
"Source line: 20\n",
"\tbsfq\t%rsi, %r9\n",
"\tcmoveq\t%rax, %r9\n",
"Source line: 22\n",
"\tcmpq\t$63, %r10\n",
"\tmovb\t$63, %r8b\n",
"\tmovb\t$63, %cl\n",
"\tja\tL49\n",
"\tmovb\t%r10b, %cl\n",
"L49:\n",
"\tsarq\t%cl, %rdi\n",
"\tmovq\t%rdi, %rax\n",
"\tsarq\t$63, %rax\n",
"\tleaq\t(%rdi,%rax), %rdi\n",
"\txorq\t%rax, %rdi\n",
"Source line: 23\n",
"\tcmpq\t$63, %r9\n",
"\tja\tL75\n",
"\tmovb\t%r9b, %r8b\n",
"L75:\n",
"\tmovb\t%r8b, %cl\n",
"\tsarq\t%cl, %rsi\n",
"\tmovq\t%rsi, %rax\n",
"\tsarq\t$63, %rax\n",
"\tleaq\t(%rsi,%rax), %rcx\n",
"\txorq\t%rax, %rcx\n",
"Source line: 24\n",
"\tcmpq\t%rcx, %rdi\n",
"\tjne\tL137\n",
"\tmovq\t%rdi, %rsi\n",
"\tjmp\tL199\n",
"Source line: 17\n",
"L105:\n",
"\tmovq\t%rsi, %rcx\n",
"\tsarq\t$63, %rcx\n",
"\tleaq\t(%rsi,%rcx), %rax\n",
"\txorq\t%rcx, %rax\n",
"\tpopq\t%rbp\n",
"\tretq\n",
"Source line: 18\n",
"L121:\n",
"\tmovq\t%rdi, %rcx\n",
"\tsarq\t$63, %rcx\n",
"\tleaq\t(%rdi,%rcx), %rax\n",
"\txorq\t%rcx, %rax\n",
"\tpopq\t%rbp\n",
"\tretq\n",
"Source line: 29\n",
"L137:\n",
"\tmovl\t$64, %edx\n",
"\txorl\t%eax, %eax\n",
"Source line: 25\n",
"L144:\n",
"\tcmpq\t%rdi, %rcx\n",
"\tjae\tL160\n",
"\tmovq\t%rcx, %rsi\n",
"\tjmp\tL166\n",
"\tnopw\t(%rax,%rax)\n",
"L160:\n",
"\tmovq\t%rdi, %rsi\n",
"\tmovq\t%rcx, %rdi\n",
"Source line: 28\n",
"L166:\n",
"\tsubq\t%rsi, %rdi\n",
"Source line: 29\n",
"\tbsfq\t%rdi, %rcx\n",
"\tcmoveq\t%rdx, %rcx\n",
"\tshrq\t%cl, %rdi\n",
"\tcmpq\t$63, %rcx\n",
"\tcmovaq\t%rax, %rdi\n",
"Source line: 24\n",
"\tcmpq\t%rdi, %rsi\n",
"\tmovq\t%rdi, %rcx\n",
"\tmovq\t%rsi, %rdi\n",
"\tjne\tL144\n",
"Source line: 21\n",
"L199:\n",
"\tcmpq\t%r10, %r9\n",
"\tmovq\t%r9, %rdx\n",
"\tcmovaeq\t%r10, %rdx\n",
"Source line: 31\n",
"\tjae\tL214\n",
"\tmovb\t%r9b, %r10b\n",
"L214:\n",
"\tmovb\t%r10b, %cl\n",
"\tshlq\t%cl, %rsi\n",
"\txorl\t%eax, %eax\n",
"\tcmpq\t$63, %rdx\n",
"\tcmovbeq\t%rsi, %rax\n",
"Source line: 33\n",
"\ttestq\t%rax, %rax\n",
"\tjs\tL237\n",
"Source line: 34\n",
"\tpopq\t%rbp\n",
"\tretq\n",
"Source line: 33\n",
"L237:\n",
"\tmovabsq\t$jl_throw, %rax\n",
"\tmovabsq\t$4467224192, %rdi ## imm = 0x10A446E80\n",
"\tcallq\t*%rax\n",
"\tnopw\t%cs:(%rax,%rax)\n"
]
}
],
"source": [
"@code_native gcd(10,3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Joystick interaction and tasks\n",
"\n",
"```\n",
"readstick()\n",
"```\n",
"will block the current Julia task, and wait until the joystick is manipulated\n",
"\n",
"It returns a `StickEvent` object.\n",
"\n",
"This is a _composite_ type with 3 fields:\n",
"```\n",
"immutable StickEvent\n",
" timestamp::DateTime\n",
" direc::Direc\n",
" state::State\n",
"end\n",
"```\n",
"\n",
"- `DateTime` is a timestamp type\n",
"- `Direc` is an _Enum_ type, with values\n",
" - `Stick.UP`\n",
" - `Stick.DOWN`\n",
" - `Stick.LEFT`\n",
" - `Stick.RIGHT`\n",
" - `Stick.MIDDLE`\n",
"- `State` is an Enum type with values \n",
" - `Stick.PRESS`\n",
" - `Stick.RELEASE`\n",
" - `Stick.HOLD`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively, you use _tasks_: these are \"souped-up\" versions of python generators.\n",
"\n",
"`sticktask()` creates a task that produces `StickEvents`: you can access them via an iterator:\n",
"\n",
"```julia\n",
"for ev in sticktask()\n",
" println(ev)\n",
"end\n",
"```\n",
"Note that this will block, so nothing can be run while it is in use.\n",
"\n",
"\n",
"The `@schedule` macro can be used to create a new task which will be added to the scheduler and run while the system is otherwise idle:\n",
"```julia\n",
"@schedule for ev in sticktask()\n",
" println(ev)\n",
"end\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exercise 2: Snake\n",
"\n",
"For those who remember old Nokia phones, we're going to recreate snake. The basic rules:\n",
"\n",
"- you have a snake of length `n`, which moves forward one block at a time\n",
"- you can change the direction with the joystick\n",
"- the aim is to eat the \"blobs\" which appear randomly (wherever the snake isn't)\n",
"- each time you eat a blob the snake gets 1 unit longer\n",
"- if you run into the edge, or into the snakes body, the game is over.\n",
"\n",
"Optional:\n",
"- speed up\n",
"- add colours\n",
"- print the score at the end"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 0.5.0",
"language": "julia",
"name": "julia-0.5"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "0.5.1"
},
"widgets": {
"state": {},
"version": "1.1.2"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment