def numgradsigma_gaus(self, iqubit, igaus, ini_state, pobj, hobj, tlist, nstep, delx=0.0005): from ctrlq.lib.solve import pulsec pobj.sigma[iqubit][igaus] += delx amp__ = [[] for i in range(pobj.nqubit)] for i in range(pobj.nqubit): for j in tlist: tmpamp__ = 0.0 for k in range(pobj.ngaus): tmpamp__ += pobj.amp[i][k] * exp(-pobj.sigma[i][k]**2 * (j - pobj.mean[i][k])**2) amp__[i].append(tmpamp__) sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(amp__, [[0.0]], sfreq, pobj.duration, pobj.nqubit, 0) f1 = self.efunc(ini_state, pobjc, hobj, 'trotter', nstep, False, twindow=False, cobj=True) pobj.sigma[iqubit][igaus] -= 2 * delx amp__ = [[] for i in range(pobj.nqubit)] for i in range(pobj.nqubit): for j in tlist: tmpamp__ = 0.0 for k in range(pobj.ngaus): tmpamp__ += pobj.amp[i][k] * exp(-pobj.sigma[i][k]**2 * (j - pobj.mean[i][k])**2) amp__[i].append(tmpamp__) sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(amp__, [[0.0]], sfreq, pobj.duration, pobj.nqubit, 0) f2 = self.efunc(ini_state, pobjc, hobj, 'trotter', nstep, False, twindow=False, cobj=True) g_ = (f1 - f2) / (2 * delx) pobj.mean[iqubit][igaus] += delx return g_
def gradfunc(self, list1, pobj, hobj, nstep, test=False): import functools, operator, math from ctrlq.lib.solve import pulsec from ctrlq.lib.agradc import grad_trotter ini_state = hobj.initial_state tlist = numpy.linspace(0, pobj.duration, nstep) dsham = numpy.diagonal(-1j * hobj.dsham.toarray()) cout = 0 for i in range(pobj.nqubit): for j in range(pobj.nwindow): pobj.amp[i][j] = list1[cout] cout += 1 for i in range(pobj.nqubit): pobj.freq[i] = list1[cout] cout += 1 sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(pobj.amp, pobj.tseq, sfreq, pobj.duration, pobj.nqubit, pobj.nwindow) aobj = grad_trotter(tlist, ini_state, pobjc, numpy.array(hobj.hdrive), dsham, hobj.states, hobj.mham) if test: cout_ = 0 for i in range(pobj.nqubit): for j in range(pobj.nwindow): numag_ = self.numgradamp_5_(i, j, ini_state, pobj, hobj, nstep, delx=1e-8) if not math.isclose(numag_, aobj.gradient[i][j], abs_tol=1e-6): cout_ += 1 print('There are ' + str(cout_) + ' gradients with absolute difference of more than 1e-6') agradient = functools.reduce(operator.iconcat, aobj.gradient, []) for i in range(pobj.nqubit): ng1 = self.numgradfreq_2_(i, aobj.energy, ini_state, pobj, hobj, nstep) agradient.append(ng1) self.energy_ = aobj.energy self.leak = 1.0 - aobj.norm return (aobj.energy, agradient)
def gaussquare(ini_state, pobj, hobj, solver, nstep, normalize, twindow=False, leak=False): from ctrlq.lib.solve import pulsec from ctrlq.cvqe.evolve import evolve import matplotlib.pyplot as plt # Gaussian square (flattop) pulse, expt. # convert pobj to amp at every time step mean = pobj.duration/2.0 amp = [] for i in range(pobj.nqubit): tmp_a = [] tlist = numpy.linspace(0., pobj.duration, nstep) for j in tlist: tmp_a.append(pobj.amp[i][0] * flattop(j-mean, mean, 8.0, 2.0)) tmp_b = 1000.* (1/(numpy.pi * 2.0)) * numpy.array(tmp_a) plt.plot(tlist, tmp_b) plt.show() amp.append(tmp_a) stseq = numpy.array(pobj.tseq) / pobj.tscale sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(amp, stseq, sfreq, pobj.duration, pobj.nqubit, pobj.nwindow) out = evolve(ini_state, pobjc, hobj, solver=solver, nstep=nstep, twindow=twindow) state_ = [] for i in hobj.states: state_.append(out[i]) state_ = numpy.array(state_) nrm = numpy.linalg.norm(state_) leak_ = 1. - nrm if normalize: nrm = numpy.linalg.norm(state_) staten = state_ /nrm else: staten = state_ energy = functools.reduce(numpy.dot, (staten.conj().T, hobj.mham, staten)) energy = energy.real[0][0] if leak: return (energy, leak_) return energy
def anagaus(self, list1, pobj, hobj, nstep, normalize): from ctrlq.lib.solve import pulsec from ctrlq.lib.agradc import grad_trotter from ctrlq.lib.pulse_helper import gaus_getnamp # Analytic gradient for gaussian pulse # list1 [[[amp, mean, sigma] for ngaus] for nqubit] ini_state = hobj.initial_state tlist = numpy.linspace(0, pobj.duration, nstep) dsham = numpy.diagonal(-1j * hobj.dsham.toarray()) cout = 0 for i in range(pobj.nqubit): for j in range(pobj.ngaus): pobj.amp[i][j] = list1[cout] cout += 1 pobj.mean[i][j] = list1[cout] cout += 1 pobj.sigma[i][j] = list1[cout] cout += 1 sfreq = numpy.array(pobj.freq) / pobj.fscale ggrad = gaus_getnamp(pobj.nqubit, pobj.ngaus, pobj.duration, pobj.amp, pobj.sigma, pobj.mean, sfreq, tlist, ini_state, numpy.array(hobj.hdrive), dsham, hobj.states, hobj.mham) pobj.gausamp_ = ggrad.amp pobjc = pulsec(ggrad.amp, [[0.0]], sfreq, pobj.duration, pobj.nqubit, 0) gradient = ggrad.gradient for i in range(pobj.nqubit): # pobjc.amp - list of amp for every trotter step ng1 = self.numgradfreq_2_(i, ggrad.energy, ini_state, pobjc, hobj, nstep, cobj=True) gradient.append(ng1) self.energy_ = ggrad.energy self.leak = 1.0 - ggrad.norm self.gradient_ = gradient return (ggrad.energy, gradient)
def efunc(self, ini_state, pobj, hobj, solver, nstep, normalize, supdate=False): from ctrlq.lib.solve import pulsec stseq = numpy.array(pobj.tseq) / pobj.tscale sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(pobj.amp, stseq, sfreq, pobj.duration, pobj.nqubit, pobj.nwindow) out = evolve(ini_state, pobjc, hobj, solver=solver, nstep=nstep) state_ = [] for i in hobj.states: state_.append(out[i]) state_ = numpy.array(state_) if normalize: nrm = numpy.linalg.norm(state_) if supdate: self.leak = 1.0 - nrm staten = state_ / nrm else: if supdate: nrm = numpy.linalg.norm(state_) self.leak = 1.0 - nrm staten = state_ energy = functools.reduce(numpy.dot, (staten.conj().T, hobj.mham, staten)) energy = energy.real[0][0] if supdate: self.energy_ = energy return energy
def efunc(self, ini_state, pobj, hobj, solver, nstep, normalize, supdate=False, twindow=True, cobj=False, tmp=0, exactV=[]): from ctrlq.lib.solve import pulsec if not cobj: stseq = numpy.array(pobj.tseq) / pobj.tscale sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(pobj.amp, stseq, sfreq, pobj.duration, pobj.nqubit, pobj.nwindow) out = evolve(ini_state, pobjc, hobj, solver=solver, nstep=nstep, twindow=twindow) else: out = evolve(ini_state, pobj, hobj, solver=solver, nstep=nstep, twindow=twindow) state_ = [] for i in hobj.states: state_.append(out[i]) state_ = numpy.array(state_) if exactV: ovlp = numpy.dot(state_.conj().T, exactV) print(' Overlap : {:>8.4f} %'.format(ovlp * 100.)) if normalize: nrm = numpy.linalg.norm(state_) if supdate: self.leak = 1.0 - nrm staten = state_ / nrm else: if supdate: nrm = numpy.linalg.norm(state_) self.leak = 1.0 - nrm staten = state_ energy = functools.reduce(numpy.dot, (staten.conj().T, hobj.mham, staten)) energy = energy.real[0][0] if supdate: self.energy_ = energy return energy
def anagaus_py(self, list1, pobj, hobj, nstep): from ctrlq.lib.solve import pulsec from ctrlq.lib.agradc import grad_trotter from ctrlq.lib.pulse_helper import gaus_getnamp #,gaus_gettamp # Analytic gradient for gaussian pulse # list1 [[[amp, mean, sigma] for ngaus] for nqubit] ini_state = hobj.initial_state tlist = numpy.linspace(0, pobj.duration, nstep) dsham = numpy.diagonal(-1j * hobj.dsham.toarray()) cout = 0 for i in range(pobj.nqubit): for j in range(pobj.ngaus): pobj.amp[i][j] = list1[cout] cout += 1 pobj.mean[i][j] = list1[cout] cout += 1 pobj.sigma[i][j] = list1[cout] cout += 1 sfreq = numpy.array(pobj.freq) / pobj.fscale amp__ = [[] for i in range(pobj.nqubit)] for i in range(pobj.nqubit): for j in tlist: tmpamp_ = 0.0 for k in range(pobj.ngaus): tmpamp_ += pobj.amp[i][k] * exp(-pobj.sigma[i][k]**2 * (j - pobj.mean[i][k])**2) amp__[i].append(tmpamp_) pobj.gausamp_ = amp__ pobjc_ = pulsec(amp__, [[0.0]], sfreq, pobj.duration, pobj.nqubit, 0) aobj = grad_trotter(tlist, ini_state, pobjc_, numpy.array(hobj.hdrive), dsham, hobj.states, hobj.mham) agradient__ = [] for i in range(pobj.nqubit): for j in range(pobj.ngaus): gamp_ = 0.0 gsig_ = 0.0 gmean = 0.0 for k in range(nstep): esigmean_ = aobj.gradient[i][k] * exp( -pobj.sigma[i][j]**2 * (tlist[k] - pobj.mean[i][j])**2) gamp_ += esigmean_ gsig_ += esigmean_ * pobj.amp[i][j] * -2.0 * pobj.sigma[i][j] *\ (tlist[k] - pobj.mean[i][j])**2 gmean += esigmean_ * pobj.amp[i][j] * 2.0 * pobj.sigma[i][j]**2 *\ (tlist[k] - pobj.mean[i][j]) agradient__.extend([gamp_, gsig_, gmean]) # freq for i in range(pobj.nqubit): # pobjc.amp - list of amp for every trotter step ng1 = self.numgradfreq_2_(i, ggrad.energy, ini_state, pobjc, hobj, nstep, cobj=True) agradient__.append(ng1) self.energy_ = aobj.energy self.leak = 1.0 - aobj.norm return (aobj.energy, agradient__)
def energy(self, normalize=True, twindow=True, flattop=False, exactV=[], shape='square'): """ Parameters ---------- normalize : bool Whether to normalize the expectation value. Defaults to True. twindow : bool Turn on/off piecewise function. Deaults to True. shape : str Shape of control pulse. 'square' and 'gaussian' forms are supported. Defaults to 'square' exactV : list Supply the exact state to print out overlap (optional). """ from ._flattop import gaussquare from ctrlq.lib.solve import pulsec if flattop: e1, l1 = gaussquare(self.ham.initial_state, self.pulse, self.ham, self.solver, self.nstep, normalize, leak=True) return (e1, self.leak) if shape == 'gaussian': amp__ = [[] for i in range(self.pulse.nqubit)] tlist__ = numpy.linspace(0, self.pulse.duration, self.nstep) for i in range(self.pulse.nqubit): for j in tlist__: tmpamp__ = 0.0 for k in range(self.pulse.ngaus): tmpamp__ += self.pulse.amp[i][k] * exp( -self.pulse.sigma[i][k]**2 * (j - self.pulse.mean[i][k])**2) amp__[i].append(tmpamp__) sfreq__ = numpy.array(self.pulse.freq) / self.pulse.fscale pobjc__ = pulsec(amp__, [[0.0]], sfreq__, self.pulse.duration, self.pulse.nqubit, 0) e1 = self.efunc(self.ham.initial_state, pobjc__, self.ham, self.solver, self.nstep, normalize, supdate=True, twindow=False, cobj=True) elif shape == 'square': e1 = self.efunc(self.ham.initial_state, self.pulse, self.ham, self.solver, self.nstep, normalize, supdate=True, twindow=twindow, exactV=exactV) else: sys.exit('Pulse shape not supported. Try square, gaussian or flattop') if self.iprint: print() print(' Energy (ctrl-vqe) : {:>18.12f} H'.format(e1)) print(' Leakage : {:>18.12f} %'.format(self.leak * 100.)) return (e1, self.leak)
def objfunc_wpulse(self, list1, pobj, hobj, nstep, normalize, interact, freqopt): from ctrlq.lib.solve import pulsec from ctrlq.lib.agradc import grad_trotter from ctrlq.lib.agradc import grad_trotter_normalized pi2 = 2 * numpy.pi device_ = device4() # ini_state = hobj.initial_state tlist = numpy.linspace(0, pobj.duration, nstep) ampcout = [[] for i in range(pobj.nqubit)] for i in range(pobj.nqubit): if pobj.nwindow == 1: ampcout[i].append(twinamp(0.0, pobj.duration, tlist)) continue for j in range(pobj.nwindow - 1): if j == 0: ampcout[i].append(twinamp(0.0, pobj.tseq[i][j], tlist)) else: ampcout[i].append( twinamp(pobj.tseq[i][j - 1], pobj.tseq[i][j], tlist)) ampcout[i].append(twinamp(pobj.tseq[i][j], pobj.duration, tlist)) amp = [[] for j in range(pobj.nqubit)] samp = [[] for j in range(pobj.nqubit)] cout = 0 for i in range(pobj.nqubit): for j in range(pobj.nwindow): if j == 0: amp[i].append(0.0) #amp=0.0 at t=0.0 for k in range(ampcout[i][j]): amp[i].append(list1[cout]) samp[i].append(list1[cout]) cout += 1 self.square_amp = samp pobj.amp = amp if freqopt: for i in range(pobj.nqubit): pobj.freq[i] = list1[cout] cout += 1 for i in range(pobj.nqubit): device_.w[i] = pi2 * list1[cout] cout += 1 sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(amp, pobj.tseq, sfreq, pobj.duration, pobj.nqubit, pobj.nwindow) hstatic_ = transmon4_static(param=device_, interact=interact) hobj_ = transmon(mham=hobj.mham, nqubit=hobj.nqubit, Hstatic=hstatic_) dsham = numpy.diagonal(-1j * hobj_.dsham.toarray()) if normalize: aobj = grad_trotter_normalized(tlist, ini_state, pobjc, numpy.array(hobj_.hdrive), dsham, hobj_.states, hobj_.mham) else: aobj = grad_trotter(tlist, ini_state, pobjc, numpy.array(hobj_.hdrive), dsham, hobj_.states, hobj_.mham) self.square_gamp = aobj.gradient agradient = [] for i in range(pobj.nqubit): cout_ = 0 for j in range(pobj.nwindow): agrad__ = 0.0 if j == 0: #agrad__ += aobj.gradient[i][0] cout_ += 1 for k in range(ampcout[i][j]): agrad__ += aobj.gradient[i][cout_] cout_ += 1 agradient.append(agrad__) if freqopt: for i in range(pobj.nqubit): ng1 = self.numgradfreq_2_(i, aobj.energy, ini_state, pobj, hobj_, nstep, normalize=normalize) agradient.append(ng1) for i in range(pobj.nqubit): ng1 = self.numgradw_2_(i, aobj.energy, ini_state, pobj, hobj_, nstep, device_, interact, normalize=normalize) agradient.append(ng1) self.energy_ = aobj.energy self.leak = 1.0 - aobj.norm self.gradient_ = agradient return (aobj.energy, agradient)
def optimize(self, method='l-bfgs-b', maxiter=100, maxls=20, gtol=1.0e-09, ftol=1.0e-09, exactE=0.0, normalize=False, gradient='numerical', shape='square', optiter=True, pulse_return=False): """Variational pulse optimization: Perform ctrl-VQE pulse optimization using the expectation value of the molecular hamiltonian supplied in ham class. Parameters ---------- method : str Numerical optimization method. Only supports 'l-bfgs-b'. normalize : bool Whether to normalize the expectation value. Defaults to False. maxiter : int Maximum number of iteration for optimization. Defaults to 100. maxls : int Set the maximum number of line searches in each optimization step (l-bfgs-b line search). Defaults to 20. gradient : str Method for computing the gradients in the optimization. 'numerical' for numerical gradients for all pulse parameters. 'analytical' for an analytical gradients for the amplitudes and numerical gradients for the frequencies. Defaults to 'numerical'. optiter : bool If set False, energy and gradients for the initial step can be returned. Defaults to True. gtol : float Exposes gtol of l-bfgs-b's in scipy. Defaults to 1e-9. ftol : float Exposes ftol of l-bfgs-b's in scipy. Defaults to 1e-9. shape : str Shape of control pulse. 'square' and 'gaussian' forms are supported. Defaults to 'square' pulse_return: bool Returns the pulse object if set True. Defaults to False. """ from ctrlq.lib.solve import pulsec # initial parameters ilist = [] if method == 'l-bfgs-b': if shape == 'gaussian': for i in range(self.pulse.nqubit): for j in range(self.pulse.ngaus): ilist.extend([ self.pulse.amp[i][j], self.pulse.mean[i][j], self.pulse.sigma[i][j] ]) elif shape == 'square': for i in range(self.pulse.nqubit): for j in range(self.pulse.nwindow): ilist.append(self.pulse.amp[i][j]) elif shape == 'flattop': # exp. for i in range(self.pulse.nqubit): ilist.append(self.pulse.amp[i][0]) else: sys.exit( 'Pulse shape not supported. Try square, gaussian or flattop') for i in self.pulse.freq: ilist.append(i) if self.iprint > 1: print(' -----* Entering pulse optimizations *-----', flush=True) print( ' Pulse parameters: Amplitude, time window (if any), frequency', flush=True) if gradient == 'numerical': if shape == 'square': E_ = self.efunc(self.ham.initial_state, self.pulse, self.ham, self.solver, self.nstep, normalize, supdate=True, twindow=True) elif shape == 'flattop': E_ = self.gaussquare_obj(ilist, self.pulse, self.ham, self.solver, self.nstep, normalize, grad=False) else: if shape == 'square': self.anatwin(ilist, self.pulse, self.ham, self.nstep, normalize) elif shape == 'flattop': E_ = self.gaussquare_obj(ilist, self.pulse, self.ham, self.solver, self.nstep, normalize, grad=False) if shape == 'gaussian': amp__ = [[] for i in range(self.pulse.nqubit)] tlist__ = numpy.linspace(0, self.pulse.duration, self.nstep) for i in range(self.pulse.nqubit): for j in tlist__: tmpamp__ = 0.0 for k in range(self.pulse.ngaus): tmpamp__ += self.pulse.amp[i][k] * exp( -self.pulse.sigma[i][k]**2 * (j - self.pulse.mean[i][k])**2) amp__[i].append(tmpamp__) sfreq__ = numpy.array(self.pulse.freq) / self.pulse.fscale pobjc__ = pulsec(amp__, [[0.0]], sfreq__, self.pulse.duration, self.pulse.nqubit, 0) E_ = self.efunc(self.ham.initial_state, pobjc__, self.ham, self.solver, self.nstep, normalize, supdate=True, twindow=False, cobj=True) self.print_step(ilist) if gradient == 'numerical': if shape == 'square': res1 = scipy.optimize.minimize(self.objfunc, ilist, args=(self.pulse, self.ham, self.solver, self.nstep, normalize, False), method=method, jac=True, bounds=self.pulse.constraint, callback=self.print_step, options={ 'maxiter': maxiter, 'gtol': gtol, 'ftol': ftol, 'maxls': maxls }) #, 'iprint':1,'disp':1}) elif shape == 'flattop': res1 = scipy.optimize.minimize(self.gaussquare_obj, ilist, args=(self.pulse, self.ham, self.solver, self.nstep, normalize), method=method, jac=True, bounds=self.pulse.constraint, callback=self.print_step, options={ 'maxiter': maxiter, 'gtol': gtol, 'ftol': ftol, 'maxls': maxls }) #, 'iprint':1,'disp':1}) elif gradient == 'analytical': if shape == 'square' or shape == 'gaussian': if shape == 'square': objf__ = self.anatwin elif shape == 'gaussian': objf__ = self.anagaus if optiter: res1 = scipy.optimize.minimize( objf__, ilist, args=(self.pulse, self.ham, self.nstep, normalize), method=method, jac=True, bounds=self.pulse.constraint, callback=self.print_step, options={ 'maxiter': maxiter, 'gtol': gtol, 'ftol': ftol, 'maxls': maxls }) #, 'iprint':1000,'disp':1000}) else: objf__(ilist, self.pulse, self.ham, self.nstep, normalize) else: res1 = scipy.optimize.minimize(self.gradfunc, ilist, args=(self.pulse, self.ham, self.nstep), method=method, jac=True, bounds=self.pulse.constraint, callback=self.print_step, options={ 'maxiter': maxiter, 'gtol': gtol, 'ftol': ftol, 'maxls': maxls }) #, 'iprint':1,'disp':1}) else: sys.exit( 'Gradient method not implemented. Supports \'numerical\' and \'analytical\' only.' ) if self.iprint > 0: print(flush=True) print(' Pulse optimization ends', flush=True) if optiter: print(' ', res1.message) print(' ------------------------------------------', flush=True) print(flush=True) print(' Printing progress', flush=True) print(' --------------------------------------------------------', flush=True) print(' --------------------------------------------------------', flush=True) print(' Iter Energy(H) Leak(%) Ediff(H) Gnorm', flush=True) for i in range(len(self.elist_)): if i == 0: idx__ = 0 else: idx__ = i - 1 print( ' {:>3d} {:>18.12f} {:>7.4f} {:>.4e} {:>.4e}'.format( i, self.elist_[i], self.llist_[i] * 100., abs(self.elist_[i] - self.elist_[idx__]), numpy.linalg.norm(self.glist_[i]))) print(' --------------------------------------------------------', flush=True) print(' --------------------------------------------------------', flush=True) print(flush=True) self.elist_ = [] self.llist_ = [] self.glist_ = [] if optiter: if self.iprint > 0: cout = 0 print(flush=True) print(' -----* Optimal pulse parameters *-----', flush=True) if shape == 'square': print(' | Amplitudes', flush=True) for i in range(self.pulse.nqubit): print(' Qubit ', i + 1, ' : ', end='', flush=True) cout_ = 0 for j in range(self.pulse.nwindow): if cout_ == 4: print(flush=True) print(' ', end='', flush=True) cout_ = 0 print(' {:>20.16f} '.format(res1.x[cout]), end='', flush=True) cout_ += 1 cout += 1 print(flush=True) print(flush=True) if not self.nstep == len(self.pulse.tseq[0]) + 1: qu = 1 print(' | Time Windows', flush=True) for i in self.pulse.tseq: print(' Qubit ', qu, ' : ', end='', flush=True) qu += 1 cout_ = 0 for j in i: if cout_ == 4: print(flush=True) print(' ', end='', flush=True) cout_ = 0 print(' {:>20.16f} '.format(j), end='', flush=True) cout_ += 1 print(flush=True) print(flush=True) elif shape == 'gaussian': amp__ = [[] for i in range(self.pulse.nqubit)] mean__ = [[] for i in range(self.pulse.nqubit)] sigma__ = [[] for i in range(self.pulse.nqubit)] for i in range(self.pulse.nqubit): for j in range(self.pulse.ngaus): amp__[i].append(res1.x[cout]) cout += 1 mean__[i].append(res1.x[cout]) cout += 1 sigma__[i].append(res1.x[cout]) cout += 1 print(' | Amplitudes', flush=True) for i in range(self.pulse.nqubit): print(' Qubit ', i + 1, ' : ', end='', flush=True) cout_ = 0 for j in range(self.pulse.ngaus): if cout_ == 4: print(flush=True) print(' ', end='', flush=True) cout_ = 0 print(' {:>20.16f} '.format(amp__[i][j]), end='', flush=True) cout_ += 1 print(flush=True) print(flush=True) print(' | Mean', flush=True) for i in range(self.pulse.nqubit): print(' Qubit ', i + 1, ' : ', end='', flush=True) cout_ = 0 for j in range(self.pulse.ngaus): if cout_ == 4: print(flush=True) print(' ', end='', flush=True) cout_ = 0 print(' {:>20.16f} '.format(mean__[i][j]), end='', flush=True) cout_ += 1 print(flush=True) print(flush=True) print(' | Variance', flush=True) for i in range(self.pulse.nqubit): print(' Qubit ', i + 1, ' : ', end='', flush=True) cout_ = 0 for j in range(self.pulse.ngaus): if cout_ == 4: print(flush=True) print(' ', end='', flush=True) cout_ = 0 print(' {:>20.16f} '.format(sigma__[i][j]), end='', flush=True) cout_ += 1 print(flush=True) print(flush=True) qu = 1 print(' | Frequencies', flush=True) for i in self.pulse.freq: print(' Qubit ', qu, ' : ', end='', flush=True) qu += 1 print(' {:>20.16f} '.format(res1.x[cout]), flush=True) cout += 1 print(flush=True) print(' Printing ends ', flush=True) print(' --------------------------------------', flush=True) print(flush=True) if pulse_return: return (self.pulse, self.energy_, self.leak) return (self.energy_, self.leak)
def anatwin(self, list1, pobj, hobj, nstep, normalize): from ctrlq.lib.solve import pulsec from ctrlq.lib.agradc import grad_trotter from ctrlq.lib.agradc import grad_trotter_normalized ini_state = hobj.initial_state tlist = numpy.linspace(0, pobj.duration, nstep) dsham = numpy.diagonal(-1j * hobj.dsham.toarray()) ampcout = [[] for i in range(pobj.nqubit)] for i in range(pobj.nqubit): if pobj.nwindow == 1: ampcout[i].append(twinamp(0.0, pobj.duration, tlist)) continue for j in range(pobj.nwindow - 1): if j == 0: ampcout[i].append(twinamp(0.0, pobj.tseq[i][j], tlist)) else: ampcout[i].append( twinamp(pobj.tseq[i][j - 1], pobj.tseq[i][j], tlist)) ampcout[i].append(twinamp(pobj.tseq[i][j], pobj.duration, tlist)) amp = [[] for j in range(pobj.nqubit)] samp = [[] for j in range(pobj.nqubit)] cout = 0 for i in range(pobj.nqubit): for j in range(pobj.nwindow): if j == 0: amp[i].append(0.0) #amp=0.0 at t=0.0 for k in range(ampcout[i][j]): amp[i].append(list1[cout]) samp[i].append(list1[cout]) cout += 1 self.square_amp = samp pobj.amp = amp for i in range(pobj.nqubit): pobj.freq[i] = list1[cout] cout += 1 sfreq = numpy.array(pobj.freq) / pobj.fscale pobjc = pulsec(amp, pobj.tseq, sfreq, pobj.duration, pobj.nqubit, pobj.nwindow) if normalize: aobj = grad_trotter_normalized(tlist, ini_state, pobjc, numpy.array(hobj.hdrive), dsham, hobj.states, hobj.mham) else: aobj = grad_trotter(tlist, ini_state, pobjc, numpy.array(hobj.hdrive), dsham, hobj.states, hobj.mham) self.square_gamp = aobj.gradient agradient = [] for i in range(pobj.nqubit): cout_ = 0 for j in range(pobj.nwindow): agrad__ = 0.0 if j == 0: #agrad__ += aobj.gradient[i][0] cout_ += 1 for k in range(ampcout[i][j]): agrad__ += aobj.gradient[i][cout_] cout_ += 1 agradient.append(agrad__) for i in range(pobj.nqubit): ng1 = self.numgradfreq_2_(i, aobj.energy, ini_state, pobj, hobj, nstep, normalize=normalize) agradient.append(ng1) self.energy_ = aobj.energy self.leak = 1.0 - aobj.norm self.gradient_ = agradient return (aobj.energy, agradient)