ScaledMatrix
类ResidualMatrix 1.9.0
的ScaledMatrix
提供另一个方法的运行规模()
在一个矩阵。换句话说,这三个操作是等价的:
垫< -矩阵(rnorm (10000), ncol = 10) smat1 < -规模(垫)头(smat1)
# #[1][2][3][4][5][6]# #(1)-0.5952843 0.6073891 0.5491519 -0.1654441 0.8280715 - 0.45138287 # #(2)0.4148672 -1.3581819 -0.5192951 0.7587801 0.5568547 - 0.62925864 # #(3)1.3613621 -1.7546698 0.7104871 -0.7316099 -0.5920986 - 1.41801126 # #(4)-0.8155146 0.1145625 1.3467783 0.3936147 1.2761509 - 0.03610536 # #(5)-1.8460836 -1.3858607 0.1625220 1.8150330 -0.5741667 - 1.31936176 # #(6日)1.6285958 0.3305292 0.5342793 -1.2213029 0.7534579 - -2.27039199 # #[7][8][9][10]# #(1)0.1278985 0.12600369 -0.2029459 -0.4452468 # #(2)-0.6647055 -0.04427008 0.9053039 0.2761594 # #(3)0.5321112 0.31695097 -0.2418060 -0.8383152 # #(4)0.3522975 1.55940025 -0.1659032 2.1293882 # #(5)-1.5634441 -0.30079842 0.2959628 -0.2240835 # #(6日)1.1922000 -1.89920203 2.2763545 1.8012138
库(DelayedArray) smat2 < -规模(DelayedArray(垫))头(smat2)
# # < 6 x 10 >矩阵类DelayedMatrix和类型的“双重”:# # [1][2][3]…[9][10]# # (1)-0.5952843 0.6073891 0.5491519。-0.2029459 - -0.4452468 # # (2)0.4148672 -1.3581819 -0.5192951。0.9053039 - 0.2761594 # # (3)1.3613621 -1.7546698 0.7104871。-0.2418060 - -0.8383152 # # (4)-0.8155146 0.1145625 1.3467783。-0.1659032 - 2.1293882 # # (5)-1.8460836 -1.3858607 0.1625220。0.2959628 - -0.2240835 # #(6日)1.6285958 0.3305292 0.5342793。2.2763545 - 1.8012138
库(ScaledMatrix) smat3 < - ScaledMatrix(垫,中心= TRUE,规模= TRUE)头(smat3)
# # < 6 x 10 >矩阵类ScaledMatrix和类型的“双重”:# # [1][2][3]…[9][10]# # (1)-0.5952843 0.6073891 0.5491519。-0.2029459 - -0.4452468 # # (2)0.4148672 -1.3581819 -0.5192951。0.9053039 - 0.2761594 # # (3)1.3613621 -1.7546698 0.7104871。-0.2418060 - -0.8383152 # # (4)-0.8155146 0.1145625 1.3467783。-0.1659032 - 2.1293882 # # (5)-1.8460836 -1.3858607 0.1625220。0.2959628 - -0.2240835 # #(6日)1.6285958 0.3305292 0.5342793。2.2763545 - 1.8012138
最大的区别在于他们如何表现在下游矩阵运算。
smat1
是一个普通的矩阵,缩放和集中值完全实现在内存中。没什么不寻常的。smat2
是一个DelayedMatrix
和经历块处理,块和运营,实现一次。这个牺牲速度更大的记忆效率,避免整个矩阵的副本。特别是,它保留了原来的结构垫
,如从稀疏或不是表示。smat3
是一个ScaledMatrix
重构某些操作,这样就可以应用于原始垫
没有任何扩展或定心。这种利用原始数据结构加速矩阵乘法和行/列金额,尽管数值精度为代价的。给定一个原始矩阵\ (\ mathbf {X} \)与\ (n \)列,列中心的一个向量\ (\ mathbf c {} \)和一个向量的列比例值\ (\ mathbf{年代}\),我们的缩放矩阵可以写成:
\ [\ mathbf {Y} = (\ mathbf {X} - \ mathbf c {} \ cdot \ mathbf {1} _n”^ T) \ mathbf{年代}\]
在哪里\ (\ mathbf{年代}={诊断接头}\文本(s_1 ^ {1},…,s_n ^ {1}) \)。如果我们想right-multiply它与另一个矩阵\ (\ mathbf {} \),我们将:
\ [\ mathbf{你}= \ mathbf {X} \ mathbf{年代}\ mathbf{一}- \ mathbf c {} \ cdot \ mathbf {1} _n”^ T \ mathbf{年代}\ mathbf {} \]
最右边的表达式只是外的产物\ (\ mathbf c {} \)列的\ (\ mathbf {SA} \)。更重要的是,我们可以使用矩阵乘法运算符\ (\ mathbf {X} \)与\ (\ mathbf {SA} \),因为这允许我们使用高效算法对于某些数据表示,例如,稀疏矩阵。
库(矩阵)垫< - rsparsematrix(20000、10000、密度= 0.01)smat < - ScaledMatrix(垫,中心= TRUE,规模= TRUE) blob < -矩阵(runif (ncol(垫)* 5),ncol = 5)系统。时间(< - smat % * % blob)
用户系统运行# # # # 0.028 0.000 0.028
#慢块处理方式。da < -规模(DelayedArray(垫))系统。时间(out2 < - da % * % blob)
用户系统运行# # # # 39.001 9.587 51.036
同样的逻辑也适用左乘和得叉积。这让我们很容易加快高层被切换到操作涉及到矩阵乘法ScaledMatrix
,例如,在近似PCA算法的BiocSingular包中。
库(BiocSingular) set.seed(1000)系统。时间(pc < - runSVD (smat k = 10, BSPARAM = IrlbaParam ()))
用户系统运行# # # # 19.634 0.221 19.856
行和列总结矩阵乘法的特殊情况,可以快速计算:
system.time (rowSums (smat))
用户系统运行# # # # 0.008 0.004 0.012
system.time (rowSums (da))
用户系统运行# # # # 21.505 7.571 29.080
构造子集,换位和重命名的维度都没有失去支持ScaledMatrix
表示:
smat [1:5]
# # < 20000 x 5 >矩阵类ScaledMatrix和类型的“双重”:# # [1][2][3][4][5]# # (1)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # # (2)-0.0007423747 3.6567273356 -0.0028795855 0.0066406752 - 0.0016133657 # # (3)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # # (4)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # # (5)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # #……# # (19996)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # # (19997)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # # (19998)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # # (19999)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 - 0.0016133657 # # (20000)-0.0007423747 -0.0073423135 -0.0028795855 0.0066406752 0.0016133657
t (smat)
# # < 10000 x 20000 >矩阵类ScaledMatrix和类型的“双重”:# # [1][2][3]…[19999]# # (1)-0.0007423747 -0.0007423747 -0.0007423747。-0.0007423747 # # (2)-0.0073423135 3.6567273356 -0.0073423135。-0.0073423135 # # (3)-0.0028795855 -0.0028795855 -0.0028795855。-0.0028795855 # # (4)0.0066406752 0.0066406752 0.0066406752。0.0066406752 # # (5)0.0016133657 0.0016133657 0.0016133657。0.0016133657 # #……# # (9996)-0.006093796 -0.006093796 -0.006093796。-0.006093796 # # (9997)0.004035216 0.004035216 0.004035216。0.004035216 # # (9998)-0.001817947 -0.001817947 -0.001817947。 -0.001817947 ## [9999,] 0.016723753 0.016723753 0.016723753 . 0.016723753 ## [10000,] -0.008103482 -0.008103482 -0.008103482 . -0.008103482 ## [,20000] ## [1,] -0.0007423747 ## [2,] -0.0073423135 ## [3,] -0.0028795855 ## [4,] 0.0066406752 ## [5,] 0.0016133657 ## ... . ## [9996,] -0.006093796 ## [9997,] 0.004035216 ## [9998,] -0.001817947 ## [9999,] 0.016723753 ## [10000,] -0.008103482
rownames (smat) < - paste0 smat (“GENE_”, 1:20000)
# # < 20000 x 10000 >矩阵类ScaledMatrix和类型的“双重”:# # [1][2][3]…[9999]# # GENE_1 -0.0007423747 -0.0073423135 -0.0028795855。0.016723753 # # GENE_2 -0.0007423747 3.6567273356 -0.0028795855。0.016723753 # # GENE_3 -0.0007423747 -0.0073423135 -0.0028795855。0.016723753 # # GENE_4 -0.0007423747 -0.0073423135 -0.0028795855。0.016723753 # # GENE_5 -0.0007423747 -0.0073423135 -0.0028795855。0.016723753 # #……# # GENE_19996 -0.0007423747 -0.0073423135 -0.0028795855。0.016723753 # # GENE_19997 -0.0007423747 -0.0073423135 -0.0028795855。0.016723753 # # GENE_19998 -0.0007423747 -0.0073423135 -0.0028795855。 0.016723753 ## GENE_19999 -0.0007423747 -0.0073423135 -0.0028795855 . 0.016723753 ## GENE_20000 -0.0007423747 -0.0073423135 -0.0028795855 . 0.016723753 ## [,10000] ## GENE_1 -0.008103482 ## GENE_2 -0.008103482 ## GENE_3 -0.008103482 ## GENE_4 -0.008103482 ## GENE_5 -0.008103482 ## ... . ## GENE_19996 -0.008103482 ## GENE_19997 -0.008103482 ## GENE_19998 -0.008103482 ## GENE_19999 -0.008103482 ## GENE_20000 -0.008103482
其他操作将导致ScaledMatrix
崩溃一般DelayedMatrix
表示,之后将使用点块处理。
smat + 1
# # < 20000 x 10000 >矩阵类DelayedMatrix和类型的“双重”:# # [1][2][3]…[9999][10000]# # GENE_1 0.9992576 0.9926577 0.9971204。1.0167238 - 0.9918965 # # GENE_2 0.9992576 4.6567273 0.9971204。1.0167238 - 0.9918965 # # GENE_3 0.9992576 0.9926577 0.9971204。1.0167238 - 0.9918965 # # GENE_4 0.9992576 0.9926577 0.9971204。1.0167238 - 0.9918965 # # GENE_5 0.9992576 0.9926577 0.9971204。1.0167238 - 0.9918965 # #……# # GENE_19996 0.9992576 0.9926577 0.9971204。1.0167238 - 0.9918965 # # GENE_19997 0.9992576 0.9926577 0.9971204。1.0167238 - 0.9918965 # # GENE_19998 0.9992576 0.9926577 0.9971204。 1.0167238 0.9918965 ## GENE_19999 0.9992576 0.9926577 0.9971204 . 1.0167238 0.9918965 ## GENE_20000 0.9992576 0.9926577 0.9971204 . 1.0167238 0.9918965
在大多数情况下,乘法的实现假设\ (\ mathbf {} \)矩阵和矩阵产品相比非常小\ (\ mathbf {X} \)。也可以用两个ScaledMatrix
es一起如果底层矩阵有高效的产品运营商。但是,如果情况并非如此,ScaledMatrix
提供一些有利于增加开销。
同样值得注意的是,这种加速并不完全是免费的。上面的表达式包括减去两个矩阵与潜在的大值,运行灾难性的取消的风险。下面的例子演示了如何ScaledMatrix
更容易受到损失精度比正常吗DelayedArray
:
set.seed(1000)垫< -矩阵(rnorm (1000000), ncol = 100000)大。垫<- mat + 1e12 # The 'correct' value, unaffected by numerical precision. ref <- rowMeans(scale(mat)) head(ref)
# # [1]-0.0025584703 -0.0008570664 -0.0019225335 -0.0001039903 0.0024761772 0.0032943203 # # [6]
#价值从一个DelayedArray规模。库(DelayedArray) smat2 < -规模(DelayedArray (big.mat))头(rowMeans (smat2))
# # [1]-0.0025583534 -0.0008571123 -0.0019226040 -0.0001039539 0.0024761618 0.0032943783 # # [6]
从ScaledMatrix #的值。库(ScaledMatrix) smat3 < ScaledMatrix(大。垫, center=TRUE, scale=TRUE) head(rowMeans(smat3))
# # [1]-0.00480 0.00848 0.00544 -0.00976 -0.01056 0.01520
在大多数实际应用中,然而,这似乎并不是一个大问题,尤其是在最值(例如,log-normalized表达式矩阵)的谎言接近于零。
sessionInfo ()
# # R正在开发的(不稳定的)(2022-10-25 r83175) # #平台:x86_64-pc-linux-gnu(64位)# #下运行:Ubuntu 22.04.1 LTS # # # #矩阵产品:默认# #布拉斯特区:/home/biocbuild/bbs - 3.17 - bioc / R / lib / libRblas。所以# # LAPACK: /usr/lib/x86_64-linux-gnu / LAPACK liblapack.so.3.10.0 # # # #语言环境:# # [1]LC_CTYPE = en_US。utf - 8 LC_NUMERIC = C # #[3]而= 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 = C LC_TELEPHONE = # # [11] LC_MEASUREMENT = en_US。utf - 8 LC_IDENTIFICATION = C附加基本包:# # # # # # [1]stats4统计图形grDevices跑龙套数据集方法# # # # # #[8]基地其他附加包:# # [1]BiocSingular_1.15.0 ScaledMatrix_1.7.0 DelayedArray_0.25.0 # # [4] IRanges_2.33.0 S4Vectors_0.37.0 MatrixGenerics_1.11.0 # # [7] matrixStats_0.62.0 BiocGenerics_0.45.0 Matrix_1.5-1 # # [10] BiocStyle_2.27.0 # # # #通过加载一个名称空间(而不是附加):# # [1]jsonlite_1.8.3 compiler_4.3.0 # # [3] BiocManager_1.30.19 rsvd_1.0.5 # # [5] Rcpp_1.0.9 stringr_1.4.1 # # [7] DelayedMatrixStats_1.21.0 parallel_4.3.0 # # [9] jquerylib_0.1.4 BiocParallel_1.33.0 # # [11] yaml_2.3.6 fastmap_1.1.0 # # [13] lattice_0.20-45 R6_2.5.1 # # [15] knitr_1.40 bookdown_0.29 # # [17] bslib_0.4.0 rlang_1.0.6 # # [19] cachem_1.0.6 stringi_1.7.8 # # [21] xfun_0.34 sass_0.4.2 # # [23] cli_3.4.1 magrittr_2.0.3 # # [25] digest_0.6.30 grid_4.3.0 # # [27] irlba_2.3.5.1 sparseMatrixStats_1.11.0 # # [29] evaluate_0.17 codetools_0.2-18 # # [31] beachmat_2.15.0 rmarkdown_2.17 # # [33] tools_4.3.0 htmltools_0.5.3