Tools

Here, I would like to summarize the free software and programming languages I like to use, possibly giving a short explanation why I prefer them over others and give tools I have tested but dismissed to use at the end.

Julia – Favorite Programming Language

Familar with: C++, Python, Java

Tested: LISP, Clojure, Haskell, C, JavaScript

When I first came across julia back in 2014, I was thinking of at as good exercise to learn a new language, mainly for plotting and analysis part of my daily scientific work. But after playing around with it for a while I soon realized that this new language hast the power to replace anything I used so far and combine speed, easiness and versatility in one solution. For now, I use it for anything from performance related code for cluster calculation to statistical analysis and plotting and even small scripts.

What I particularly like about this language is the integrated parallelism, fully typed code under the hood but only visible if needed, possibility to use UTF8 symbols and the end keyword instead of indentation syntax. Really, I love indentation and I use it to 100%, but that is exactly the reason I don’t want to rely on it as a part of the syntax – goodbye copy/paste and welcome debugging.

In my opinion we will see a big change and growth of the julia language in the upcoming 5 to 10 years.
Basically, it is much closer to julia than previous versions and shares a lot of modern concepts, exact that the syntax is much more complex, usually.

Here is and example code which is an introduction to julia I did for a tutorial.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# Welcome to julia introduction
# by Stanislav Kazmin

# You can download julia from: https://julialang.org/downloads/
# The documentation can be found on https://docs.julialang.org/en/v1/
# The forum can be used to ask questions or search for similar problems: https://discourse.julialang.org
# After extracting the .tar archive you should be able to run julia by executing bin/julia.
# To run a script interactively, load it by executing `include("path/to/script.jl)` inside the REPL.
# In my opinion the best way to use julia is within Atom or VS Code where you can send
# parts of a script, blocks or the whole file directly to the REPL.
# This file is meant to be executed line by line.
# The output is written in a comment after the code on the same line.
# NOTE: On a 32 bit machine the default types would be Int32 and Float32.

# In the REPL when the prompt is empty, typing ? and typing a function/type name (or part of the name) will open the
# documentation fo this function/type.
# In the REPL when the prompt is empty, typing ] will lead to the package manager mode.
# Here one can add packages by typing "add PackageName" (tab works for auto-complete the names).
# Some useful packages are PyPlot, Plots, DataFrames.
# You can leave the help mode or the package manager mode by pressing the backspace when the prompt is empty.

# Once a package is downloaded it can be used by calling e. g.
using LinearAlgebra # preinstalled package
# Note, that the first call for a specific package may take longer because the packages get precompiled.

# lines starting with '#' or everything after '#' on the same line is considered as a comment

###################################################
# Basics
###################################################

# In julia every object/structure/number has a type.
# They follow a hierarchy and are essential part of julia's concept.

# Basic number types are
1 # Int64
1.0 # Float64
1e2 # also a Float64, not Int64!
1 // 2 # Rational
big"123456789123456789123456789" # BigInt
true # Bool
false # Bool

# One can check the type of any object by calling e. g.
typeof(1.0)

# When defining a variable we do not have to explicitly state the type.
# However a concrete type will be determined by julia.
a = 2.0
typeof(a) # Float64

# One can redefine variables and give them other types
a = 2
typeof(a) # Int64

# To avoid such redefinitions one can use the `const` prefix (only in global scope).
# This will force the variable to have the type it was first defined with.
# However, you still will be able to change its value (a warning will be printed, though).
const c = 3.14
typeof(c) # Float64
c = 2.71 # WARNING: redefining constant c
c = 1 # ERROR: invalid redefinition of constant c

###################################################
# Basic Operations
###################################################

