classiq 0.70.0__py3-none-any.whl → 0.72.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 (98) hide show
  1. classiq/__init__.py +0 -6
  2. classiq/_internals/client.py +11 -1
  3. classiq/applications/chemistry/chemistry_model_constructor.py +18 -16
  4. classiq/applications/combinatorial_helpers/optimization_model.py +9 -2
  5. classiq/applications/combinatorial_helpers/pyomo_utils.py +6 -1
  6. classiq/applications/finance/__init__.py +0 -3
  7. classiq/applications/qsvm/__init__.py +0 -2
  8. classiq/interface/_version.py +1 -1
  9. classiq/interface/backend/backend_preferences.py +22 -0
  10. classiq/interface/backend/quantum_backend_providers.py +2 -0
  11. classiq/interface/debug_info/debug_info.py +4 -0
  12. classiq/interface/generator/expressions/expression_constants.py +0 -3
  13. classiq/interface/generator/expressions/expression_types.py +8 -3
  14. classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +135 -0
  15. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -0
  16. classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +5 -1
  17. classiq/interface/generator/expressions/proxies/classical/utils.py +34 -0
  18. classiq/interface/generator/functions/builtins/internal_operators.py +1 -0
  19. classiq/interface/generator/functions/classical_type.py +1 -1
  20. classiq/interface/generator/functions/type_name.py +16 -0
  21. classiq/interface/generator/functions/type_qualifier.py +7 -0
  22. classiq/interface/generator/generated_circuit_data.py +14 -1
  23. classiq/interface/generator/hardware/hardware_data.py +3 -1
  24. classiq/interface/generator/quantum_function_call.py +8 -1
  25. classiq/interface/generator/synthesis_execution_parameter.py +1 -0
  26. classiq/interface/generator/transpiler_basis_gates.py +3 -1
  27. classiq/interface/generator/types/compilation_metadata.py +1 -0
  28. classiq/interface/hardware.py +1 -0
  29. classiq/interface/ide/visual_model.py +1 -0
  30. classiq/interface/interface_version.py +1 -1
  31. classiq/interface/model/allocate.py +7 -0
  32. classiq/interface/model/block.py +12 -0
  33. classiq/interface/model/classical_if.py +4 -0
  34. classiq/interface/model/handle_binding.py +21 -0
  35. classiq/interface/model/inplace_binary_operation.py +4 -0
  36. classiq/interface/model/model.py +3 -1
  37. classiq/interface/model/phase_operation.py +4 -0
  38. classiq/interface/model/port_declaration.py +3 -0
  39. classiq/interface/model/power.py +4 -0
  40. classiq/interface/model/quantum_expressions/quantum_expression.py +4 -0
  41. classiq/interface/model/quantum_function_call.py +4 -0
  42. classiq/interface/model/quantum_function_declaration.py +1 -1
  43. classiq/interface/model/quantum_statement.py +5 -0
  44. classiq/interface/model/quantum_type.py +22 -0
  45. classiq/interface/model/repeat.py +4 -0
  46. classiq/interface/model/statement_block.py +3 -0
  47. classiq/interface/model/variable_declaration_statement.py +5 -0
  48. classiq/interface/server/routes.py +0 -2
  49. classiq/model_expansions/atomic_expression_functions_defs.py +35 -13
  50. classiq/model_expansions/capturing/captured_vars.py +156 -34
  51. classiq/model_expansions/closure.py +0 -9
  52. classiq/model_expansions/evaluators/classical_type_inference.py +70 -0
  53. classiq/model_expansions/evaluators/parameter_types.py +20 -10
  54. classiq/model_expansions/expression_evaluator.py +0 -11
  55. classiq/model_expansions/function_builder.py +2 -8
  56. classiq/model_expansions/generative_functions.py +7 -30
  57. classiq/model_expansions/interpreters/base_interpreter.py +7 -8
  58. classiq/model_expansions/interpreters/generative_interpreter.py +33 -5
  59. classiq/model_expansions/quantum_operations/__init__.py +0 -2
  60. classiq/model_expansions/quantum_operations/block_evaluator.py +16 -2
  61. classiq/model_expansions/quantum_operations/call_emitter.py +49 -6
  62. classiq/model_expansions/quantum_operations/emitter.py +64 -6
  63. classiq/model_expansions/quantum_operations/expression_evaluator.py +4 -0
  64. classiq/model_expansions/quantum_operations/handle_evaluator.py +1 -1
  65. classiq/model_expansions/quantum_operations/quantum_function_call.py +49 -0
  66. classiq/model_expansions/quantum_operations/repeat_block_evaluator.py +34 -0
  67. classiq/model_expansions/scope.py +33 -21
  68. classiq/model_expansions/scope_initialization.py +28 -32
  69. classiq/model_expansions/transformers/model_renamer.py +69 -63
  70. classiq/model_expansions/utils/sympy_utils.py +24 -0
  71. classiq/model_expansions/visitors/variable_references.py +1 -0
  72. classiq/qmod/__init__.py +3 -1
  73. classiq/qmod/builtins/functions/__init__.py +8 -0
  74. classiq/qmod/builtins/functions/allocation.py +36 -0
  75. classiq/qmod/builtins/functions/arithmetic.py +10 -5
  76. classiq/qmod/builtins/functions/mid_circuit_measurement.py +3 -0
  77. classiq/qmod/builtins/operations.py +2 -2
  78. classiq/qmod/declaration_inferrer.py +52 -24
  79. classiq/qmod/model_state_container.py +9 -0
  80. classiq/qmod/native/pretty_printer.py +25 -3
  81. classiq/qmod/pretty_print/pretty_printer.py +31 -14
  82. classiq/qmod/python_classical_type.py +12 -1
  83. classiq/qmod/qfunc.py +33 -8
  84. classiq/qmod/qmod_variable.py +188 -147
  85. classiq/qmod/quantum_function.py +3 -4
  86. classiq/qmod/semantics/validation/type_hints.py +19 -10
  87. classiq/qmod/symbolic.py +16 -3
  88. {classiq-0.70.0.dist-info → classiq-0.72.0.dist-info}/METADATA +1 -1
  89. {classiq-0.70.0.dist-info → classiq-0.72.0.dist-info}/RECORD +90 -91
  90. classiq/applications/finance/finance_model_constructor.py +0 -137
  91. classiq/applications/grover/__init__.py +0 -9
  92. classiq/applications/grover/grover_model_constructor.py +0 -167
  93. classiq/applications/libraries/__init__.py +0 -0
  94. classiq/applications/libraries/qmci_library.py +0 -22
  95. classiq/applications/qsvm/qsvm_model_constructor.py +0 -131
  96. classiq/model_expansions/quantum_operations/classicalif.py +0 -57
  97. classiq/model_expansions/quantum_operations/repeat.py +0 -62
  98. {classiq-0.70.0.dist-info → classiq-0.72.0.dist-info}/WHEEL +0 -0
