Probabilities contain NaN - Vibronic Samples

Hi,

I am receiving NaN values when trying to create vibronic samples. The data I am using matches literature, so I don’t believe it is that. I have a suspicion it is due to there being zeros in my Li and Lf arrays. As I understand it, these are simply the cartesian coordinates for the normal modes. I have tried creating samples using different methods, but always receive the NaN error. If anyone could provide an explanation on how to solve this that would be appreciated.

import numpy as np
import strawberryfields as sf
from strawberryfields import ops
from strawberryfields.apps import qchem, data, plot
from strawberryfields.apps.qchem.vibronic import energies
from strawberryfields.apps.plot import spectrum
import matplotlib.pyplot as plt

ri, m, wi, Li = qchem.read_gamess(r"C:\ethenefreq.txt")
rf, mf, wff, Lf = qchem.read_gamess(r"C:\s1freq.txt")


wi =  wi[6:] # ground state frequencies
wf =  np.array([668.18, 675.79, 892.93, 900.56, 950.70, 1298.70, 1300.89, 1517.26, 2845.94, 2846.25, 2856.70, 2914.49]) # excited state frequencies
m = np.repeat(m, 3)

# Remove the first 6 arrays
Li = Li[6:]

# Reshape the array into a (18, 12) array
Li = np.reshape(Li, (18, 12))

# Remove the first 6 arrays
Lf = Lf[6:]

# Reshape the array into a (18, 12) array
Lf = np.reshape(Lf, (18, 12))

# Flatten the array 
ri = ri.flatten()

# Flatten the array 
rf = rf.flatten()

# Compute displacement vector and Duschinsky matrix
Ud, delta = qchem.duschinsky(Li, Lf, ri, rf, wf, m)

# map this information to GBS parameters
_, U1, r, U2, alpha = qchem.vibronic.gbs_params(wi, wf, Ud, delta)

# Generate Duschisnky matrix
plt.imshow(abs(Ud), cmap="Greens")
plt.colorbar()
plt.xlabel("Mode index")
plt.ylabel("Mode index")
plt.tight_layout()
plt.show()

# Number of modes
n_modes = len(wi)

# number of samples
nr_samples = 20000

# Generate samples and energies using qchem functions
s = qchem.vibronic.sample(t, U1, r, U2, alpha, nr_samples)
e = qchem.vibronic.energies(s, wi, wf)
plot.spectrum(e, xmin=-1000, xmax=8000)

ethenefreq.txt (60.7 KB)
s1freq.txt (60.1 KB)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[15], line 58
     56     qchem.vibronic.VibronicTransition(U1, r, U2, alpha) | q
     57     sf.ops.MeasureFock() | q
---> 58 samples = eng.run(gbs, shots=n_samples).samples.tolist()
     60 n_mean = np.mean(samples, axis=0)

File ~\anaconda3\Lib\site-packages\strawberryfields\engine.py:570, in LocalEngine.run(self, program, args, compile_options, **kwargs)
    565         if c.op.measurement_deps and eng_run_options["shots"] > 1:
    566             raise NotImplementedError(
    567                 "Feed-forwarding of measurements cannot be used together with multiple shots."
    568             )
--> 570 return super()._run(
    571     program_lst, args=args, compile_options=compile_options, **eng_run_options
    572 )

File ~\anaconda3\Lib\site-packages\strawberryfields\engine.py:306, in BaseEngine._run(self, program, args, compile_options, **kwargs)
    303 p.bind_params(args)
    304 p.lock()
--> 306 _, self.samples, self.samples_dict = self._run_program(p, **kwargs)
    307 self.run_progs.append(p)
    309 if isinstance(p, TDMProgram) and received_rolled:

File ~\anaconda3\Lib\site-packages\strawberryfields\engine.py:430, in LocalEngine._run_program(self, prog, **kwargs)
    427 for cmd in prog.circuit:
    428     try:
    429         # try to apply it to the backend and, if op is a measurement, store it in values
--> 430         val = cmd.op.apply(cmd.reg, self.backend, **kwargs)
    431         if val is not None:
    432             for i, r in enumerate(cmd.reg):

File ~\anaconda3\Lib\site-packages\strawberryfields\ops.py:325, in Measurement.apply(self, reg, backend, **kwargs)
    322 if _shots is None:
    323     return None
--> 325 values = super().apply(reg, backend, **kwargs)
    327 # store the results in the register reference objects
    328 for v, r in zip(np.transpose(values), reg):

File ~\anaconda3\Lib\site-packages\strawberryfields\ops.py:228, in Operation.apply(self, reg, backend, **kwargs)
    226 temp = [rr.ind for rr in reg]
    227 # call the child class specialized _apply method
--> 228 return self._apply(temp, backend, **kwargs)

File ~\anaconda3\Lib\site-packages\strawberryfields\ops.py:1179, in MeasureFock._apply(self, reg, backend, shots, **kwargs)
   1178 def _apply(self, reg, backend, shots=1, **kwargs):
-> 1179     samples = backend.measure_fock(reg, shots=shots, select=self.select, **kwargs)
   1181     if isinstance(samples, list):
   1182         samples = np.array(samples)

File ~\anaconda3\Lib\site-packages\strawberryfields\backends\gaussianbackend\backend.py:233, in GaussianBackend.measure_fock(self, modes, shots, select, **kwargs)
    231 # check we are sampling from a gaussian state with zero mean
    232 if allclose(mu, zeros_like(mu)):
--> 233     samples = hafnian_sample_state(reduced_cov, shots)
    234 else:
    235     samples = hafnian_sample_state(reduced_cov, shots, mean=reduced_mean)

File ~\anaconda3\Lib\site-packages\thewalrus\samples.py:361, in hafnian_sample_state(cov, samples, mean, hbar, cutoff, max_photons, parallel)
    358     return np.vstack(results)
    360 params = [cov, samples, mean, hbar, cutoff, max_photons]
--> 361 return _hafnian_sample(params)

File ~\anaconda3\Lib\site-packages\thewalrus\samples.py:311, in _hafnian_sample(args)
    308 j = 0
    310 while j < samples:
--> 311     result = generate_hafnian_sample(
    312         cov, mean=mean, hbar=hbar, cutoff=cutoff, max_photons=max_photons
    313     )
    315     if result != -1:
    316         # if result == -1, then you never get anything beyond cutoff
    317         samples_array.append(result)

File ~\anaconda3\Lib\site-packages\thewalrus\samples.py:250, in generate_hafnian_sample(cov, mean, hbar, cutoff, max_photons)
    247     norm_probs = probs.sum()
    248     probs /= norm_probs
--> 250     det_outcome_i = np.random.choice(det_outcomes, p=probs)
    251     det_pattern[mode] = det_outcome_i
    253 if det_pattern[order_inv][-1] == cutoff:

File mtrand.pyx:954, in numpy.random.mtrand.RandomState.choice()

ValueError: probabilities contain NaN

Thanks :slight_smile:
Reece

Hey @ReeceOB!

I think it’s just a precision thing. There is a line in TheWalrus here that removes unwanted negative values <-1e-11. You can locally change that precision to be 1e-10, and then it might work fine :slight_smile: