classiq 0.99.0__py3-none-any.whl → 0.102.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 (54) hide show
  1. classiq/__init__.py +3 -0
  2. classiq/_internals/api_wrapper.py +29 -4
  3. classiq/applications/chemistry/op_utils.py +31 -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_node_evaluators/utils.py +6 -3
  8. classiq/execution/__init__.py +11 -1
  9. classiq/execution/jobs.py +122 -5
  10. classiq/interface/_version.py +1 -1
  11. classiq/interface/exceptions.py +0 -42
  12. classiq/interface/executor/execution_request.py +1 -0
  13. classiq/interface/executor/quantum_code.py +0 -6
  14. classiq/interface/executor/user_budget.py +2 -6
  15. classiq/interface/generator/generation_request.py +40 -0
  16. classiq/interface/generator/quantum_program.py +8 -36
  17. classiq/interface/generator/transpiler_basis_gates.py +1 -3
  18. classiq/interface/generator/types/compilation_metadata.py +1 -1
  19. classiq/interface/helpers/model_normalizer.py +24 -0
  20. classiq/interface/helpers/text_utils.py +20 -5
  21. classiq/interface/model/bind_operation.py +3 -0
  22. classiq/interface/model/invert.py +7 -0
  23. classiq/interface/model/model.py +42 -3
  24. classiq/interface/model/quantum_function_call.py +17 -5
  25. classiq/model_expansions/arithmetic_compute_result_attrs.py +10 -1
  26. classiq/model_expansions/interpreters/base_interpreter.py +3 -2
  27. classiq/model_expansions/quantum_operations/call_emitter.py +0 -3
  28. classiq/model_expansions/visitors/uncomputation_signature_inference.py +15 -38
  29. classiq/open_library/functions/__init__.py +55 -27
  30. classiq/open_library/functions/bit_operations.py +30 -0
  31. classiq/open_library/functions/encodings.py +182 -0
  32. classiq/open_library/functions/modular_arithmetics.py +597 -0
  33. classiq/open_library/functions/qft_space_arithmetics.py +81 -0
  34. classiq/open_library/functions/state_preparation.py +13 -7
  35. classiq/open_library/functions/utility_functions.py +22 -3
  36. classiq/qmod/builtins/functions/exponentiation.py +2 -2
  37. classiq/qmod/builtins/operations.py +29 -4
  38. classiq/qmod/native/pretty_printer.py +15 -4
  39. classiq/qmod/pretty_print/pretty_printer.py +14 -2
  40. classiq/qmod/qmod_variable.py +1 -1
  41. classiq/qmod/quantum_callable.py +8 -2
  42. classiq/qmod/quantum_expandable.py +3 -1
  43. classiq/qmod/quantum_function.py +2 -1
  44. classiq/qmod/semantics/error_manager.py +11 -1
  45. classiq/qmod/utilities.py +7 -4
  46. classiq/synthesis_action/__init__.py +20 -0
  47. classiq/synthesis_action/actions.py +106 -0
  48. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/METADATA +1 -1
  49. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/RECORD +51 -47
  50. classiq/interface/executor/register_initialization.py +0 -36
  51. classiq/open_library/functions/modular_exponentiation.py +0 -272
  52. classiq/open_library/functions/qsvt_temp.py +0 -536
  53. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/WHEEL +0 -0
  54. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,30 @@
