Slicing vector of matrices - matrix

I would like to slice a vector of matrices by some condition. The code I have now looks like
sliced = data[:][[data[:][end,1] .> 0]
where data is a vector of irregularly sized matrices of size (n,2). The above code doesn't work, because it thinks I'm trying to slice the last element of the vector or something. The overall question I'm trying to ask is whether there is a way to slice an irregular vector of matrices based on some consistent condition?

(Edited based on the clarification of the condition, thanks to #DanGetz)
Given a data vector of matrices:
julia> data = [[1 2; 3 4; 5 6; 7 8], [-1 -2], [10 20; 30 40], [9 8; -7 6]]
4-element Vector{Matrix{Int64}}:
[1 2; 3 4; 5 6; 7 8]
[-1 -2]
[10 20; 30 40]
[9 8; -7 6]
If we wanted to use logical indexing like in the question, we could broadcasting on an anonymous function like so:
julia> data[(m -> m[end, begin] > 0).(data)]
2-element Vector{Matrix{Int64}}:
[1 2; 3 4; 5 6; 7 8]
[10 20; 30 40]
But in this case, an array comprehension or a filter would be clearer:
julia> [m for m in data if m[end, begin] > 0]
2-element Vector{Matrix{Int64}}:
[1 2; 3 4; 5 6; 7 8]
[10 20; 30 40]
julia> filter(data) do (m)
m[end, begin] > 0
end
2-element Vector{Matrix{Int64}}:
[1 2; 3 4; 5 6; 7 8]
[10 20; 30 40]
(begin here is a generic way of writing the first index of an array dimension - it works both for normal arrays where the first index is 1, and for things like OffsetArrays.)

Related

julia how to quickly generate matrix by row from range

How can I quickly generate matrix by row from range?
For example, given
my_example_matrix = [[1 2 3]
[4 5 6]
[7 8 9]]
How can I generate the matrix fastly by using range 1:9?
Best.
This is quick in a way because no part of it allocates memory, so the length of the range won't matter.
julia> transpose(reshape(1:9, (3, 3)))
3×3 LinearAlgebra.Transpose{Int64,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}}:
1 2 3
4 5 6
7 8 9

How to make an array of vectors and matrices in Julia

I don't know how to make an array of vectors and matrices in Julia. For example, how I make a list p such that
p[1]=[1;2]
p[2]=[2 3; 4 5]
?
You can use an array of "Any"
p=Any[[1;2],[2 3; 4 5]]
which returns
2-element Array{Any,1}:
[1, 2]
[2 3; 4 5]

Julia: Is there a way to enumerate all matrices of size m by n with entries from a discrete set?

I am working with a set of functions of two variables f(x,y) in a 2D-grid. The function itself in each point in the grid can only take values from a finite set. I need to enumerate all possible functions that I can construct.
In particular, a function is defined as a matrix where the ith jth element tells me the value of the function evaluated at x_i, y_j.
I want to be able to create all the matrices possible. I know the total number of such matrices is nf^(nx*ny) where nf is the number of values that the function can take in a point, and nx, ny are the number of points in the grid of x and y. So, my tests will be with a modest number of grid points.
Thank you
I tried to express the problem as enumerating all branches in a tree and using recursion, but couldnt create a matrix as an output.
Is this something you want?
function funs(fs)
nf = length(fs)
#assert length(unique(size.(fs))) == 1
nx,ny = size(fs[1])
sigs = Iterators.product(ntuple(i -> 1:nf, nx*ny)...)
([fs[sig[i+(j-1)*nx]][nx,ny] for i in 1:nx, j in 1:ny] for sig in sigs)
end
I am returning a generator that you can easily iterate over without materializing as collecting it might use too much memory. Of course for small data you can collect it with the additional benefit that it will be a nx*ny dimensional array allowing you to easily slice over the varying dimensions.
Here is an example:
julia> fs = [fill(1,2,2), fill(2,2,2), fill(3,2,2)]
3-element Array{Array{Int64,2},1}:
[1 1; 1 1]
[2 2; 2 2]
[3 3; 3 3]
julia> funs(fs)
Base.Generator{Base.Iterators.ProductIterator{NTuple{4,UnitRange{Int64}}},getfield(Main, Symbol("##46#49")){Array{Array{Int64,2},1},Int64,Int64}}(getfield(Main, Symbol("##46#49")){Array{Array{Int64,2},1},Int64,Int64}(Array{Int64,2}[[1 1; 1 1], [2 2; 2 2], [3 3; 3 3]], 2, 2), Base.Iterators.ProductIterator{NTuple{4,UnitRange{Int64}}}((1:3, 1:3, 1:3, 1:3)))
julia> collect(funs(fs))
3×3×3×3 Array{Array{Int64,2},4}:
[:, :, 1, 1] =
[1 1; 1 1] [1 1; 2 1] [1 1; 3 1]
[2 1; 1 1] [2 1; 2 1] [2 1; 3 1]
[3 1; 1 1] [3 1; 2 1] [3 1; 3 1]
[:, :, 2, 1] =
[1 2; 1 1] [1 2; 2 1] [1 2; 3 1]
[2 2; 1 1] [2 2; 2 1] [2 2; 3 1]
[3 2; 1 1] [3 2; 2 1] [3 2; 3 1]
[:, :, 3, 1] =
[1 3; 1 1] [1 3; 2 1] [1 3; 3 1]
[2 3; 1 1] [2 3; 2 1] [2 3; 3 1]
[3 3; 1 1] [3 3; 2 1] [3 3; 3 1]
[:, :, 1, 2] =
[1 1; 1 2] [1 1; 2 2] [1 1; 3 2]
[2 1; 1 2] [2 1; 2 2] [2 1; 3 2]
[3 1; 1 2] [3 1; 2 2] [3 1; 3 2]
[:, :, 2, 2] =
[1 2; 1 2] [1 2; 2 2] [1 2; 3 2]
[2 2; 1 2] [2 2; 2 2] [2 2; 3 2]
[3 2; 1 2] [3 2; 2 2] [3 2; 3 2]
[:, :, 3, 2] =
[1 3; 1 2] [1 3; 2 2] [1 3; 3 2]
[2 3; 1 2] [2 3; 2 2] [2 3; 3 2]
[3 3; 1 2] [3 3; 2 2] [3 3; 3 2]
[:, :, 1, 3] =
[1 1; 1 3] [1 1; 2 3] [1 1; 3 3]
[2 1; 1 3] [2 1; 2 3] [2 1; 3 3]
[3 1; 1 3] [3 1; 2 3] [3 1; 3 3]
[:, :, 2, 3] =
[1 2; 1 3] [1 2; 2 3] [1 2; 3 3]
[2 2; 1 3] [2 2; 2 3] [2 2; 3 3]
[3 2; 1 3] [3 2; 2 3] [3 2; 3 3]
[:, :, 3, 3] =
[1 3; 1 3] [1 3; 2 3] [1 3; 3 3]
[2 3; 1 3] [2 3; 2 3] [2 3; 3 3]
[3 3; 1 3] [3 3; 2 3] [3 3; 3 3]
Here is what I understand from OP:
function all_functions(finite_set, nx, ny)
I = Iterators.product(fill(finite_set, nx*ny)...)
(reshape(collect(i), (nx,ny)) for i in I)
end
and in action:
julia>fs = (0,1,2,3)
julia>collect(Iterators.take(all_functions(fs, 2, 2), 8))
Array{Int64,2}[[0 0; 0 0], [1 0; 0 0], [2 0; 0 0], [3 0; 0 0], [0 0; 1 0], [1 0; 1 0], [2 0; 1 0], [3 0; 1 0]]

convert multi D array into vector Matlab

Thanks in advance for the help
Suppose I have a multi D array such that
x(:,:,1) = [1 2 ; 3 4];
x(:,:,2) = [5 6 ; 7 8];
x(:,:,3) = [9 10 ; 11 12];
I would like quickly and efficiently convert x into
y = [1 5 9 2 6 10 3 7 11 4 8 12];
I there an efficient way to go about this besides using loops (the matrix I would like to do this to is relatively large)?
You can use the colon operator : but you first have to reorder the matrix x:
x(:,:,1) = [1 2 ; 3 4];
x(:,:,2) = [5 6 ; 7 8];
x(:,:,3) = [9 10 ; 11 12];
z=permute(x,[3 2 1]);
y=z(:).'

Adding rows / columns to existing matrices in core.matrix (Clojure)

How does one add a row or a column to an existing matrix? I'm trying to add a bias-term, a column of ones, as the first row of a matrix. In Octave I can do this with:
M = [ones(size(M, 1), 1), M];
You can use the join function to append arrays along the major dimension.
And you can combine this with broadcast to get a matrix of ones in whatever size you like, e.g.:
e.g.
(join (broadcast 1 [1 3])
[[1 2 3]
[4 5 6]
[7 8 9]])
=> [[1 1 1]
[1 2 3]
[4 5 6]
[7 8 9]]

Resources