Commit 870d331c authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding KernelBuilder.exp() method.

parent 3a4b9879
Loading
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
from qcor import *

exponent_op = adag(0) * a(1) - adag(1) * a(0)

builder = KernelBuilder()

builder.x(0)
builder.exp('theta', exponent_op)
ansatz = builder.create()

# Define the hamiltonian
H = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) - 6.125 * Z(1) + 5.907

# Create the ObjectiveFunction, specify central finite diff gradient
obj = createObjectiveFunction(ansatz, H, 1, {'gradient-strategy':'central', 'step':1e-1})

# create the lbfgs optimizer
optimizer = createOptimizer('nlopt', {'algorithm':'l-bfgs', 'ftol':1e-3})

# Run VQE...
results = optimizer.optimize(obj)
print(results)
 No newline at end of file
+37 −0
Original line number Diff line number Diff line
from qcor import *

exp_args = [adag(0) * a(1) - adag(1)*a(0), adag(0)*a(2) - adag(2)*a(0)]

builder = KernelBuilder()

builder.x(0)
for i, exp_arg in enumerate(exp_args):
    builder.exp(('x',i), exp_arg)
ansatz = builder.create()

# Custom arg_translator in a Pythonic way
def ansatz_translate(self, q: qreg, x: List[float]):
    ret_dict = {}    
    ret_dict["q"] = q
    ret_dict["x"] = x
    ret_dict["exp_args"] = exp_args
    return ret_dict

ansatz.translate = MethodType(ansatz_translate, qjit)

# Define the hamiltonian
H = createOperator(
    '5.907 - 2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1 + 9.625 - 9.625 Z2 - 3.91 X1 X2 - 3.91 Y1 Y2')

# Create the ObjectiveFunction, specify central finite diff gradient
obj = createObjectiveFunction(
    ansatz, H, 2, {'gradient-strategy': 'central', 'step': 1e-2})

# create the lbfgs optimizer
optimizer = createOptimizer('nlopt', {'algorithm': 'l-bfgs', 'ftol': 1e-3})

# Run VQE...
results = optimizer.optimize(obj)
print(results)

#print(ansatz.llvm_mlir(qalloc(3), results[1]))
 No newline at end of file
+23 −4
Original line number Diff line number Diff line
@@ -696,15 +696,34 @@ class KernelBuilder(object):
        if isinstance(qbit, list):
            for i in qbit:
                self.measure(i)
            # self.qjit_str += self.TAB + 'qbits = {}'.format(qbit)
            # self.qjit_str += self.TAB+'for i in range(qbits):\n'.format(qbit)
            # self.qjit_str += self.TAB+self.TAB+'Measure({}[i])\n'.format(self.qreg_name)
        elif isinstance(qbit, int):
            self.qjit_str += self.TAB+'Measure({}[{}])\n'.format(self.qreg_name, qbit)
        else:
            print('[KernelBuilder] invalid input to measure {}'.format(qbit))
            exit(1)

    def exp(self, variable, op : xacc.Observable):
        params_str = ''
        if isinstance(variable, str):
            params_str = variable
            if str(variable) not in self.kernel_args:
                self.kernel_args[str(variable)] = float
        elif isinstance(variable, tuple):
            params_str = variable[0]+'['+str(variable[1])+']'
            if variable[0] not in self.kernel_args:
                self.kernel_args[variable[0]] = List[float]
        else:
            print('[KernelBuilder Error] Invalid exp() parameter type.')
            exit(1)

        op_str = op.toString()
        op_type = 'fermion' if '^' in op_str else 'pauli'
        hash_object = hashlib.md5(op_str.encode('utf-8'))
        op_var_name = '__internal_op_var_'+str(hash_object.hexdigest())
        self.qjit_str += self.TAB+"{} = _internal_python_createObservable(\"{}\", \"{}\")\n".format(op_var_name, op_type, op_str)
        self.qjit_str += self.TAB+'exp_i_theta({}, {}, {})\n'.format(self.qreg_name, params_str, op_var_name)
   

    # Synthesis from matrix, or from matrix generator
    # can provide method = [qsearch,qfast,kak, etc.]
    def synthesize(self, **kwargs):
@@ -764,7 +783,7 @@ class KernelBuilder(object):

        args_str = 'q : qreg, ' + ', '.join(k+' : '+allowed_type_map[str(v)] for k,v in self.kernel_args.items())
        func = 'def {}({}):\n'.format(kernel_name, args_str)+self.qjit_str
        # print(func)
        print(func)
        result = globals()
        exec(func, result)
        # print(result)