@@ -1,137 +0,0 @@
1
- import warnings
2
- from math import floor, log
3
- from typing import Union
4
-
5
- from classiq.interface.exceptions import ClassiqError
6
- from classiq.interface.finance.function_input import FinanceFunctionInput
7
- from classiq.interface.finance.gaussian_model_input import GaussianModelInput
8
- from classiq.interface.finance.log_normal_model_input import LogNormalModelInput
9
- from classiq.interface.generator.expressions.expression import Expression
10
- from classiq.interface.generator.functions.port_declaration import (
11
- PortDeclarationDirection,
12
- )
13
- from classiq.interface.model.allocate import Allocate
14
- from classiq.interface.model.handle_binding import HandleBinding
15
- from classiq.interface.model.model import Model, SerializedModel
16
- from classiq.interface.model.native_function_definition import NativeFunctionDefinition
17
- from classiq.interface.model.port_declaration import PortDeclaration
18
- from classiq.interface.model.quantum_function_call import QuantumFunctionCall
19
- from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
20
- from classiq.interface.model.quantum_type import QuantumNumeric
21
- from classiq.interface.model.variable_declaration_statement import (
22
- VariableDeclarationStatement,
23
- )
24
-
25
- from classiq.applications.libraries.qmci_library import QMCI_LIBRARY
26
- from classiq.qmod.utilities import qmod_val_to_expr_str
27
-
28
- _OUTPUT_VARIABLE_NAME = "payoff_estimation"
29
-
30
-
31
- def construct_finance_model(
32
- finance_model_input: Union[LogNormalModelInput, GaussianModelInput],
33
- finance_function_input: FinanceFunctionInput,
34
- phase_port_size: int,
35
- ) -> SerializedModel:
36
- warnings.warn(
37
- "Function 'construct_finance_model' has been deprecated and will no longer"
38
- "be supported starting on 03/02/2025 the earliest\nHint: It is now possible to "
39
- "implement Option Pricing in pure Qmod. For example, see the Option Pricing notebook on the "
40
- "Classiq library at https://github.com/Classiq/classiq-library/blob/main/applications/finance/option_pricing/option_pricing.ipynb",
41
- category=DeprecationWarning,
42
- stacklevel=2,
43
- )
44
- if isinstance(finance_model_input, LogNormalModelInput):
45
- finance_model = f"struct_literal(LogNormalModel, num_qubits={finance_model_input.num_qubits}, mu={finance_model_input.mu}, sigma={finance_model_input.sigma})"
46
- finance_function = "log_normal_finance"
47
- post_process_function = "log_normal_finance_post_process"
48
- total_num_qubits = finance_model_input.num_qubits
49
- elif isinstance(finance_model_input, GaussianModelInput):
50
- finance_model = f"struct_literal(GaussianModel, num_qubits={finance_model_input.num_qubits}, normal_max_value={finance_model_input.normal_max_value}, default_probabilities={finance_model_input.default_probabilities}, rhos={finance_model_input.rhos}, loss={finance_model_input.loss}, min_loss={finance_model_input.min_loss})"
51
- finance_function = "gaussian_finance"
52
- post_process_function = "gaussian_finance_post_process"
53
- total_num_qubits = (
54
- finance_model_input.num_qubits
55
- + len(finance_model_input.rhos)
56
- + floor(log(sum(finance_model_input.loss), 2))
57
- + 1
58
- )
59
- else:
60
- raise ClassiqError(f"Invalid model input: {finance_model_input}")
61
-
62
- polynomial_degree = 0
63
- if finance_function_input.polynomial_degree is not None:
64
- polynomial_degree = finance_function_input.polynomial_degree
65
-
66
- tail_probability = 0.0
67
- if finance_function_input.tail_probability is not None:
68
- tail_probability = finance_function_input.tail_probability
69
-
70
- finance_function_object = f"struct_literal(FinanceFunction, f={qmod_val_to_expr_str(finance_function_input.f)}, threshold={finance_function_input.condition.threshold}, larger={finance_function_input.condition.larger}, polynomial_degree={polynomial_degree}, use_chebyshev_polynomial_approximation={finance_function_input.use_chebyshev_polynomial_approximation}, tail_probability={tail_probability})"
71
- num_unitary_qubits = total_num_qubits + 1
72
-
73
- model = Model(
74
- functions=[
75
- *QMCI_LIBRARY,
76
- NativeFunctionDefinition(
77
- name="main",
78
- positional_arg_declarations=[
79
- PortDeclaration(
80
- name="phase_port",
81
- quantum_type=QuantumNumeric(
82
- size=Expression(expr=f"{phase_port_size}"),
83
- is_signed=Expression(expr="False"),
84
- fraction_digits=Expression(expr=f"{phase_port_size}"),
85
- ),
86
- direction=PortDeclarationDirection.Output,
87
- ),
88
- ],
89
- body=[
90
- VariableDeclarationStatement(name="unitary_port"),
91
- Allocate(
92
- size=Expression(expr=f"{num_unitary_qubits}"),
93
- target=HandleBinding(name="unitary_port"),
94
- ),
95
- Allocate(
96
- size=Expression(expr=f"{phase_port_size}"),
97
- target=HandleBinding(name="phase_port"),
98
- ),
99
- QuantumFunctionCall(
100
- function="qmci",
101
- positional_args=[
102
- QuantumLambdaFunction(
103
- pos_rename_params=["state", "ind"],
104
- body=[
105
- QuantumFunctionCall(
106
- function=finance_function,
107
- positional_args=[
108
- Expression(expr=finance_model),
109
- Expression(expr=finance_function_object),
110
- HandleBinding(name="state"),
111
- HandleBinding(name="ind"),
112
- ],
113
- ),
114
- ],
115
- ),
116
- HandleBinding(name="phase_port"),
117
- HandleBinding(name="unitary_port"),
118
- ],
119
- ),
120
- ],
121
- ),
122
- ],
123
- classical_execution_code=f"""
124
- phase_port_size = {phase_port_size}
125
- counts = sample()
126
- save({{"counts": counts}})
127
- probability_estimation = qae_with_qpe_result_post_processing(
128
- estimation_register_size=phase_port_size,
129
- estimation_method=1,
130
- result=counts
131
- )
132
- save({{"probability_estimation": probability_estimation}})
133
- {_OUTPUT_VARIABLE_NAME} = {post_process_function}({finance_model}, {finance_function_object}, probability_estimation)
134
- save({{"{_OUTPUT_VARIABLE_NAME}": {_OUTPUT_VARIABLE_NAME}}})
135
- """.strip(),
136
- )
137
- return model.get_model()
@@ -1,9 +0,0 @@
1
- from .grover_model_constructor import construct_grover_model
2
-
3
- __all__ = [
4
- "construct_grover_model",
5
- ]
6
-
7
-
8
- def __dir__() -> list[str]:
9
- return __all__
@@ -1,167 +0,0 @@
1
- import warnings
2
-
3
- from classiq.interface.generator.expressions.expression import Expression
4
- from classiq.interface.generator.functions.port_declaration import (
5
- PortDeclarationDirection,
6
- )
7
- from classiq.interface.model.allocate import Allocate
8
- from classiq.interface.model.bind_operation import BindOperation
9
- from classiq.interface.model.handle_binding import HandleBinding, SlicedHandleBinding
10
- from classiq.interface.model.model import Model, SerializedModel
11
- from classiq.interface.model.native_function_definition import NativeFunctionDefinition
12
- from classiq.interface.model.port_declaration import PortDeclaration
13
- from classiq.interface.model.quantum_expressions.arithmetic_operation import (
14
- ArithmeticOperation,
15
- ArithmeticOperationKind,
16
- )
17
- from classiq.interface.model.quantum_function_call import QuantumFunctionCall
18
- from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
19
- from classiq.interface.model.quantum_type import QuantumBitvector, QuantumNumeric
20
- from classiq.interface.model.variable_declaration_statement import (
21
- VariableDeclarationStatement,
22
- )
23
-
24
- from classiq import RegisterUserInput
25
- from classiq.open_library.functions.grover import grover_search, phase_oracle
26
-
27
- _OUTPUT_VARIABLE_NAME = "result"
28
-
29
- _PREDICATE_FUNCTION_NAME = "expr_predicate"
30
-
31
-
32
- def _arithmetic_oracle_ios(
33
- definitions: list[tuple[str, RegisterUserInput]], handle_name: str
34
- ) -> list[HandleBinding]:
35
- cursor = 0
36
- ios: list[HandleBinding] = []
37
- for _, reg in definitions:
38
- ios.append(
39
- SlicedHandleBinding(
40
- base_handle=HandleBinding(name=handle_name),
41
- start=Expression(expr=f"{cursor}"),
42
- end=Expression(expr=f"{cursor + reg.size}"),
43
- )
44
- )
45
- cursor += reg.size
46
- return ios
47
-
48
-
49
- def _construct_arithmetic_oracle(
50
- predicate_function: str,
51
- definitions: list[tuple[str, RegisterUserInput]],
52
- ) -> QuantumFunctionCall:
53
- predicate_var_binding = _arithmetic_oracle_ios(definitions, "state")
54
- predicate_var_binding.append(HandleBinding(name="oracle"))
55
- return QuantumFunctionCall(
56
- function="phase_oracle",
57
- positional_args=[
58
- QuantumLambdaFunction(
59
- pos_rename_params=["state", "oracle"],
60
- body=[
61
- QuantumFunctionCall(
62
- function=predicate_function,
63
- positional_args=predicate_var_binding,
64
- ),
65
- ],
66
- ),
67
- HandleBinding(name="packed_vars"),
68
- ],
69
- )
70
-
71
-
72
- def grover_main_port_declarations(
73
- definitions: list[tuple[str, RegisterUserInput]],
74
- direction: PortDeclarationDirection,
75
- ) -> list[PortDeclaration]:
76
- return [
77
- PortDeclaration(
78
- name=name,
79
- quantum_type=QuantumNumeric(
80
- size=Expression(expr=f"{reg.size}"),
81
- is_signed=Expression(expr=f"{reg.is_signed}"),
82
- fraction_digits=Expression(expr=f"{reg.fraction_places}"),
83
- ),
84
- direction=direction,
85
- )
86
- for name, reg in definitions
87
- ]
88
-
89
-
90
- def construct_grover_model(
91
- definitions: list[tuple[str, RegisterUserInput]],
92
- expression: str,
93
- num_reps: int = 1,
94
- ) -> SerializedModel:
95
- warnings.warn(
96
- "Function 'construct_grover_model' has been deprecated and will no longer"
97
- "be supported starting on 03/02/2025 the earliest\nHint: It is now possible to "
98
- "implement the Grover algorithm in pure Qmod. For example, see the Grover notebook on the "
99
- "Classiq library at https://github.com/Classiq/classiq-library/blob/main/algorithms/grover/3_sat_grover/3_sat_grover.ipynb",
100
- category=DeprecationWarning,
101
- stacklevel=2,
102
- )
103
- predicate_port_decls = grover_main_port_declarations(
104
- definitions, PortDeclarationDirection.Inout
105
- )
106
- predicate_port_decls.append(
107
- PortDeclaration(
108
- name="res",
109
- quantum_type=QuantumBitvector(length=Expression(expr="1")),
110
- direction=PortDeclarationDirection.Inout,
111
- )
112
- )
113
- num_qubits = sum(reg.size for _, reg in definitions)
114
-
115
- grover_model = Model(
116
- functions=[
117
- NativeFunctionDefinition(
118
- name=_PREDICATE_FUNCTION_NAME,
119
- positional_arg_declarations=predicate_port_decls,
120
- body=[
121
- ArithmeticOperation(
122
- expression=Expression(expr=expression),
123
- result_var=HandleBinding(name="res"),
124
- operation_kind=ArithmeticOperationKind.InplaceXor,
125
- ),
126
- ],
127
- ),
128
- NativeFunctionDefinition(
129
- name="main",
130
- positional_arg_declarations=grover_main_port_declarations(
131
- definitions, PortDeclarationDirection.Output
132
- ),
133
- body=[
134
- VariableDeclarationStatement(name="packed_vars"),
135
- Allocate(
136
- size=Expression(expr=f"{num_qubits}"),
137
- target=HandleBinding(name="packed_vars"),
138
- ),
139
- QuantumFunctionCall(
140
- function="grover_search",
141
- positional_args=[
142
- Expression(expr=f"{num_reps}"),
143
- QuantumLambdaFunction(
144
- pos_rename_params=["packed_vars"],
145
- body=[
146
- _construct_arithmetic_oracle(
147
- _PREDICATE_FUNCTION_NAME,
148
- definitions,
149
- )
150
- ],
151
- ),
152
- HandleBinding(name="packed_vars"),
153
- ],
154
- ),
155
- BindOperation(
156
- in_handles=[HandleBinding(name="packed_vars")],
157
- out_handles=[
158
- HandleBinding(name=name) for name, _ in definitions
159
- ],
160
- ),
161
- ],
162
- ),
163
- *[f for f in grover_search.create_model().functions if f.name != "main"],
164
- *[f for f in phase_oracle.create_model().functions if f.name != "main"],
165
- ],
166
- )
167
- return grover_model.get_model()
File without changes
@@ -1,22 +0,0 @@
1
- from classiq.open_library.functions.amplitude_estimation import amplitude_estimation
2
- from classiq.qmod.builtins.functions import Z
3
- from classiq.qmod.qfunc import qfunc
4
- from classiq.qmod.qmod_variable import QArray, QBit, QNum
5
- from classiq.qmod.quantum_callable import QCallable
6
-
7
-
8
- @qfunc
9
- def qmci(
10
- space_transform: QCallable[QArray[QBit], QBit],
11
- phase: QNum,
12
- packed_vars: QArray[QBit],
13
- ) -> None:
14
- amplitude_estimation(
15
- lambda reg: Z(reg[reg.len - 1]),
16
- lambda reg: space_transform(reg[0 : reg.len - 1], reg[reg.len - 1]),
17
- phase,
18
- packed_vars,
19
- )
20
-
21
-
22
- QMCI_LIBRARY = [func for func in qmci.create_model().functions if func.name != "main"]
@@ -1,131 +0,0 @@
1
- import warnings
2
- from typing import Any
3
-
4
- from classiq.interface.applications.qsvm import DataList, LabelsInt
5
- from classiq.interface.exceptions import ClassiqValueError
6
- from classiq.interface.generator.expressions.expression import Expression
7
- from classiq.interface.generator.functions.port_declaration import (
8
- PortDeclarationDirection,
9
- )
10
- from classiq.interface.model.allocate import Allocate
11
- from classiq.interface.model.handle_binding import HandleBinding
12
- from classiq.interface.model.model import Model, SerializedModel
13
- from classiq.interface.model.native_function_definition import NativeFunctionDefinition
14
- from classiq.interface.model.port_declaration import PortDeclaration
15
- from classiq.interface.model.quantum_function_call import QuantumFunctionCall
16
- from classiq.interface.model.quantum_statement import QuantumStatement
17
-
18
- from classiq.qmod.builtins.enums import Pauli, QSVMFeatureMapEntanglement
19
- from classiq.qmod.utilities import qmod_val_to_expr_str
20
-
21
- INVALID_FEATURE_MAP_FUNC_NAME_MSG = "Invalid feature_map_function_name, it can be bloch_sphere_feature_map or pauli_feature_map"
22
-
23
- _OUTPUT_VARIABLE_NAME = "qsvm_results"
24
-
25
-
26
- def _bloch_sphere_feature_map_function_params(
27
- bloch_feature_dimension: int,
28
- ) -> tuple[list[Expression], str]:
29
- return [
30
- Expression(expr=f"{bloch_feature_dimension}")
31
- ], f"ceiling({bloch_feature_dimension}/2)"
32
-
33
-
34
- def _pauli_feature_map_function_params(
35
- paulis: list[list[Pauli]],
36
- entanglement: QSVMFeatureMapEntanglement,
37
- alpha: int,
38
- reps: int,
39
- feature_dimension: int,
40
- ) -> tuple[list[Expression], str]:
41
- paulis_str = (
42
- "["
43
- + ",".join(
44
- [
45
- "[" + ",".join([qmod_val_to_expr_str(p) for p in p_list]) + "]"
46
- for p_list in paulis
47
- ]
48
- )
49
- + "]"
50
- )
51
- pauli_feature_map_params = (
52
- f"paulis={paulis_str}, "
53
- f"entanglement={qmod_val_to_expr_str(entanglement)}, "
54
- f"alpha={alpha}, "
55
- f"reps={reps}, "
56
- f"feature_dimension={feature_dimension}"
57
- )
58
- return [
59
- Expression(
60
- expr=f"struct_literal(QSVMFeatureMapPauli, {pauli_feature_map_params})"
61
- )
62
- ], f"{feature_dimension}"
63
-
64
-
65
- def get_qsvm_qmain_body(
66
- feature_map_function_name: str, **kwargs: Any
67
- ) -> list[QuantumStatement]:
68
- if feature_map_function_name == "bloch_sphere_feature_map":
69
- params, size_expr = _bloch_sphere_feature_map_function_params(**kwargs)
70
- elif feature_map_function_name == "pauli_feature_map":
71
- params, size_expr = _pauli_feature_map_function_params(**kwargs)
72
- else:
73
- raise ClassiqValueError(INVALID_FEATURE_MAP_FUNC_NAME_MSG)
74
-
75
- return [
76
- Allocate(
77
- size=Expression(expr=size_expr),
78
- target=HandleBinding(name="qbv"),
79
- ),
80
- QuantumFunctionCall(
81
- function=feature_map_function_name,
82
- positional_args=[*params, HandleBinding(name="qbv")],
83
- ),
84
- ]
85
-
86
-
87
- def construct_qsvm_model(
88
- train_data: DataList,
89
- train_labels: LabelsInt,
90
- test_data: DataList,
91
- test_labels: LabelsInt,
92
- predict_data: DataList,
93
- feature_map_function_name: str,
94
- **kwargs: Any,
95
- ) -> SerializedModel:
96
- warnings.warn(
97
- "Function 'construct_qsvm_model' has been deprecated and will no longer"
98
- "be supported starting on 03/02/2025 the earliest\nHint: It is now possible to "
99
- "implement QSVM in pure Qmod. For example, see the QSVM notebook on the "
100
- "Classiq library at https://github.com/Classiq/classiq-library/blob/main/algorithms/qml/qsvm/qsvm.ipynb",
101
- category=DeprecationWarning,
102
- stacklevel=2,
103
- )
104
- qsvm_qmod = Model(
105
- functions=[
106
- NativeFunctionDefinition(
107
- name="main",
108
- positional_arg_declarations=[
109
- PortDeclaration(
110
- name="qbv",
111
- direction=PortDeclarationDirection.Output,
112
- ),
113
- ],
114
- body=get_qsvm_qmain_body(
115
- feature_map_function_name=feature_map_function_name, **kwargs
116
- ),
117
- ),
118
- ],
119
- classical_execution_code=f"""
120
- {_OUTPUT_VARIABLE_NAME} = qsvm_full_run(
121
- train_data={train_data},
122
- train_labels={train_labels},
123
- test_data={test_data},
124
- test_labels={test_labels},
125
- predict_data={predict_data}
126
- )
127
- save({{{_OUTPUT_VARIABLE_NAME!r}: {_OUTPUT_VARIABLE_NAME}}})
128
- """.strip(),
129
- )
130
-
131
- return qsvm_qmod.get_model()
@@ -1,57 +0,0 @@
1
- from collections.abc import Sequence
2
-
3
- from classiq.interface.debug_info.debug_info import new_function_debug_info_by_node
4
- from classiq.interface.model.classical_if import ClassicalIf
5
- from classiq.interface.model.quantum_function_call import QuantumFunctionCall
6
- from classiq.interface.model.quantum_statement import QuantumStatement
7
-
8
- from classiq.model_expansions.closure import FunctionClosure
9
- from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
10
- from classiq.model_expansions.scope import Scope
11
-
12
-
13
- def _is_all_identity_calls(body: Sequence[QuantumStatement]) -> bool:
14
- return all(
15
- isinstance(stmt, QuantumFunctionCall) and stmt.func_name.lower() == "identity"
16
- for stmt in body
17
- )
18
-
19
-
20
- class ClassicalIfEmitter(CallEmitter[ClassicalIf]):
21
- def emit(self, classical_if: ClassicalIf, /) -> bool:
22
- condition = self._interpreter.evaluate(classical_if.condition).as_type(bool)
23
- op_name = "then" if condition else "else"
24
- is_generative = classical_if.is_generative()
25
-
26
- body: Sequence[QuantumStatement]
27
- if is_generative:
28
- if not classical_if.has_generative_block(op_name):
29
- return True
30
- context = self._expand_generative_context(classical_if, op_name, op_name)
31
- context.blocks["body"] = context.blocks[op_name]
32
- context.blocks.pop(op_name)
33
- body = context.statements("body")
34
- else:
35
- body = classical_if.then if condition else classical_if.else_
36
-
37
- if _is_all_identity_calls(body):
38
- return True
39
-
40
- if is_generative or not self._should_wrap(body):
41
- for stmt in body:
42
- if is_generative:
43
- self._interpreter._builder.emit_statement(stmt)
44
- else:
45
- self._interpreter.emit_statement(stmt)
46
- return True
47
-
48
- then_else_func = FunctionClosure.create(
49
- name=self._counted_name_allocator.allocate("then" if condition else "else"),
50
- body=body,
51
- scope=Scope(parent=self._current_scope),
52
- lambda_external_vars=self._builder.current_block.captured_vars,
53
- )
54
- self._emit_quantum_function_call(
55
- then_else_func, list(), new_function_debug_info_by_node(classical_if)
56
- )
57
- return True
@@ -1,62 +0,0 @@
1
- from classiq.interface.debug_info.debug_info import new_function_debug_info_by_node
2
- from classiq.interface.exceptions import ClassiqExpansionError
3
- from classiq.interface.generator.expressions.expression import Expression
4
- from classiq.interface.generator.functions.builtins.internal_operators import (
5
- REPEAT_OPERATOR_NAME,
6
- )
7
- from classiq.interface.generator.functions.classical_type import Integer
8
- from classiq.interface.model.classical_parameter_declaration import (
9
- ClassicalParameterDeclaration,
10
- )
11
- from classiq.interface.model.repeat import Repeat
12
-
13
- from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
14
- from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
15
- from classiq.model_expansions.scope import Scope
16
- from classiq.qmod.quantum_function import GenerativeQFunc
17
-
18
-
19
- class RepeatEmitter(CallEmitter[Repeat]):
20
- def emit(self, repeat: Repeat, /) -> bool:
21
- count = self._interpreter.evaluate(repeat.count).as_type(int)
22
- if count < 0:
23
- raise ClassiqExpansionError(
24
- f"repeat count must be non-negative, got {count}"
25
- )
26
- op_name = self._counted_name_allocator.allocate(REPEAT_OPERATOR_NAME)
27
- for i in range(count):
28
- self._emit_iteration(repeat, i, op_name)
29
- return True
30
-
31
- def _emit_iteration(self, repeat: Repeat, i: int, op_name: str) -> None:
32
- closure_constructor: type[FunctionClosure]
33
- extra_args: dict
34
- if repeat.is_generative():
35
- closure_constructor = GenerativeFunctionClosure
36
- extra_args = {
37
- "generative_blocks": {
38
- "body": GenerativeQFunc(
39
- repeat.get_generative_block("body"),
40
- ),
41
- }
42
- }
43
- else:
44
- closure_constructor = FunctionClosure
45
- extra_args = {}
46
- iteration_function = closure_constructor.create(
47
- name=op_name,
48
- positional_arg_declarations=[
49
- ClassicalParameterDeclaration(
50
- name=repeat.iter_var, classical_type=Integer()
51
- )
52
- ],
53
- body=repeat.body,
54
- scope=Scope(parent=self._current_scope),
55
- lambda_external_vars=self._builder.current_block.captured_vars,
56
- **extra_args,
57
- )
58
- self._emit_quantum_function_call(
59
- iteration_function,
60
- [Expression(expr=str(i))],
61
- new_function_debug_info_by_node(repeat),
62
- )