0
mat <- large matrix
f1 <- function(M) {
    X <<- M
    f1 <- function() {
        do something with X but does not modify it 
    }
}
f1(mat)
X is no longer in scope

How does one achieve what is described in the pseudocode above in R? In MATLAB, you can use "global X". What is the equivalent in R? If there is none, what is the most efficient way to deal with the scenario above: a function takes in a large matrix as an argument and many different helper function within it act on that matrix (but do not modify it) thus the matrix needs to be copied as few times as possible. Thanks for your help.

David Wang
  • 87
  • 1
  • 5
  • what kind of operations are you performing on X? you might need something that "changes by reference" if you do not want R to copy the matrix repeatedly – chinsoon12 Feb 20 '18 at 03:13
  • The inner functions should already have access to `M`, due to lexical scoping, so I'm not sure what the `X <<-` assignment would achieve. Also, R already tries not to copy unless it's necessary, so I'm not sure how big a problem this actually is, see [discussion here](https://stackoverflow.com/a/15764949/1222578). – Marius Feb 20 '18 at 03:21
  • @Marius What about inner, inner functions? The inner inner function would not see X if I use X <- but it will if I use X <<-. The inner function, like you said, sees to behave that way. Also, if R is truly copy-on-modify, why does this happen? library(pryr) \n mat <- matrix(1,ncol=100,nrow=100) \n f1 <- function(M) {address(M)} \n address(mat) \n "0x146d0698" \n f1(mat) \n "0x6b97040". The addresess are different – David Wang Feb 20 '18 at 03:38
  • I also would like to mention that my function requires gpu support so I'm using vclMatrix from gpuR. These matrices sit in GPU RAM, so I absolutely cannot copy it even once after the GPU matrix has been made or the memory is going to get really clogged up. – David Wang Feb 20 '18 at 03:45
  • I might be wrong but I think R is actually not making a copy of the object if you pass it as a parameter and don't modify it. If it does you can use `data.tables` and then it won't. – moodymudskipper Feb 20 '18 at 10:46

1 Answers1

0

I am not sure what you'd like to achieve with your helper functions, but as @Marius mentioned in the comment, the inner functions should already have access to M. Hence codes like this would work:

f1 <- function(M) {
  f2 <- function() {
    f3 <- function() {
      # f3 divides M by 2
      M/2
    }
    # f2 prints results from f3 and also times M by 2
    print(f3())
    print(M * 2)
  }
  # f1 returns results from f2
  return(f2())
}

mat <- matrix(1:4, 2)

f1(mat)
#      [,1] [,2]
# [1,]  0.5  1.5
# [2,]  1.0  2.0
#      [,1] [,2]
# [1,]    2    6
# [2,]    4    8

mat
#      [,1] [,2]
# [1,]    1    3
# [2,]    2    4

There's no need to do X <<- M in f1 here, especially if you don't want a copy of M in memory.

ytu
  • 1,822
  • 3
  • 19
  • 42