Ejemplo n.º 1
0
def optimize_circuit(params):
    """Minimize the variational circuit and return its minimum value.

    The code you write for this challenge should be completely contained within this function
    between the # QHACK # comment markers. You should create a device and convert the
    variational_circuit function into an executable QNode. Next, you should minimize the variational
    circuit using gradient-based optimization to update the input params. Return the optimized value
    of the QNode as a single floating-point number.

    Args:
        params (np.ndarray): Input parameters to be optimized, of dimension 30

    Returns:
        float: the value of the optimized QNode
    """

    optimal_value = 0.0

    # QHACK #

    # Initialize the device
    dev = qml.device("default.qubit", wires=2)

    # Instantiate the QNode
    circuit = qml.QNode(variational_circuit, dev)

    # Minimize the circuit
    #Create the optimizer

    opt = qml.GradientDescentOptimizer(stepsize=0.4)

    def cost(x):
        return circuit(x)

    # initialise the optimizer
    opt = qml.GradientDescentOptimizer(stepsize=0.4)

    # set the number of steps
    steps = 100
    # set the initial parameter values

    for i in range(steps):
        # update the circuit parameters
        params = opt.step(cost, params)

    optimal_value = cost(params)

    # QHACK #

    # Return the value of the minimized QNode
    return optimal_value
Ejemplo n.º 2
0
    def test_complex(self):
        random.seed(1234)
        pnp.random.seed(1234)
        mp = create_freezable_circuit(3, layer_size=2)
        circuit = qml.QNode(variational_circuit,
                            device(mp.mask(Axis.WIRES).size))
        optimizer = qml.GradientDescentOptimizer()

        def cost_fn(params, masked_circuit=None):
            return cost(
                params,
                circuit,
                masked_circuit,
            )

        mp.perturb(axis=Axis.LAYERS, amount=2, mode=Mode.SET, mask=FreezeMask)
        mp.perturb(axis=Axis.WIRES, amount=2, mode=Mode.SET, mask=FreezeMask)

        last_changeable = pnp.sum(mp.parameters[~mp._accumulated_mask()])
        frozen = pnp.sum(mp.parameters[mp._accumulated_mask()])
        for _ in range(10):
            params = optimizer.step(cost_fn,
                                    mp.differentiable_parameters,
                                    masked_circuit=mp)
            mp.differentiable_parameters = params
            current_changeable = pnp.sum(
                mp.parameters[~mp._accumulated_mask()])
            assert last_changeable - current_changeable != 0
            assert frozen - pnp.sum(mp.parameters[mp._accumulated_mask()]) == 0
            last_changeable = current_changeable
Ejemplo n.º 3
0
def benchmark_casual(dev_name, s3=None):
    """A simple optimization workflow

    Args:
        dev_name (str): Either "local", "sv1", "tn1", or "ionq"
        s3 (tuple):  A tuple of (bucket, prefix) to specify the s3 storage location

    """
    n_steps = 2
    n_wires = 4
    n_layers = 6
    interface = "autograd"
    diff_method = "best"

    if dev_name == "local":
        device = qml.device("braket.local.qubit", wires=n_wires, shots=None)
    elif dev_name == "sv1":
        device = qml.device(
            "braket.aws.qubit",
            device_arn="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
            s3_destination_folder=s3,
            wires=n_wires,
            shots=None,
        )
    elif dev_name == "tn1":
        shots = 1000
        device = qml.device(
            "braket.aws.qubit",
            device_arn="arn:aws:braket:::device/quantum-simulator/amazon/tn1",
            s3_destination_folder=s3,
            wires=n_wires,
            shots=shots,
        )
    elif dev_name == "ionq":
        shots = 100
        device = qml.device(
            "braket.aws.qubit",
            device_arn="arn:aws:braket:::device/qpu/ionq/ionQdevice",
            s3_destination_folder=s3,
            wires=n_wires,
            shots=shots,
        )
    else:
        raise ValueError("dev_name not 'local', 'sv1', 'ionq', or 'tn1'")

    @qml.qnode(device, interface=interface, diff_method=diff_method)
    def circuit(params_):
        qml.templates.BasicEntanglerLayers(params_, wires=range(n_wires))
        return qml.expval(qml.PauliZ(0))

    rng = pnp.random.default_rng(seed=42)
    params = pnp.array(rng.standard_normal((n_layers, n_wires)),
                       requires_grad=True)

    opt = qml.GradientDescentOptimizer(stepsize=0.1)

    print("starting optimization")
    for i in range(n_steps):
        params = opt.step(circuit, params)
        print("step: ", i)
