Add 2d tuple to a 2d array in Julia - matrix

How to add a 2d tuple to a 2d matrix in Julia?
t1 = ((10,20),(30,40)); #2d immutable tuple
a = [1 2;3 4] #2d matrix
a .+ t1
throws an error:
MethodError: no method matching +(::Int64, ::Tuple{Int64, Int64})
Closest candidates are:
+(::Any, ::Any, ::Any, ::Any...) at operators.jl:560
+(::T, ::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:87
+(::Integer, ::Ptr) at pointer.jl:161
...
Stacktrace:
[1] _broadcast_getindex_evalf
# .\broadcast.jl:648 [inlined]
[2] _broadcast_getindex
# .\broadcast.jl:621 [inlined]
[3] getindex
# .\broadcast.jl:575 [inlined]
[4] copy
# .\broadcast.jl:922 [inlined]
[5] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2}, Nothing, typeof(+), Tuple{Matrix{Int64}, Tuple{Tuple{Int64, Int64}, Tuple{Int64, Int64}}}})
# Base.Broadcast .\broadcast.jl:883
[6] top-level scope
# REPL[15]:1
Is there a vector/matrix addition method exists?
Obviously I can use a for loop for element by element addition.

Ah, so the problem here is that, while you call t1 a "2d tuple", it is really not; it is a nested tuple, a tuple-of-tuples, and is thus not really comparable to your 2d array (which really is a two-dimensional object and not just an array-of-arrays).
If you want to add a two-dimensional array to an immutable object that can be stack-allocated like a Tuple while being truly two-dimensional, then you can use the StaticArrays.jl package, which provides the immutable SArray type:
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> using StaticArrays
julia> t1 = SA[10 20; 30 40]
2×2 SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
10 20
30 40
julia> a + t1
2×2 SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
11 22
33 44
However, if for any reason you really want to stick with nesting instead of multidimensionality, then let's make the array nested as well
julia> t1 = ((10,20),(30,40)) #tuple-of-tuples
((10, 20), (30, 40))
julia> a = [[1,2],[3,4]] #vector-of-vectors
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
in which case you can easily solve by recursion
add(a,b) = a + b
add(a::Vector, b::NTuple{N}) where N = [add(a[i],b[i]) for i in 1:N]
add(a::NTuple{N}, b::Vector) where N = [add(a[i],b[i]) for i in 1:N]
julia> add(a,t1)
2-element Vector{Vector{Int64}}:
[11, 22]
[33, 44]
This approach will also scale to arbitrarily deeply nested objects:
julia> a = [[[1,2],[3,4]],[[5,6],[7,8]]]
2-element Vector{Vector{Vector{Int64}}}:
[[1, 2], [3, 4]]
[[5, 6], [7, 8]]
julia> t1 = (((10,20),(30,40)),((50,60),(70,80)))
(((10, 20), (30, 40)), ((50, 60), (70, 80)))
julia> add(a,t1)
2-element Vector{Vector{Vector{Int64}}}:
[[11, 22], [33, 44]]
[[55, 66], [77, 88]]
Unfortunately, there is widespread semantic confusion between true multidimensional arrays and the common hack of using a vector-of-vectors in languages which do not support real multidimensional arrays.

#cbk has already explained how nested arrays are not equivalent to multidimensional structures. But you can of course write your addition as a nested broadcast if your structure is already nested. Since (I belive) Julia 1.6, there is syntax for standalone "broadcasted operators", with which this is possible:
julia> t1 = ((10,20),(30,40))
((10, 20), (30, 40))
julia> a = [[1,2],[3,4]]
2-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
julia> broadcast(.+, a, t1)
2-element Vector{Vector{Int64}}:
[11, 22]
[33, 44]
If a is a Matrix, you can do the same on eachrow:
julia> a = [1 2;3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> broadcast(.+, eachrow(a), t1)
2-element Vector{Vector{Int64}}:
[11, 22]
[33, 44]
(In this specific case, map is equivalent to broadcast.)

Related

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]

