To run Julia without a local installation, use (for instance) CoCalc.
To install Julia (plus an editor and key packages) on your machine, download and install JuliaPro.
Alternatively, download Julia and install. You may also want to use the Atom editor with the Juno IDE. To run IJulia with either jupyter or nteract from your local installation, see IJulia for instructions.
? cos to get help with the cos function This cell is a "Markdown" cell. This is meant for comments and documentation, not computations.
You can change a cell to "Code" or "Markdown" in the menu.
Markdown cells can handle LaTeX. An example: $\alpha = \beta/2$. A Markdown cell can also contain some formatting, like lists of this kind
To insert a new cell, use the menu.
The next cell is "Code". You can run it. Text after a # sign is treated as a comment.
The subsequent cell shows how to get help on a command.
In [1]:
a = 2 #this is a comment
#run this cell by using the menu, or by Shift+Enter
Out[1]:
In [2]:
? cos #to get help on the cos() function
Out[2]:
There are many packages for Julia, for instance, for plotting or statistical methods (see http://pkg.julialang.org/ for a list). To install a package, you do either
(works everywhere) run import Pkg and then Pkg.add("Packagename")
(works in the Julia console, REPL) enter the "package manager mode" by typing ], then run add PackageName. You leave the package manager mode by ctrl-c or backspace.
Once a package is installed, you can use it by running
using PackageName
In [3]:
using Dates
include("printmat.jl") #just a function for prettier matrix printing
Out[3]:
In [4]:
using Plots #this loads the Plots package
#pyplot(size=(600,400)) #choice of plotting backend
gr(size=(480,320))
default(fmt = :svg) #try :png or :svg
In [5]:
q = 1 #create a scalar
Q = [ 1 2 3; #create 2x3 matrix
4 5 6 ]
println("q is a scalar. To print, use println() or printlnPs()")
println(q)
println("\nQ is a matrix. To print, use display() or printmat()")
printmat(Q) #case sensitive (q and Q are different)
#the \n adds a line break
In [6]:
println("\n","element [1,2] of Q: ", #commands continue on
Q[1,2]) #the next line (until finished)
println("\ncolumns 2 and 3 of Q: ")
printmat(Q[:,2:3])
println("\nline 1 of Q (as a vector): ")
printmat(Q[1,:])
The syntax for linear algebra is similar to the standard text book approach. For instance,
Q'Q (or Q'*Q) multiplies the transpose ($Q'$) with the matrix ($Q$)A*B does matrix multiplication100*Q multiplies each element of the matrix ($Q$) by 100However, to add a scalar to each element of a matrix, use 100 .+ Q. Notice the dot.
In [7]:
println("transpose of Q:")
printmat(Q')
println("Q'Q:")
printmat(Q'Q)
println("scalar * matrix:")
printmat(100*Q)
println("scalar .+ matrix:") #notice the dot
printmat(100 .+ Q)
In [8]:
θ = 1:10:21 #a sequence (range), type \theta + TAB to get this symbol
println("\n","θ is a sequence: ",θ)
ρ = collect(θ) #make the sequence into a vector, \rho+TAB
println("\n","ρ is a vector: ")
printmat(ρ)
In [9]:
x = [-1.5,-1.0,-0.5,0,0.5] #this is a vector
println("x values: ")
printmat(x)
vv = -1 .< x .<= 0 #true for x values (-1,0], vv is a vector
println("true if x is in (-1,0]: ")
printmat(vv)
x2 = x[vv] #x values for which vv==true
println("x values that are in (-1,0]: ")
printmat(x2)
In [10]:
x = [-1.5,-1.0,-0.5,0,0.5] #this is a vector
println("x values: ")
printmat(x)
v1 = findfirst(x.==0)
println("(first) index v in x such x[v]==0: ",v1)
v2 = findall(x.>=0)
println("\nall indices v in x such x[v]>=0: ")
printmat(v2)
y = [-1.0,0]
v3 = indexin(y,x)
println("\nindices in x so that x[v] equals the vector y=$y: ")
printmat(v3)
In [11]:
z = 1.05
if 1 <= z <= 2 #(a) if true, run the next command (y=z) and then jump to end
y = z
elseif z < 1 #(b) if (a) is false, try this instead
y = 1
else #(c) if also (b) is false, do this
y = 2
end
println(y)
The are two types of loops: "for loops" and "while loops".
The for loop is best when you know how many times you want to loop (for instance, over all $m$ rows in a matrix).
The while loop is best when you want to keep looping until something happens, for instance, that $x_0$ and $x_1$ get really close.
The default behaviour in IJulia and inside functions is that assignments of x inside the loop overwrites x defined before the loop. To get the same behavior in the REPL (for instance, when you do include("myscript.jl") at the Julia prompt), you need to add global x somewhere inside the loop.
To make sure that the y calculated inside the loop does not affect y outside the loop, add local y.
A variable (here z2) that does not exist before the loop is local to the loop.
In [12]:
x = 0
y = -999
for i = 3:3:9 #first i=3, then i=6, and last i=9, try also i=1:9
#global x #only needed in REPL/scripts
local y #don't overwrite y outside loop
x = x + i #adding i to the "old" x
y = i
z2 = -998 #notice: z2 has not been used before
println("i=$i, x=$x and z2=$z2") #$x prints the value of x
end
println("\nAfter loop: x=$x and y=$y")
#println(z2) #does not work: z2 is local to the loop
In [13]:
(m,n) = (4,3) #same as m=4;n=3
x = fill(-999,(m,n)) #to put results in, initialized as -999
for i = 1:m, j = 1:n
x[i,j] = 10*i + j
end
println("new x matrix: \n")
printmat(x)
The "while loop" in the next cell iterates until two variables ($x_0$ and $x_1$) get close.
The background to the example is that we want to solve a function $f(x)=x^2$ for the $x$ value that makes $f(x)=2$. The Newton-Raphson algorithm starts with a value $x_0$ and updates it to $ x_1 = x_0 + (2-f(x_0))/f'(x_0) $ where $f'(x_0)$ is the derivative of $f()$ evaluated at $x_0$. The algorithm iterates until $x_0$ and $x_1$ are close. Clearly, we are trying to find the square root of 2.
In [14]:
println("Solving x^2 = 2 with Newton-Raphson:\n")
x₀ = Inf #x\_0 + TAB
x₁ = 10
while abs(x₁-x₀) > 0.001 #keep going until they get similar
#global x₀, x₁ #only needed in REPL/script
local y, dy #don't overwrite any y,dy outside loop
x₀ = x₁ #initial guess is taken from old guess
y = x₀^2 #value of function
dy = 2*x₀ #derivative of function
x₁ = x₀ + (2 - y)/dy #updating the guess, Newton-Raphson
printlnPs(x₀," is changed to ",x₁)
end
printlnPs("\nThe result x₁=$x₁ should be close to ",sqrt(2))
The next cell defines a new function, fn1(). It takes a scalar input (x) and returns a scalar output (y).
If you instead use a vector as the input, then the computation fails. (The reason is that you cannot do x^2 on a vector. You could on a square matrix, though.)
However, using the "dot" syntax
y = fn1.(x)
gives an array as output where element y[i,j] = fn1(x[i,j]).
In [15]:
function fn1(x) #define a new function
y = (x-1.1)^2 - 0.5
return y
end
Out[15]:
In [16]:
y = fn1(1.5)
printlnPs("result from fn1(1.5): ",y)
x = [1;1.5]
#y = fn1(x) #would give an error
y = fn1.(x) #calling on the function, dot. to do for each element in x
printlnPs("\nresult from fn1.(x): ")
printmat(y)
In [17]:
x = -3:6/99:6
plot( [x x],[fn1.(x) cos.(x)],
linecolor = [:red :blue],
linestyle = [:solid :dash],
linewidth = [2 1],
label = ["fn1()" "cos"],
title = "My Results",
xlabel = "x",
ylabel = "my output value" )
Out[17]:
Julia has many different types of variables: signed integers (like 2 or -5), floating point numbers (2.0 and -5.1), bools (false/true), bitarrays (similar to bools, but with more efficient use of memory), strings ("hello"), Dates (2017-04-23) and many more types.
In [18]:
a = 2 #integer, Int (Int64 on most machines)
b = 2.0 #floating point, (Float64 on most machines)
A = [1,2]
B = [1.0,2.0]
println("Finding the type of a, b, A and B:")
println(typeof(a)," ",typeof(b)," ",typeof(A)," ",typeof(B))
In [19]:
c = 2 > 1.1
C = A .> 1.5 #A is an array, so C is too
println("Finding the type of c and C:")
println(typeof(c)," ",typeof(C))
A calculation like "integer" + "float" works and the type of the result will be a float (the more flexible type). Similarly, "bool" + "integer" will give an integer. These promotion rules make it easy to have mixed types in calculations, and also provide a simple way of converting a variable from one type to another. (There are also an explicit convert() function that might be quicker.)
In [20]:
println(1+2.0) #integer + Float
println((1>0) + 2) #bool + integer
In [21]:
x1 = 1:10
x2 = "And Ezra Pound and T.S. Eliot fighting in the captain's tower..."
x3 = rand(4,3)
x = [x1,x2,x3]
println("x[2] is: ",x[2])
In [ ]: