Dirac-3 Developer Beginner Guide
Dirac-3 is the latest addition to QCi's Entropy Quantum Computing (EQC) product line, a unique quantum-hardware approach for tackling hard polynomial optimization problems. Dirac-3 uses non-binary qudits as its unit of quantum information (cf. binary qubits), where each quantum state is represented by dimensions. Dirac-3 can solve problems with variables beyond binary , including non-negative integers and sum-constrained continuous numbers. For further information on qudits, please read through the Qudit Primer to better understand the benefits of high-dimensional programming. To delve deeper into the underlying physics of EQC technology, refer to our paper: An Open Quantum System for Discrete Optimization.
Discrete-based variables allow Dirac-3 to solve a variety of important problems including integer-optimization problems with higher-order-polynomial objective functions. This tutorial provides an introduction to how to formulate such problems for Dirac-3 and run them as jobs via QCi's cloud-based REST API. Dirac-3 is a stochastic solver that does not necessarily find the same solution on every run. Thus, the general approach is to use multiple runs per job to "sample" a solution space that we configure to be large enough to contain the global minimum (a.k.a., the ground state) we seek for the problem at hand.
Prerequisites: In order to begin running problems with Dirac-3 you will need to:
The following code block initializes a QciClient
client (from the qci-client
Python package imported as qci_client
) that connects to a Dirac-3 device via QCi's REST API on the cloud (at url
). As with all of QciClient
's API-request methods, the client
's get_allocations
method checks for a non-expired access token from the API, and automatically retrieves/refreshes it when needed (using api_token
as the refresh token). A successful get_allocations
call verifies both your authenticated API connectivity and your allocation time (in seconds) for running jobs on Dirac-3. Run this code block successfully (with api_token
updated to your API token) before attempting to run the subsequent example problems.
In [ ]:
- import importlib.metadata
- from pprint import pprint
- from qci_client import JobStatus, QciClient
- # Requires qci-client v4.5.0+.
- print(f"qci-client v{importlib.metadata.version('qci-client')}")
- url = "https://api.qci-prod.com"
- api_token = "<replace your token here>"
- client = QciClient(url=url, api_token=api_token)
- print(client.get_allocations()["allocations"]["dirac"])
- # This should output something similar to:
- # qci-client v4.5.0
- # {'metered': True, 'seconds': 600}
Polynomial Objective Functions
Dirac-3 solves objective-function-minimization problems over discrete spaces by searching for the ground state (i.e., lowest value) for the total "energy" of a potentially complex system with many variables with multiplicative interactions of different orders. Generally, this corresponds to finding the set of variables that minimizes the energy returned by the following -variable polynomial objective function up to degree five:
where is the real-valued linear return of each variable, and , , , and are real-valued joint returns of variables (a.k.a., interaction terms). Constant terms are omitted as they do not affect the location of minima.
Dirac-3 allows direct submission for minimization only. It is assumed that users perform a simple transformation before submitting the problem to handle maximization (i.e., multiply coefficients by -1). For additional information please refer to our Dirac-3 User Guide.
Encoding Polynomials
Encoding a polynomial objective function is important for correctly defining a problem. Consider the degree-three polynomial in two variables , :
The terms of this polynomial are encoded separately as lists of coefficients and indices. The (real-valued) coefficients of this polynomial are encoded as
poly_coefs = [3.14, -2, 3, -4, 5, -6, 7, -8]
,
whereas the degree of the term corresponding to each coefficient is encoded using a nested list of indices as
poly_indices = [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 1], [0, 1, 2], [0, 1, 2], [1, 1, 2], [2, 2, 2]]
.
As long as the elements of poly_coefs
and poly_indices
correspond to each other in the encoding, the ordering of polynomial terms does not matter. Each index list in poly_indices
should have a length corresponding to the maximum degree of the polynomial. The elements of each index list refer to the 1-based variable number, with repeats corresponding to a higher degree for that variable and zero(s) used to specify a lower degree term. All index elements must be non-decreasing from left to right, which ensures a unique representation of each polynomial term. Missing terms of a given degree are simply omitted from both lists, and multiple terms of the same degree are allowed and will be simply summed as indicated (e.g., the and terms). The all-zero index refers to a degree-zero constant term (here ), which is normally omitted as it does not affect the minimization and is currently not supported by Dirac-3.
Dirac-3 as an Integer Solver
When used as an integer solver, Dirac-3's qudits are configured so that each represents an integer variable with a user-defined integer-valued upper bound , i.e.,
where is called the number of levels for variable .
Note that taking for all and reduces the problem formulation to be equivalent to the common quadratic unconstrained binary optimization (QUBO), which Dirac-3 can solve.
Formulating and Running Integer Problems on Dirac-3
We define a basic integer-optimization problem for submission to Dirac-3. To illustrate a standard problem submission, a polynomial is used that has multiple local minima surrounding a global minumum at the origin. We intend to find the non-negative integer values of and that minimize the energy defined by:
where has five levels and has three levels .
For the purposes of illustration, this simple polynomial does not have "mixed terms" involving the product of and . In the positive quadrant, this function is known to have a global minimum at with energy , and local minima at , , and with energies , , and , respectively.
Uploading the Problem File
The first step is to extract the polynomial coefficients and format polynomial variable indices for each term in the equation. The termwise polynomial coefficients will be represented as a list as follows:
poly_coefs = [0.25, 0.25, -1.6666667, -1.6666667, 3, 3]
.
The polynomial indices for the coefficients will be represented as follows in the same order of terms as represented in the polynomial coefficients:
poly_indices = [[1, 1, 1, 1], [2, 2, 2, 2], [0, 1, 1, 1], [0, 2, 2, 2], [0, 0, 1, 1], [0, 0, 2, 2]]
.
We'll use poly_coeffs
and poly_indices
to generate the data file. We will then use the client
that we initialized above to upload the file via the API. To allow the API to validate the polynomial, we explicitly provide the polynomial's min_degree
, max_degree
, and num_variables
.
In [ ]:
- # Let's consider a simple Hamiltonian problem
- poly_indices_int_problem = [[1, 1, 1, 1], [2, 2, 2, 2], [0, 1, 1, 1], [0, 2, 2, 2], [0, 0, 1, 1], [0, 0, 2, 2]]
- poly_coefs_int_problem = [0.25, 0.25, -1.6666667, -1.6666667, 3, 3]
- data_int_problem = [{"idx": idx, "val": val} for idx, val in zip(poly_indices_int_problem, poly_coefs_int_problem)]
- file_int_problem = {
- "file_name": "dirac_3_integer_example",
- "file_config": {
- "polynomial": {
- "num_variables": 2,
- "min_degree": 2,
- "max_degree": 4,
- "data": data_int_problem,
- }
- }
- }
- file_response_int_problem = client.upload_file(file=file_int_problem)
- file_response_int_problem
- # This should output something similar to:
- # {'file_id': '670ff26b5e0855263226e27f'}
Specifying Job Body Parameters
We now build the job body, selecting from the following configuration parameters:
-
job_type
: The type of job to be performed. In this case, ’sample-hamiltonian-integer’ indicates that the job minimizes a Hamiltonian with integer variables. -
job_name
: An optional user-defined string that names the job. Here, it’s set to ’test_integer_variable_hamiltonian_job’. -
job_tags
: An optional list of user-defined strings to tag the job for easier reference and organization. In this example, the tags are [’tag1’, ’tag2’]. -
job_params
: A dictionary containing parameters for configuring the job's problem and device. The relevant fields generally depend on the choice ofjob_type
anddevice_type
, the latter of which must be present injob_params
and here is ’dirac-3’. For ’sample-hamiltonian-integer’ on ’dirac-3’, the followingjob_params
fields are relevant:num_samples
: The optional number of samples to run for the stochastic solver. The value must be between 1 and 100, with default 1.relaxation_schedule
: A configuration selector that must be in the set , representing four different schedules. The relaxation schedule controls multiple parameters of the quantum machine including the amount of loss, number of feedback loops, the amount of quantum fluctuation, and mean photon number measured. While the first two parameters are fixed, the last two can be further adjusted by users (see below). Lower relaxation schedules are set to larger amount of dissipation in a open quantum system setup, leading to more iterations needed to reach stable states. As a result, the probability of finding an optimal solution can be higher in higher schedules, especially on a competitive energy landscape with the trade-off of longer evolution time. This parameter is optional with a default of 1.num_levels
: An array of positive integers that defines the maximum possible value for each variable. For example, means and take two-level binary values 0 or 1 (qubit) and takes a three-level value 0, 1, or 2 (qudit). If each variable has the same upper bound, then an array with only a single value may be passed. The job will error if the total ofnum_levels
over all variables exceeds the device limit (currently 954 on Dirac-3).mean_photon_number
: An optional advanced configuration parameter that is normally set automatically through the choice ofrelaxation_schedule
. A value specified here overrides the default value and should be a real-number value from 0.001 to 1. This parameter is the average number of photons detected over a specific time period which is a time-bin representing a possible value of a variable in Dirac-3. This is a common metric used in photon statistics and quantum optics to approximate the probability of being in the single-photon regime of coherent light. Low mean photon number maintains the quantum superposition effect in high-dimensional time-bin modes of the wavefunction. Notice that extremely low mean photon number to the same order of thermal or electronic noise in single photon detector might affect the solution negatively. [Fox, M. (2006). Quantum Optics. Wiley, 75-104., Pearson, D., Elliott, C. (2004). On the Optimal Mean Photon Number for Quantum Cryptography., Mower, J., Zhang, Z., Desjardins, P., Lee, C., Shapiro, J. H., Englund, D. (2013). High-dimensional quantum key distribution using dispersive optics. Phys. Rev. A, 87(6), 062322., Nguyen, L., Rehain, P., Sua, Y. M., Huang, Y. (2018). Programmable quantum random number generator without postprocessing. Opt. Lett., 43(4), 631-634.]quantum_fluctuation_coefficient
: An optional advanced configuration parameter that is normally set automatically through the choice ofrelaxation_schedule
. A value specified here overrides the default value and should be an integer value , which is used to compute the coefficient in the real-valued interval . The inherent randomness of photon arrival time comes from the quantum nature of light giving rise to a fundamental limitation in single photon counting, known as Poisson noise. Dirac-3 takes advantage of this noise arising from quantum fluctuation to gain opportunity to large search space and jump out of local minima. This parameter can be adjusted to allow high or low amount of quantum fluctuation into the open system. A low fluctuation tends to provide a worse solution than a high fluctuation. Notice that, to maintain a good returned solution, this parameter should not reach too high in the same order as the signal photon. [Bédard, G. (1967). Analysis of Light Fluctuations from Photon Counting Statistics, J. Opt. Soc. Am., 57, 1201-1206.]
-
polynomial_file_id
: The unique identifier for the uploaded polynomial file, retrieved from the file response'sfile_id
. This ID links the job to the specific problem data.
By preparing the job body in this manner, you set up all necessary configurations and metadata required by the QCi API to process the integer-optimization task on the Dirac-3 device.
In [ ]:
- # Build the job body to be submitted to the QCi API.
- # This is where the job type and the Dirac-3 device and its configuration are specified.
- job_body_int_problem = client.build_job_body(
- job_type='sample-hamiltonian-integer',
- job_name='test_integer_variable_hamiltonian_job', # user-defined string, optional
- job_tags=['tag1', 'tag2'], # user-defined list of string identifiers, optional
- job_params={
- 'device_type': 'dirac-3',
- 'num_samples': 5,
- 'relaxation_schedule': 1,
- 'num_levels': [5, 2], # For demonstration, this excludes some but not all of the known local minima.
- },
- polynomial_file_id=file_response_int_problem['file_id'],
- )
- pprint(job_body_int_problem)
- # This should output something similar to:
- # {'job_submission': {'device_config': {'dirac-3_qudit': {'num_levels': [5, 2],
- # 'num_samples': 5,
- # 'relaxation_schedule': 1}},
- # 'job_name': 'test_integer_variable_hamiltonian_job',
- # 'job_tags': ['tag1', 'tag2'],
- # 'problem_config': {'qudit_hamiltonian_optimization': {'polynomial_file_id': '674f27a75e08552632271ef7'}}}}
Submitting the Job to the API and Running It
Now using the job body that we just created we'll submit the job to QCi's REST API. After submission your job will progress through the following states:
- QUEUED: waiting for the Dirac-3 to become available
- RUNNING: the job has been submitted to the Dirac-3 and is running
- COMPLETED: the job has completed and results are available for analysis
In [ ]:
- # Submit the job and await the result.
- job_response_int_problem = client.process_job(job_body=job_body_int_problem)
- # Before inspecting solution(s), ensure that job did not error.
- assert job_response_int_problem["status"] == JobStatus.COMPLETED.value
- # Ten samples taken.
- print("Found solutions:")
- pprint(job_response_int_problem['results']['solutions'])
- print("with energies:")
- pprint(job_response_int_problem['results']['energies'])
- print("and counts:")
- pprint(job_response_int_problem['results']['counts'])
- # This should output something similar to:
- # 2024-12-03 09:00:11 - Dirac allocation balance = 0 s (unmetered)
- # 2024-12-03 09:00:11 - Job submitted: job_id='674f2b0b324e163bf2d890c7'
- # 2024-12-03 09:00:11 - QUEUED
- # 2024-12-03 09:00:14 - RUNNING
- # 2024-12-03 09:00:24 - COMPLETED
- # 2024-12-03 09:00:26 - Dirac allocation balance = 0 s (unmetered)
- # Found solutions:
- # [[0, 0]]
- # with energies:
- # [0]
- # and counts:
- # [5]
Inspecting Detailed Results
In the Python code above we printed the most relevant solution information for the ten samples, which are lists of:
- solution - a vector representing the solution to the problem from a given run on the Dirac hardware
- energy - the objective value for solution returned by the device
- count - the number of times that the solution was observed (esp. relevant when
num_samples > 1
)
The full job response from the client has more information, as seen in the job_response
variable below.
In [ ]:
- pprint(job_response_int_problem)
- # This should output something similar to:
- # {'job_info': {'job_id': '674f5de4324e163bf2d890fa',
- # 'job_result': {'device_usage_s': 8,
- # 'file_id': '674f5e1b5e08552632271fd7'},
- # 'job_status': {'completed_at_rfc3339nano': '2024-12-03T19:38:03.837Z',
- # 'queued_at_rfc3339nano': '2024-12-03T19:37:08.037Z',
- # 'running_at_rfc3339nano': '2024-12-03T19:37:08.315Z',
- # 'submitted_at_rfc3339nano': '2024-12-03T19:37:08.036Z'},
- # 'job_submission': {'device_config': {'dirac-3_qudit': {'num_levels': [5,
- # 2],
- # 'num_samples': 10,
- # 'relaxation_schedule': 1}},
- # 'job_name': 'test_integer_variable_hamiltonian_job',
- # 'job_tags': ['tag1', 'tag2'],
- # 'problem_config': {'qudit_hamiltonian_optimization': {'polynomial_file_id': '674f29fc5e08552632271f09'}}}},
- # 'results': {'counts': [10], 'energies': [0], 'solutions': [[0, 0]]},
- # 'status': 'COMPLETED'}
In addition to the solutions and energies, job_response
contains additional information that may be useful:
job_id
: The unique id of the job that was runjob_submission
->problem_config
: contains all the information about the problem that was configured for the jobjob_submission
->device_config
: contains all the information about the device that was configured for the jobjob_result
->file_id
: the unique id of the results file that stores the job's result (otherwise haserror
field with error message)job_result
->device_usage_s
: the amount of "billable" time used on the deviceresults
: the solutions and corresponding energies (and their corresponding counts) that were found for the job
Dirac-3 as a Continuous Solver
When used as a continuous solver, Dirac-3 are configured so that each represents a non-negative continuous variable with a user-defined sum constraint, i.e.,
Here, is real-valued with an expected resolution of , where is the real-valued summation constraint. Dirac-3 currently provides a maximum of about .
Formulating and Running Continuous Problems on Dirac-3
We define a basic continuous-optimization problem for submission to Dirac-3. In order to illustrate a standard problem submission, a simple polynomial problem will be utilized. We intend to find the values of , , , and that minimize the energy defined by:
with sum constraint (i.e., ).
Uploading the Problem File
The first step is to extract the polynomial coefficients and format polynomial variable indices for each term in the equation. The polynomial coefficients will be represented as a list as follows:
- poly_coefs = [3, 2.1, 1.5, 7.9, 1, 1]
The polynomial indices for the coefficients will be represented as follows in the same order as represented in the original equation:
- poly_indices = [[0,0,4], [0,1,1], [0,2,2], [0,2,3], [2,4,4], [3,3,3]]
We'll use poly_coeffs
and poly_indices
to generate the data file. We will then use the client
that we initialized above to upload the file via the API. To allow the API to validate the polynomial, we explicitly provide the polynomial's min_degree
, max_degree
, and num_variables
. (Explicitly specifying the problem's num_variables
can be especially important for this problem type when the problem contains an extra "slack variable" that does not explicitly appear in any polynomial terms.)
In [ ]:
- # Let's consider a simple Hamiltonian problem
- poly_indices_cts_problem = [[0,0,4], [0,1,1], [0,2,2], [0,2,3], [2,4,4], [3,3,3]]
- poly_coefs_cts_problem = [3, 2.1, 1.5, 7.9, 1, 1]
- data_cts_problem = [{"idx": idx, "val": val} for idx, val in zip(poly_indices_cts_problem, poly_coefs_cts_problem)]
- file_cts_problem = {
- "file_name": "dirac_3_continuous_variable_example",
- "file_config": {
- "polynomial": {
- "num_variables": 4,
- "min_degree": 1,
- "max_degree": 3,
- "data": data_cts_problem,
- }
- }
- }
- file_response_cts_problem = client.upload_file(file=file_cts_problem)
- file_response_cts_problem
- # This should output something similar to:
- # {'file_id': '670ff26b5e0855263226e27f'}
Specifying Job Body Parameters
We now build the job body, selecting from the following configuration parameters:
-
job_type
: Specifies the type of job to be performed. In this case, ’sample-hamiltonian’ indicates that the job minimizes a Hamiltonian with continuous non-negative variables obeying a sum constraint. -
job_name
: An optional user-defined string that names the job. Here, it’s set to ’dirac_3_continuous_variable_example’. -
job_tags
: An optional list of user-defined string identifiers to tag the job for easier reference and organization. In this example, the tags are [’tag1’, ’tag2’]. -
job_params
: A dictionary containing parameters for configuring the problem and the device. The relevant fields generally depend on the choice of problem anddevice_type
, which must be present and here is ’dirac-3’. For this problem on this device, the followingjob_params
fields are relevant:num_samples
: The optional number of samples to run for the stochastic solver. The value must be between 1 and 100, with default 1.relaxation_schedule
: A configuration selector that must be in the set , representing four different schedules. The relaxation schedule controls multiple parameters of the quantum machine including the amount of loss, number of feedback loops, the amount of quantum fluctuation, and mean photon number measured. While the first two parameters are fixed, the last two can be further adjusted by users (see below). Lower relaxation schedules are set to larger amount of dissipation in a open quantum system setup, leading to more iterations needed to reach stable states. As a result, the probability of finding an optimal solution can be higher in higher schedules, especially on a competitive energy landscape with the trade-off of longer evolution time. This parameter is optional with a default of 1.sum_constraint
: A constraint applied to the problem space such that the solution variables must sum to the provided value. Optional value that must be between 1 and 10000, with default 1.solution_precision
: An optional number that specifies the level of precision to apply to the solutions. Omit this when the highest precision continuous solutions are deisired. If specified, then a distillation method is applied to the continuous solutions to reduce them to the submittedsolution_precision
. Note thatsum_constraint
must be divisible bysolution_precision
when the latter is specified.mean_photon_number
: An optional advanced configuration parameter that is normally set automatically through the choice ofrelaxation_schedule
. A value specified here overrides the default value and should be a real-number value from 0.001 to 1. This parameter is the average number of photons detected over a specific time period which is a time-bin representing a possible value of a variable in Dirac-3. This is a common metric used in photon statistics and quantum optics to approximate the probability of being in the single-photon regime of coherent light. Low mean photon number maintains the quantum superposition effect in high-dimensional time-bin modes of the wavefunction. Notice that extremely low mean photon number to the same order of thermal or electronic noise in single photon detector might affect the solution negatively. [Fox, M. (2006). Quantum Optics. Wiley, 75-104., Pearson, D., Elliott, C. (2004). On the Optimal Mean Photon Number for Quantum Cryptography., Mower, J., Zhang, Z., Desjardins, P., Lee, C., Shapiro, J. H., Englund, D. (2013). High-dimensional quantum key distribution using dispersive optics. Phys. Rev. A, 87(6), 062322., Nguyen, L., Rehain, P., Sua, Y. M., Huang, Y. (2018). Programmable quantum random number generator without postprocessing. Opt. Lett., 43(4), 631-634.]quantum_fluctuation_coefficient
: An optional advanced configuration parameter that is normally set automatically through the choice ofrelaxation_schedule
. A value specified here overrides the default value and should be an integer value , which is used to compute the coefficient in the real-valued interval . The inherent randomness of photon arrival time comes from the quantum nature of light giving rise to a fundamental limitation in single photon counting, known as Poisson noise. Dirac-3 takes advantage of this noise arising from quantum fluctuation to gain opportunity to large search space and jump out of local minima. This parameter can be adjusted to allow high or low amount of quantum fluctuation into the open system. A low fluctuation tends to provide a worse solution than a high fluctuation. Notice that, to maintain a good returned solution, this parameter should not reach too high in the same order as the signal photon. [Bédard, G. (1967). Analysis of Light Fluctuations from Photon Counting Statistics, J. Opt. Soc. Am., 57, 1201-1206.]
-
polynomial_file_id
: The unique identifier for the uploaded polynomial file, retrieved from the file response'sfile_id
. This ID links the job to the specific problem data.
By preparing the job_body
in this manner, you set up all necessary configurations and metadata required by the QCi API to process the sum-contrained continuous-optimization task on the Dirac-3 device.
In [ ]:
- # Build the job body to be submitted to the QCi API.
- # This is where the job type and the Dirac-3 device and its configuration are specified.
- job_body_cts_problem = client.build_job_body(
- job_type='sample-hamiltonian',
- job_name='test_continuous_variable_hamiltonian_job', # user-defined string, optional
- job_tags=['tag1', 'tag2'], # user-defined list of string identifiers, optional
- job_params={
- 'device_type': 'dirac-3',
- 'relaxation_schedule': 1,
- 'sum_constraint': 1,
- },
- polynomial_file_id=file_response_cts_problem['file_id'],
- )
- pprint(job_body_cts_problem)
- # This should output something similar to:
- # {'job_submission': {'device_config': {'dirac-3_normalized_qudit': {'relaxation_schedule': 1,
- # 'sum_constraint': 1}},
- # 'job_name': 'test_continuous_variable_hamiltonian_job',
- # 'job_tags': ['tag1', 'tag2'],
- # 'problem_config': {'normalized_qudit_hamiltonian_optimization': {'polynomial_file_id': '670ff2765e0855263226e283'}}}}
Submitting the Job to the API and Running It
In [ ]:
- # Submit the job and await the result.
- job_response_cts_problem = client.process_job(job_body=job_body_cts_problem)
- # Before inspecting solution, ensure that job did not error.
- assert job_response_cts_problem["status"] == JobStatus.COMPLETED.value
- # Only one sample taken.
- print(
- f"solution: {job_response_cts_problem['results']['solutions'][0]} with "
- f"energy: {job_response_cts_problem['results']['energies'][0]}"
- )
- # This should output something similar to:
- # 2024-05-15 10:59:49 - Dirac allocation balance = 600 s
- # 2024-05-15 10:59:49 - Job submitted: job_id='6644ea05d448b017e54f9663'
- # 2024-05-15 10:59:49 - QUEUED
- # 2024-05-15 10:59:52 - RUNNING
- # 2024-05-15 11:00:46 - COMPLETED
- # 2024-05-15 11:00:48 - Dirac allocation balance = 599 s
- # solution: 0.4174435, 0.5825538, 0, 0] with energy: 0.8749975
Inspecting Detailed Results
In [ ]:
- pprint(job_response_cts_problem)
- # This should output something similar to:
- # {'job_info': {'job_id': '6750b4b4324e163bf2d89395',
- # 'job_result': {'device_usage_s': 1,
- # 'file_id': '6750b4b65e08552632272819'},
- # 'job_status': {'completed_at_rfc3339nano': '2024-12-04T19:59:50.632Z',
- # 'queued_at_rfc3339nano': '2024-12-04T19:59:48.302Z',
- # 'running_at_rfc3339nano': '2024-12-04T19:59:48.679Z',
- # 'submitted_at_rfc3339nano': '2024-12-04T19:59:48.302Z'},
- # 'job_submission': {'device_config': {'dirac-3_normalized_qudit': {'num_samples': 1,
- # 'relaxation_schedule': 1,
- # 'sum_constraint': 1}},
- # 'job_name': 'test_continuous_variable_hamiltonian_job',
- # 'job_tags': ['tag1', 'tag2'],
- # 'problem_config': {'normalized_qudit_hamiltonian_optimization': {'polynomial_file_id': '6750b4ab5e08552632272817'}}}},
- # 'results': {'counts': [1],
- # 'energies': [0.8749975],
- # 'solutions': [[0.4174435, 0.5825538, 0, 0]]},
- # 'status': 'COMPLETED'}