1 + 3 # 4
1 + 3.0 # 4.0; the type is "promoted" to the type which can hold the result
1 / 2 # 0.5 (Float64); integer division is promoted to Float64
1 / 2.0 # 0.5 (Float64)
div(1, 2) # 0 (Int64); this is the integer division as used in c/cpp
1 ÷ 2 # 0 (Int64); same as div(1, 2) but using the unicode symbol '÷'
3 * 4 # 12
a = 2.0
3a # 6.0; you can skip the '*' for multiplication when the number is followed by a variable or parenthesis
3(4 + 5) # 27
4^2 # 16 (Int64); '^' is the power operator
4.0^6 # 4096.0
1 + 2im # Complex Number
# It is a parametric type Complex{Int64} - complex number a + b*i where a and b are Int64.
# More on parametric types will be discussed later.
# It is useful as you can e. g. perform an exact complex number division bu using rationals
(1 + 2im) // (3 - 4im) # -1//5 + 2//5*im
typeof(-1//5 + 2//5*im) # Complex{Rational{Int}}
# Further, you have the mod operator '%' and the left-division operator '\'
# '\' is much more powerful and is used to efficiently solve system of equations in matrix form.
35 / 5 # 7.0
5 \ 35 # 7.0
35 % 7 # 0
35 % 36 # 35
sqrt(2) # 1.4142135623730951
2 # 1.4142135623730951
Complex(-2) # 0.0 + 1.4142135623730951im

###################################################
# Strings
###################################################

# Strings are enclosed into double quotes.
# Single quotes define a single character (different type).

s = "This is a string."

# Multi-line strings can be defined through tripled double quotes.
s2 = """First line
Second line"""

# Alternatively you can use the new line escape character \n.
s3 = "First line\nSecond line"
s2 == s3 # true

# String concatenation is done with '*' (not '+' like in other languages, because the operation in non-commutative).
"String 1" * " String 2"

# However, this is rarely needed as one can use a very powerful string interpolation with '$'.
a = 1
b = "COOL!"
"a is $a. When we add 3 to it, it becomes $(a + 3). $(b)"

###################################################
# Functions
###################################################

# Functions are defined with the 'function' keyword.
# The return value is the last statement in the function.
# The 'return' keyword is optional.

function add1(x)
  x + 1 # same as return x + 1
end

# You can use a shorter notation.
add1(x) = x + 1

# You can define default values for the arguments (the arguments without default values come first).
myadd(x, y = 0) = x + y
myadd(1) # 1
myadd(1, 2) # 3
# myadd(x = 0, y) is not valid.

# You can define keyword arguments after a semicolon ';'.
question(surname, q = "How are you?"; answer = "I'm fine!") = "$(q) $(surname): $(answer)"
question("Martin") # "How are you? Martin: I'm fine!"
question("Robot", "How old are you?") # "How old are you? Robot: I'm fine!"
question("Ann"; answer = "I am sleepy...") # "How are you? Ann: I am sleepy..."

# Functions in julia are first class elements.
# They can be passed as arguments to other function and defined within other functions.
# They never belong to a certain object like in cpp or python.
f(x) = 2*x
mymap(f, x) = f(x)
mymap(f, 2) # 4
mymap(identity, 2) # 2

# Because functions are first class, julia offers a convenient anonymous/lambda function notation.
x -> 2*x # this is a function without a name
mymap(x -> 2*x, 2) # 4
mymap(x -> x^3, 2) # 8
mymap((x, y = 4) -> x^y, 2) # 16

# Larger lambda functions can be defined by using 'function' keyword but skipping the name.
function (x)
  x^2
end

# To return multiple values you can use a tuple.
f(x, y) = (2*x, 3*y)
f(3, 3) # (6, 9)

# You can use the splice operator '...' to define arbitrary number of arguments.
varargs(x...) = x
varargs(1) # (1,) tuple with one element ≠ 1
varargs(1, 2) # (1, 2)
varargs(1, 2, 3, 4, 5) # (1, 2, 3, 4, 5)

# In a similar way you can split the arguments into a function call with '...'
f(x, y) = x + y
f((1,2)...) # 3

# when calling a function and using keyword arguments you can ether use a semicolon or a comma.
# f(x, y; a = 1) or f(x, y, a = 1)

# An important aspect is that you can specify the type of the arguments for a function and by this dispatch on the types.
# Julia will dispatch on the types of all arguments.
myfunc(x, y) = "generic"
myfunc(x::String, y::String) = "both are strings"
myfunc(x::Number, y) = "x is a number"
myfunc(1, 3) # "x is a number"
myfunc((3,4), 3) # "generic"
myfunc("a", "s") # "both are strings"

# It is important to know, that julia will always deduce the type of all arguments
# and compile/call the function which matches the types (called a method).
# This allows julia to produce very efficient code.

###################################################
# Ranges
###################################################

# A useful type in julia is the range type.
# You can define a range with the ':' operator or with the range function
1:10
typeof(1:10) # UnitRange{Int64}
1:2:10 # 1:2:9; start at 1 and go in steps of 2 until ≤ 10
range(1, 10; step = 1) # 1:1:10
range(1, 10; step = 0.1) # 1.0:0.1:10.0
range(1, 9; length = 101) # 1.0:0.08:9.0
range(1, step = 1, length = 10) # 1:1:10
0.0 : -0.01 : -π # 0.0:-0.01:-3.14

###################################################
# Control Flow
###################################################

# Every block in julia starts with a keyword and ends with 'end'.
# conditions are defined by in the following way
a = 3
if a > 2
  println("larger")
end # larger

a = 1
if a > 2
  println("larger")
else
  println("smaller")
end # smaller

a = 2
if a > 2
  println("larger")
elseif a < 2
  println("smaller")
else
  println("equal")
end # equal

# The trinary operator is also available.
2 > 1 ? true : false # true

# You can use ! to invert the condition.
!(2 > 1) ? true : false # false

# Finally, you can use lazy && (and) and || (or) for conditional execution
2 > 1 && (d = true) # true
d # true
0 > 1 || (d = false) # false
d # false
0 > 1 && (d = 45) # false (here, the d = 45 was not performed, as the first condition was wrong, this is the why it is called "lazy")
d # false

# We can do a simple for loop (iterating over a certain variable).
# You can use 'in, '=' or '∈' in the for loop definition.
# The values to iterate over can be arrays, ranges, generators, strings, ...
for i in 1:10
  println(i)
end

# a while loop executed as long as the condition is true
function easy_while()
  i = 1
  while i < 10
    println(i)
    i += 1
  end
end
easy_while()

# NOTE: in julia for and while introduce a new local scope.
# To access variables outside the loop in the global scope you have to use 'global'.
# However, inside a function you can access variables outside the loop!
x = 0
for i ∈ 1:10
  global x += i
end
x # 55

# but
function for_loop()
  x = 0
  for i ∈ 1:10
    x += i
  end
  return x
end
for_loop() # 55

# you can use 'continue' or 'break' inside a for loop to manipulate the flow
for i in 1:10
  if i == 2
    continue
  end
  if i == 5
    break
  end
  println(i)
end # prints 1, 3 and 4

# You can always use 'begin' and 'end' to enclose code (useful in Atom/VS code to call a whole code block).
begin
  a = 1
  b = 2
end

# You can introduce local scopes with 'let'
x = 0
let
  x = 0
  for i ∈ 1:10
    x += i
  end
  @show x # x = 55
end # 55
x # 0 (the global variable was not changed)

###################################################
# Unicode Characters and Syntactic Sugar
###################################################

# In julia you are allowed to use (nearly) any UTF8 character.
# In the REPL you can start to type '\' and the corresponding latex name like \alpha
# and then press TAB to auto-complete the the unicode character α.
# In Atom/VS Code/Emacs (and others?) you have extensions for inserting unicode characters.
π # π = 3.1415926535897...
α = 2
Σ = sum
Σ([1, 2, 3]) # 6
a +² b = a^2 + b^2 # you can define arbitrary infix operators by appending some subscripts/superscripts to them.
34 # 25

f ⊕ g = x -> f(x) + g(x) # apply f and g on x and take the sum

f(x) = 2x
g(x) = x + 3
(f ⊕ g)(4) # 15

# function concatenation
(f ∘ g)(4) # 14; the same as f(g(4))
# result piping
g(4) |> f # 14

And here is a working implementation of forward auto-differentiation, i.e., numerically exact computer differentiation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
struct Dual{T <: Number} <: Number
  x::T
  dx::T
end

Dual(x::Number, y::Number) = Dual(promote(x, y)...)

Base.convert(::Type{Dual{T}}, x::Dual{T}) where T = x
Base.convert(::Type{Dual{T}}, x::Dual) where {T <: Number} = Dual(convert(T, x.x), convert(T, x.dx))
Base.convert(::Type{Dual{T}}, x::Number) where {T <: Number} = Dual(convert(T, x), zero(x))

Base.promote_rule(::Type{Dual{T}}, ::Type{Dual{U}}) where {T <: Number,U <: Number} = Dual{promote_type(T, U)}
Base.promote_rule(::Type{Dual{T}}, ::Type{U})  where {T <: Number,U <: Number}      = Dual{promote_type(T, U)}

Base.:+(u::Dual, v::Dual) = Dual(u.x + v.x, u.dx + v.dx)
Base.:-(u::Dual) = Dual(-u.x, -u.dx)
Base.:-(u::Dual, v::Dual) = u + -v

Base.:*(u::Dual, v::Dual) = Dual(u.x * v.x, u.dx * v.x + v.dx * u.x)
Base.:inv(u::Dual) = Dual(1 / u.x, -u.x / u.dx^2)
Base.:/(u::Dual, v::Dual) = u * inv(v)

Base.abs(a::Dual) = Dual(abs(a.x), a.dx * sign(a.x))
Base.exp(a::Dual)  = Dual(exp(a.x), a.dx * exp(a.x))
Base.log(a::Dual)  = Dual(log(a.x), a.dx / a.x)
Base.sqrt(a::Dual) = Dual((a.x), a.dx / (2 *(a.x)))
Base.:^(a::Dual, b::Dual) = exp(b * log(a))

Base.sin(a::Dual)  = Dual(sin(a.x), a.dx * cos(a.x))
Base.cos(a::Dual)  = Dual(cos(a.x), a.dx * -sin(a.x))


autodiff(f, x) = f(Dual(x, one(x))).dx

Base.adjoint(f::Function) = x -> autodiff(f, x)

d(f::Function) = x -> autodiff(f, x)

Base.:^(f::Function, ::Val{0}) = identity
Base.:^(f::Function, ::Val{N}) where N = f^(N - 1) ∘ f
Base.:^(f::Function, n::Integer) = ^(f, Val(n))

# examples of usage
f(x) = 2 * x
g(x) = x^3

(d)(f)(3) # df/dx at 3
(d)(g)(3) # dg/dx at 3
(d^2)(g)(3) # d^2g/dx^2 at 3

# or even
f'(3) # df/dx at 3
g'
(3) # dg/dx at 3
g''(3) # d^2g/dx^2 at 3

Git – Version Control

Git, basically nothing more to say here. The best version control system I have ever seen. I use it for LaTeX projects, letters, code, tutorials. Nevertheless, I usually use it from within and IDE, which directly brings me to the next topic.

VS Code – My IDE and Text Editor

Tested: Atom, KDevelop, Sublime Text, Emacs, Vim, Kate, Code::Blocks, Brackets

Nothing was harder to find for my than a good text editor/IDE for my workflow. After a lot of testing and searching I finally found the solution. VS Code brings everything I need for any type of editing. This main list includes:

  • integrated git
  • integrated terminal
  • integrated julia code execution
  • syntax highlighting
  • LaTeX tools and synced preview
  • spell and grammar checking
  • customizable everything
  • free
  • fast

Be sure to use the unbranded version instead of the proprietary Microsoft branded one.

LaTeX – Markup Language

For everything written I finally ended where I first have started – LuaLaTeX. I was very impressed by pandoc and the possibility to use it to convert to e-book and online formats but at the end of the day nothing than LaTeX was flexible enough to realize my ideas in the way I wanted them. Once you get in touch with LaTeX, you will eventually find yourself writing simple letters with it, not just because you can but more because it will always work and produce high quality results.

Further software

Photo EditorDarkTable and Gimp
Audio EditorArdour
BibliographyZotero with Better BibTeX Plugin
SystemArch Linux with KDE Plasma