Search code examples
rarraysalgorithmperformancegradient

How to calculate the gradient of an n-dimensional array of data in R


I feel like there must be some function in some package that does this, but for the life of me I cannot find one that calculates the gradient of an array of data points (not a function) by simply doing central differences centered on each data point.

Here's an example where I generate a 5x5x5 grid of data points with known x, y, and z coordinates, and calculate the gradient using central differences for the point 3,3,3:

response_data <- array(NA, dim = c(5,5,5))
for(i in 1:dim(response_data)[1]) {
  for(j in 1:dim(response_data)[2]) {
    for(k in 1:dim(response_data)[3]) {
      response_data[i,j,k] <- i*j*k
    }
  }
}
  
x_values <- 1:5
y_values <- 1:5
z_values <- 1:5

#Central difference at 3,3,3:
partial_x <- (response_data[4, 3, 3] - response_data[2, 3, 3])/
  (x_values[4] - x_values[2])
partial_y <- (response_data[3, 4, 3] - response_data[3, 2, 3])/
  (y_values[4] - y_values[2])
partial_z <- (response_data[3, 3, 4] - response_data[3, 3, 2])/
  (z_values[4] - z_values[2])

That's fairly straightforward. What I'm looking for is a function that can do so for all the points in the input dataset (or all the non-edge points at least), for an arbitrarily n-dimensional dataset.

Edit: pracma::gradient can do this for a 1- or 2-dimensional array. Still looking for one that can handle n-dimensional arrays

Edit 2: I was able to write code to calculate the gradient for a 3-dimensional array. It feels like there should be a straightforward way to loop through the dimensions for an arbitrarily n-dimensional array, but I'm not sure how to choose the dimension dynamically

response_data <- array(NA, dim = c(5,5,5))
for(i in 1:dim(response_data)[1]) {
  for(j in 1:dim(response_data)[2]) {
    for(k in 1:dim(response_data)[3]) {
      response_data[i,j,k] <- i*j*k
    }
  }
}

#Put all coordinates into one list
coord_vals <- list(x_values = 1:5, y_values = 1:5, z_values = 1:5)

#Create empty array to hold partial derivatives
# (each list is partial derivatives wrt that pred variable)
pds <- rep(list(array(NA, dim = sapply(coord_vals, length))),
           length(pred_vars))
names(pds) <- names(coord_vals)

#Calculate gradient
#First dimension
dimension <- 1
for(j in 1:length(coord_vals[[2]])) {
  for(k in 1:length(coord_vals[[3]])) {
    pds[[dimension]][ , j, k] <- 
      pracma::gradient(F = response_data[, j, k],
                       h1 = coord_vals[[dimension]])
  }
}
#Second dimension
dimension <- 2
for(i in 1:length(coord_vals[[1]])) {
  for(k in 1:length(coord_vals[[3]])) {
    pds[[dimension]][i, , k] <- 
      pracma::gradient(F = response_data[i, , k],
                       h1 = coord_vals[[dimension]])
  }
}
#Third dimension
dimension <- 3
for(i in 1:length(coord_vals[[1]])) {
  for(j in 1:length(coord_vals[[2]])) {
    pds[[dimension]][i, j, ] <- 
      pracma::gradient(F = response_data[i, j, ],
                       h1 = coord_vals[[dimension]])
  }
}

