A Simple Way to Specify Symmetric, Block Diagonal Matrices (2024)

The goal of lotri is to easily specify block-diagonal matrices with (lo)wer (tri)angular matrices. Its as if you have won the (badly spelled) lotri (or lottery).

This was made to allow people (like me) to specify lower triangular matrices similar to the domain specific language implemented in nlmixr. Originally I had it included in RxODE, but thought it may have more general applicability, so I separated it into a new package.

Installation

You can install the released version of lotri from CRAN with:

And the development version from GitHub with:

# install.packages("devtools")devtools::install_github("nlmixrdevelopment/lotri")

Example

This is a basic example for an easier way to specify matrices in R. For instance to fully specify a simple 2x2 matrix, in R you specify:

mat <- matrix(c(1, 0.5, 0.5, 1),nrow=2,ncol=2,dimnames=list(c("a", "b"), c("a", "b")))

With lotri, you simply specify:

library(lotri)library(microbenchmark)library(ggplot2)mat <- lotri(a+b ~ c(1, 0.5, 1))print(mat)#> a b#> a 1.0 0.5#> b 0.5 1.0

I find it more legible and easier to specify, especially if you have a more complex matrix. For instance with the more complex matrix:

mat <- lotri({ a+b ~ c(1, 0.5, 1) c ~ 1 d +e ~ c(1, 0.5, 1)})print(mat)#> a b c d e#> a 1.0 0.5 0 0.0 0.0#> b 0.5 1.0 0 0.0 0.0#> c 0.0 0.0 1 0.0 0.0#> d 0.0 0.0 0 1.0 0.5#> e 0.0 0.0 0 0.5 1.0

To fully specify this in base R you would need to use:

mat <- matrix(c(1, 0.5, 0, 0, 0, 0.5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 0.5, 1), nrow=5, ncol=5, dimnames= list(c("a", "b", "c", "d", "e"), c("a", "b", "c", "d", "e")))print(mat)#> a b c d e#> a 1.0 0.5 0 0.0 0.0#> b 0.5 1.0 0 0.0 0.0#> c 0.0 0.0 1 0.0 0.0#> d 0.0 0.0 0 1.0 0.5#> e 0.0 0.0 0 0.5 1.0

Of course with the excellent Matrix package this is a bit easier:

library(Matrix)mat <- matrix(c(1, 0.5, 0.5, 1), nrow=2, ncol=2, dimnames=list(c("a", "b"), c("a", "b")))mat <- bdiag(list(mat, matrix(1), mat))## Convert back to standard matrixmat <- as.matrix(mat)##dimnames(mat) <- list(c("a", "b", "c", "d", "e"), c("a", "b", "c", "d", "e"))print(mat)#> a b c d e#> a 1.0 0.5 0 0.0 0.0#> b 0.5 1.0 0 0.0 0.0#> c 0.0 0.0 1 0.0 0.0#> d 0.0 0.0 0 1.0 0.5#> e 0.0 0.0 0 0.5 1.0

Regardless, I think lotri is a bit easier to use.

lotri also allows lists of matrices to be created by conditioning on an id with the | syntax.

For example:

mat <- lotri({ a+b ~ c(1, 0.5, 1) | id c ~ 1 | occ d + e ~ c(1, 0.5, 1) | id(lower=3, upper=2, omegaIsChol=FALSE)})print(mat)#> $id#> d e#> d 1.0 0.5#> e 0.5 1.0#> #> $occ#> c#> c 1#> #> Properties: lower, upper, omegaIsCholprint(mat$lower)#> $id#> d e #> 3 3 #> #> $occ#> c #> -Infprint(mat$upper)#> $id#> d e #> 2 2 #> #> $occ#> c #> Infprint(mat$omegaIsChol)#> $id#> [1] FALSE

This gives a list of matrix(es) conditioned on the variable after the |. It also can add properties to each list that can be accessible after the list of matrices is returned, as shown in the above example. To do this, you simply have to enclose the properties after the conditional variable. That is et1 ~ id(lower=3).

Combining symmetric (named) matrices

Now there is even a faster way to do a similar banded matrix concatenation with lotriMat

