classiq 0.83.0__py3-none-any.whl → 0.85.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/_internals/api_wrapper.py +27 -0
- classiq/applications/chemistry/chemistry_model_constructor.py +0 -2
- classiq/applications/chemistry/hartree_fock.py +68 -0
- classiq/applications/chemistry/mapping.py +85 -0
- classiq/applications/chemistry/op_utils.py +79 -0
- classiq/applications/chemistry/problems.py +195 -0
- classiq/applications/chemistry/ucc.py +109 -0
- classiq/applications/chemistry/z2_symmetries.py +368 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +30 -1
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +20 -42
- classiq/{model_expansions/evaluators → evaluators}/arg_type_match.py +12 -4
- classiq/{model_expansions/evaluators → evaluators}/argument_types.py +1 -1
- classiq/evaluators/classical_expression.py +53 -0
- classiq/{model_expansions/evaluators → evaluators}/classical_type_inference.py +3 -4
- classiq/{model_expansions/evaluators → evaluators}/parameter_types.py +17 -15
- classiq/execution/__init__.py +12 -1
- classiq/execution/execution_session.py +238 -49
- classiq/execution/jobs.py +26 -1
- classiq/execution/qnn.py +2 -2
- classiq/execution/user_budgets.py +39 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/constants.py +1 -0
- classiq/interface/debug_info/debug_info.py +0 -4
- classiq/interface/execution/primitives.py +29 -1
- classiq/interface/executor/estimate_cost.py +35 -0
- classiq/interface/executor/execution_result.py +13 -0
- classiq/interface/executor/result.py +116 -1
- classiq/interface/executor/user_budget.py +26 -33
- classiq/interface/generator/expressions/atomic_expression_functions.py +10 -1
- classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +0 -6
- classiq/interface/generator/functions/builtins/internal_operators.py +2 -0
- classiq/interface/generator/functions/classical_type.py +2 -35
- classiq/interface/generator/functions/concrete_types.py +20 -3
- classiq/interface/generator/functions/type_modifier.py +0 -19
- classiq/interface/generator/generated_circuit_data.py +5 -18
- classiq/interface/generator/types/compilation_metadata.py +0 -3
- classiq/interface/ide/operation_registry.py +45 -0
- classiq/interface/ide/visual_model.py +68 -3
- classiq/interface/model/bounds.py +12 -2
- classiq/interface/model/model.py +12 -7
- classiq/interface/model/port_declaration.py +2 -24
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +7 -4
- classiq/interface/model/variable_declaration_statement.py +33 -6
- classiq/interface/pretty_print/__init__.py +0 -0
- classiq/{qmod/native → interface/pretty_print}/expression_to_qmod.py +18 -11
- classiq/interface/server/routes.py +4 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +47 -6
- classiq/model_expansions/function_builder.py +4 -1
- classiq/model_expansions/interpreters/base_interpreter.py +3 -3
- classiq/model_expansions/interpreters/generative_interpreter.py +16 -1
- classiq/model_expansions/quantum_operations/allocate.py +1 -1
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +64 -22
- classiq/model_expansions/quantum_operations/bind.py +2 -2
- classiq/model_expansions/quantum_operations/bounds.py +7 -1
- classiq/model_expansions/quantum_operations/call_emitter.py +26 -20
- classiq/model_expansions/quantum_operations/classical_var_emitter.py +16 -0
- classiq/model_expansions/quantum_operations/variable_decleration.py +31 -11
- classiq/model_expansions/scope.py +7 -0
- classiq/model_expansions/scope_initialization.py +3 -3
- classiq/model_expansions/transformers/model_renamer.py +6 -4
- classiq/model_expansions/transformers/type_modifier_inference.py +81 -43
- classiq/model_expansions/transformers/var_splitter.py +1 -1
- classiq/model_expansions/visitors/symbolic_param_inference.py +2 -3
- classiq/open_library/functions/__init__.py +3 -2
- classiq/open_library/functions/amplitude_amplification.py +10 -18
- classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
- classiq/open_library/functions/grover.py +14 -6
- classiq/open_library/functions/modular_exponentiation.py +22 -20
- classiq/open_library/functions/qaoa_penalty.py +8 -1
- classiq/open_library/functions/state_preparation.py +18 -32
- classiq/qmod/__init__.py +2 -0
- classiq/qmod/builtins/enums.py +23 -0
- classiq/qmod/builtins/functions/__init__.py +2 -0
- classiq/qmod/builtins/functions/exponentiation.py +32 -4
- classiq/qmod/builtins/operations.py +65 -1
- classiq/qmod/builtins/structs.py +55 -3
- classiq/qmod/classical_variable.py +74 -0
- classiq/qmod/declaration_inferrer.py +3 -2
- classiq/qmod/native/pretty_printer.py +20 -20
- classiq/qmod/pretty_print/expression_to_python.py +2 -1
- classiq/qmod/pretty_print/pretty_printer.py +35 -21
- classiq/qmod/python_classical_type.py +12 -5
- classiq/qmod/qfunc.py +2 -19
- classiq/qmod/qmod_constant.py +2 -5
- classiq/qmod/qmod_parameter.py +2 -5
- classiq/qmod/qmod_variable.py +61 -23
- classiq/qmod/quantum_expandable.py +5 -3
- classiq/qmod/quantum_function.py +49 -4
- classiq/qmod/semantics/annotation/qstruct_annotator.py +1 -1
- classiq/qmod/semantics/validation/main_validation.py +1 -9
- classiq/qmod/symbolic_type.py +2 -1
- classiq/qmod/utilities.py +0 -2
- classiq/qmod/write_qmod.py +1 -1
- {classiq-0.83.0.dist-info → classiq-0.85.0.dist-info}/METADATA +4 -1
- {classiq-0.83.0.dist-info → classiq-0.85.0.dist-info}/RECORD +101 -90
- classiq/interface/model/quantum_variable_declaration.py +0 -7
- classiq/model_expansions/evaluators/classical_expression.py +0 -36
- /classiq/{model_expansions/evaluators → evaluators}/__init__.py +0 -0
- /classiq/{model_expansions/evaluators → evaluators}/control.py +0 -0
- /classiq/{model_expansions → evaluators}/expression_evaluator.py +0 -0
- /classiq/{model_expansions/evaluators → evaluators}/quantum_type_utils.py +0 -0
- /classiq/{model_expansions/evaluators → evaluators}/type_type_match.py +0 -0
- {classiq-0.83.0.dist-info → classiq-0.85.0.dist-info}/WHEEL +0 -0
@@ -4,6 +4,7 @@ import itertools
|
|
4
4
|
import warnings
|
5
5
|
from collections.abc import Collection, Iterator, Sequence
|
6
6
|
from contextlib import contextmanager
|
7
|
+
from typing import Optional, Union
|
7
8
|
|
8
9
|
from classiq.interface.exceptions import (
|
9
10
|
ClassiqDeprecationWarning,
|
@@ -18,6 +19,7 @@ from classiq.interface.model.bind_operation import BindOperation
|
|
18
19
|
from classiq.interface.model.control import Control
|
19
20
|
from classiq.interface.model.invert import Invert
|
20
21
|
from classiq.interface.model.model_visitor import ModelVisitor
|
22
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
21
23
|
from classiq.interface.model.phase_operation import PhaseOperation
|
22
24
|
from classiq.interface.model.port_declaration import PortDeclaration
|
23
25
|
from classiq.interface.model.power import Power
|
@@ -31,34 +33,43 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
31
33
|
QuantumExpressionOperation,
|
32
34
|
)
|
33
35
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
34
|
-
from classiq.interface.model.quantum_statement import QuantumStatement
|
35
36
|
from classiq.interface.model.within_apply_operation import WithinApply
|
37
|
+
from classiq.interface.source_reference import SourceReference
|
36
38
|
|
37
39
|
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
38
40
|
|
39
41
|
|
40
42
|
def _inconsistent_type_modifier_error(
|
41
|
-
port_name: str,
|
43
|
+
port_name: str,
|
44
|
+
expected: TypeModifier,
|
45
|
+
actual: TypeModifier,
|
46
|
+
source_ref: Optional[Union[SourceReference, str]] = None,
|
42
47
|
) -> str:
|
48
|
+
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
43
49
|
return (
|
44
|
-
f"The
|
50
|
+
f"The use of variable '{port_name}' does not conform to its declared modifier: "
|
45
51
|
f"expected '{expected.name}', but found '{actual.name}'.\n"
|
46
|
-
f"Tip: If the
|
47
|
-
f"
|
48
|
-
|
52
|
+
f"Tip: If the cumulative use of the variable in the function matches '{expected.name}', "
|
53
|
+
f"use the `unchecked` flag to instruct the compiler to disregard individual operations."
|
54
|
+
f"{source_ref_str}\n"
|
55
|
+
"The deprecation warning will be elevated to an error starting July 23, 2025, at the earliest."
|
49
56
|
)
|
50
57
|
|
51
58
|
|
52
59
|
def _inconsistent_type_modifier_in_binding_error(
|
53
|
-
expected: TypeModifier,
|
60
|
+
expected: TypeModifier,
|
61
|
+
known_modifiers: dict[str, TypeModifier],
|
62
|
+
source_ref: Optional[Union[SourceReference, str]] = None,
|
54
63
|
) -> str:
|
55
64
|
actual = ", ".join(
|
56
65
|
f"{name}: {modifier.name}" for name, modifier in known_modifiers.items()
|
57
66
|
)
|
67
|
+
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
58
68
|
return (
|
59
|
-
f"
|
69
|
+
f"Inconsistent modifiers in variable binding: "
|
60
70
|
f"Expected modifier: {expected.name}, Actual modifiers: {actual}"
|
61
|
-
|
71
|
+
f"{source_ref_str}\n"
|
72
|
+
"The deprecation warning will be elevated to an error starting July 23, 2025, at the earliest."
|
62
73
|
)
|
63
74
|
|
64
75
|
|
@@ -85,6 +96,7 @@ class TypeModifierValidation(ModelVisitor):
|
|
85
96
|
support_unused_ports # could be turned off for debugging
|
86
97
|
)
|
87
98
|
self._skip_validation = skip_validation
|
99
|
+
self._source_ref: Optional[Union[SourceReference, str]] = None
|
88
100
|
|
89
101
|
@contextmanager
|
90
102
|
def validate_ports(
|
@@ -119,6 +131,17 @@ class TypeModifierValidation(ModelVisitor):
|
|
119
131
|
finally:
|
120
132
|
self._conjugation_context = previous_context
|
121
133
|
|
134
|
+
@contextmanager
|
135
|
+
def source_reference_context(
|
136
|
+
self, source_ref: Optional[Union[SourceReference, str]]
|
137
|
+
) -> Iterator[None]:
|
138
|
+
previous_source_ref = self._source_ref
|
139
|
+
self._source_ref = source_ref
|
140
|
+
try:
|
141
|
+
yield
|
142
|
+
finally:
|
143
|
+
self._source_ref = previous_source_ref
|
144
|
+
|
122
145
|
def _set_unused_as_const(self) -> None:
|
123
146
|
unresolved_ports = [
|
124
147
|
port
|
@@ -161,7 +184,7 @@ class TypeModifierValidation(ModelVisitor):
|
|
161
184
|
if signature_modifier is not TypeModifier.and_(signature_modifier, modifier):
|
162
185
|
warnings.warn(
|
163
186
|
_inconsistent_type_modifier_error(
|
164
|
-
candidate, signature_modifier, modifier
|
187
|
+
candidate, signature_modifier, modifier, self._source_ref
|
165
188
|
),
|
166
189
|
ClassiqDeprecationWarning,
|
167
190
|
stacklevel=1,
|
@@ -176,13 +199,17 @@ class TypeModifierValidation(ModelVisitor):
|
|
176
199
|
|
177
200
|
def run(
|
178
201
|
self,
|
179
|
-
|
180
|
-
body: Sequence[QuantumStatement],
|
202
|
+
func_def: NativeFunctionDefinition,
|
181
203
|
unchecked: Collection[str],
|
182
204
|
) -> None:
|
183
|
-
with
|
205
|
+
with (
|
206
|
+
self.validate_ports(
|
207
|
+
func_def.port_declarations, unchecked
|
208
|
+
) as should_validate,
|
209
|
+
self.source_reference_context(f"function '{func_def.name}'"),
|
210
|
+
):
|
184
211
|
if should_validate:
|
185
|
-
self.visit(body)
|
212
|
+
self.visit(func_def.body)
|
186
213
|
self._update_bound_vars()
|
187
214
|
|
188
215
|
def _update_bound_vars(self) -> None:
|
@@ -193,16 +220,18 @@ class TypeModifierValidation(ModelVisitor):
|
|
193
220
|
self._validate_modifier(var, reduced_modifier)
|
194
221
|
|
195
222
|
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
223
|
+
with self.source_reference_context(call.source_ref):
|
224
|
+
for handle, port in call.handles_with_params:
|
225
|
+
self._validate_modifier(handle.name, port.type_modifier)
|
226
|
+
if port.direction is PortDeclarationDirection.Output:
|
227
|
+
self._add_initialized_modifier(handle.name, port.type_modifier)
|
200
228
|
|
201
229
|
if self._has_inputs(call):
|
202
230
|
bound_vars = {
|
203
231
|
handle.name
|
204
232
|
for handle, port in call.handles_with_params
|
205
233
|
if port.direction is not PortDeclarationDirection.Inout
|
234
|
+
and handle.name not in self._unchecked
|
206
235
|
}
|
207
236
|
self._bound_vars.append(bound_vars)
|
208
237
|
|
@@ -214,13 +243,15 @@ class TypeModifierValidation(ModelVisitor):
|
|
214
243
|
)
|
215
244
|
|
216
245
|
def visit_Allocate(self, alloc: Allocate) -> None:
|
217
|
-
self.
|
218
|
-
|
246
|
+
with self.source_reference_context(alloc.source_ref):
|
247
|
+
self._validate_modifier(alloc.target.name, TypeModifier.Permutable)
|
248
|
+
self._add_initialized_modifier(alloc.target.name, TypeModifier.Permutable)
|
219
249
|
|
220
250
|
def visit_BindOperation(self, bind_op: BindOperation) -> None:
|
221
251
|
var_names = {
|
222
252
|
handle.name
|
223
253
|
for handle in itertools.chain(bind_op.in_handles, bind_op.out_handles)
|
254
|
+
if handle.name not in self._unchecked
|
224
255
|
}
|
225
256
|
self._bound_vars.append(var_names)
|
226
257
|
for handle in bind_op.out_handles:
|
@@ -251,7 +282,7 @@ class TypeModifierValidation(ModelVisitor):
|
|
251
282
|
):
|
252
283
|
warnings.warn(
|
253
284
|
_inconsistent_type_modifier_in_binding_error(
|
254
|
-
min_modifier, known_modifiers
|
285
|
+
min_modifier, known_modifiers, self._source_ref
|
255
286
|
),
|
256
287
|
ClassiqDeprecationWarning,
|
257
288
|
stacklevel=1,
|
@@ -277,42 +308,49 @@ class TypeModifierValidation(ModelVisitor):
|
|
277
308
|
return [handle.name for handle in vrc.var_handles]
|
278
309
|
|
279
310
|
def visit_ArithmeticOperation(self, arith: ArithmeticOperation) -> None:
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
self.
|
284
|
-
|
285
|
-
|
311
|
+
with self.source_reference_context(arith.source_ref):
|
312
|
+
result_var = arith.result_var.name
|
313
|
+
self._validate_modifier(result_var, TypeModifier.Permutable)
|
314
|
+
for expr_var in self._extract_expr_vars(arith):
|
315
|
+
self._validate_modifier(expr_var, TypeModifier.Const)
|
316
|
+
if not arith.is_inplace:
|
317
|
+
self._add_initialized_modifier(result_var, TypeModifier.Permutable)
|
286
318
|
|
287
319
|
def visit_AmplitudeLoadingOperation(
|
288
320
|
self, amp_load: AmplitudeLoadingOperation
|
289
321
|
) -> None:
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
self.
|
322
|
+
with self.source_reference_context(amp_load.source_ref):
|
323
|
+
result_var = amp_load.result_var.name
|
324
|
+
self._validate_modifier(result_var, TypeModifier.Mutable)
|
325
|
+
for expr_var in self._extract_expr_vars(amp_load):
|
326
|
+
self._validate_modifier(expr_var, TypeModifier.Const)
|
294
327
|
|
295
328
|
def visit_PhaseOperation(self, phase_op: PhaseOperation) -> None:
|
296
|
-
|
297
|
-
self.
|
329
|
+
with self.source_reference_context(phase_op.source_ref):
|
330
|
+
for expr_var in self._extract_expr_vars(phase_op):
|
331
|
+
self._validate_modifier(expr_var, TypeModifier.Const)
|
298
332
|
|
299
333
|
def visit_Control(self, control: Control) -> None:
|
300
|
-
|
301
|
-
self.
|
302
|
-
|
303
|
-
|
304
|
-
|
334
|
+
with self.source_reference_context(control.source_ref):
|
335
|
+
for control_var in self._extract_expr_vars(control):
|
336
|
+
self._validate_modifier(control_var, TypeModifier.Const)
|
337
|
+
self.visit(control.body)
|
338
|
+
if control.else_block is not None:
|
339
|
+
self.visit(control.else_block)
|
305
340
|
|
306
341
|
def visit_Invert(self, invert: Invert) -> None:
|
307
|
-
self.
|
342
|
+
with self.source_reference_context(invert.source_ref):
|
343
|
+
self.visit(invert.body)
|
308
344
|
|
309
345
|
def visit_Power(self, power: Power) -> None:
|
310
|
-
self.
|
346
|
+
with self.source_reference_context(power.source_ref):
|
347
|
+
self.visit(power.body)
|
311
348
|
|
312
349
|
def visit_WithinApply(self, within_apply: WithinApply) -> None:
|
313
|
-
with self.
|
314
|
-
self.
|
315
|
-
|
350
|
+
with self.source_reference_context(within_apply.source_ref):
|
351
|
+
with self.conjugation_context():
|
352
|
+
self.visit(within_apply.compute)
|
353
|
+
self.visit(within_apply.action)
|
316
354
|
|
317
355
|
|
318
356
|
def _merge_overlapping(bound_vars: Sequence[Collection[str]]) -> list[set[str]]:
|
@@ -218,7 +218,7 @@ class VarSplitter(ModelRenamer):
|
|
218
218
|
return [
|
219
219
|
VariableDeclarationStatement(
|
220
220
|
name=part.target_var_name,
|
221
|
-
|
221
|
+
qmod_type=part.target_var_type,
|
222
222
|
)
|
223
223
|
for part in chain.from_iterable(symbol_parts.values())
|
224
224
|
]
|
@@ -10,7 +10,6 @@ from classiq.interface.generator.expressions.atomic_expression_functions import
|
|
10
10
|
from classiq.interface.generator.expressions.expression import Expression
|
11
11
|
from classiq.interface.generator.functions.classical_type import (
|
12
12
|
ClassicalArray,
|
13
|
-
ClassicalList,
|
14
13
|
ClassicalTuple,
|
15
14
|
ClassicalType,
|
16
15
|
)
|
@@ -53,7 +52,7 @@ def set_generative_recursively(classical_type: ClassicalType) -> None:
|
|
53
52
|
set_generative_recursively(field_type)
|
54
53
|
return
|
55
54
|
classical_type.set_generative()
|
56
|
-
if isinstance(classical_type,
|
55
|
+
if isinstance(classical_type, ClassicalArray):
|
57
56
|
set_generative_recursively(classical_type.element_type)
|
58
57
|
if isinstance(classical_type, ClassicalTuple):
|
59
58
|
for element_type in classical_type.element_types:
|
@@ -155,7 +154,7 @@ class SymbolicParamInference(ModelVisitor):
|
|
155
154
|
for param, arg in zip_longest(params, call.positional_args):
|
156
155
|
if (
|
157
156
|
not isinstance(param, AnonClassicalParameterDeclaration)
|
158
|
-
or param.classical_type.
|
157
|
+
or not param.classical_type.is_purely_declarative
|
159
158
|
):
|
160
159
|
self._process_compile_time_expressions(arg)
|
161
160
|
else:
|
@@ -6,6 +6,7 @@ from .amplitude_estimation import *
|
|
6
6
|
from .discrete_sine_cosine_transform import *
|
7
7
|
from .discrete_sine_cosine_transform import _qct_d_operator, _qct_pi_operator
|
8
8
|
from .grover import *
|
9
|
+
from .grover import _cond_phase_flip
|
9
10
|
from .hea import *
|
10
11
|
from .linear_pauli_rotation import *
|
11
12
|
from .linear_pauli_rotation import _single_pauli
|
@@ -51,7 +52,6 @@ OPEN_LIBRARY_FUNCTIONS = [
|
|
51
52
|
qsvt_inversion,
|
52
53
|
qsvt_lcu,
|
53
54
|
qsvt_lcu_step,
|
54
|
-
allocate_num,
|
55
55
|
qaoa_mixer_layer,
|
56
56
|
qaoa_cost_layer,
|
57
57
|
qaoa_layer,
|
@@ -79,11 +79,11 @@ OPEN_LIBRARY_FUNCTIONS = [
|
|
79
79
|
_check_msb,
|
80
80
|
encode_in_angle,
|
81
81
|
encode_on_bloch,
|
82
|
+
_cond_phase_flip,
|
82
83
|
]
|
83
84
|
|
84
85
|
__all__ = [
|
85
86
|
"_single_pauli",
|
86
|
-
"allocate_num",
|
87
87
|
"amplitude_amplification",
|
88
88
|
"amplitude_estimation",
|
89
89
|
"apply_to_all",
|
@@ -105,6 +105,7 @@ __all__ = [
|
|
105
105
|
"modular_increment",
|
106
106
|
"multiswap",
|
107
107
|
"phase_oracle",
|
108
|
+
"prepare_basis_state",
|
108
109
|
"prepare_bell_state",
|
109
110
|
"prepare_complex_amplitudes",
|
110
111
|
"prepare_dicke_state",
|
@@ -1,11 +1,10 @@
|
|
1
1
|
from classiq.open_library.functions.grover import grover_operator
|
2
|
+
from classiq.qmod.builtins.functions.allocation import free
|
2
3
|
from classiq.qmod.builtins.functions.standard_gates import RY
|
3
4
|
from classiq.qmod.builtins.operations import (
|
4
5
|
allocate,
|
5
|
-
bind,
|
6
6
|
control,
|
7
7
|
power,
|
8
|
-
within_apply,
|
9
8
|
)
|
10
9
|
from classiq.qmod.cparam import CInt, CReal
|
11
10
|
from classiq.qmod.qfunc import qfunc
|
@@ -71,21 +70,14 @@ def exact_amplitude_amplification(
|
|
71
70
|
theta = pi / (4 * k + 2)
|
72
71
|
rot_phase = 2 * acos(sin(theta) / amplitude)
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
73
|
+
allocate(aux)
|
74
|
+
amplitude_amplification(
|
75
|
+
k,
|
76
|
+
lambda qvars_: control(qvars_[0] == 0, lambda: oracle(qvars_[1 : qvars_.size])),
|
77
|
+
lambda qvars_: [
|
78
|
+
space_transform(qvars_[1 : qvars_.size]),
|
79
|
+
RY(rot_phase, qvars_[0]),
|
79
80
|
],
|
80
|
-
|
81
|
-
k,
|
82
|
-
lambda qvars_: control(
|
83
|
-
qvars_[0] == 0, lambda: oracle(qvars_[1 : qvars_.size])
|
84
|
-
),
|
85
|
-
lambda qvars_: [
|
86
|
-
space_transform(qvars_[1 : qvars_.size]),
|
87
|
-
RY(rot_phase, qvars_[0]),
|
88
|
-
],
|
89
|
-
extended_qvars,
|
90
|
-
),
|
81
|
+
[aux, packed_qvars],
|
91
82
|
)
|
83
|
+
free(aux)
|
@@ -11,7 +11,7 @@ from classiq.qmod.builtins.operations import (
|
|
11
11
|
within_apply,
|
12
12
|
)
|
13
13
|
from classiq.qmod.qfunc import qfunc
|
14
|
-
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
14
|
+
from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit, QNum
|
15
15
|
from classiq.qmod.symbolic import pi
|
16
16
|
|
17
17
|
|
@@ -21,13 +21,13 @@ def _b_operator(q: QBit) -> None:
|
|
21
21
|
|
22
22
|
|
23
23
|
@qfunc
|
24
|
-
def _qct_d_operator(x: QNum, q: QBit) -> None:
|
24
|
+
def _qct_d_operator(x: Const[QNum], q: QBit) -> None:
|
25
25
|
_b_operator(q)
|
26
26
|
control(x == 0, lambda: invert(lambda: _b_operator(q)))
|
27
27
|
|
28
28
|
|
29
29
|
@qfunc
|
30
|
-
def _qct_pi_operator(x: QArray[QBit], q: QBit) -> None:
|
30
|
+
def _qct_pi_operator(x: Permutable[QArray[QBit]], q: Const[QBit]) -> None:
|
31
31
|
control(
|
32
32
|
q == 1,
|
33
33
|
lambda: [
|
@@ -120,8 +120,8 @@ def qct_qst_type1(x: QArray[QBit]) -> None:
|
|
120
120
|
within_apply(lambda: _t_operator(x), lambda: qft(x))
|
121
121
|
|
122
122
|
|
123
|
-
@qfunc
|
124
|
-
def qct_qst_type2(x: QArray[QBit], q: QBit) -> None:
|
123
|
+
@qfunc(unchecked=["q"])
|
124
|
+
def qct_qst_type2(x: QArray[QBit], q: Const[QBit]) -> None:
|
125
125
|
"""
|
126
126
|
[Qmod Classiq-library function]
|
127
127
|
|
@@ -10,14 +10,22 @@ from classiq.qmod.builtins.operations import (
|
|
10
10
|
)
|
11
11
|
from classiq.qmod.qfunc import qfunc
|
12
12
|
from classiq.qmod.qmod_parameter import CInt
|
13
|
-
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
13
|
+
from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit, QNum
|
14
14
|
from classiq.qmod.quantum_callable import QCallable
|
15
15
|
from classiq.qmod.symbolic import pi
|
16
16
|
|
17
17
|
|
18
|
+
@qfunc(unchecked=["target"])
|
19
|
+
def _cond_phase_flip(
|
20
|
+
predicate: QCallable[Permutable[QBit]], target: Const[QBit]
|
21
|
+
) -> None:
|
22
|
+
within_apply(lambda: H(target), lambda: predicate(target))
|
23
|
+
|
24
|
+
|
18
25
|
@qfunc
|
19
26
|
def phase_oracle(
|
20
|
-
predicate: QCallable[QArray[QBit]
|
27
|
+
predicate: QCallable[Const[QArray[QBit]], Permutable[QBit]],
|
28
|
+
target: Const[QArray[QBit]],
|
21
29
|
) -> None:
|
22
30
|
"""
|
23
31
|
[Qmod Classiq-library function]
|
@@ -42,13 +50,13 @@ def phase_oracle(
|
|
42
50
|
"""
|
43
51
|
aux = QBit()
|
44
52
|
within_apply(
|
45
|
-
|
46
|
-
|
53
|
+
lambda: [allocate(aux), X(aux)],
|
54
|
+
lambda: _cond_phase_flip(lambda x: predicate(target, x), aux),
|
47
55
|
)
|
48
56
|
|
49
57
|
|
50
|
-
@qfunc
|
51
|
-
def reflect_about_zero(packed_vars: QArray[QBit]) -> None:
|
58
|
+
@qfunc(unchecked=["packed_vars"])
|
59
|
+
def reflect_about_zero(packed_vars: Const[QArray[QBit]]) -> None:
|
52
60
|
"""
|
53
61
|
[Qmod Classiq-library function]
|
54
62
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from classiq.open_library.functions.qft_functions import qft, qft_no_swap
|
2
2
|
from classiq.qmod.builtins.classical_functions import qft_const_adder_phase
|
3
|
+
from classiq.qmod.builtins.functions.allocation import free
|
3
4
|
from classiq.qmod.builtins.functions.standard_gates import PHASE, SWAP, X
|
4
5
|
from classiq.qmod.builtins.operations import (
|
5
6
|
allocate,
|
@@ -11,7 +12,7 @@ from classiq.qmod.builtins.operations import (
|
|
11
12
|
)
|
12
13
|
from classiq.qmod.cparam import CInt
|
13
14
|
from classiq.qmod.qfunc import qfunc
|
14
|
-
from classiq.qmod.qmod_variable import QArray, QBit
|
15
|
+
from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit
|
15
16
|
from classiq.qmod.symbolic import min, mod_inverse
|
16
17
|
|
17
18
|
|
@@ -50,8 +51,10 @@ def qft_space_add_const(value: CInt, phi_b: QArray[QBit]) -> None:
|
|
50
51
|
)
|
51
52
|
|
52
53
|
|
53
|
-
@qfunc
|
54
|
-
def cc_modular_add(
|
54
|
+
@qfunc(unchecked=["phi_b"])
|
55
|
+
def cc_modular_add(
|
56
|
+
n: CInt, a: CInt, phi_b: Permutable[QArray[QBit]], c1: Const[QBit], c2: Const[QBit]
|
57
|
+
) -> None:
|
55
58
|
"""
|
56
59
|
[Qmod Classiq-library function]
|
57
60
|
|
@@ -69,11 +72,9 @@ def cc_modular_add(n: CInt, a: CInt, phi_b: QArray[QBit], c1: QBit, c2: QBit) ->
|
|
69
72
|
ctrl: QArray[QBit] = QArray()
|
70
73
|
aux = QBit()
|
71
74
|
|
75
|
+
allocate(aux)
|
72
76
|
within_apply(
|
73
|
-
lambda: (
|
74
|
-
allocate(aux),
|
75
|
-
bind([c1, c2], ctrl),
|
76
|
-
),
|
77
|
+
lambda: bind([c1, c2], ctrl),
|
77
78
|
lambda: (
|
78
79
|
control(ctrl, lambda: qft_space_add_const(a, phi_b)),
|
79
80
|
invert(lambda: qft_space_add_const(n, phi_b)),
|
@@ -87,11 +88,16 @@ def cc_modular_add(n: CInt, a: CInt, phi_b: QArray[QBit], c1: QBit, c2: QBit) ->
|
|
87
88
|
),
|
88
89
|
),
|
89
90
|
)
|
91
|
+
free(aux)
|
90
92
|
|
91
93
|
|
92
|
-
@qfunc
|
94
|
+
@qfunc(unchecked=["b"])
|
93
95
|
def c_modular_multiply(
|
94
|
-
n: CInt,
|
96
|
+
n: CInt,
|
97
|
+
a: CInt,
|
98
|
+
b: Permutable[QArray[QBit]],
|
99
|
+
x: Const[QArray[QBit]],
|
100
|
+
ctrl: Const[QBit],
|
95
101
|
) -> None:
|
96
102
|
"""
|
97
103
|
[Qmod Classiq-library function]
|
@@ -118,7 +124,7 @@ def c_modular_multiply(
|
|
118
124
|
|
119
125
|
|
120
126
|
@qfunc
|
121
|
-
def multiswap(x: QArray[QBit], y: QArray[QBit]) -> None:
|
127
|
+
def multiswap(x: Permutable[QArray[QBit]], y: Permutable[QArray[QBit]]) -> None:
|
122
128
|
"""
|
123
129
|
[Qmod Classiq-library function]
|
124
130
|
|
@@ -150,16 +156,12 @@ def inplace_c_modular_multiply(n: CInt, a: CInt, x: QArray[QBit], ctrl: QBit) ->
|
|
150
156
|
x: The quantum factor.
|
151
157
|
ctrl: The control bit.
|
152
158
|
"""
|
153
|
-
b: QArray[QBit] = QArray()
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
control(ctrl, lambda: multiswap(x, b)),
|
160
|
-
invert(lambda: c_modular_multiply(n, mod_inverse(a, n), b, x, ctrl)),
|
161
|
-
),
|
162
|
-
)
|
159
|
+
b: QArray[QBit] = QArray(length=x.len + 1)
|
160
|
+
allocate(b)
|
161
|
+
c_modular_multiply(n, a, b, x, ctrl)
|
162
|
+
control(ctrl, lambda: multiswap(x, b))
|
163
|
+
invert(lambda: c_modular_multiply(n, mod_inverse(a, n), b, x, ctrl))
|
164
|
+
free(b)
|
163
165
|
|
164
166
|
|
165
167
|
@qfunc
|
@@ -1,5 +1,8 @@
|
|
1
|
+
import warnings
|
1
2
|
from typing import Literal
|
2
3
|
|
4
|
+
from classiq.interface.exceptions import ClassiqDeprecationWarning
|
5
|
+
|
3
6
|
from classiq.qmod.builtins.functions import RX, H, suzuki_trotter
|
4
7
|
from classiq.qmod.builtins.operations import repeat
|
5
8
|
from classiq.qmod.builtins.structs import PauliTerm
|
@@ -42,7 +45,11 @@ def qaoa_cost_layer(
|
|
42
45
|
hamiltonian: The Hamiltonian terms for the QAOA model.
|
43
46
|
target: The target quantum array variable.
|
44
47
|
"""
|
45
|
-
|
48
|
+
with warnings.catch_warnings(): # FIXME: Remove (CLS-2912)
|
49
|
+
warnings.simplefilter(
|
50
|
+
"ignore", category=ClassiqDeprecationWarning
|
51
|
+
) # FIXME: Remove (CLS-2912)
|
52
|
+
suzuki_trotter(hamiltonian, g, 1, 1, target)
|
46
53
|
|
47
54
|
|
48
55
|
@qfunc
|
@@ -27,7 +27,7 @@ from classiq.qmod.builtins.operations import (
|
|
27
27
|
repeat,
|
28
28
|
within_apply,
|
29
29
|
)
|
30
|
-
from classiq.qmod.cparam import CArray,
|
30
|
+
from classiq.qmod.cparam import CArray, CInt, CReal
|
31
31
|
from classiq.qmod.qfunc import qfunc
|
32
32
|
from classiq.qmod.qmod_variable import Output, QArray, QBit, QNum
|
33
33
|
from classiq.qmod.symbolic import (
|
@@ -45,37 +45,6 @@ from classiq.qmod.symbolic import (
|
|
45
45
|
)
|
46
46
|
|
47
47
|
|
48
|
-
@qfunc
|
49
|
-
def allocate_num(
|
50
|
-
num_qubits: CInt,
|
51
|
-
is_signed: CBool,
|
52
|
-
fraction_digits: CInt,
|
53
|
-
out: Output[
|
54
|
-
QNum[Literal["num_qubits"], Literal["is_signed"], Literal["fraction_digits"]]
|
55
|
-
],
|
56
|
-
) -> None:
|
57
|
-
"""
|
58
|
-
[Qmod Classiq-library function]
|
59
|
-
|
60
|
-
This function is **deprecated** and will no longer be supported starting on
|
61
|
-
16/06/2025 at the earliest. Instead, use `allocate` which supports the same
|
62
|
-
parameters.
|
63
|
-
|
64
|
-
Initializes a quantum number with the given number of qubits, sign, and fractional digits.
|
65
|
-
|
66
|
-
Args:
|
67
|
-
num_qubits: The number of qubits to allocate.
|
68
|
-
is_signed: Whether the number is signed or unsigned.
|
69
|
-
fraction_digits: The number of fractional digits.
|
70
|
-
"""
|
71
|
-
warnings.warn(
|
72
|
-
"Function `allocate_num` is deprecated and will no longer be supported starting on 16/06/2025 at the earliest. Instead, use `allocate` which supports the same parameters. ",
|
73
|
-
ClassiqDeprecationWarning,
|
74
|
-
stacklevel=1,
|
75
|
-
)
|
76
|
-
allocate(num_qubits, out)
|
77
|
-
|
78
|
-
|
79
48
|
def _prepare_uniform_trimmed_state_apply_rotation(
|
80
49
|
size_lsb: CInt, lsbs_val: CInt, rotation_var: QBit
|
81
50
|
) -> None:
|
@@ -483,3 +452,20 @@ def prepare_dicke_state(k: int, qvar: QArray[QBit]) -> None:
|
|
483
452
|
if k > 0:
|
484
453
|
apply_to_all(X, qvar[0:k])
|
485
454
|
prepare_dicke_state_unary_input(k, qvar)
|
455
|
+
|
456
|
+
|
457
|
+
@qfunc
|
458
|
+
def prepare_basis_state(state: list[bool], arr: Output[QArray]) -> None:
|
459
|
+
"""
|
460
|
+
[Qmod Classiq-library function]
|
461
|
+
|
462
|
+
Initializes a quantum array in the specified basis state.
|
463
|
+
|
464
|
+
Args:
|
465
|
+
values: The desired basis state, given as a list of boolean values for each qubit.
|
466
|
+
arr: The quantum array to prepare.
|
467
|
+
"""
|
468
|
+
allocate(len(state), arr)
|
469
|
+
for idx, value in enumerate(state):
|
470
|
+
if value:
|
471
|
+
X(arr[idx])
|
classiq/qmod/__init__.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from .builtins import * # noqa: F403
|
2
2
|
from .builtins import __all__ as _builtins_all
|
3
3
|
from .cfunc import cfunc
|
4
|
+
from .classical_variable import measure
|
4
5
|
from .create_model_function import create_model
|
5
6
|
from .expression_query import get_expression_numeric_attributes
|
6
7
|
from .qfunc import qfunc
|
@@ -29,6 +30,7 @@ __all__ = [
|
|
29
30
|
"QStruct",
|
30
31
|
"cfunc",
|
31
32
|
"create_model",
|
33
|
+
"measure",
|
32
34
|
"get_expression_numeric_attributes",
|
33
35
|
"qfunc",
|
34
36
|
"write_qmod",
|