def perf_test( model, n_particles, prior, n_exp, heuristic_class, true_model=None, true_prior=None ): """ Runs a trial of using SMC to estimate the parameters of a model, given a number of particles, a prior distribution and an experiment design heuristic. :param qinfer.Model model: Model whose parameters are to be estimated. :param int n_particles: Number of SMC particles to use. :param qinfer.Distribution prior: Prior to use in selecting SMC particles. :param int n_exp: Number of experimental data points to draw from the model. :param qinfer.Heuristic heuristic_class: Constructor function for the experiment design heuristic to be used. :param qinfer.Model true_model: Model to be used in generating experimental data. If ``None``, assumed to be ``model``. :param qinfer.Distribution true_prior: Prior to be used in selecting the true model parameters. If ``None``, assumed to be ``prior``. :rtype np.ndarray: See :ref:`perf_testing_struct` for more details on the type returned by this function. :return: A record array of performance metrics, indexed by the number of experiments performed. """ if true_model is None: true_model = model if true_prior is None: true_prior = prior true_mps = true_prior.sample() performance = np.zeros((n_exp,), dtype=PERFORMANCE_DTYPE) updater = SMCUpdater(model, n_particles, prior) heuristic = heuristic_class(updater) for idx_exp in xrange(n_exp): expparams = heuristic() datum = true_model.simulate_experiment(true_mps, expparams) with timing() as t: updater.update(datum, expparams) delta = updater.est_mean() - true_mps performance[idx_exp]['elapsed_time'] = t.delta_t performance[idx_exp]['loss'] = np.dot(model.Q, delta**2) performance[idx_exp]['resample_count'] = updater.resample_count return performance
def main(): m = SimpleMacroModel() prior = UniformDistribution([[0, 1], [0, 1]]) u = SMCUpdater(m, 1000, prior) modelparams = prior.sample() expparams = np.array([(12.0,)], dtype=m.expparams_dtype) datum = m.simulate_experiment(modelparams, expparams) print datum u.update(datum, expparams) print u.est_mean() print m.call_count
def main(): m = SimpleMacroModel() prior = UniformDistribution([[0, 1], [0, 1]]) u = SMCUpdater(m, 1000, prior) modelparams = prior.sample() expparams = np.array([(12.0, )], dtype=m.expparams_dtype) datum = m.simulate_experiment(modelparams, expparams) print datum u.update(datum, expparams) print u.est_mean() print m.call_count
mps_buf.release() eps_buf.release() dest_buf.release() # Now we concatenate over outcomes. return FiniteOutcomeModel.pr0_to_likelihood_array(outcomes, pr0) ## SCRIPT ###################################################################### if __name__ == "__main__": # NOTE: This is now redundant with the perf_testing module. simple_model = SimplePrecessionModel() for model in [AcceleratedPrecessionModel(), SimplePrecessionModel()]: true = np.random.random(1) updater = SMCUpdater(model, 100000, UniformDistribution([0, 1])) tic = time.time() for idx_exp in range(200): if not (idx_exp % 20): print(idx_exp) expparams = np.array([(9 / 8)**idx_exp]) updater.update(simple_model.simulate_experiment(true, expparams), expparams) print(model, updater.est_mean(), true, time.time() - tic)
#SIMULATE******************************************************* #simulate outcomes- based on the true T1, and the chosen intial value #will be replaced by actual data collection from NMR for Mz values sim_outcome=model.simulate_experiment(true_model,expparams) outcome=sim_outcome #NMR EXPERIMENT************************************************* #USE this instead of simualate when doing experiments in NMR # outcome=np.array([[[float(raw_input('Enter obtained Mz: '))]]]) # dummy=float(raw_input('waiting for Mz')) # Mz_value=LF.lorentzfit(str(idx_trials+2)+'_spectrum.txt') # outcome=np.array([[[Mz_value/abs(Mo_norm)]]]) #Run SMC and update the posterior distribution updater.update(outcome,expparams,check_for_resample=True) #STORE DATA****************************************** data[idx_trials]['est_mean'] = updater.est_mean() data[idx_trials]['sim_outcome'] = outcome data[idx_trials]['expparams'] = expparams data[idx_trials]['covariance'] = updater.est_covariance_mtx() save_exp.writelines(str(expparams)+'\n') save_mean.write(str(updater.est_mean())+'\n') save_out.write(str(outcome)+'\n') save_cov.write(str(updater.est_covariance_mtx())+'\n') # PLOT *******************************************
# SIMULATE******************************************************* # simulate outcomes- based on the true T1, and the chosen intial value # will be replaced by actual data collection from NMR for Mz values sim_outcome = model.simulate_experiment(true_model, expparams) outcome = sim_outcome # NMR EXPERIMENT************************************************* # USE this instead when doing experiments in NMR # outcome=np.array([[[float(raw_input('Enter obtained Mz: '))]]]) # dummy=float(raw_input('waiting for Mz')) # Mz_value=LF.lorentzfit(str(idx_trials+2)+'_spectrum.txt') # outcome=np.array([[[Mz_value/abs(Mo_norm)]]]) # Run SMC and update the posterior distribution updater.update(outcome, expparams) # STORE DATA****************************************** data[idx_trials]['est_mean'] = updater.est_mean() data[idx_trials]['sim_outcome'] = outcome data[idx_trials]['expparams'] = expparams # PLOT ******************************************* # plotting particles and weights particles = updater.particle_locations weights = updater.particle_weights fig = plt.figure() plt.axvline(updater.est_mean(), linestyle='--', c='blue', linewidth=2)
# Copy the buffer back from the GPU and free memory there. cl.enqueue_copy(self._queue, pr0, dest_buf) mps_buf.release() eps_buf.release() dest_buf.release() # Now we concatenate over outcomes. return FiniteOutcomeModel.pr0_to_likelihood_array(outcomes, pr0) ## SCRIPT ###################################################################### if __name__ == "__main__": # NOTE: This is now redundant with the perf_testing module. simple_model = SimplePrecessionModel() for model in [AcceleratedPrecessionModel(), SimplePrecessionModel()]: true = np.random.random(1) updater = SMCUpdater(model, 100000, UniformDistribution([0, 1])) tic = time.time() for idx_exp in range(200): if not (idx_exp % 20): print(idx_exp) expparams = np.array([(9 / 8) ** idx_exp]) updater.update(simple_model.simulate_experiment(true, expparams), expparams) print(model, updater.est_mean(), true, time.time() - tic)
def perf_test(model, n_particles, prior, n_exp, heuristic_class, true_model=None, true_prior=None, true_mps=None, extra_updater_args=None): """ Runs a trial of using SMC to estimate the parameters of a model, given a number of particles, a prior distribution and an experiment design heuristic. :param qinfer.Model model: Model whose parameters are to be estimated. :param int n_particles: Number of SMC particles to use. :param qinfer.Distribution prior: Prior to use in selecting SMC particles. :param int n_exp: Number of experimental data points to draw from the model. :param qinfer.Heuristic heuristic_class: Constructor function for the experiment design heuristic to be used. :param qinfer.Model true_model: Model to be used in generating experimental data. If ``None``, assumed to be ``model``. Note that if the true and estimation models have different numbers of parameters, the loss will be calculated by aligning the respective model vectors "at the right," analogously to the convention used by NumPy broadcasting. :param qinfer.Distribution true_prior: Prior to be used in selecting the true model parameters. If ``None``, assumed to be ``prior``. :param numpy.ndarray true_mps: The true model parameters. If ``None``, it will be sampled from ``true_prior``. Note that as this function runs exactly one trial, only one model parameter vector may be passed. In particular, this requires that ``len(true_mps.shape) == 1``. :param dict extra_updater_args: Extra keyword arguments for the updater, such as resampling and zero-weight policies. :rtype np.ndarray: See :ref:`perf_testing_struct` for more details on the type returned by this function. :return: A record array of performance metrics, indexed by the number of experiments performed. """ if true_model is None: true_model = model if true_prior is None: true_prior = prior if true_mps is None: true_mps = true_prior.sample() if extra_updater_args is None: extra_updater_args = {} n_min_modelparams = min(model.n_modelparams, true_model.n_modelparams) dtype, is_scalar_exp = actual_dtype(model, true_model) performance = np.zeros((n_exp, ), dtype=dtype) updater = SMCUpdater(model, n_particles, prior, **extra_updater_args) heuristic = heuristic_class(updater) for idx_exp in range(n_exp): # Set inside the loop to handle the case where the # true model is time-dependent as well as the estimation model. performance[idx_exp]['true'] = true_mps expparams = heuristic() datum = true_model.simulate_experiment(true_mps, expparams) with timing() as t: updater.update(datum, expparams) # Update the true model. true_mps = true_model.update_timestep(promote_dims_left(true_mps, 2), expparams)[:, :, 0] est_mean = updater.est_mean() delta = np.subtract(*shorten_right(est_mean, true_mps)) loss = np.dot(delta**2, model.Q[-n_min_modelparams:]) performance[idx_exp]['elapsed_time'] = t.delta_t performance[idx_exp]['loss'] = loss performance[idx_exp]['resample_count'] = updater.resample_count performance[idx_exp]['outcome'] = datum performance[idx_exp]['est'] = est_mean if is_scalar_exp: performance[idx_exp]['experiment'] = expparams else: for param_name in [param[0] for param in model.expparams_dtype]: performance[idx_exp][param_name] = expparams[param_name] return performance
def perf_test( model, n_particles, prior, n_exp, heuristic_class, true_model=None, true_prior=None, true_mps=None, extra_updater_args=None ): """ Runs a trial of using SMC to estimate the parameters of a model, given a number of particles, a prior distribution and an experiment design heuristic. :param qinfer.Model model: Model whose parameters are to be estimated. :param int n_particles: Number of SMC particles to use. :param qinfer.Distribution prior: Prior to use in selecting SMC particles. :param int n_exp: Number of experimental data points to draw from the model. :param qinfer.Heuristic heuristic_class: Constructor function for the experiment design heuristic to be used. :param qinfer.Model true_model: Model to be used in generating experimental data. If ``None``, assumed to be ``model``. :param qinfer.Distribution true_prior: Prior to be used in selecting the true model parameters. If ``None``, assumed to be ``prior``. :param np.ndarray true_mps: The true model parameters. If ``None``, it will be sampled from ``true_prior``. Note that the performance record can only handle one outcome and therefore ONLY ONE TRUE MODEL. An error will occur if ``true_mps.shape[0] > 1`` returns ``True``. :param dict extra_updater_args: Extra keyword arguments for the updater, such as resampling and zero-weight policies. :rtype np.ndarray: See :ref:`perf_testing_struct` for more details on the type returned by this function. :return: A record array of performance metrics, indexed by the number of experiments performed. """ if true_model is None: true_model = model if true_prior is None: true_prior = prior if true_mps is None: true_mps = true_prior.sample() if extra_updater_args is None: extra_updater_args = {} dtype, is_scalar_exp = actual_dtype(model) performance = np.zeros((n_exp,), dtype=dtype) updater = SMCUpdater(model, n_particles, prior, **extra_updater_args) heuristic = heuristic_class(updater) performance['true'] = true_mps for idx_exp in xrange(n_exp): expparams = heuristic() datum = true_model.simulate_experiment(true_mps, expparams) with timing() as t: updater.update(datum, expparams) est_mean = updater.est_mean() delta = est_mean - true_mps loss = np.dot(delta**2, model.Q) performance[idx_exp]['elapsed_time'] = t.delta_t performance[idx_exp]['loss'] = loss performance[idx_exp]['resample_count'] = updater.resample_count performance[idx_exp]['outcome'] = datum performance[idx_exp]['est'] = est_mean if is_scalar_exp: performance[idx_exp]['experiment'] = expparams else: for param_name in [param[0] for param in model.expparams_dtype]: performance[idx_exp][param_name] = expparams[param_name] return performance
def perf_test( model, n_particles, prior, n_exp, heuristic_class, true_model=None, true_prior=None, true_mps=None, extra_updater_args=None ): """ Runs a trial of using SMC to estimate the parameters of a model, given a number of particles, a prior distribution and an experiment design heuristic. :param qinfer.Model model: Model whose parameters are to be estimated. :param int n_particles: Number of SMC particles to use. :param qinfer.Distribution prior: Prior to use in selecting SMC particles. :param int n_exp: Number of experimental data points to draw from the model. :param qinfer.Heuristic heuristic_class: Constructor function for the experiment design heuristic to be used. :param qinfer.Model true_model: Model to be used in generating experimental data. If ``None``, assumed to be ``model``. Note that if the true and estimation models have different numbers of parameters, the loss will be calculated by aligning the respective model vectors "at the right," analogously to the convention used by NumPy broadcasting. :param qinfer.Distribution true_prior: Prior to be used in selecting the true model parameters. If ``None``, assumed to be ``prior``. :param numpy.ndarray true_mps: The true model parameters. If ``None``, it will be sampled from ``true_prior``. Note that as this function runs exactly one trial, only one model parameter vector may be passed. In particular, this requires that ``len(true_mps.shape) == 1``. :param dict extra_updater_args: Extra keyword arguments for the updater, such as resampling and zero-weight policies. :rtype np.ndarray: See :ref:`perf_testing_struct` for more details on the type returned by this function. :return: A record array of performance metrics, indexed by the number of experiments performed. """ if true_model is None: true_model = model if true_prior is None: true_prior = prior if true_mps is None: true_mps = true_prior.sample() if extra_updater_args is None: extra_updater_args = {} n_min_modelparams = min(model.n_modelparams, true_model.n_modelparams) dtype, is_scalar_exp = actual_dtype(model, true_model) performance = np.zeros((n_exp,), dtype=dtype) updater = SMCUpdater(model, n_particles, prior, **extra_updater_args) heuristic = heuristic_class(updater) for idx_exp in range(n_exp): # Set inside the loop to handle the case where the # true model is time-dependent as well as the estimation model. performance[idx_exp]['true'] = true_mps expparams = heuristic() datum = true_model.simulate_experiment(true_mps, expparams) with timing() as t: updater.update(datum, expparams) # Update the true model. true_mps = true_model.update_timestep( promote_dims_left(true_mps, 2), expparams )[:, :, 0] est_mean = updater.est_mean() delta = np.subtract(*shorten_right(est_mean, true_mps)) loss = np.dot(delta**2, model.Q[-n_min_modelparams:]) performance[idx_exp]['elapsed_time'] = t.delta_t performance[idx_exp]['loss'] = loss performance[idx_exp]['resample_count'] = updater.resample_count performance[idx_exp]['outcome'] = datum performance[idx_exp]['est'] = est_mean if is_scalar_exp: performance[idx_exp]['experiment'] = expparams else: for param_name in [param[0] for param in model.expparams_dtype]: performance[idx_exp][param_name] = expparams[param_name] return performance
def sim_qubit_fid(n_meas, n_meas_rep, meas_dist, n_trials=100, n_particles=1000, n_rec=15): r"""Calculates the average fidelity of the optimal estimator (approximated by SMC) averaged over Haar random pure states and a random sample of measurement outcomes. The estimator is calculated at a given number of interim times throughout the tomographic process. :param n_meas: The number of copies of the system given in each tomographic run :type n_meas: Integer :param n_meas_rep: The number of measurement outcomes to average the fidelity over for each copy of the system in a tomographic run :type n_meas_rep: Integer :param meas_dist: Object defining the distribution from which to draw measurement directions :type meas_dist: Object possessing `sample(n)` function that returns a numpy.array((2, n)) of unit vectors in :math:`\mathbb{C}^2` :param n_trials: The number of tomographic runs (aka samples from the pure state prior) the fidelity is averaged over :type n_trials: Integer :param n_particles: Number of SMC particles to use :type n_particles: Integer :param n_rec: Number of places to record average fidelity (on a log scale) :type n_rec: Integer :returns: An array with the calculated average fidelities at the specified times for all tomographic runs :return type: numpy.array((n_trials, n_rec)) """ n_qubits = 1 # This function isn't guaranteed to generalize by changing # this value, but it is included here to aid readability and # aid any future generalization efforts dim = 2 * n_qubits # Record data on a logarithmic scale rec_idxs = np.unique(np.round(np.logspace(0, np.log10(n_meas), n_rec))) n_rec = rec_idxs.shape[0] # Allocate result array fidelities = np.empty((n_trials, n_rec)) # Instantiate model and state prior model = HaarTestModel(n_qubits=n_qubits) prior = HaarDistribution(n_qubits=n_qubits) # Sample all the measurement directions used at once (since some samplers # might be more efficient doing things this way) raw_meas_dirs = meas_dist.sample(n_trials * n_meas) # Reshape the measurement directions to be a n_trials x n_meas array of unit # vectors in C^2 meas_dirs = np.reshape(raw_meas_dirs.T, (n_trials, n_meas, 2)) for trial_idx in xrange(n_trials): # Pick a random true state and instantiate the Bayes updater true_state = prior.sample() true_vec = model.param2vec(true_state) updater = SMCUpdater(model, n_particles, prior, resampler=LiuWestResampler(a=0.95, h=None)) rec_idx = 0 for meas_idx in xrange(n_meas): meas_dir = meas_dirs[trial_idx, meas_idx] # Set the experimental parameters for the measurement expparams = np.array([(meas_dir, n_meas_rep)], dtype=model.expparams_dtype) # Simulate data and update data = model.simulate_experiment(true_state, expparams) updater.update(data, expparams) if meas_idx + 1 in rec_idxs: # Generate the estimated state -> average then maximal # eigenvector weights = updater.particle_weights locs = updater.particle_locations avg_state = 1j * np.zeros([dim, dim]) for idx_locs in xrange(n_particles): psi = model.param2vec(locs[idx_locs][np.newaxis]) avg_state += weights[idx_locs] * np.outer(psi, psi.conj()) eigs = la.eig(avg_state) max_eig = eigs[1][:, np.argmax(eigs[0])] fidelities[trial_idx, rec_idx] = model.fidelity(true_vec, max_eig) rec_idx += 1 # Give progress updates print(100 * ((trial_idx + 1) / n_trials)) return fidelities
def fid_smc(n_meas, K, n_qubits=1, n_trials=100, n_particles=1000, n_rec=15): """ Evaluates the average fidelity incurred by using sequential Monte Carlo (SMC) to estimate pure states. :param n_meas: The number of copies of the system given in each tomographic run :type n_meas: Integer :param K: Number of single-shot measurements :type K: Integer :param n_trials: Number of times to run the SMC estimation procedure. :type n_trials: Integer :param n_particles: Number of SMC particles to use. :type n_particles: Integer :param n_rec: Number of place to record data (on a log scale) :type n_rec: Integer :returns: Dictionary of various fidelities and timings :return type: Dictionary """ dim = int(2 ** n_qubits) # Record data on a logarithmic scale rec_idx = np.unique(np.round(np.logspace(0, np.log10(n_meas), n_rec))) n_rec = rec_idx.shape[0] # Allocate arrays to hold results. fidelity_mub = np.empty((n_trials, n_rec)) fidelity_opt = np.empty((n_trials, n_rec)) fidelity_WM = np.empty((n_trials, n_rec)) fidelity_DST = np.empty((n_trials, n_rec)) # Instantiate models and distributions model = HaarTestModel(n_qubits=n_qubits) prior = HaarDistribution(n_qubits=n_qubits) measMUB = MUBDistribution() measWM = WeakMeasDistribution(eps=0.05) measDST = DSTDistribution(0.1) timing = np.empty((n_trials,)) # Make and show a progress bar. """ prog = ProgressBar() prog.show() """ for idx_trial in xrange(n_trials): # Pick a random true state and instantiate the Bayes updater true_state = prior.sample() true_vec = model.param2vec(true_state) updater_opt = SMCUpdater(model, n_particles, prior, resampler=LiuWestResampler(a=0.95, h=None)) updater_mub = SMCUpdater(model, n_particles, prior, resampler=LiuWestResampler(a=0.95, h=None)) updater_WM = SMCUpdater(model, n_particles, prior, resampler=LiuWestResampler(a=0.95, h=None)) updater_DST = SMCUpdater(model, n_particles, prior, resampler=LiuWestResampler(a=0.95, h=None)) # Record the start time. tic = time.time() idx_rec = 0 for idx_meas in xrange(n_meas): # Choose a random measurement direction foo = prior.sample() meas_opt = model.param2vec(foo) meas_mub = measMUB.sample() meas_WM = measWM.sample()[:, 0] meas_DST = measDST.sample()[:, 0] expparams_opt = np.array([(meas_opt, K)], dtype=model.expparams_dtype) expparams_mub = np.array([(meas_mub, K)], dtype=model.expparams_dtype) expparams_WM = np.array([(meas_WM, K)], dtype=model.expparams_dtype) expparams_DST = np.array([(meas_DST, K)], dtype=model.expparams_dtype) # Simulate data and update data_opt = model.simulate_experiment(true_state, expparams_opt) updater_opt.update(data_opt, expparams_opt) data_mub = model.simulate_experiment(true_state, expparams_mub) updater_mub.update(data_mub, expparams_mub) data_WM = model.simulate_experiment(true_state, expparams_WM) updater_WM.update(data_WM, expparams_WM) data_DST = model.simulate_experiment(true_state, expparams_DST) updater_DST.update(data_DST, expparams_DST) if idx_meas + 1 in rec_idx: # Generate the estimated state -> average then maximal eigenvector weights = updater_opt.particle_weights locs = updater_opt.particle_locations ave_state = 1j * np.zeros([dim, dim]) for idx_locs in xrange(n_particles): psi = model.param2vec(locs[idx_locs][np.newaxis]) ave_state += weights[idx_locs] * np.outer(psi, psi.conj()) eigs = la.eig(ave_state) max_eig = eigs[1][:, np.argmax(eigs[0])] fidelity_opt[idx_trial, idx_rec] = model.fidelity(true_vec, max_eig) # MUB weights = updater_mub.particle_weights locs = updater_mub.particle_locations ave_state = 1j * np.zeros([dim, dim]) for idx_locs in xrange(n_particles): psi = model.param2vec(locs[idx_locs][np.newaxis]) ave_state += weights[idx_locs] * np.outer(psi, psi.conj()) eigs = la.eig(ave_state) max_eig = eigs[1][:, np.argmax(eigs[0])] fidelity_mub[idx_trial, idx_rec] = model.fidelity(true_vec, max_eig) # Weak Measurement weights = updater_WM.particle_weights locs = updater_WM.particle_locations ave_state = 1j * np.zeros([dim, dim]) for idx_locs in xrange(n_particles): psi = model.param2vec(locs[idx_locs][np.newaxis]) ave_state += weights[idx_locs] * np.outer(psi, psi.conj()) eigs = la.eig(ave_state) max_eig = eigs[1][:, np.argmax(eigs[0])] fidelity_WM[idx_trial, idx_rec] = model.fidelity(true_vec, max_eig) # DST Measurement weights = updater_DST.particle_weights locs = updater_DST.particle_locations ave_state = 1j * np.zeros([dim, dim]) for idx_locs in xrange(n_particles): psi = model.param2vec(locs[idx_locs][np.newaxis]) ave_state += weights[idx_locs] * np.outer(psi, psi.conj()) eigs = la.eig(ave_state) max_eig = eigs[1][:, np.argmax(eigs[0])] fidelity_DST[idx_trial, idx_rec] = model.fidelity(true_vec, max_eig) idx_rec += 1 # Record how long it took us. timing[idx_trial] = time.time() - tic print(100 * ((idx_trial + 1) / n_trials)) # prog.value = 100 * ((idx_trial + 1) / n_trials) return { "fidelity_opt": fidelity_opt, "fidelity_mub": fidelity_mub, "fidelity_WM": fidelity_WM, "fidelity_DST": fidelity_DST, "timing": timing, }