# Arithmetic

    library(dbMatrix)

## dbMatrix arithmetic

`dbMatrix` objects support `Arith` and `Ops` operations. We will demonstrate how to perform arithmetic operations on `dbSparseMatrix` objects.

Note: Some operations with zero values are not yet supported with dbMatrix objects. In addition, certain arithmetic operations between `dbMatrix` objects are also not yet supported. We welcome user feedback and reporting issues on the Github page.

### Create test data

Let’s create a simple sparse matrix for demonstration:

    # Create a sparse matrix
    set.seed(42)
    dgc <- Matrix::rsparsematrix(100, 50, density = 0.1, rand.x = function(n) rpois(n, 5) + 1)
    rownames(dgc) <- paste0("gene_", seq_len(100))
    colnames(dgc) <- paste0("cell_", seq_len(50))

    dplyr::glimpse(dgc)
    #> Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
    #>   ..@ i       : int [1:500] 1 7 15 26 32 38 48 81 90 93 ...
    #>   ..@ p       : int [1:51] 0 12 22 33 38 46 54 66 80 89 ...
    #>   ..@ Dim     : int [1:2] 100 50
    #>   ..@ Dimnames:List of 2
    #>   .. ..$ : chr [1:100] "gene_1" "gene_2" "gene_3" "gene_4" ...
    #>   .. ..$ : chr [1:50] "cell_1" "cell_2" "cell_3" "cell_4" ...
    #>   ..@ x       : num [1:500] 4 7 5 7 3 8 4 5 4 7 ...
    #>   ..@ factors : list()

The matrix contains 100 rows (genes) and 50 columns (cells). Like most single-cell RNA-seq data, the matrix is sparse.

### Create a dbMatrix object

Let’s create a `dbSparseMatrix` object from the above `dgc` object.

    # Note: by default the constructor creates a dbMatrix object in-memory
    con <- DBI::dbConnect(duckdb::duckdb(), ":memory:")

    dbsm <- dbMatrix(
      value = dgc,
      con = con,
      name = "test_matrix",
      class = "dbSparseMatrix",
      overwrite = TRUE
    )

    # preview the object
    dbsm
    #> 100 x 50  dbMatrix of class "dbSparseMatrix"
    #> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
    #>
    #> gene_1           .         .         . . .         . 5.0000000         .
    #> gene_2   4.0000000         .         . . .         .         .         .
    #> gene_3           . 7.0000000         . . . 8.0000000         . 3.0000000
    #>
    #> ......suppressing 40 columns and 94 rows
    #>
    #> gene_98          .         .         . . .         .         .         .
    #> gene_99          .         . 5.0000000 . .         .         .         .
    #> gene_100 7.0000000         .         . . .         .         .         .

### Scalar Arithmetic

`dbMatrix` emulates scalar arithmetic in the `Matrix` package.

Note: Addition or subtraction with non-zero addends on a `dbSparseMatrix` results in a `dbDenseMatrix`.

    dbsm + 1
    #> ℹ Performing on-the-fly densification (cold path). See ?dbMatrix_options for details.
    #> 100 x 50  dbMatrix of class "dbDenseMatrix"
    #> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
    #>
    #> gene_1   1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 6.0000000
    #> gene_2   5.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
    #> gene_3   1.0000000 8.0000000 1.0000000 1.0000000 1.0000000 9.0000000 1.0000000
    #>
    #> ......suppressing 40 columns and 94 rows
    #>
    #> gene_98  1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
    #> gene_99  1.0000000 1.0000000 6.0000000 1.0000000 1.0000000 1.0000000 1.0000000
    #> gene_100 8.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000

    dbsm * 100
    #> 100 x 50  dbMatrix of class "dbSparseMatrix"
    #> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
    #>
    #> gene_1             .           .           . . .           . 500.0000000
    #> gene_2   400.0000000           .           . . .           .           .
    #> gene_3             . 700.0000000           . . . 800.0000000           .
    #>
    #> ......suppressing 40 columns and 94 rows
    #>
    #> gene_98            .           .           . . .           .           .
    #> gene_99            .           . 500.0000000 . .           .           .
    #> gene_100 700.0000000           .           . . .           .           .

