classiq 0.40.0__py3-none-any.whl → 0.41.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +4 -2
- classiq/_internals/api_wrapper.py +3 -21
- classiq/applications/chemistry/chemistry_model_constructor.py +86 -100
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +6 -24
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +33 -45
- classiq/applications/combinatorial_optimization/__init__.py +2 -0
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +29 -26
- classiq/applications/finance/finance_model_constructor.py +23 -26
- classiq/applications/grover/grover_model_constructor.py +37 -38
- classiq/applications/qsvm/qsvm.py +1 -2
- classiq/applications/qsvm/qsvm_model_constructor.py +15 -16
- classiq/execution/__init__.py +4 -0
- classiq/execution/execution_session.py +151 -0
- classiq/execution/qnn.py +80 -0
- classiq/executor.py +2 -109
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +11 -0
- classiq/interface/applications/qsvm.py +0 -8
- classiq/interface/ast_node.py +12 -2
- classiq/interface/backend/backend_preferences.py +25 -1
- classiq/interface/backend/quantum_backend_providers.py +4 -4
- classiq/interface/executor/execution_preferences.py +4 -59
- classiq/interface/executor/execution_result.py +22 -1
- classiq/interface/generator/arith/arithmetic_expression_validator.py +0 -2
- classiq/interface/generator/arith/binary_ops.py +88 -25
- classiq/interface/generator/arith/unary_ops.py +28 -19
- classiq/interface/generator/expressions/atomic_expression_functions.py +6 -2
- classiq/interface/generator/expressions/enums/__init__.py +10 -0
- classiq/interface/generator/expressions/enums/classical_enum.py +5 -1
- classiq/interface/generator/expressions/expression.py +9 -2
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +7 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +0 -1
- classiq/interface/generator/expressions/sympy_supported_expressions.py +10 -1
- classiq/interface/generator/functions/builtins/internal_operators.py +7 -62
- classiq/interface/generator/functions/builtins/open_lib_functions.py +810 -2
- classiq/interface/generator/functions/classical_type.py +1 -3
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/model/bind_operation.py +3 -1
- classiq/interface/model/call_synthesis_data.py +2 -13
- classiq/interface/model/classical_if.py +3 -1
- classiq/interface/model/classical_parameter_declaration.py +13 -0
- classiq/interface/model/control.py +3 -101
- classiq/interface/model/inplace_binary_operation.py +3 -1
- classiq/interface/model/invert.py +3 -1
- classiq/interface/model/port_declaration.py +8 -1
- classiq/interface/model/power.py +3 -1
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +4 -2
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +11 -1
- classiq/interface/model/quantum_function_call.py +4 -10
- classiq/interface/model/quantum_function_declaration.py +26 -4
- classiq/interface/model/quantum_lambda_function.py +1 -20
- classiq/interface/model/quantum_statement.py +9 -2
- classiq/interface/model/repeat.py +3 -1
- classiq/interface/model/statement_block.py +19 -13
- classiq/interface/model/validations/handles_validator.py +8 -2
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +3 -1
- classiq/interface/server/routes.py +0 -5
- classiq/qmod/__init__.py +1 -2
- classiq/qmod/builtins/classical_execution_primitives.py +22 -2
- classiq/qmod/builtins/functions.py +51 -1
- classiq/qmod/builtins/operations.py +6 -36
- classiq/qmod/declaration_inferrer.py +8 -15
- classiq/qmod/native/__init__.py +9 -0
- classiq/qmod/native/expression_to_qmod.py +12 -9
- classiq/qmod/native/pretty_printer.py +4 -4
- classiq/qmod/pretty_print/__init__.py +9 -0
- classiq/qmod/pretty_print/expression_to_python.py +221 -0
- classiq/qmod/pretty_print/pretty_printer.py +421 -0
- classiq/qmod/qmod_parameter.py +7 -4
- classiq/qmod/quantum_callable.py +2 -1
- classiq/qmod/quantum_expandable.py +4 -3
- classiq/qmod/quantum_function.py +4 -16
- classiq/qmod/symbolic.py +1 -6
- classiq/synthesis.py +15 -16
- {classiq-0.40.0.dist-info → classiq-0.41.0.dist-info}/METADATA +5 -4
- {classiq-0.40.0.dist-info → classiq-0.41.0.dist-info}/RECORD +79 -76
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- {classiq-0.40.0.dist-info → classiq-0.41.0.dist-info}/WHEEL +0 -0
classiq/__init__.py
CHANGED
@@ -9,7 +9,8 @@ from classiq.interface.generator.arith.register_user_input import (
|
|
9
9
|
RegisterUserInput,
|
10
10
|
)
|
11
11
|
from classiq.interface.generator.control_state import ControlState
|
12
|
-
from classiq.interface.generator.expressions.enums
|
12
|
+
from classiq.interface.generator.expressions.enums import * # noqa: F403
|
13
|
+
from classiq.interface.generator.expressions.enums import __all__ as _enums_all
|
13
14
|
from classiq.interface.generator.functions import * # noqa: F403
|
14
15
|
from classiq.interface.generator.functions import __all__ as _ifunc_all
|
15
16
|
from classiq.interface.generator.model import * # noqa: F403
|
@@ -33,6 +34,7 @@ from classiq.applications.chemistry import (
|
|
33
34
|
molecule_problem_to_qmod,
|
34
35
|
)
|
35
36
|
from classiq.applications.combinatorial_optimization import (
|
37
|
+
compute_qaoa_initial_point,
|
36
38
|
construct_combinatorial_optimization_model,
|
37
39
|
pyo_model_to_hamiltonian,
|
38
40
|
)
|
@@ -95,13 +97,13 @@ __all__ = (
|
|
95
97
|
"set_execution_preferences",
|
96
98
|
"set_quantum_program_execution_preferences",
|
97
99
|
"show",
|
98
|
-
"Pauli",
|
99
100
|
]
|
100
101
|
+ _md_all
|
101
102
|
+ _ifunc_all
|
102
103
|
+ _sub_modules
|
103
104
|
+ _application_constructors_all
|
104
105
|
+ _qmod_all
|
106
|
+
+ _enums_all
|
105
107
|
)
|
106
108
|
|
107
109
|
|
@@ -12,7 +12,7 @@ from classiq.interface.execution.jobs import (
|
|
12
12
|
ExecutionJobDetailsV1,
|
13
13
|
ExecutionJobsQueryResultsV1,
|
14
14
|
)
|
15
|
-
from classiq.interface.executor import execution_request
|
15
|
+
from classiq.interface.executor import execution_request
|
16
16
|
from classiq.interface.generator import quantum_program as generator_result
|
17
17
|
from classiq.interface.hardware import HardwareInformation
|
18
18
|
from classiq.interface.jobs import (
|
@@ -22,7 +22,7 @@ from classiq.interface.jobs import (
|
|
22
22
|
JobID,
|
23
23
|
JSONObject,
|
24
24
|
)
|
25
|
-
from classiq.interface.model.
|
25
|
+
from classiq.interface.model.model import Model
|
26
26
|
from classiq.interface.server import routes
|
27
27
|
|
28
28
|
from classiq._internals.client import client
|
@@ -101,7 +101,7 @@ class ApiWrapper:
|
|
101
101
|
|
102
102
|
@classmethod
|
103
103
|
async def call_generation_task(
|
104
|
-
cls, model:
|
104
|
+
cls, model: Model
|
105
105
|
) -> generator_result.QuantumProgram:
|
106
106
|
poller = JobPoller(base_url=routes.TASKS_GENERATE_FULL_PATH)
|
107
107
|
result = await poller.run_pydantic(model, timeout_sec=None)
|
@@ -192,24 +192,6 @@ class ApiWrapper:
|
|
192
192
|
)
|
193
193
|
return ExecutionJobsQueryResultsV1.parse_obj(data)
|
194
194
|
|
195
|
-
@classmethod
|
196
|
-
async def call_execute_estimate(
|
197
|
-
cls, request: execution_request.ExecutionRequest
|
198
|
-
) -> execute_result.EstimationResults:
|
199
|
-
poller = JobPoller(base_url=routes.EXECUTE_ESTIMATE_FULL_PATH)
|
200
|
-
result = await poller.run_pydantic(request, timeout_sec=None)
|
201
|
-
return _parse_job_response(result, execute_result.EstimationResults)
|
202
|
-
|
203
|
-
@classmethod
|
204
|
-
async def call_execute_quantum_program(
|
205
|
-
cls, request: execution_request.ExecutionRequest
|
206
|
-
) -> execute_result.MultipleExecutionDetails:
|
207
|
-
poller = JobPoller(
|
208
|
-
base_url=routes.EXECUTE_QUANTUM_PROGRAM_FULL_PATH,
|
209
|
-
)
|
210
|
-
result = await poller.run_pydantic(request, timeout_sec=None)
|
211
|
-
return _parse_job_response(result, execute_result.MultipleExecutionDetails)
|
212
|
-
|
213
195
|
@classmethod
|
214
196
|
async def call_analysis_task(
|
215
197
|
cls, params: analysis_params.AnalysisParams
|
@@ -20,12 +20,14 @@ from classiq.interface.generator.expressions.expression import Expression
|
|
20
20
|
from classiq.interface.generator.function_params import IOName
|
21
21
|
from classiq.interface.generator.functions.classical_type import (
|
22
22
|
ClassicalArray,
|
23
|
-
ClassicalType,
|
24
23
|
Real,
|
25
24
|
)
|
26
25
|
from classiq.interface.generator.functions.port_declaration import (
|
27
26
|
PortDeclarationDirection,
|
28
27
|
)
|
28
|
+
from classiq.interface.model.classical_parameter_declaration import (
|
29
|
+
ClassicalParameterDeclaration,
|
30
|
+
)
|
29
31
|
from classiq.interface.model.handle_binding import HandleBinding
|
30
32
|
from classiq.interface.model.model import Model, SerializedModel
|
31
33
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
@@ -65,137 +67,120 @@ _MOLECULE_PROBLEM_RESULT = "molecule_result"
|
|
65
67
|
_HAE_GATE_MAPPING: Dict[str, QuantumFunctionCall] = {
|
66
68
|
"h": QuantumFunctionCall(
|
67
69
|
function="H",
|
68
|
-
|
70
|
+
positional_args=[HandleBinding(name="q")],
|
69
71
|
),
|
70
72
|
"x": QuantumFunctionCall(
|
71
73
|
function="X",
|
72
|
-
|
74
|
+
positional_args=[HandleBinding(name="q")],
|
73
75
|
),
|
74
76
|
"y": QuantumFunctionCall(
|
75
77
|
function="Y",
|
76
|
-
|
78
|
+
positional_args=[HandleBinding(name="q")],
|
77
79
|
),
|
78
80
|
"z": QuantumFunctionCall(
|
79
81
|
function="Z",
|
80
|
-
|
82
|
+
positional_args=[HandleBinding(name="q")],
|
81
83
|
),
|
82
84
|
"i": QuantumFunctionCall(
|
83
85
|
function="I",
|
84
|
-
|
86
|
+
positional_args=[HandleBinding(name="q")],
|
85
87
|
),
|
86
88
|
"s": QuantumFunctionCall(
|
87
89
|
function="S",
|
88
|
-
|
90
|
+
positional_args=[HandleBinding(name="q")],
|
89
91
|
),
|
90
92
|
"t": QuantumFunctionCall(
|
91
93
|
function="T",
|
92
|
-
|
94
|
+
positional_args=[HandleBinding(name="q")],
|
93
95
|
),
|
94
96
|
"sdg": QuantumFunctionCall(
|
95
97
|
function="SDG",
|
96
|
-
|
98
|
+
positional_args=[HandleBinding(name="q")],
|
97
99
|
),
|
98
100
|
"tdg": QuantumFunctionCall(
|
99
101
|
function="TDG",
|
100
|
-
|
102
|
+
positional_args=[HandleBinding(name="q")],
|
101
103
|
),
|
102
104
|
"p": QuantumFunctionCall(
|
103
105
|
function="PHASE",
|
104
|
-
|
106
|
+
positional_args=[HandleBinding(name="q")],
|
105
107
|
),
|
106
108
|
"rx": QuantumFunctionCall(
|
107
109
|
function="RX",
|
108
|
-
|
109
|
-
inouts={"target": HandleBinding(name="q")},
|
110
|
+
positional_args=[Expression(expr="angle"), HandleBinding(name="q")],
|
110
111
|
),
|
111
112
|
"ry": QuantumFunctionCall(
|
112
113
|
function="RY",
|
113
|
-
|
114
|
-
inouts={"target": HandleBinding(name="q")},
|
114
|
+
positional_args=[Expression(expr="angle"), HandleBinding(name="q")],
|
115
115
|
),
|
116
116
|
"rz": QuantumFunctionCall(
|
117
117
|
function="RZ",
|
118
|
-
|
119
|
-
inouts={"target": HandleBinding(name="q")},
|
118
|
+
positional_args=[Expression(expr="angle"), HandleBinding(name="q")],
|
120
119
|
),
|
121
120
|
"rxx": QuantumFunctionCall(
|
122
121
|
function="RXX",
|
123
|
-
|
124
|
-
inouts={"target": HandleBinding(name="q")},
|
122
|
+
positional_args=[Expression(expr="angle"), HandleBinding(name="q")],
|
125
123
|
),
|
126
124
|
"ryy": QuantumFunctionCall(
|
127
125
|
function="RYY",
|
128
|
-
|
129
|
-
inouts={"target": HandleBinding(name="q")},
|
126
|
+
positional_args=[Expression(expr="angle"), HandleBinding(name="q")],
|
130
127
|
),
|
131
128
|
"rzz": QuantumFunctionCall(
|
132
129
|
function="RZZ",
|
133
|
-
|
134
|
-
inouts={"target": HandleBinding(name="q")},
|
130
|
+
positional_args=[Expression(expr="angle"), HandleBinding(name="q")],
|
135
131
|
),
|
136
132
|
"ch": QuantumFunctionCall(
|
137
133
|
function="CH",
|
138
|
-
|
139
|
-
"target": HandleBinding(name="q1"),
|
140
|
-
"control": HandleBinding(name="q2"),
|
141
|
-
},
|
134
|
+
positional_args=[HandleBinding(name="q1"), HandleBinding(name="q2")],
|
142
135
|
),
|
143
136
|
"cx": QuantumFunctionCall(
|
144
137
|
function="CX",
|
145
|
-
|
146
|
-
"target": HandleBinding(name="q1"),
|
147
|
-
"control": HandleBinding(name="q2"),
|
148
|
-
},
|
138
|
+
positional_args=[HandleBinding(name="q1"), HandleBinding(name="q2")],
|
149
139
|
),
|
150
140
|
"cy": QuantumFunctionCall(
|
151
141
|
function="CY",
|
152
|
-
|
153
|
-
"target": HandleBinding(name="q1"),
|
154
|
-
"control": HandleBinding(name="q2"),
|
155
|
-
},
|
142
|
+
positional_args=[HandleBinding(name="q1"), HandleBinding(name="q2")],
|
156
143
|
),
|
157
144
|
"cz": QuantumFunctionCall(
|
158
145
|
function="CZ",
|
159
|
-
|
160
|
-
"target": HandleBinding(name="q1"),
|
161
|
-
"control": HandleBinding(name="q2"),
|
162
|
-
},
|
146
|
+
positional_args=[HandleBinding(name="q1"), HandleBinding(name="q2")],
|
163
147
|
),
|
164
148
|
"crx": QuantumFunctionCall(
|
165
149
|
function="CRX",
|
166
150
|
params={"theta": Expression(expr="angle")},
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
151
|
+
positional_args=[
|
152
|
+
Expression(expr="angle"),
|
153
|
+
HandleBinding(name="q1"),
|
154
|
+
HandleBinding(name="q2"),
|
155
|
+
],
|
171
156
|
),
|
172
157
|
"cry": QuantumFunctionCall(
|
173
158
|
function="CRY",
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
159
|
+
positional_args=[
|
160
|
+
Expression(expr="angle"),
|
161
|
+
HandleBinding(name="q1"),
|
162
|
+
HandleBinding(name="q2"),
|
163
|
+
],
|
179
164
|
),
|
180
165
|
"crz": QuantumFunctionCall(
|
181
166
|
function="CRZ",
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
167
|
+
positional_args=[
|
168
|
+
Expression(expr="angle"),
|
169
|
+
HandleBinding(name="q1"),
|
170
|
+
HandleBinding(name="q2"),
|
171
|
+
],
|
187
172
|
),
|
188
173
|
"cp": QuantumFunctionCall(
|
189
174
|
function="CPHASE",
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
175
|
+
positional_args=[
|
176
|
+
Expression(expr="angle"),
|
177
|
+
HandleBinding(name="q1"),
|
178
|
+
HandleBinding(name="q2"),
|
179
|
+
],
|
195
180
|
),
|
196
181
|
"swap": QuantumFunctionCall(
|
197
182
|
function="SWAP",
|
198
|
-
|
183
|
+
positional_args=[HandleBinding(name="q1"), HandleBinding(name="q2")],
|
199
184
|
),
|
200
185
|
}
|
201
186
|
|
@@ -297,18 +282,18 @@ def _get_chemistry_function(
|
|
297
282
|
chemistry_problem: CHEMISTRY_PROBLEMS_TYPE,
|
298
283
|
chemistry_function_name: str,
|
299
284
|
inouts: Mapping[IOName, HandleBinding],
|
300
|
-
ansatz_parameters_expressions: Optional[
|
285
|
+
ansatz_parameters_expressions: Optional[List[Expression]] = None,
|
301
286
|
) -> QuantumFunctionCall:
|
302
287
|
problem_prefix = _CHEMISTRY_PROBLEM_PREFIX_MAPPING[type(chemistry_problem)]
|
303
288
|
return QuantumFunctionCall(
|
304
289
|
function=f"{problem_prefix}_{chemistry_function_name}",
|
305
|
-
|
306
|
-
|
290
|
+
positional_args=[
|
291
|
+
Expression(
|
307
292
|
expr=_convert_library_problem_to_qmod_problem(chemistry_problem)
|
308
293
|
),
|
309
|
-
|
310
|
-
|
311
|
-
|
294
|
+
*(ansatz_parameters_expressions or []),
|
295
|
+
*inouts.values(),
|
296
|
+
],
|
312
297
|
)
|
313
298
|
|
314
299
|
|
@@ -325,28 +310,26 @@ def _get_hartree_fock(
|
|
325
310
|
def _get_hea_function(hea_parameters: HEAParameters) -> QuantumFunctionCall:
|
326
311
|
return QuantumFunctionCall(
|
327
312
|
function="full_hea",
|
328
|
-
|
329
|
-
|
330
|
-
|
313
|
+
positional_args=[
|
314
|
+
Expression(expr=f"{hea_parameters.num_qubits}"),
|
315
|
+
Expression(
|
331
316
|
expr=f"{[int(_is_parametric_gate(_HAE_GATE_MAPPING[gate])) for gate in hea_parameters.one_qubit_gates+hea_parameters.two_qubit_gates]}"
|
332
317
|
),
|
333
|
-
|
334
|
-
|
318
|
+
Expression(expr="t"),
|
319
|
+
Expression(
|
335
320
|
expr=f"{[list(connectivity_pair) for connectivity_pair in hea_parameters.connectivity_map]}"
|
336
321
|
),
|
337
|
-
|
338
|
-
|
339
|
-
operands={
|
340
|
-
"operands_1qubit": [
|
322
|
+
Expression(expr=f"{hea_parameters.reps}"),
|
323
|
+
[
|
341
324
|
QuantumLambdaFunction(body=[_HAE_GATE_MAPPING[gate]])
|
342
325
|
for gate in hea_parameters.one_qubit_gates
|
343
326
|
],
|
344
|
-
|
327
|
+
[
|
345
328
|
QuantumLambdaFunction(body=[_HAE_GATE_MAPPING[gate]])
|
346
329
|
for gate in hea_parameters.two_qubit_gates
|
347
330
|
],
|
348
|
-
|
349
|
-
|
331
|
+
HandleBinding(name="qbv"),
|
332
|
+
],
|
350
333
|
)
|
351
334
|
|
352
335
|
|
@@ -360,10 +343,10 @@ def _get_ansatz(
|
|
360
343
|
chemistry_problem,
|
361
344
|
_ANSATZ_PARAMETERS_FUNCTION_NAME_MAPPING[type(ansatz_parameters)],
|
362
345
|
{"qbv": HandleBinding(name="qbv")},
|
363
|
-
|
364
|
-
|
346
|
+
[
|
347
|
+
Expression(expr=str(param_value))
|
365
348
|
for param_name, param_value in ansatz_parameters.__dict__.items()
|
366
|
-
|
349
|
+
],
|
367
350
|
)
|
368
351
|
|
369
352
|
|
@@ -391,7 +374,9 @@ save({{{_MOLECULE_PROBLEM_RESULT!r}: {_MOLECULE_PROBLEM_RESULT}}})
|
|
391
374
|
|
392
375
|
|
393
376
|
def _is_parametric_gate(call: QuantumFunctionCall) -> bool:
|
394
|
-
return len(call.params) > 0
|
377
|
+
return len(call.params) > 0 or any(
|
378
|
+
isinstance(arg, Expression) for arg in call.positional_args
|
379
|
+
)
|
395
380
|
|
396
381
|
|
397
382
|
def _get_execution_result_post_processing_statements(
|
@@ -420,14 +405,18 @@ def _get_hea_port_size(hea_parameters: HEAParameters) -> int:
|
|
420
405
|
|
421
406
|
def _get_chemistry_quantum_main_params(
|
422
407
|
ansatz_parameters: AnsatzParameters,
|
423
|
-
) ->
|
408
|
+
) -> List[ClassicalParameterDeclaration]:
|
424
409
|
if not isinstance(ansatz_parameters, HEAParameters):
|
425
|
-
return
|
426
|
-
return
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
410
|
+
return []
|
411
|
+
return [
|
412
|
+
ClassicalParameterDeclaration(
|
413
|
+
name="t",
|
414
|
+
classical_type=ClassicalArray(
|
415
|
+
element_type=Real(),
|
416
|
+
size=_get_hea_port_size(ansatz_parameters),
|
417
|
+
),
|
418
|
+
),
|
419
|
+
]
|
431
420
|
|
432
421
|
|
433
422
|
def _get_problem_to_hamiltonian_name(chemistry_problem: CHEMISTRY_PROBLEMS_TYPE) -> str:
|
@@ -459,14 +448,10 @@ def _get_chemistry_quantum_main(
|
|
459
448
|
|
460
449
|
return NativeFunctionDefinition(
|
461
450
|
name="main",
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
name="qbv", direction=PortDeclarationDirection.Output
|
467
|
-
)
|
468
|
-
}
|
469
|
-
),
|
451
|
+
positional_arg_declarations=_get_chemistry_quantum_main_params(
|
452
|
+
ansatz_parameters
|
453
|
+
)
|
454
|
+
+ [PortDeclaration(name="qbv", direction=PortDeclarationDirection.Output)],
|
470
455
|
body=body,
|
471
456
|
)
|
472
457
|
|
@@ -476,14 +461,15 @@ def _get_chemistry_classical_code(
|
|
476
461
|
execution_parameters: ChemistryExecutionParameters,
|
477
462
|
) -> str:
|
478
463
|
qmod_problem = _convert_library_problem_to_qmod_problem(chemistry_problem)
|
479
|
-
return
|
464
|
+
return (
|
465
|
+
f"""
|
480
466
|
{_EXECUTION_RESULT} = vqe(
|
481
467
|
hamiltonian={_get_problem_to_hamiltonian_name(chemistry_problem)}({qmod_problem}), {_get_chemistry_vqe_additional_params(execution_parameters)}
|
482
468
|
)
|
483
469
|
save({{{_EXECUTION_RESULT!r}: {_EXECUTION_RESULT}}})
|
484
|
-
"""
|
485
|
-
chemistry_problem
|
486
|
-
)
|
470
|
+
"""
|
471
|
+
+ _get_execution_result_post_processing_statements(chemistry_problem)
|
472
|
+
).strip()
|
487
473
|
|
488
474
|
|
489
475
|
def construct_chemistry_model(
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import itertools
|
2
|
-
from typing import List, Union
|
2
|
+
from typing import List, Union
|
3
3
|
|
4
4
|
import numpy as np
|
5
5
|
import pyomo.environ as pyo
|
@@ -9,7 +9,6 @@ from classiq.interface.combinatorial_optimization.solver_types import QSolver
|
|
9
9
|
from classiq.interface.executor.vqe_result import VQESolverResult
|
10
10
|
from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
|
11
11
|
|
12
|
-
from classiq import Pauli
|
13
12
|
from classiq.applications.combinatorial_helpers.optimization_model import (
|
14
13
|
OptimizationModel,
|
15
14
|
)
|
@@ -17,7 +16,6 @@ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_sparsing imp
|
|
17
16
|
SparsePauliOp,
|
18
17
|
)
|
19
18
|
from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
|
20
|
-
get_pauli_operator,
|
21
19
|
pauli_operator_to_hamiltonian,
|
22
20
|
)
|
23
21
|
from classiq.applications.combinatorial_helpers.pyomo_utils import (
|
@@ -27,12 +25,12 @@ from classiq.qmod.builtins import PauliTerm
|
|
27
25
|
|
28
26
|
|
29
27
|
def compute_qaoa_initial_point(
|
30
|
-
hamiltonian: List[
|
28
|
+
hamiltonian: List[PauliTerm],
|
31
29
|
repetitions: int,
|
32
30
|
) -> List[float]:
|
33
|
-
coeffs_ising = [pauli_term
|
31
|
+
coeffs_ising = [pauli_term.coefficient for pauli_term in hamiltonian[1:]]
|
34
32
|
# the first coeff is the II...I term
|
35
|
-
coeffs_abs = np.abs(coeffs_ising)
|
33
|
+
coeffs_abs = np.abs(coeffs_ising) # type: ignore[arg-type]
|
36
34
|
coeffs_largest = np.sort(coeffs_abs)[len(coeffs_ising) // 2 :]
|
37
35
|
operator_norm = np.mean(coeffs_largest)
|
38
36
|
time_step = 1 / (2 * operator_norm) # adapted such that for MAXCUT time_step = 1
|
@@ -42,31 +40,15 @@ def compute_qaoa_initial_point(
|
|
42
40
|
return list(itertools.chain(*zip(gamma_params, beta_params)))
|
43
41
|
|
44
42
|
|
45
|
-
def
|
43
|
+
def pyo_model_to_hamiltonian(
|
46
44
|
pyo_model: pyo.ConcreteModel, penalty_energy: float
|
47
|
-
) -> List[
|
45
|
+
) -> List[PauliTerm]:
|
48
46
|
pauli_list = OptimizationModel(
|
49
47
|
pyo_model, penalty_energy=penalty_energy, qsolver=QSolver.QAOAPenalty
|
50
48
|
).ising.pauli_list
|
51
49
|
return pauli_operator_to_hamiltonian(pauli_list)
|
52
50
|
|
53
51
|
|
54
|
-
def pyo_model_to_hamiltonian(
|
55
|
-
pyo_model: pyo.ConcreteModel, penalty_energy: float
|
56
|
-
) -> List[PauliTerm]:
|
57
|
-
hamiltonian = _internal_pyo_model_to_hamiltonian(pyo_model, penalty_energy)
|
58
|
-
pauli_operator = get_pauli_operator(hamiltonian).pauli_list
|
59
|
-
pauli_terms = []
|
60
|
-
for item in pauli_operator:
|
61
|
-
term = PauliTerm(
|
62
|
-
[Pauli[p] for p in item[0]], # type:ignore[arg-type]
|
63
|
-
cast(complex, item[1]).real, # type:ignore[arg-type]
|
64
|
-
)
|
65
|
-
pauli_terms.append(term)
|
66
|
-
|
67
|
-
return pauli_terms
|
68
|
-
|
69
|
-
|
70
52
|
def _str_to_list_int(str_ints: str) -> List[int]:
|
71
53
|
return list(map(int, list(str_ints)))
|
72
54
|
|
@@ -1,65 +1,53 @@
|
|
1
|
-
from typing import List
|
1
|
+
from typing import List
|
2
2
|
|
3
|
-
from classiq.interface.chemistry.operator import PauliOperator
|
4
3
|
from classiq.interface.generator.expressions.enums.pauli import Pauli
|
5
4
|
from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
|
6
5
|
from classiq.interface.helpers.custom_pydantic_types import PydanticPauliList
|
7
6
|
|
8
|
-
from classiq.exceptions import
|
9
|
-
|
10
|
-
ClassiqNonNumericCoefficientInPauliError,
|
11
|
-
ClassiqValueError,
|
12
|
-
)
|
7
|
+
from classiq.exceptions import ClassiqNonNumericCoefficientInPauliError
|
8
|
+
from classiq.qmod.builtins import PauliTerm
|
13
9
|
|
14
10
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def pauli_integers_to_str(paulis: List[Pauli]) -> str:
|
20
|
-
return "".join([Pauli(pauli).name for pauli in paulis])
|
21
|
-
|
22
|
-
|
23
|
-
def pauli_operator_to_hamiltonian(pauli_list: PydanticPauliList) -> List[QmodPyStruct]:
|
24
|
-
pauli_struct_list: List[QmodPyStruct] = []
|
11
|
+
def pauli_operator_to_hamiltonian(pauli_list: PydanticPauliList) -> List[PauliTerm]:
|
12
|
+
pauli_terms: List[PauliTerm] = []
|
25
13
|
for pauli_term in pauli_list:
|
26
14
|
if not isinstance(pauli_term[1], complex) or pauli_term[1].imag != 0:
|
27
15
|
raise ClassiqNonNumericCoefficientInPauliError(
|
28
16
|
"Coefficient is not a number."
|
29
17
|
)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
"pauli": [Pauli[p] for p in pauli_term[0]],
|
34
|
-
"coefficient": pauli_term[1].real,
|
35
|
-
}
|
18
|
+
term = PauliTerm(
|
19
|
+
[Pauli[p] for p in pauli_term[0]], # type: ignore[arg-type]
|
20
|
+
pauli_term[1].real, # type: ignore[arg-type]
|
36
21
|
)
|
37
|
-
|
22
|
+
pauli_terms.append(term)
|
38
23
|
|
24
|
+
return pauli_terms
|
39
25
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
26
|
+
|
27
|
+
def pauli_enum_to_str(pauli: Pauli) -> str:
|
28
|
+
return {
|
29
|
+
Pauli.I: "Pauli.I",
|
30
|
+
Pauli.X: "Pauli.X",
|
31
|
+
Pauli.Y: "Pauli.Y",
|
32
|
+
Pauli.Z: "Pauli.Z",
|
33
|
+
}.get(pauli, "")
|
34
|
+
|
35
|
+
|
36
|
+
def _pauli_terms_to_qmod(hamiltonian: List[PauliTerm]) -> str:
|
37
|
+
qmod_strings = []
|
38
|
+
for term in hamiltonian:
|
39
|
+
pauli_str = ", ".join([pauli_enum_to_str(p) for p in term.pauli]) # type: ignore[attr-defined]
|
40
|
+
qmod_strings.append(
|
41
|
+
f"struct_literal(PauliTerm, pauli=[{pauli_str}], coefficient={term.coefficient})"
|
45
42
|
)
|
46
|
-
for elem in pauli_operator
|
47
|
-
]
|
48
43
|
|
49
|
-
|
50
|
-
pauli = PauliOperator(pauli_list=pauli_list)
|
51
|
-
except ValueError:
|
52
|
-
raise ClassiqExecutorInvalidHamiltonianError() from None
|
44
|
+
return ", ".join(qmod_strings)
|
53
45
|
|
54
|
-
return pauli
|
55
46
|
|
47
|
+
def _pauli_dict_to_str(hamiltonian: List[QmodPyStruct]) -> str:
|
48
|
+
res = []
|
49
|
+
for struct in hamiltonian:
|
50
|
+
pauli_str = ", ".join([pauli_enum_to_str(p) for p in struct["pauli"]])
|
51
|
+
res.append(f'"pauli": [{pauli_str}], "coefficient": {struct["coefficient"]}')
|
56
52
|
|
57
|
-
|
58
|
-
if not all(isinstance(summand[1], complex) for summand in hamiltonian.pauli_list):
|
59
|
-
raise ClassiqValueError(
|
60
|
-
"Supporting only Hamiltonian with numeric coefficients."
|
61
|
-
)
|
62
|
-
return ", ".join(
|
63
|
-
f"struct_literal(PauliTerm, pauli=[{_pauli_str_to_enums(pauli)}], coefficient={cast(complex, coeff).real})"
|
64
|
-
for pauli, coeff in hamiltonian.pauli_list
|
65
|
-
)
|
53
|
+
return f"{{{', '.join(res)}}}"
|
@@ -5,6 +5,7 @@ from classiq.interface.combinatorial_optimization.encoding_types import Encoding
|
|
5
5
|
from classiq.interface.combinatorial_optimization.solver_types import QSolver
|
6
6
|
|
7
7
|
from classiq.applications.combinatorial_helpers.combinatorial_problem_utils import (
|
8
|
+
compute_qaoa_initial_point,
|
8
9
|
get_optimization_solution_from_pyo,
|
9
10
|
pyo_model_to_hamiltonian,
|
10
11
|
)
|
@@ -23,6 +24,7 @@ __all__ = [
|
|
23
24
|
"examples",
|
24
25
|
"get_optimization_solution_from_pyo",
|
25
26
|
"pyo_model_to_hamiltonian",
|
27
|
+
"compute_qaoa_initial_point",
|
26
28
|
]
|
27
29
|
|
28
30
|
|