0

I am looking for an equivalent of permute(A,dimorder) from Matlab, in order to convert some Matlab code to R. A loop entails a line that looks something like this:

x = permute(a{i}(b(i,ii),:,:,:,:,:),[2 3 4 5 6 1])

The cell array structure e.g. a{1}(1,:,:,:,:,:) results in selecting the first row of matrices within the cell array a{}. [2 3 4 5 6 1] in permute() refers to the dimorder. The documentation for the matlab function permute() including example output can be found here: https://de.mathworks.com/help/matlab/ref/permute.html

There are several functions in R referring to permutation in some way or another, but non of them seemed to be what I am looking for, though I may have gotten something wrong.

7
  • 2
    For base R, aperm: stackoverflow.com/questions/10679131/… Commented Oct 21, 2021 at 12:08
  • @jblood94 Unfortunatly I do not get equivalent results to the matlab code if I use aperm(a[[i]] [b[i,ii],], c(2,3,4,5,6,1)). With abind I do not know how to include the part [2 3 4 5 6 1]. Commented Oct 21, 2021 at 12:23
  • Interesting. The functions are equivalent as far as I can tell. Can you put together a reproducible example? Commented Oct 21, 2021 at 12:30
  • @jbloo94 I added some matlab code to my question that delivers reproducable results. It is a Matlab script I am converting (cut out most of the comments, so it may look a little chaotic, relevant line (loop) is in the lower part). Commented Oct 21, 2021 at 12:43
  • Can you add your R attempt? Commented Oct 21, 2021 at 12:49

1 Answer 1

1

I believe I successfully replicated the MATLAB script in R. I don't think you actually need an equivalent for permute. In the MATLAB script, permute appears to be simply dropping excess dimensions. R does that by default unless you specify drop = FALSE when you subset an array, e.g.,

lnA[[tau, modal]] <- a[[modal]][outcomes[modal, tau],,,drop = FALSE]

If I add lnA = cell(T, NumModalities); to the MATLAB script before your final for loop and then modify the inside of the loop to be

lnA{tau, modal} = permute(a{modal}(outcomes(modal,tau),:,:,:,:,:),[2 3 4 5 6 1]);

Then I get the same array of matrices in lnA for both the MATLAB and R implementations.

In R, I use an array of lists as the equivalent of a MATLAB 2+ dimension cell array:

lnA1 = cell(T, 1); # MATLAB
lnA1 <- vector("list", Time) # R    
lnA2 = cell(T, NumModalities); # MATLAB
lnA2 <- array(vector("list", Time*NumModalities), c(Time, NumModalities)) # R
lnA2 <- matrix(vector("list", Time*NumModalities), Time) # R
lnA3 = cell(T, NumModalities, 2); # MATLAB
lnA3 <- array(vector("list", Time*NumModalities*2), c(Time, NumModalities, 2)) # R

Here's the implementation:

nat_log <- function (x) { # necessary as log(0) not defined...
  x <- log(x + exp(-16))
}

# Set up a list for D and A
D <- list(c(1, 0),       # (left better, right better)
          c(1, 0, 0, 0)) #(start, hint, choose-left, choose-right)
A <- c(rep(list(array(0, c(3, 2, 4))), 2), list(array(0, c(4, 2, 4))))

Ns <- lengths(D) # number of states in each state factor (2 and 4)
A[[1]][,,1:Ns[2]] <- matrix(c(1,1,  # No Hint
                              0,0,  # Machine-Left Hint
                              0,0), # Machine-Right Hint
                      ncol = 2, nrow = 3, byrow = TRUE)

pHA <- 1
A[[1]][,,2] <- matrix(c(0,       0,       # No Hint
                        pHA,     1 - pHA, # Machine-Left Hint
                        1 - pHA, pHA),    # Machine-Right Hint
                      nrow = 3, ncol = 2, byrow = TRUE)

A[[2]][,,1:2] <- matrix(c(1, 1,   # Null
                          0, 0,   # Loss
                          0, 0),  # Win
                        ncol = 2, nrow = 3, byrow = TRUE)

pWin <- 0.8
A[[2]][,,3] <- matrix(c(0,        0,         # Null        
                        1 - pWin, pWin,      # Loss
                        pWin,     1 - pWin), # Win
                      ncol = 2, nrow = 3, byrow = TRUE)

A[[2]][,,4] <- matrix(c(0,        0,        # Null        
                        pWin,     1 - pWin, # Loss
                        1 - pWin, pWin),    # Win
                      ncol = 2, nrow = 3, byrow = TRUE)

for (i in 1:Ns[2]) {
  A[[3]][i,,i] <- c(1,1)
}

# Set up a list of matrices:
a <- lapply(1:3, function(i) A[[i]]*200)
a[[1]][,,2] <- matrix(c(0,    0,     # No Hint
                        0.25, 0.25,  # Machine-Left Hint
                        0.25, 0.25), # Machine-Right Hint
                      nrow = 3, ncol = 2, byrow = TRUE)

outcomes <- matrix(c(1, 2, 1,
                     1, 1, 2,
                     1, 2, 4),
                   ncol = 3, nrow = 3, byrow = TRUE)

NumModalities <- length(a)       # number of outcome factors
Time <- 3L
lnA <- array(vector("list", Time*NumModalities), c(Time, NumModalities))

for (tau in 1:Time){
  for (modal in 1:NumModalities){
    lnA[[tau, modal]] <- a[[modal]][outcomes[modal, tau],,]
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Worked! I implemented this loop to translate my "a" matrix list into the array list: a1 <- c(rep(list(array(0, c(3, 2, 4))), 2), list(array(0, c(4, 2, 4)))) for (i in 1:ncol(A)){ for (ii in 1:nrow(A)){ a1[[ii]][,,i] = a[[ii,i]] } } Called it a1 for differentiating purpose to "a"...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.