1

So here's the skinny:

  1. Imagine a Rubik's Cube; it's 3x3x3. I happen to have an array that is a rubik's "cube" only it's 4x4xn. With n starting off as 1

  2. When a certain condition in each 4x4 matrix within the array is true, then the matrix replicates itself; that is n grows by 1 (the array, or rubik's cube gets longer/ becomes a cuboid). Let's say, for each 4x4 matrix within the array, if [2,4] > [2,1], then the matrix replicates another version of itself within the array.

  3. When that same certain condition in each 4x4 matrix within the array is false, then the matrix itself "dies" or erases itself out of existence. The array, or rubik's cube gets shorter. Let's say, for each 4x4 matrix within the array, if [2,4] < [2,1], then the matrix erases itself out of the array.

  4. So I tried to build this into an array, and apparently you can't just add and drop matrices from an array at will.

  5. I've been told you have to build a tensor - (from my conceptual model to what wikipedia says, it looks like this is a 2nd order stress tensor). I'm not a physics guy, and definitely not a math purists. I'm a basic applied mathematics guy (ORSA), but I don't have any kind of degree in that, just a few years experience doing "analysis".

  6. Is it possible for anyone to please demonstrate for me how I might build this structure in R. I hope you understand that finding comprehensible/ conceptual information on how to build a tensor in R of the type I believe I'm writing about is incredibly difficult.

Thank you so very much for whatever assistance you can provide.

I am very grateful for it.

So here's some of what I've tried:

cells<-c(0,.4,0,0,.25,.6,.25,.5,4,12,4,10,20,0,0,0)
Mu<-matrix(cells, 4,4, byrow=TRUE)
Ma<-list(Mu)
for(i in Ma){
    if(i[2,4] > i[2,1]){
       j <-length(Ma) + 1
       c[Ma, j<-Mu]
    }else if(i[2,4] < i[2,1]){
        Ma[[i]] <- NULL
        }
    }
}

This doesn't work.

Jonathan Charlton
  • 1,975
  • 6
  • 23
  • 30
  • Also, as a follow-up question, is the way of finding the max value among the matrices in a certain location[i,j] in an array the same as with a tensor? When I was trying to do this with an array, I did this: 'BEST <- the_array[1, 1:3, which.max(the_array[1, 4, ])]. Would it be any different for the tensor structure?' – Jonathan Charlton May 23 '12 at 03:27
  • Since you want the set of 4*4 matrices to be able to grow and shrink, why not use a list (or an environment) of 4*4 matrices? – Vincent Zoonekynd May 23 '12 at 03:45
  • When I tried to build a list, I found it exceptionally difficult to self replicate based on the conditions of the elements within an element of a list. So let us say there is a matrix as an element within the list, and I want to compare an element within that matrix with another element within that matrix to see if I'm either dropping or replicating that matrix, that is very difficult to do (I'm not saying it's impossible; I'm saying I've tried as many ways under the sun to do it, and R + my limited knowledge of it + my gorilla logic = error) – Jonathan Charlton May 23 '12 at 03:55
  • Vincent, would you happen to know another person who may have asked how to do that on stackoverflow - create an environment/ list of matrices from which one can then access the elements to see if a condition is true? Thank you very much for your help. I will try to build this list in R and show you how I've done that. It's just none of my ways have even come remotely close to achieving what I'm trying to do. – Jonathan Charlton May 23 '12 at 03:59
  • This will be much easier for people to answer if you provide a [reproducible](http://stackoverflow.com/q/5963269/324364) example. – joran May 23 '12 at 04:05
  • see also package `abind` to deal add/extract slices from arrays – baptiste Nov 17 '12 at 22:31

1 Answers1

4

Since you need to be able to add or remove 4*4 matrices from your array, it may be easier to use a list of 4*4 matrices, instead of an array.

# Initial data
d <- replicate(3, matrix(sample(1:16),4,4), simplify=FALSE)
# Remove an element
remove <- function(d, i) {
  d[[i]] <- NULL
  d
}
# Duplicate an element
duplicate <- function(d, i) {
  d <- append(d, list(d[[i]]))
  d
}
# Example
d <- remove(d, 1)
d <- duplicate(d, 2)
d <- remove(d, 1)
d

If performance is an issue (the list is copied again and again), you may prefer to use an environment instead.

# Sample data
d <- replicate(3, matrix(sample(1:16),4,4), simplify=FALSE)
names(d) <- as.character(seq_along(d))
e <- as.environment(d)
# Remove an element
remove <- function(e, i) {
  rm(list=as.character(i), envir=e)
  e
}
# Duplicate an element
duplicate <- function(e, i) {
  stopifnot( length(ls(e)) > 0 )
  j <- max( as.numeric(ls(e)) ) + 1
  assign( as.character(j), get( as.character(i), envir=e ), envir=e )
  e
}
# Example (the elements are named, and their names do not change)
remove(e, 1)
duplicate(e, 3)
remove(e, 2)
as.list(e)

With your conditions for duplication and removal, this becomes:

# Sample data
d <- replicate(3, matrix(sample(1:16),4,4), simplify=FALSE)
names(d) <- as.character(seq_along(d))
e <- as.environment(d)
# Main loop
for(i in ls(e)) {      # i is the name of the matrix
  m <- get(i, envir=e) # The matrix itself
  if(m[2,4] > m[2,1]) {
    cat("Duplicating", i, "\n")
    duplicate(e, i)
  } else {
    cat("Removing", i, "\n")
    remove(e, i)
  }
}
as.list(e)
Vincent Zoonekynd
  • 31,893
  • 5
  • 69
  • 78