### Matrix Arithmetic

`dbMatrix` also supports matrix arithmetic for `dbMatrix` objects that are conformable.

    dbsm + dbsm
    #> 100 x 50  dbMatrix of class "dbSparseMatrix"
    #> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
    #>
    #> gene_1            .          .          . . .          . 10.0000000          .
    #> gene_2    8.0000000          .          . . .          .          .          .
    #> gene_3            . 14.0000000          . . . 16.0000000          .  6.0000000
    #>
    #> ......suppressing 40 columns and 94 rows
    #>
    #> gene_98           .          .          . . .          .          .          .
    #> gene_99           .          . 10.0000000 . .          .          .          .
    #> gene_100 14.0000000          .          . . .          .          .          .

### Matrix Multiplication

#### Hadamard product

    dbsm * dbsm
    #> 100 x 50  dbMatrix of class "dbSparseMatrix"
    #> [[ Colnames 'cell_1', 'cell_2', 'cell_3' ... suppressing 44 ...'cell_48', 'cell_49', 'cell_50' ]]
    #>
    #> gene_1            .          .          . . .          . 25.0000000          .
    #> gene_2   16.0000000          .          . . .          .          .          .
    #> gene_3            . 49.0000000          . . . 64.0000000          .  9.0000000
    #>
    #> ......suppressing 40 columns and 94 rows
    #>
    #> gene_98           .          .          . . .          .          .          .
    #> gene_99           .          . 25.0000000 . .          .          .          .
    #> gene_100 49.0000000          .          . . .          .          .          .

#### Matrix product

TODO

### Cleanup

    DBI::dbDisconnect(con, shutdown = TRUE)
    options(old_options)

### Session Info

    sessionInfo()
    #> R version 4.5.2 (2025-10-31)
    #> Platform: x86_64-pc-linux-gnu
    #> Running under: AlmaLinux 8.10 (Cerulean Leopard)
    #>
    #> Matrix products: default
    #> BLAS/LAPACK: FlexiBLAS NETLIB;  LAPACK version 3.12.0
    #>
    #> locale:
    #>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
    #>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
    #>  [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] stats     graphics  grDevices utils     datasets  methods   base
    #>
    #> other attached packages:
    #> [1] dbMatrix_0.1.0
    #>
    #> loaded via a namespace (and not attached):
    #>  [1] bit_4.6.0             Matrix_1.7-4          jsonlite_2.0.0
    #>  [4] dplyr_1.1.4           compiler_4.5.2        tidyselect_1.2.1
    #>  [7] Rcpp_1.1.0            blob_1.2.4            nanoarrow_0.7.0-1
    #> [10] pins_1.4.1            assertthat_0.2.1      dbProject_0.0.0.9002
    #> [13] jquerylib_0.1.4       arrow_22.0.0          yaml_2.3.10
    #> [16] fastmap_1.2.0         lattice_0.22-7        R6_2.6.1
    #> [19] generics_0.1.4        knitr_1.50            tibble_3.3.0
    #> [22] MatrixGenerics_1.22.0 DBI_1.2.3             bslib_0.9.0
    #> [25] pillar_1.11.1         connections_0.2.1     rlang_1.1.6
    #> [28] cachem_1.1.0          xfun_0.54             sass_0.4.10
    #> [31] bit64_4.6.0-1         cli_3.6.5             withr_3.0.2
    #> [34] magrittr_2.0.4        digest_0.6.38         grid_4.5.2
    #> [37] rscontract_0.1.2      dbplyr_2.5.1          lifecycle_1.0.4
    #> [40] vctrs_0.6.5           evaluate_1.0.5        glue_1.8.0
    #> [43] data.table_1.17.8     duckdb_1.4.2          rmarkdown_2.30
    #> [46] purrr_1.2.0           matrixStats_1.5.0     tools_4.5.2
    #> [49] pkgconfig_2.0.3       htmltools_0.5.8.1