Ejemplo n.º 4
0
def optimize_circuit(params):
    """Minimize the variational circuit and return its minimum value.

    The code you write for this challenge should be completely contained within this function
    between the # QHACK # comment markers. You should create a device and convert the
    variational_circuit function into an executable QNode. Next, you should minimize the variational
    circuit using gradient-based optimization to update the input params. Return the optimized value
    of the QNode as a single floating-point number.

    Args:
        params (np.ndarray): Input parameters to be optimized, of dimension 30

    Returns:
        float: the value of the optimized QNode
    """

    optimal_value = 0.0

    # QHACK #

    # Initialize the device
    dev = qml.device('default.qubit', wires=WIRES)

    # Instantiate the QNode
    circuit = qml.QNode(variational_circuit, dev)

    #Get Gradient
    def parameter_shift_term(qnode, params, pos):
        shifted = params.copy()

        shifted[pos] += np.pi / 2
        forward = qnode(shifted)

        shifted[pos] -= np.pi
        backward = qnode(shifted)

        return 0.5 * (forward - backward)

    def get_grads(qnode, params):

        gradients = np.zeros_like(params)

        for i in range(30):
            gradients[i] = parameter_shift_term(qnode, params, i)

        return gradients

    # Minimize the circuit

    steps = 1200
    for i in range(steps):
        params = qml.GradientDescentOptimizer(stepsize=0.02).step(
            circuit, params)

    optimal_value = circuit(params)
    # QHACK #

    # Return the value of the minimized QNode
    return optimal_value
Ejemplo n.º 5
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    # Initialize parameters
    num_qubits = len(H.wires)
    num_param_sets = (2**num_qubits) - 1
    params = np.random.uniform(low=-np.pi / 2,
                               high=np.pi / 2,
                               size=(num_param_sets, 3))

    energy = 0

    # QHACK #

    # Create a quantum device, set up a cost funtion and optimizer, and run the VQE.
    # (We recommend ~500 iterations to ensure convergence for this problem,
    # or you can design your own convergence criteria)

    # Device Creation
    dev = qml.device('default.qubit', wires=H.wires)

    # Cost Function. Using ExpvalCost useful to use with hamiltonians
    cost_fn = qml.ExpvalCost(variational_ansatz, H, dev)

    # Optimizer
    opt = qml.GradientDescentOptimizer(stepsize=0.1)

    # Optimization loop

    max_iterations = 800
    conv_tol = 1e-05

    for n in range(max_iterations):
        params, prev_energy = opt.step_and_cost(cost_fn, params)
        energy = cost_fn(params)
        conv = np.abs(energy - prev_energy)

        # if n % 20 == 0:
        #     print('Iteration = {:},  Energy = {:.8f} Ha'.format(n, energy))

        if conv <= conv_tol:
            break

    #

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 6
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    energy = 0

    # QHACK #

    # Initialize the quantum device
    num_qubits = len(H.wires)
    dev = qml.device('default.qubit', wires=num_qubits)
    #print(H)

    # Randomly choose initial parameters (how many do you need?)
    params = np.random.uniform(low=-np.pi / 2, high=np.pi / 2,
                               size=(num_qubits - 1))

    # Set up a cost function
    cost_fn = qml.ExpvalCost(variational_ansatz, H, dev)

    # Set up an optimizer
    opt = qml.GradientDescentOptimizer(stepsize=0.01)

    # Run the VQE by iterating over many steps of the optimizer
    max_iterations = 500
    conv_tol = 1e-06

    for n in range(max_iterations):
        params, prev_energy = opt.step_and_cost(cost_fn, params)
        energy = cost_fn(params)
        conv = np.abs(energy - prev_energy)

        # # DEBUG PRINT
        # if n % 20 == 0:
        #     print('Iteration = {:},  Energy = {:.8f} Ha'.format(n, energy))
        #     print(params)

        if conv <= conv_tol:
            break

    # @qml.qnode(dev)
    # def circuit(params):
    #     variational_ansatz(params, H.wires)
    #     return qml.probs(H.wires)
    # print(circuit(params))

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 7
0
def GDO(steps, cost):
    print(f'doing measurement for {steps} times')
    params = np.array([0.0000001, 0.0000001])
    cost(params)
    opt = qml.GradientDescentOptimizer(stepsize=0.5)
    for i in range(steps):
        params = opt.step(cost, params)
        #print('Cost after step {:5d}: {: .7f}'.format(i+1, cost(params)))
    #print('Optimized rotation angle: {}'.format(params),'\n')
    print('probability of [00,01,10,11] is :')
    print(circuit(params), '\n')