+12 −2
Original line number Diff line number Diff line
@@ -22,8 +22,12 @@ PauliOperator operator-(PauliOperator &op, double coeff) {
  return -1.0 * coeff + op;
}

FermionOperator adag(int idx) {return FermionOperator(xacc::quantum::Operators{{idx, true}});};
FermionOperator a(int idx) {return FermionOperator(xacc::quantum::Operators{{idx, false}});};
FermionOperator adag(int idx) {
  return FermionOperator(xacc::quantum::Operators{{idx, true}});
};
FermionOperator a(int idx) {
  return FermionOperator(xacc::quantum::Operators{{idx, false}});
};

PauliOperator X(int idx) { return PauliOperator({{idx, "X"}}); }

@@ -120,7 +124,13 @@ std::shared_ptr<Observable> operatorTransform(const std::string &type,
  return xacc::getService<xacc::ObservableTransform>(type)->transform(op);
}

std::shared_ptr<Observable> _internal_python_createObservable(
    const std::string &name, const std::string &repr) {
  return createOperator(name, repr);
}

namespace __internal__ {

std::vector<std::shared_ptr<xacc::CompositeInstruction>> observe(
    std::shared_ptr<xacc::Observable> obs,
    std::shared_ptr<CompositeInstruction> program) {
+30 −20
Original line number Diff line number Diff line
#pragma once

#include "qcor_utils.hpp"

#include "FermionOperator.hpp"
#include "Observable.hpp"
#include "PauliOperator.hpp"
#include "FermionOperator.hpp"
#include "qcor_utils.hpp"

namespace qcor {

@@ -30,7 +29,6 @@ PauliOperator operator+(PauliOperator &op, double coeff);
PauliOperator operator-(double coeff, PauliOperator &op);
PauliOperator operator-(PauliOperator &op, double coeff);


Eigen::MatrixXcd get_dense_matrix(PauliOperator &op);
Eigen::MatrixXcd get_dense_matrix(std::shared_ptr<Observable> op);

@@ -102,23 +100,35 @@ double observe(std::shared_ptr<CompositeInstruction> program,
               xacc::internal_compiler::qreg &q);
namespace __internal__ {
// Observe the kernel and return the measured kernels
std::vector<std::shared_ptr<CompositeInstruction>>
observe(std::shared_ptr<Observable> obs,
std::vector<std::shared_ptr<CompositeInstruction>> observe(
    std::shared_ptr<Observable> obs,
    std::shared_ptr<CompositeInstruction> program);

}  // namespace __internal__

std::shared_ptr<Observable> _internal_python_createObservable(
    const std::string &name, const std::string &repr);
    
// Create an observable from a string representation
std::shared_ptr<Observable> createObservable(const std::string &repr);
std::shared_ptr<Observable> createObservable(const std::string& name, const std::string &repr);
std::shared_ptr<Observable> createObservable(const std::string &name, HeterogeneousMap&& options);
std::shared_ptr<Observable> createObservable(const std::string &name, HeterogeneousMap& options);
std::shared_ptr<Observable> createObservable(const std::string &name,
                                             const std::string &repr);
std::shared_ptr<Observable> createObservable(const std::string &name,
                                             HeterogeneousMap &&options);
std::shared_ptr<Observable> createObservable(const std::string &name,
                                             HeterogeneousMap &options);

std::shared_ptr<Observable> createOperator(const std::string &repr);
std::shared_ptr<Observable> createOperator(const std::string& name, const std::string &repr);
std::shared_ptr<Observable> createOperator(const std::string &name, HeterogeneousMap&& options);
std::shared_ptr<Observable> createOperator(const std::string &name, HeterogeneousMap& options);

std::shared_ptr<Observable> operatorTransform(const std::string& type, qcor::Observable& op);
std::shared_ptr<Observable> operatorTransform(const std::string& type, std::shared_ptr<Observable> op);
std::shared_ptr<Observable> createOperator(const std::string &name,
                                           const std::string &repr);
std::shared_ptr<Observable> createOperator(const std::string &name,
                                           HeterogeneousMap &&options);
std::shared_ptr<Observable> createOperator(const std::string &name,
                                           HeterogeneousMap &options);

std::shared_ptr<Observable> operatorTransform(const std::string &type,
                                              qcor::Observable &op);
std::shared_ptr<Observable> operatorTransform(const std::string &type,
                                              std::shared_ptr<Observable> op);

}  // namespace qcor
 No newline at end of file