<commit_before># -*- coding: utf-8 -*-

import json

import numpy as np
from numpy import pi
import qutip as qu

from maxwellbloch import ob_base, field, t_funcs


class OBAtom(ob_base.OBBase):

    def __init__(self, num_states=1, energies=[], decays=[], fields=[]):
        """
        Args:
            decays: list of dicts representing decays.
            e.g.
            [ { "rate": 1.0, "channels": [[0,1]] }
              { "rate": 2.0, "channels": [[2,1], [3,1]] } ]
        """

        super().__init__()

        self.num_states = num_states
        self.energies = energies
        self.decays = decays

        self.build_fields(fields)

        self.build_operators()

        self.init_rho()

    def __repr__(self):
        return ("Atom(num_states={0}, " +
                "energies={1}, " +
                "decays={2}, " +
                "fields={3})").format(self.num_states,
                                      self.energies,
                                      self.decays,
                                      self.fields)

    def add_field(self, field_dict):
        self.fields.append(field.Field(**field_dict))

    def build_fields(self, field_dicts):
        self.fields = []
        for f in field_dicts:
            self.add_field(f)
        return self.fields

    def build_operators(self):
        """ Build the quantum operators representing the bare Hamiltonian,
            collapse operators and interaction Hamiltonian.
        """

        self.build_H_0()
        self.build_c_ops()
        self.build_H_Delta()
        self.build_H_Omega()

    def build_H_0(self):
        """ Makes a Bare Hamiltonian with the energies as diagonals.

        Leave the list empty for all zero energies (i.e. if you don't care
        about absolute energies.)

        Returns:
            H_0 = [energies[0]             0  ...]
                  [             0 energies[1] ...]
                  [           ...         ... ...]

        """

        if self.energies:
            H_0 = np.diag(np.array(self.energies))
        else:
            H_0 = np.zeros([self.num_states, self.num_states])

        self.H_0 = qu.Qobj(H_0)
        return self.H_0

    def build_c_ops(self):
        """ Takes the list of decays and makes a list of collapse operators to
            be passed to the solver.
        """

        self.c_ops = []

        for d in self.decays:
            r = d["rate"]
            for c in d["channels"]:
                self.c_ops.append(np.sqrt(2 * pi * r) * self.sigma(c[0], c[1]))
        return self.c_ops

    def build_H_Delta(self):

        self.H_Delta = qu.Qobj(np.zeros([self.num_states, self.num_states]))

        for f in self.fields:
            if f.detuning_positive:
                sgn = 1.
            else:
                sgn = -1.
            for c in f.coupled_levels:
                self.H_Delta -= sgn * f.detuning * self.sigma(c[1], c[1])
<commit_msg>Add a null decay operator in the case of no decays<commit_after># -*- coding: utf-8 -*-

import json

import numpy as np
from numpy import pi
import qutip as qu

from maxwellbloch import ob_base, field, t_funcs


class OBAtom(ob_base.OBBase):

    def __init__(self, num_states=1, energies=[], decays=[], fields=[]):
        """
        Args:
            decays: list of dicts representing decays.
            e.g.
            [ { "rate": 1.0, "channels": [[0,1]] }
              { "rate": 2.0, "channels": [[2,1], [3,1]] } ]
        """

        super().__init__()

        self.num_states = num_states
        self.energies = energies
        self.decays = decays # TODO: Do we need self.decays if building c_ops?

        self.build_fields(fields)

        self.build_operators()

        self.init_rho()

    def __repr__(self):
        return ("Atom(num_states={0}, " +
                "energies={1}, " +
                "decays={2}, " +
                "fields={3})").format(self.num_states,
                                      self.energies,
                                      self.decays,
                                      self.fields)

    def add_field(self, field_dict):
        self.fields.append(field.Field(**field_dict))

    def build_fields(self, field_dicts):
        self.fields = []
        for f in field_dicts:
            self.add_field(f)
        return self.fields

    def build_operators(self):
        """ Build the quantum operators representing the bare Hamiltonian,
            collapse operators and interaction Hamiltonian.
        """

        self.build_H_0()
        self.build_c_ops()
        self.build_H_Delta()
        self.build_H_Omega()

    def build_H_0(self):
        """ Makes a Bare Hamiltonian with the energies as diagonals.

        Leave the list empty for all zero energies (i.e. if you don't care
        about absolute energies.)

        Returns:
            H_0 = [energies[0]             0  ...]
                  [             0 energies[1] ...]
                  [           ...         ... ...]

        """

        if self.energies:
            H_0 = np.diag(np.array(self.energies))
        else:
            H_0 = np.zeros([self.num_states, self.num_states])

        self.H_0 = qu.Qobj(H_0)
        return self.H_0

    def build_c_ops(self):
        """ Takes the list of decays and makes a list of collapse operators to
            be passed to the solver.

        Notes:
            We want at least one collapse operator to force the master equation
            solver producing density matrices, not state vectors. In the case
            that self.decays is empty, we'll add a zero collapse operator.
        """

        self.c_ops = []

        if not self.decays:
            self.c_ops.append(qu.Qobj(np.zeros([self.num_states,
                self.num_states])))
        else:
            for d in self.decays:
                r = d["rate"]
                for c in d["channels"]:
                    self.c_ops.append(np.sqrt(2*pi*r)*self.sigma(c[0], c[1]))

        return self.c_ops

    def build_H_Delta(self):

        self.H_Delta = qu.Qobj(np.zeros([self.num_states, self.num_states]))

        for f in self.fields:
            if f.detuning_positive:
                sgn = 1.
            else:
                sgn = -1.
            for c in f.coupled_levels:
                self.H_Delta -= sgn * f.detuning * self.sigma(c[1], c[1])

{'fraction_non_alphanumeric': 0.11444270015698588, 'fraction_numerical': 0.01098901098901099, 'mean_word_length': 1.500392464678179, 'pattern_counts': {'":': 8, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2847580', 'n_tokens_mistral': 1992, 'n_tokens_neox': 1882, 'n_words': 474}