Nonmoralizing model
Global interaction quantum stochastic walk suffers from creating additional connections. This renders it unsuitable for constructing fast quantum walks on directed graphs. To counteract this effect, the nonmoralizing quantum stochastic walk was introduced (see arXiv preprint and its published version). Such a model is constructed in several steps. First, the dimensionality of the system is increased by attaching a multidimensional subspace to each vertex. Next, the Hamiltonian and the Lindblad operators are modified, and an additional Hamiltonian - so-called local Hamiltonian - is introduced.
Please note that current definition of nm_glob_ham
differs from the one presented in the paper.
Below we present additional functionality useful for analyzing nonmoralizing quantum stochastic walk. By default, the operator is generalized as in the original paper.
QSWalk.Vertex
QSWalk.VertexSet
QSWalk.default_nm_loc_ham
QSWalk.fourier_matrix
QSWalk.make_vertex_set
QSWalk.nm_glob_ham
QSWalk.nm_init
QSWalk.nm_lind
QSWalk.nm_loc_ham
QSWalk.nm_measurement
QSWalk.subspace
QSWalk.vertexsetsize
QSWalk.vlist
Full docs
QSWalk.Vertex
— Typetype Vertex
Type consisting of list of Int
, describing the labels of vectors from the canonical basis corresponding to the Vertex
. To get the vector label one can use Vertex()
function, or Vertex[i]
for a unique label.
See [1] for the more information and usage exmaples.
[1] K. Domino, A. Glos, M. Ostaszewski, Superdiffusive quantum stochastic walk definable on arbitrary directed graph, Quantum Information & Computation, Vol.17 No.11&12, pp. 0973-0986, arXiv:1701.04624.
QSWalk.VertexSet
— Typetype VertexSet
Type consisting of a list of Vertex
objects. It describes the partition of the linear subspace. Object of this type should be constructed using make_vertex_set
or by nm_lind
functions. In order to get a list of the vertices from an object of type vertexset
, one should use vlist
function, or, for a specific Vertex
, an getindex function vertexset[i]
.
QSWalk.nm_glob_ham
— Functionnm_glob_ham(A[, hamiltonians][, weights, epsilon])
Return global Hamiltonian for the moralization procedure. Matrix A
should the adjacency matrix of a directed graph, for which one aims to construct the nonmoralizing dynamics. Here, hamiltonians
is an optional argument which is a Dictionary with keys of type Tuple{Int, Int}
or Tuple{Vertex, Vertex}
. The first collects the submatrices according to their shape, while the second collects them according to each pair of vertices. As the default all-one submatrices are chosen. The last argument states that only those elements for which abs(A[i, j]) >= epsilon
are considered.
Note: The submatrices of the result matrix are scaled by corresponding weights
argument, which should be a square matrix of the same dimension as A
. If weights
is not provided, then weights[i,j]=A[i,j]
, if A[i,j]
is nonzero and A[j,i]
is zero, weights[i,j]=A[j,i]
, if A[i,j]
in reverse scenario, weights[i,j]=(A[i,j]+A[j,i])/2
if both are nonzero, and zero otherwise.
Examples
julia> A = [ 0 1 0; 1 0 1; 0 1 0]
3×3 Array{Int64,2}:
0 1 0
1 0 1
0 1 0
julia> nm_glob_ham(A) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
1.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im
1.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
julia> dict_deg = Dict{Tuple{Int,Int},Matrix{ComplexF64}}((1, 2) => (2+1im)*ones(1, 2), (2, 1) =>1im*ones(2, 1));
julia> nm_glob_ham(A, dict_deg) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 2.0+1.0im 2.0+1.0im 0.0+0.0im
2.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
2.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
0.0+0.0im 0.0-1.0im 0.0-1.0im 0.0+0.0im
julia> v1, v2, v3 = vlist(make_vertex_set(A))
3-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3])
Vertex([4])
julia> dict_vec = Dict{Tuple{Vertex,Vertex},Matrix{ComplexF64}}((v1, v2) =>2*ones(1, 2), (v2, v3) =>[1im 2im;]');
julia> nm_glob_ham(A, dict_vec) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 2.0+0.0im 2.0+0.0im 0.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-1.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-2.0im
0.0+0.0im 0.0+1.0im 0.0+2.0im 0.0+0.0im
nm_glob_ham(A[, hamiltonians][, weights, epsilon])
Return global Hamiltonian for the moralization procedure. Matrix A
should the adjacency matrix of a directed graph, for which one aims to construct the nonmoralizing dynamics. Here, hamiltonians
is an optional argument which is a Dictionary with keys of type Tuple{Int, Int}
or Tuple{Vertex, Vertex}
. The first collects the submatrices according to their shape, while the second collects them according to each pair of vertices. As the default all-one submatrices are chosen. The last argument states that only those elements for which abs(A[i, j]) >= epsilon
are considered.
Note: The submatrices of the result matrix are scaled by corresponding weights
argument, which should be a square matrix of the same dimension as A
. If weights
is not provided, then weights[i,j]=A[i,j]
, if A[i,j]
is nonzero and A[j,i]
is zero, weights[i,j]=A[j,i]
, if A[i,j]
in reverse scenario, weights[i,j]=(A[i,j]+A[j,i])/2
if both are nonzero, and zero otherwise.
Examples
julia> A = [ 0 1 0; 1 0 1; 0 1 0]
3×3 Array{Int64,2}:
0 1 0
1 0 1
0 1 0
julia> nm_glob_ham(A) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
1.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im
1.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
julia> dict_deg = Dict{Tuple{Int,Int},Matrix{ComplexF64}}((1, 2) => (2+1im)*ones(1, 2), (2, 1) =>1im*ones(2, 1));
julia> nm_glob_ham(A, dict_deg) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 2.0+1.0im 2.0+1.0im 0.0+0.0im
2.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
2.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
0.0+0.0im 0.0-1.0im 0.0-1.0im 0.0+0.0im
julia> v1, v2, v3 = vlist(make_vertex_set(A))
3-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3])
Vertex([4])
julia> dict_vec = Dict{Tuple{Vertex,Vertex},Matrix{ComplexF64}}((v1, v2) =>2*ones(1, 2), (v2, v3) =>[1im 2im;]');
julia> nm_glob_ham(A, dict_vec) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 2.0+0.0im 2.0+0.0im 0.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-1.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-2.0im
0.0+0.0im 0.0+1.0im 0.0+2.0im 0.0+0.0im
nm_glob_ham(A[, hamiltonians][, weights, epsilon])
Return global Hamiltonian for the moralization procedure. Matrix A
should the adjacency matrix of a directed graph, for which one aims to construct the nonmoralizing dynamics. Here, hamiltonians
is an optional argument which is a Dictionary with keys of type Tuple{Int, Int}
or Tuple{Vertex, Vertex}
. The first collects the submatrices according to their shape, while the second collects them according to each pair of vertices. As the default all-one submatrices are chosen. The last argument states that only those elements for which abs(A[i, j]) >= epsilon
are considered.
Note: The submatrices of the result matrix are scaled by corresponding weights
argument, which should be a square matrix of the same dimension as A
. If weights
is not provided, then weights[i,j]=A[i,j]
, if A[i,j]
is nonzero and A[j,i]
is zero, weights[i,j]=A[j,i]
, if A[i,j]
in reverse scenario, weights[i,j]=(A[i,j]+A[j,i])/2
if both are nonzero, and zero otherwise.
Examples
julia> A = [ 0 1 0; 1 0 1; 0 1 0]
3×3 Array{Int64,2}:
0 1 0
1 0 1
0 1 0
julia> nm_glob_ham(A) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
1.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im
1.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
julia> dict_deg = Dict{Tuple{Int,Int},Matrix{ComplexF64}}((1, 2) => (2+1im)*ones(1, 2), (2, 1) =>1im*ones(2, 1));
julia> nm_glob_ham(A, dict_deg) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 2.0+1.0im 2.0+1.0im 0.0+0.0im
2.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
2.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
0.0+0.0im 0.0-1.0im 0.0-1.0im 0.0+0.0im
julia> v1, v2, v3 = vlist(make_vertex_set(A))
3-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3])
Vertex([4])
julia> dict_vec = Dict{Tuple{Vertex,Vertex},Matrix{ComplexF64}}((v1, v2) =>2*ones(1, 2), (v2, v3) =>[1im 2im;]');
julia> nm_glob_ham(A, dict_vec) |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 2.0+0.0im 2.0+0.0im 0.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-1.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-2.0im
0.0+0.0im 0.0+1.0im 0.0+2.0im 0.0+0.0im
QSWalk.nm_lind
— Functionnm_lind(A[, lindbladians][, epsilon])
Return single Lindbladian operator and a vertex set describing how vertices are bound to subspaces. The operator is constructed according to the corection scheme presented in [1]. Parameter A
is a square matrix, describing the connection between the canonical subspaces in a similar manner as the adjacency matrix. Parameter epsilon
, with the default value eps()
, determines the relevant values by abs(A[i, j]) >= epsilon
formula. List lindbladians
describes the elementary matrices used. It can be Dict{Int, SparseDenseMatrix}
, which returns the matrix by the indegree, or Dict{Vertex, SparseDenseMatrix}
which, for different vertices, may return different matrix. The matrix should have orthogonal columns and be of the size outdeg of the vertex. As default the function uses Fourier matrices.
Note: It is expected that for all pair of vertices there exists a matrix in the lindbladians
list.
Note: The orthogonality of matrices in lindbladians
is not verified.
Note: The submatrices of the result matrix are multiplied by corresponding A
element.
[1] K. Domino, A. Glos, M. Ostaszewski, Superdiffusive quantum stochastic walk definable on arbitrary directed graph, Quantum Information & Computation, Vol.17 No.11&12, pp. 0973-0986, arXiv:1701.04624.
Examples
julia> A = [0 1 0; 1 0 1; 0 1 0]
3×3 Array{Int64,2}:
0 1 0
1 0 1
0 1 0
julia> L, vset = nm_lind(A)
(
[2, 1] = 1.0+0.0im
[3, 1] = 1.0+0.0im
[1, 2] = 1.0+0.0im
[4, 2] = 1.0+0.0im
[1, 3] = 1.0+0.0im
[4, 3] = 1.0+0.0im
[2, 4] = 1.0+0.0im
[3, 4] = -1.0+1.22465e-16im, VertexSet(Vertex[Vertex([1]), Vertex([2, 3]), Vertex([4])]))
julia> B1, B2 = 2*diagm(0=>[1.]), 3*ones(2, 2)
([2.0], [3.0 3.0; 3.0 3.0])
julia> nm_lind(A, Dict{Int,Matrix{Float64}}(1=>B1, 2=>B2))
(
[2, 1] = 3.0+0.0im
[3, 1] = 3.0+0.0im
[1, 2] = 2.0+0.0im
[4, 2] = 2.0+0.0im
[1, 3] = 2.0+0.0im
[4, 3] = 2.0+0.0im
[2, 4] = 3.0+0.0im
[3, 4] = 3.0+0.0im, VertexSet(Vertex[Vertex([1]), Vertex([2, 3]), Vertex([4])]))
julia> v1, v2, v3 = vlist(vset)
3-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3])
Vertex([4])
julia> nm_lind(A, Dict{Vertex,Matrix{Float64}}(v1 => ones(1, 1), v2 => [2 2; 2 -2], v3 => 3*ones(1, 1)))[1] |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 2.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im -2.0+0.0im
0.0+0.0im 3.0+0.0im 3.0+0.0im 0.0+0.0im
nm_lind(A[, lindbladians][, epsilon])
Return single Lindbladian operator and a vertex set describing how vertices are bound to subspaces. The operator is constructed according to the corection scheme presented in [1]. Parameter A
is a square matrix, describing the connection between the canonical subspaces in a similar manner as the adjacency matrix. Parameter epsilon
, with the default value eps()
, determines the relevant values by abs(A[i, j]) >= epsilon
formula. List lindbladians
describes the elementary matrices used. It can be Dict{Int, SparseDenseMatrix}
, which returns the matrix by the indegree, or Dict{Vertex, SparseDenseMatrix}
which, for different vertices, may return different matrix. The matrix should have orthogonal columns and be of the size outdeg of the vertex. As default the function uses Fourier matrices.
Note: It is expected that for all pair of vertices there exists a matrix in the lindbladians
list.
Note: The orthogonality of matrices in lindbladians
is not verified.
Note: The submatrices of the result matrix are multiplied by corresponding A
element.
[1] K. Domino, A. Glos, M. Ostaszewski, Superdiffusive quantum stochastic walk definable on arbitrary directed graph, Quantum Information & Computation, Vol.17 No.11&12, pp. 0973-0986, arXiv:1701.04624.
Examples
julia> A = [0 1 0; 1 0 1; 0 1 0]
3×3 Array{Int64,2}:
0 1 0
1 0 1
0 1 0
julia> L, vset = nm_lind(A)
(
[2, 1] = 1.0+0.0im
[3, 1] = 1.0+0.0im
[1, 2] = 1.0+0.0im
[4, 2] = 1.0+0.0im
[1, 3] = 1.0+0.0im
[4, 3] = 1.0+0.0im
[2, 4] = 1.0+0.0im
[3, 4] = -1.0+1.22465e-16im, VertexSet(Vertex[Vertex([1]), Vertex([2, 3]), Vertex([4])]))
julia> B1, B2 = 2*diagm(0=>[1.]), 3*ones(2, 2)
([2.0], [3.0 3.0; 3.0 3.0])
julia> nm_lind(A, Dict{Int,Matrix{Float64}}(1=>B1, 2=>B2))
(
[2, 1] = 3.0+0.0im
[3, 1] = 3.0+0.0im
[1, 2] = 2.0+0.0im
[4, 2] = 2.0+0.0im
[1, 3] = 2.0+0.0im
[4, 3] = 2.0+0.0im
[2, 4] = 3.0+0.0im
[3, 4] = 3.0+0.0im, VertexSet(Vertex[Vertex([1]), Vertex([2, 3]), Vertex([4])]))
julia> v1, v2, v3 = vlist(vset)
3-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3])
Vertex([4])
julia> nm_lind(A, Dict{Vertex,Matrix{Float64}}(v1 => ones(1, 1), v2 => [2 2; 2 -2], v3 => 3*ones(1, 1)))[1] |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 2.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im -2.0+0.0im
0.0+0.0im 3.0+0.0im 3.0+0.0im 0.0+0.0im
nm_lind(A[, lindbladians][, epsilon])
Return single Lindbladian operator and a vertex set describing how vertices are bound to subspaces. The operator is constructed according to the corection scheme presented in [1]. Parameter A
is a square matrix, describing the connection between the canonical subspaces in a similar manner as the adjacency matrix. Parameter epsilon
, with the default value eps()
, determines the relevant values by abs(A[i, j]) >= epsilon
formula. List lindbladians
describes the elementary matrices used. It can be Dict{Int, SparseDenseMatrix}
, which returns the matrix by the indegree, or Dict{Vertex, SparseDenseMatrix}
which, for different vertices, may return different matrix. The matrix should have orthogonal columns and be of the size outdeg of the vertex. As default the function uses Fourier matrices.
Note: It is expected that for all pair of vertices there exists a matrix in the lindbladians
list.
Note: The orthogonality of matrices in lindbladians
is not verified.
Note: The submatrices of the result matrix are multiplied by corresponding A
element.
[1] K. Domino, A. Glos, M. Ostaszewski, Superdiffusive quantum stochastic walk definable on arbitrary directed graph, Quantum Information & Computation, Vol.17 No.11&12, pp. 0973-0986, arXiv:1701.04624.
Examples
julia> A = [0 1 0; 1 0 1; 0 1 0]
3×3 Array{Int64,2}:
0 1 0
1 0 1
0 1 0
julia> L, vset = nm_lind(A)
(
[2, 1] = 1.0+0.0im
[3, 1] = 1.0+0.0im
[1, 2] = 1.0+0.0im
[4, 2] = 1.0+0.0im
[1, 3] = 1.0+0.0im
[4, 3] = 1.0+0.0im
[2, 4] = 1.0+0.0im
[3, 4] = -1.0+1.22465e-16im, VertexSet(Vertex[Vertex([1]), Vertex([2, 3]), Vertex([4])]))
julia> B1, B2 = 2*diagm(0=>[1.]), 3*ones(2, 2)
([2.0], [3.0 3.0; 3.0 3.0])
julia> nm_lind(A, Dict{Int,Matrix{Float64}}(1=>B1, 2=>B2))
(
[2, 1] = 3.0+0.0im
[3, 1] = 3.0+0.0im
[1, 2] = 2.0+0.0im
[4, 2] = 2.0+0.0im
[1, 3] = 2.0+0.0im
[4, 3] = 2.0+0.0im
[2, 4] = 3.0+0.0im
[3, 4] = 3.0+0.0im, VertexSet(Vertex[Vertex([1]), Vertex([2, 3]), Vertex([4])]))
julia> v1, v2, v3 = vlist(vset)
3-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3])
Vertex([4])
julia> nm_lind(A, Dict{Vertex,Matrix{Float64}}(v1 => ones(1, 1), v2 => [2 2; 2 -2], v3 => 3*ones(1, 1)))[1] |> Matrix
4×4 Array{Complex{Float64},2}:
0.0+0.0im 1.0+0.0im 1.0+0.0im 0.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im 2.0+0.0im
2.0+0.0im 0.0+0.0im 0.0+0.0im -2.0+0.0im
0.0+0.0im 3.0+0.0im 3.0+0.0im 0.0+0.0im
QSWalk.nm_measurement
— Functionnm_measurement(probability, vertexset)
Return joint probability of probability
, which is real-valued probability vector according to vertexset
.
Note: It is up to user to provide proper probability vector.
Examples
julia> probability = [0.05, 0.1, 0.25, 0.3, 0.01, 0.20, 0.04, 0.05]
8-element Array{Float64,1}:
0.05
0.1
0.25
0.3
0.01
0.2
0.04
0.05
julia> nm_measurement(probability, VertexSet([[1, 4], [2, 3, 5], [6], [7, 8]]))
4-element Array{Float64,1}:
0.35
0.36
0.2
0.09
nm_measurement(state, vertexset)
Return joint probability of cannonical measurement of density matrix state
, according to vertexset
.
Note: It is up to user to provide proper density state.
Examples
julia> state = [1/6 0 1/6; 0 2/3 0; 1/6 0 1/6]
3×3 Array{Float64,2}:
0.166667 0.0 0.166667
0.0 0.666667 0.0
0.166667 0.0 0.166667
julia> nm_measurement(state, VertexSet([[1, 3], [2]]))
2-element Array{Float64,1}:
0.3333333333333333
0.6666666666666666
QSWalk.nm_loc_ham
— Functionnm_loc_ham(vertexset[, hamiltoniansByDegree])
Return Hamiltonian acting locally on each vertex from vertexset
linear subspace. hamiltoniansByDegree
is a dictionary Dict{Int, SparseDenseMatrix}
, which, for a given dimension of vertex linear subspace, yields a hermitian operator. Only matrices for existing dimensions needs to be specified.
Note: Value of vertexset
should be generated by make_vertex_set
in order to match demoralization procedure. Numerical analysis suggests, that hamiltonians should be complex valued.
Examples
julia> vset = VertexSet([[1, 2], [3, 4]])
VertexSet(Vertex[Vertex([1, 2]), Vertex([3, 4])])
julia> Matrix(nm_loc_ham(vset))
4×4 Array{Complex{Float64},2}:
0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im
0.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
0.0+0.0im 0.0+0.0im 0.0-1.0im 0.0+0.0im
julia> A = [1 1im; -1im 1]
2×2 Array{Complex{Int64},2}:
1+0im 0+1im
0-1im 1+0im
julia> nm_loc_ham(vset, Dict{Int,Matrix{ComplexF64}}(2 => A))
4×4 SparseArrays.SparseMatrixCSC{Complex{Float64},Int64} with 8 stored entries:
[1, 1] = 1.0+0.0im
[2, 1] = 0.0-1.0im
[1, 2] = 0.0+1.0im
[2, 2] = 1.0+0.0im
[3, 3] = 1.0+0.0im
[4, 3] = 0.0-1.0im
[3, 4] = 0.0+1.0im
[4, 4] = 1.0+0.0im
nm_loc_ham(vertexset[, hamiltoniansByVertex])
Return Hamiltonian acting locally on each vertex from vertexset
linear subspace. hamiltoniansByVertex
is a dictionary Dict{Vertex, SparseDenseMatrix}
, which, for a given vertex, yields a hermitian operator of the size equal to the dimension of the vertex subspace.
Note: Value of vertexset
should be generated by make_vertex_set
in order to match demoralization procedure. Numerical analysis suggests, that hamiltonians should be complex valued.
Examples
julia> vset = VertexSet([[1, 2], [3, 4]])
VertexSet(Vertex[Vertex([1, 2]), Vertex([3, 4])])
julia> Matrix(nm_loc_ham(vset))
4×4 Array{Complex{Float64},2}:
0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im
0.0-1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im
0.0+0.0im 0.0+0.0im 0.0-1.0im 0.0+0.0im
julia> A, B = [1 1im; -1im 1], [0 1; 1 0]
(Complex{Int64}[1 + 0im 0 + 1im; 0 - 1im 1 + 0im], [0 1; 1 0])
julia> v1, v2 = vlist(vset)
2-element Array{Vertex,1}:
Vertex([1, 2])
Vertex([3, 4])
julia> nm_loc_ham(vset, Dict{Vertex,Matrix{Number}}(v1 => A, v2 => B))
4×4 SparseArrays.SparseMatrixCSC{Complex{Float64},Int64} with 6 stored entries:
[1, 1] = 1.0+0.0im
[2, 1] = 0.0-1.0im
[1, 2] = 0.0+1.0im
[2, 2] = 1.0+0.0im
[4, 3] = 1.0+0.0im
[3, 4] = 1.0+0.0im
QSWalk.nm_init
— Functionnm_init(init_vertices, vertexset)
Create initial state in the case of the nonmoralizing evolution based on init_vertices
of type Vector{Vertex}
. The result is a block diagonal matrix, where each block corresponds to vertex from vertexset
. The final state represent an uniform probability over nm_measurement
.
Note: The function returns sparse matrix with ComplexF64
field type.
Examples
julia> vset = VertexSet([[1], [2, 3, 4], [5, 6, 7], [8, 9]])
VertexSet(Vertex[Vertex([1]), Vertex([2, 3, 4]), Vertex([5, 6, 7]), Vertex([8, 9])])
julia> nm_init(vset[[1, 3, 4]], vset)
9×9 SparseArrays.SparseMatrixCSC{Complex{Float64},Int64} with 6 stored entries:
[1, 1] = 0.333333+0.0im
[5, 5] = 0.111111+0.0im
[6, 6] = 0.111111+0.0im
[7, 7] = 0.111111+0.0im
[8, 8] = 0.166667+0.0im
[9, 9] = 0.166667+0.0im
nm_init(init_states, vertexset)
Create initial state in the case of the nonmoralizing evolution based on init_states
of type Dict{Vertex, <:AbstractMatrix{<:Number}}
. For each given vertex a block from dictionary is used, otherwise zero matrix is chosen. Each matrix from dictionary should be nonnegative and sum of all traces should equal one. The keys of init_vertices
should be a vertices from vertexset
. Note that matrix from init_states
corresponding to vertex v
should be of size length(v)
×length(v)
.
Note: The function returns sparse matrix with ComplexF64
field type.
Examples
julia> vset = VertexSet([[1], [2, 3, 4], [5, 6, 7], [8, 9]])
VertexSet(Vertex[Vertex([1]), Vertex([2, 3, 4]), Vertex([5, 6, 7]), Vertex([8, 9])])
julia> A1, A2, A3 = ones(ComplexF64, 1, 1)/4, [ 1/5+0im 0 1/5; 0 1/10 0 ; 1/5 0 1/5 ], [0.125 -0.125+0im; -0.125 0.125]
(Complex{Float64}[0.25 + 0.0im], Complex{Float64}[0.2 + 0.0im 0.0 + 0.0im 0.2 + 0.0im; 0.0 + 0.0im 0.1 + 0.0im 0.0 + 0.0im; 0.2 + 0.0im 0.0 + 0.0im 0.2 + 0.0im], Complex{Float64}[0.125 + 0.0im -0.125 + 0.0im; -0.125 + 0.0im 0.125 + 0.0im])
julia> nm_init(Dict(vset[1] =>A1, vset[3] =>A2, vset[4] =>A3), vset)
9×9 SparseArrays.SparseMatrixCSC{Complex{Float64},Int64} with 10 stored entries:
[1, 1] = 0.25+0.0im
[5, 5] = 0.2+0.0im
[7, 5] = 0.2+0.0im
[6, 6] = 0.1+0.0im
[5, 7] = 0.2+0.0im
[7, 7] = 0.2+0.0im
[8, 8] = 0.125+0.0im
[9, 8] = -0.125+0.0im
[8, 9] = -0.125+0.0im
[9, 9] = 0.125+0.0im
QSWalk.default_nm_loc_ham
— Functiondefault_nm_loc_ham(size)
Return default local Hamiltonian of size size
×size
for the demoralization procedure. The Hamiltonian is sparse with nonzero elements on the first upper diagonal (equal to 1im
) and lower diagonal (equal to -1im
).
Note: This function is used to provide the default argument for nm_loc_ham
function.
Examples
julia> QSWalk.default_nm_loc_ham(4)
4×4 SparseArrays.SparseMatrixCSC{Complex{Float64},Int64} with 6 stored entries:
[2, 1] = 0.0-1.0im
[1, 2] = 0.0+1.0im
[3, 2] = 0.0-1.0im
[2, 3] = 0.0+1.0im
[4, 3] = 0.0-1.0im
[3, 4] = 0.0+1.0im
QSWalk.make_vertex_set
— Functionmake_vertex_set(A[, epsilon])
Creates object of type VertexSet
which represents how vertices are located in matrix. Should be used only in the nondefault use of evolve_generator
function. It is always equal to the second element if output of evolve_generator
function.
Examples
julia> A = [1 2 3; 0 3. 4.; 0 0 5.]
3×3 Array{Float64,2}:
1.0 2.0 3.0
0.0 3.0 4.0
0.0 0.0 5.0
julia> vlist(make_vertex_set(A))
3-element Array{Vertex,1}:
Vertex([1, 2, 3])
Vertex([4, 5])
Vertex([6])
julia> vlist(make_vertex_set(A, epsilon = 2.5))
3-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3])
Vertex([4])
QSWalk.vlist
— Functionvlist(vset)
Returns the list of vertices for given vset
of type VertexSet
.
julia> vset = VertexSet([[1], [2, 3, 4], [5, 6, 7], [8, 9]])
VertexSet(Vertex[Vertex([1]), Vertex([2, 3, 4]), Vertex([5, 6, 7]), Vertex([8, 9])])
julia> vlist(vset)
4-element Array{Vertex,1}:
Vertex([1])
Vertex([2, 3, 4])
Vertex([5, 6, 7])
Vertex([8, 9])
QSWalk.subspace
— Functionsubspace(v)
Returns the subspace connected to vertex v
.
julia> v = Vertex([1,2,3])
Vertex([1, 2, 3])
julia> subspace(v)
3-element Array{Int64,1}:
1
2
3
QSWalk.fourier_matrix
— Functionfourier_matrix(size)
Returns Fourier matrix of size size
×size
.
Examples
julia> fourier_matrix(1)
1×1 SparseArrays.SparseMatrixCSC{Complex{Float64},Int64} with 1 stored entry:
[1, 1] = 1.0+0.0im
julia> fourier_matrix(2)
2×2 SparseArrays.SparseMatrixCSC{Complex{Float64},Int64} with 4 stored entries:
[1, 1] = 1.0+0.0im
[2, 1] = 1.0+0.0im
[1, 2] = 1.0+0.0im
[2, 2] = -1.0+1.22465e-16im
QSWalk.vertexsetsize
— Functionvertexsetsize(vertexset)
Return the dimension of the linearspace corresponding to given vertexset
.
Examples
julia> vertexsetsize(VertexSet([[1, 2, 3], [4, 5]]))
5