subtract the different dimensional arrays in R - arrays

Let A and B be arrays, of dimension [2,3,4] and [100,2], respectively. Note that 2 is the common dimension.
My desired answer is an array C of dimension [100,2,3,4] such that
C[h,i,j,k] = A[i,j,k] - B[h,i]
for all h,i,j,k.
Or
C[h,i,j,k] = A[i,j,k] + B[h,i]
for all h,i,j,k.
The later case is more easy to check the answer using the following example arrays.
E.g.,
A <- array(NA,c(2,3,4))
for (i in 1:2) {for(j in 1:3){for(k in 1:4){
A[i,j,k] <- i*1000000+j*100000+k*10000
}}}
B <- array(NA,c(100,2))
for (h in 1:100) {for(i in 1:2){B[h,i] <- h*10+i }}

How about this
C <- array(NA, c(dim(B)[1], dim(A)))
# Approach 1
for (h in 1 : dim(B)[1])
for(i in 1 : dim(A)[1])
C[h, i,, ] <- A[i,, ] - B[h, i]
# Approach 2
for (h in 1 : dim(B)[1])
C[h,,,] <- sweep(A, 1, B[h, ], "-")
To check if the answer is correct, pick some values for h, i, j, k
i <- 1; j <- 2; k <- 3; h <- 50
C[h, i, j, k]
#[1] 2338998
A[i,j,k] - B[h,i]
#[1] 2338998

Related

Maximum Sum of elements of array which is not divisible by M, deleting/avoiding at most K consequtive array elements

Given: N, K, M and A(array)
N = No. of elements in the array
K = Maximum consequtive array elements that can be avoided/not considered in the answer
|A| = N
Starting from the last index of the array, you have to find the maximum sum that can be obtained by using the elements of the array, such that at any instant the sum is not divisibe by M. The sum can be aquired by traversing from the last index to the first index of the array (in order), and you have a choice to either include that element into the final answer, or avoid it.
There are two conditions :
When an item is included, the total sum of all elements included till that moment (including the current element that is being included), should not be divisible by M.
When an item is avoided, it has to be kept in mind that you can avoid at most K consequtive array elements at once.
Note : It is strictly required to start from the last index, and skipping any index will count towards the limit on the maximum consequtive elements that can be avoided (i.e K).
If there exists no way to traverse from the last index to the first index by satisfying the two conditions at all instances of the traversal, we have to return back -1, or else return back the maximum sum possible.
Constraints :
2 <= N <= 10^5
1 <= K <= 10
1 <= M <= 20
Example 1 :
N = 5
K = 1
M = 2
A = [1, 2, 3 ,4, 5]
Output : 5 + 4 + 2 = 11
Example 2 :
N = 5
K = 2
M = 2
A = [3, 4, 2, 6, 8]
Output = -1
Example 3 :
N = 7
K = 2
M = 2
A = [1,4,2,6,3,7,7]
Output : 7 + 6 + 2 + 4 = 19
We can do 3-D dynamic programming to solve this, very similarly to the other post. Here's the definition of the formula I'm using:
Let dp[i][k][r], 0 <= i < N, 0 <= k <= K, 0 <= r < M
be the maximum valid sum achievable after processing indices [i, i+1, ..., N-1]
such that index i is our kth consecutive skip and the sum's remainder is r (mod M).
We want max(dp[0][_][_])
dp[i][k][r] = -INF if k + i > N
= -INF if r == 0 and k + i /= N
= -INF if r /= 0 and k + i == N
= 0 if r == 0 and k + i == N
= dp[i+1][k-1][r] if k > 0 and r /= 0
= A[i] + max(dp[i+1][j][(r-A[i]) % M] over all j), if k == 0
The formula is quite long, due to the fact that the initial empty sum of 0 (which is technically divisible by M) is allowed but all others are not. There's also an initial value of the formula not included above: if A[N-1] (the last element) is not divisible by M, then dp[N-1][0][A[N-1]%M] is A[N-1]. You can shorten this formula by two lines, but you do have at least 4 distinct patterns to match.
The time and space complexity are O(NMK), but the space complexity can be reduced to O(MK) by only ever storing the last two rows of your DP table.
Here's a Python computation of that DP formula:
def f(A: List[int], N: int, K: int, M: int) -> int:
assert N == len(A)
if M == 1:
return -1
dp = [[[-math.inf for _ in range(M)] for _ in range(K + 1)] for _ in range(N)]
for i in range(N):
k = N - i
if 0 <= k <= K:
dp[i][k][0] = 0
if A[N - 1] % M != 0:
dp[N - 1][0][A[N - 1] % M] = A[N - 1]
for i in reversed(range(N - 1)):
elem = A[i]
# When k == 0
for r in range(1, M):
for j in range(K + 1):
dp[i][0][r] = max(dp[i][0][r], elem + dp[i + 1][j][(r - elem) % M])
# When k > 0
for k in range(1, K + 1):
for r in range(1, M):
dp[i][k][r] = dp[i + 1][k - 1][r]
ans = max([max(x) for x in dp[0]])
return ans if math.isfinite(ans) else -1
If you'd like to test this code and other answers, plus a slow brute force solution, here's an online code-runner

