def get_qng_combos(objective, func=stokes_block, initial_values=None, samples=None, backend=None, device=None, noise=None) -> typing.List[typing.Dict]: """ get all the objects needed to evaluate the qng for some objective; return them in a list of dictionaries. Parameters ---------- objective: Objective: the Objective whose qng is sought. func: callable: (Default = stokes_block): the function used to obtain the (blocks of) the qgt. Default uses stokes_block, defined above. initial_values: dict, optional: a dictionary indicating the intial parameters with which to compile all objectives appearing in the qng. samples: int, optional: the number of samples with which to compile all objectives appearing in the qng. Default: none. backend: str, optional: the backend with which to compile all objectives appearing in the qng. default: pick for you. device: optional: the device with which to compile all objectives appearing in the qng. Default: no device use or emulation. noise: str or NoiseModel, optional: the noise model with which to compile all objectives appearing in the qng. Default: no noise. Returns ------- list of dicts: a list of dictionaries, each entry corresponding to the qng for 1 argument of objective, in the order of said objectives. """ combos = [] vars = objective.extract_variables() compiled = compile_multitarget(gate=objective) compiled = compile_trotterized_gate(gate=compiled) compiled = compile_h_power(gate=compiled) compiled = compile_power_gate(gate=compiled) compiled = compile_controlled_phase(gate=compiled) compiled = compile_controlled_rotation(gate=compiled) for i, arg in enumerate(compiled.args): if not isinstance(arg, ExpectationValueImpl): ### this is a variable, no QNG involved mat = QngMatrix([[[1]]]) vec = CallableVector([__grad_inner(arg, arg)]) mapping = {0: {v: __grad_inner(arg, v) for v in vars}} else: ### if the arg is an expectationvalue, we need to build some qngs and mappings! blocks = func(arg, initial_values=initial_values, samples=samples, device=device, backend=backend, noise=noise) mat = QngMatrix(blocks) vec = subvector_procedure(arg, initial_values=initial_values, samples=samples, device=device, backend=backend, noise=noise) mapping = {} self_pars = get_self_pars(arg.U) for j, p in enumerate(self_pars): indict = {} for v in p.extract_variables(): gi = __grad_inner(p, v) if isinstance(gi, Objective): g = compile_objective(gi, variables=initial_values, samples=samples, device=device, backend=backend, noise=noise) else: g = gi indict[v] = g mapping[j] = indict posarg = jax.grad(compiled.transformation, i) p = Objective(compiled.args, transformation=posarg) pos = compile_objective(p, variables=initial_values, samples=samples, device=device, backend=backend, noise=noise) combos.append(qng_dict(arg, mat, vec, mapping, pos)) return combos
def get_qng_combos(objective, initial_values=None, samples=None, backend=None, backend_options=None, noise=None): combos = [] vars = objective.extract_variables() compiled = compile_multitarget(gate=objective) compiled = compile_trotterized_gate(gate=compiled) compiled = compile_h_power(gate=compiled) compiled = compile_power_gate(gate=compiled) compiled = compile_controlled_phase(gate=compiled) compiled = compile_controlled_rotation(gate=compiled) for i, arg in enumerate(compiled.args): if not isinstance(arg, ExpectationValueImpl): ### this is a variable, no QNG involved mat = QngMatrix([[[1]]]) vec = CallableVector([__grad_inner(arg, arg)]) mapping = {0: {v: __grad_inner(arg, v) for v in vars}} else: ### if the arg is an expectationvalue, we need to build some qngs and mappings! blocks = qng_metric_tensor_blocks(arg, initial_values=initial_values, samples=samples, backend=backend, noise=noise, backend_options=backend_options) mat = QngMatrix(blocks) vec = subvector_procedure(arg, initial_values=initial_values, samples=samples, backend=backend, noise=noise, backend_options=backend_options) mapping = {} self_pars = get_self_pars(arg.U) for j, p in enumerate(self_pars): indict = {} for v in p.extract_variables(): gi = __grad_inner(p, v) if isinstance(gi, Objective): g = compile_objective(gi, variables=initial_values, samples=samples, backend=backend, noise=noise, backend_options=backend_options) else: g = gi indict[v] = g mapping[j] = indict posarg = jax.grad(compiled.transformation, argnums=i) p = Objective(compiled.args, transformation=posarg) pos = compile_objective(p, variables=initial_values, samples=samples, backend=backend, noise=noise, backend_options=backend_options) combos.append(qng_dict(arg, mat, vec, mapping, pos)) return combos