Ejemplo n.º 8
0
def benchmark_qchem(dev_name, s3=None):
    """A basic qchem workflow

    Args:
        dev_name (str): Either "local", "sv1", "tn1", or "ionq"
        s3 (tuple):  A tuple of (bucket, prefix) to specify the s3 storage location
    """
    n_wires = 4

    if dev_name == "local":
        device = qml.device("braket.local.qubit", wires=n_wires, shots=None)
    elif dev_name == "sv1":
        device = qml.device(
            "braket.aws.qubit",
            device_arn="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
            s3_destination_folder=s3,
            wires=n_wires,
            shots=None,
        )
    elif dev_name == "tn1":
        shots = 1000
        device = qml.device(
            "braket.aws.qubit",
            device_arn="arn:aws:braket:::device/quantum-simulator/amazon/tn1",
            s3_destination_folder=s3,
            wires=n_wires,
            shots=shots,
        )
    elif dev_name == "ionq":
        shots = 100
        device = qml.device(
            "braket.aws.qubit",
            device_arn="arn:aws:braket:::device/qpu/ionq/ionQdevice",
            s3_destination_folder=s3,
            wires=n_wires,
            shots=shots,
        )
    else:
        raise ValueError("dev_name not 'local', 'sv1','tn1', or 'ionq'")

    def circuit(params, wires):
        qml.PauliX(0)
        qml.PauliX(1)
        qml.DoubleExcitation(params[0], wires=[0, 1, 2, 3])
        qml.SingleExcitation(params[1], wires=[0, 2])
        qml.SingleExcitation(params[2], wires=[1, 3])

    params = [0.0] * 3
    cost_fn = qml.ExpvalCost(circuit, ham_h2, device, optimize=True)
    opt = qml.GradientDescentOptimizer(stepsize=0.5)

    for _ in range(1):
        params, energy = opt.step_and_cost(cost_fn, params)
Ejemplo n.º 9
0
def optimize_circuit(params):
    """Minimize the variational circuit and return its minimum value.

    The code you write for this challenge should be completely contained within this function
    between the # QHACK # comment markers. You should create a device and convert the
    variational_circuit function into an executable QNode. Next, you should minimize the variational
    circuit using gradient-based optimization to update the input params. Return the optimized value
    of the QNode as a single floating-point number.

    Args:
        params (np.ndarray): Input parameters to be optimized, of dimension 30

    Returns:
        float: the value of the optimized QNode
    """

    optimal_value = 0.0

    # QHACK #

    # Initialize the device
    # dev = ...
    dev = qml.device("default.qubit", wires=WIRES)

    # Instantiate the QNode
    # circuit = qml.QNode(variational_circuit, dev)
    circuit = qml.QNode(variational_circuit, dev)
    # Minimize the circuit
    steps = 200
    gd_cost = []
    opt = qml.GradientDescentOptimizer(0.1)

    theta = params.copy()
    for i in range(steps):
        theta = opt.step(circuit, theta)
        gd_cost.append(circuit(theta))

    #print(theta)
    #print(gd_cost[-1])
    #optimal_value=np.array(optimal_value)

    #qnp_cost=[]
    #opt = qml.QNGOptimizer(0.01)
    #theta=params.copy()
    #for _ in range(steps):
    #    theta=opt.step(circuit,theta)
    #    qnp_cost.append(circuit(theta))
    optimal_value = circuit(theta)
    # QHACK #
    # Return the value of the minimized QNode
    return optimal_value
Ejemplo n.º 10
0
def optimize_circuit(params):
    """Minimize the variational circuit and return its minimum value.

    The code you write for this challenge should be completely contained within this function
    between the # QHACK # comment markers. You should create a device and convert the
    variational_circuit function into an executable QNode. Next, you should minimize the variational
    circuit using gradient-based optimization to update the input params. Return the optimized value
    of the QNode as a single floating-point number.

    Args:
        params (np.ndarray): Input parameters to be optimized, of dimension 30

    Returns:
        float: the value of the optimized QNode
    """

    optimal_value = 0.0

    # QHACK #

    # Initialize the device
    # dev = ...
    dev = qml.device('default.qubit', wires=WIRES)

    # Instantiate the QNode
    # circuit = qml.QNode(variational_circuit, dev)
    circuit = qml.QNode(variational_circuit, dev)

    # Minimize the circuit
    opt = qml.GradientDescentOptimizer(stepsize=0.4)

    steps = 100

    #init_params = np.array([0.011 for i in range(30)])
    #params = init_params

    def cost(params):
        return (circuit(params))

    for i in range(steps):

        params = opt.step(cost, params)

        #if (i + 1) % 5 == 0:
        #    print("Cost after step {:5d}: {: .7f}".format(i + 1, cost(params)))

    # QHACK #

    # Return the value of the minimized QNode
    optimal_value = cost(params)
    return optimal_value
Ejemplo n.º 11
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    # Initialize parameters
    num_qubits = len(H.wires)
    num_param_sets = (2**num_qubits) - 1
    np.random.seed(10)
    params = np.random.uniform(low=-np.pi / 2,
                               high=np.pi / 2,
                               size=(num_param_sets, 3))

    energy = 0

    # QHACK #
    dev0 = qml.device('default.qubit', wires=num_qubits)

    cost_fn = qml.ExpvalCost(variational_ansatz, H, dev0, optimize=True)
    opt = qml.GradientDescentOptimizer(stepsize=0.1)
    #np.random.seed(0)
    max_iterations = 550
    #conv_tol = 1e-06

    n = 0
    #for n in range(max_iterations):
    while True:
        params = opt.step(cost_fn, params)
        previous = float(energy)
        energy = cost_fn(params)
        if round(float(energy), 8) == round(previous, 8) or n == 500:
            break
        n += 1
        #conv = np.abs(energy - prev_energy)

    # Create a quantum device, set up a cost funtion and optimizer, and run the VQE.
    # (We recommend ~500 iterations to ensure convergence for this problem,
    # or you can design your own convergence criteria)

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 12
0
    def GDOPT():
        for x_idx, shotnum in enumerate(SHOTRANGE):
            circuit = initialize(shotnum)
            print(f"round {x_idx} of {DENSITY} with {shotnum} shots")

            opt = qml.GradientDescentOptimizer(0.01)
            print("Doing the gradient descent")
            thetagd = init_params
            for y_idx in range(STEPS):
                thetagd = opt.step(circuit, thetagd)
                GD_COST[x_idx, y_idx] = circuit(thetagd)
        print("finally save GD cost file")
        np.save("./datafiles/gdshotcosttoy.npy", GD_COST)
        return  # exit for GC