Product of two 3D array and a 2D matrix

I'm trying to find a much more efficient way to code in R the following matrix:
Let A and C be two 3D array of dimension (n, n, m) and B a matrix of dimension (m, m), then M is an (n, n) matrix such that:
M_ij = SUM_kl A_ijk * B_kl * C_ijl
for (i in seq(n)) {
for (j in seq(n)) {
M[i, j] <- A[i,j,] %*% B %*% C[i,j,]
}
}
It is possible to write this with the TensorA package using i and j as parallel dimension, but I'd rather stay with base R object.
einstein.tensor(A %e% log(B), C, by = c("i", "j"))
Thanks!
I don't know if this would be faster, but it would avoid one level of looping:
for (i in seq(n))
M[i,] <- diag(A[i,,] %*% B %*% t(C[i,,]))
It gives the same answer as yours in this example:
n <- 2
m <- 3
A <- array(1:(n^2*m), c(n, n, m))
C <- A + 1
B <- matrix(1:(m^2), m, m)
M <- matrix(NA, n, n)
for (i in seq(n))
M[i,] <- diag(A[i,,] %*% B %*% t(C[i,,]))
M
# [,1] [,2]
# [1,] 1854 3216
# [2,] 2490 4032
Edited to add: Based on https://stackoverflow.com/a/42569902/2554330, here's a slightly faster version:
for (i in seq(n))
M[i,] <- rowSums((A[i,,] %*% B) * C[i,,])
I did some timing with n <- 200 and m <- 300, and this was the fastest at 3.1 sec, versus my original solution at 4.7 sec, and the one in the question at 17.4 sec.

Block diagonal matrix from columns

Suppose I have an m x n matrix A .
Is there a way to create B, a (n x m) x n matrix whose "diagonal" is formed by A's columns ?
Example:
A = [1 2;
3 4]
B = [1 0;
3 0;
0 2;
0 4]
Here is a way:
Convert A to a cell array of its columns, using mat2cell;
From that cell array generate a comma-separated list, and use it as an input to blkdiag.
Code:
A = [1 2; 3 4]; %// example data
C = mat2cell(A, size(A,1), ones(1,size(A,2))); %// step 1
B = blkdiag(C{:}); %// step 2
This produces
B =
1 0
3 0
0 2
0 4
Here is a short script to accomplish this. It works for any dimensions of A.
A=[1 2; 3 4];
[R C] = size(A);
for i=1:C
B( 1+R*(i-1) : R*i , i ) = A(:,i);
end

matrix addition from an array r

I have an array with 272 matrices, each one is 2 by 2. I now want to sum these matrices up using matrix addition. So I want the return to be a single 2 by 2 matrix. Here are some code I have used.
y <- as.matrix(faithful)
B <- matrix(c(0,0,0,0),nrow = 2)
sigma <- function(n = 272,u_new) {
vec = replicate(272,B)
for (i in 1:n) {
w <- (y-u_new)[i,]
x <- ptilde1[i]*(w%*%t(w))
vec[,,i][1,1] <- x[1,1]
vec[,,i][1,2] <- x[1,2]
vec[,,i][2,1] <- x[2,1]
vec[,,i][2,2] <- x[2,2]}
vec
}
Here vec is the array with 272 matrices. Thank you in advance.
Here is code which loops a number of times (272) and adds a matrix to the same list.
B <- matrix(c(0,0,0,0),nrow = 2)
list <- list(B)
for (i in 2:272) {
list[[i]] <- B
}
To add them all together, you can use the Reduce() function:
sum <- Reduce('+', list)
> sum
[,1] [,2]
[1,] 0 0
[2,] 0 0
This is a contrived example because all the matrices are the zero matrix. I will leave it to you as a homework assignment to use the matrices you actually want to sum together.

while and return in a loop (Haskell) [duplicate]

This question already has answers here:
While in a loop in Haskell
(2 answers)
Closed 7 years ago.
How to code the following pseudo-code elegantly in Haskell?
for (i from 0 to 100):
for (j from 0 to 100):
k=0
while ( f(i,j,k) >0 ):
return (i,j,k)
k+=1
where f is an unimportant function of i,jand k.
So it should output something like this: [(0,0,0),(0,0,1)..], a list with each element a tuple formed by i,jandk. (It's fine if it were of the form [[0,0,0],[0,0,1]...] instead of tuples.)
Assuming with return you actually mean Python-like yield, otherwise the algorithm wouldn't make sense.
Using do notation, this is very straightforward:
do
i <- [0..100]
j <- [0..100]
k <- takeWhile (\k -> f i j k > 0) [0..]
return (i, j, k)
Untested:
[ (i,j,k) |
i <- [0 .. 100],
j <- [0 .. 100],
k <- takeWhile (\k -> f i j k > 0) [0 ..] ]
This is a list comprehension that loops over i/j in the obvious way, and uses takeWhile to limit k by the result of f.

Resources