I would like to create a n x m-dimension Matrix of k x k-dimension Matrices (containing zeros).
How can I do that in Julia?
n-d comprehensions are probably easiest:
[zeros(k,k) for i=1:n, j=1:m]
Update: You need to be careful here: presumably you want to fill the array with different matrices of zeros: the other proposed solutions (fill or repmat) will actually give you an array where all the entries are the same zeros matrix, e.g.:
julia> k = 2; n = 3; m = 4; A = fill(zeros(k, k), n, m)
3×4 Array{Array{Float64,2},2}:
[0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0]
[0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0]
[0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0]
julia> A[1,1][1,1] = 1; A
3×4 Array{Array{Float64,2},2}:
[1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0]
[1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0]
[1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0] [1.0 0.0; 0.0 0.0]
I also use something like this
fill(zeros(k, k), n, m)
Yet-Another-Answer, to complement the already beautiful ones above.
repmat([zeros(k,k)], n,m)
(or its more syntactically flexible cousin repeat([zeros(k,k)], outer=(n,m)))
EDIT: This seems to be the fastest method by far
I will put benchmarks below:
BENCHMARKS:
(from fastest to slowest)
k = 2; n = 3; m = 4
julia> #time for i in 1:10e4; A = repmat([zeros(k,k)], n,m); end
0.601392 seconds (2.80 M allocations: 112.915 MB, 1.49% gc time)
julia> #time for i in 1:10e4; A = fill(zeros(k,k), n,m); end
1.053698 seconds (200.00 k allocations: 27.466 MB, 0.13% gc time)
julia> #time for i in 1:10e4; A = repeat([zeros(k,k)], outer=(n,m)); end
1.217569 seconds (6.10 M allocations: 222.778 MB, 1.97% gc time)
julia> #time for i in 1:10e4; A = [zeros(k,k) for i=1:n, j=1:m]; end
8.217551 seconds (2.83 M allocations: 214.951 MB, 0.19% gc time)
Related
a= zeros(4,4)
Print a like this
> 4×4 Array{Float64,2}:
> 0.0 0.0 0.0 0.0
> 0.0 0.0 0.0 0.0
> 0.0 0.0 0.0 0.0
> 0.0 0.0 0.0 0.0
but println(a) prints like this
[0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0]
How can I "print" a in the former way within a function? I want it fo debugging purposes.
Use display(x).
Let me comment here on what is going on here. A key difference is between show(io, x) and show(io, mime, x), as you can see in the docs:
help?> show(stdout, a)
show([io::IO = stdout], x)
Write a text representation of a value x to the output stream io. New types T
should overload show(io::IO, x::T). The representation used by show generally
includes Julia-specific formatting and type information, and should be
parseable Julia code when possible.
repr returns the output of show as a string.
To customize human-readable text output for objects of type T, define
show(io::IO, ::MIME"text/plain", ::T) instead. Checking the :compact IOContext
property of io in such methods is recommended, since some containers show their
elements by calling this method with :compact => true.
So:
show without MIME writes a text representation of an object,
show with MIME tries to produce a human-readable format.
Now print(io, x) fallsback to show(io, x) as you can see here:
function print(io::IO, x)
lock(io)
try
show(io, x)
finally
unlock(io)
end
return nothing
end
and display by default in REPL falls back to show(io, mime, a):
function display(d::REPLDisplay, mime::MIME"text/plain", x)
io = outstream(d.repl)
get(io, :color, false) && write(io, answer_color(d.repl))
if isdefined(d.repl, :options) && isdefined(d.repl.options, :iocontext)
# this can override the :limit property set initially
io = foldl(IOContext, d.repl.options.iocontext,
init=IOContext(io, :limit => true, :module => Main))
end
show(io, mime, x)
println(io)
nothing
end
(in both cases I have copied definitions from the Base, that you end up getting using default print(a) and display(a) operations - skipping methods that are called in the process)
You can find more information about it here in the Julia manual.
So in your case - as Jun Tian suggested you can use display. Also just to show that this all falls back to show:
julia> a = zeros(4,4);
julia> show(stdout, a)
[0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0]
julia> show(stdout, "text/plain", a)
4×4 Array{Float64,2}:
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
Sometimes you want to save that line showing the size and type. Hence, another option worth noting is DelimitedFiles:
julia> a= zeros(4,4);
julia> using DelimitedFiles; writedlm(stdout, a)
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
in C(++) I can do in a header file myFLOAT.h
typedef myFLOAT double;
// typedef myFLOAT BigFloat; // with the correct lib
Then I can write code based on the type myFLOAT
and switch very easily for the code between double and BigFloat
by just uncomment/comment the corresponding line
in the header file.
How do I do the same in Julia?
I tried
abstract type myFLOAT <: Float64 end
#abstract type myFLOAT <: BigFloat end
but I get
ERROR: invalid subtyping in definition of myFLOAT
I add the following comment after the answer from #clbieganek
My simulation code generally looks like
init = initSimulation(args);
result = doSimulation(init);
Plotting(result);
I agree that I can/should use AbstractFloat "everywhere" in doSimulation().
But with
const myFLOAT = Float64 # thanks
I want to guarantee that every myFLOAT in 'struct init' is a Float64 or BigFloat depending on the use case. This way 'doSimulation(init)' will choose
the correct Float type.
In Julia, concrete types cannot be sub-typed. Float64 and BigFloat are both concrete types, which is why you are getting the invalid sub-typing error. The direct translation of what you are trying to do is to create a type alias:
const MyType = Float64
However, the Julian approach is to define your types and methods using the most generic types possible. In your case, you could use AbstractFloat. Then your code will work with both Float64 and BigFloat. For example,
julia> struct A
x::AbstractFloat
end
julia> function foo(a::A, x::AbstractFloat)
return a.x + x
end
foo (generic function with 1 method)
julia> a1 = A(4.5)
A(4.5)
julia> foo(a1, 5.2)
9.7
julia> a2 = A(BigFloat(4.5))
A(4.5)
julia> foo(a2, BigFloat(5.2))
9.70000000000000017763568394002504646778106689453125
The Julia type hierarchy for numbers can be viewed here.
You can use the where syntax for the functions, and use syntax like T, then, for either:
julia> function f(a::T) where T <: Number
ret = zeros(T, 5, 5)
ret
end
f (generic function with 1 method)
julia> x = 1.0
1.0
julia> f(x)
5×5 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
julia> y = BigFloat(1.0)
1.0
julia> f(y)
5×5 Array{BigFloat,2}:
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
julia>
I have a xy-grid with two vector fields u and v. I represent vector fields as Array{Float64, 3} with dimensions nx × ny × 2.
I would like to have dot product u.v as a scalar field (Array{Float64,2} with dimensions nx×ny). What is the best way to achieve that?
It would be perfect to have something like dot(u,v,3), where 3 is the dimension over which the dot product is taken.
nx, ny = 3, 4
u = Array{Float64,3}(rand(0:1, nx, ny, 2))
#[0.0 1.0 0.0 1.0; 1.0 0.0 1.0 0.0; 1.0 0.0 1.0 0.0]
#[1.0 0.0 1.0 0.0; 1.0 0.0 0.0 1.0; 1.0 0.0 1.0 1.0]
v = Array{Float64,3}(rand(0:1, nx, ny, 2))
#[1.0 1.0 1.0 1.0; 0.0 1.0 0.0 0.0; 0.0 1.0 1.0 0.0]
#[1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 1.0 1.0 1.0 0.0]
[dot(u[i,j,:], v[i,j,:]) for i in 1:nx, j in 1:ny]
3×4 Array{Float64,2}:
1.0 1.0 0.0 1.0
0.0 0.0 0.0 0.0
1.0 0.0 2.0 0.0
sum(u.*v,3) is both (reasonably) fast and short.
To explicity get a matrix you can squeeze the third dimension like so squeeze(sum(u.*v,3), 3)
Update: Of course, this has allocations and is not the best answer if speed is everything. In this case, see #DNF's direct loop implementation which is basically as fast as you can get it.
squeeze(sum(u .* v, 3), 3) is clean and simple, but if you need more speed, this is approximately 20x times faster on my pc:
a = fill(zero(eltype(u)), nx, ny)
#inbounds for k in indices(u, 3)
for j in indices(u, 2)
for i in indices(u, 1)
a[i, j] += u[i, j, k] * v[i, j, k]
end
end
end
Edit: For easier benchmarking comparison, this try this code:
function dotsum3(u, v)
a = fill(zero(eltype(u)), size(u, 1), size(u, 2))
#inbounds for k in indices(u, 3)
for j in indices(u, 2)
for i in indices(u, 1)
a[i, j] += u[i, j, k] * v[i, j, k]
end
end
end
return a
end
Also note that, if using #inbounds, one should probably explicitely check that the sizes of u and v are compatible.
Another version is
a = copy(view(u,:,:,1))
a .*= view(v,:,:,1)
a .+= #views u[:,:,2].*v[:,:,2]
Which is easily extensible to arbitrary 3rd dimension length. The benchmarks from my machine:
julia> using BenchmarkTools
julia> function f1(u,v)
a = fill(zero(eltype(u)), nx, ny)
#inbounds for k in indices(u, 3)
for j in indices(u, 2)
for i in indices(u, 1)
a[i, j] += u[i, j, k] * v[i, j, k]
end
end
end
return a
end
f1 (generic function with 1 method)
julia> f2(u,v) = squeeze(sum(u .* v, 3), 3)
f2 (generic function with 1 method)
julia> function f3(u,v)
a = copy(view(u,:,:,1))
a .*= view(v,:,:,1)
a .+= #views u[:,:,2].*v[:,:,2]
return a
end
f3 (generic function with 1 method)
julia> nx, ny = 3, 4
(3, 4)
julia> u = Array{Float64,3}(rand(0:1, nx, ny, 2));
julia> v = Array{Float64,3}(rand(0:1, nx, ny, 2));
Timing results:
julia> #btime f1($u,$v); # DNF suggestion
1.016 μs (1 allocation: 176 bytes)
julia> #btime f2($u,$v); # original answer
1.263 μs (14 allocations: 816 bytes)
julia> #btime f3($u,$v); # this answer
168.591 ns (5 allocations: 432 bytes)
The suggested version is faster (which is logical considering memory ordering of Julia Arrays).
I would like to produce an n x 3 matrix where n is the number of pixels (width * height).
x = linspace(-1, 1, width)
y = linspace(-1, 1, height)
r = 1.0
viewDirections = [[i j 1.0] for i in x for j in y]
However, when I run this I get a:
16-element Array{Array{Float64,2},1}
and not my desired a 16x3 Array{Float64,2}. I am obviously not using comprehensions properly to construct matrices. I tried using comprehensions to create an array of tuples, but I can't then convert those tuples into a matrix.
The problem here is array comprehension will give us a nested array instead of a Matrix. This is the right behavior of comprehension, it won't do extra guesswork for us, so we need to convert the nested array to matrix manually, which can be done using vcat with splating operator(...):
julia> vcat(viewDirections...)
6×3 Array{Float64,2}:
-1.0 -1.0 1.0
-1.0 1.0 1.0
0.0 -1.0 1.0
0.0 1.0 1.0
1.0 -1.0 1.0
1.0 1.0 1.0
It seems like you're constructing homogeneous coordinates from 2D Euclidean space. Using Base.Iterators.product is a more concise and robust way to create the iterator:
julia> w = linspace(-1,1,3)
-1.0:1.0:1.0
julia> h = linspace(-1,1,2)
-1.0:2.0:1.0
julia> r = 1.0
1.0
julia> viewDirections = [collect(i) for i in Iterators.product(w, h, r)]
3×2 Array{Array{Float64,1},2}:
[-1.0, -1.0, 1.0] [-1.0, 1.0, 1.0]
[0.0, -1.0, 1.0] [0.0, 1.0, 1.0]
[1.0, -1.0, 1.0] [1.0, 1.0, 1.0]
julia> hcat(viewDirections...).'
6×3 Array{Float64,2}:
-1.0 -1.0 1.0
0.0 -1.0 1.0
1.0 -1.0 1.0
-1.0 1.0 1.0
0.0 1.0 1.0
1.0 1.0 1.0
Note that, the order of coordinates is different from your original version, that's because Julia is column-major, Iterators.product will iterate the rightest dimension "outestly" i.e. [[i j r] for j in y for i in x ]. If the order is important in your use case, just pay attention to it.
Here are some benchmark results when width/height goes large:
julia> w = linspace(-1,1,300)
-1.0:0.006688963210702341:1.0
julia> h = linspace(-1,1,200)
-1.0:0.010050251256281407:1.0
julia> foo(w,h,r) = hcat([collect(i) for i in Iterators.product(w, h, r)]...).'
julia> bar(w,h,r) = vcat([[i j r] for i in w for j in h]...)
julia> #btime foo($w,$h,$r);
6.172 ms (60018 allocations: 10.99 MiB)
julia> #btime bar($w,$h,$r);
11.294 ms (360028 allocations: 17.02 MiB)
Imagine you have a 3 dimensonal Julia Array A of type Float64 where size(A) = (2, 3, 3).
How could you assign blocks of this array at a time using 2-dimensional arrays? For example, say I wanted A[1, :, :] to be the identity matrix. I would think of doing something like this:
A = Array(Float64, 2, 3, 3)
A[1, :, :] = eye(3)
When I do this I get the following error:
ERROR: argument dimensions must match
in setindex! at array.jl:592
I know it is because size(A[1, :, :]) = (1, 3, 3), but I can't figure out how to either 1) get this slice to be just (3, 3) so eye(3) fits or 2) make eye(3) also be (1, 3, 3) to conform to the shape of the slice of A.
Any suggestions?
EDIT 12:51 AM PST 8-13-13
I learned two new things:
If I take a slice of A along either of the other two dimensions, the result is a 2-dimensional array instead of a 3-d array with the leading dimension being 1.
I found a temporary fix to my specific problem by doing A[1, :, :] = reshape(eye(3), (1, 3, 3)). This is sub-optimal and I am hoping for a better fix.
You may be looking for slice:
julia> sA = slice(A, 1, :, :)
3x3 SubArray of 2x3x3 Float64 Array:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> sA[:] = eye(3)
3x3 Float64 Array:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
julia> A
2x3x3 Float64 Array:
[:, :, 1] =
1.0 0.0 0.0
0.0 0.0 0.0
[:, :, 2] =
0.0 1.0 0.0
0.0 0.0 0.0
[:, :, 3] =
0.0 0.0 1.0
0.0 0.0 0.0