In [1]:
for x in ARGS; println(x); end
In [2]:
println("Greetings! 你好! 안녕하세요?")
In [3]:
run(`julia --help`)
In [4]:
理念="idea"
Out[4]:
In [6]:
println("$理念")
In [7]:
π
Out[7]:
From Variables: Stylistic Conventions
While Julia imposes few restrictions on valid names, it has become useful to adopt the following conventions:
'_'
), but use of underscores is discouraged unless the name would be hard to read otherwise.Type
s and Module
s begin with a capital letter and word separation is shown with upper camel case instead of underscores.function
s and macro
s are in lower case, without underscores.!
. These are sometimes called “mutating” or “in-place” functions because they are intended to produce changes in their arguments after the function is called, not just return a value.
In [9]:
WORD_SIZE
Out[9]:
In [10]:
UInt
Out[10]:
In [11]:
typeof(WORD_SIZE)
Out[11]:
In [12]:
typeof(π)
Out[12]:
In [13]:
0b10
Out[13]:
In [14]:
0o10
Out[14]:
In [15]:
for T in [Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128]
println("$(lpad(T,7)): [$(typemin(T)),$(typemax(T))]")
end
In [17]:
typemax(Int64) + 1 == typemin(Int64)
Out[17]:
In [18]:
typemax(UInt64) + 1 == typemin(UInt64)
Out[18]:
In [19]:
div(typemax(Int64), 0)
In [21]:
@printf "%ld" typemin(Int64)
div(typemin(Int64), -1)
In [37]:
0x.1p0 == (1.0/16.0)
Out[37]:
In [43]:
0x.1p1 == (1.0/16.0) * 2^1
Out[43]:
In [44]:
sizeof(0x.1p0)
Out[44]:
In [45]:
1/Inf
Out[45]:
In [46]:
sizeof(Inf)
Out[46]:
In [47]:
0/0
Out[47]:
In [48]:
2 * Inf
Out[48]:
In [49]:
Inf^Inf
Out[49]:
In [51]:
Inf / Inf
Out[51]:
In [52]:
0 * Inf
Out[52]:
In [53]:
(typemin(Float64),typemax(Float64))
Out[53]:
In [56]:
eps(Float32),eps(Float64), eps(Float32) / eps(Float64)
Out[56]:
In [57]:
nextfloat(π)
In [58]:
nextfloat(3.141592653)
Out[58]:
In [59]:
1.1 + 0.1
Out[59]:
In [60]:
with_rounding(Float64,RoundDown) do
1.1 + 0.1
end
Out[60]:
In [61]:
1.1 + 0.1 == with_rounding(Float64,RoundDown) do
1.1 + 0.1
end
Out[61]:
In [1]:
BigInt(typemax(Int64))*BigInt(12345678)
Out[1]:
In [2]:
parse(BigFloat, "1.23456789012345678901")
Out[2]:
In [3]:
BigFloat(π)
Out[3]:
In [7]:
factorial(BigInt(40))
Out[7]:
In [8]:
@doc factorial
Out[8]:
In [9]:
x = 3
Out[9]:
In [10]:
2x^2 - 3x + 1
Out[10]:
In [11]:
1.5x^2 - .5x + 1
Out[11]:
In [12]:
2^2x
Out[12]:
In [13]:
(2^2)x
Out[13]:
In [47]:
print_type_info(T) = begin
const COLUME_WIDTH = 20
# TODO %s can't preserve literal
@printf "%s:\n" T
@printf "\t%s\t%s\n" rpad("zero:",COLUME_WIDTH) zero(T)
@printf "\t%s\t%s\n" rpad("one:",COLUME_WIDTH) one(T)
try
@printf "\t%s\t%s\n" rpad("typemin:",COLUME_WIDTH) typemin(T)
@printf "\t%s\t%s\n" rpad("typemax:",COLUME_WIDTH) typemax(T)
catch e
# do nothing
end
end
for t in [Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128,BigInt]
print_type_info(t)
end
for t in [Float16,Float32,Float64,BigFloat]
print_type_info(t)
end
In [48]:
one(Float32)
Out[48]:
In [50]:
one(Float64)
Out[50]:
In [51]:
1 / 2
Out[51]:
In [52]:
typeof(1 / 2)
Out[52]:
In [53]:
2 \ 1
Out[53]:
In [54]:
100 % 33
Out[54]:
In [58]:
bits(~0b1010101010101010)
Out[58]:
In [59]:
bits(0b11 & 0b10)
Out[59]:
In [60]:
bits(0b11 | 0b10)
Out[60]:
In [63]:
bits(0b1010 $ 0b1100) # xor
Out[63]:
In [65]:
1 >> 2 == 1 >>> 2 # TODO what's the difference?
Out[65]:
In [66]:
isequal(1 >> 2, 1 >>> 2)
Out[66]:
In [67]:
1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
Out[67]:
In [68]:
Float32(π)
Out[68]:
In [69]:
Float64(π)
Out[69]:
In [71]:
cos(1 + 2im) == cos(complex(1, 2))
Out[71]:
In [72]:
complex(Inf, NaN)
Out[72]:
In [73]:
typeof(2//3)
Out[73]:
In [74]:
0.33 < 1//3
Out[74]:
In [75]:
str = "Hello, world.\n"
Out[75]:
In [76]:
str[end]
Out[76]:
In [77]:
str[end÷2]
Out[77]:
In [78]:
str[end÷3]
Out[78]:
In [79]:
str[end÷3:end÷2]
Out[79]:
In [80]:
s = "\u2200 x \u2203 y"
Out[80]:
In [81]:
for i = 1:endof(s)
try
println(s[i])
catch
# ignore the index error
end
end
In [82]:
for c in s
println(c)
end
In [85]:
language="Julia"
"Hello $language\!" == string("Hello ", language, "!")
Out[85]:
In [86]:
"1 + 2 = $(1 + 2)"
Out[86]:
In [88]:
str = """
Hello,
$language.
"""
Out[88]:
In [1]:
last_index = -1
while last_index != 0
last_index = last_index < 0 ? search("xylophone", 'o') : search("xylophone", 'o', last_index + 1)
@printf "%d\n" last_index
end
In [2]:
repeat(".:Z:.", 10)
Out[2]:
In [4]:
join(["apples", "bananas", "pear", "pineapples"], ", ", " and ")
Out[4]:
In [8]:
regex = r"^\s*(?:#|$)"
Out[8]:
In [9]:
ismatch(regex, "not a comment")
Out[9]:
In [10]:
ismatch(regex, "# a comment")
Out[10]:
In [11]:
typeof(regex)
Out[11]:
In [14]:
m = match(r"^\s*(?:#\s*(.*?)\s*$|$)", "# a comment")
Out[14]:
In [15]:
m[1]
Out[15]:
In [16]:
m.match
Out[16]:
In [17]:
m.captures
Out[17]:
In [18]:
m.offsets
Out[18]:
In [27]:
replace("first second third", r"^(\w+) (?P<agroup>\w+)", s"\g<agroup> \1")
Out[27]:
In [28]:
replace("first second third", r"(\w+) (?P<agroup>\w+)$", s"\g<agroup> \1")
Out[28]:
In [29]:
b"DATA\xff\u2200"
Out[29]:
In [31]:
bits('\u2200')
Out[31]:
In [33]:
bits('\xe2\x88\x80')
Out[33]:
In [38]:
function f(x,y)
x + y
end
∑ = f
Out[38]:
In [39]:
f(2, 3) == ∑(2, 3)
Out[39]:
In [40]:
function hypot(x,y)
x = abs(x)
y = abs(y)
if x > y
r = y/x
return x*sqrt(1+r*r)
end
if y == 0
return zero(x)
end
r = x/y
return y*sqrt(1+r*r)
end
Out[40]:
In [41]:
hypot(3, 4)
Out[41]:
In [42]:
+(1,2,3)
Out[42]:
In [43]:
fadd = +
fadd(1, 2, 3)
Out[43]:
In [45]:
[1 2 3]
Out[45]:
In [46]:
[1, 2, 3]
Out[46]:
In [47]:
[1 2; 3 4; 5 6]
Out[47]:
In [48]:
hcat(1, 2, 3) == [1 2 3]
Out[48]:
In [49]:
vcat(1, 2, 3) == [1, 2, 3]
Out[49]:
In [58]:
hvcat( (2, 2, 2) , 1, 2, 3, 4, 5, 6) == [1 2; 3 4; 5 6]
Out[58]:
In [66]:
hvcat(2, 1, 2, 3, 4, 5, 6) == [1 2; 3 4; 5 6]
Out[66]:
In [71]:
mx = [1 2im; 3im 4; 5 6im]
Out[71]:
In [72]:
mx'
Out[72]:
In [73]:
mx.'
Out[73]:
In [75]:
1:100 == colon(1, 100)
Out[75]:
In [76]:
# See Functions: Operators With Special Names
In [77]:
x -> x^2 + 2x - 1
Out[77]:
In [78]:
function (x)
x^2 + 2x - 1
end
Out[78]:
In [79]:
map(x -> x^2 + 2x - 1, [1,3,-1])
Out[79]:
In [80]:
function foo(a,b)
a+b, a*b
end
foo(2, 3)
Out[80]:
In [81]:
bar(a,b,x...) = (a,b,x)
bar(1,2,3,4,5,6)
Out[81]:
In [82]:
baz(a,b) = a + b
args = [1,2]
baz(args...)
Out[82]:
In [86]:
function bonus_add(a, b, c=5)
a + b + c
end
bonus_add(2, 3) == bonus_add(2, 3, 5)
Out[86]:
In [91]:
function extra_add(a; b=3, c=5)
a + b + c
end
extra_add(2, b=4, c=4) == extra_add(0, b=5) == extra_add(2)
Out[91]:
In [95]:
map(x->begin
if x < 0 && iseven(x)
return 0
elseif x == 0
return 1
else
return x
end
end,
[1, 2, 3]) == map([1, 2, 3]) do x # Am I writing ruby? ^_^
if x < 0 && iseven(x)
return 0
elseif x == 0
return 1
else
return x
end
end # The do x syntax creates an anonymous function with argument x and passes it as the first argument
Out[95]:
In [101]:
begin
x = 1
y = 2
x + y
end == (x = 1; y = 2; x + y)
Out[101]:
In [102]:
# Although it is typical, there is no requirement that begin blocks be multiline or that (;) chains be single-line
begin x = 1; y = 2; x + y end == (x = 1;
y = 2;
x + y)
Out[102]:
In [105]:
function test_order(x, y)
if x < y
println("$x is less than $y")
elseif x > y
println("$x is greater than $y")
else
println("$x is equal to $y")
end
end
Out[105]:
In [106]:
test_order(1, 3)
if
blocks are “leaky”, i.e. they do not introduce a local scope. This means that new variables defined inside the ìf
clauses can be used after the if
block, even if they weren’t defined before.
In [107]:
function test_order_leaky(x,y)
if x < y
relation = "less than"
elseif x == y
relation = "equal to"
end
println("$x is ", relation, " $y.")
end
Out[107]:
In [110]:
test_order_leaky(1, 3)
In [111]:
test_order_leaky(11, 3)
In [112]:
5 > 1 && println("5 > 1")
In [113]:
4 < 1 || println("false")
In [114]:
i = 1
while i <= 5
println(i)
i += 1
end
In [116]:
for j=1:5; println(j); end
In [117]:
for s in ["foo","bar","baz"]
println(s)
end
In [119]:
# OH! This is AWESOME!
for i = 1:2, j in ["apple", "banana", "pear"]
println((i, j))
end
In [120]:
positive_exp(x) = x>=0 ? exp(-x) : throw(DomainError())
Out[120]:
In [121]:
positive_exp(1)
Out[121]:
In [122]:
positive_exp(-100)
In [123]:
typeof(DomainError()) <: Exception
Out[123]:
In [125]:
throw(UndefVarError(:a_missing_variable))
In [126]:
fussy_sqrt(x) = x >= 0 ? sqrt(x) : error("negative x not allowed")
Out[126]:
In [127]:
fussy_sqrt(100)
Out[127]:
In [128]:
fussy_sqrt(-250)
In [129]:
function verbose_fussy_sqrt(x)
println("before fussy_sqrt")
r = fussy_sqrt(x)
println("after fussy_sqrt")
return r
end
Out[129]:
In [130]:
verbose_fussy_sqrt(-1)
In [131]:
info("Hi"); 1+1
warn("Hi"); 1+1
error("Hi"); 1+1
In [132]:
try error() end #Returns nothing
In [133]:
try
println("step 1 ok")
error("step 2 failed")
println("step 3 was never reached")
catch e
if isa(e, DomainError)
# Obviously, it's not
else
println(e)
end
finally
println("step 4 is ensured")
end
In [134]:
# https://github.com/transcranial/jupyter-themer
run(`pip install jupyter-themer`)
In [148]:
run(`jupyter-themer -c tomorrow-night-eighties`)
In [149]:
run(`jupyter-themer`)
In [150]:
function producer()
produce("start")
for n=1:4
produce(2n)
end
produce("stop")
end
Out[150]:
In [155]:
p = Task(producer)
Out[155]:
In [156]:
for i=0:6
got = consume(p)
println("$(typeof(got)): $got")
end
In [157]:
for got in Task(producer)
println("$(typeof(got)): $got")
end
In [158]:
p.state
Out[158]:
In [162]:
let
global x = "global"
# a new scope
let
local x = "local_let"
# not a new scope
begin
# not a new scope
if x == "local_let"
println(x)
end
end
let
local x = "local_let_2"
println(x)
end
end
end
x
Out[162]:
for
loops and comprehensions have the following behavior: any new variables introduced in their body scopes are freshly allocated for each loop iteration. This is in contrast to while
loops which reuse the variables for all iterations. Therefore these constructs are similar to while
loops with let
blocks inside
In [163]:
i = 0
for i = 1:3
end
i # here equal to 3
Out[163]:
In [164]:
x = 0
[ x for x=1:3 ]
x # here still equal to 0
Out[164]:
In [3]:
i = 0
j = 3
while j > i
println((i, j))
j -= 1
end
(i, j)
Out[3]:
In [4]:
e
Out[4]:
In [5]:
const K = e * π
Out[5]:
In [6]:
(1+2)::Int
Out[6]:
In [12]:
function foo()
x::Int8 = 100
x
end
Out[12]:
In [13]:
typeof(foo())
Out[13]:
In [20]:
local y::Int8 = 10
Out[20]:
In [21]:
y = 200
Out[21]:
In [22]:
y
Out[22]:
In [23]:
typeof(y)
Out[23]:
In [24]:
local y::Int8=200
abstract Number
abstract Real <: Number
abstract AbstractFloat <: Real
abstract Integer <: Real
abstract Signed <: Integer
abstract Unsigned <: Integer
In [25]:
Integer <: Number
Out[25]:
In [26]:
Integer <: AbstractFloat
Out[26]:
In [27]:
bitstype 7 sevenbit
In [28]:
bitstype 128 onetwoeightbits
In [29]:
bitstype 128 ∰
In [30]:
sizeof(∰)
Out[30]:
In [32]:
type footype
bar
baz::Int
qux::Float64
end
In [36]:
ft = footype("bar", 8, 12.9)
Out[36]:
In [37]:
footype("bar", 8, 12)
Out[37]:
In [38]:
footype("bar", 8, "12.9")
In [39]:
typeof(ft)
Out[39]:
In [40]:
fieldnames(ft)
Out[40]:
In [41]:
fieldnames(footype)
Out[41]:
In [42]:
ft.bar = 1//2
Out[42]:
Composite types with no fields are singletons; there can be only one instance of such types:
In [43]:
type NoFields
end
In [44]:
is(NoFields(), NoFields())
Out[44]:
In [45]:
immutable MyComplex
real::Float64
imag::Float64
end
In [46]:
c = MyComplex(12, 34)
Out[46]:
In [47]:
c.real
Out[47]:
In [48]:
c.real = 13
In [49]:
IntOrString = Union{Int,AbstractString}
Out[49]:
In [50]:
1 :: IntOrString
Out[50]:
In [51]:
"1" :: IntOrString
Out[51]:
In [52]:
1.0 :: IntOrString
In [53]:
type MyPoint{T}
x::T
y::T
end
In [54]:
mp = MyPoint(1, 2)
Out[54]:
In [55]:
mp = MyPoint(1, "2")
In [57]:
MyPoint{Float64} <: MyPoint
Out[57]:
In [58]:
Float64 <: Real
Out[58]:
In [59]:
MyPoint{Float64} <: MyPoint{Real}
Out[59]:
In [60]:
abstract Pointly{T}
In [61]:
Pointly{Int} <: Pointly
Out[61]:
In [63]:
type SpecificPoint{T} <: Pointly{T}
x::T
y::T
end
In [65]:
SpecificPoint{AbstractString} <: Pointly
Out[65]:
In [66]:
SpecificPoint("a", "b")
Out[66]:
In [67]:
abstract RealPoint{T<:Real}
In [72]:
RealPoint{Float32} <: RealPoint
Out[72]:
In [73]:
Tuple{Int,AbstractString} <: Tuple{Real,Any}
Out[73]:
In [74]:
Tuple{Int,AbstractString} <: Tuple{Real,}
Out[74]:
In [77]:
(1.0, 1.0) :: Tuple{Vararg{Real}}
Out[77]:
In [78]:
isa(("1",1,2), Tuple{AbstractString,Vararg{Int}})
Out[78]:
In [79]:
isa(("1",1,2,3.0), Tuple{AbstractString,Vararg{Int}})
Out[79]:
In [81]:
isa(Float64, Type{Float64})
Out[81]:
In [82]:
isa(Float64, Type{Real})
Out[82]:
In [83]:
bitstype 64 MyPtr{T}
In [84]:
MyPtr{Float64} <: MyPtr{Real}
Out[84]:
In [85]:
MyPtr{Float64} <: MyPtr
Out[85]:
In [86]:
MyPtr{onetwoeightbits}
Out[86]:
In [88]:
typealias MyAliasPtr MyPtr
Out[88]:
In [89]:
MyAliasPtr <: MyPtr
Out[89]:
In [90]:
MyPtr <: MyPtr
Out[90]:
In [91]:
Array{Float64,1} <: Array{Float64} <: Array
Out[91]:
In [92]:
typealias MyVector{T} Array{T,1}
typealias MyMatrix{T} Array{T,2}
Out[92]:
In [93]:
super(Float64)
Out[93]:
In [94]:
super(ans)
Out[94]:
In [95]:
super(ans)
Out[95]:
In [96]:
super(ans)
Out[96]:
In [97]:
function firstlast(b::Bool)
return b ? "First" : "Last"
end
println(firstlast(true))
In [98]:
firstlast(::Type{Val{true}}) = "First"
firstlast(::Type{Val{false}}) = "Last"
Out[98]:
In [99]:
@doc firstlast
Out[99]:
In [106]:
firstlast(Val{true})
Out[106]:
In [107]:
firstlast(::Type{Val{3}}) = "3"
Out[107]:
In [108]:
firstlast(Val{3})
Out[108]:
In [109]:
firstlast(3)
In [110]:
isnull(3)
In [111]:
isnull(Nullable(3))
Out[111]:
In [112]:
get(Nullable{Float64}())
In [113]:
methods(display)
Out[113]:
In [115]:
optional_function(a=1, b=2) = a + b
Out[115]:
In [116]:
methods(optional_function)
Out[116]:
In [119]:
println("abc\ufff9abc\ufffbabc")
In [122]:
println("abc\ufffaabc\ufffbabc")
In [123]:
println("\u202eABCDE\u202dXYZ")
In [124]:
println("大字\u200d小字")
In [125]:
Base.call(x::Number, arg) = x * arg
Out[125]:
In [126]:
a_number=10
Out[126]:
In [127]:
10(20)
Out[127]:
In [128]:
function emptyfunc
end
Out[128]:
In [1]:
type OrderedPair
x::Real
y::Real
OrderedPair(x,y) = x > y ? error("out of order") : new(x,y)
end
In [2]:
OrderedPair(1, 2)
Out[2]:
In [3]:
OrderedPair(2, 1)
In [4]:
type Foo
bar
baz
Foo(bar,baz) = new(bar,baz)
end
In [1]:
type SelfReferential
obj::SelfReferential
end
In [2]:
type BetterSelfReferential
obj::BetterSelfReferential
BetterSelfReferential() = (x = new(); x.obj = x)
end
In [4]:
sr = SelfReferential()
In [5]:
bsr = BetterSelfReferential()
Out[5]:
In [6]:
is(bsr, bsr.obj.obj)
Out[6]:
In some cases you could consider adding methods to Base.convert instead of defining a constructor, because defining a convert() method automatically defines a corresponding constructor, while the reverse is not true. That is, defining Base.convert(::Type{T}, args...) = ... automatically defines a constructor T(args...) = ....
In [7]:
type SummedArray{T<:Number,S<:Number}
data::Vector{T}
sum::S
function call{T}(::Type{SummedArray}, a::Vector{T})
S = widen(T)
new{T,S}(a, sum(S, a))
end
end
In [11]:
sa = SummedArray(Vector{Int32}([1, 2, 3]))
Out[11]:
In [12]:
sa.sum
Out[12]:
promote_rule(::Type{UInt8}, ::Type{Int8}) = Int
promote_rule(::Type{BigInt}, ::Type{Int8}) = BigInt
In [13]:
promote_type(Int8, UInt16)
Out[13]:
promote_rule{T<:Integer}(::Type{Rational{T}}, ::Type{T}) = Rational{T}
promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, ::Type{S}) = Rational{promote_type(T,S)}
promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, ::Type{Rational{S}}) = Rational{promote_type(T,S)}
promote_rule{T<:Integer,S<:AbstractFloat}(::Type{Rational{T}}, ::Type{S}) = promote_type(T,S)
In [14]:
immutable Squares
count::Int
end
Base.start(::Squares) = 1
Base.next(S::Squares, state) = (state*state, state+1)
Base.done(S::Squares, s) = s > S.count;
Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type
Base.length(S::Squares) = S.count;
In [15]:
for i in Squares(7)
println(i)
end
In [16]:
length(Squares(100)) == 100
Out[16]:
In [17]:
25 in Squares(10)
Out[17]:
In [18]:
mean(Squares(100)), std(Squares(100))
Out[18]:
In [19]:
collect(Squares(100))'
Out[19]:
In [21]:
Base.sum(S::Squares) = (n = S.count; return n*(n+1)*(2n+1)÷6)
sum(Squares(1803))
Out[21]:
In [23]:
1 + 2 | 3 == (1 + 2) | 3
Out[23]:
In [24]:
1 .* 2
Out[24]:
module MyModule
using Lib
using BigLib: thing1, thing2
import Base.show
importall OtherLib
export MyType, foo
type MyType
x
end
bar(x) = 2x
foo(a::MyType) = bar(a.x) + 1
show(io, a::MyType) = print(io, "MyType $(a.x)")
end
module Parent
module Utils
...
end
using .Utils
...
end
In [25]:
?@time
Out[25]:
In [35]:
@time collect(Squares(300000000))'
Out[35]:
to re-use documentation between different versions of a function:
@doc "..." foo!
@doc (@doc foo!) foo
In [36]:
foo = (x) -> 0
Out[36]:
In [37]:
@doc "fooing" foo
In [38]:
@doc foo
Out[38]:
In [39]:
"`abc` is just _ABC_ as we know"
abc = "abc"
Out[39]:
In [40]:
@doc abc
Out[40]:
In [1]:
intarray = Array(Int64, 100)
Out[1]:
In [2]:
intarray = zeros(Int64, 100)
Out[2]:
In [3]:
eltype(intarray)
Out[3]:
In [4]:
length(intarray)
Out[4]:
In [5]:
ndims(intarray)
Out[5]:
In [6]:
size(intarray)
Out[6]:
In [7]:
strides(intarray)
Out[7]:
In [8]:
@doc strides
Out[8]:
In [10]:
array = cell((3, 3))
Out[10]:
In [11]:
m = zeros((3, 3))
Out[11]:
In [12]:
size(m)
Out[12]:
In [13]:
size(m, 2)
Out[13]:
In [14]:
strides(m)
Out[14]:
In [15]:
rand(3)
Out[15]:
In [17]:
randn(3)
Out[17]:
In [18]:
@doc eye
Out[18]:
In [19]:
ey = eye(3, 2)
Out[19]:
In [20]:
fm = fill(3, (3, 3))
Out[20]:
In [21]:
a, b, c, d, e, f = 1, 2, 3, 4, 5, 6
[a b c; d e f]
Out[21]:
In [22]:
hvcat((3,3), a,b,c,d,e,f)
Out[22]:
In [23]:
[a b;c d; e f]
Out[23]:
In [24]:
hvcat((2,2,2), a,b,c,d,e,f)
Out[24]:
In [25]:
@doc hvcat
Out[25]:
The general syntax for indexing into an n-dimensional array A is:
X = A[I_1, I_2, ..., I_n]
where each I_k
may be:
Range
of the form a:b
, or a:b:c
:
or Colon()
to select entire dimensions[]
The result X
generally has dimensions
(length(I_1), length(I_2), ..., length(I_n))
, with location
(i_1, i_2, ..., i_n)
of X
containing the value
A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]
. Trailing dimensions
indexed with scalars are dropped. For example, the dimensions of A[I, 1]
will be
(length(I),)
. Boolean vectors are first transformed with find
; the size of
a dimension indexed by a boolean vector will be the number of true values in the vector.
As a special part of this syntax, the end
keyword may be used to represent the last
index of each dimension within the indexing brackets, as determined by the size of the
innermost array being indexed.
Alternatively, single elements of a multidimensional array can be indexed as
x = A[I]
where I
is a CartesianIndex
, effectively an n
-tuple of integers.
See Iteration below.
Indexing syntax is equivalent to a call to getindex
:
X = getindex(A, I_1, I_2, ..., I_n)
Example:
julia> x = reshape(1:16, 4, 4)
4x4 Array{Int64,2}:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
julia> x[2:3, 2:end-1]
2x2 Array{Int64,2}:
6 10
7 11
Empty ranges of the form n:n-1
are sometimes used to indicate the inter-index
location between n-1
and n
. For example, the searchsorted()
function uses
this convention to indicate the insertion point of a value not found in a sorted
array:
julia> a = [1,2,5,6,7];
julia> searchsorted(a, 3)
3:2
In [26]:
x = reshape(1:16, 4, 4)
Out[26]:
In [27]:
x[2:3, 2:end-1]
Out[27]:
In [28]:
3:2
Out[28]:
In [29]:
typeof(3:2)
Out[29]:
In [30]:
typeof(1:50)
Out[30]:
In [31]:
A = rand(4,3)
B = sub(A, 1:3, 2:3)
(A, B)
Out[31]:
In [32]:
square(x) = x^2
@vectorize_1arg Number square
Out[32]:
In [33]:
methods(square)
Out[33]:
In [34]:
square(A)
Out[34]:
In [35]:
a = rand(2,1); A = rand(2,3);
(a, A)
Out[35]:
In [36]:
broadcast(+, a, A)
Out[36]:
In [37]:
b = rand(1,2)
broadcast(+, a, b)
Out[37]:
In [38]:
spzeros(3,5)
Out[38]:
In [39]:
speye(3,5)
Out[39]:
In [40]:
I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];
S = sparse(I,J,V)
Out[40]:
In [41]:
findn(S)
Out[41]:
In [42]:
findnz(S)
Out[42]:
In [44]:
@doc findn
Out[44]:
In [45]:
@doc findnz
Out[45]:
In [46]:
sparse(eye(5))
Out[46]:
In [47]:
issparse(speye(5))
Out[47]:
In [48]:
full(S)
Out[48]:
Matrix factorizations (a.k.a. matrix decompositions) compute the factorization of a matrix into a product of matrices, and are one of the central concepts in linear algebra.
The following table summarizes the types of matrix factorizations that have been implemented in Julia. Details of their associated methods can be found in the Linear Algebra section of the standard library documentation.
Cholesky |
Cholesky factorization |
CholeskyPivoted |
Pivoted Cholesky factorization |
LU |
LU factorization |
LUTridiagonal |
LU factorization for Tridiagonal matrices |
UmfpackLU |
LU factorization for sparse matrices (computed by UMFPack) |
QR |
QR factorization |
QRCompactWY |
Compact WY form of the QR factorization |
QRPivoted |
Pivoted QR factorization |
Hessenberg |
Hessenberg decomposition |
Eigen |
Spectral decomposition |
SVD |
Singular value decomposition |
GeneralizedSVD |
Generalized SVD |
Matrices with special symmetries and structures arise often in linear algebra and are frequently associated with various matrix factorizations. Julia features a rich collection of special matrix types, which allow for fast computation with specialized routines that are specially developed for particular matrix types.
The following tables summarize the types of special matrices that have been implemented in Julia, as well as whether hooks to various optimized methods for them in LAPACK are available.
Hermitian |
Hermitian matrix |
UpperTriangular |
Upper triangular matrix |
LowerTriangular |
Lower triangular matrix |
Tridiagonal |
Tridiagonal matrix |
SymTridiagonal |
Symmetric tridiagonal matrix |
Bidiagonal |
Upper/lower bidiagonal matrix |
Diagonal |
Diagonal matrix |
UniformScaling |
Uniform scaling operator |
Matrix type | + |
- |
* |
\ |
Other functions with optimized methods |
---|---|---|---|---|---|
Hermitian |
MV | inv() ,
sqrtm() , expm() |
|||
UpperTriangular |
MV | MV | inv() , det() |
||
LowerTriangular |
MV | MV | inv() , det() |
||
SymTridiagonal |
M | M | MS | MV | eigmax() , eigmin() |
Tridiagonal |
M | M | MS | MV | |
Bidiagonal |
M | M | MS | MV | |
Diagonal |
M | M | MV | MV | inv() , det() ,
logdet() , /() |
UniformScaling |
M | M | MVS | MVS | /() |
Legend:
M (matrix) | An optimized method for matrix-matrix operations is available |
V (vector) | An optimized method for matrix-vector operations is available |
S (scalar) | An optimized method for matrix-scalar operations is available |
Matrix type | LAPACK | eig() |
eigvals() |
eigvecs() |
svd() |
svdvals() |
---|---|---|---|---|---|---|
Hermitian |
HE | ARI | ||||
UpperTriangular |
TR | A | A | A | ||
LowerTriangular |
TR | A | A | A | ||
SymTridiagonal |
ST | A | ARI | AV | ||
Tridiagonal |
GT | |||||
Bidiagonal |
BD | A | A | |||
Diagonal |
DI | A |
Legend:
A (all) | An optimized method to find all the characteristic values and/or vectors is available | e.g. eigvals(M) |
R (range) | An optimized method to find the il th through the ih th characteristic values are available |
eigvals(M, il, ih) |
I (interval) | An optimized method to find the characteristic values in the interval [vl , vh ] is available |
eigvals(M, vl, vh) |
V (vectors) | An optimized method to find the characteristic vectors corresponding to the characteristic values x=[x1, x2,...] is available |
eigvecs(M, x) |
A UniformScaling
operator represents a scalar times the identity operator, λ*I
. The identity operator I
is defined as a constant and is an instance of UniformScaling
. The size of these operators are generic and match the other matrix in the binary operations +
, -
, *
and \
. For A+I
and A-I
this means that A
must be square. Multiplication with the identity operator I
is a noop (except for checking that the scaling factor is one) and therefore almost without overhead.
In [49]:
I
Out[49]:
In [50]:
write(STDOUT,"Hello World")
Out[50]:
In [ ]:
read(STDIN,Char)
In [ ]:
a
In [1]:
write(STDOUT,0x61)
Out[1]:
In [2]:
print(STDOUT,0x61)
In [4]:
open("hello.txt", "w") do f
write(f, "Hello")
end
Out[4]:
In [6]:
open("hello.txt", "r") do f
uppercase(readall(f))
end
Out[6]:
In [7]:
running = true
Out[7]:
In [8]:
@async begin
server = listen(2000)
while running
sock = accept(server)
println("Hello World\n")
end
end
Out[8]:
In [9]:
connect(2000)
Out[9]:
In [10]:
running = false
Out[10]:
In [11]:
connect(2000)
Out[11]:
In [12]:
connect(2000)
Out[12]:
In [1]:
listen(ip"127.0.0.1",2000)
Out[1]:
In [2]:
@async begin
server = listen(2001)
while true
sock = accept(server)
@async while isopen(sock)
write(sock,readline(sock))
end
end
end
Out[2]:
In [3]:
clientside=connect(2001)
Out[3]:
In [4]:
@async while true
write(STDOUT,readline(clientside))
end
Out[4]:
In [5]:
println(clientside,"Hello World from the Echo Server")
In [6]:
close(clientside)
In [7]:
clientside=connect(2001)
Out[7]:
In [8]:
close(clientside)
In [9]:
getaddrinfo("github.com")
Out[9]:
In [10]:
r = remotecall(2, rand, 2, 2)
In [11]:
@doc remotecall
Out[11]:
In [12]:
r = remotecall(1, rand, 2, 2)
Out[12]:
In [13]:
fetch(r)
Out[13]:
In [15]:
s = @spawnat 1 1 .+ fetch(r)
Out[15]:
In [16]:
fetch(s)
Out[16]:
In [17]:
remotecall_fetch(1, getindex, r, 1, 1)
Out[17]:
In [18]:
@doc @everywhere
Out[18]:
A file can also be preloaded on multiple processes at startup, and a driver script can be used to drive the computation:
julia -p <n> -L file1.jl -L file2.jl driver.jl
Functions addprocs(), rmprocs(), workers(), and others are available as a programmatic means of adding, removing and querying the processes in a cluster.
In [19]:
@doc addprocs
Out[19]:
In [20]:
addprocs(CPU_CORES)
Out[20]:
In [21]:
@doc rmprocs
Out[21]:
In [22]:
rmprocs(2:5)
Out[22]:
In [23]:
@doc workers
Out[23]:
In [24]:
workers()
Out[24]:
In [25]:
addprocs(1)
Out[25]:
In [27]:
A = rand(1000,1000)
Bref = @spawn A^2
fetch(Bref)
Out[27]:
In [28]:
Bref = @spawn rand(1000,1000)^2
fetch(Bref)
Out[28]:
In [29]:
@everywhere function count_heads(n)
c::Int = 0
for i=1:n
c += rand(Bool)
end
c
end
In [30]:
a = @spawn count_heads(100000000)
b = @spawn count_heads(100000000)
fetch(a)+fetch(b)
Out[30]:
In [31]:
nheads = @parallel (+) for i=1:200000000
Int(rand(Bool))
end
Out[31]:
Using “outside” variables in parallel loops is perfectly reasonable if the variables are read-only:
In [33]:
a = randn(1000)
f = (x) -> x + 1
@parallel (+) for i=1:100000
f(a[rand(1:end)])
end
Out[33]:
In [34]:
M = Matrix{Float64}[rand(1000,1000) for i=1:10]
pmap(svd, M)
Out[34]:
In [35]:
@doc pmap
Out[35]:
In [36]:
@doc svd
Out[36]:
In [ ]: