I want to move an array from my laptop (Julia 1.3.1) to my desktop PC (Julia 1.6.2).
I make an array in Julia 1.3.1 as follows.
using LinearAlgebra
H = ... #give a matrix H
eigen,vector = eigen(H)
Then, I'd like to move "vector" to Julia 1.6.2.
How do you do that?
The simplest way is by using DelimitedFiles:
julia> v = [1.0,2.0,3.0]
julia> using DelimitedFiles
julia> writedlm("f.txt", v)
julia> readdlm("f.txt")
3×1 Matrix{Float64}:
1.0
2.0
3.0
julia> vec(readdlm("f.txt"))
3-element Vector{Float64}:
1.0
2.0
3.0
Note that DelmitedFiles works with matrices so the last example shows what to do if you rather store a vector.
Edit following Bogumil's comment
When you have a Matrix of Complex numbers you need to provide the output type for readdlm:
julia> v = Complex.(rand(2,3), rand(2,3))
2×3 Matrix{ComplexF64}:
0.282157+0.540556im 0.757765+0.103518im 0.979935+0.212347im
0.557499+0.934859im 0.604032+0.338489im 0.431962+0.945946im
julia> writedlm("f.txt", v)
julia> readdlm("f.txt",'\t',Complex{Float64})
2×3 Matrix{ComplexF64}:
0.282157+0.540556im 0.757765+0.103518im 0.979935+0.212347im
0.557499+0.934859im 0.604032+0.338489im 0.431962+0.945946im
julia> readdlm("f.txt",'\t',Complex{Float64}) == v
true
Another way is to use a binary format. For long term in-between version serialization BSON (binary json) could be a good option:
julia> using BSON
julia> BSON.bson("v.bson", v = v)
julia> v2 = BSON.load("v.bson")[:v]
2×3 Matrix{ComplexF64}:
0.282157+0.540556im 0.757765+0.103518im 0.979935+0.212347im
0.557499+0.934859im 0.604032+0.338489im 0.431962+0.945946im
Related
I have a pair of matrices, say Ws, Xs, of equal dimension and a function myFunc(w, x) which takes two vectors as input. I want to apply this function to pairs of columns (think of it as zip-ing the columns) and mapping this function to them.
Is there a non-iterative way to do this? If there were only two columns in each of Ws, Xs, I can do
allCols = permutedims(reshape(hcat(Ws, Xs), d, 2), [1, 3, 2])
mapslices(x -> myFunc(x[:, 1], x[:, 2]), allCols, dims=[1, 2])
but I'm having trouble moving to an arbitrary number of columns.
Edit: using vcat and the correct dimensions seems to fix this:
# assume d is column size
wxArray = reshape(vcat(Ws, Xs), 2, d) # group pairs of columns together
mapslices(x -> myFunc(x[:, 1], x[:, 2]), wxArray, dims=[1,2])
You can use eachcol function like this (I give three ways just to show different possible approaches but eachcol is crucial in all of them):
julia> Ws = rand(2,3)
2×3 Array{Float64,2}:
0.164036 0.233236 0.937968
0.724233 0.102248 0.55047
julia> Xs = rand(2,3)
2×3 Array{Float64,2}:
0.0493071 0.735849 0.643352
0.909295 0.276808 0.396145
julia> using LinearAlgebra
julia> dot.(eachcol(Ws), eachcol(Xs))
3-element Array{Float64,1}:
0.6666296397421881
0.19992972241709792
0.8215096642236619
julia> dot.(eachcol.((Ws, Xs))...)
3-element Array{Float64,1}:
0.6666296397421881
0.19992972241709792
0.8215096642236619
julia> map(dot, eachcol(Ws), eachcol(Xs))
3-element Array{Float64,1}:
0.6666296397421881
0.19992972241709792
0.8215096642236619
This requires Julia 1.1.
EDIT
If you are on Julia 1.0 and do want to avoid iteration while not mind some extra allocations (the solution above avoids allocations) you can also use cat function (which is a bit simpler than your approach I think):
julia> Ws = rand(2,3)
2×3 Array{Float64,2}:
0.975749 0.660932 0.391192
0.619872 0.278402 0.799096
julia> Xs = rand(2,3)
2×3 Array{Float64,2}:
0.0326003 0.272455 0.713046
0.389058 0.886105 0.950822
julia> mapslices(x -> (x[:,1], x[:,2]), cat(Ws, Xs; dims=3), dims=[1,3])[1,:,1]
3-element Array{Tuple{Array{Float64,1},Array{Float64,1}},1}:
([0.975749, 0.619872], [0.0326003, 0.389058])
([0.660932, 0.278402], [0.272455, 0.886105])
([0.391192, 0.799096], [0.713046, 0.950822])
of course you can also simply do this:
julia> map(i -> (Ws[:,i], Xs[:,i]), axes(Ws, 2))
3-element Array{Tuple{Array{Float64,1},Array{Float64,1}},1}:
([0.975749, 0.619872], [0.0326003, 0.389058])
([0.660932, 0.278402], [0.272455, 0.886105])
([0.391192, 0.799096], [0.713046, 0.950822])
or more fancy:
julia> (i -> (Ws[:,i], Xs[:,i])).(axes(Ws, 2))
3-element Array{Tuple{Array{Float64,1},Array{Float64,1}},1}:
([0.975749, 0.619872], [0.0326003, 0.389058])
([0.660932, 0.278402], [0.272455, 0.886105])
([0.391192, 0.799096], [0.713046, 0.950822])
I have an array that can take Float64 and Missing values:
local x::Array{Union{Float64, Missing}, 1} = [1.0, missing, 3.0]
I can add more Float64 values using the append! function, but I can't add a missing value this way. I get the following error:
julia> append!(x, missing)
ERROR: MethodError: no method matching length(::Missing)
What's the correct way to add missing values to this array?
Yes you are right that push! should be used.
Additionally your code does not need to be so verbose:
julia> x = [1.0, missing, 3.0]
3-element Array{Union{Missing, Float64},1}:
1.0
missing
3.0
julia> y = Union{Missing, Float64}[]
0-element Array{Union{Missing, Float64},1}
julia> push!(y,1);
julia> push!(y,missing)
2-element Array{Union{Missing, Float64},1}:
1.0
missing
Moreover, instead of Array{Union{Float64, Missing}, 1} the shorter and more readable version Vector{Union{Float64, Missing}} can be used.
I should have been using push! - append! is for adding collections, while push! is for single values.
I am using Julia from time to time, however I am surprised by the following behavior:
Let's define an 3x4 array
julia> m=rand(3,4)
3×4 Array{Float64,2}:
0.889018 0.500847 0.539856 0.828231
0.492425 0.582958 0.521406 0.754102
0.28227 0.834333 0.669967 0.0939701
Now I check that
julia> size(m,1), size(m,2)
(3, 4)
as expected.
However, I am surprised by this:
julia> size(m,3), size(m,2018)
(1, 1)
-> I would have expected (0,0) or an error message
Looking the Julia code confirms this behavior:
size(t::AbstractArray{T,N}, d) where {T,N} = d <= N ? size(t)[d] : 1
Moreover:
julia> m[2,1,1,1,1]
0.4924252391289974
-> I would have expected an out of bounds error
So my question is: "what is the rationale?"
( I do not thing it is a bug, I use Julia version 0.6.2)
I believe it's for broadcasting.
julia> m=rand(3,4)
3×4 Array{Float64,2}:
0.139323 0.663912 0.994985 0.517332
0.423913 0.121753 0.0327054 0.0754665
0.392672 0.47006 0.351121 0.787318
julia> size(m)
(3, 4)
julia> n = rand(3)
3-element Array{Float64,1}:
0.716752
0.98755
0.661226
julia> m .* n
3×4 Array{Float64,2}:
0.09986 0.475861 0.713157 0.370799
0.418636 0.120237 0.0322983 0.074527
0.259645 0.310816 0.23217 0.520595
Notice that n is of one dimension less, so it's size 1 in the 2nd dimension and thus applies column-wise. Scalars in broadcast are treated differently and are generally inlined into the fused broadcasting function which you cannot do with a mutable type, so the size 1 = expand in higher dimensions rule for broadcast is a nice way to implement this.
I have functions which are called many times and require temporary arrays. Rather than array allocation happening every time the function is called, I would like the temporary to be statically allocated once.
How do I create a statically allocated array in Julia, with function scope?
Ok, let's assume that your function is called foo with an argument x and your array is just 100 hundred elements (each of which is a 64-bit value) with one dimension. Then you can create a scope around that function
let
global foo
let A = Array{Int64}(100)
function foo(x)
# do your tasks
end
end
A should be a let variable since it would overwrite any other global A.
You can wrap the temp array as a reference in a class:
type MyWrapper
thetmparray
thefunction::Function
function MyWrapper(outertmp::Array)
this = new(outertmp)
this.thefunction = function()
#use this.thetmparray or outertmp
end
return this
end
end
This away you can avoid global variables and (in the future) have a per-executor/thread/process/machine/etc temp array.
You can use either the let block or partial application (I prefer this approach for such a case):
function bind_array(A::Array)
function f(x)
A = A*x
end
end
Now you can bind a private array to every new "instance" of your f:
julia> f_x = bind_array(ones(1,2))
f (generic function with 1 method)
julia> display(f_x(2))
1x2 Array{Float64,2}:
2.0 2.0
julia> display(f_x(3))
1x2 Array{Float64,2}:
6.0 6.0
julia> f_y = bind_array(ones(3,2))
f (generic function with 1 method)
julia> display(f_y(2))
3x2 Array{Float64,2}:
2.0 2.0
2.0 2.0
2.0 2.0
julia> display(f_y(3))
3x2 Array{Float64,2}:
6.0 6.0
6.0 6.0
6.0 6.0
I would like to create a 1×1 array (say an Array{Float64,2}) and initialize it to some value. Of course this works:
M=zeros(1,1)
M[1,1]=0.1234
Is there a more concise way to create M and initialize it at the same time?
Since [1.1234] will give you a Vector in Julia the simplest way I could come up with is:
julia> fill(1.234,1,1)
1x1 Array{Float64,2}:
1.234
An alternative is to reshape:
julia> reshape([1.234], 1, 1)
1x1 Array{Float64,2}:
1.234
The existing answers are not what I would recommend. The best way is to use
julia> hcat(5)
1×1 Array{Int64,2}:
5
This is most concise and parallels the [x y] concatenation form.