Array Multiplication in Julia - arrays

I'm trying to do something that I believe should be relatively simple in Julia, but I can't seem to find any mention of this problem.
Basically what I've got is an mxn matrix, and an nx1 vector. What I would like to do is multiply the vector against the matrix, elementwise, but along the axis such that every element of the matrix is multiplied.
In numpy for instance this would be:
np.multiply(array, vector)
Is there any way to do this in Julia?
I tried just extending the vector to fill an array:
projection = 1:size(matrix)[1]
weight_change = hcat(map(x -> vector, projection))
but that yields something with a type of Array{Array{Float64, 2}, 2}, when what I really need is just Array{Float64, 2}, which means that an elementwise multiplication won't really work.
Is there any way to either fix my approach or remedy my bugged solution?

You're looking for the .* element-wise, broadcasting multiply operator:
julia> A = [ i + j*im for i=1:3, j=1:4 ]
3x4 Array{Complex{Int64},2}:
1+1im 1+2im 1+3im 1+4im
2+1im 2+2im 2+3im 2+4im
3+1im 3+2im 3+3im 3+4im
julia> v = [1:4]
4-element Array{Int64,1}:
1
2
3
4
julia> w = [1:3]
3-element Array{Int64,1}:
1
2
3
julia> A .* w
3x4 Array{Complex{Int64},2}:
1+1im 1+2im 1+3im 1+4im
4+2im 4+4im 4+6im 4+8im
9+3im 9+6im 9+9im 9+12im
julia> A .* v'
3x4 Array{Complex{Int64},2}:
1+1im 2+4im 3+9im 4+16im
2+1im 4+4im 6+9im 8+16im
3+1im 6+4im 9+9im 12+16im

Related

Julia accessing specific Matrix elements using vectors as indexes

Suppose I have a 4*2 matrix as follows:
a = [1 2; 3 4; 5 6; 7 8]
4×2 Matrix{Int64}:
1 2
3 4
5 6
7 8
I want to access the matrix using a vector specifying which element I want to access in each column. In NumPy from python, I would do the following command:
a[[1,3], [1,2]]
# expected output:
1×2 Matrix{Int64}:
1(as a[1,1]) 6(as a[3,2])
but in Julia, I got the following matrix:
2×2 Matrix{Int64}:
1 2
5 6
How can I do it in an julia way?
UPDATE: Inspired by DNF answer:
julia> a[CartesianIndex.([1 3], [1 2])]
1×2 Matrix{Int64}:
1 6
seems to me the right balance of clarity and similarity to OP.
ORIGINAL answer:
Maybe not the optimal way, but:
[a[x...] for x in [[[1,1]] [[3,2]]]]
works.
Note that this returns a row vector, like in the OP. In Julia there is a difference between a vector and a matrix. A matrix with one row or one column is not the same as a vector.
The [[]] notation is to let hcat handle vector elements correctly. If a vector output is good enough, then: [[1,1],[3,2]] is enough.
The syntax a[i, j] is syntax sugar for getindex(a, i, j). You can broadcast getindex to get the desired behavior (unfortunately, you cannot broadcast the [] syntax itself):
getindex.(Ref(a), [1,3], [1,2])
You must protect a itself against being broadcasted, by wrapping it in a Ref.

How to convert an array of array to array in Julia?

In the following example I am getting an array of array as an output. I would like to seek suggestion on reducing it to n-element vector.
Example: I have a vector x and then I perform subtraction on first 2 elements of the array which outputs a.
x = Float64.([1,2,3,4,5])
a= x[2,:] - x[1,:]
1-element Vector{Float64}:
1.0
Now when i collect the following range, it returns array of array, as shown below.
c = collect(range(minimum(x).*a, maximum(x).*a, length=10))
10-element Vector{Vector{Float64}}:
[1.0]
[1.4444444444444444]
[1.8888888888888888]
[2.333333333333333]
[2.7777777777777777]
[3.2222222222222223]
[3.6666666666666665]
[4.111111111111111]
[4.555555555555555]
[5.0]
I would like to know how may I convert this to a vector, which can output following result?
# Expected result:
10-element Vector{Float64}:
1.0
1.4444444444444444
1.8888888888888888
2.333333333333333
2.7777777777777777
3.2222222222222223
3.6666666666666665
4.111111111111111
4.555555555555555
5.0
Thanks!!
When constructing a you want a= x[2] - x[1]. Then a will be a scalar, and everything else will behave as expected.
In general, you can use a combination of splatting and vcat:
julia> xs = [[1],[2,3],[],[4],[5,6,7]]
5-element Vector{Vector{Any}}:
[1]
[2, 3]
[]
[4]
[5, 6, 7]
julia> vcat(xs...)
7-element Vector{Any}:
1
2
3
4
5
6
7
That being said, I would follow Oscar Smith's advice and fix the root problem.

Accessing elements of array based on indices given by another array

