Geometric Measure of Coherence¶
In [1]:
Copied!
import numpy as np
from tqdm.auto import tqdm
import matplotlib.pyplot as plt
import torch
try:
import numqi
except ImportError:
%pip install numqi
import numqi
np_rng = np.random.default_rng()
import numpy as np
from tqdm.auto import tqdm
import matplotlib.pyplot as plt
import torch
try:
import numqi
except ImportError:
%pip install numqi
import numqi
np_rng = np.random.default_rng()
Pure state¶
$$ C_{g}\left(|\psi\rangle\right)=1-\max_{i}\left|\langle i|\psi\rangle\right|^{2} $$
In [2]:
Copied!
psi = np.array([1,0,0,0], dtype=np.float64)
print('computational basis: ', numqi.coherence.get_geometric_coherence_pure(psi))
# TODO for some random pure state
psi = numqi.random.rand_haar_state(4)
print('random pure state: ', numqi.coherence.get_geometric_coherence_pure(psi))
psi = np.array([1,1,1,1], dtype=np.float64)/2
print('maximally coherent state: ', numqi.coherence.get_geometric_coherence_pure(psi))
psi = np.array([1,0,0,0], dtype=np.float64)
print('computational basis: ', numqi.coherence.get_geometric_coherence_pure(psi))
# TODO for some random pure state
psi = numqi.random.rand_haar_state(4)
print('random pure state: ', numqi.coherence.get_geometric_coherence_pure(psi))
psi = np.array([1,1,1,1], dtype=np.float64)/2
print('maximally coherent state: ', numqi.coherence.get_geometric_coherence_pure(psi))
computational basis: 0 random pure state: 0.6738805592986645 maximally coherent state: 0.75
Mixed state¶
$$ \begin{align*} C_{g}(\rho)&=\min_{\left\{ p_{\alpha},|\psi_{\alpha}\rangle\right\} }\sum_{\alpha}p_{\alpha}C_{g}\left(|\psi_{\alpha}\rangle\right)\\ &=1-\max_{\left\{ \tilde{\rho}_{\alpha}\right\} }\sum_{\alpha}\max_{i}\tilde{\rho}_{\alpha,ii} \end{align*} $$
$$ \max_{i}\tilde{\rho}_{\alpha,ii}=\lim_{T\to0^{+}} T \log\left(\sum_{i}\mathrm{exp}\left(\tilde{\rho}_{\alpha,ii}/T\right)\right) $$
log-sum-exp is the "real" SoftMax wiki-link. The naive "$\max_i$" is hard to converge (easily trapped in local minimum), while log-sum-exp works much better.
In [3]:
Copied!
dim = 32 #when dim=64, more num_repeat is needed
psi = numqi.state.maximally_coherent_state(dim)
dm_target = psi.reshape(-1,1) * psi.conj()
alpha_list = np.linspace(0, 1, 50)
model = numqi.coherence.GeometricCoherenceModel(dim, num_term=4*dim, temperature=0.3)
kwargs = dict(theta0='uniform', num_repeat=3, tol=1e-10, print_every_round=0)
gc_list = []
for alpha_i in tqdm(alpha_list):
model.set_density_matrix(numqi.utils.hf_interpolate_dm(dm_target, alpha=alpha_i))
theta_optim = numqi.optimize.minimize(model, **kwargs).fun
with torch.no_grad():
gc_list.append(model(use_temperature=False).item())
gc_list = np.array(gc_list)
gc_analytical = numqi.state.get_maximally_coherent_state_gmc(dim, alpha=alpha_list)
fig,ax = plt.subplots()
ax.plot(alpha_list, gc_list, label='manifold-opt')
ax.plot(alpha_list, gc_analytical, 'x', label='analytical')
ax.legend()
ax.set_xlabel('alpha')
ax.set_ylabel('geometric coherence')
ax.set_title(f'dim={dim}')
fig.tight_layout()
dim = 32 #when dim=64, more num_repeat is needed
psi = numqi.state.maximally_coherent_state(dim)
dm_target = psi.reshape(-1,1) * psi.conj()
alpha_list = np.linspace(0, 1, 50)
model = numqi.coherence.GeometricCoherenceModel(dim, num_term=4*dim, temperature=0.3)
kwargs = dict(theta0='uniform', num_repeat=3, tol=1e-10, print_every_round=0)
gc_list = []
for alpha_i in tqdm(alpha_list):
model.set_density_matrix(numqi.utils.hf_interpolate_dm(dm_target, alpha=alpha_i))
theta_optim = numqi.optimize.minimize(model, **kwargs).fun
with torch.no_grad():
gc_list.append(model(use_temperature=False).item())
gc_list = np.array(gc_list)
gc_analytical = numqi.state.get_maximally_coherent_state_gmc(dim, alpha=alpha_list)
fig,ax = plt.subplots()
ax.plot(alpha_list, gc_list, label='manifold-opt')
ax.plot(alpha_list, gc_analytical, 'x', label='analytical')
ax.legend()
ax.set_xlabel('alpha')
ax.set_ylabel('geometric coherence')
ax.set_title(f'dim={dim}')
fig.tight_layout()