Measurement optimization¶
In QuanEstimation, three measurement optimization scenarios are considered. The first one is to optimize a set of rank-one projective measurement, it can be written in a specific basis \(\{|\phi_i\rangle\}\) with \(|\phi_i\rangle=\sum_j C_{ij}|j\rangle\) in the Hilbert space as \(\{|\phi_i\rangle\langle\phi_i|\}\). In this case, the goal is to search a set of optimal coefficients \(C_{ij}\). The second scenario is to find the optimal linear combination of an input measurement \(\{\Pi_j\}\). The third scenario is to find the optimal rotated measurement of an input measurement. After rotation, the new measurement is \(\{U\Pi_i U^{\dagger}\}\), where \(U=\prod_k \exp(i s_k\lambda_k)\) with \(\lambda_k\) a SU(\(N\)) generator and \(s_k\) a real number in the regime \([0,2\pi]\). In this scenario, the goal is to search a set of optimal coefficients \(s_k\). Here different algorithms are invoked to search the optimal measurement include particle swarm optimization (PSO) [1], differential evolution (DE) [2], and automatic differentiation (AD) [3]. The codes for execute measurement optimization are
m = MeasurementOpt(mtype="projection", minput=[], savefile=False,
method="DE", **kwargs)
m.dynamics(tspan, rho0, H0, dH, Hc=[], ctrl=[], decay=[], \
dyn_method="expm")
m.CFIM(W=[])
mtype
represents the type of measurement optimization which defaults to "projection"
.
In this setting, rank-one projective measurement optimization will be performed minput
will keep empty in this scenario. For the other two measurement optimization scenarios
mtype="input"
. If the users want to find the optimal linear combination of an input
measurement, the variable minput
should be input as minput=["LC", [Pi1,Pi2,...], m]
with [Pi1,Pi2,...]
a set of POVM and m
the number of operators of the output
measurement. For finding the optimal linear combination of an input measurement, the
variable minput
becomes minput=["rotation", [Pi1,Pi2,...]]
. savefile
means whether
to save all the measurements. If set False
the measurements in the final episode and
the values of the objective function in all episodes will be saved, if savefile=True
the measurements and the values of the objective function obtained in all episodes will
be saved during the training. method
represents the algorithm used to optimize the
measurements, options are: "PSO", "DE" and "AD". **kwargs
is the keyword and default
value corresponding to the optimization algorithm which will be introduced in detail
below.
If the dynamics of the system can be described by the master equation, then the dynamics data
tspan
, rho0
, H0
and dH
shoule be input. tspan
is the time length for the evolution,
rho0
represents the density matrix of the initial state, H0
and dH
are the free
Hamiltonian and its derivatives on the unknown parameters to be estimated. H0
is a matrix
when the free Hamiltonian is time-independent and a list of matrices with the length equal to
tspan
when it is time-dependent. dH
should be input as \([\partial_a{H_0}, \partial_b{H_0}, \cdots]\).
Hc
and ctrl
are two lists represent the control Hamiltonians and the corresponding control
coefficients. decay
contains decay operators \((\Gamma_1,\Gamma_2, \cdots)\) and the
corresponding decay rates \((\gamma_1, \gamma_2, \cdots)\) with the input rule
decay=[[\(\Gamma_1\), \(\gamma_1\)], [\(\Gamma_2\), \(\gamma_2\)],...]. The default values for decay
,
Hc
and ctrl
are empty which means the dynamics is unitary and only governed by the free
Hamiltonian. dyn_method="expm"
represents the method for solving the dynamics is
matrix exponential, it can also be set as dyn_method="ode"
which means the dynamics
(differential equation) is directly solved with the ODE solvers.
The objective function for measurement optimization are CFI and \(\mathrm{Tr}(W\mathcal{I}^
{-1})\) with \(\mathcal{I}\) the CFIM. \(W\) corresponds to W
in the objective function is the
weight matrix which defaults to the identity matrix.
opt = MeasurementOpt(mtype=:Projection, seed=1234)
alg = DE(kwargs...)
dynamics = Lindblad(opt, tspan, rho0, H0, dH; Hc=missing,
ctrl=missing, decay=missing, dyn_method=:Expm)
obj = CFIM_obj(W=missing)
run(opt, alg, obj, dynamics; savefile=false)
mtype
represents the type of measurement optimization which defaults to "Projection"
.
In this setting, rank-one projective measurement optimization will be performed. For the other
two measurement optimization scenarios this variable becomes mtype="LC"
and mtype="Rotation"
.
If the users want to find the optimal linear combination of an input measurement, the input
rule of opt
is MeasurementOpt(mtype=:LC,POVM_basis=[Pi1,Pi2,...],M_num=m)
with
[Pi1,Pi2,...]
a set of POVM and m
the number of operators of the output measurement.
For finding the optimal linear combination of an input measurement, the code opt
is
MeasurementOpt(mtype=:LC,POVM_basis=[Pi1,Pi2,...])
. seed
is the random seed which can
ensure the reproducibility of results.
If the dynamics of the system can be described by the master equation, then the dynamics data
tspan
, rho0
, H0
and dH
shoule be input. tspan
is the time length for the evolution,
rho0
represents the density matrix of the initial state, H0
and dH
are the free
Hamiltonian and its derivatives on the unknown parameters to be estimated. H0
is a matrix
when the free Hamiltonian is time-independent and a list of matrices with the length equal to
tspan
when it is time-dependent. dH
should be input as \([\partial_a{H_0}, \partial_b{H_0}, \cdots]\).
Hc
and ctrl
are two lists represent the control Hamiltonians and the corresponding control
coefficients. decay
contains decay operators \((\Gamma_1,\Gamma_2, \cdots)\) and the
corresponding decay rates \((\gamma_1, \gamma_2, \cdots)\) with the input rule
decay=[[\(\Gamma_1\), \(\gamma_1\)], [\(\Gamma_2\), \(\gamma_2\)],...]. The default values for decay
,
Hc
and ctrl
are missing
which means the dynamics is unitary and only governed by the free
Hamiltonian. dyn_method=:Expm
represents the method for solving the dynamics is
matrix exponential, it can also be set as dyn_method=:Ode
which means the dynamics
(differential equation) is directly solved with the ODE solvers.
The objective function for measurement optimization are CFI and \(\mathrm{Tr}(W\mathcal{I}^
{-1})\) with \(\mathcal{I}\) the CFIM. \(W\) corresponds to W
in the objective function is the
weight matrix which defaults to the identity matrix. The variable savefile
means whether to
save all the measurements. If set false
the measurements in the final episode and the values
of the objective function in all episodes will be saved, if savefile=true
the measurements
and the values of the objective function obtained in all episodes will be saved during the
training. The algorithm used for optimizing the measurements are PSO, DE and AD. kwargs...
is the keywords and default values corresponding to the optimization algorithm which will be
introduced in detail below.
PSO¶
The code for measurement optimization with PSO is as follows
m = MeasurementOpt(method="PSO", **kwargs)
kwargs
is of the form
kwargs = {"p_num":10, "measurement0":[], "max_episode":[1000,100], \
"c0":1.0, "c1":2.0, "c2":2.0, "seed":1234}
\(~~~~~~~~~~\)**kwargs\(~~~~~~~~~~\) | \(~~~~\)default values\(~~~~\) |
---|---|
"p_num" | 10 |
"measurement0" | [ ] |
"max_episode" | [1000,100] |
"c0" | 1.0 |
"c1" | 2.0 |
"c2" | 2.0 |
"seed" | 1234 |
p_num
is the number of particles, c0
, c1
and c2
are the PSO parameters
representing the inertia weight, cognitive learning factor and social learning factor,
respectively. max_episode
accepts both integers and arrays with two elements. If it is
an integer, for example max_episode=1000
, it means the program will continuously run
1000 episodes. However, if it is an array, for example max_episode=[1000,100]
, the
program will run 1000 episodes in total but replace control coefficients of all the
particles with global best every 100 episodes. seed
is the random seed which can
ensure the reproducibility of the results. measurement0
in the algorithm is a list
representing the initial guesses of measurements. In the case of projective measurement
optimization, the entry of measurement0
is a list of arrays with the length equal to
the dimension of the system. In the cases of finding the optimal linear combination and
the optimal rotation of a given set of measurement, the entry of measurement0
is a
2D-array and array, respectively. Here, an example of generating measurement0
is given
as follows
Example 7.1
from quanestimation import *
import numpy as np
# the dimension of the system
dim = 6
# generation of the entry of `measurement0`
C = [[] for i in range(dim)]
for i in range(dim):
r_ini = 2*np.random.random(dim)-np.ones(dim)
r = r_ini/np.linalg.norm(r_ini)
phi = 2*np.pi*np.random.random(dim)
C[i] = [r[j]*np.exp(1.0j*phi[j]) for j in range(dim)]
C = np.array(gramschmidt(C))
measurement0 = [C]
from quanestimation import *
import numpy as np
# the dimension of the system
dim = 6
# a given set of measurement
POVM_basis = SIC(dim)
# the number of operators of the output measurement
m = 4
# generation of the entry of `measurement0`
B = np.array([np.random.random(len(POVM_basis)) for i in range(m)])
measurement0 = [B]
from quanestimation import *
import numpy as np
# the dimension of the system
dim = 6
# a given set of measurement
POVM_basis = SIC(dim)
# generation of the entry of `measurement0`
s = np.random.random(dim**2)
measurement0 = [s]
In this algorithm, the length of measurement0
should be less than or equal to p_num
.
alg = PSO(p_num=10, ini_particle=missing, max_episode=[1000,100],
c0=1.0, c1=2.0, c2=2.0)
\(~~~~~~~~~~\)keywords\(~~~~~~~~~~\) | \(~~~~\)default values\(~~~~\) |
---|---|
"p_num" | 10 |
"ini_particle" | missing |
"max_episode" | [1000,100] |
"c0" | 1.0 |
"c1" | 2.0 |
"c2" | 2.0 |
p_num
is the number of particles, c0
, c1
, and c2
are the PSO parameters representing
the inertia weight, cognitive learning factor, and social learning factor, respectively.
max_episode
accepts both integers and arrays with two elements. If it is an integer,
for example max_episode=1000
, it means the program will continuously run 1000 episodes.
However, if it is an array, for example max_episode=[1000,100]
, the program will run 1000
episodes in total but replace control coefficients of all the particles with global best
every 100 episodes. ini_particle
in the algorithm is a list representing the initial guesses
of measurements, In the case of projective measurement optimization, the entry of ini_particle
is a list of arrays with the length equal to the dimension of the system. In the cases of
finding the optimal linear combination and the optimal rotation of a given set of measurement,
the entry of ini_particle
is a 2D-array and array, respectively. Here, an example of
generating ini_particle
is given as follows
Example 7.1
using QuanEstimation
# the dimension of the system
dim = 6
# generation of the entry of `measurement0`
C = [ComplexF64[] for _ in 1:dim]
for i in 1:dim
r_ini = 2*rand(dim) - ones(dim)
r = r_ini/norm(r_ini)
ϕ = 2pi*rand(dim)
C[i] = [r*exp(im*ϕ) for (r,ϕ) in zip(r,ϕ)]
end
C = QuanEstimation.gramschmidt(C)
measurement0 = ([C],)
using QuanEstimation
# the dimension of the system
dim = 6
# a given set of measurement
POVM_basis = QuanEstimation.SIC(dim)
# the number of operators of the output measurement
m = 4
# generation of the entry of `measurement0`
B = [rand(length(POVM_basis)) for _ in 1:m]
measurement0 = ([B],)
using QuanEstimation
# the dimension of the system
dim = 6
# a given set of measurement
POVM_basis = QuanEstimation.SIC(dim)
# generation of the entry of `measurement0`
s = rand(dim^2)
measurement0 = ([s],)
In this algorithm, the length of measurement0
should be less than or equal to p_num
.
DE¶
The code for measurement optimization with DE is as follows
m = MeasurementOpt(method="DE", **kwargs)
kwargs
is of the form
kwargs = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
\(~~~~~~~~~~\)**kwargs\(~~~~~~~~~~\) | \(~~~~\)default values\(~~~~\) |
---|---|
"p_num" | 10 |
"measurement0" | [ ] |
"max_episode" | 1000 |
"c" | 1.0 |
"cr" | 0.5 |
"seed" | 1234 |
p_num
represents the number of populations, c
and cr
are the mutation constant and the
crossover constant. Here max_episode
is an integer representing the number of episodes,
the variable measurement0
is the same with measurement0
in PSO.
alg = DE(p_num=10, ini_population=missing, max_episode=1000,
c=1.0, cr=0.5)
\(~~~~~~~~~~\)keywords\(~~~~~~~~~~\) | \(~~~~\)default values\(~~~~\) |
---|---|
"p_num" | 10 |
"ini_population" | [ ] |
"max_episode" | 1000 |
"c" | 1.0 |
"cr" | 0.5 |
p_num
represents the number of populations, c
and cr
are the mutation constant
and the crossover constant. Here max_episode
is an integer representing the number of
episodes, the variable ini_population
is the same with ini_particle
in PSO.
AD¶
The code for measurement optimization with AD is as follows
com = MeasurementOpt(method="AD", **kwargs)
kwargs
is of the form
kwargs = {"Adam":False, "measurement0":[], "max_episode":300, \
"epsilon":0.01, "beta1":0.90, "beta2":0.99}
\(~~~~~~~~~~\)**kwargs\(~~~~~~~~~~\) | \(~~~~\)default values\(~~~~\) |
---|---|
"Adam" | False |
"measurement0" | [ ] |
"max_episode" | 300 |
"epsilon" | 0.01 |
"beta1" | 0.90 |
"beta2" | 0.99 |
The measurements will update according to the learning rate "epsilon"
for Adam=False
,
However, Adam algorithm can be introduced to update the measurements which can be realized by
setting Adam=True
. In this case, the Adam parameters include learning rate, the exponential
decay rate for the first moment estimates, and the second moment estimates can be set by the
user via epsilon
, beta1
, and beta2
. The input rule of measurement0
is the same with
that in PSO, but the length of measurement0
is equal to one.
alg = AD(Adam=false, max_episode=300, epsilon=0.01, beta1=0.90,
beta2=0.99)
\(~~~~~~~~~~\)keywords\(~~~~~~~~~~\) | \(~~~~\)default values\(~~~~\) |
---|---|
"Adam" | false |
"max_episode" | 300 |
"epsilon" | 0.01 |
"beta1" | 0.90 |
"beta2" | 0.99 |
The measurements will update according to the learning rate "epsilon"
for Adam=False
,
However, Adam algorithm can be introduced to update the measurements which can be realized by
setting Adam=true
. In this case, the Adam parameters include learning rate, the exponential
decay rate for the first moment estimates, and the second moment estimates can be set by the
user via epsilon
, beta1
, and beta2
.
Example 7.2
A single qubit system whose dynamics is governed by
where \(H = \frac{1}{2}\omega \sigma_3\) is the free Hamiltonian with \(\omega\) the frequency, \(\sigma_{\pm}=(\sigma_1 \pm \sigma_2)/2\) and \(\gamma_{+}\), \(\gamma_{-}\) are decay rates. Here \(\sigma_{i}\) for \((i=1,2,3)\) is the Pauli matrix.
In this case, the probe state is taken as \(\frac{1}{\sqrt{2}}(|0\rangle +|1\rangle)\), \(|0\rangle\) \((|1\rangle)\) is the eigenstate of \(\sigma_3\) with respect to the eigenvalue \(1\) \((-1)\).
from quanestimation import *
import numpy as np
# initial state
rho0 = 0.5*np.array([[1., 1.], [1., 1.]])
# free Hamiltonian
omega = 1.0
sx = np.array([[0., 1.], [1., 0.]])
sy = np.array([[0., -1.j], [1.j, 0.]])
sz = np.array([[1., 0.], [0., -1.]])
H0 = 0.5*omega*sz
# derivative of the free Hamiltonian on omega
dH = [0.5*sz]
# dissipation
sp = np.array([[0., 1.], [0., 0.]])
sm = np.array([[0., 0.], [1., 0.]])
decay = [[sp, 0.], [sm, 0.1]]
# generation of a set of POVM basis
dim = np.shape(rho0)[0]
POVM_basis = SIC(dim)
# time length for the evolution
tspan = np.linspace(0., 10., 2500)
M_num = dim
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="projection", minput=[], savefile=False, \
method="DE", **DE_paras)
M_num = dim
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], \
"max_episode":[1000,100], "c0":1.0, \
"c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="projection", minput=[], savefile=False, \
method="PSO", **PSO_paras)
M_num = 2
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, M_num], \
savefile=False, method="DE", **DE_paras)
M_num = 2
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], "max_episode":[1000,100], \
"c0":1.0, "c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, M_num], \
savefile=False, method="PSO", **PSO_paras)
M_num = 2
# measurement optimization algorithm: AD
AD_paras = {"Adam":False, "measurement0":[], "max_episode":300, \
"epsilon":0.01, "beta1":0.90, "beta2":0.99}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, M_num], \
savefile=False, method="AD", **AD_paras)
M_num = dim
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="DE", **DE_paras)
M_num = dim
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], \
"max_episode":[1000,100], "c0":1.0, \
"c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="PSO", **PSO_paras)
M_num = dim
# measurement optimization algorithm: AD
AD_paras = {"Adam":False, "measurement0":[], "max_episode":300, \
"epsilon":0.01, "beta1":0.90, "beta2":0.99}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="AD", **AD_paras)
# input the dynamics data
m.dynamics(tspan, rho0, H0, dH, decay=decay, dyn_method="expm")
# objective function: CFI
m.CFIM()
# convert the ".csv" file to the ".npy" file
M_ = np.loadtxt("measurements.csv", dtype=np.complex128)
csv2npy_measurements(M_, M_num)
# load the measurements
M = np.load("measurements.npy")[-1]
using QuanEstimation
using Random
using StableRNGs
using LinearAlgebra
using DelimitedFiles
# initial state
rho0 = 0.5*ones(2, 2)
# free Hamiltonian
omega = 1.0
sx = [0. 1.; 1. 0.0im]
sy = [0. -im; im 0.]
sz = [1. 0.0im; 0. -1.]
H0 = 0.5*omega*sz
# derivative of the free Hamiltonian on omega
dH = [0.5*sz]
# dissipation
sp = [0. 1.; 0. 0.0im]
sm = [0. 0.; 1. 0.0im]
decay = [[sp, 0.], [sm, 0.1]]
# generation of a set of POVM basis
dim = size(rho0, 1)
POVM_basis = QuanEstimation.SIC(dim)
M_num = dim
# time length for the evolution
tspan = range(0., 10., length=2500)
opt = QuanEstimation.MeasurementOpt(mtype=:Projection, seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
opt = QuanEstimation.MeasurementOpt(mtype=:LC,
POVM_basis=POVM_basis, M_num=M_num,
seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
# measurement optimization algorithm: AD
alg = QuanEstimation.AD(Adam=true, max_episode=300, epsilon=0.01,
beta1=0.90, beta2=0.99)
opt = QuanEstimation.MeasurementOpt(mtype=:Rotation,
POVM_basis=POVM_basis, seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
# measurement optimization algorithm: AD
alg = QuanEstimation.AD(Adam=true, max_episode=300, epsilon=0.01,
beta1=0.90, beta2=0.99)
# input the dynamics data
dynamics = QuanEstimation.Lindblad(opt, tspan ,rho0, H0, dH,
decay=decay, dyn_method=:Expm)
# objective function: CFI
obj = QuanEstimation.CFIM_obj()
# run the measurement optimization problem
QuanEstimation.run(opt, alg, obj, dynamics; savefile=false)
# convert the flattened data into a list of matrix
M_ = readdlm("measurements.csv",'\t', Complex{Float64})
M = [[reshape(M_[i,:], dim, dim) for i in 1:M_num]
for j in 1:Int(length(M_[:,1])/M_num)][end]
Example 7.3
In the multiparameter scenario, the dynamics of electron and nuclear coupling in NV\(^{-}\) can be expressed as
\begin{align}
\partial_t\rho=-i[H_0,\rho]+\frac{\gamma}{2}(S_3\rho S_3-S^2_3\rho-\rho S^2_3)
\end{align}
with \(\gamma\) the dephasing rate. And \begin{align} H_0/\hbar=DS^2_3+g_{\mathrm{S}}\vec{B}\cdot\vec{S}+g_{\mathrm{I}}\vec{B}\cdot\vec{I}+\vec{S}^{\,\mathrm{T}}\mathcal{A}\vec{I} \end{align}
is the free evolution Hamiltonian, where \(\vec{S}=(S_1,S_2,S_3)^{\mathrm{T}}\) and \(\vec{I}=(I_1,I_2,I_3)^{\mathrm{T}}\) with \(S_i=s_i\otimes I\) and \(I_i=I\otimes \sigma_i\) \((i=1,2,3)\) the electron and nuclear operators. \(s_1, s_2, s_3\) are spin-1 operators with
and \(s_3=\mathrm{diag}(1,0,-1)\) and \(\sigma_i (i=1,2,3)\) is Pauli matrix. \(\mathcal{A}=\mathrm{diag} (A_1,A_1,A_2)\) is the hyperfine tensor with \(A_1\) and \(A_2\) the axial and transverse magnetic hyperfine coupling coefficients. The coefficients \(g_{\mathrm{S}}=g_\mathrm{e}\mu_\mathrm{B}/\hbar\) and \(g_{\mathrm{I}}=g_\mathrm{n}\mu_\mathrm{n}/\hbar\), where \(g_\mathrm{e}\) (\(g_\mathrm{n}\)) is the \(g\) factor of the electron (nuclear), \(\mu_\mathrm{B}\) (\(\mu_\mathrm{n}\)) is the Bohr (nuclear) magneton and \(\hbar\) is the Plank's constant. \(\vec{B}\) is the magnetic field which be estimated.
In this case,the initial state is taken as \(\frac{1}{\sqrt{2}}(|1\rangle+|\!-\!1\rangle)\otimes|\!\!\uparrow\rangle\), where \(\frac{1}{\sqrt{2}}(|1\rangle+|\!-\!1\rangle)\) is an electron state with \(|1\rangle\) (\(|\!-\!1\rangle\)) the eigenstate of \(s_3\) with respect to the eigenvalue \(1\) (\(-1\)). \(|\!\!\uparrow\rangle\) is a nuclear state and the eigenstate of \(\sigma_3\) with respect to the eigenvalue 1. \(W\) is set to be \(I\).
Here three types of measurement optimization are considerd, projective measurement, linear combination of a given set of positive operator-valued measure (POVM) and optimal rotated measurement of an input measurement.
from quanestimation import *
import numpy as np
# initial state
rho0 = np.zeros((6, 6), dtype=np.complex128)
rho0[0][0], rho0[0][4], rho0[4][0], rho0[4][4] = 0.5, 0.5, 0.5, 0.5
# free Hamiltonian
sx = np.array([[0., 1.],[1., 0.]])
sy = np.array([[0., -1.j],[1.j, 0.]])
sz = np.array([[1., 0.],[0., -1.]])
ide2 = np.array([[1., 0.],[0., 1.]])
s1 = np.array([[0., 1., 0.],[1., 0., 1.],[0., 1., 0.]])/np.sqrt(2)
s2 = np.array([[0., -1.j, 0.],[1.j, 0., -1.j],[0., 1.j, 0.]])/np.sqrt(2)
s3 = np.array([[1., 0., 0.],[0., 0., 0.],[0., 0., -1.]])
ide3 = np.array([[1., 0., 0.],[0., 1., 0.],[0., 0., 1.]])
I1, I2, I3 = np.kron(ide3, sx), np.kron(ide3, sy), np.kron(ide3, sz)
S1, S2, S3 = np.kron(s1, ide2), np.kron(s2, ide2), np.kron(s3, ide2)
B1, B2, B3 = 5.0e-4, 5.0e-4, 5.0e-4
# All numbers are divided by 100 in this example
# for better calculation accurancy
cons = 100
D = (2*np.pi*2.87*1000)/cons
gS = (2*np.pi*28.03*1000)/cons
gI = (2*np.pi*4.32)/cons
A1 = (2*np.pi*3.65)/cons
A2 = (2*np.pi*3.03)/cons
H0 = D*np.kron(np.dot(s3, s3), ide2) + gS*(B1*S1+B2*S2+B3*S3) \
+ gI*(B1*I1+B2*I2+B3*I3) + A1*(np.kron(s1, sx) + np.kron(s2, sy)) \
+ A2*np.kron(s3, sz)
# derivatives of the free Hamiltonian on B1, B2, and B3
dH = [gS*S1+gI*I1, gS*S2+gI*I2, gS*S3+gI*I3]
# control Hamiltonians
Hc = [S1, S2, S3]
# dissipation
decay = [[S3,2*np.pi/cons]]
# generation of a set of POVM basis
dim = len(rho0)
POVM_basis = [np.dot(basis(dim, i), basis(dim, i).conj().T) \
for i in range(dim)]
# time length for the evolution
tspan = np.linspace(0., 2., 4000)
M_num = dim
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="projection", minput=[], savefile=False, \
method="DE", **DE_paras)
M_num = dim
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], \
"max_episode":[1000,100], "c0":1.0, \
"c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="projection", minput=[], savefile=False, \
method="PSO", **PSO_paras)
M_num = 4
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, M_num], \
savefile=False, method="DE", **DE_paras)
M_num = 4
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], "max_episode":[1000,100], \
"c0":1.0, "c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, M_num], \
savefile=False, method="PSO", **PSO_paras)
M_num = 4
# measurement optimization algorithm: AD
AD_paras = {"Adam":False, "measurement0":[], "max_episode":300, \
"epsilon":0.01, "beta1":0.90, "beta2":0.99}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, M_num], \
savefile=False, method="AD", **AD_paras)
M_num = dim
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="DE", **DE_paras)
M_num = dim
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], \
"max_episode":[1000,100], "c0":1.0, \
"c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="PSO", **PSO_paras)
M_num = dim
# measurement optimization algorithm: AD
AD_paras = {"Adam":False, "measurement0":[], "max_episode":300, \
"epsilon":0.01, "beta1":0.90, "beta2":0.99}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="AD", **AD_paras)
# input the dynamics data
m.dynamics(tspan, rho0, H0, dH, decay=decay, dyn_method="expm")
# objective function: tr(WI^{-1})
m.CFIM()
# convert the ".csv" file to the ".npy" file
M_ = np.loadtxt("measurements.csv", dtype=np.complex128)
csv2npy_measurements(M_, M_num)
# load the measurements
M = np.load("measurements.npy")[-1]
using QuanEstimation
using Random
using LinearAlgebra
using DelimitedFiles
# initial state
rho0 = zeros(ComplexF64, 6, 6)
rho0[1:4:5, 1:4:5] .= 0.5
# Hamiltonian
sx = [0. 1.; 1. 0.]
sy = [0. -im; im 0.]
sz = [1. 0.; 0. -1.]
s1 = [0. 1. 0.; 1. 0. 1.; 0. 1. 0.]/sqrt(2)
s2 = [0. -im 0.; im 0. -im; 0. im 0.]/sqrt(2)
s3 = [1. 0. 0.; 0. 0. 0.; 0. 0. -1.]
Is = I1, I2, I3 = [kron(I(3), sx), kron(I(3), sy), kron(I(3), sz)]
S = S1, S2, S3 = [kron(s1, I(2)), kron(s2, I(2)), kron(s3, I(2))]
B = B1, B2, B3 = [5.0e-4, 5.0e-4, 5.0e-4]
# All numbers are divided by 100 in this example
# for better calculation accurancy
cons = 100
D = (2pi*2.87*1000)/cons
gS = (2pi*28.03*1000)/cons
gI = (2pi*4.32)/cons
A1 = (2pi*3.65)/cons
A2 = (2pi*3.03)/cons
H0 = sum([D*kron(s3^2, I(2)), sum(gS*B.*S), sum(gI*B.*Is),
A1*(kron(s1, sx) + kron(s2, sy)), A2*kron(s3, sz)])
# derivatives of the free Hamiltonian on B1, B2 and B3
dH = gS*S+gI*Is
# control Hamiltonians
Hc = [S1, S2, S3]
# dissipation
decay = [[S3, 2pi/cons]]
# generation of a set of POVM basis
dim = size(rho0, 1)
POVM_basis = [QuanEstimation.basis(dim, i)*QuanEstimation.basis(dim, i)'
for i in 1:dim]
# time length for the evolution
tspan = range(0., 2., length=4000)
M_num = dim
opt = QuanEstimation.MeasurementOpt(mtype=:Projection, seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
M_num = 4
opt = QuanEstimation.MeasurementOpt(mtype=:LC,
POVM_basis=POVM_basis, M_num=M_num,
seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
# measurement optimization algorithm: AD
alg = QuanEstimation.AD(Adam=true, max_episode=300, epsilon=0.01,
beta1=0.90, beta2=0.99)
M_num = dim
opt = QuanEstimation.MeasurementOpt(mtype=:Rotation,
POVM_basis=POVM_basis, seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
# measurement optimization algorithm: AD
alg = QuanEstimation.AD(Adam=true, max_episode=300, epsilon=0.01,
beta1=0.90, beta2=0.99)
# input the dynamics data
dynamics = QuanEstimation.Lindblad(opt, tspan ,rho0, H0, dH,
decay=decay, dyn_method=:Expm)
# objective function: CFI
obj = QuanEstimation.CFIM_obj()
# run the measurement optimization problem
QuanEstimation.run(opt, alg, obj, dynamics; savefile=false)
M_ = readdlm("measurements.csv",'\t', Complex{Float64})
M = [[reshape(M_[i,:], dim, dim) for i in 1:M_num]
for j in 1:Int(length(M_[:,1])/M_num)][end]
If the parameterization process is implemented with the Kraus operators, then the corresponding parameters should be input via
m = MeasurementOpt(mtype="projection", minput=[], savefile=False,
method="DE", **kwargs)
m.Kraus(K, dK)
m.CFIM(W=[])
opt = MeasurementOpt(mtype=:Projection, seed=1234)
alg = DE(kwargs...)
dynamics = Kraus(opt, K, dK)
obj = CFIM_obj(W=missing)
run(opt, alg, obj, dynamics; savefile=false)
where K
and dK
are the Kraus operators and its derivatives with respect to the
unknown parameters.
Example 7.4
The Kraus operators for the amplitude damping channel are
where \(\gamma\) is the unknown parameter to be estimated which represents the decay probability. In this example, the probe state is taken as \(|+\rangle\langle+|\) with \(|+\rangle=\frac{1}{\sqrt{2}}(|0\rangle+|1\rangle)\). Here \(|0\rangle\) \((|1\rangle)\) is the eigenstate of \(\sigma_3\) (Pauli matrix) with respect to the eigenvalue \(1\) \((-1)\).
from quanestimation import *
import numpy as np
# initial state
rho0 = 0.5*np.array([[1., 1.], [1., 1.]])
# Kraus operators for the amplitude damping channel
gamma = 0.1
K1 = np.array([[1., 0.], [0., np.sqrt(1-gamma)]])
K2 = np.array([[0., np.sqrt(gamma)], [0., 0.]])
K = [K1, K2]
# derivatives of Kraus operators on gamma
dK1 = np.array([[1., 0.], [0.0, -0.5/np.sqrt(1-gamma)]])
dK2 = np.array([[0., 0.5/np.sqrt(gamma)], [0., 0.]])
dK = [[dK1], [dK2]]
# measurement
POVM_basis = SIC(len(rho0))
M_num = 2
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="projection", minput=[], savefile=False, \
method="DE", **DE_paras)
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], \
"max_episode":[1000,100], "c0":1.0, \
"c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="projection", minput=[], savefile=False, \
method="PSO", **PSO_paras)
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, 2], \
savefile=False, method="DE", **DE_paras)
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], "max_episode":[1000,100], \
"c0":1.0, "c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, 2], \
savefile=False, method="PSO", **PSO_paras)
# measurement optimization algorithm: AD
AD_paras = {"Adam":False, "measurement0":[], "max_episode":300, \
"epsilon":0.01, "beta1":0.90, "beta2":0.99}
m = MeasurementOpt(mtype="input", minput=["LC", POVM_basis, 2], \
savefile=False, method="AD", **AD_paras)
# measurement optimization algorithm: DE
DE_paras = {"p_num":10, "measurement0":[], "max_episode":1000, \
"c":1.0, "cr":0.5, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="DE", **DE_paras)
# measurement optimization algorithm: PSO
PSO_paras = {"p_num":10, "measurement0":[], \
"max_episode":[1000,100], "c0":1.0, \
"c1":2.0, "c2":2.0, "seed":1234}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="PSO", **PSO_paras)
# measurement optimization algorithm: AD
AD_paras = {"Adam":False, "measurement0":[], "max_episode":300, \
"epsilon":0.01, "beta1":0.90, "beta2":0.99}
m = MeasurementOpt(mtype="input", minput=["rotation", POVM_basis], \
savefile=False, method="AD", **AD_paras)
# input the dynamics data
m.Kraus(rho0, K, dK)
# objective function: CFI
m.CFIM()
# convert the ".csv" file to the ".npy" file
M_ = np.loadtxt("measurements.csv", dtype=np.complex128)
csv2npy_measurements(M_, M_num)
# load the measurements
M = np.load("measurements.npy")[-1]
using QuanEstimation
using DelimitedFiles
# initial state
rho0 = 0.5*ones(2, 2)
# Kraus operators for the amplitude damping channel
gamma = 0.1
K1 = [1. 0.; 0. sqrt(1-gamma)]
K2 = [0. sqrt(gamma); 0. 0.]
K = [K1, K2]
# derivatives of Kraus operators on gamma
dK1 = [1. 0.; 0. -0.5/sqrt(1-gamma)]
dK2 = [0. 0.5/sqrt(gamma); 0. 0.]
dK = [[dK1], [dK2]]
# measurement
dim = size(rho0,1)
POVM_basis = QuanEstimation.SIC(dim)
M_num = 2
opt = QuanEstimation.MeasurementOpt(mtype=:Projection, seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
opt = QuanEstimation.MeasurementOpt(mtype=:LC,
POVM_basis=POVM_basis, M_num=2,
seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
# measurement optimization algorithm: AD
alg = QuanEstimation.AD(Adam=true, max_episode=300, epsilon=0.01,
beta1=0.90, beta2=0.99)
opt = QuanEstimation.MeasurementOpt(mtype=:Rotation,
POVM_basis=POVM_basis, seed=1234)
# measurement optimization algorithm: DE
alg = QuanEstimation.DE(p_num=10, ini_population=missing,
max_episode=1000, c=1.0, cr=0.5)
# measurement optimization algorithm: PSO
alg = QuanEstimation.PSO(p_num=10, ini_particle=missing,
max_episode=[1000,100], c0=1.0, c1=2.0,
c2=2.0)
# measurement optimization algorithm: AD
alg = QuanEstimation.AD(Adam=true, max_episode=300, epsilon=0.01,
beta1=0.90, beta2=0.99)
# input the dynamics data
dynamics = QuanEstimation.Kraus(opt, rho0, K, dK)
# objective function: CFI
obj = QuanEstimation.CFIM_obj()
# run the measurement optimization problem
QuanEstimation.run(opt, alg, obj, dynamics; savefile=false)
# convert the flattened data into a list of matrix
M_ = readdlm("measurements.csv",'\t', Complex{Float64})
M = [[reshape(M_[i,:], dim, dim) for i in 1:M_num]
for j in 1:Int(length(M_[:,1])/M_num)][end]
Bibliography¶
[1] J. Kennedy and R. Eberhar, Particle swarm optimization, Proc. 1995 IEEE International Conference on Neural Networks 4, 1942-1948 (1995).
[2] R. Storn and K. Price, Differential Evolution-A Simple and Efficient Heuristic for global Optimization over Continuous Spaces, J. Global Optim. 11, 341 (1997).
[3] A. G. Baydin, B. A. Pearlmutter, A. A. Radul, and J. M. Siskind, Automatic differentiation in machine learning: a survey, J. Mach. Learn. Res. 18, 1-43 (2018).