How to get product of all elements in a row of matrix in Julia - matrix

I'm using Julia and trying to get a vector p. The elements of p is the multiplying product of all elements in the same row of matrix P. I can do it by using for loops on each row, but is there a more efficient way to do it?
Thanks :)

Sounds like you should be able to do
julia> P = reshape(1:9, 3, 3)
3×3 reshape(::UnitRange{Int64}, 3, 3) with eltype Int64:
1 4 7
2 5 8
3 6 9
julia> prod.(eachrow(P))
3-element Vector{Int64}:
28
80
162

Related

Neighbors in the matrix - algorithm

I have a problem with coming up with an algorithm for the "graph" :(
Maybe one of you would be so kind and direct me somehow <3
The task is as follows:
We have a board of at least 3x3 (it doesn't have to be a square, it can be 4x5 for example). The user specifies a sequence of moves (as in Android lock pattern). The task is to check how many points he has given are adjacent to each other horizontally or vertically.
Here is an example:
Matrix:
1 2 3 4
5 6 7 8
9 10 11 12
The user entered the code: 10,6,7,3
The algorithm should return the number 3 because:
10 is a neighbor of 6
6 is a neighbor of 7
7 is a neighbor of 3
Eventually return 3
Second example:
Matrix:
1 2 3
4 5 6
7 8 9
The user entered the code: 7,8,6,3
The algorithm should return 2 because:
7 is a neighbor of 8
8 is not a neighbor of 6
6 is a neighbor of 3
Eventually return 2
Ofc number of operations equal length of array - 1
Sorry for "ile" and "tutaj", i'm polish
If all the codes are unique, use them as keys to a dictionary (with (row/col) pairs as values). Loop thru the 2nd item in user input to the end, check if math.Abs(cur.row-prev.row)+math.Abs(cur.col-prev.col)==1. This is not space efficient but deal with user input in linear complexity.
The idea is you have 4 conditions, one for each direction. Given any matrix of the shape n,m which is made of a sequence of integers AND given any element:
The element left or right will always be + or - 1 to the given element.
The element up or down will always be + or - m to the given element.
So, if abs(x-y) is 1 or m, then x and y are neighbors.
I demonstrate this in python.
def get_neighbors(seq,matrix):
#Conditions
check = lambda x,y,m: np.abs(x-y)==1 or np.abs(x-y)==m
#Pairs of sequences appended with m
params = zip(seq, seq[1:], [matrix.shape[1]]*(len(seq)-1))
neighbours = [check(*i) for i in params]
count = sum(neighbours)
return neighbours, count
seq = [7,8,6,3]
matrix = np.arange(1,10).reshape((3,3))
neighbours, count = get_neighbors(seq, matrix)
print('Matrix:')
print(matrix)
print('')
print('Sequence:', seq)
print('')
print('Count of neighbors:',count)
Matrix:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
Sequence: [10, 6, 7, 3]
Count of neighbors: 3
Another example -
seq = [7,8,6,3]
matrix = np.arange(1,10).reshape((3,3))
neighbours, count = get_neighbors(seq, matrix)
Matrix:
[[1 2 3]
[4 5 6]
[7 8 9]]
Sequence: [7, 8, 6, 3]
Count of neighbors: 2
So your input is the width of a table, the height of a table, and a list of numbers.
W = 4, H = 3, list = [10,6,7,3]
There are two steps:
Convert the list of numbers into a list of row/column coordinates (1 to [1,1], 5 to [2,1], 12 to [3,4]).
In the new list of coordinates, find consequent pairs, which have one coordinate identical, and the other one has a difference of 1.
Both steps are quite simple ("for" loops). Do you have problems with 1 or 2?

How to put even numbers from matrix in separate vector in Julia?

I am solving some matrix problems in Julia and i need to put numbers that can be divided by 2 (or any other number) from matrix in separate vector. Generally, when I need to separate numbers from matrix that can be divided with 2 or 3 or 4...etc i can't index them properly. Basically, I need Julia equivalent for Matlab command:
vector=matrix(rem(matrix,2)==0)
.
I tried few things mentioned below:
vector=matrix[matrix.%2==0];
vector=(matrix.%2==0);
I expect output to be vector of numbers that can be divided with certain number but in first case I get errors and in second I only get "true" or "false".
This is my first post, so sorry if I made any mistakes or broke any rules.
Thanks in advance!
First of all, welcome to stackoverflow!
One way to get what you want, that you almost got right, is the following:
julia> M = rand(1:10, 3,3)
3×3 Array{Int64,2}:
3 10 7
6 7 8
2 10 6
julia> v = M[M .% 2 .== 0]
6-element Array{Int64,1}:
6
2
10
10
8
6
Note the extra dot in .== which applies the equality comparison elementwise.
A faster version would be to use findall:
julia> M[findall(x->x%2==0, M)]
6-element Array{Int64,1}:
6
2
10
10
8
6
Here, x->x%2==0 is a anonymous function representing the find criterium. In the special case x%2==0 this can simply be replaced by iseven:
julia> M[findall(iseven, M)]
6-element Array{Int64,1}:
6
2
10
10
8
6
You can also utilize array-comprehensions to get what you want as well, which should be even faster:
julia> [x for x in M if iseven(x)]
6-element Array{Int64,1}:
6
2
10
10
8
6
Finally, perhaps the most idomatic option, is to use filter:
julia> filter(iseven, M)
6-element Array{Int64,1}:
6
2
10
10
8
6

How can I subtract columns from a 2D array of JULIA?

I'm new to julia and I have a problem.
I am working with Julia (Jupyter notebook) and I do not know how can I do column 3 - column 2 and write the result as a new column at the end of the matrix/array2D.
I have tried this:
newCol = array[(1:end),3] - array[(1:end),2]
Any suggestion?
You can subtract the two columns and then concatenate it with the original array using the normal build-an-array syntax:
julia> arr
2x3 Array{Int32,2}:
1 2 3
5 6 7
julia> [arr [arr[:,3] - arr[:,2]]]
2x4 Array{Int32,2}:
1 2 3 1
5 6 7 1
Or use hcat:
julia> hcat(arr,arr[:,3] - arr[:,2])
2x4 Array{Int32,2}:
1 2 3 1
5 6 7 1
(Note that neither of these act in place, so you'd need to assign the result somewhere if you want to use it later.)

matlab for loop: fastest and most efficient method to reproduce large matrix

My data is a 2096x252 matrix of double values. I need a for loop or an equivalent which performs the following:
Each time the matrix is reproduced the first array is deleted and the second becomes the first. When the loop runs again, the remaining matrix is reproduced and the first array is deleted and the next becomes the first and so on.
I've tried using repmat but it is too slow and tedious when dealing with large matrices (2096x252).
Example input:
1 2 3 4
3 4 5 6
3 5 7 5
9 6 3 2
Desired output:
1 2 3 4
3 4 5 6
3 5 7 5
9 6 3 2
3 4 5 6
3 5 7 5
9 6 3 2
3 5 7 5
9 6 3 2
9 6 3 2
Generally with Matlab it is much faster to pre-allocate a large array than to build it incrementally. When you know in advance the final size of the large array there's no reason not to follow this general advice.
Something like the following should do what you want. Suppose you have an array in(nrows, ncols); then
indices = [0 nrows:-1:1];
out = zeros(sum(indices),ncols);
for ix = 1:nrows
out(1+sum(indices(1:ix)):sum(indices(1:ix+1)),:) = in(ix:end,:);
end
This worked on your small test input. I expect you can figure out what is going on.
Whether it is the fastest of all possible approaches I don't know, but I expect it to be much faster than building a large matrix incrementally.
Disclaimer:
You'll probably have memory issues with large matrices, but that is not the question.
Now, to the business:
For a given matrix A, the straightforward approach with the for loop would be:
[N, M] = size(A);
B = zeros(sum(1:N), M);
offset = 1;
for i = 1:N
B(offset:offset + N - i, :) = A(i:end, :);
offset = offset + size(A(i:end, :), 1);
end
B is the desired output matrix.
However, this solution is expected to be slow as well, because of the for loop.
Edit: preallocated B instead of dynamically changing size (this optimization should achieve a slight speedup).

How to get the mean of rows of a matrix in Octave?

>> a = [2,3,4;6,7,8]
a =
2 3 4
6 7 8
>> mean(a)
ans =
4 5 6
where [4 5 6] is the mean for each column
How can I get the mean for each row?
In my example, I would expect [3;7]
From http://www.mathworks.co.uk/help/techdoc/ref/mean.html:
For matrices, mean(A,2) is a column vector containing the mean value of each row.
In Octave it's the same.
Alternatively to the other answer, you can simply use the transpose feature
>> a'
ans =
2 6
3 7
4 8
>> mean(a')
ans =
3 7
I suggest this answer over the other because it works for any row based octave function (max , min , sum , etc)
You can do
mean (a, 2)
returns : [3; 7]
Trick is the 2nd parameter specifies along which dimension you want mean. 1 is default ("Column").

Resources