classiq 0.100.0__py3-none-any.whl → 0.104.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.
Files changed (95) hide show
  1. classiq/__init__.py +3 -0
  2. classiq/_internals/api_wrapper.py +29 -4
  3. classiq/applications/chemistry/op_utils.py +63 -1
  4. classiq/applications/chemistry/problems.py +18 -6
  5. classiq/applications/chemistry/ucc.py +2 -2
  6. classiq/evaluators/parameter_types.py +1 -4
  7. classiq/evaluators/qmod_annotated_expression.py +1 -1
  8. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +1 -8
  9. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +1 -1
  10. classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +2 -2
  11. classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +18 -29
  12. classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +1 -6
  13. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +1 -7
  14. classiq/evaluators/qmod_node_evaluators/utils.py +6 -3
  15. classiq/evaluators/qmod_type_inference/quantum_type_comparison.py +52 -0
  16. classiq/execution/__init__.py +11 -1
  17. classiq/execution/execution_session.py +1 -1
  18. classiq/execution/functions/__init__.py +3 -0
  19. classiq/execution/functions/_logging.py +19 -0
  20. classiq/execution/functions/constants.py +9 -0
  21. classiq/execution/functions/parse_provider_backend.py +90 -0
  22. classiq/execution/functions/sample.py +257 -0
  23. classiq/execution/jobs.py +122 -5
  24. classiq/interface/_version.py +1 -1
  25. classiq/interface/backend/backend_preferences.py +15 -0
  26. classiq/interface/backend/provider_config/providers/aqt.py +1 -1
  27. classiq/interface/backend/provider_config/providers/azure.py +1 -2
  28. classiq/interface/backend/provider_config/providers/ibm.py +1 -1
  29. classiq/interface/backend/quantum_backend_providers.py +3 -0
  30. classiq/interface/exceptions.py +0 -42
  31. classiq/interface/executor/execution_request.py +1 -0
  32. classiq/interface/executor/quantum_code.py +0 -6
  33. classiq/interface/executor/result.py +9 -5
  34. classiq/interface/generator/arith/binary_ops.py +38 -2
  35. classiq/interface/generator/function_param_list.py +4 -2
  36. classiq/interface/generator/functions/builtins/internal_operators.py +5 -9
  37. classiq/interface/generator/functions/classical_type.py +45 -0
  38. classiq/interface/generator/functions/type_name.py +23 -0
  39. classiq/interface/generator/generated_circuit_data.py +0 -2
  40. classiq/interface/generator/generation_request.py +9 -4
  41. classiq/interface/generator/quantum_program.py +8 -36
  42. classiq/interface/generator/types/compilation_metadata.py +9 -0
  43. classiq/interface/hardware.py +1 -0
  44. classiq/interface/helpers/model_normalizer.py +62 -2
  45. classiq/interface/helpers/text_utils.py +17 -6
  46. classiq/interface/interface_version.py +1 -1
  47. classiq/interface/model/invert.py +15 -0
  48. classiq/interface/model/model.py +42 -3
  49. classiq/interface/model/model_visitor.py +4 -2
  50. classiq/interface/model/quantum_function_call.py +17 -5
  51. classiq/interface/model/quantum_type.py +21 -0
  52. classiq/interface/model/statement_block.py +0 -4
  53. classiq/model_expansions/capturing/captured_vars.py +16 -12
  54. classiq/model_expansions/function_builder.py +9 -1
  55. classiq/model_expansions/interpreters/base_interpreter.py +12 -10
  56. classiq/model_expansions/interpreters/generative_interpreter.py +9 -24
  57. classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +1 -0
  58. classiq/model_expansions/quantum_operations/assignment_result_processor.py +132 -28
  59. classiq/model_expansions/quantum_operations/bind.py +4 -0
  60. classiq/model_expansions/quantum_operations/call_emitter.py +5 -35
  61. classiq/model_expansions/quantum_operations/emitter.py +1 -4
  62. classiq/model_expansions/quantum_operations/expression_evaluator.py +0 -3
  63. classiq/model_expansions/visitors/uncomputation_signature_inference.py +15 -47
  64. classiq/open_library/functions/__init__.py +42 -27
  65. classiq/open_library/functions/bit_operations.py +30 -0
  66. classiq/open_library/functions/modular_arithmetics.py +597 -0
  67. classiq/open_library/functions/qft_space_arithmetics.py +81 -0
  68. classiq/open_library/functions/state_preparation.py +6 -3
  69. classiq/open_library/functions/utility_functions.py +22 -3
  70. classiq/qmod/builtins/functions/__init__.py +9 -0
  71. classiq/qmod/builtins/functions/arithmetic.py +131 -0
  72. classiq/qmod/builtins/functions/exponentiation.py +34 -4
  73. classiq/qmod/builtins/operations.py +30 -41
  74. classiq/qmod/native/pretty_printer.py +12 -12
  75. classiq/qmod/pretty_print/pretty_printer.py +11 -15
  76. classiq/qmod/qmod_parameter.py +4 -0
  77. classiq/qmod/qmod_variable.py +38 -63
  78. classiq/qmod/quantum_callable.py +8 -2
  79. classiq/qmod/quantum_expandable.py +3 -1
  80. classiq/qmod/quantum_function.py +45 -8
  81. classiq/qmod/semantics/validation/function_name_collisions_validation.py +7 -4
  82. classiq/qmod/semantics/validation/model_validation.py +7 -2
  83. classiq/qmod/symbolic_type.py +4 -2
  84. classiq/qmod/utilities.py +7 -4
  85. classiq/synthesis_action/__init__.py +20 -0
  86. classiq/synthesis_action/actions.py +106 -0
  87. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/METADATA +1 -1
  88. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/RECORD +90 -84
  89. classiq/interface/executor/register_initialization.py +0 -36
  90. classiq/interface/generator/amplitude_loading.py +0 -103
  91. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +0 -77
  92. classiq/open_library/functions/modular_exponentiation.py +0 -272
  93. classiq/open_library/functions/qsvt_temp.py +0 -536
  94. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/WHEEL +0 -0
  95. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,77 +0,0 @@