testList <- list(lotri({et2 + et3 + et4 ~ c(40, 0.1, 20, 0.1, 0.1, 30)}), lotri(et5 ~ 6), lotri(et1+et6 ~c(0.1, 0.01, 1)), matrix(c(1L, 0L, 0L, 1L), 2, 2, dimnames=list(c("et7", "et8"), c("et7", "et8"))))matf <- function(.mats){ .omega <- as.matrix(Matrix::bdiag(.mats)) .d <- unlist(lapply(seq_along(.mats), function(x) { dimnames(.mats[[x]])[2] })) dimnames(.omega) <- list(.d, .d) return(.omega)}print(matf(testList))#> et2 et3 et4 et5 et1 et6 et7 et8#> et2 40.0 0.1 0.1 0 0.00 0.00 0 0#> et3 0.1 20.0 0.1 0 0.00 0.00 0 0#> et4 0.1 0.1 30.0 0 0.00 0.00 0 0#> et5 0.0 0.0 0.0 6 0.00 0.00 0 0#> et1 0.0 0.0 0.0 0 0.10 0.01 0 0#> et6 0.0 0.0 0.0 0 0.01 1.00 0 0#> et7 0.0 0.0 0.0 0 0.00 0.00 1 0#> et8 0.0 0.0 0.0 0 0.00 0.00 0 1print(lotriMat(testList))#> et2 et3 et4 et5 et1 et6 et7 et8#> et2 40.0 0.1 0.1 0 0.00 0.00 0 0#> et3 0.1 20.0 0.1 0 0.00 0.00 0 0#> et4 0.1 0.1 30.0 0 0.00 0.00 0 0#> et5 0.0 0.0 0.0 6 0.00 0.00 0 0#> et1 0.0 0.0 0.0 0 0.10 0.01 0 0#> et6 0.0 0.0 0.0 0 0.01 1.00 0 0#> et7 0.0 0.0 0.0 0 0.00 0.00 1 0#> et8 0.0 0.0 0.0 0 0.00 0.00 0 1mb <- microbenchmark(matf(testList),lotriMat(testList))print(mb)#> Unit: microseconds#> expr min lq mean median uq max neval#> matf(testList) 459.609 471.7575 543.02145 479.706 516.7105 4697.318 100#> lotriMat(testList) 2.280 2.8195 4.21159 3.303 4.6460 46.721 100autoplot(mb)#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.

A Simple Way to Specify Symmetric, Block Diagonal Matrices (1)

You may also combine named and unnamed matrices, but the resulting matrix will be unnamed, and still be faster than Matrix:

testList <- list(lotri({et2 + et3 + et4 ~ c(40, 0.1, 20, 0.1, 0.1, 30)}), lotri(et5 ~ 6), lotri(et1+et6 ~c(0.1, 0.01, 1)), matrix(c(1L, 0L, 0L, 1L), 2, 2))matf <- function(.mats){ .omega <- as.matrix(Matrix::bdiag(.mats)) return(.omega)}print(matf(testList))#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]#> [1,] 40.0 0.1 0.1 0 0.00 0.00 0 0#> [2,] 0.1 20.0 0.1 0 0.00 0.00 0 0#> [3,] 0.1 0.1 30.0 0 0.00 0.00 0 0#> [4,] 0.0 0.0 0.0 6 0.00 0.00 0 0#> [5,] 0.0 0.0 0.0 0 0.10 0.01 0 0#> [6,] 0.0 0.0 0.0 0 0.01 1.00 0 0#> [7,] 0.0 0.0 0.0 0 0.00 0.00 1 0#> [8,] 0.0 0.0 0.0 0 0.00 0.00 0 1print(lotriMat(testList))#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]#> [1,] 40.0 0.1 0.1 0 0.00 0.00 0 0#> [2,] 0.1 20.0 0.1 0 0.00 0.00 0 0#> [3,] 0.1 0.1 30.0 0 0.00 0.00 0 0#> [4,] 0.0 0.0 0.0 6 0.00 0.00 0 0#> [5,] 0.0 0.0 0.0 0 0.10 0.01 0 0#> [6,] 0.0 0.0 0.0 0 0.01 1.00 0 0#> [7,] 0.0 0.0 0.0 0 0.00 0.00 1 0#> [8,] 0.0 0.0 0.0 0 0.00 0.00 0 1mb <- microbenchmark(matf(testList),lotriMat(testList))print(mb)#> Unit: microseconds#> expr min lq mean median uq max neval#> matf(testList) 453.898 464.4790 511.40373 489.6425 517.6250 2004.861 100#> lotriMat(testList) 2.254 2.7245 4.07269 4.0970 4.5285 11.251 100autoplot(mb)#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.