def optimize_circuit(params):
    """Minimize the variational circuit and return its minimum value.

    The code you write for this challenge should be completely contained within this function
    between the # QHACK # comment markers. You should create a device and convert the
    variational_circuit function into an executable QNode. Next, you should minimize the variational
    circuit using gradient-based optimization to update the input params. Return the optimized value
    of the QNode as a single floating-point number.

    Args:
        params (np.ndarray): Input parameters to be optimized, of dimension 30

    Returns:
        float: the value of the optimized QNode
    """

    optimal_value = 0.0

    # QHACK #

    # Initialize the device
    dev = qml.device("default.qubit", wires=WIRES)

    # Instantiate the QNode
    circuit = qml.QNode(variational_circuit, dev)

    # Minimize the circuit
    #optimizer
    opt = qml.GradientDescentOptimizer(stepsize=0.3)

    #training parameters
    max_iterations = 500
    conv_tol = 1e-12

    for n in range(max_iterations):
        params, prev_energy = opt.step_and_cost(circuit, params)
        energy = circuit(params)
        conv = np.abs(energy - prev_energy)

        if n % 50 == 0:
            print('Iteration = {:},  Energy = {:.8f} Ha'.format(n, energy))

        if conv <= conv_tol:
            break
    optimal_value = energy
    # QHACK #

    # Return the value of the minimized QNode
    return optimal_value
Ejemplo n.º 14
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    energy = 0

    # QHACK #
    num_qubits = len(H.wires)

    # Initialize the quantum device
    dev = qml.device("default.qubit", wires=num_qubits)

    # Randomly choose initial parameters (how many do you need?)
    params = np.random.uniform(0, np.pi, size=(num_qubits-1))

    # Set up a cost function
    cost_fn = qml.ExpvalCost(variational_ansatz, H, dev)

    # Set up an optimizer
    opt = qml.GradientDescentOptimizer(0.02)

    # Run the VQE by iterating over many steps of the optimizer
    max_iterations = 500
    conv_tol = 1e-09

    energies = []

    for n in range(max_iterations):
        params, prev_energy = opt.step_and_cost(cost_fn, params)
        energies.append(cost_fn(params))
        conv = np.abs(energies[-1] - prev_energy)

        if conv <= conv_tol:
            break

    energy = energies[-1]

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 15
0
def optimize_circuit(params):
    """Minimize the variational circuit and return its minimum value.

    The code you write for this challenge should be completely contained within this function
    between the # QHACK # comment markers. You should create a device and convert the
    variational_circuit function into an executable QNode. Next, you should minimize the variational
    circuit using gradient-based optimization to update the input params. Return the optimized value
    of the QNode as a single floating-point number.

    Args:
        params (np.ndarray): Input parameters to be optimized, of dimension 30

    Returns:
        float: the value of the optimized QNode
    """

    optimal_value = 0.0

    # QHACK #

    # Initialize the device
    dev = qml.device("default.qubit", wires=WIRES)

    # Instantiate the QNode

    circuit = qml.QNode(variational_circuit, dev)
    # Minimize the circuit

    print('circuit...', circuit(params))

    print('hamiltonian..', hamiltonian)

    # def cost(var):
    #     return 1-circuit(var)
    steps = 100
    opt = qml.GradientDescentOptimizer(0.25)
    qng_cost = []
    theta = params
    print(params)
    for _ in range(steps):
        theta = opt.step(circuit, theta)

        # qng_cost.append(circuit(theta))

    print(circuit(theta))
    # QHACK #

    # Return the value of the minimized QNode
    return optimal_value
