How to obtain efficiently a matrix that adds all elements up to/from (i,j) in Julia - matrix

P is a given matrix (i.g., 2-dimensional array). The size of P is I×J.
I want to have two matrices, A and B, such that
The sizes of A and B are the same as the size of P.
Then, I wrote the following code in Julia 1.6.
f(P) = cumsum(cumsum(P,dims=1),dims=2)
g(P) = f( reverse!(reverse!(P,dims=1),dims=2))[end:-1:begin,end:-1:begin]
It works. Here is an example.
P = rand(1:6,3,4)
#3×4 Matrix{Int64}:
# 4 1 1 4
# 2 2 6 6
# 3 1 5 2
f(P)
#3×4 Matrix{Int64}:
# 4 5 6 10
# 6 9 16 26
# 9 13 25 37
g(P)
#3×4 Matrix{Int64}:
# 37 28 24 12
# 27 22 19 8
# 11 8 7 2
Does anybody have a better idea? If there is a faster method, I'd like to know.
Context
I want to expand the above functions f and g to tensors, that it, P is a tensor (i.g., d-dimensional array) whose size is I1×…×Id. I want to make two arrays, A and B, such that

Related

Julialang: In-place sort for columns of a matrix

I have a huge matrix and want to sort the columns in place for speed/memory efficency. Is it possible to use in-place sort for the columns of a matrix in Julia?
As an example, take the following matrix:
julia> M=Matrix{Int}(3,3);
julia> for i = 1:size(M)[1]
for j = 1:size(M)[2]
M[i,j]=3*(j-1)+i
end
end
julia> M
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
I want to use in-place sort for the columns to obtain the matrix
3×3 Array{Int64,2}:
3 6 9
2 5 8
1 4 7
This can be obtained without in-place sort as follows:
julia> M_sorted=Matrix{Int}(3,3);
julia> for j = 1:size(M)[2]
M_sorted[:,j]=sort(M[:,j],rev=true)
end
julia> M_sorted
3×3 Array{Int64,2}:
3 6 9
2 5 8
1 4 7
But something like that fails (here only for one column):
julia> sort!(M[:,1],rev=true)
3-element Array{Int64,1}:
3
2
1
julia> M
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
Is there any way to use in-place sort in this case? Note that there is no problem with the indexing since the matrix is saved column-wise in memory:
julia> M[1:end]
9-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
So I think it should be possible.
Slicing creates a copy of the column and sorts on that. If you instead want to directly sort in the memory of the existing array, use a view. Example:
M=Matrix{Int}(undef,3,3)
for i = 1:size(M)[1]
for j = 1:size(M)[2]
M[i,j]=3*(j-1)+i
end
end
M
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
sort!(#view(M[:,1]),rev=true)
M
3×3 Array{Int64,2}:
3 4 7
2 5 8
1 6 9

Take out elements from a vector that meets certain condition

I have two vectors, A = [1,3,5] and B = [1,2,3,4,5,6,7,8,9,10]. I want to get C=[2,4,6,7,8,9,10] by extracting some elements from B that A doesn't have.
I don't want to use loops, because this is a simplified problem from a real data simulation. In the real case A and B are huge, but A is included in B.
Here are two methods,
C=setdiff(B,A)
but if values are repeated in B they will only come up once in C, or
C=B(~ismember(B,A))
which will preserve repeated values in B.
One approach with unique, sort and diff -
C = [A B];
[~,~,idC] = unique(C);
[sidC,id_idC] = sort(idC);
start_id = id_idC(diff([0 sidC])==1);
out = C(start_id(start_id>numel(A)))
Sample runs -
Case #1 (Sample from question):
A =
1 3 5
B =
1 2 3 4 5 6 7 8 9 10
out =
2 4 6 7 8 9 10
Case #2 (Bit more generic case):
A =
11 15 14
B =
19 14 6 8 9 11 15
out =
6 8 9 19

matrix exponentiation in linear recursion algorithm

I am trying to do http://www.spoj.com/problems/FIBTWIST/ problem by linear recursion. However, since the constraints are large I have to use matrix exponentiation.
I have read http://zobayer.blogspot.in/2010/11/matrix-exponentiation.html
so according to it equations formed are
ft(n)=ft(n-1)+ft(n-2)+g(n) ft(0)=0, ft(0)=1
g(n) =g(n-1)+1 g(1)=0
But now I am confused how to form matrices A and B of the form A*M=B. It is given as Type 7 in mentioned blogspot link but I am having difficulty in understanding it.
Define a third sequence, fut, Fibonacci-untwist, as
fut(n)=ft(n)+(n+2).
Then
fut(n)=ft(n)+n+1=ft(n-1)+ft(n-2)+(n-1)+(n+2)=fut(n-2)+fut(n-1)
So fut is just another solution of the Fibonacci recursion, and thus
fut(n)=f(n-1)*fut(0)+f(n)*fut(1)=2*f(n-1)+4*f(n)=2*f(n)+2*f(n+1)=2*f(n+2)
and finally
ft(n)=2*f(n+2)-(n+2)
Test:
f(n): 0 1 1 2 3 5 8 13 21 34
2*f(n+2): 2 4 6 10 16 26 42 68
n+2: 2 3 4 5 6 7 8 9
ft(n): 0 1 2 5 10 19 34 59
and really, the last row is the difference of the second and third row.

Cumulative Maxima as Indicated by X in APL

The third item in the FinnAPL Library is called “Cumulative maxima (⌈) of subvectors of Y indicated by X ” where X is a binary vector and Y os a vector of numbers. Here's an example of its usage:
X←1 0 0 0 1 0 0 0
Y←9 78 3 2 50 7 69 22
Y[A⍳⌈\A←⍋A[⍋(+\X)[A←⍋Y]]] ⍝ output 9 78 78 78 50 50 69 69
You can see that beginning from either the beginning or from any 1 value in the X array, the cumulave maximum is found for all corresponding digits in Y until another 1 is found in X. In the example given, X is divding the array into two equal parts of 4 numbers each. In the first part, 9 is the maxima until 78 is encountered, and in the second part 50 is the maxima until 69 is encountered.
That's easy enough to understand, and I could blindly use it as is, but I'd like to understand how it works, because APL idioms are essentially algorithms made up of operators and functions. To understand APL well, it's important to understand how the masters were able to weave it all together into such compact and elegant lines of code.
I find this particular idiom especially hard to understand because of the indexing nested two layers deep. So my question is, what makes this idiom tick?
This idiom can be broken down into smaller idioms, and most importantly, it contains idiom #11 from the FinnAPL Library entitled:
Grade up (⍋) for sorting subvectors of Y indicated by X
Using the same values for X and Y given in the question, here's an example of its usage:
X←1 0 0 0 1 0 0 0
Y←9 78 3 2 50 7 69 22
A[⍋(+\X)[A←⍋Y]] ⍝ output 4 3 1 2 6 8 5 7
As before, X is dividing the vector into two halves, and the output indicates, for each position, what digit of Y is needed to sort each of the halves. So, the 4 in the output is saying that it needs the 4th digit of Y (2) in the 1st position; the 3 indicates the 3rd digit (3) in the 2nd position; the 1 indicates the 1st digit (9) in the third position; etc. Thus, if we apply this indexing to Y, we get:
Y[A[⍋(+\X)[A←⍋Y]]] ⍝ output 2 3 9 78 7 22 50 69
In order to understand the indexing within this grade-up idiom, consider what is happening with the following:
(+\X)[A←⍋Y] ⍝ Sorted Cumulative Addition
Breaking it down step by step:
A←⍋Y ⍝ 4 3 6 1 8 5 7 2
+\X ⍝ 1 1 1 1 2 2 2 2
(+\X)[A←⍋Y] ⍝ 1 1 2 1 2 2 2 1 SCA
A[⍋(+\X)[A←⍋Y]] ⍝ 4 3 1 2 6 8 5 7
You can see that sorted cumulative addition (SCA) of X 1 1 2 1 2 2 2 1 applied to A acts as a combination of compress left and compress right. All values of A that line up with a 1 are moved to the left, and those lining up with a 2 move to the right. Of course, if X had more 1s, it would be compressing and locating the compressed packets in the order indicated by the values of the SCA result. For example, if the SCA of X were like 3 3 2 1 2 2 1 1 1, you would end up with the 4 digits corresponding to the 1s, followed by the 3 digits corresponding to the 2s, and finally, the 2 digits corresponding to the 3s.
You may have noticed that I skipped the step that would show the effect of grade up ⍋:
(+\X)[A←⍋Y] ⍝ 1 1 2 1 2 2 2 1 SCA
⍋(+\X)[A←⍋Y] ⍝ 1 2 4 8 3 5 6 7 Grade up
A[⍋(+\X)[A←⍋Y]] ⍝ 4 3 1 2 6 8 5 7
The effect of compression and rearrangement isn't accomplised by SCA alone. It effectively acts as rank, as I discussed in another post. Also in that post, I talked about how rank and index are essentially two sides of the same coin, and you can use grade up to switch between the two. Therefore, that is what is happening here: SCA is being converted to an index to apply to A, and the effect is grade-up sorted subvectors as indicated by X.
From Sorted Subvectors to Cumulative Maxima
As already described, the result of sorting the subvectors is an index, which when applied to Y, compresses the data into packets and arranges those packets according to X. The point is that it is an index, and once again, grade up is applied, which converts indexes into ranks:
⍋A[⍋(+\X)[A←⍋Y]] ⍝ 3 4 2 1 7 5 8 6
The question here is, why? Well, the next step is applying a cumulative maxima, and that really only makes sense if it is applied to values for rank which represent relative magnitude within each packet. Looking at the values, you can see that 4 is is the maxima for the first group of 4, and 8 is for the second group. Those values correspond to the input values of 78 and 69, which is what we want. It doesn't make sense (at least in this case) to apply a maxima to index values, which represent position, so the conversion to rank is necessary. Applying the cumulative maxima gives:
⌈\A←⍋A[⍋(+\X)[A←⍋Y]] ⍝ 3 4 4 4 7 7 8 8
That leaves one last step to finish the index. After doing a cumulative maxima operation, the vector values still represent rank, so they need to be converted back to index values. To do that, the index-of operator is used. It takes the value in the right argument and returns their position as found in the left argument:
A⍳⌈\A←⍋A[⍋(+\X)[A←⍋Y]] ⍝ 1 2 2 2 5 5 7 7
To make it easier to see:
3 4 2 1 7 5 8 6 left argument
3 4 4 4 7 7 8 8 right argument
1 2 2 2 5 5 7 7 result
The 4 is in the 2nd position in the left argument, so the result shows a 2 for every 4 in the right argument. The index is complete, so applying it to Y, we get the expected result:
Y[A⍳⌈\A←⍋A[⍋(+\X)[A←⍋Y]]] ⍝ 9 78 78 78 50 50 69 69
My implementation:
X←1 0 0 0 1 0 0 0
Y←9 78 3 2 50 7 69 22
¯1+X/⍳⍴X ⍝ position
0 4
(,¨¯1+X/⍳⍴X)↓¨⊂Y
9 78 3 2 50 7 69 22 50 7 69 22
(1↓(X,1)/⍳⍴X,1)-X/⍳⍴X ⍝ length
4 4
(,¨(1↓(X,1)/⍳⍴X,1)-X/⍳⍴X)↑¨(,¨¯1+X/⍳⍴X)↓¨⊂Y
9 78 3 2 50 7 69 22
⌈\¨(,¨(1↓(X,1)/⍳⍴X,1)-X/⍳⍴X)↑¨(,¨¯1+X/⍳⍴X)↓¨⊂Y
9 78 78 78 50 50 69 69
∊⌈\¨(,¨(1↓(X,1)/⍳⍴X,1)-X/⍳⍴X)↑¨(,¨¯1+X/⍳⍴X)↓¨⊂Y
9 78 78 78 50 50 69 69
Have a nice day.

Summation of difference between matrix elements

I am in the process of building a function in MATLAB. As a part of it I have to calculate differences between elements in two matrices and sum them up.
Let me explain considering two matrices,
1 2 3 4 5 6
13 14 15 16 17 18
and
7 8 9 10 11 12
19 20 21 22 23 24
The calculations in the first row - only four elements in both matrices are considered at once (zero indicates padding):
(1-8)+(2-9)+(3-10)+(4-11): This replaces 1 in initial matrix.
(2-9)+(3-10)+(4-11)+(5-12): This replaces 2 in initial matrix.
(3-10)+(4-11)+(5-12)+(6-0): This replaces 3 in initial matrix.
(4-11)+(5-12)+(6-0)+(0-0): This replaces 4 in initial matrix. And so on
I am unable to decide how to code this in MATLAB. How do I do it?
I use the following equation.
Here i ranges from 1 to n(h), n(h), the number of distant pairs. It depends on the lag distance chosen. So if I choose a lag distance of 1, n(h) will be the number of elements - 1.
When I use a 7 X 7 window, considering the central value, n(h) = 4 - 1 = 3 which is the case here.
You may want to look at the circshfit() function:
a = [1 2 3 4; 9 10 11 12];
b = [5 6 7 8; 12 14 15 16];
for k = 1:3
b = circshift(b, [0 -1]);
b(:, end) = 0;
diff = sum(a - b, 2)
end

Resources