A Simple Way to Specify Symmetric, Block Diagonal Matrices (2)

New features

A new feature is the ability to condition on variables by |. This will be useful when simulating nested random effects using the upcoming RxODE

A Simple Way to Specify Symmetric, Block Diagonal Matrices (2024)

FAQs

How to find a block diagonal matrix? ›

B = blkdiag( A1,...,AN ) returns the block diagonal matrix created by aligning the input matrices A1,...,AN along the diagonal of B .

Does a diagonal matrix have to be symmetric? ›

A diagonal matrix is defined as a square matrix in which all off-diagonal entries are zero. (Note that a diagonal matrix is necessarily symmetric.) Entries on the main diagonal may or may not be zero.

How do you create a block diagonal matrix in R? ›

By utilizing the bdiag() function, users can efficiently create block diagonal matrices from existing matrices, random data, or combinations of matrices and zeros. This versatility makes R a preferred choice for various mathematical and statistical tasks involving block diagonal matrices.

Is the transpose of a diagonal matrix a diagonal matrix? ›

1. The transpose of a diagonal matrix is equal to the original matrix. 2. Sums and differences of diagonal matrices are also diagonal matrices.

How do you represent a diagonal matrix? ›

A square matrix in which every element except the principal diagonal elements is zero is called a Diagonal Matrix. A square matrix D = [dij]n x n will be called a diagonal matrix if dij = 0, whenever i is not equal to j. There are many types of matrices like the Identity matrix.

What is the notation for block diagonal matrix? ›

Block diagonal matrices

It can also be indicated as A1 ⊕ A2 ⊕ ... ⊕ An or diag(A1, A2, ..., An) (the latter being the same formalism used for a diagonal matrix).

How do you define a diagonal matrix in R? ›

In R, one can create a diagonal n by n matrix from an n-length vector x via diag(x). The output has the elements of x on the diagonal, and 0 on the off-diagonal elements. Likewise, one can make an identity n by n matrix by supplying an integer n, so diag(n) is the identity matrix of dimension n by n.

How do you make a block matrix? ›

Block matrices can be created using ArrayFlatten. When two block matrices have the same shape and their diagonal blocks are square matrices, then they multiply similarly to matrix multiplication.

How do you select the diagonal elements of a matrix in R? ›

If x is a matrix then diag(x) returns the diagonal of x . The resulting vector will have names if the matrix x has matching column and row names. If x is a vector (or a 1-d array) then diag(x) returns a diagonal matrix whose diagonal is x .

What is an example of a diagonal matrix? ›

Identity matrix, null matrix, and scalar matrix are examples of a diagonal matrix as each of them has its non-principal diagonal elements to be zeros. The sum of two diagonal matrices is a diagonal matrix.

Does the diagonal stay the same in a transpose? ›

Clearly, the diagonal entries are the same, as the transpose does not change them.

Can diagonal matrix be negative? ›

No, the positive definite matrix cannot have negative diagonal elements, because for any diagonal negative element, Ajj A j j , one could choose a vector x=ej x = e j , which is the unit vector with 1 at the j th position and 0 elsewhere, such that xTAx<0.

What is the formula for finding the diagonal matrix? ›

Diagonalization of any square matrix is the ability to find a diagonal matrix such that: D = P − 1 ∗ A ∗ P , where matrix is an invertible matrix. This means that matrix A can be turned into a diagonal matrix D by using an invertible matrix P.

How do I find the diagonal of a matrix? ›

Diagonal Elements of a Matrix