Ejemplo n.º 16
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    energy = 0

    # QHACK #

    num_qubits = len(H.wires)
    num_params = num_qubits

    # Initialize the quantum device
    dev = qml.device('default.qubit', wires=num_qubits)

    # Randomly choose initial parameters (how many do you need?)
    alphas = np.random.uniform(low=-1, high=1, size=(num_params,))
    params = np.zeros(num_qubits-1)

    params[0] = 2. * np.arccos(alphas[0])
    prod_sins = np.sin(params[0]/2)

    for i in range(1,num_qubits-1):
        params[i] = 2 * np.arccos(alphas[i] * (-1)**(i+1) / prod_sins)
        prod_sins *= np.sin(params[i] / 2)

    cost = qml.ExpvalCost(variational_ansatz, H, dev)

    steps = 500

    opt = qml.GradientDescentOptimizer(stepsize=0.02)

    for i in range(steps):
        params = opt.step(cost, params)

    energy = cost(params)

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 17
0
def benchmark_vqe(hyperparams={}):
    """
    Performs VQE optimizations.

    Args:
            hyperparams (dict): hyperparameters to configure this benchmark

                    * 'ham': Molecular Hamiltonian represented as a PennyLane Hamiltonian class

                    * 'ansatz': VQE ansatz

                    * 'params': Numpy array of trainable parameters that is fed into the ansatz.

                    * 'n_steps': Number of VQE steps

                    * 'device': Device on which the circuit is run, or valid device name

                    * 'interface': Name of the interface to use

                    * 'diff_method': Name of differentiation method

                    * 'optimize': argument for grouping the observables composing the Hamiltonian
    """

    ham, ansatz, params, n_steps, device, interface, diff_method, grouping = _vqe_defaults(
        hyperparams)

    if version.parse(qml.__version__) > version.parse("0.17"):
        if grouping:
            ham.compute_grouping()

        @qml.qnode(device)
        def cost_fn(weights):
            ansatz(weights, wires=device.wires)
            return qml.expval(ham)

    else:
        cost_fn = qml.ExpvalCost(ansatz,
                                 ham,
                                 device,
                                 interface=interface,
                                 diff_method=diff_method,
                                 optimize=grouping)

    opt = qml.GradientDescentOptimizer(stepsize=0.4)
    for _ in range(n_steps):
        params, energy = opt.step_and_cost(cost_fn, params)
Ejemplo n.º 18
0
def optimize():
    # initialise the optimizer
    opt = qml.GradientDescentOptimizer(stepsize=0.4)

    # set the number of steps
    steps = 100
    # set the initial parameter values
    params = np.array([0.01, 0.01])

    for i in range(steps):
        # update the circuit parameters
        params = opt.step(cost, params)

        if (i + 1) % 5 == 0:
            print('Cost after step {:5d}: {: .7f}'.format(i + 1, cost(params)))

    print('Optimized rotation angles: {}'.format(params))
def train():
    # initialise the optimizer
    opt = qml.GradientDescentOptimizer(stepsize=0.4)

    # set the number of steps
    steps = 100
    # set the initial parameter values
    params = init_params

    for i in range(steps):
        # update the circuit parameters
        params = opt.step(cost, params)

        if (i + 1) % 5 == 0:
            print("Cost after step {:5d}: {: .7f}".format(i + 1, cost(params)))

    print("Optimized rotation angles: {}".format(params))
Ejemplo n.º 20
0
def optimize(init_params):
	opt = qml.GradientDescentOptimizer(stepsize=0.1)

	# set the number of steps
	steps = 20
	# set the initial parameter values
	params = init_params

	for i in range(steps):
	    # update the circuit parameters
	    params = opt.step(cost, params)

	    print('Cost after step {:5d}: {:8f}'.format(i+1, cost(params)) )

	print('Optimized mag_alpha:{:8f}'.format(params[0]))
	print('Optimized phase_alpha:{:8f}'.format(params[1]))
	print('Optimized phi:{:8f}'.format(params[2]))
Ejemplo n.º 21
0
def optimize_graddesc(init_params):
    opt = qml.GradientDescentOptimizer(stepsize=0.4)

    steps = 100
    params = init_params
    var = []
    var.append(params)

    for i in range(steps):
        # update the circuit parameters
        params = opt.step(cost, params)
        var.append(params)

        if (i + 1) % 5 == 0:
            print('Cost after step {:5d}: {: .7f}'.format(i + 1, cost(params)))

    print('Optimized rotation angles: {}, {}'.format(params, cost(params)))
    return var
