DelayedTensor 1.13.0
Authors: Koki Tsuyuzaki [aut, cre]
Last modified: 2024-10-23 23:57:56.972842
Compiled: Tue Oct 29 17:02:54 2024
suppressPackageStartupMessages(library("DelayedTensor"))
suppressPackageStartupMessages(library("DelayedArray"))
suppressPackageStartupMessages(library("HDF5Array"))
suppressPackageStartupMessages(library("DelayedRandomArray"))
darr1 <- RandomUnifArray(c(2,3,4))
darr2 <- RandomUnifArray(c(2,3,4))
There are several settings in DelayedTensor.
First, the sparsity of the intermediate DelayedArray objects
calculated inside DelayedTensor is set by setSparse
.
Note that the sparse mode is experimental.
Whether it contributes to higher speed and lower memory is quite dependent on the sparsity of the DelayedArray, and the current implementation does not recognize the block size, which may cause out-of-memory errors, when the data is extremely huge.
Here, we specify as.sparse
as FALSE
(this is also the default value for now).
DelayedTensor::setSparse(as.sparse=FALSE)
Next, the verbose message is suppressed by setVerbose
.
This is useful when we want to monitor the calculation process.
Here we specify as.verbose
as FALSE
(this is also the default value for now).
DelayedTensor::setVerbose(as.verbose=FALSE)
The block size of block processing is specified by setAutoBlockSize
.
When the sparse mode is off, all the functions of DelayedTensor
are performed as block processing,
in which each block vector/matrix/tensor is expanded to memory space
from on-disk file incrementally so as not to exceed the specified size.
Here, we specify the block size as 1E+8
.
setAutoBlockSize(size=1E+8)
## automatic block size set to 1e+08 bytes (was 1e+08)
Finally, the temporal directory to store the intermediate HDF5 files during running DelayedTensor is specified by setHDF5DumpDir
.
Note that in many systems the /var
directory has the storage limitation, so if there is no enough space, user should specify the other directory.
# tmpdir <- paste(sample(c(letters,1:9), 10), collapse="")
# dir.create(tmpdir, recursive=TRUE))
tmpdir <- tempdir()
setHDF5DumpDir(tmpdir)
These specified values are also extracted by each getter function.
DelayedTensor::getSparse()
## $delayedtensor.sparse
## [1] FALSE
DelayedTensor::getVerbose()
## $delayedtensor.verbose
## [1] FALSE
getAutoBlockSize()
## [1] 1e+08
getHDF5DumpDir()
## [1] "/tmp/RtmpsBtZbY"
Unfold (a.k.a. matricizing) operations are used to reshape a tensor into a matrix.
In unfold
, row_idx
and col_idx
are specified to set which modes are used
as the row/column.
dmat1 <- DelayedTensor::unfold(darr1, row_idx=c(1,2), col_idx=3)
dmat1
## <6 x 4> HDF5Matrix object of type "double":
## [,1] [,2] [,3] [,4]
## [1,] 0.52895402 0.66354926 0.39118738 0.70460494
## [2,] 0.42671647 0.13188626 0.32174007 0.65192906
## [3,] 0.52530978 0.54854998 0.11820052 0.07698941
## [4,] 0.03477175 0.32994865 0.34266433 0.58913021
## [5,] 0.85087939 0.29428657 0.14706950 0.60151514
## [6,] 0.90908221 0.88938736 0.09704689 0.77968259
fold
is the inverse operation of unfold
, which is used to reshape
a matrix into a tensor.
In fold
, row_idx
/col_idx
are specified to set which modes correspond
the row/column of the output tensor and modes
is specified to set the mode of the output tensor.
dmat1_to_darr1 <- DelayedTensor::fold(dmat1,
row_idx=c(1,2), col_idx=3, modes=dim(darr1))
dmat1_to_darr1
## <2 x 3 x 4> DelayedArray object of type "double":
## ,,1
## [,1] [,2] [,3]
## [1,] 0.52895402 0.52530978 0.85087939
## [2,] 0.42671647 0.03477175 0.90908221
##
## ,,2
## [,1] [,2] [,3]
## [1,] 0.6635493 0.5485500 0.2942866
## [2,] 0.1318863 0.3299487 0.8893874
##
## ,,3
## [,1] [,2] [,3]
## [1,] 0.39118738 0.11820052 0.14706950
## [2,] 0.32174007 0.34266433 0.09704689
##
## ,,4
## [,1] [,2] [,3]
## [1,] 0.70460494 0.07698941 0.60151514
## [2,] 0.65192906 0.58913021 0.77968259
identical(as.array(darr1), as.array(dmat1_to_darr1))
## [1] TRUE
There are some wrapper functions of unfold
and fold
.
For example, in k_unfold
, mode m
is used as the row, and the other modes
are is used as the column.
k_fold
is the inverse operation of k_unfold
.
dmat2 <- DelayedTensor::k_unfold(darr1, m=1)
dmat2_to_darr1 <- k_fold(dmat2, m=1, modes=dim(darr1))
identical(as.array(darr1), as.array(dmat2_to_darr1))
## [1] TRUE
dmat3 <- DelayedTensor::k_unfold(darr1, m=2)
dmat3_to_darr1 <- k_fold(dmat3, m=2, modes=dim(darr1))
identical(as.array(darr1), as.array(dmat3_to_darr1))
## [1] TRUE
dmat4 <- DelayedTensor::k_unfold(darr1, m=3)
dmat4_to_darr1 <- k_fold(dmat4, m=3, modes=dim(darr1))
identical(as.array(darr1), as.array(dmat4_to_darr1))
## [1] TRUE
In rs_unfold
, mode m
is used as the row, and the other modes
are is used as the column.
rs_fold
and rs_unfold
also perform the same operations.
On the other hand, cs_unfold
specifies the mode m
as the column
and the other modes are specified as the column.
cs_fold
is the inverse operation of cs_unfold
.
dmat8 <- DelayedTensor::cs_unfold(darr1, m=1)
dmat8_to_darr1 <- DelayedTensor::cs_fold(dmat8, m=1, modes=dim(darr1))
identical(as.array(darr1), as.array(dmat8_to_darr1))
## [1] TRUE
dmat9 <- DelayedTensor::cs_unfold(darr1, m=2)
dmat9_to_darr1 <- DelayedTensor::cs_fold(dmat9, m=2, modes=dim(darr1))
identical(as.array(darr1), as.array(dmat9_to_darr1))
## [1] TRUE
dmat10 <- DelayedTensor::cs_unfold(darr1, m=3)
dmat10_to_darr1 <- DelayedTensor::cs_fold(dmat10, m=3, modes=dim(darr1))
identical(as.array(darr1), as.array(dmat10_to_darr1))
## [1] TRUE
In matvec
, m=2 is specified as unfold.
unmatvec
is the inverse operation of matvec
.
dmat11 <- DelayedTensor::matvec(darr1)
dmat11_darr1 <- DelayedTensor::unmatvec(dmat11, modes=dim(darr1))
identical(as.array(darr1), as.array(dmat11_darr1))
## [1] TRUE
ttm
multiplies a tensor by a matrix.
m
specifies in which mode the matrix will be multiplied.
dmatZ <- RandomUnifArray(c(10,4))
DelayedTensor::ttm(darr1, dmatZ, m=3)
## <2 x 3 x 10> DelayedArray object of type "double":
## ,,1
## [,1] [,2] [,3]
## [1,] 0.9358299 0.4164523 0.5340920
## [2,] 0.5751499 0.6649364 0.9088382
##
## ,,2
## [,1] [,2] [,3]
## [1,] 1.0671853 0.6408163 1.0245586
## [2,] 0.7775366 0.5348084 1.2859583
##
## ,,3
## [,1] [,2] [,3]
## [1,] 1.3296397 0.7523609 0.8843548
## [2,] 0.7787854 0.8071487 1.4245122
##
## ...
##
## ,,8
## [,1] [,2] [,3]
## [1,] 1.1627438 0.5758040 0.8079606
## [2,] 0.7161695 0.7445252 1.3205452
##
## ,,9
## [,1] [,2] [,3]
## [1,] 0.6262998 0.2949243 0.4819006
## [2,] 0.5140881 0.4054570 0.4840830
##
## ,,10
## [,1] [,2] [,3]
## [1,] 1.2062478 0.6137882 0.8192216
## [2,] 0.7195471 0.7672187 1.3751165
ttl
multiplies a tensor by multiple matrices.
ms
specifies in which mode these matrices will be multiplied.
dmatX <- RandomUnifArray(c(10,2))
dmatY <- RandomUnifArray(c(10,3))
dlizt <- list(dmatX = dmatX, dmatY = dmatY)
DelayedTensor::ttl(darr1, dlizt, ms=c(1,2))
## <10 x 10 x 4> DelayedArray object of type "double":
## ,,1
## [,1] [,2] [,3] ... [,9] [,10]
## [1,] 1.3879279 0.8376831 1.1293502 . 0.7476935 0.6465517
## [2,] 2.3995231 1.4934105 2.0669798 . 1.1970759 1.1072002
## ... . . . . . .
## [9,] 2.0314601 1.2612527 1.7421111 . 1.0199794 0.9380897
## [10,] 1.2873534 0.8089383 1.1285020 . 0.6259090 0.5922078
##
## ...
##
## ,,4
## [,1] [,2] [,3] ... [,9] [,10]
## [1,] 1.1226969 0.6852522 0.9930883 . 0.4754329 0.7353010
## [2,] 2.3337358 1.3925030 1.9470025 . 1.1243167 1.4063654
## ... . . . . . .
## [9,] 1.9489585 1.1647245 1.6326476 . 0.9312216 1.1814198
## [10,] 1.3191512 0.7825812 1.0838811 . 0.6548515 0.7776054
vec
collapses a DelayedArray into
a 1D DelayedArray (vector).
DelayedTensor::vec(darr1)
## <24> HDF5Array object of type "double":
## [1] [2] [3] . [23] [24]
## 0.5289540 0.4267165 0.5253098 . 0.6015151 0.7796826
fnorm
calculates the Frobenius norm of a DelayedArray.
DelayedTensor::fnorm(darr1)
## [1] 2.587998
innerProd
calculates the inner product value of two
DelayedArray.
DelayedTensor::innerProd(darr1, darr2)
## [1] 4.445472
Inner product multiplies two tensors and collapses to 0D tensor (norm). On the other hand, the outer product is an operation that leaves all subscripts intact.
DelayedTensor::outerProd(darr1[,,1], darr2[,,1])
## <2 x 3 x 2 x 3> HDF5Array object of type "double":
## ,,1,1
## [,1] [,2] [,3]
## [1,] 0.29538437 0.29334931 0.47515751
## [2,] 0.23829175 0.01941762 0.50765977
##
## ,,2,1
## [,1] [,2] [,3]
## [1,] 0.088280877 0.087672664 0.142009279
## [2,] 0.071217730 0.005803303 0.151723159
##
## ,,1,2
## [,1] [,2] [,3]
## [1,] 0.31477572 0.31260707 0.50635058
## [2,] 0.25393509 0.02069235 0.54098655
##
## ,,2,2
## [,1] [,2] [,3]
## [1,] 0.4447539 0.4416897 0.7154344
## [2,] 0.3587907 0.0292367 0.7643723
##
## ,,1,3
## [,1] [,2] [,3]
## [1,] 0.050267975 0.049921653 0.080861441
## [2,] 0.040552056 0.003304456 0.086392617
##
## ,,2,3
## [,1] [,2] [,3]
## [1,] 0.36631605 0.36379231 0.58925874
## [2,] 0.29551358 0.02408045 0.62956589
Using DelayedDiagonalArray
, we can originally create a diagonal
DelayedArray by specifying the dimensions (modes) and the values.
dgdarr <- DelayedTensor::DelayedDiagonalArray(c(5,6,7), 1:5)
dgdarr
## <5 x 6 x 7> sparse DelayedArray object of type "integer":
## ,,1
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 0 0 0 0 0
## [2,] 0 0 0 0 0 0
## [3,] 0 0 0 0 0 0
## [4,] 0 0 0 0 0 0
## [5,] 0 0 0 0 0 0
##
## ...
##
## ,,7
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0 0 0 0 0 0
## [2,] 0 0 0 0 0 0
## [3,] 0 0 0 0 0 0
## [4,] 0 0 0 0 0 0
## [5,] 0 0 0 0 0 0
Similar to the diag
of the base package,
the diag
of DelayedTensor is used to extract
and assign values to DelayedArray.
DelayedTensor::diag(dgdarr)
## <5> DelayedArray object of type "integer":
## [1] [2] [3] [4] [5]
## 1 2 3 4 5
DelayedTensor::diag(dgdarr) <- c(1111, 2222, 3333, 4444, 5555)
DelayedTensor::diag(dgdarr)
## <5> DelayedArray object of type "double":
## [1] [2] [3] [4] [5]
## 1111 2222 3333 4444 5555
modeSum
calculates the summation for a given mode m
of
a DelayedArray.
The mode specified as m
is collapsed into 1D as follows.
DelayedTensor::modeSum(darr1, m=1)
## <1 x 3 x 4> DelayedArray object of type "double":
## ,,1
## [,1] [,2] [,3]
## [1,] 0.9556705 0.5600815 1.7599616
##
## ,,2
## [,1] [,2] [,3]
## [1,] 0.7954355 0.8784986 1.1836739
##
## ,,3
## [,1] [,2] [,3]
## [1,] 0.7129274 0.4608648 0.2441164
##
## ,,4
## [,1] [,2] [,3]
## [1,] 1.3565340 0.6661196 1.3811977
DelayedTensor::modeSum(darr1, m=2)
## <2 x 1 x 4> DelayedArray object of type "double":
## ,,1
## [,1]
## [1,] 1.905143
## [2,] 1.370570
##
## ,,2
## [,1]
## [1,] 1.506386
## [2,] 1.351222
##
## ,,3
## [,1]
## [1,] 0.6564574
## [2,] 0.7614513
##
## ,,4
## [,1]
## [1,] 1.383109
## [2,] 2.020742
DelayedTensor::modeSum(darr1, m=3)
## <2 x 3 x 1> DelayedArray object of type "double":
## ,,1
## [,1] [,2] [,3]
## [1,] 2.288296 1.269050 1.893751
## [2,] 1.532272 1.296515 2.675199
Similar to modeSum
, modeMean
calculates the average value
for a given mode m
of a DelayedArray.
DelayedTensor::modeMean(darr1, m=1)
## <1 x 3 x 4> DelayedArray object of type "double":
## ,,1
## [,1] [,2] [,3]
## [1,] 0.4778352 0.2800408 0.8799808
##
## ,,2
## [,1] [,2] [,3]
## [1,] 0.3977178 0.4392493 0.5918370
##
## ,,3
## [,1] [,2] [,3]
## [1,] 0.3564637 0.2304324 0.1220582
##
## ,,4
## [,1] [,2] [,3]
## [1,] 0.6782670 0.3330598 0.6905989
DelayedTensor::modeMean(darr1, m=2)
## <2 x 1 x 4> DelayedArray object of type "double":
## ,,1
## [,1]
## [1,] 0.6350477
## [2,] 0.4568568
##
## ,,2
## [,1]
## [1,] 0.5021286
## [2,] 0.4504074
##
## ,,3
## [,1]
## [1,] 0.2188191
## [2,] 0.2538171
##
## ,,4
## [,1]
## [1,] 0.4610365
## [2,] 0.6735806
DelayedTensor::modeMean(darr1, m=3)
## <2 x 3 x 1> DelayedArray object of type "double":
## ,,1
## [,1] [,2] [,3]
## [1,] 0.5720739 0.3172624 0.4734377
## [2,] 0.3830680 0.3241287 0.6687998
There are some tensor specific product such as Hadamard product, Kronecker product, and Khatri-Rao product.
Suppose a tensor \(A \in \Re ^{I \times J}\) and a tensor \(B \in \Re ^{I \times J}\).
Hadamard product is defined as the element-wise product of \(A\) and \(B\).
Hadamard product can be extended to higher-order tensors.
\[ A \circ B = \begin{bmatrix} a_{11}b_{11} & a_{12}b_{12} & \cdots & a_{1J}b_{1J} \\ a_{21}b_{21} & a_{22}b_{22} & \cdots & a_{2J}b_{2J} \\ \vdots & \vdots & \ddots & \vdots \\ a_{I1}b_{I1} & a_{I2}b_{I2} & \cdots & a_{IJ}b_{IJ} \\ \end{bmatrix} \]
hadamard
calculates Hadamard product of two DelayedArray
objects.
prod_h <- DelayedTensor::hadamard(darr1, darr2)
dim(prod_h)
## [1] 2 3 4
hadamard_list
calculates Hadamard product of multiple
DelayedArray objects.
prod_hl <- DelayedTensor::hadamard_list(list(darr1, darr2))
dim(prod_hl)
## [1] 2 3 4
Suppose a tensor \(A \in \Re ^{I \times J}\) and a tensor \(B \in \Re ^{K \times L}\).
Kronecker product is defined as all the possible combination of element-wise product and the dimensions of output tensor are \({IK \times JL}\).
Kronecker product can be extended to higher-order tensors.
\[ A \otimes B = \begin{bmatrix} a_{11}B & a_{12}B & \cdots & a_{1J}B \\ a_{21}B & a_{22}B & \cdots & a_{2J}B \\ \vdots & \vdots & \ddots & \vdots \\ a_{I1}B & a_{I2}B & \cdots & a_{IJ}B \\ \end{bmatrix} \]
kronecker
calculates Kronecker product of two DelayedArray
objects.
prod_kron <- DelayedTensor::kronecker(darr1, darr2)
dim(prod_kron)
## [1] 4 9 16
kronecker_list
calculates Kronecker product of multiple
DelayedArray objects.
prod_kronl <- DelayedTensor::kronecker_list(list(darr1, darr2))
dim(prod_kronl)
## [1] 4 9 16
Suppose a tensor \(A \in \Re ^{I \times J}\) and a tensor \(B \in \Re ^{K \times J}\).
Khatri-Rao product is defined as the column-wise Kronecker product and the dimensions of output tensor is \({IK \times J}\).
\[ A \odot B = \begin{bmatrix} a_{1} \otimes a_{1} & a_{2} \otimes a_{2} & \cdots & a_{J} \otimes a_{J} \\ \end{bmatrix} \]
Khatri-Rao product can only be used for 2D tensors (matrices).
khatri_rao
calculates Khatri-Rao product of two DelayedArray
objects.
prod_kr <- DelayedTensor::khatri_rao(darr1[,,1], darr2[,,1])
dim(prod_kr)
## [1] 4 3
khatri_rao_list
calculates Khatri-Rao product of multiple
DelayedArray objects.
prod_krl <- DelayedTensor::khatri_rao_list(list(darr1[,,1], darr2[,,1]))
dim(prod_krl)
## [1] 4 3
list_rep
replicates an arbitrary number of any R object.
str(DelayedTensor::list_rep(darr1, 3))
## List of 3
## $ :Formal class 'RandomUnifArray' [package "DelayedRandomArray"] with 1 slot
## .. ..@ seed:Formal class 'RandomUnifArraySeed' [package "DelayedRandomArray"] with 6 slots
## .. .. .. ..@ min : num 0
## .. .. .. ..@ max : num 1
## .. .. .. ..@ dim : int [1:3] 2 3 4
## .. .. .. ..@ chunkdim: int [1:3] 2 3 4
## .. .. .. ..@ seeds :List of 1
## .. .. .. .. ..$ : int [1:2] -856879986 -1767329831
## .. .. .. ..@ sparse : logi FALSE
## $ :Formal class 'RandomUnifArray' [package "DelayedRandomArray"] with 1 slot
## .. ..@ seed:Formal class 'RandomUnifArraySeed' [package "DelayedRandomArray"] with 6 slots
## .. .. .. ..@ min : num 0
## .. .. .. ..@ max : num 1
## .. .. .. ..@ dim : int [1:3] 2 3 4
## .. .. .. ..@ chunkdim: int [1:3] 2 3 4
## .. .. .. ..@ seeds :List of 1
## .. .. .. .. ..$ : int [1:2] -856879986 -1767329831
## .. .. .. ..@ sparse : logi FALSE
## $ :Formal class 'RandomUnifArray' [package "DelayedRandomArray"] with 1 slot
## .. ..@ seed:Formal class 'RandomUnifArraySeed' [package "DelayedRandomArray"] with 6 slots
## .. .. .. ..@ min : num 0
## .. .. .. ..@ max : num 1
## .. .. .. ..@ dim : int [1:3] 2 3 4
## .. .. .. ..@ chunkdim: int [1:3] 2 3 4
## .. .. .. ..@ seeds :List of 1
## .. .. .. .. ..$ : int [1:2] -856879986 -1767329831
## .. .. .. ..@ sparse : logi FALSE
modebind_list
collapses multiple DelayedArray objects
into single DelayedArray object.
m
specifies the collapsed dimension.
dim(DelayedTensor::modebind_list(list(darr1, darr2), m=1))
## [1] 4 3 4
dim(DelayedTensor::modebind_list(list(darr1, darr2), m=2))
## [1] 2 6 4
dim(DelayedTensor::modebind_list(list(darr1, darr2), m=3))
## [1] 2 3 8
rbind_list
is the row-wise modebind_list
and
collapses multiple 2D DelayedArray objects
into single DelayedArray object.
dim(DelayedTensor::rbind_list(list(darr1[,,1], darr2[,,1])))
## [1] 4 3
cbind_list
is the column-wise modebind_list
and
collapses multiple 2D DelayedArray objects
into single DelayedArray object.
dim(DelayedTensor::cbind_list(list(darr1[,,1], darr2[,,1])))
## [1] 2 6
## R Under development (unstable) (2024-10-21 r87258)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.1 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.21-bioc/R/lib/libRblas.so
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_GB LC_COLLATE=C
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: America/New_York
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats4 stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] DelayedRandomArray_1.15.0 HDF5Array_1.35.0
## [3] rhdf5_2.51.0 DelayedArray_0.33.0
## [5] SparseArray_1.7.0 S4Arrays_1.7.0
## [7] abind_1.4-8 IRanges_2.41.0
## [9] S4Vectors_0.45.0 MatrixGenerics_1.19.0
## [11] matrixStats_1.4.1 BiocGenerics_0.53.0
## [13] Matrix_1.7-1 DelayedTensor_1.13.0
## [15] BiocStyle_2.35.0
##
## loaded via a namespace (and not attached):
## [1] jsonlite_1.8.9 compiler_4.5.0 BiocManager_1.30.25
## [4] crayon_1.5.3 rsvd_1.0.5 Rcpp_1.0.13
## [7] rhdf5filters_1.19.0 parallel_4.5.0 jquerylib_0.1.4
## [10] BiocParallel_1.41.0 yaml_2.3.10 fastmap_1.2.0
## [13] lattice_0.22-6 R6_2.5.1 XVector_0.47.0
## [16] ScaledMatrix_1.15.0 knitr_1.48 einsum_0.1.2
## [19] bookdown_0.41 bslib_0.8.0 rlang_1.1.4
## [22] cachem_1.1.0 xfun_0.48 sass_0.4.9
## [25] cli_3.6.3 Rhdf5lib_1.29.0 BiocSingular_1.23.0
## [28] zlibbioc_1.53.0 digest_0.6.37 grid_4.5.0
## [31] irlba_2.3.5.1 rTensor_1.4.8 dqrng_0.4.1
## [34] lifecycle_1.0.4 evaluate_1.0.1 codetools_0.2-20
## [37] beachmat_2.23.0 rmarkdown_2.28 tools_4.5.0
## [40] htmltools_0.5.8.1