Digitized Counterdiabatic Quantum Optimization#
- class DCQOProblem(Q, H_init, H_prob, A_lam, agp_coeffs, lam_func, g_func=None, H_control=None, qarg_prep=None)[source]#
General structure to formulate Digitized Counterdiabatic Quantum Optimization problems. This class is used to solve DCQO problems with the algorithms COLD (counterdiabatic optimized local driving) or LCD (local counterdiabatic driving). To run the COLD algorithm on the problem, you need to specify the control Hamiltonian
H_controland the inverse scheduling functiong_func. These are not needed for the LCD algorithm. To learn more about counterdiabatic driving, make sure to check out the tutorial.- Parameters:
- Qnp.array
The QUBO matrix.
- H_initQubitOperator
Hamiltonian, the system is at the time t=0.
- H_probQubitOperator
Hamiltonian, the system evolves to for t=T.
- A_lamQubitOperator
Operator holding an appoximation for the adiabatic gauge potential (AGP).
- agp_coeffscallable
The parameters for the adiabatic gauge potential (AGP). If the COLD method is being used, they must depend on the optimization pulses in
H_control.- lam_funccallable
A function \(\lambda(t, T)\) mapping \(t \in [0, T]\) to \(\lambda \in [0, 1]\). This function needs to return a sympy expression with \(t\) and \(T\) as sympy.Symbols.
- g_funccallable, optional
The inverse function of \(\lambda(t, T)\). This function needs to return a sympy expression with \(\lambda\) and \(T\) as sympy.Symbols. Only needed for the COLD algorithm.
- H_controlQubitOperator, optional
Hamiltonian specifying the control pulses for the COLD method. If not given, the LCD method is used automatically.
- qarg_prepcallable, optional
A function receiving a QuantumVariable for preparing the inital state. By default, the groundstate of the x-operator \(\ket{-}^n\) is prepared.
Examples
For a quick demonstration we build a DCQO problem instance for a 4x4 QUBO. We choose a first order AGP ansatz with uniform coefficients and solve it with LCD.
import numpy as np import sympy as sp from qrisp.operators.qubit import X, Y, Z from qrisp.algorithms.cold import DCQOProblem from qrisp import QuantumVariable Q = np.array([ [-1.2, 0.40, 0.0, 0.0], [ 0.40, 0.30, 0.20, 0.0], [ 0.0, 0.20,-1.1, 0.30], [ 0.0, 0.0, 0.30,-0.80] ]) N = Q.shape[0] # Define QUBO problem hamiltonian h = -0.5 * np.diag(Q) - 0.5 * np.sum(Q, axis=1) J = 0.5 * Q H_init = 1 * sum([X(i) for i in range(N)]) H_prob = (sum([sum([J[i][j]*Z(i)*Z(j) for j in range(i)]) for i in range(N)]) + sum([h[i]*Z(i) for i in range(N)])) # Create AGP A_lam = sum([Y(i) for i in range(N)]) # uniform # Function for uniform AGP coefficients def alpha(lam): A = lam * h B = 1 - lam nom = np.sum(A + 4*B*h) denom = 2 * (np.sum(A**2) + N * (B**2)) + 4 * (lam**2) * np.sum(np.tril(J, -1).sum(axis=1)) alph = nom/denom alph = [alph]*N return alph # Simple scheduling function 0 -> 1 def lam(): t, T = sp.symbols("t T", real=True) lam_expr = t/T return lam_expr # Create problem instance lcd_problem = DCQOProblem(Q, H_init, H_prob, A_lam, alpha, lam) # Run problem with LCD algorithm qarg = QuantumVariable(N) res = lcd_problem.run(qarg, N_steps=4, T=12, method="LCD") print(res)
{'1011': [0.40630593694063055, np.float64(-2.5)], '1111': [0.16247837521624783, np.float64(-0.9999999999999999)], '0111': [0.13156868431315685, np.float64(-0.6000000000000001)], '1000': [0.06881931180688193, np.float64(-1.2)], '0011': [0.05949940500594993, np.float64(-1.3)], '1010': [0.04499955000449995, np.float64(-2.3)], '1101': [0.04084959150408495, np.float64(-0.9)], '0110': [0.019769802301976978, np.float64(-0.40000000000000013)], '1100': [0.01815981840181598, np.float64(-0.09999999999999998)], '0100': [0.013679863201367985, np.float64(0.3)], '0001': [0.010399896001039988, np.float64(-0.8)], '0000': [0.007659923400765992, np.float64(0.0)], '1110': [0.006329936700632993, np.float64(-0.7999999999999999)], '0101': [0.0052899471005289946, np.float64(-0.5)], '1001': [0.0024299757002429973, np.float64(-2.0)], '0010': [0.0017599824001759982, np.float64(-1.1)]}
We get a dictionary where the key is the quantum state and the values are lists of [probability, cost]. So our most likely result is ‘1011’ with probabilty 0.4 and the QUBO cost \(x^T Q x = -2.5\).
Methods#
|
Run the specific DCQO problem instance with given quantum arguments, number of timesteps and evolution time. |
|
Simulate the local counterdiabatic driving (LCD) Hamiltonian on a quantum argument via trotterization. |
|
Simulate counterdiabatic optimized local driving (COLD) Hamiltonian on a quantumvariable via trotterization. |
|
Compiles the circuit that is created by the |
|
Subroutine for the optimization method used in COLD. |
Returns the cost y = x^T Q x for a given binary array x. |
Quick run#
Quickly run LCD/COLD with our predefined operators and functions in QUBO.py:
- solve_QUBO(Q: array, problem_args: dict, run_args: dict)[source]#
Solves a QUBO Matrix using counterdiabatic driving. This method uses the pre-defined COLD/LCD operators (hamiltonian, scheduling function, AGP parameters) as described in the tutorial. To define your own operators, create a DCQO instance and use the
runmethod.- Parameters:
- Qnp.array
QUBO Matrix to solve.
- problem_argsdict
Holds arguments for DCQO problem creation (
method: str (“COLD”/”LCD”),uniform: bool).- run_argsdict
Holds arguments for running the DCQO instance (
N_steps,T,N_opt,CRAB). For all options, seeDCQOProblem.run().
- Returns:
- resultdict
The dictionary holding the QUBO vector results, with their probabilitites and cost. They are ordered from most to least likely and the dictionary entries are {“state”: [prob, cost]}.
Examples
import numpy as np from qrisp.algorithms.cold import solve_QUBO Q = np.array([[-1.1, 0.6, 0.4, 0.0, 0.0, 0.0], [0.6, -0.9, 0.5, 0.0, 0.0, 0.0], [0.4, 0.5, -1.0, -0.6, 0.0, 0.0], [0.0, 0.0, -0.6, -0.5, 0.6, 0.0], [0.0, 0.0, 0.0, 0.6, -0.3, 0.5], [0.0, 0.0, 0.0, 0.0, 0.5, -0.4]]) problem_args = {"method": "COLD", "uniform": False} run_args = {"N_steps": 4, "T": 8, "N_opt": 1, "CRAB": False, "objective": "agp_coeff_magnitude", "bounds": (-3, 3)} result = solve_QUBO(Q, problem_args, run_args) print(result)
{'101101': [0.2749327493274933, np.float64(-3.4)], '011101': [0.14747147471474714, np.float64(-3.0)], '111101': [0.10500105001050011, np.float64(-2.1)], '101100': [0.0888608886088861, np.float64(-3.0)], '011100': [0.04720047200472005, np.float64(-2.6)], '101110': [0.043830438304383046, np.float64(-2.1)], '111100': [0.035760357603576036, np.float64(-1.7000000000000002)], '011110': [0.024410244102441025, np.float64(-1.7)], '100101': [0.02137021370213702, np.float64(-2.0)], '110101': [0.016960169601696017, np.float64(-1.7000000000000002)], '111110': [0.01686016860168602, np.float64(-0.8)], '111001': [0.016390163901639016, np.float64(-0.4)], '001101': [0.014560145601456015, np.float64(-3.1)], '010101': [0.014370143701437016, np.float64(-1.7999999999999998)], '101011': [0.011320113201132012, np.float64(-1.0)], '111000': [0.008620086200862008, np.float64(0.0)], '100001': [0.007290072900729008, np.float64(-1.5)], '000101': [0.006580065800658007, np.float64(-0.9)], '110100': [0.006420064200642007, np.float64(-1.3000000000000003)], '011011': [0.006090060900609006, np.float64(-0.6)], '101000': [0.005780057800578007, np.float64(-1.3)], '100100': [0.0057700577005770064, np.float64(-1.6)], '101001': [0.005720057200572007, np.float64(-1.7000000000000002)], '101111': [0.005310053100531005, np.float64(-1.5)], '100110': [0.005230052300523006, np.float64(-0.7)], '010100': [0.004050040500405004, np.float64(-1.4)], '001100': [0.004040040400404004, np.float64(-2.7)], '011000': [0.003870038700387004, np.float64(-0.9)], '011111': [0.0032400324003240034, np.float64(-1.1)], '100000': [0.0031800318003180035, np.float64(-1.1)], '110010': [0.0029900299002990033, np.float64(-1.1)], '010001': [0.002930029300293003, np.float64(-1.3)], '011001': [0.002850028500285003, np.float64(-1.3)], '110011': [0.002770027700277003, np.float64(-0.5000000000000001)], '001110': [0.002650026500265003, np.float64(-1.8)], '010110': [0.0025900259002590025, np.float64(-0.5)], '110001': [0.0024400244002440027, np.float64(-1.2000000000000002)], '000100': [0.0022800228002280024, np.float64(-0.5)], '100011': [0.002020020200202002, np.float64(-0.8000000000000002)], '111011': [0.001770017700177002, np.float64(0.3)], '010000': [0.0015300153001530014, np.float64(-0.9)], '101010': [0.0014900149001490016, np.float64(-1.6)], '111111': [0.0014200142001420015, np.float64(-0.20000000000000007)], '000010': [0.0010500105001050011, np.float64(-0.3)], '110111': [0.0008300083000830009, np.float64(0.19999999999999984)], '010011': [0.0008200082000820009, np.float64(-0.6)], '001011': [0.0007900079000790008, np.float64(-0.7000000000000001)], '100111': [0.0007200072000720008, np.float64(-0.09999999999999998)], '001000': [0.0006300063000630007, np.float64(-1.0)], '100010': [0.0006000060000600005, np.float64(-1.4000000000000001)], '001111': [0.0005800058000580006, np.float64(-1.2000000000000002)], '010010': [0.0005700057000570006, np.float64(-1.2)], '001001': [0.0005300053000530005, np.float64(-1.4)], '011010': [0.0005200052000520005, np.float64(-1.2)], '000011': [0.0005000050000500006, np.float64(0.3)], '111010': [0.0004300043000430004, np.float64(-0.3)], '110000': [0.00026000260002600025, np.float64(-0.8000000000000002)], '000110': [0.00026000260002600025, np.float64(0.39999999999999997)], '010111': [0.00021000210002100023, np.float64(0.09999999999999998)], '000001': [0.0001700017000170002, np.float64(-0.4)], '001010': [0.00012000120001200013, np.float64(-1.3)], '000000': [9.00009000090001e-05, np.float64(0.0)], '000111': [8.000080000800009e-05, np.float64(1.0)], '110110': [2.0000200002000023e-05, np.float64(-0.4000000000000002)]}