Ejemplo n.º 22
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    energy = 0

    # QHACK #

    # Initialize the quantum device
    num_qubits = len(H.wires)
    dev = qml.device("default.qubit", wires=num_qubits)

    # Randomly choose initial parameters (how many do you need?)
    params = np.random.uniform(low=-np.pi / 2,
                               high=np.pi / 2,
                               size=(num_qubits - 1))

    # Set up a cost function
    cost = qml.ExpvalCost(variational_ansatz, H, dev)

    # Set up an optimizer
    opt = qml.GradientDescentOptimizer(0.1)

    # Run the VQE by iterating over many steps of the optimizer
    for i in range(400):
        #if i % 10: print(f"step {i}, cost {cost(params)}")
        params = opt.step(cost, params)

    energy = cost(params)

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 23
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    energy = 0

    # QHACK #
    num_qubits = len(H.wires)

    # Initialize the quantum device
    dev = qml.device('default.qubit', wires=num_qubits)

    # Randomly choose initial parameters (how many do you need?)
    params = np.random.normal(size=num_qubits - 1)

    # Set up a cost function
    cost_fn = qml.ExpvalCost(variational_ansatz, H, dev)

    # Set up an optimizer
    opt = qml.GradientDescentOptimizer()

    # Run the VQE by iterating over many steps of the optimizer

    max_iterations = 500
    for n in range(max_iterations):
        params = opt.step(cost_fn, params)
        energy = cost_fn(params)
        # if n % 20 == 0:
        # print('Iteration = {:},  Energy = {:.8f} Ha, Params = {:}'.format(n, energy, params))

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 24
0
def run_vqe(H):
    """Runs the variational quantum eigensolver on the problem Hamiltonian using the
    variational ansatz specified above.

    Fill in the missing parts between the # QHACK # markers below to run the VQE.

    Args:
        H (qml.Hamiltonian): The input Hamiltonian

    Returns:
        The ground state energy of the Hamiltonian.
    """
    # Initialize parameters
    num_qubits = len(H.wires)
    num_param_sets = (2 ** num_qubits) - 1
    params = np.random.uniform(low=-np.pi / 2, high=np.pi / 2, size=(num_param_sets, 3))

    energy = 0

    # QHACK #

    # Create a quantum device, set up a cost funtion and optimizer, and run the VQE.
    # (We recommend ~500 iterations to ensure convergence for this problem,
    # or you can design your own convergence criteria)
    dev = qml.device("default.qubit", wires=num_qubits)

    cost = qml.ExpvalCost(variational_ansatz, H, dev)

    opt = qml.GradientDescentOptimizer(0.1)
    #opt = qml.AdamOptimizer()

    for i in range(400):
        #if i % 10: print(f"step {i}, cost {cost(params)}")
        params = opt.step(cost, params)

    energy = cost(params)

    # QHACK #

    # Return the ground state energy
    return energy
Ejemplo n.º 25
0
# As explained above, we express it in terms of expectation values through Bayes' theorem.


def cost(weights):
    """Cost function which tends to zero when A |x> tends to |b>."""

    p_global_ground = global_ground(weights)
    p_ancilla_ground = ancilla_ground(weights)
    p_cond = p_global_ground / p_ancilla_ground

    return 1 - p_cond


##############################################################################
# To minimize the cost function we use the gradient-descent optimizer.
opt = qml.GradientDescentOptimizer(eta)

##############################################################################
# We initialize the variational weights with random parameters (with a fixed seed).

np.random.seed(rng_seed)
w = q_delta * np.random.randn(n_qubits)

##############################################################################
# We are ready to perform the optimization loop.

cost_history = []
for it in range(steps):
    w = opt.step(cost, w)
    _cost = cost(w)
    print("Step {:3d}       Cost = {:9.7f}".format(it, _cost))
Ejemplo n.º 26
0

##############################################################################
# Now, we create three QNodes, each corresponding to a device above,
# and optimize them using gradient descent via the parameter-shift rule.

qnode_analytic = qml.QNode(circuit, dev_analytic)
qnode_stochastic = qml.QNode(circuit, dev_stochastic)

init_params = strong_ent_layers_uniform(num_layers, num_wires)

# Optimizing using exact gradient descent

cost_GD = []
params_GD = init_params
opt = qml.GradientDescentOptimizer(eta)

for _ in range(steps):
    cost_GD.append(qnode_analytic(params_GD))
    params_GD = opt.step(qnode_analytic, params_GD)

# Optimizing using stochastic gradient descent with shots=1

dev_stochastic.shots = 1
cost_SGD1 = []
params_SGD1 = init_params
opt = qml.GradientDescentOptimizer(eta)

for _ in range(steps):
    cost_SGD1.append(qnode_stochastic(params_SGD1))
    params_SGD1 = opt.step(qnode_stochastic, params_SGD1)
