Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cooper pair box #184

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions c3/generator/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,19 +1005,18 @@ def __init__(self, **props):
super().__init__(**props)
self.inputs = props.pop("inputs", 1)
self.outputs = props.pop("outputs", 1)
self.signal = None
if (
self.params["offset_amp"] is None
): # i.e. it was not set in the general params already
self.params["offset_amp"] = props.pop("offset_amp")

def process(self, instr, chan, signal: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Distort signal by adding noise."""
offset_amp = self.params["offset_amp"].get_value()
out_signal = {}
for k, sig in signal[0].items():
out_signal[k] = sig + offset_amp
self.signal = out_signal
def process(
self, instr: Instruction, chan: str, signal: List[Dict[str, Any]]
) -> Dict[str, Any]:
"""Distort signal by adding constant noise."""
components = instr.comps
for comp in components[chan].values():
if isinstance(comp, Envelope):
offset_amp = comp.params["offset_amp"].get_value()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will throw an error when "offset_amp" is not in the Envelope parameters. An easy fix would be to add it in the default here: https://github.com/superplay1/c3/blob/1d685e5d8daf73640898040ee5b3ab8bcce02695/c3/signal/pulse.py#L47-L54

self.signal["values"] = signal[0]["values"] + offset_amp
self.signal["ts"] = signal[0]["ts"]
self.signal["name"] = instr.name
return self.signal


Expand Down
156 changes: 156 additions & 0 deletions c3/libraries/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,162 @@ def get_potential_function(
# pass


@dev_reg_deco
class CooperPairBox(PhysicalComponent):
"""
The CooperPairBox is a basic model of a modifiable Charge qubit. Which is defined by the Hamiltonian:
H=4*EC*(N-NG)^2 + E_J*cos(Phi)
Parameters
----------
EC: Quantity
Charge energy of the qubit
EJ: Quantity
Josephon energy of the qubit
NG: Quantity
Initial value of NG in the hamiltonian from above
Asym: Quantity
Parameter that can modify the effective Josephon energy
Reduced Flux: Quantity
Parameter that can modify the effective Josephon energy
hilbert_dim: Quantity
Dimension of the hilbert space we want to look at
calc_dim: Quantity
Number which defines how many charge levels are included in calculating the hamiltonian
"""

def __init__(
self,
name: str,
desc: str = None,
comment: str = None,
hilbert_dim: int = None,
calc_dim: Quantity = None,
EC: Quantity = None,
EJ: Quantity = None,
NG: Quantity = None,
Asym: Quantity = None,
Reduced_Flux: Quantity = None,
use_FR: bool = True,
params=None,
):
super().__init__(
name=name,
desc=desc,
comment=comment,
hilbert_dim=hilbert_dim,
params=params,
)
if not self.hilbert_dim % 2:
raise Exception("Hilbert dimension has to be odd.")
if EC:
self.params["EC"] = EC
if EJ:
self.params["EJ"] = EJ
if Asym:
self.params["Asym"] = Asym
if Reduced_Flux:
self.params["Reduced_Flux"] = Reduced_Flux
if NG:
self.params["NG"] = NG
if calc_dim:
self.params["calc_dim"] = calc_dim
self.init_Hamiltonian()

def init_Hs(self, ann_oper):
pass

def init_Ls(self, ann_oper):
pass

def init_Hamiltonian(self):
"""
initialize Hamiltonian for initial NG
"""
ec = tf.cast(self.params["EC"].get_value(), tf.complex128)
ej = tf.cast(self.params["EJ"].get_value(), tf.complex128)
asym = tf.cast(self.params["Asym"].get_value(), tf.complex128)
reduced_flux = tf.cast(self.params["Reduced_Flux"].get_value(), tf.complex128)
self.calc_dim = tf.cast(self.params["calc_dim"].get_value(), tf.int32)
ng_mat = tf.linalg.diag(
tf.ones(self.calc_dim - 1, tf.complex128), k=1
) + tf.linalg.diag(tf.ones(self.calc_dim - 1, tf.complex128), k=-1)
ng = tf.cast(self.params["NG"].get_value(), tf.float64)
EJphi = ej * tf.sqrt(
asym**2 + (1 - asym**2) * tf.math.cos(np.pi * reduced_flux) ** 2
)
h = (
4
* ec
* tf.linalg.diag(
tf.cast(
tf.range(
-(self.calc_dim - 1) / 2 - ng,
(self.calc_dim - 1) / 2 - ng + 1,
)
** 2,
tf.complex128,
)
)
- EJphi / 2 * ng_mat
)
e, v = tf.linalg.eigh(h)
self.transform = tf.expand_dims(v, axis=0)
self.static_h = tf.linalg.diag(e)[: self.hilbert_dim, : self.hilbert_dim]
self.transform_inv = tf.expand_dims(tf.linalg.inv(v), axis=0)

def get_Hamiltonian(
self,
signal=None,
transform=None,
):
"""
Calculate Hamiltonians for a given signal, i.e. at each time step.
Parameters
----------
signal : dictionary
Dictionary containing times and values of NG
Returns
-------
tf.Tensor
Hamiltonians
"""
ec = tf.cast(self.params["EC"].get_value(), tf.complex128)
ej = tf.cast(self.params["EJ"].get_value(), tf.complex128)
asym = tf.cast(self.params["Asym"].get_value(), tf.complex128)
ng = tf.cast(self.params["NG"].get_value(), tf.float64)
reduced_flux = tf.cast(self.params["Reduced_Flux"].get_value(), tf.complex128)
EJphi = ej * tf.sqrt(
asym**2 + (1 - asym**2) * tf.math.cos(np.pi * reduced_flux) ** 2
)
ng_mat = (
EJphi
/ 2
* (
tf.linalg.diag(tf.ones(self.calc_dim - 1, tf.complex128), k=1)
+ tf.linalg.diag(tf.ones(self.calc_dim - 1, tf.complex128), k=-1)
)
)
diag_mat_list = tf.range(-(self.calc_dim - 1) / 2, (self.calc_dim - 1) / 2 + 1)
diag_mat = (
2
* tf.sqrt(ec)
* tf.cast(tf.linalg.diag(diag_mat_list), dtype=tf.complex128)
)
ec_identity = 2 * tf.sqrt(ec) * tf.eye(self.calc_dim, dtype=tf.complex128)
ec_identity = tf.expand_dims(ec_identity, axis=0)
diag_mat = tf.expand_dims(diag_mat, axis=0)
ng_mat = tf.expand_dims(ng_mat, axis=0)

if signal:
ng_of_t = tf.cast(signal["values"] + ng, dtype=tf.complex128)
ng_of_t = tf.expand_dims(tf.expand_dims(ng_of_t, axis=1), axis=2)
h = (diag_mat - ng_of_t * ec_identity) ** 2 - ng_mat
h = self.transform_inv @ h @ self.transform
return h
else:
return self.static_h


@dev_reg_deco
class SNAIL(Qubit):
"""
Expand Down
Binary file added test/CooperPairBox.pickle
Binary file not shown.
Loading