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]
Related
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.)
So I have a size N in julia and I need an NxN sparse matrix with N ones in it, in random places. What would be the best way to go about this?
At first I thought about randomly generating indexes and then setting those numbers to 1 in a sparse matrix but I recently found the sprand functions however I don't understand how to use them correctly or apply them to my problem. I tried using it with my limited understanding and it keeps generating error messages. Help is of course always greatly appreciated :)
Inspired by #DanGetz comment above, the following solution is a one-line function using randperm. I deleted the original answer as it was not very helpful.
sparseN(N) = sparse(randperm(N), randperm(N), ones(N), N, N)
This is also incredibly fast:
#time sparseN(10_000);
0.000558 seconds (30 allocations: 782.563 KiB)
A sparse matrix of dimension (N rows)x(M columns) has at most NxM components that can be indexed using the K=[0,N*M) integer set. For any k in K you can retrieve element indices (i,j) thanks to a Euclidean division k = i + j*N (here column major layout).
To randomly sample n elements of K (without repetition), you can use Knuth algorithm "Algorithm S (Selection sampling technique)" 3.4.2, in its book Vol2., seminumerical-Algorithms
In Julia:
function random_select(n::Int64,K::Int64)
#assert 0<=n<=K
sample=Vector{Int64}(n)
t=Int64(0)
m=Int64(0)
while m<n
if (K-t)*rand()>=n-m
t+=1
else
m+=1
sample[m]=t
t+=1
end
end
sample
end
The next part simply retrieves the I,J indices to create the sparse matrix from its coordinate form:
function create_sparseMatrix(n::Int64,N::Int64,M::Int64)
#assert (0<=N)&&(0<=M)
#assert 0<=n<=N*M
nonZero = random_select(n,N*M)
# column major: k=i+j*N
I = map(k->mod(k,N),nonZero)
J = map(k->div(k,N),nonZero)
sparse(I+1,J+1,ones(n),N,M)
end
Usage example: a 4x5 sparse matrix with 3 nonzero (=1.0) at random positions:
julia> create_sparseMatrix(3,4,5)
4×5 SparseMatrixCSC{Float64,Int64} with 3 stored entries:
[4, 1] = 1.0
[3, 2] = 1.0
[3, 3] = 1.0
Border case tests:
julia> create_sparseMatrix(0,4,5)
4×5 SparseMatrixCSC{Float64,Int64} with 0 stored entries
julia> create_sparseMatrix(4*5,4,5)
4×5 SparseMatrixCSC{Float64,Int64} with 20 stored entries:
[1, 1] = 1.0
[2, 1] = 1.0
[3, 1] = 1.0
[4, 1] = 1.0
⋮
[4, 4] = 1.0
[1, 5] = 1.0
[2, 5] = 1.0
[3, 5] = 1.0
[4, 5] = 1.0
Insisting on a one-line-ish solution:
using StatsBase
sparseones(N,M,K) = sparse(
(x->(first.(x).+1,last.(x).+1))(divrem.(sample(0:N*M-1,K,replace=false),M))...,
ones(K),N,M
)
Giving:
julia> sparseones(3,4,5)
3×4 SparseMatrixCSC{Float64,Int64} with 5 stored entries:
[1, 1] = 1.0
[2, 1] = 1.0
[3, 3] = 1.0
[2, 4] = 1.0
[3, 4] = 1.0
This method is essentially the same as the earlier answer with the advantage of re-using existing sample and being much shorter. It is even faster on larger matrices.
I have array of size N, I need to generate all permutations variants of size K from this array. Variants [1 2 3] and [3 1 2] are different. Standard solutions which I found were
1) Just permutations, where I obtain all reordering of the same size as array.
2) Just combinations, where I obtain all combinations of size K from array of size N, but for these algorithms [1 2 6] and [6 1 2] are the same, while I need them to be different.
Could You help me to find an effective solution?
I should implement it on Matlab, but I hope I will be able to translate Your solutions from other languages.
Basically, in any language which can produce all unordered subsets of size K from 1:N, and which can produce all permutations of 1:K, getting all the ordered subsets is as simple as iterating over the subsets and permuting them using every K-permutation.
In Julia language:
using Combinatorics, Iterators, Base.Iterators
N = 4
K = 2
collect(flatten(permutations(subset) for subset in subsets(1:N,K)))
Gives:
12-element Array{Array{Int64,1},1}:
[1, 2]
[2, 1]
[1, 3]
[3, 1]
[1, 4]
[4, 1]
[2, 3]
[3, 2]
[2, 4]
[4, 2]
[3, 4]
[4, 3]
Combine the two solutions you found. Here's the python code:
allPermutations = list()
combinations=getCombinations(arr, K)
for comb in combinations:
allPermutations.extend(getPermutations(comb))
1.arr is the input array.
2.getCombinations is a function which returns a list of all the combinations in arr of size K.
3.getPermutations returns all permutations of the array given as input.
This may be very obvious, but how do you multiply a column vector by a matrix? For example:
let n matrix:from-column-list [[1 0]]
let m matrix:from-row-list [[1 0] [0 1]]
Using matrix:times does not work as the dimensions are not the same, and I can't find any other way of doing it. Any help would be great.
Matrix multiplication is not commutative. This works fine:
let n matrix:from-column-list [[1 0]] let m matrix:from-row-list [[1 0] [0 1]] show matrix:times m n
hth
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]]