classiq 0.55.0__py3-none-any.whl → 0.56.1__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/interface/_version.py +1 -1
- classiq/interface/debug_info/debug_info.py +11 -0
- classiq/interface/executor/result.py +0 -3
- classiq/interface/generator/visitor.py +13 -1
- classiq/interface/ide/visual_model.py +2 -0
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/handle_binding.py +28 -0
- classiq/interface/model/quantum_statement.py +3 -0
- classiq/model_expansions/capturing/mangling_utils.py +22 -0
- classiq/model_expansions/capturing/propagated_var_stack.py +36 -25
- classiq/model_expansions/closure.py +3 -1
- classiq/model_expansions/function_builder.py +9 -4
- classiq/model_expansions/interpreter.py +7 -1
- classiq/model_expansions/quantum_operations/control.py +35 -9
- classiq/model_expansions/quantum_operations/emitter.py +13 -3
- classiq/model_expansions/quantum_operations/expression_operation.py +55 -17
- classiq/model_expansions/quantum_operations/power.py +5 -0
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +4 -11
- classiq/model_expansions/quantum_operations/repeat.py +5 -0
- classiq/model_expansions/scope_initialization.py +2 -2
- classiq/qmod/__init__.py +0 -2
- classiq/qmod/builtins/functions/arithmetic.py +0 -2
- classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +0 -12
- classiq/qmod/builtins/functions/exponentiation.py +0 -6
- classiq/qmod/builtins/functions/grover.py +0 -17
- classiq/qmod/builtins/functions/linear_pauli_rotation.py +0 -5
- classiq/qmod/builtins/functions/modular_exponentiation.py +0 -3
- classiq/qmod/builtins/functions/qaoa_penalty.py +0 -8
- classiq/qmod/builtins/functions/qft_functions.py +0 -3
- classiq/qmod/builtins/functions/qpe.py +0 -6
- classiq/qmod/builtins/functions/qsvt.py +0 -12
- classiq/qmod/builtins/functions/standard_gates.py +0 -88
- classiq/qmod/builtins/functions/state_preparation.py +7 -15
- classiq/qmod/builtins/functions/swap_test.py +0 -3
- classiq/qmod/builtins/operations.py +39 -0
- classiq/qmod/qfunc.py +33 -1
- classiq/qmod/qmod_constant.py +31 -3
- {classiq-0.55.0.dist-info → classiq-0.56.1.dist-info}/METADATA +2 -3
- {classiq-0.55.0.dist-info → classiq-0.56.1.dist-info}/RECORD +40 -41
- classiq/qmod/synthesize_separately.py +0 -15
- {classiq-0.55.0.dist-info → classiq-0.56.1.dist-info}/WHEEL +0 -0
@@ -12,6 +12,7 @@ from classiq.interface.generator.expressions.evaluated_expression import (
|
|
12
12
|
)
|
13
13
|
from classiq.interface.generator.expressions.expression import Expression
|
14
14
|
from classiq.interface.generator.functions.type_name import TypeName
|
15
|
+
from classiq.interface.generator.visitor import NodeType, Transformer
|
15
16
|
from classiq.interface.model.bind_operation import BindOperation
|
16
17
|
from classiq.interface.model.control import Control
|
17
18
|
from classiq.interface.model.handle_binding import (
|
@@ -40,6 +41,7 @@ from classiq.model_expansions.scope import QuantumSymbol
|
|
40
41
|
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
41
42
|
|
42
43
|
ExpressionOperationT = TypeVar("ExpressionOperationT", bound=QuantumExpressionOperation)
|
44
|
+
AST_NODE = TypeVar("AST_NODE", bound=NodeType)
|
43
45
|
|
44
46
|
|
45
47
|
class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
@@ -51,7 +53,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
51
53
|
self,
|
52
54
|
op: ExpressionOperationT,
|
53
55
|
expression: Expression,
|
54
|
-
symbols_to_split:
|
56
|
+
symbols_to_split: dict[QuantumSymbol, set[HandleBinding]],
|
55
57
|
) -> None:
|
56
58
|
symbols_parts, bind_ops = self._get_bind_ops(symbols_to_split)
|
57
59
|
|
@@ -81,8 +83,8 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
81
83
|
)
|
82
84
|
)
|
83
85
|
|
84
|
-
@staticmethod
|
85
86
|
def _get_updated_op_split_symbols(
|
87
|
+
self,
|
86
88
|
op: ExpressionOperationT,
|
87
89
|
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
88
90
|
) -> ExpressionOperationT:
|
@@ -111,11 +113,10 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
111
113
|
)
|
112
114
|
return new_expr
|
113
115
|
|
114
|
-
|
115
|
-
def _check_all_handles_were_replaced(new_expr_str: str) -> None:
|
116
|
+
def _check_all_handles_were_replaced(self, new_expr_str: str) -> None:
|
116
117
|
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
117
118
|
vrc.visit(ast.parse(new_expr_str))
|
118
|
-
for handle in vrc
|
119
|
+
for handle in self._get_handles(vrc):
|
119
120
|
if isinstance(
|
120
121
|
handle,
|
121
122
|
(SubscriptHandleBinding, SlicedHandleBinding, FieldHandleBinding),
|
@@ -124,12 +125,12 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
124
125
|
|
125
126
|
def _get_bind_ops(
|
126
127
|
self,
|
127
|
-
symbols_to_split:
|
128
|
+
symbols_to_split: dict[QuantumSymbol, set[HandleBinding]],
|
128
129
|
) -> tuple[list[list[tuple[QuantumSymbol, str]]], list[BindOperation]]:
|
129
130
|
bind_ops = []
|
130
131
|
symbols_parts = []
|
131
|
-
for symbol in symbols_to_split:
|
132
|
-
symbol_parts = self._get_symbol_parts(symbol)
|
132
|
+
for symbol, target_parts in symbols_to_split.items():
|
133
|
+
symbol_parts = self._get_symbol_parts(symbol, target_parts)
|
133
134
|
symbols_parts.append(symbol_parts)
|
134
135
|
bind_ops.append(
|
135
136
|
BindOperation(
|
@@ -143,11 +144,14 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
143
144
|
return symbols_parts, bind_ops
|
144
145
|
|
145
146
|
def _get_symbol_parts(
|
146
|
-
self, symbol: QuantumSymbol
|
147
|
+
self, symbol: QuantumSymbol, target_parts: set[HandleBinding]
|
147
148
|
) -> list[tuple[QuantumSymbol, str]]:
|
148
149
|
quantum_type = symbol.quantum_type
|
149
150
|
|
150
|
-
if
|
151
|
+
if all(
|
152
|
+
symbol.handle == target_part or symbol.handle not in target_part.prefixes()
|
153
|
+
for target_part in target_parts
|
154
|
+
) or isinstance(quantum_type, (QuantumBit, QuantumNumeric)):
|
151
155
|
return [
|
152
156
|
(
|
153
157
|
symbol,
|
@@ -163,7 +167,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
163
167
|
)
|
164
168
|
return list(
|
165
169
|
chain.from_iterable(
|
166
|
-
self._get_symbol_parts(symbol[idx])
|
170
|
+
self._get_symbol_parts(symbol[idx], target_parts)
|
167
171
|
for idx in range(quantum_type.length_value)
|
168
172
|
)
|
169
173
|
)
|
@@ -173,27 +177,33 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
173
177
|
|
174
178
|
return list(
|
175
179
|
chain.from_iterable(
|
176
|
-
self._get_symbol_parts(field_symbol)
|
180
|
+
self._get_symbol_parts(field_symbol, target_parts)
|
177
181
|
for field_symbol in symbol.fields.values()
|
178
182
|
)
|
179
183
|
)
|
180
184
|
|
181
|
-
def _get_symbols_to_split(
|
185
|
+
def _get_symbols_to_split(
|
186
|
+
self, expression: Expression
|
187
|
+
) -> dict[QuantumSymbol, set[HandleBinding]]:
|
182
188
|
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
183
189
|
vrc.visit(ast.parse(expression.expr))
|
184
190
|
symbol_names_to_split = dict.fromkeys(
|
185
191
|
handle.name
|
186
|
-
for handle in vrc
|
192
|
+
for handle in self._get_handles(vrc)
|
187
193
|
if isinstance(handle, (SubscriptHandleBinding, FieldHandleBinding))
|
188
194
|
)
|
189
|
-
return
|
190
|
-
symbol
|
195
|
+
return {
|
196
|
+
symbol: {
|
197
|
+
handle.collapse()
|
198
|
+
for handle in vrc.var_handles
|
199
|
+
if handle.name == symbol.handle.name
|
200
|
+
}
|
191
201
|
for symbol_name in symbol_names_to_split
|
192
202
|
if isinstance(
|
193
203
|
symbol := self._current_scope[symbol_name].value,
|
194
204
|
QuantumSymbol,
|
195
205
|
)
|
196
|
-
|
206
|
+
}
|
197
207
|
|
198
208
|
def _evaluate_op_expression(self, op: ExpressionOperationT) -> Expression:
|
199
209
|
return self._evaluate_expression(op.expression)
|
@@ -238,3 +248,31 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
238
248
|
isinstance(op.result_type, QuantumNumeric)
|
239
249
|
and (op.result_type.sign_value or op.result_type.fraction_digits_value > 0)
|
240
250
|
)
|
251
|
+
|
252
|
+
def _get_handles(self, collector: VarRefCollector) -> list[HandleBinding]:
|
253
|
+
return [
|
254
|
+
handle
|
255
|
+
for handle in collector.var_handles
|
256
|
+
if isinstance(self._interpreter.evaluate(handle.name).value, QuantumSymbol)
|
257
|
+
]
|
258
|
+
|
259
|
+
def _rewrite(
|
260
|
+
self,
|
261
|
+
subject: AST_NODE,
|
262
|
+
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
263
|
+
) -> AST_NODE:
|
264
|
+
class ReplaceSplitVars(Transformer):
|
265
|
+
@staticmethod
|
266
|
+
def visit_HandleBinding(handle: HandleBinding) -> HandleBinding:
|
267
|
+
handle = handle.collapse()
|
268
|
+
for handle_to_replace, replacement in symbol_mapping.items():
|
269
|
+
handle = handle.replace_prefix(
|
270
|
+
handle_to_replace, HandleBinding(name=replacement[0])
|
271
|
+
)
|
272
|
+
return handle
|
273
|
+
|
274
|
+
@staticmethod
|
275
|
+
def visit_Expression(expr: Expression) -> Expression:
|
276
|
+
return self._update_op_expression(symbol_mapping, expr)
|
277
|
+
|
278
|
+
return ReplaceSplitVars().visit(subject)
|
@@ -2,6 +2,7 @@ from typing import Union
|
|
2
2
|
|
3
3
|
import sympy
|
4
4
|
|
5
|
+
from classiq.interface.exceptions import ClassiqExpansionError
|
5
6
|
from classiq.interface.generator.expressions.evaluated_expression import (
|
6
7
|
EvaluatedExpression,
|
7
8
|
)
|
@@ -72,4 +73,8 @@ class PowerEmitter(Emitter[Power]):
|
|
72
73
|
|
73
74
|
def _get_power_value(self) -> Union[int, sympy.Basic]:
|
74
75
|
power_value = self._interpreter.evaluate(self._power.power).value
|
76
|
+
if isinstance(power_value, int) and power_value < 0:
|
77
|
+
raise ClassiqExpansionError(
|
78
|
+
f"power exponent must be non-negative, got {power_value}"
|
79
|
+
)
|
75
80
|
return power_value
|
@@ -29,6 +29,7 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
29
29
|
)
|
30
30
|
from classiq.interface.model.within_apply_operation import WithinApply
|
31
31
|
|
32
|
+
from classiq.model_expansions.capturing.mangling_utils import demangle_handle
|
32
33
|
from classiq.model_expansions.evaluators.quantum_type_utils import copy_type_information
|
33
34
|
from classiq.model_expansions.quantum_operations.expression_operation import (
|
34
35
|
ExpressionOperationEmitter,
|
@@ -228,26 +229,18 @@ class QuantumAssignmentOperationEmitter(
|
|
228
229
|
self._interpreter.emit_statement(allocate_call)
|
229
230
|
return True
|
230
231
|
|
231
|
-
@staticmethod
|
232
232
|
def _get_updated_op_split_symbols(
|
233
|
+
self,
|
233
234
|
op: QuantumAssignmentOperation,
|
234
235
|
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
235
236
|
) -> QuantumAssignmentOperation:
|
236
|
-
if op.result_var not in symbol_mapping:
|
237
|
-
return op
|
238
|
-
handle_str, quantum_type = symbol_mapping[op.result_var]
|
239
|
-
if handle_str in op.expression.expr:
|
240
|
-
raise ClassiqExpansionError(
|
241
|
-
HANDLE_ERROR_MESSAGE.format(handle_str=str(op.result_var))
|
242
|
-
)
|
243
|
-
new_result_handle = HandleBinding(name=handle_str)
|
244
237
|
return op.model_copy(
|
245
|
-
update=dict(result_var=
|
238
|
+
update=dict(result_var=self._rewrite(op.result_var, symbol_mapping))
|
246
239
|
)
|
247
240
|
|
248
241
|
|
249
242
|
def _validate_naive_inplace_handles(qe: ArithmeticOperation) -> None:
|
250
243
|
if qe.result_var in qe.var_handles:
|
251
244
|
raise ClassiqExpansionError(
|
252
|
-
HANDLE_ERROR_MESSAGE.format(handle_str=str(qe.result_var))
|
245
|
+
HANDLE_ERROR_MESSAGE.format(handle_str=str(demangle_handle(qe.result_var)))
|
253
246
|
)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
from classiq.interface.exceptions import ClassiqExpansionError
|
1
2
|
from classiq.interface.generator.expressions.expression import Expression
|
2
3
|
from classiq.interface.generator.functions.builtins.internal_operators import (
|
3
4
|
REPEAT_OPERATOR_NAME,
|
@@ -17,6 +18,10 @@ from classiq.qmod.quantum_function import GenerativeQFunc
|
|
17
18
|
class RepeatEmitter(Emitter[Repeat]):
|
18
19
|
def emit(self, repeat: Repeat, /) -> None:
|
19
20
|
count = self._interpreter.evaluate(repeat.count).as_type(int)
|
21
|
+
if count < 0:
|
22
|
+
raise ClassiqExpansionError(
|
23
|
+
f"repeat count must be non-negative, got {count}"
|
24
|
+
)
|
20
25
|
for i in range(count):
|
21
26
|
with self._propagated_var_stack.capture_variables(repeat):
|
22
27
|
self._emit_propagated(repeat, i)
|
@@ -43,7 +43,7 @@ def get_main_renamer(
|
|
43
43
|
return ExpressionRenamer(var_mapping={})
|
44
44
|
|
45
45
|
|
46
|
-
def
|
46
|
+
def add_constants_to_scope(constants: list[Constant], scope: Scope) -> None:
|
47
47
|
for constant in constants:
|
48
48
|
scope[constant.name] = Evaluated(
|
49
49
|
value=evaluate_classical_expression(constant.value, scope).value
|
@@ -142,5 +142,5 @@ def init_top_level_scope(
|
|
142
142
|
) -> None:
|
143
143
|
_add_functions_to_scope(model.functions, scope)
|
144
144
|
_add_generative_functions_to_scope(generative_functions, scope)
|
145
|
-
|
145
|
+
add_constants_to_scope(model.constants, scope)
|
146
146
|
_init_builtins_scope(scope)
|
classiq/qmod/__init__.py
CHANGED
@@ -8,7 +8,6 @@ from .qmod_constant import QConstant
|
|
8
8
|
from .qmod_parameter import Array, CArray, CBool, CInt, CReal
|
9
9
|
from .qmod_variable import Input, Output, QArray, QBit, QNum, QStruct
|
10
10
|
from .quantum_callable import QCallable, QCallableList
|
11
|
-
from .synthesize_separately import synthesize_separately
|
12
11
|
from .write_qmod import write_qmod
|
13
12
|
|
14
13
|
__all__ = [
|
@@ -31,5 +30,4 @@ __all__ = [
|
|
31
30
|
"get_expression_numeric_attributes",
|
32
31
|
"qfunc",
|
33
32
|
"write_qmod",
|
34
|
-
"synthesize_separately",
|
35
33
|
] + _builtins_all
|
@@ -23,8 +23,6 @@ def unitary(
|
|
23
23
|
Args:
|
24
24
|
elements: A 2d array of complex numbers representing the unitary matrix. This matrix must be unitary.
|
25
25
|
target: The quantum state to apply the unitary on. Should be of corresponding size.
|
26
|
-
|
27
|
-
Links: [Reference Manual](https://docs.classiq.io/qmod/builtins/functions/standard_gates/unitary)
|
28
26
|
"""
|
29
27
|
pass
|
30
28
|
|
@@ -105,9 +105,6 @@ def qct_qst_type1(x: QArray[QBit]) -> None:
|
|
105
105
|
|
106
106
|
Args:
|
107
107
|
x: The qubit array to apply the transform to.
|
108
|
-
|
109
|
-
Links:
|
110
|
-
- [Quantum Sine and Cosine Transforms](https://docs.classiq.io/latest/reference-manual/qmod/library-reference/open-library-functions/qct_qst/qct_qst/)
|
111
108
|
"""
|
112
109
|
within_apply(lambda: _t_operator(x), lambda: qft(x))
|
113
110
|
|
@@ -134,9 +131,6 @@ def qct_qst_type2(x: QArray[QBit], q: QBit) -> None:
|
|
134
131
|
Args:
|
135
132
|
x: The LSB part of the qubit array to apply the transform to.
|
136
133
|
q: The MSB of the qubit array to apply the transform to.
|
137
|
-
|
138
|
-
Links:
|
139
|
-
- [Quantum Sine and Cosine Transforms](https://docs.classiq.io/latest/reference-manual/qmod/library-reference/open-library-functions/qct_qst/qct_qst/)
|
140
134
|
"""
|
141
135
|
extended_state: QArray = QArray("extended_state")
|
142
136
|
_vn_operator(x, q)
|
@@ -156,9 +150,6 @@ def qct_type2(x: QArray[QBit]) -> None:
|
|
156
150
|
|
157
151
|
Args:
|
158
152
|
x: The qubit array to apply the transform to.
|
159
|
-
|
160
|
-
Links:
|
161
|
-
- [Quantum Sine and Cosine Transforms](https://docs.classiq.io/latest/reference-manual/qmod/library-reference/open-library-functions/qct_qst/qct_qst/)
|
162
153
|
"""
|
163
154
|
q = QBit("q")
|
164
155
|
within_apply(lambda: allocate(1, q), lambda: qct_qst_type2(x, q))
|
@@ -174,9 +165,6 @@ def qst_type2(x: QArray[QBit]) -> None:
|
|
174
165
|
|
175
166
|
Args:
|
176
167
|
x: The qubit array to apply the transform to.
|
177
|
-
|
178
|
-
Links:
|
179
|
-
- [Quantum Sine and Cosine Transforms](https://docs.classiq.io/latest/reference-manual/qmod/library-reference/open-library-functions/qct_qst/qct_qst/)
|
180
168
|
"""
|
181
169
|
q = QBit("q")
|
182
170
|
within_apply(
|
@@ -45,8 +45,6 @@ def suzuki_trotter(
|
|
45
45
|
The Suzuki-Trotter decomposition of a given order nullifies the error of the Taylor series expansion of the product of exponentials up to that order.
|
46
46
|
The error of a Suzuki-Trotter decomposition decreases as the order and number of repetitions increase.
|
47
47
|
|
48
|
-
See [N. Hatano and M. Suzuki, Finding Exponential Product Formulas of Higher Orders (2005)](https://arxiv.org/abs/math-ph/0506007).
|
49
|
-
|
50
48
|
Args:
|
51
49
|
pauli_operator: The Pauli operator to be exponentiated.
|
52
50
|
evolution_coefficient: A global evolution coefficient multiplying the Pauli operator.
|
@@ -73,8 +71,6 @@ def qdrift(
|
|
73
71
|
The QDrift method randomizes the order of the operators in the product of exponentials to stochastically reduce the error of the approximation.
|
74
72
|
The error of the QDrift method decreases as the number of QDrift steps increases.
|
75
73
|
|
76
|
-
See [E. Campbell, Random Compiler for Fast Hamiltonian Simulation (2019)](https://arxiv.org/abs/1811.08017).
|
77
|
-
|
78
74
|
Args:
|
79
75
|
pauli_operator: The Pauli operator to be exponentiated.
|
80
76
|
evolution_coefficient: A global evolution coefficient multiplying the Pauli operator.
|
@@ -100,8 +96,6 @@ def exponentiation_with_depth_constraint(
|
|
100
96
|
The Suzuki-Trotter decomposition is a method for approximating the exponential of a sum of operators by a product of exponentials of each operator.
|
101
97
|
This function automatically determines the order and number of repetitions of the Suzuki-Trotter decomposition to minimize the error given a depth constraint.
|
102
98
|
|
103
|
-
See [A. M. Childs et al., Toward the first quantum simulation with quantum speedup (2017)](https://arxiv.org/abs/1711.10980).
|
104
|
-
|
105
99
|
Args:
|
106
100
|
pauli_operator: The Pauli operator to be exponentiated.
|
107
101
|
evolution_coefficient: A global coefficient multiplying the Pauli operator.
|
@@ -39,11 +39,6 @@ def phase_oracle(
|
|
39
39
|
Args:
|
40
40
|
predicate: A predicate function that takes a QArray of QBits and sets a single QBit |1> if the predicate is true, and |0> otherwise.
|
41
41
|
target: The target QArray of QBits to apply the phase oracle to.
|
42
|
-
|
43
|
-
Usage Examples:
|
44
|
-
[Grover Algorithm](https://docs.classiq.io/latest/explore/functions/qmod_library_reference/classiq_open_library/grover_operator/grover_operator/)
|
45
|
-
|
46
|
-
[Hidden shift](https://docs.classiq.io/latest/explore/algorithms/algebraic/hidden_shift/hidden_shift/)
|
47
42
|
"""
|
48
43
|
aux = QBit("aux")
|
49
44
|
within_apply(
|
@@ -125,18 +120,10 @@ def grover_operator(
|
|
125
120
|
where $S_{\\psi_1}$ is a reflection about marked states, and $S_{\\psi_0}$ is a reflection
|
126
121
|
about a given state defined by $|\\psi_0\rangle = A|0\rangle$.
|
127
122
|
|
128
|
-
|
129
123
|
Args:
|
130
124
|
oracle: A unitary operator which adds a phase of (-1) to marked states.
|
131
125
|
space_transform: The operator which creates $|\\psi_0\rangle$, the initial state, used by the diffuser to reflect about it.
|
132
126
|
packed_vars: The state to which to apply the grover operator.
|
133
|
-
|
134
|
-
|
135
|
-
For further reading, see:
|
136
|
-
|
137
|
-
- [The Grover Operator notebook](../explore/functions/qmod_library_reference/classiq_open_library/grover_operator/grover_operator/)
|
138
|
-
- [Wikipedia page](https://en.wikipedia.org/wiki/Grover%27s_algorithm).
|
139
|
-
|
140
127
|
"""
|
141
128
|
oracle(packed_vars)
|
142
129
|
grover_diffuser(lambda qba: space_transform(qba), packed_vars)
|
@@ -158,10 +145,6 @@ def grover_search(
|
|
158
145
|
packed_vars: Packed form of the variable to apply the grover operator on.
|
159
146
|
|
160
147
|
Returns: None
|
161
|
-
|
162
|
-
Links:
|
163
|
-
[Grover Algorithm](https://docs.classiq.io/latest/explore/functions/qmod_library_reference/classiq_open_library/grover_operator/grover_operator/)
|
164
|
-
|
165
148
|
"""
|
166
149
|
hadamard_transform(packed_vars)
|
167
150
|
power(
|
@@ -61,11 +61,6 @@ def linear_pauli_rotations(
|
|
61
61
|
q: List of indicator qubits for each of the given Pauli bases.
|
62
62
|
|
63
63
|
Notice that bases, slopes, offset and q should be of the same size.
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
Links:
|
68
|
-
[linear_pauli_rotations](https://docs.classiq.io/latest/explore/functions/qmod_library_reference/classiq_open_library/linear_pauli_rotations/linear_pauli_rotations)
|
69
64
|
"""
|
70
65
|
repeat(
|
71
66
|
q.len,
|
@@ -186,9 +186,6 @@ def modular_exp(n: CInt, a: CInt, x: QArray[QBit], power: QArray[QBit]) -> None:
|
|
186
186
|
a: The base of the exponentiation. Should be non-negative.
|
187
187
|
x: A quantum number that multiplies the modular exponentiation and holds the output. It should be at least the size of $\\lceil \\log(n) \rceil$.
|
188
188
|
power: The power of the exponentiation.
|
189
|
-
|
190
|
-
Usage Example:
|
191
|
-
[Modular Exponentiation](https://docs.classiq.io/latest/explore/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example)
|
192
189
|
"""
|
193
190
|
repeat(
|
194
191
|
count=power.len,
|
@@ -17,9 +17,6 @@ def qaoa_mixer_layer(b: CReal, target: QArray[QBit]) -> None:
|
|
17
17
|
The mixer layer is a sequence of `X` gates applied to each qubit in the target quantum
|
18
18
|
array variable.
|
19
19
|
|
20
|
-
Please refer to the [QAOA mixer tutorial](https://docs.classiq.io/latest/reference-manual/built-in-algorithms/combinatorial-optimization/problem-solving/) for an example
|
21
|
-
|
22
|
-
|
23
20
|
Args:
|
24
21
|
b: The rotation parameter for the mixer layer.
|
25
22
|
target: The target quantum array.
|
@@ -40,7 +37,6 @@ def qaoa_cost_layer(
|
|
40
37
|
The cost layer represents the primary objective that the QAOA algorithm seeks to optimize, such as
|
41
38
|
minimizing energy or maximizing profit, depending on the application.
|
42
39
|
|
43
|
-
For more details on defining cost functions in QAOA models using Pyomo, see: [Problem Formulation](https://docs.classiq.io/latest/reference-manual/built-in-algorithms/combinatorial-optimization/)
|
44
40
|
Args:
|
45
41
|
g: The rotation parameter for the cost layer (prefactor).
|
46
42
|
hamiltonian: The Hamiltonian terms for the QAOA model.
|
@@ -62,7 +58,6 @@ def qaoa_layer(
|
|
62
58
|
Quantum Approximate Optimization Algorithm (QAOA). The cost layer encodes the problem's objective,
|
63
59
|
while the mixer layer introduces quantum superposition and drives the search across the solution space.
|
64
60
|
|
65
|
-
For more details mon the QAOA problem formulation, please see the following [tutorial](https://docs.classiq.io/latest/reference-manual/built-in-algorithms/combinatorial-optimization/)
|
66
61
|
Args:
|
67
62
|
g: The rotation parameter for the cost layer.
|
68
63
|
b: The rotation parameter for the mixer layer.
|
@@ -107,9 +102,6 @@ def qaoa_penalty(
|
|
107
102
|
enforce certain constraints (e.g., binary or integer variables) during the
|
108
103
|
optimization process.
|
109
104
|
|
110
|
-
Please refer to the [Optimization Problem tutorial](https://docs.classiq.io/latest/reference-manual/built-in-algorithms/combinatorial-optimization/problem-formulation/) for details.
|
111
|
-
|
112
|
-
|
113
105
|
Args:
|
114
106
|
num_qubits: The number of qubits in the quantum circuit.
|
115
107
|
params_list The list of QAOA parameters.
|
@@ -46,9 +46,6 @@ def qft(target: QArray[QBit]) -> None:
|
|
46
46
|
|
47
47
|
Args:
|
48
48
|
target: The quantum object to be transformed
|
49
|
-
|
50
|
-
Further reading in Classiq Library:
|
51
|
-
Link: [qft library reference](https://github.com/Classiq/classiq-library/blob/main/functions/qmod_library_reference/classiq_open_library/qft/qft.ipynb)
|
52
49
|
"""
|
53
50
|
repeat(
|
54
51
|
target.len / 2, # type:ignore[arg-type]
|
@@ -19,9 +19,6 @@ def qpe_flexible(unitary_with_power: QCallable[CInt], phase: QNum) -> None:
|
|
19
19
|
Args:
|
20
20
|
unitary_with_power: A callable that returns the unitary operator $U^k$ given an integer $k$. This callable is used to control the application of powers of the unitary operator.
|
21
21
|
phase: The quantum variable that represents the estimated phase (eigenvalue), assuming initialized to zero.
|
22
|
-
|
23
|
-
Further reading in Classiq Library:
|
24
|
-
Link: [qpe library reference](https://github.com/Classiq/classiq-library/blob/main/functions/qmod_library_reference/classiq_open_library/qpe/qpe.ipynb)
|
25
22
|
"""
|
26
23
|
phase_array: QArray = QArray("phase_array")
|
27
24
|
bind(phase, phase_array)
|
@@ -48,8 +45,5 @@ def qpe(unitary: QCallable, phase: QNum) -> None:
|
|
48
45
|
Args:
|
49
46
|
unitary: A callable representing the unitary operator $U$, whose eigenvalue is to be estimated.
|
50
47
|
phase: The quantum variable that represents the estimated phase (eigenvalue), assuming initialized to zero.
|
51
|
-
|
52
|
-
Further reading in Classiq Library:
|
53
|
-
Link: [qpe library reference](https://github.com/Classiq/classiq-library/blob/main/functions/qmod_library_reference/classiq_open_library/qpe/qpe.ipynb)
|
54
48
|
"""
|
55
49
|
qpe_flexible(unitary_with_power=lambda k: power(k, unitary), phase=phase)
|
@@ -34,9 +34,6 @@ def qsvt_step(
|
|
34
34
|
u: A block encoded unitary matrix.
|
35
35
|
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
36
36
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
37
|
-
|
38
|
-
Further reading in Classiq Library:
|
39
|
-
[QSVT function usage example](https://docs.classiq.io/latest/explore/functions/qmod_library_reference/classiq_open_library/qsvt/qsvt/)
|
40
37
|
"""
|
41
38
|
u(qvar)
|
42
39
|
projector_controlled_phase(phase1, proj_cnot_2, qvar, aux)
|
@@ -80,9 +77,6 @@ def qsvt(
|
|
80
77
|
u: A block encoded unitary matrix.
|
81
78
|
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
82
79
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
83
|
-
|
84
|
-
Further reading in Classiq Library:
|
85
|
-
[QSVT function usage example](https://docs.classiq.io/latest/explore/functions/qmod_library_reference/classiq_open_library/qsvt/qsvt/)
|
86
80
|
"""
|
87
81
|
H(aux)
|
88
82
|
|
@@ -138,9 +132,6 @@ def projector_controlled_phase(
|
|
138
132
|
proj_cnot: Projector-controlled-not unitary that sets an auxilliary qubit to |1> when the state is in the projection.
|
139
133
|
qvar: The quantum variable to which the rotation applies, which resides in the entire block encoding space.
|
140
134
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotation. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
141
|
-
|
142
|
-
Further reading in Classiq Library:
|
143
|
-
[QSVT function usage example](https://docs.classiq.io/latest/explore/functions/qmod_library_reference/classiq_open_library/qsvt/qsvt/)
|
144
135
|
"""
|
145
136
|
proj_cnot(qvar, aux)
|
146
137
|
RZ(phase, aux)
|
@@ -167,9 +158,6 @@ def qsvt_inversion(
|
|
167
158
|
u: A block encoded unitary matrix.
|
168
159
|
qvar: The quantum variable to which U is applied, which resides in the entire block encoding space.
|
169
160
|
aux: A zero auxilliary qubit, used for the projector-controlled-phase rotations. Given as an inout so that qsvt can be used as a building-block in a larger algorithm.
|
170
|
-
|
171
|
-
For usage example, see:
|
172
|
-
[QSVT matrix inversion example](https://docs.classiq.io/latest/explore/algorithms/qsvt/qsvt_matrix_inversion/qsvt_matrix_inversion)
|
173
161
|
"""
|
174
162
|
qsvt(
|
175
163
|
phase_seq,
|