qwalkr

qwalkr is a package for the analysis of the time evolution of quantum walks. The package consists mainly of methods for the numerical estimation of matrices that arise in this field of research. This vignette intends to give an overview of the core functionalities provided by qwalkr.

Installation

You can install the stable version of qwalkr from CRAN:

install.packages("qwalkr")

For the development version, you can install from Github like so:

# install.packages("devtools")
devtools::install_github("vitormarquesr/qwalkr")

Usage

To use qwalkr, you must first load it like so:

library(qwalkr)

Now, you are all set.

Creating a Quantum Walk

At the moment, qwalkr only supports continuous-time quantum walks.

You can create a continuous-time quantum walk by calling qwalkr::ctqwalk() with an additional argument representing the Hamiltonian of the system i.e. a hermitian matrix. For instance, let’s create a walk on the complete graph of order three (\(K_3\)), the Hamiltonian is going to be its adjacency matrix.


K3 <- rbind(c(0, 1, 1),
           c(1, 0, 1),
           c(1, 1, 0))
w <- ctqwalk(hamiltonian = K3)

The ctqwalk object stores the spectral decomposition of the Hamiltonian for future usage by other methods. We can get a glimpse of the eigenvalues and their multiplicities by printing the object.

w
#> Continuous-Time Quantum Walk
#> 
#> [+]Order: 3 
#> 
#> [+]Spectrum of the Hamiltonian:
#>                   
#> Eigenvalue:   2 -1
#> Multiplicity: 1  2

qwalkr::ctqwalk() runs qwalkr::spectral() under the hood and tries to infer eigenvalue multiplicity, you can disable this feature with multiplicity=FALSE or set the tolerance for numerical equality with tol.

Let’s talk a bit about spectral, the linear algebra system used by qwalkr.

Linear Algebra System - Spectral

qwalkr::spectral() is a constructor for class spectral which enhances base R spectral decomposition function base::eigen(), providing specialized treatment for hermitian matrices. Its constructor and methods can handle repeated eigenvalues, orthogonal projectors, matrix functions, and so on.

You can create an instance by providing a hermitian matrix to qwalkr::spectral():

A <- rbind(c(0, 1, 1),
           c(1, 0, 1),
           c(1, 1, 0))

s <- spectral(A)

The object stores the ordered eigenvalues (descending) and their multiplicities alongside their eigenvectors:

s
#> $eigvals
#> [1]  2 -1
#> 
#> $multiplicity
#> [1] 1 2
#> 
#> $eigvectors
#>           [,1]       [,2]       [,3]
#> [1,] 0.5773503  0.8164966  0.0000000
#> [2,] 0.5773503 -0.4082483 -0.7071068
#> [3,] 0.5773503 -0.4082483  0.7071068
#> 
#> attr(,"class")
#> [1] "spectral"

You can turn off eigenvalue multiplicity inference with multiplicity=FALSE and set the tolerance for numerical equality with tol=1e-10.

Methods

With a spectral instance in hand, we can extract several matrices of interest. Use qwalkr::get_eigspace() to extract the eigenspace associated with an eigenvalue. For instance, let’s extract the eigenvectors corresponding to the eigenvalue -1 by providing its index in the ordered spectra (two in this case)


get_eigspace(s, id = 2)
#>            [,1]       [,2]
#> [1,]  0.8164966  0.0000000
#> [2,] -0.4082483 -0.7071068
#> [3,] -0.4082483  0.7071068

Since the eigenvalue -1 has multiplicity two, its eigenspace has dimension two as well, thus we get two eigenvectors. If we extract the 2-eigenspace, we only get one vector.


get_eigspace(s, id=1)
#>           [,1]
#> [1,] 0.5773503
#> [2,] 0.5773503
#> [3,] 0.5773503

We can extract the orthogonal projector onto the -1-eigenspace by calling qwalkr::get_eigproj() in the same way as the previous function:


E2 <- get_eigproj(s, id=2)
E2
#>            [,1]       [,2]       [,3]
#> [1,]  0.6666667 -0.3333333 -0.3333333
#> [2,] -0.3333333  0.6666667 -0.3333333
#> [3,] -0.3333333 -0.3333333  0.6666667

Since the eigenspace has dimension two, its trace (qwalkr::tr()) is going to take such a value


tr(E2)
#> [1] 2

As to the 2-eigenspace we get

E1 <- get_eigproj(s, id=1)
E1
#>           [,1]      [,2]      [,3]
#> [1,] 0.3333333 0.3333333 0.3333333
#> [2,] 0.3333333 0.3333333 0.3333333
#> [3,] 0.3333333 0.3333333 0.3333333

tr(E1)
#> [1] 1

For additional methods for class spectral check its help page.

Quantum Walks of class spectral

As with continuous-time quantum walks, some walks have their evolution influenced by the spectrum of the Hamiltonian. In such a case, the class representing the walk is also a child of spectral and thus inherits its methods. For instance, a ctqwalk object is also an instance of spectral, and hence the methods of the previous section apply:

w
#> Continuous-Time Quantum Walk
#> 
#> [+]Order: 3 
#> 
#> [+]Spectrum of the Hamiltonian:
#>                   
#> Eigenvalue:   2 -1
#> Multiplicity: 1  2

get_eigspace(w, id=2)
#>            [,1]       [,2]
#> [1,]  0.8164966  0.0000000
#> [2,] -0.4082483 -0.7071068
#> [3,] -0.4082483  0.7071068

class(w)
#> [1] "ctqwalk"  "spectral"

Time-Evolution

You can get the unitary time evolution operator of the walk by calling qwalkr::unitary_matrix() with the time t you want to evaluate it at. Let’s take a look at the operator of the walk on \(K_3\) at time \(t=\frac{\pi}{3}\):

unitary_matrix(w, t=pi/3)
#>                       [,1]                  [,2]                  [,3]
#> [1,]  0.1666667-0.2886751i -0.3333333+0.5773503i -0.3333333+0.5773503i
#> [2,] -0.3333333+0.5773503i  0.1666667-0.2886751i -0.3333333+0.5773503i
#> [3,] -0.3333333+0.5773503i -0.3333333+0.5773503i  0.1666667-0.2886751i

Analogously, the mixing matrix of the walk can be obtained with qwalkr::mixing_matrix():

mixing_matrix(w, t=pi/3)
#>           [,1]      [,2]      [,3]
#> [1,] 0.1111111 0.4444444 0.4444444
#> [2,] 0.4444444 0.1111111 0.4444444
#> [3,] 0.4444444 0.4444444 0.1111111

Average Evolution

Use qwalkr::avg_matrix() to obtain the (standard) average mixing matrix:

avg_matrix(w)
#>           [,1]      [,2]      [,3]
#> [1,] 0.5555556 0.2222222 0.2222222
#> [2,] 0.2222222 0.5555556 0.2222222
#> [3,] 0.2222222 0.2222222 0.5555556

To instead calculate the (generalized) average mixing matrix under an arbitrary probability distribution, call qwalkr::gavg_matrix() with an additional parameter R containing samples of the desired distribution. For instance, the average mixing matrix of \(K_3\) under a standard Exponential random variable can be obtained with:

set.seed(10)
gavg_matrix(w, R=rexp(1000))
#>           [,1]      [,2]      [,3]
#> [1,] 0.6017741 0.1991130 0.1991130
#> [2,] 0.1991130 0.6017741 0.1991130
#> [3,] 0.1991130 0.1991130 0.6017741