def run_and_create(n):
    inputfile = open('./Task2Code/input_for_exercise3.txt', "r")

    N = int(inputfile.readline())  #Number of Atoms
    nmodes = 3 * N - 6  #Number of Modes

    w = np.zeros(nmodes, float)  #vib. frequencies of ground electronic state
    wp = np.zeros(nmodes, float)  #vib. frequencies of excited electronic state
    Ud = np.zeros((nmodes, nmodes), float)  #Duschinsky Matrix
    delta = np.zeros(nmodes, float)  #Displacement Vector

    ###############################
    ##### READ IN PARAMETERS ######
    ###############################

    for i in range(nmodes):
        w[i] = float(inputfile.readline())
    for i in range(nmodes):
        wp[i] = float(inputfile.readline())
    for i in range(nmodes):
        for j in range(nmodes):
            Ud[i, j] = float(inputfile.readline())

    for i in range(nmodes):
        delta[i] = float(inputfile.readline())

    T = 500  # temperature

    #####################################
    ##### CALCULATE GBS PARAMETERS ######
    #####################################

    t, U1, r, U2, alpha = vibronic.gbs_params(w, wp, Ud, delta, T)

    ###############################
    ###### GENERATE SAMPLES #######
    ###############################

    nr_samples = n
    s = sample.vibronic(t, U1, r, U2, alpha, nr_samples)
    e = vibronic.energies(s, w, wp)

    ###############################
    ######## PLOT SPECTRUM ########
    ###############################

    spectrum = plot.spectrum(e, xmin=-300, xmax=2000)
    offline.plot(spectrum, filename="spectrum_{}_samples.html".format(n))
from :cite:`huh2015boson`, can be found in the :mod:`~.apps.data` module:
"""
from strawberryfields.apps import vibronic, data
import numpy as np
formic = data.Formic()
w = formic.w  # ground state frequencies
wp = formic.wp  # excited state frequencies
Ud = formic.Ud  # Duschinsky matrix
delta = formic.delta  # displacement vector
T = 0  # temperature

##############################################################################
# We can now map this chemical information to GBS parameters using the function
# :func:`~.gbs_params`:

t, U1, r, U2, alpha = vibronic.gbs_params(w, wp, Ud, delta, T)

##############################################################################
# Note that since two-mode squeezing operators are involved, if we have :math:`N` vibrational
# modes, the Gaussian state prepared is a :math:`2N`-mode Gaussian state and the samples
# are vectors of length :math:`2N`. The first :math:`N` modes are those of the final electronic
# state; the remaining :math:`N` modes are those of the ground state. From above, :math:`t` is a
# vector of two-mode squeezing parameters, :math:`U_1` and :math:`U_2` are the interferometer
# unitaries (we need two interferometers), :math:`r` is a vector of single-mode squeezing
# parameters, and `alpha` is a vector of displacements.
#
# Photons detected at the output of the GBS device correspond to a specific transition energy.
# The GBS algorithm for vibronic spectra works because the programmed device provides samples
# in such a way that the energies that are sampled with high probability are the peaks of the
# vibronic spectrum. The function :func:`~.energies` can be used to compute the energies for
# a set of samples. In this case we show the energy of the first five samples:
 def test_invalid_temperature(self):
     """Test if function raises a ``ValueError`` when a negative temperature is given."""
     with pytest.raises(ValueError,
                        match="Temperature must be zero or positive"):
         vibronic.gbs_params(self.w, self.wp, self.Ud, self.d, -1)
 def test_zero_temperature(self):
     """Test if function returns zero two-mode squeezing parameters when temperature is zero."""
     t, _, _, _, _ = vibronic.gbs_params(self.w, self.wp, self.Ud, self.d,
                                         0.0)
     assert np.all(t == 0)
class TestGBSParams:
    """Tests for the function ``strawberryfields.apps.vibronic.gbs_params``"""

    dim = 7
    w = np.array([
        3765.2386, 3088.1826, 1825.1799, 1416.9512, 1326.4684, 1137.0490,
        629.7144
    ])
    wp = np.array([
        3629.9472, 3064.9143, 1566.4602, 1399.6554, 1215.3421, 1190.9077,
        496.2845
    ])
    Ud = np.array([
        [0.9934, 0.0144, 0.0153, 0.0268, 0.0638, 0.0751, -0.0428],
        [-0.0149, 0.9931, 0.0742, 0.0769, -0.0361, -0.0025, 0.0173],
        [-0.0119, -0.0916, 0.8423, 0.1799, -0.3857, 0.3074, 0.0801],
        [0.0381, 0.0409, -0.3403, -0.5231, -0.6679, 0.3848, 0.1142],
        [-0.0413, -0.0342, -0.4004, 0.7636, -0.1036, 0.4838, 0.0941],
        [0.0908, -0.0418, -0.0907, 0.3151, -0.5900, -0.7193, 0.1304],
        [-0.0325, 0.0050, -0.0206, 0.0694, -0.2018, 0.0173, -0.9759],
    ])
    d = np.array([0.2254, 0.1469, 1.5599, -0.3784, 0.4553, -0.3439, 0.0618])

    T = 300.0

    t, U1, S, U2, alpha = vibronic.gbs_params(w, wp, Ud, d, T)

    @pytest.mark.parametrize("unitary", [U1, U2])
    def test_unitary(self, unitary):
        """Test if function outputs the interferometer unitaries that are valid unitaries,
        i.e., satisfying U U^dag = I"""
        assert unitary.shape == (self.dim, self.dim)
        assert np.allclose(unitary @ unitary.T.conj(), np.identity(self.dim))

    def test_displacement(self):
        """Test if function returns correct displacement parameters"""
        assert np.allclose(self.alpha * np.sqrt(2), self.d)

    def test_squeezing(self):
        """Test if function returns squeezing parameters as a vector rather than a diagonal
        matrix"""
        assert self.S.shape == (self.dim, )

    def test_duschinsky(self):
        """Test if function returns interferometer unitary and squeezing parameters that
        correctly reconstruct the input Duschinsky matrix"""
        sigma = np.diag(np.exp(self.S))
        J = self.U2 @ sigma @ self.U1
        Ud = np.diag(self.wp**-0.5) @ J @ np.diag(self.w**0.5)
        assert np.allclose(Ud, self.Ud)

    def test_invalid_temperature(self):
        """Test if function raises a ``ValueError`` when a negative temperature is given."""
        with pytest.raises(ValueError,
                           match="Temperature must be zero or positive"):
            vibronic.gbs_params(self.w, self.wp, self.Ud, self.d, -1)

    def test_twomode(self):
        """Test if function returns two-mode squeezing parameters that correctly reconstruct the
        input normal mode frequencies."""
        w = -k * self.T / (0.5 * h * c * 100) * np.log(np.tanh(self.t))
        assert np.allclose(w, self.w)

    def test_zero_temperature(self):
        """Test if function returns zero two-mode squeezing parameters when temperature is zero."""
        t, _, _, _, _ = vibronic.gbs_params(self.w, self.wp, self.Ud, self.d,
                                            0.0)
        assert np.all(t == 0)