Suppose I have the following 4x4 Array in Julia:
julia> A=rand(4,4)
4×4 Array{Float64,2}:
0.00624508 0.624399 0.458094 0.341848
0.303817 0.269487 0.580949 0.534655
0.748525 0.419411 0.469938 0.659914
0.730659 0.191461 0.996144 0.74772
And I have another 6x2 Array where each row represents a row-column pair:
julia> B=[ 1 1; 1 3; 2 2; 2 4; 3 1; 3 3]
6×2 Array{Int64,2}:
1 1
1 3
2 2
2 4
3 1
3 3
The first row of B represents the element [1,1] of A, the second row of B represents the element [1,3] of A, and so on. I want to access the elements of A based on the coordinates given by each row of B. In R for example, the command A[B] gives exactly what I want: 0.00624508 0.458094 0.269487 0.534655 0.748525 0.469938 but in Julia, the same command gives
julia> A[B]
6×2 Array{Float64,2}:
0.00624508 0.00624508
0.00624508 0.748525
0.303817 0.303817
0.303817 0.730659
0.748525 0.00624508
0.748525 0.748525
and this is not what I want. Is there a similar way of coding A[B] in Julia, so that I obtain what I obtain in R? Must be applicable to any Array.
Construct an array of CartesianIndex out of your index pairs:
julia> A[CartesianIndex.(B[:, 1], B[:, 2])]
6-element Array{Float64,1}:
0.987200021334854
0.5261639427155012
0.8430528192705655
0.5300778835366697
0.5044387593056074
0.0025132074927423087
This is necessary to distinguish such "point indexing" from "shape indexing", as you observed it (I made those terms up).
Ideally, you would already construct B as such an array, but that is not always feasible, of course.

The best way to convert Vector into Matrix in Julia?

Suppose I have a variable v of a type Vector.
What would be the best / fastest way to just convert it into Matrix representation (for whatever reason)?
To clarify, v'' will do the job, but is it the best way to do this?
Reshape should be the most efficient. From the docs:
reshape(A, dims): Create an array with the same data as the given array, but with different dimensions. An implementation for a particular type of array may choose whether the data is copied or shared.
julia> v = rand(3)
3-element Array{Float64,1}:
0.690673
0.392635
0.0519467
julia> reshape(v, length(v), 1)
3x1 Array{Float64,2}:
0.690673
0.392635
0.0519467
v[:,:] is probably the clearest way to do this.
For example:
julia> v=[1,2,3]
3-element Array{Int64,1}:
1
2
3
julia> m=v[:,:]
3x1 Array{Int64,2}:
1
2
3
julia> ndims(m)
2
Or just use:
v = [1, 2, 3]
hcat(v)
Result:
3×1 Array{Int64,2}:
1
2
3

Julia Reverse N-dimensional arrays

In Python, Numpy arrays can be reversed using the standard [::-1] i.e.
A = np.diag(np.arange(1,3))
A[::, ::-1]
A[::-1]
A[::-1, ::-1]
Julia does not support [::-1] and the reverse method only works on 1D arrays and only 1D columns (where as rows are 2D by default).
Is there an alternative I'm missing?
Try the following, which is essentially the same as the numpy version:
julia> X = rand(3,3)
3x3 Array{Float64,2}:
0.782622 0.996359 0.335781
0.719058 0.188848 0.985693
0.455355 0.910717 0.870187
julia> X[end:-1:1,end:-1:1]
3x3 Array{Float64,2}:
0.870187 0.910717 0.455355
0.985693 0.188848 0.719058
0.335781 0.996359 0.782622
In Julia 1.0, to reverse a (column) vector:
julia> reverse([1, 2, 3])
3-element Array{Int64,1}:
3
2
1
For reversing rows, just state that you want to flip the second dimension:
julia> reverse([1 2 3], dims=2)
1×3 Array{Int64,2}:
3 2 1
EDIT: Alternatively, you can also index in reverse using end:-1:1, and that way also allows you to request a view instead of a copy:
julia> a = reshape(randperm(9), 3, 3)
3×3 Matrix{Int64}:
4 7 9
5 2 1
3 6 8
julia> #view a[:, end:-1:1]
3×3 view(::Matrix{Int64}, :, 3:-1:1) with eltype Int64:
9 7 4
1 2 5
8 6 3
Following up #IainDunning's answer, an important difference between numpy and Julia here is that X[:,end:-1:1] in Julia returns a copy and in numpy X[:,::-1] will return a view of the same data (no copy is made).
I'm just learning Julia myself, but it seems like you can accomplish something similar in Julia using sub(X, :, size(X)[2]:-1:1), which returns Julia's equivalent of a view (SubArray). Interestingly, you can't use the end keyword in this construct as far as I can see, and instead you must pass in the actual end index in the dimension.
You can use the function flipdim(mat, d).
Ref: http://docs.julialang.org/en/release-0.4/stdlib/arrays/
Try this set of functions:
function reverser(x::AbstractArray, dims::AbstractVector{<:Integer})
y = copy(x)
for d in dims
y = reverse(y, dims=d)
end
return y
end
reverser(x::AbstractArray) = reverser(x, 1:ndims(x)) # all dimensions
reverser(x::AbstractArray, d::Integer) = reverser(x, [1])
Julia 1.6 supports reversing any or all of the dimensions of an arbitrary multidimensional array (implemented here). To reverse all of the dimensions, you can simply do reverse(X).

Resources