An element aij of a matrix A = [aij] is a diagonal elements of matrix if i = j, such as when rows and column suffixes are equal. Thus, a11 , a22 , a33, a44, … so on are diagonal elements of the matrix A = [aij]. The principal diagonal is also known as the leading diagonal.

How do you find the diagonal sum of a matrix? ›

Approaches to Compute Diagonal Sum

Efficient Approach: For square matrices, we can use an optimized approach where we add the elements of the main diagonal at index i to the sum directly using matrix[i][i]. This approach avoids unnecessary iterations and is more efficient for larger matrices.

What is the determinant of the block diagonal matrix? ›

  1. The determinant of a block diagonal matrix is equal to the product of the determinants of the diagonal blocks. In your case, you have a block diagonal matrix of the form A=(A1000A2000A3) ...
  2. You can, though it is a bit ad-hoc. For example, note that if we let T1=(100000000010000000001000000)
May 23, 2012

References

Top Articles
Wedding Gift Etiquette: Your Complete Guide To Gifting | The Wedding Shop
Wedding Dress and Bridal Wear Outlet in Burbage | Your Wedding Shop
Cranes For Sale in United States| IronPlanet
Printable Whoville Houses Clipart
Walgreens Pharmqcy
Craftsman M230 Lawn Mower Oil Change
Craigslist Cars And Trucks Buffalo Ny
Oscar Nominated Brings Winning Profile to the Kentucky Turf Cup
Insidekp.kp.org Hrconnect
The Witcher 3 Wild Hunt: Map of important locations M19
Moparts Com Forum
Moonshiner Tyler Wood Net Worth
065106619
New Stores Coming To Canton Ohio 2022
Slope Tyrones Unblocked Games
Www Craigslist Milwaukee Wi
X-Chromosom: Aufbau und Funktion
BMW K1600GT (2017-on) Review | Speed, Specs & Prices
Isaidup
Panolian Batesville Ms Obituaries 2022
Reviews over Supersaver - Opiness - Spreekt uit ervaring
Deshuesadero El Pulpo
Why Are Fuel Leaks A Problem Aceable
Greensboro sit-in (1960) | History, Summary, Impact, & Facts
Bra Size Calculator & Conversion Chart: Measure Bust & Convert Sizes
EVO Entertainment | Cinema. Bowling. Games.
Cal State Fullerton Titan Online
Calvin Coolidge: Life in Brief | Miller Center
APUSH Unit 6 Practice DBQ Prompt Answers & Feedback | AP US History Class Notes | Fiveable
Kids and Adult Dinosaur Costume
Roadtoutopiasweepstakes.con
The Hoplite Revolution and the Rise of the Polis
Www Craigslist Com Shreveport Louisiana
Tributes flow for Soundgarden singer Chris Cornell as cause of death revealed
Dreammarriage.com Login
October 31St Weather
Dadeclerk
How much does Painttool SAI costs?
This 85-year-old mom co-signed her daughter's student loan years ago. Now she fears the lender may take her house
2023 Fantasy Football Draft Guide: Rankings, cheat sheets and analysis
Lcwc 911 Live Incident List Live Status
Isabella Duan Ahn Stanford
Is Ameriprise A Pyramid Scheme
What Is The Optavia Diet—And How Does It Work?
John Wick: Kapitel 4 (2023)
Bridgeport Police Blotter Today
Bank Of America Appointments Near Me
Model Center Jasmin
Mawal Gameroom Download
Palmyra Authentic Mediterranean Cuisine مطعم أبو سمرة
Ihop Deliver
Latest Posts
Article information

Author: Edwin Metz

Last Updated:

Views: 5558

Rating: 4.8 / 5 (78 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Edwin Metz

Birthday: 1997-04-16

Address: 51593 Leanne Light, Kuphalmouth, DE 50012-5183

Phone: +639107620957

Job: Corporate Banking Technician

Hobby: Reading, scrapbook, role-playing games, Fishing, Fishing, Scuba diving, Beekeeping

Introduction: My name is Edwin Metz, I am a fair, energetic, helpful, brave, outstanding, nice, helpful person who loves writing and wants to share my knowledge and understanding with you.