Ejemplo n.º 27
0
Archivo: main.py Proyecto: kant/DL-PoC

def square_loss(X, Y):
    loss = 0
    for x, y in zip(X, Y):
        loss = loss + (x - y)**2
    return loss / len(X)


def cost(theta, p):
    #  p is prob. of ket zero, 1-p is prob of ket 1
    return square_loss(W(theta), [p, 1 - p])


# initialise the optimizer
opt = qml.GradientDescentOptimizer(stepsize=0.4)
# set the number of steps
steps = 100
# set the initial theta value of variational circuit state
theta = np.random.randn(2)
print("Initial probs. of basis states: {}".format(W(theta)))


def update(theta, p):
    # p = probability
    for i in range(steps):
        # update the circuit parameters
        theta = opt.step(lambda v: cost(v, p), theta)
        #if (i + 1) % 10 == 0:
        #print("Cost @ step {:5d}: {: .7f}".format(i, cost(theta,p)))
    print("Probs. of basis states: {}".format(W(theta)))
Ejemplo n.º 28
0
# Let's now come back to the actual implementation.
# PennyLane's `EmbeddingKernel` class allows you to easily evaluate the kernel target alignment:

print(
    "The kernel-target-alignment for our dataset with random parameters is {:.3f}"
    .format(k.target_alignment(dataset.X, dataset.Y, init_params)))

# Now let's code up an optimization loop and improve this!
#
# We will make use of regular gradient descent optimization.
# To speed up the optimization we will not use the entire training set but rather sample smaller subsets of the data at each step, we choose $4$ datapoints at random.
# Remember that PennyLane's inbuilt optimizer works to _minimize_ the cost function that is given to it, which is why we have to multiply the kernel target alignment by $-1$ to actually _maximize_ it in the process.

# +
params = init_params
opt = qml.GradientDescentOptimizer(2.5)

for i in range(500):
    subset = np.random.choice(list(range(len(dataset.X))), 4)
    params = opt.step(
        lambda _params: -k.target_alignment(dataset.X[subset], dataset.Y[
            subset], _params), params)

    if (i + 1) % 50 == 0:
        print("Step {} - Alignment = {:.3f}".format(
            i + 1, k.target_alignment(dataset.X, dataset.Y, params)))
# -

# We want to assess the impact of training the parameters of the quantum kernel.
# Thus, let's build a second support vector classifier with the trained kernel:
# Quantum natural gradient optimization
# -------------------------------------
#
# PennyLane provides an implementation of the quantum natural gradient
# optimizer, :class:`~.QNGOptimizer`. Let's compare the optimization convergence
# of the QNG Optimizer and the :class:`~.GradientDescentOptimizer` for the simple variational
# circuit above.

steps = 200
init_params = np.array([0.432, -0.123, 0.543, 0.233])

##############################################################################
# Performing vanilla gradient descent:

gd_cost = []
opt = qml.GradientDescentOptimizer(0.01)

theta = init_params
for _ in range(steps):
    theta = opt.step(circuit, theta)
    gd_cost.append(circuit(theta))

##############################################################################
# Performing quantum natural gradient descent:

qng_cost = []
opt = qml.QNGOptimizer(0.01)

theta = init_params
for _ in range(steps):
    theta = opt.step(circuit, theta)
Ejemplo n.º 30
0
init_params = np.array([3.97507603, 3.00854038])


##############################################################################
# We will carry out each optimization over a maximum of 500 steps. As was done in the VQE
# tutorial, we aim to reach a convergence tolerance of around :math:`10^{-6}`.
# We use a step size of 0.01.

max_iterations = 500
conv_tol = 1e-06
step_size = 0.01

##############################################################################
# First, we carry out the VQE optimization using the standard gradient descent method.

opt = qml.GradientDescentOptimizer(stepsize=step_size)

params = init_params

gd_param_history = [params]
gd_cost_history = []

for n in range(max_iterations):

    # Take step
    params, prev_energy = opt.step_and_cost(cost_fn, params)
    gd_param_history.append(params)
    gd_cost_history.append(prev_energy)

    energy = cost_fn(params)