1
- from collections.abc import Mapping, Sequence
2
- from typing import Literal
3
-
4
- import pydantic
5
-
6
- from classiq.interface.exceptions import ClassiqValueError
7
- from classiq.interface.generator.amplitude_loading import (
8
- AMPLITUDE_IO_NAME,
9
- TARGET_OUTPUT_NAME,
10
- )
11
- from classiq.interface.model.handle_binding import (
12
- ConcreteHandleBinding,
13
- HandleBinding,
14
- )
15
- from classiq.interface.model.quantum_expressions.quantum_expression import (
16
- QuantumAssignmentOperation,
17
- )
18
- from classiq.interface.model.quantum_statement import HandleMetadata
19
- from classiq.interface.model.quantum_type import QuantumBit, QuantumNumeric, QuantumType
20
-
21
- MULTI_VARS_UNSUPPORTED_ERROR = (
22
- "Amplitude Loading with more than one input variable is unsupported."
23
- )
24
-
25
- VAR_TYPE_ILLEGAL = "Amplitude Loading input variable should be a quantum numeric"
26
-
27
-
28
- class AmplitudeLoadingOperation(QuantumAssignmentOperation):
29
- kind: Literal["AmplitudeLoadingOperation"]
30
-
31
- _result_type: QuantumType = pydantic.PrivateAttr(default_factory=QuantumBit)
32
-
33
- @property
34
- def wiring_inouts(
35
- self,
36
- ) -> Mapping[str, ConcreteHandleBinding]:
37
- inouts = {self.result_name(): self.result_var}
38
- if len(self.var_handles) == 1:
39
- inouts[AMPLITUDE_IO_NAME] = self.var_handles[0]
40
- return inouts
41
-
42
- @property
43
- def readable_inouts(self) -> Sequence[HandleMetadata]:
44
- inouts = [
45
- HandleMetadata(
46
- handle=self.result_var,
47
- readable_location="on the left-hand side of an in-place assignment",
48
- )
49
- ]
50
- if len(self.var_handles) == 1:
51
- inouts.append(
52
- HandleMetadata(
53
- handle=self.var_handles[0],
54
- readable_location="in an expression",
55
- )
56
- )
57
- return inouts
58
-
59
- @property
60
- def wiring_outputs(self) -> Mapping[str, HandleBinding]:
61
- return {}
62
-
63
- def initialize_var_types(
64
- self,
65
- var_types: dict[str, QuantumType],
66
- machine_precision: int,
67
- ) -> None:
68
- if len(var_types) != 1:
69
- raise ClassiqValueError(MULTI_VARS_UNSUPPORTED_ERROR)
70
- var_type = list(var_types.values())[0]
71
- if not isinstance(var_type, QuantumNumeric):
72
- raise ClassiqValueError(VAR_TYPE_ILLEGAL)
73
- super().initialize_var_types(var_types, machine_precision)
74
-
75
- @classmethod
76
- def result_name(cls) -> str:
77
- return TARGET_OUTPUT_NAME
@@ -1,272 +0,0 @@
1
- from classiq.open_library.functions.qft_functions import qft, qft_no_swap
2
- from classiq.qmod.builtins.classical_functions import qft_const_adder_phase
3
- from classiq.qmod.builtins.functions.allocation import free
4
- from classiq.qmod.builtins.functions.standard_gates import PHASE, SWAP, X
5
- from classiq.qmod.builtins.operations import (
6
- allocate,
7
- bind,
8
- control,
9
- invert,
10
- repeat,
11
- skip_control,
12
- within_apply,
13
- )
14
- from classiq.qmod.cparam import CInt
15
- from classiq.qmod.qfunc import qfunc, qperm
16
- from classiq.qmod.qmod_variable import Const, QArray, QBit
17
- from classiq.qmod.symbolic import min, mod_inverse
18
-
19
-
20
- @qfunc
21
- def _check_msb(ref: CInt, x: QArray[QBit], aux: QBit) -> None:
22
- within_apply(
23
- lambda: invert(lambda: qft_no_swap(x)),
24
- lambda: control(x[0] == ref, lambda: X(aux)),
25
- )
26
-
27
-
28
- @qfunc
29
- def qft_space_add_const(value: CInt, phi_b: QArray[QBit]) -> None:
30
- """
31
- [Qmod Classiq-library function]
32
-
33
- Adds a constant to a quantum number (in the Fourier space) using the Quantum Fourier Transform (QFT) Adder algorithm.
34
- Assuming that the input `phi_b` has `n` qubits, the result will be $\\phi_b+=value \\mod 2^n$.
35
-
36
- To perform the full algorithm, use:
37
- within_apply(lambda: QFT(phi_b), qft_space_add_const(value, phi_b))
38
-
39
- Args:
40
- value: The constant to add to the quantum number.
41
- phi_b: The quantum number (at the aft space) to which the constant is added.
42
-
43
- """
44
- repeat(
45
- count=phi_b.len,
46
- iteration=lambda index: PHASE(
47
- theta=qft_const_adder_phase(
48
- index, value, phi_b.len # type:ignore[arg-type]
49
- ),
50
- target=phi_b[index],
51
- ),
52
- )
53
-
54
-
55
- @qperm(disable_perm_check=True)
56
- def cc_modular_add(
57
- n: CInt, a: CInt, phi_b: QArray[QBit], c1: Const[QBit], c2: Const[QBit]
58
- ) -> None:
59
- """
60
- [Qmod Classiq-library function]
61
-
62
- Adds a constant `a` to a quantum number `phi_b` modulo the constant `n`, controlled by 2 qubits.
63
- The quantum number `phi_b` and the constant `a` are assumed to be in the QFT space.
64
-
65
- Args:
66
- n: The modulo number.
67
- a: The constant to add to the quantum number.
68
- phi_b: The quantum number to which the constant is added.
69
- c1: a control qubit.
70
- c2: a control qubit.
71
-
72
- """
73
- ctrl: QArray[QBit] = QArray()
74
- aux = QBit()
75
-
76
- allocate(aux)
77
- within_apply(
78
- lambda: bind([c1, c2], ctrl),
79
- lambda: (
80
- control(ctrl, lambda: qft_space_add_const(a, phi_b)),
81
- invert(lambda: qft_space_add_const(n, phi_b)),
82
- _check_msb(1, phi_b, aux),
83
- control(aux, lambda: qft_space_add_const(n, phi_b)),
84
- within_apply(
85
- lambda: invert(
86
- lambda: control(ctrl, lambda: qft_space_add_const(a, phi_b))
87
- ),
88
- lambda: _check_msb(0, phi_b, aux),
89
- ),
90
- ),
91
- )
92
- free(aux)
93
-
94
-
95
- @qperm(disable_perm_check=True)
96
- def c_modular_multiply(
97
- n: CInt,
98
- a: CInt,
99
- b: QArray[QBit],
100
- x: Const[QArray[QBit]],
101
- ctrl: Const[QBit],
102
- ) -> None:
103
- """
104
- [Qmod Classiq-library function]
105
-
106
- Performs out-of-place multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`,
107
- controlled by a quantum bit `ctrl` and adds the result to a quantum array `b`. Applies $b += xa \\mod n$ if `ctrl=1`, and the identity otherwise.
108
-
109
- Args:
110
- n: The modulo number. Should be non-negative.
111
- a: The classical factor. Should be non-negative.
112
- b: The quantum number added to the multiplication result. Stores the result of the multiplication.
113
- x: The quantum factor.
114
- ctrl: The control bit.
115
- """
116
- within_apply(
117
- lambda: qft(b),
118
- lambda: repeat(
119
- count=x.len,
120
- iteration=lambda index: cc_modular_add(
121
- n, (a * (2**index)) % n, b, x[index], ctrl
122
- ),
123
- ),
124
- )
125
-
126
-
127
- @qperm
128
- def multiswap(x: QArray[QBit], y: QArray[QBit]) -> None:
129
- """
130
- [Qmod Classiq-library function]
131
-
132
- Swaps the qubit states between two arrays.
133
- Qubits of respective indices are swapped, and additional qubits in the longer array are left unchanged.
134
-
135
- Args:
136
- x: The first array
137
- y: The second array
138
-
139
- """
140
- repeat(
141
- count=min(x.len, y.len),
142
- iteration=lambda index: SWAP(x[index], y[index]),
143
- )
144
-
145
-
146
- @qfunc
147
- def inplace_c_modular_multiply(n: CInt, a: CInt, x: QArray[QBit], ctrl: QBit) -> None:
148
- """
149
- [Qmod Classiq-library function]
150
-
151
- Performs multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`,
152
- controlled by a quantum bit `ctrl`. Applies $x=xa \\mod n$ if `ctrl=1`, and the identity otherwise.
153
-
154
- Args:
155
- n: The modulo number. Should be non-negative.
156
- a: The classical factor. Should be non-negative.
157
- x: The quantum factor.
158
- ctrl: The control bit.
159
- """
160
- b: QArray[QBit] = QArray(length=x.len + 1)
161
- allocate(b)
162
- c_modular_multiply(n, a, b, x, ctrl)
163
- control(ctrl, lambda: multiswap(x, b))
164
- invert(lambda: c_modular_multiply(n, mod_inverse(a, n), b, x, ctrl))
165
- free(b)
166
-
167
-
168
- @qperm(disable_perm_check=True)
169
- def modular_add_qft_space(n: CInt, a: CInt, phi_b: QArray[QBit]) -> None:
170
- """
171
- [Qmod Classiq-library function]
172
-
173
- Adds a constant `a` to a quantum number `phi_b` modulo the constant `n`.
174
- The quantum number `phi_b` is assumed to be in the QFT space.
175
-
176
- Args:
177
- n: The modulo number.
178
- a: The constant to add to the quantum number.
179
- phi_b: The quantum number to which the constant is added.
180
-
181
- """
182
- aux = QBit()
183
-
184
- allocate(aux)
185
- qft_space_add_const(a, phi_b),
186
- skip_control(
187
- lambda: (
188
- invert(lambda: qft_space_add_const(n, phi_b)),
189
- _check_msb(1, phi_b, aux),
190
- control(aux, lambda: qft_space_add_const(n, phi_b)),
191
- )
192
- )
193
- invert(lambda: qft_space_add_const(a, phi_b))
194
- skip_control(lambda: _check_msb(0, phi_b, aux))
195
- qft_space_add_const(a, phi_b)
196
- free(aux)
197
-
198
-
199
- @qperm(disable_perm_check=True)
200
- def modular_multiply(
201
- n: CInt,
202
- a: CInt,
203
- b: QArray[QBit],
204
- x: Const[QArray[QBit]],
205
- ) -> None:
206
- """
207
- [Qmod Classiq-library function]
208
-
209
- Performs out-of-place multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`,
210
- and adds the result to a quantum array `b` (Applies $b += xa \\mod n$).
211
-
212
- Args:
213
- n: The modulo number. Should be non-negative.
214
- a: The classical factor. Should be non-negative.
215
- b: The quantum number added to the multiplication result. Stores the result of the multiplication.
216
- x: The quantum factor.
217
- """
218
- within_apply(
219
- lambda: qft(b),
220
- lambda: repeat(
221
- count=x.len,
222
- iteration=lambda index: control(
223
- x[index], lambda: modular_add_qft_space(n, (a * (2**index)) % n, b)
224
- ),
225
- ),
226
- )
227
-
228
-
229
- @qfunc
230
- def inplace_modular_multiply(n: CInt, a: CInt, x: QArray[QBit]) -> None:
231
- """
232
- [Qmod Classiq-library function]
233
-
234
- Performs multiplication of a quantum number `x` by a classical number `a` modulo classical number `n`
235
- (Applies $x=xa \\mod n$).
236
-
237
- Args:
238
- n: The modulo number. Should be non-negative.
239
- a: The classical factor. Should be non-negative.
240
- x: The quantum factor.
241
-
242
- Comment: It is assumed that `a` has an inverse modulo `n`
243
- """
244
- b: QArray[QBit] = QArray(length=x.len + 1)
245
- allocate(b)
246
- modular_multiply(n, a, b, x)
247
- multiswap(x, b)
248
- invert(lambda: modular_multiply(n, mod_inverse(a, n), b, x))
249
- free(b)
250
-
251
-
252
- @qfunc
253
- def modular_exp(n: CInt, a: CInt, x: QArray[QBit], power: QArray[QBit]) -> None:
254
- """
255
- [Qmod Classiq-library function]
256
-
257
- Raises a classical integer `a` to the power of a quantum number `power` modulo classical integer `n`
258
- times a quantum number `x`. Performs $x=(a^{power} \\mod n)*x$ in-place.
259
- (and specifically if at the input $x=1$, at the output $x=a^{power} \\mod n$).
260
-
261
- Args:
262
- n: The modulus number. Should be non-negative.
263
- a: The base of the exponentiation. Should be non-negative.
264
- 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$.
265
- power: The power of the exponentiation.
266
- """
267
- repeat(
268
- count=power.len,
269
- iteration=lambda index: inplace_c_modular_multiply(
270
- n, (a ** (2**index)) % n, x, power[index]
271
- ),
272
- )