what is the mathematical logic of this solution (finding a number that is a multiple of numbers 1 to 20)

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
I already found a solution but it was almost brute forcing which took about 7 seconds to run until it found the solution.
I found answers on stackoverflow but couldn't understand the logic behind finding the answer. I know what LCM and GCM are but how did he figure out to use them this way to find the answer? (which is 232,792,560)
def find_multiple
lcm = 1
(2..20).each do |i|
lcm *= i / gcd(lcm, i)
end
lcm
end
def gcd(a, b)
while b > 0
a %= b
return b if a == 0
b %= a
end
a
end
puts find_multiple
A shorter way, using the built in lcm method of Integer
p (2..20).inject(&:lcm) # => 232792560
"lcm" means "least common multiple". (To refresh your memory: the lcm is useful when adding or subtracting fractions with different denominators). The code above is an extremely terse way of coding the following process:
Take 2 and 3, calculate the lcm, which is 6.
With this 6, calculate
the lcm with the next number, 4. The result is 12.
Calculate the lcm
of 12 and 5. Result 60
Calculate the lcm of 60 and 6. Result 60
etc. all the way upto 20
Every non-negative integer can be expressed by its prime decomposition. Therefore, every number divisible by all numbers between 2 and 20 can be expressed
2**n2 * 3**n3 * 5**n5 * 7**n7 * 11**n11 * 13**n13 * 17**n17 * 19**n19
2, 3, 5, 7, 11, 13, 17 and 19 are the primes between 2 and 20, and the values of the exponents are to be determined.
Ruby provides a method Prime::prime_division that the returns the prime decomposition of a number. Let's compute the prime decomposition of every number between 2 and 20:
(2..20).each { |n| puts "#{n}: #{Prime.prime_division(n)}" }
2: [[2, 1]]
3: [ [3, 1]]
4: [[2, 2]]
5: [ [5, 1]]
6: [[2, 1], [3, 1]]
7: [ [7, 1]]
8: [[2, 3]]
9: [ [3, 2]]
10: [[2, 1], [5, 1]]
11: [ [11, 1]]
12: [[2, 2], [3, 1]]
13: [ [13, 1]]
14: [[2, 1], [7, 1]]
15: [[3, 1], [5, 1]]
16: [[2, 4]]
17: [ [17, 1]]
18: [[2, 1], [3, 2]]
19: [ [19, 1]]
20: [[2, 2], [5, 1]]
12, for example, equals 2**2 * 3**1, expressed [2,2], [3,1]. Each two-tuple is of the form [p,e], where p is the prime and e is the exponent.
Now consider each prime between 2 and 20. We see that every even number requires 2 raised to a power, the maximum of which is 4, for 16.that This tells us that every number n divisible by every number between 2 and 20 must be divisible by 2**4. If n is divisible by 2**4, it is of course also divisible by 2**1, 2**2 and 2**3, thereby satisfying the requirements of all other even numbers between 2 and 20. It follows that n2 in the above expression must be at least 4. Since we want the smallest product of the primes raised to a power, we set n2 to 4.
For the prime 3. the exponents are seen to 1, 1, 2, 1 and 2 for the five numbers between 2 and 20 that are divisible by 3. All numbers divisible by all numbers between 2 and 20 therefore must be divisible by 3**2. We therefore set n3 to 2.
Repeating this for each of the remaining primes 5, 7, 11, 13, 17 and 19, we see that the smallest number divisible by all numbers between 2 and 20 equals
2**4 * 3**2 * 5**1 * 7**1 * 11**1 * 13**1 * 17**1 * 19**1
#=> 232792560
Ruby has another method, Prime::Prime.int_from_prime_division that produces this number from the form of the array returned by prime_division:
Prime.int_from_prime_division([[2,4], [3,2], [5,1], [7,1], [11,1], [13,1],
[17,1], [19,1]])
#=> 232792560
We can wrap this up into the following calculation.
def smallest_divisible_by_2_to_n(n)
Prime.int_from_prime_division(
(2..n).each_with_object({}) do |n,h|
Prime.prime_division(n).each { |p,e| h[p] = [h[p].to_i, e].max }
end.to_a)
end
Note that if the hash h does not have a key p, h[p] #=> nil. It is for that reason that I have written h[p].to_i, as nil.to_i #=> 0. See Nilclass#to_i. That method is precisely for situations such as this one.
smallest_divisible_by_2_to_n(10)
#=> 2520
smallest_divisible_by_2_to_n(20)
#=> 232792560
smallest_divisible_by_2_to_n(30)
#=> 2329089562800

Julia sparse matrix with random 1's

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.

Fast algorithm to generate all nonordered permutations of lenght K from N

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.

Augment a matrix in NumPy

I start with a 2x4 matrix A
import numpy as np
A = np.matrix([[1, 2, 3, 4], [5, 6, 7, 8]])
I also have another 1x4 matrix B
B = np.matrix([9, 10, 11, 12])
How do I concatenate A and B so that I get a 3x4 matrix C
C = [[9 10 11 12]
[1 2 3 4]
[5 6 7 8]]
Note that B is prepended before row 0 of matrix A.
From: http://docs.scipy.org/doc/numpy/reference/routines.array-manipulation.html
C = np.concatenate((B, A))
The r_ command also works:
np.r_[C,B]
also works (and np.c_ is a variant on r_ for gluing columns)

Resources