1
+ from classiq.open_library.functions.utility_functions import apply_to_all
2
+ from classiq.qmod.builtins.functions.standard_gates import SWAP, X
3
+ from classiq.qmod.builtins.operations import invert, repeat
4
+ from classiq.qmod.qfunc import qperm
5
+ from classiq.qmod.qmod_variable import QArray, QBit
6
+
7
+
8
+ @qperm
9
+ def cyclic_shift_left(reg: QArray[QBit]) -> None:
10
+ """
11
+ Performs a left shift on the quantum register array `reg` using SWAP gates.
12
+ """
13
+ n = reg.size
14
+ repeat(n - 1, lambda i: SWAP(reg[n - i - 1], reg[n - i - 2]))
15
+
16
+
17
+ @qperm
18
+ def cyclic_shift_right(reg: QArray[QBit]) -> None:
19
+ """
20
+ Performs a right shift on the quantum register array `reg` by inverting cyclic_shift_left.
21
+ """
22
+ invert(lambda: cyclic_shift_left(reg))
23
+
24
+
25
+ @qperm
26
+ def bitwise_negate(x: QArray[QBit]) -> None:
27
+ """
28
+ Negates each bit of the input x.
29
+ """
30
+ apply_to_all(X, x)
@@ -0,0 +1,182 @@
1
+ from typing import Literal
2
+
3
+ import numpy as np
4
+
5
+ from classiq.qmod.builtins.functions.allocation import free
6
+ from classiq.qmod.builtins.functions.standard_gates import CX, SWAP, X
7
+ from classiq.qmod.builtins.operations import allocate, bind, control, invert, repeat
8
+ from classiq.qmod.qfunc import qperm
9
+ from classiq.qmod.qmod_variable import Input, Output, QArray, QBit, QNum
10
+
11
+
12
+ def get_rewire_list(qvars: list[QBit]) -> list[QBit]:
13
+ rewire_list = qvars[int(np.log2(len(qvars))) :]
14
+ for i, qvar in enumerate(qvars[: int(np.log2(len(qvars)))]):
15
+ rewire_list.insert(2 ** (i + 1) - 1, qvar)
16
+ return rewire_list
17
+
18
+
19
+ @qperm
20
+ def inplace_binary_to_one_hot(qvar: QArray) -> None:
21
+ """
22
+ Inplace conversion of binary encoded value to one-hot encoding.
23
+ The implementation is based on https://quantumcomputing.stackexchange.com/questions/5526/garbage-free-reversible-binary-to-unary-decoder-construction.
24
+ The input is assumed to be of size 2^n, where n is the number of bits in the binary representation.
25
+ For example, the state |01000>=|2> will be converted to |00100> (one-hot for 2).
26
+
27
+ Args:
28
+ qvar: binary input array padded with 0's to be converted to one-hot encoding.
29
+ """
30
+ temp_qvars = [QBit(f"x{i}") for i in range(qvar.len)]
31
+ bind(qvar, temp_qvars) # type: ignore[arg-type]
32
+ bind(get_rewire_list(temp_qvars), qvar) # type: ignore[arg-type]
33
+
34
+ # logic
35
+ X(qvar[0])
36
+ for i in range(int(np.log2(qvar.len))):
37
+ index = 2 ** (i + 1) - 1
38
+ for j in range(2**i - 1):
39
+ control(qvar[index], lambda i=i, j=j: SWAP(qvar[j], qvar[j + 2**i])) # type: ignore[misc]
40
+ for j in range(2**i - 1):
41
+ CX(qvar[j + 2**i], qvar[index])
42
+
43
+ CX(qvar[index], qvar[index - 2**i])
44
+
45
+
46
+ @qperm
47
+ def inplace_one_hot_to_unary(qvar: QArray) -> None:
48
+ """
49
+ Inplace conversion of one-hot encoded value to unary encoding.
50
+ The input is assumed to be of size n, where n is the number of bits in the one-hot representation.
51
+ The remaining unary representation will at the higher n-1 bits, where the lsb is cleared to 0.
52
+ For example, the state |0010> (one-hot for 2) will be converted to |0>|110> (unary for 2).
53
+
54
+ Args:
55
+ qvar: one-hot input array to be converted to unary encoding.
56
+ """
57
+ # fill with 1s after the leading 1 bit
58
+ repeat(qvar.len - 1, lambda i: CX(qvar[qvar.len - i - 1], qvar[qvar.len - i - 2]))
59
+ # clear the 0 bit, to be excluded from the unary encoding
60
+ X(qvar[0])
61
+
62
+
63
+ @qperm
64
+ def one_hot_to_unary(one_hot: Input[QArray], unary: Output[QArray]) -> None:
65
+ """
66
+ Conversion of one-hot encoded value to unary encoding. The output `unary` variable
67
+ is smaller in 1 qubit than the input `one_hot` variable.
68
+ For example, the state |0010> (one-hot for 2) will be converted to |110> (unary for 2).
69
+
70
+ Args:
71
+ one_hot: one-hot input array to be converted to unary encoding.
72
+ unary: unary output array.
73
+ """
74
+ inplace_one_hot_to_unary(one_hot)
75
+ lsb: QBit = QBit()
76
+ bind(one_hot, [lsb, unary])
77
+ free(lsb)
78
+
79
+
80
+ @qperm
81
+ def one_hot_to_binary(
82
+ one_hot: Input[QArray],
83
+ binary: Output[QNum[Literal["ceiling(log(one_hot.len, 2))"]]],
84
+ ) -> None:
85
+ """
86
+ Conversion of one-hot encoded value to binary encoding. The output `binary` variable
87
+ is of size log2(one_hot.size) rounded up.
88
+ For example, the state |0010> (one-hot for 2) will be converted to |01>=|2>.
89
+
90
+ Args:
91
+ one_hot: one-hot input array to be converted to binary encoding.
92
+ binary: binary output variable.
93
+ """
94
+ extension: QArray = QArray()
95
+ invert(lambda: inplace_binary_to_one_hot(one_hot))
96
+ bind(one_hot, [binary, extension])
97
+ free(extension)
98
+
99
+
100
+ @qperm
101
+ def unary_to_binary(unary: Input[QArray], binary: Output[QNum]) -> None:
102
+ """
103
+ Conversion of unary encoded value to binary encoding. The output `binary` variable
104
+ is of size log2(unary.size + 1) rounded up.
105
+ For example, the state |110> (unary for 2) will be converted to |01>=|2>.
106
+
107
+ Args:
108
+ unary: unary input array to be converted to binary encoding.
109
+ binary: binary output variable.
110
+ """
111
+ one_hot: QArray = QArray()
112
+ unary_to_one_hot(unary, one_hot)
113
+ one_hot_to_binary(one_hot, binary)
114
+
115
+
116
+ @qperm
117
+ def unary_to_one_hot(unary: Input[QArray], one_hot: Output[QArray]) -> None:
118
+ """
119
+ Conversion of unary encoded value to one-hot encoding. The output `one_hot` variable
120
+ is larger in 1 qubit than the input `unary` variable.
121
+ For example, the state |110> (unary for 2) will be converted to |0010> (one-hot for 2).
122
+
123
+ Args:
124
+ unary: unary input array to be converted to one-hot encoding.
125
+ one_hot: one-hot output array.
126
+ """
127
+ lsb: QBit = QBit()
128
+ allocate(lsb)
129
+ bind([lsb, unary], one_hot)
130
+ invert(lambda: inplace_one_hot_to_unary(one_hot))
131
+
132
+
133
+ @qperm
134
+ def binary_to_one_hot(binary: Input[QNum], one_hot: Output[QArray]) -> None:
135
+ """
136
+ Conversion of binary encoded value to one-hot encoding. The output `one_hot` variable
137
+ is of size 2^n, where n is the number of bits in the binary representation.
138
+ For example, the state |01>=|2> will be converted to |0010> (one-hot for 2).
139
+
140
+ Args:
141
+ binary: binary input variable to be converted to one-hot encoding.
142
+ one_hot: one-hot output array.
143
+ """
144
+ extension: QArray = QArray()
145
+ allocate(2**binary.size - binary.size, extension)
146
+ bind([binary, extension], one_hot)
147
+
148
+ inplace_binary_to_one_hot(one_hot)
149
+
150
+
151
+ @qperm
152
+ def binary_to_unary(binary: Input[QNum], unary: Output[QArray]) -> None:
153
+ """
154
+ Conversion of binary encoded value to unary encoding. The output `unary` variable
155
+ is of size 2^n - 1, where n is the number of bits in the binary representation.
156
+ For example, the state |01>=|2> will be converted to |110> (unary for 2).
157
+
158
+ Args:
159
+ binary: binary input variable to be converted to unary encoding.
160
+ unary: unary output array.
161
+ """
162
+ one_hot: QArray = QArray()
163
+ binary_to_one_hot(binary, one_hot)
164
+ one_hot_to_unary(one_hot, unary)
165
+
166
+
167
+ @qperm
168
+ def pad_zeros(total_size: int, qvar: Input[QArray], padded: Output[QArray]) -> None:
169
+ """
170
+ Pad the input qvar with additional qubits at the end to reach the total_size.
171
+
172
+ Args:
173
+ total_size: The desired total size after padding.
174
+ qvar: The input quantum array to be padded.
175
+ padded: The output quantum array after padding.
176
+ """
177
+ extension: QArray = QArray()
178
+ allocate(total_size - qvar.len, extension)
179
+ bind([qvar, extension], padded)
180
+
181
+
182
+ # TODO: when the functions can have default arguments, add `pad` function with direction and value