An open API service indexing awesome lists of open source software.

https://github.com/stla/eigenr

Complex matrix algebra with Eigen
https://github.com/stla/eigenr

eigen r rcpp

Last synced: 2 months ago
JSON representation

Complex matrix algebra with Eigen

Awesome Lists containing this project

README

          

---
title: "EigenR"
output: github_document
editor_options:
chunk_output_type: console
---

[![R-CMD-check](https://github.com/stla/EigenR/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/stla/EigenR/actions/workflows/R-CMD-check.yaml)

```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = TRUE, collapse = TRUE, warning = FALSE, message = FALSE
)
```

Originally, I entitled this package *Fast Matrix Algebra with 'Eigen'*, because
I expected it to be faster than R base. But this is not the case. So I entitled
it *Complex Matrix Algebra with 'Eigen'*, because it supports some operations
on complex matrices which are not supported by R base: determinant, Cholesky
decomposition, and linear least-squares problems.

```{r packages}
library(EigenR)
library(microbenchmark)
```

## Determinant

```{r det_benchmark}
set.seed(666L)
M <- matrix(rnorm(300L*300L, mean = 1), 300L, 300L)
M[sample.int(300L*300L, 300L*270L)] <- 0 # 90% of zeros
Ms <- asSparseMatrix(M)
microbenchmark(
base = det(M),
EigenR = Eigen_det(M),
EigenR_sparse = Eigen_det(Ms), # :-(
times = 200L
)
```

Determinants of complex matrices are supported:

```{r det_cplx_benchmark}
set.seed(666L)
Mr <- matrix(rnorm(100L*100L, mean = 1), 100L, 100L)
Mi <- matrix(rnorm(100L*100L, mean = 1), 100L, 100L)
M <- Mr + 1i * Mi
library(complexplus)
microbenchmark(
EigenR = Eigen_det(M), # :-)
complexplus = Det(M),
times = 30L
)
```

## Inverse matrix

```{r inverse_benchmark}
set.seed(666L)
M <- matrix(rnorm(100L*100L), 100L, 100L)
microbenchmark(
base = solve(M),
EigenR = Eigen_inverse(M), # :-)
times = 500L
)
```

## Pseudo-inverse matrix

```{r pseudoinverse_benchmark}
set.seed(666L)
M <- matrix(rnorm(100L*70L), 100L, 70L)
library(MASS)
library(pracma)
microbenchmark(
MASS = ginv(M),
pracma = pinv(M),
EigenR = Eigen_pinverse(M), # :-)
times = 500L
)
```

## Cholesky decomposition

```{r chol_benchmark}
set.seed(666L)
M <- matrix(rpois(10000L, 25), 100L, 100L)
A <- crossprod(M)
microbenchmark(
base = chol(A),
EigenR = Eigen_chol(A),
times = 1000L
)
```

Cholesky decomposition of complex matrices is supported.

## Pivoted Cholesky decomposition

```{r UtDU_benchmark, warning=FALSE}
set.seed(666L)
M <- matrix(rgamma(202L*199L, 10), 202L, 199L)
M <- cbind(M, M[, 1L] + 3*M[, 2L])
A <- crossprod(M)
microbenchmark(
base = chol(A, pivot = TRUE),
EigenR = Eigen_UtDU(A), # :-)
times = 1000L
)
```

Pivoted Cholesky decomposition of complex matrices is supported.

## Kernel

```{r kernel_benchmark}
set.seed(666L)
M <- matrix(rpois(10000L, 25), 100L, 100L)
A <- cbind(M, M)
At <- t(A)
library(MASS)
microbenchmark(
MASS = Null(At),
EigenR_LU = Eigen_kernel(A, method = "LU"), # :-)
EigenR_COD = Eigen_kernel(A, method = "COD"),
times = 100L
)
```

## Linear least-squares problems

```{r lsSolve_benchmark}
set.seed(666L)
n <- 700L; p <- 200L
A <- matrix(rnorm(n * p), n, p)
b <- rnorm(n)
microbenchmark(
stats = lm.fit(A, b),
EigenR_svd = Eigen_lsSolve(A, b, method = "svd"), # :-(
EigenR_cod = Eigen_lsSolve(A, b, method = "cod"), # :-)
times = 100L
)
```

Complex matrices `A` and `b` are supported.

## Exponential

```{r exp_benchmark}
set.seed(666L)
M <- matrix(rnorm(40L*40L, mean = 1), 40L, 40L)
microbenchmark(
expm = expm::expm(M),
EigenR = Eigen_exp(M), # :-)
times = 500L
)
```

Exponential of complex matrices is supported:

```{r exp_cplx_benchmark}
set.seed(666L)
Mr <- matrix(rnorm(40L*40L, mean = 1), 40L, 40L)
Mi <- matrix(rnorm(40L*40L, mean = 1), 40L, 40L)
M <- Mr + 1i * Mi
library(complexplus)
microbenchmark(
complexplus = matexp(M),
EigenR = Eigen_exp(M), # :-)
times = 500L
)
```

## Schur decomposition

```{r schur_real}
set.seed(666L)
M <- matrix(rnorm(200L*200L, mean = 1), 200L, 200L)
library(Matrix)
microbenchmark(
Matrix = Schur(M),
EigenR = Eigen_realSchur(M), # :-)
times = 50L
)
```

Use `Eigen_complexSchur` for the complex Schur decomposition.