classiq 0.71.0__py3-none-any.whl → 0.72.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.
Files changed (54) 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/generator/expressions/expression_types.py +4 -1
  12. classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +135 -0
  13. classiq/interface/generator/functions/builtins/internal_operators.py +1 -0
  14. classiq/interface/generator/generated_circuit_data.py +13 -0
  15. classiq/interface/generator/hardware/hardware_data.py +3 -1
  16. classiq/interface/generator/transpiler_basis_gates.py +3 -1
  17. classiq/interface/hardware.py +1 -0
  18. classiq/interface/model/handle_binding.py +21 -0
  19. classiq/interface/server/routes.py +0 -2
  20. classiq/model_expansions/atomic_expression_functions_defs.py +35 -13
  21. classiq/model_expansions/closure.py +0 -9
  22. classiq/model_expansions/evaluators/parameter_types.py +6 -10
  23. classiq/model_expansions/interpreters/base_interpreter.py +4 -4
  24. classiq/model_expansions/interpreters/generative_interpreter.py +33 -5
  25. classiq/model_expansions/quantum_operations/__init__.py +0 -2
  26. classiq/model_expansions/quantum_operations/block_evaluator.py +16 -2
  27. classiq/model_expansions/quantum_operations/call_emitter.py +4 -1
  28. classiq/model_expansions/quantum_operations/emitter.py +26 -9
  29. classiq/model_expansions/quantum_operations/handle_evaluator.py +1 -1
  30. classiq/model_expansions/quantum_operations/quantum_function_call.py +49 -0
  31. classiq/model_expansions/quantum_operations/repeat_block_evaluator.py +34 -0
  32. classiq/model_expansions/scope.py +34 -14
  33. classiq/model_expansions/scope_initialization.py +8 -4
  34. classiq/model_expansions/transformers/model_renamer.py +69 -63
  35. classiq/model_expansions/utils/sympy_utils.py +24 -0
  36. classiq/model_expansions/visitors/variable_references.py +1 -0
  37. classiq/qmod/builtins/functions/__init__.py +8 -0
  38. classiq/qmod/builtins/functions/allocation.py +36 -0
  39. classiq/qmod/builtins/functions/arithmetic.py +10 -5
  40. classiq/qmod/builtins/functions/mid_circuit_measurement.py +3 -0
  41. classiq/qmod/builtins/operations.py +2 -2
  42. classiq/qmod/model_state_container.py +9 -0
  43. classiq/qmod/symbolic.py +16 -3
  44. {classiq-0.71.0.dist-info → classiq-0.72.1.dist-info}/METADATA +1 -1
  45. {classiq-0.71.0.dist-info → classiq-0.72.1.dist-info}/RECORD +46 -51
  46. classiq/applications/finance/finance_model_constructor.py +0 -137
  47. classiq/applications/grover/__init__.py +0 -9
  48. classiq/applications/grover/grover_model_constructor.py +0 -167
  49. classiq/applications/libraries/__init__.py +0 -0
  50. classiq/applications/libraries/qmci_library.py +0 -22
  51. classiq/applications/qsvm/qsvm_model_constructor.py +0 -131
  52. classiq/model_expansions/quantum_operations/classicalif.py +0 -57
  53. classiq/model_expansions/quantum_operations/repeat.py +0 -62
  54. {classiq-0.71.0.dist-info → classiq-0.72.1.dist-info}/WHEEL +0 -0
@@ -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
- )