Solution

  • If you don't want to import utilities from Python environments but would like to stay with R only, you can customize a recursive function to compute the N-dim matrix gradient, where pracma::gradient can be applied as an "atom" helper function.

    For example, you can design your function like below

    library(pracma)
    f <- function(arr, coords) {
      if (is.null(dim(arr))) {
        return(gradient(arr, coords[[1]]))
      }
      idx <- seq_along(dim(arr))
      lapply(idx, \(k) apply(arr, k, \(x) f(x, coords[-k]), simplify = FALSE))
    }
    
    • Example 1 With 2-D matrix arr and its coordinates coords
    set.seed(0)
    dims <- c(3, 4)
    arr <- array(rnorm(prod(dims)), dims)
    coords <- lapply(setNames(dims, seq_along(dims)), \(x) seq.int(x) / x)
    

    you will obtain

    > f(arr, coords)
    [[1]]
    [[1]][[1]]
    [1]  0.03790015 -4.38304264  2.26444813 13.33288169
    
    [[1]][[2]]
    [1] 2.96349918 0.06302583 0.69790405 4.23325563
    
    [[1]][[3]]
    [1] -11.478997  -2.671133   1.481882  -3.172968
    
    
    [[2]]
    [[2]][[1]]
    [1] -4.7675629  0.1002675  4.9680979
    
    [[2]][[2]]
    [1] -2.573364 -4.218569 -5.863774
    
    [[2]][[3]]
    [1] 1.9015398 1.3841998 0.8668598
    
    [[2]][[4]]
    [1] -4.923180 -4.805494 -4.687808
    
    • Example 2

    With 3-D matrix arr and its coordinates coords

    dims <- c(3, 4, 5)
    arr <- array(rnorm(prod(dims)), dims)
    coords <- lapply(setNames(dims, seq_along(dims)), \(x) seq.int(x) / x)
    

    you will obtain

    > f(arr, coords)
    [[1]]
    [[1]][[1]]
    [[1]][[1]][[1]]
    [[1]][[1]][[1]][[1]]
    [1] -12.0530565  -3.3001526   5.3495434   2.2228848  -0.8005662
    
    [[1]][[1]][[1]][[2]]
    [1] -8.4197008 -4.9084579  0.3304114  0.7856278 -0.4867822
    
    [[1]][[1]][[1]][[3]]
    [1]  6.8212517  1.7321512 -2.2211682  0.4520727  1.9895325
    
    [[1]][[1]][[1]][[4]]
    [1] -10.136289  -7.635313  -3.607466   1.192120   4.464835
    
    
    [[1]][[1]][[2]]
    [[1]][[1]][[2]][[1]]
    [1]  0.03790015 -4.38304264  2.26444813 13.33288169
    
    [[1]][[1]][[2]][[2]]
    [1]  2.9445847  3.1666806  1.5778130 -0.2331506
    
    [[1]][[1]][[2]][[3]]
    [1] -2.53538826 -0.35719956  0.08296439 -1.65506036
    
    [[1]][[1]][[2]][[4]]
    [1] -5.086027 -2.889889 -1.572489 -2.451226
    
    [[1]][[1]][[2]][[5]]
    [1] -4.8349994 -1.7738492  0.4081584 -0.4709841
    
    
    
    [[1]][[2]]
    [[1]][[2]][[1]]
    [[1]][[2]][[1]][[1]]
    [1]  0.1838589  2.0746033 -0.3501288 -1.8273417  1.0109221
    
    [[1]][[2]][[1]][[2]]
    [1] -0.8120899 -4.2481020  3.7641991  9.3149100  3.4173077
    
    [[1]][[2]][[1]][[3]]
    [1] -4.7140899 -0.6204195  1.0137378  1.9825739  5.4109231
    
    [[1]][[2]][[1]][[4]]
    [1] -3.15128550 -0.09210678 -4.24279603 -7.37662755 -3.30059111
    
    
    [[1]][[2]][[2]]
    [[1]][[2]][[2]][[1]]
    [1] 2.96349918 0.06302583 0.69790405 4.23325563
    
    [[1]][[2]][[2]][[2]]
    [1]  2.1667401 -1.8961537 -0.2377742  5.4834991
    
    [[1]][[2]][[2]][[3]]
    [1] -7.152829 -2.092992  4.022700  5.078556
    
    [[1]][[2]][[2]][[4]]
    [1]  8.7496648 -0.8050604 -6.6433703 -2.9269550
    
    [[1]][[2]][[2]][[5]]
    [1] 10.674773  0.954940 -9.330530 -9.896166
    
    
    
    [[1]][[3]]
    [[1]][[3]][[1]]
    [[1]][[3]][[1]][[1]]
    [1] -8.1450719 -0.6100748  3.8437980 -2.0490800 -4.8608337
    
    [[1]][[3]][[1]][[2]]
    [1]  3.240145  3.966691  3.631668 -2.105163 -6.780426
    
    [[1]][[3]][[1]][[3]]
    [1] -1.092504 -1.068858 -2.355757  2.628884  8.924069
    
    [[1]][[3]][[1]][[4]]
    [1]   8.0159938   4.8773025   0.8808687  -6.0388153 -12.1007569
    
    
    [[1]][[3]][[2]]
    [[1]][[3]][[2]][[1]]
    [1] -11.478997  -2.671133   1.481882  -3.172968
    
    [[1]][[3]][[2]][[2]]
    [1] -2.3708240  0.1498945  3.3922213  4.1138296
    
    [[1]][[3]][[2]][[3]]
    [1] -4.156173 -3.038159  2.210371  6.340888
    
    [[1]][[3]][[2]][[4]]
    [1] -2.710232 -4.809749  1.191582  9.292430
    
    [[1]][[3]][[2]][[5]]
    [1] -4.2459059  0.7042119 -0.9365505 -7.5274307
    
    
    
    
    [[2]]
    [[2]][[1]]
    [[2]][[1]][[1]]
    [[2]][[1]][[1]][[1]]
    [1] -12.0530565  -3.3001526   5.3495434   2.2228848  -0.8005662
    
    [[2]][[1]][[1]][[2]]
    [1]  0.1838589  2.0746033 -0.3501288 -1.8273417  1.0109221
    
    [[2]][[1]][[1]][[3]]
    [1] -8.1450719 -0.6100748  3.8437980 -2.0490800 -4.8608337
    
    
    [[2]][[1]][[2]]
    [[2]][[1]][[2]][[1]]
    [1] -4.7675629  0.1002675  4.9680979
    
    [[2]][[1]][[2]][[2]]
    [1]  2.57458631  1.27266284 -0.02926063
    
    [[2]][[1]][[2]][[3]]
    [1] 1.682144 1.714314 1.746484
    
    [[2]][[1]][[2]][[4]]
    [1] -4.2650204  0.3692156  5.0034516
    
    [[2]][[1]][[2]][[5]]
    [1] -3.1781275 -0.8488647  1.4803982
    
    
    
    [[2]][[2]]
    [[2]][[2]][[1]]
    [[2]][[2]][[1]][[1]]
    [1] -8.4197008 -4.9084579  0.3304114  0.7856278 -0.4867822
    
    [[2]][[2]][[1]][[2]]
    [1] -0.8120899 -4.2481020  3.7641991  9.3149100  3.4173077
    
    [[2]][[2]][[1]][[3]]
    [1]  3.240145  3.966691  3.631668 -2.105163 -6.780426
    
    
    [[2]][[2]][[2]]
    [[2]][[2]][[2]][[1]]
    [1] -2.573364 -4.218569 -5.863774
    
    [[2]][[2]][[2]][[2]]
    [1]  1.9912028 -0.7206154 -3.4324337
    
    [[2]][[2]][[2]][[3]]
    [1] -1.780937  1.106520  3.993977
    
    [[2]][[2]][[2]][[4]]
    [1]  6.111748  1.260139 -3.591471
    
    [[2]][[2]][[2]][[5]]
    [1]  8.4542020 -0.6279546 -9.7101112
    
    
    
    [[2]][[3]]
    [[2]][[3]][[1]]
    [[2]][[3]][[1]][[1]]
    [1]  6.8212517  1.7321512 -2.2211682  0.4520727  1.9895325
    
    [[2]][[3]][[1]][[2]]
    [1] -4.7140899 -0.6204195  1.0137378  1.9825739  5.4109231
    
    [[2]][[3]][[1]][[3]]
    [1] -1.092504 -1.068858 -2.355757  2.628884  8.924069
    
    
    [[2]][[3]][[2]]
    [[2]][[3]][[2]][[1]]
    [1] 1.9015398 1.3841998 0.8668598
    
    [[2]][[3]][[2]][[2]]
    [1] -5.0196652 -0.9899268  3.0398116
    
    [[2]][[3]][[2]][[3]]
    [1] -0.9215451 -0.2964056  0.3287338
    
    [[2]][[3]][[2]][[4]]
    [1] -1.137778 -1.070680 -1.003582
    
    [[2]][[3]][[2]][[5]]
    [1] 0.9150564 1.0096812 1.1043059
    
    
    
    [[2]][[4]]
    [[2]][[4]][[1]]
    [[2]][[4]][[1]][[1]]
    [1] -10.136289  -7.635313  -3.607466   1.192120   4.464835
    
    [[2]][[4]][[1]][[2]]
    [1] -3.15128550 -0.09210678 -4.24279603 -7.37662755 -3.30059111
    
    [[2]][[4]][[1]][[3]]
    [1]   8.0159938   4.8773025   0.8808687  -6.0388153 -12.1007569
    
    
    [[2]][[4]][[2]]
    [[2]][[4]][[2]][[1]]
    [1] -4.923180 -4.805494 -4.687808
    
    [[2]][[4]][[2]][[2]]
    [1] -0.7321779  0.6401908  2.0125594
    
    [[2]][[4]][[2]][[3]]
    [1] 4.128667 2.702075 1.275483
    
    [[2]][[4]][[2]][[4]]
    [1] -1.494574  3.333191  8.160957
    
    [[2]][[4]][[2]][[5]]
    [1] -6.153830 -1.636486  2.880858
    
    
    
    
    [[3]]
    [[3]][[1]]
    [[3]][[1]][[1]]
    [[3]][[1]][[1]][[1]]
    [1]  0.03790015 -4.38304264  2.26444813 13.33288169
    
    [[3]][[1]][[1]][[2]]
    [1] 2.96349918 0.06302583 0.69790405 4.23325563
    
    [[3]][[1]][[1]][[3]]
    [1] -11.478997  -2.671133   1.481882  -3.172968
    
    
    [[3]][[1]][[2]]
    [[3]][[1]][[2]][[1]]
    [1] -4.7675629  0.1002675  4.9680979
    
    [[3]][[1]][[2]][[2]]
    [1] -2.573364 -4.218569 -5.863774
    
    [[3]][[1]][[2]][[3]]
    [1] 1.9015398 1.3841998 0.8668598
    
    [[3]][[1]][[2]][[4]]
    [1] -4.923180 -4.805494 -4.687808
    
    
    
    [[3]][[2]]
    [[3]][[2]][[1]]
    [[3]][[2]][[1]][[1]]
    [1]  2.9445847  3.1666806  1.5778130 -0.2331506
    
    [[3]][[2]][[1]][[2]]
    [1]  2.1667401 -1.8961537 -0.2377742  5.4834991
    
    [[3]][[2]][[1]][[3]]
    [1] -2.3708240  0.1498945  3.3922213  4.1138296
    
    
    [[3]][[2]][[2]]
    [[3]][[2]][[2]][[1]]
    [1]  2.57458631  1.27266284 -0.02926063
    
    [[3]][[2]][[2]][[2]]
    [1]  1.9912028 -0.7206154 -3.4324337
    
    [[3]][[2]][[2]][[3]]
    [1] -5.0196652 -0.9899268  3.0398116
    
    [[3]][[2]][[2]][[4]]
    [1] -0.7321779  0.6401908  2.0125594
    
    
    
    [[3]][[3]]
    [[3]][[3]][[1]]
    [[3]][[3]][[1]][[1]]
    [1] -2.53538826 -0.35719956  0.08296439 -1.65506036
    
    [[3]][[3]][[1]][[2]]
    [1] -7.152829 -2.092992  4.022700  5.078556
    
    [[3]][[3]][[1]][[3]]
    [1] -4.156173 -3.038159  2.210371  6.340888
    
    
    [[3]][[3]][[2]]
    [[3]][[3]][[2]][[1]]
    [1] 1.682144 1.714314 1.746484
    
    [[3]][[3]][[2]][[2]]
    [1] -1.780937  1.106520  3.993977
    
    [[3]][[3]][[2]][[3]]
    [1] -0.9215451 -0.2964056  0.3287338
    
    [[3]][[3]][[2]][[4]]
    [1] 4.128667 2.702075 1.275483
    
    
    
    [[3]][[4]]
    [[3]][[4]][[1]]
    [[3]][[4]][[1]][[1]]
    [1] -5.086027 -2.889889 -1.572489 -2.451226
    
    [[3]][[4]][[1]][[2]]
    [1]  8.7496648 -0.8050604 -6.6433703 -2.9269550
    
    [[3]][[4]][[1]][[3]]
    [1] -2.710232 -4.809749  1.191582  9.292430
    
    
    [[3]][[4]][[2]]
    [[3]][[4]][[2]][[1]]
    [1] -4.2650204  0.3692156  5.0034516
    
    [[3]][[4]][[2]][[2]]
    [1]  6.111748  1.260139 -3.591471
    
    [[3]][[4]][[2]][[3]]
    [1] -1.137778 -1.070680 -1.003582
    
    [[3]][[4]][[2]][[4]]
    [1] -1.494574  3.333191  8.160957
    
    
    
    [[3]][[5]]
    [[3]][[5]][[1]]
    [[3]][[5]][[1]][[1]]
    [1] -4.8349994 -1.7738492  0.4081584 -0.4709841
    
    [[3]][[5]][[1]][[2]]
    [1] 10.674773  0.954940 -9.330530 -9.896166
    
    [[3]][[5]][[1]][[3]]
    [1] -4.2459059  0.7042119 -0.9365505 -7.5274307
    
    
    [[3]][[5]][[2]]
    [[3]][[5]][[2]][[1]]
    [1] -3.1781275 -0.8488647  1.4803982
    
    [[3]][[5]][[2]][[2]]
    [1]  8.4542020 -0.6279546 -9.7101112
    
    [[3]][[5]][[2]][[3]]
    [1] 0.9150564 1.0096812 1.1043059
    
    [[3]][[5]][[2]][[4]]
    [1] -6.153830 -1.636486  2.880858
    

    A variant based on 2-D gradient matrix representations

    The previous solution applied the 1-D gradient vectors as the basic expressions cells, but the following variant is based on 2-D matrix, which looks more concise and compact.

    library(pracma)
    f <- function(arr, coords) {
      if (length(dim(arr))==2) {
        return(gradient(arr, coords[[2]], coords[[1]]))
      }
      idx <- seq_along(dim(arr))
      lapply(idx, \(k) apply(arr, k, \(x) f(x, coords[-k])))
    }
    
    • Example 1 With 2-D matrix arr and its coordinates coords
    set.seed(0)
    dims <- c(3, 4)
    arr <- array(rnorm(prod(dims)), dims)
    coords <- lapply(setNames(dims, seq_along(dims)), \(x) seq.int(x) / x)
    

    you will obtain

    > f(arr, coords)
    $X
                 [,1]        [,2]      [,3]      [,4]
    [1,]   0.03790015 -4.38304264 2.2644481 13.332882
    [2,]   2.96349918  0.06302583 0.6979041  4.233256
    [3,] -11.47899722 -2.67113287 1.4818816 -3.172968
    
    $Y
               [,1]      [,2]      [,3]      [,4]
    [1,] -4.7675629 -2.573364 1.9015398 -4.923180
    [2,]  0.1002675 -4.218569 1.3841998 -4.805494
    [3,]  4.9680979 -5.863774 0.8668598 -4.687808
    
    • Example 1 With 2-D matrix arr and its coordinates coords
    set.seed(0)
    dims <- c(3, 4)
    arr <- array(rnorm(prod(dims)), dims)
    coords <- lapply(setNames(dims, seq_along(dims)), \(x) seq.int(x) / x)
    

    you will obtain

    > f(arr, coords)
    [[1]]
    [[1]][[1]]
    [[1]][[1]]$X
               [,1]      [,2]       [,3]      [,4]       [,5]
    [1,] -12.053056 -3.300153  5.3495434 2.2228848 -0.8005662
    [2,]  -8.419701 -4.908458  0.3304114 0.7856278 -0.4867822
    [3,]   6.821252  1.732151 -2.2211682 0.4520727  1.9895325
    [4,] -10.136289 -7.635313 -3.6074656 1.1921204  4.4648354
    
    [[1]][[1]]$Y
                [,1]       [,2]        [,3]      [,4]       [,5]
    [1,]  0.03790015  2.9445847 -2.53538826 -5.086027 -4.8349994
    [2,] -4.38304264  3.1666806 -0.35719956 -2.889889 -1.7738492
    [3,]  2.26444813  1.5778130  0.08296439 -1.572489  0.4081584
    [4,] 13.33288169 -0.2331506 -1.65506036 -2.451226 -0.4709841
    
    
    [[1]][[2]]
    [[1]][[2]]$X
               [,1]        [,2]       [,3]      [,4]      [,5]
    [1,]  0.1838589  2.07460333 -0.3501288 -1.827342  1.010922
    [2,] -0.8120899 -4.24810197  3.7641991  9.314910  3.417308
    [3,] -4.7140899 -0.62041952  1.0137378  1.982574  5.410923
    [4,] -3.1512855 -0.09210678 -4.2427960 -7.376628 -3.300591
    
    [[1]][[2]]$Y
               [,1]       [,2]      [,3]       [,4]      [,5]
    [1,] 2.96349918  2.1667401 -7.152829  8.7496648 10.674773
    [2,] 0.06302583 -1.8961537 -2.092992 -0.8050604  0.954940
    [3,] 0.69790405 -0.2377742  4.022700 -6.6433703 -9.330530
    [4,] 4.23325563  5.4834991  5.078556 -2.9269550 -9.896166
    
    
    [[1]][[3]]
    [[1]][[3]]$X
              [,1]       [,2]       [,3]      [,4]       [,5]
    [1,] -8.145072 -0.6100748  3.8437980 -2.049080  -4.860834
    [2,]  3.240145  3.9666905  3.6316680 -2.105163  -6.780426
    [3,] -1.092504 -1.0688579 -2.3557567  2.628884   8.924069
    [4,]  8.015994  4.8773025  0.8808687 -6.038815 -12.100757
    
    [[1]][[3]]$Y
               [,1]       [,2]      [,3]      [,4]       [,5]
    [1,] -11.478997 -2.3708240 -4.156173 -2.710232 -4.2459059
    [2,]  -2.671133  0.1498945 -3.038159 -4.809749  0.7042119
    [3,]   1.481882  3.3922213  2.210371  1.191582 -0.9365505
    [4,]  -3.172968  4.1138296  6.340888  9.292430 -7.5274307
    
    
    
    [[2]]
    [[2]][[1]]
    [[2]][[1]]$X
                [,1]       [,2]       [,3]      [,4]       [,5]
    [1,] -12.0530565 -3.3001526  5.3495434  2.222885 -0.8005662
    [2,]   0.1838589  2.0746033 -0.3501288 -1.827342  1.0109221
    [3,]  -8.1450719 -0.6100748  3.8437980 -2.049080 -4.8608337
    
    [[2]][[1]]$Y
               [,1]        [,2]     [,3]       [,4]       [,5]
    [1,] -4.7675629  2.57458631 1.682144 -4.2650204 -3.1781275
    [2,]  0.1002675  1.27266284 1.714314  0.3692156 -0.8488647
    [3,]  4.9680979 -0.02926063 1.746484  5.0034516  1.4803982
    
    
    [[2]][[2]]
    [[2]][[2]]$X
               [,1]      [,2]      [,3]       [,4]       [,5]
    [1,] -8.4197008 -4.908458 0.3304114  0.7856278 -0.4867822
    [2,] -0.8120899 -4.248102 3.7641991  9.3149100  3.4173077
    [3,]  3.2401446  3.966691 3.6316680 -2.1051632 -6.7804260
    
    [[2]][[2]]$Y
              [,1]       [,2]      [,3]      [,4]       [,5]
    [1,] -2.573364  1.9912028 -1.780937  6.111748  8.4542020
    [2,] -4.218569 -0.7206154  1.106520  1.260139 -0.6279546
    [3,] -5.863774 -3.4324337  3.993977 -3.591471 -9.7101112
    
    
    [[2]][[3]]
    [[2]][[3]]$X
              [,1]       [,2]      [,3]      [,4]     [,5]
    [1,]  6.821252  1.7321512 -2.221168 0.4520727 1.989532
    [2,] -4.714090 -0.6204195  1.013738 1.9825739 5.410923
    [3,] -1.092504 -1.0688579 -2.355757 2.6288840 8.924069
    
    [[2]][[3]]$Y
              [,1]       [,2]       [,3]      [,4]      [,5]
    [1,] 1.9015398 -5.0196652 -0.9215451 -1.137778 0.9150564
    [2,] 1.3841998 -0.9899268 -0.2964056 -1.070680 1.0096812
    [3,] 0.8668598  3.0398116  0.3287338 -1.003582 1.1043059
    
    
    [[2]][[4]]
    [[2]][[4]]$X
               [,1]        [,2]       [,3]      [,4]       [,5]
    [1,] -10.136289 -7.63531259 -3.6074656  1.192120   4.464835
    [2,]  -3.151286 -0.09210678 -4.2427960 -7.376628  -3.300591
    [3,]   8.015994  4.87730251  0.8808687 -6.038815 -12.100757
    
    [[2]][[4]]$Y
              [,1]       [,2]     [,3]      [,4]      [,5]
    [1,] -4.923180 -0.7321779 4.128667 -1.494574 -6.153830
    [2,] -4.805494  0.6401908 2.702075  3.333191 -1.636486
    [3,] -4.687808  2.0125594 1.275483  8.160957  2.880858
    
    
    
    [[3]]
    [[3]][[1]]
    [[3]][[1]]$X
                 [,1]        [,2]      [,3]      [,4]
    [1,]   0.03790015 -4.38304264 2.2644481 13.332882
    [2,]   2.96349918  0.06302583 0.6979041  4.233256
    [3,] -11.47899722 -2.67113287 1.4818816 -3.172968
    
    [[3]][[1]]$Y
               [,1]      [,2]      [,3]      [,4]
    [1,] -4.7675629 -2.573364 1.9015398 -4.923180
    [2,]  0.1002675 -4.218569 1.3841998 -4.805494
    [3,]  4.9680979 -5.863774 0.8668598 -4.687808
    
    
    [[3]][[2]]
    [[3]][[2]]$X
              [,1]       [,2]       [,3]       [,4]
    [1,]  2.944585  3.1666806  1.5778130 -0.2331506
    [2,]  2.166740 -1.8961537 -0.2377742  5.4834991
    [3,] -2.370824  0.1498945  3.3922213  4.1138296
    
    [[3]][[2]]$Y
                [,1]       [,2]       [,3]       [,4]
    [1,]  2.57458631  1.9912028 -5.0196652 -0.7321779
    [2,]  1.27266284 -0.7206154 -0.9899268  0.6401908
    [3,] -0.02926063 -3.4324337  3.0398116  2.0125594
    
    
    [[3]][[3]]
    [[3]][[3]]$X
              [,1]       [,2]       [,3]      [,4]
    [1,] -2.535388 -0.3571996 0.08296439 -1.655060
    [2,] -7.152829 -2.0929925 4.02270020  5.078556
    [3,] -4.156173 -3.0381594 2.21037116  6.340888
    
    [[3]][[3]]$Y
             [,1]      [,2]       [,3]     [,4]
    [1,] 1.682144 -1.780937 -0.9215451 4.128667
    [2,] 1.714314  1.106520 -0.2964056 2.702075
    [3,] 1.746484  3.993977  0.3287338 1.275483
    
    
    [[3]][[4]]
    [[3]][[4]]$X
              [,1]       [,2]      [,3]      [,4]
    [1,] -5.086027 -2.8898887 -1.572489 -2.451226
    [2,]  8.749665 -0.8050604 -6.643370 -2.926955
    [3,] -2.710232 -4.8097493  1.191582  9.292430
    
    [[3]][[4]]$Y
               [,1]      [,2]      [,3]      [,4]
    [1,] -4.2650204  6.111748 -1.137778 -1.494574
    [2,]  0.3692156  1.260139 -1.070680  3.333191
    [3,]  5.0034516 -3.591471 -1.003582  8.160957
    
    
    [[3]][[5]]
    [[3]][[5]]$X
              [,1]       [,2]       [,3]       [,4]
    [1,] -4.834999 -1.7738492  0.4081584 -0.4709841
    [2,] 10.674773  0.9549400 -9.3305298 -9.8961664
    [3,] -4.245906  0.7042119 -0.9365505 -7.5274307
    
    [[3]][[5]]$Y
               [,1]       [,2]      [,3]      [,4]
    [1,] -3.1781275  8.4542020 0.9150564 -6.153830
    [2,] -0.8488647 -0.6279546 1.0096812 -1.636486
    [3,]  1.4803982 -9.7101112 1.1043059  2.880858