pyqrack-cuda 1.40.3__tar.gz → 1.42.0__tar.gz

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 (27) hide show
  1. {pyqrack_cuda-1.40.3/pyqrack_cuda.egg-info → pyqrack_cuda-1.42.0}/PKG-INFO +1 -1
  2. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/__init__.py +7 -5
  3. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/neuron_activation_fn.py +1 -1
  4. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/pauli.py +1 -1
  5. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/qrack_circuit.py +1 -1
  6. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/qrack_neuron.py +2 -1
  7. pyqrack_cuda-1.42.0/pyqrack/qrack_neuron_torch_layer.py +144 -0
  8. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/qrack_simulator.py +1 -1
  9. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/quimb_circuit_type.py +1 -1
  10. pyqrack_cuda-1.42.0/pyqrack/stats/__init__.py +6 -0
  11. pyqrack_cuda-1.42.0/pyqrack/stats/load_quantized_data.py +33 -0
  12. pyqrack_cuda-1.42.0/pyqrack/stats/quantize_by_range.py +51 -0
  13. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
  14. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack_cuda.egg-info/SOURCES.txt +4 -0
  15. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/setup.py +2 -2
  16. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/LICENSE +0 -0
  17. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/MANIFEST.in +0 -0
  18. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/Makefile +0 -0
  19. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/README.md +0 -0
  20. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyproject.toml +0 -0
  21. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/qrack_system/__init__.py +0 -0
  22. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack/qrack_system/qrack_system.py +0 -0
  23. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
  24. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
  25. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack_cuda.egg-info/requires.txt +0 -0
  26. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/pyqrack_cuda.egg-info/top_level.txt +0 -0
  27. {pyqrack_cuda-1.40.3 → pyqrack_cuda-1.42.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cuda
3
- Version: 1.40.3
3
+ Version: 1.42.0
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -1,12 +1,14 @@
1
- # (C) Daniel Strano and the Qrack contributors 2017-2021. All rights reserved.
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style license that can be
4
4
  # found in the LICENSE file or at https://opensource.org/licenses/MIT.
5
5
 
6
- from .qrack_system import QrackSystem, Qrack
7
- from .qrack_simulator import QrackSimulator
8
- from .qrack_neuron import QrackNeuron
9
- from .qrack_circuit import QrackCircuit
10
6
  from .pauli import Pauli
11
7
  from .neuron_activation_fn import NeuronActivationFn
12
8
  from .quimb_circuit_type import QuimbCircuitType
9
+ from .qrack_circuit import QrackCircuit
10
+ from .qrack_neuron import QrackNeuron
11
+ from .qrack_neuron_torch_layer import QrackTorchNeuron, QrackNeuronFunction, QrackNeuronTorchLayer
12
+ from .qrack_simulator import QrackSimulator
13
+ from .qrack_system import QrackSystem, Qrack
14
+ from .stats.quantize_by_range import quantize_by_range
@@ -1,4 +1,4 @@
1
- # (C) Daniel Strano and the Qrack contributors 2017-2021. All rights reserved.
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
2
  #
3
3
  # Pauli operators are specified for "b" (or "basis") parameters.
4
4
  #
@@ -1,4 +1,4 @@
1
- # (C) Daniel Strano and the Qrack contributors 2017-2021. All rights reserved.
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
2
  #
3
3
  # Pauli operators are specified for "b" (or "basis") parameters.
4
4
  #
@@ -1,4 +1,4 @@
1
- # (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style license that can be
4
4
  # found in the LICENSE file or at https://opensource.org/licenses/MIT.
@@ -1,4 +1,4 @@
1
- # (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style license that can be
4
4
  # found in the LICENSE file or at https://opensource.org/licenses/MIT.
@@ -9,6 +9,7 @@ import sys
9
9
  from .qrack_system import Qrack
10
10
  from .neuron_activation_fn import NeuronActivationFn
11
11
 
12
+
12
13
  class QrackNeuron:
13
14
  """Class that exposes the QNeuron class of Qrack
14
15
 
@@ -0,0 +1,144 @@
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
+ #
3
+ # Initial draft by Elara (OpenAI custom GPT)
4
+ # Refined and architecturally clarified by Dan Strano
5
+ #
6
+ # Use of this source code is governed by an MIT-style license that can be
7
+ # found in the LICENSE file or at https://opensource.org/licenses/MIT.
8
+
9
+ _IS_TORCH_AVAILABLE = True
10
+ try:
11
+ import torch
12
+ import torch.nn as nn
13
+ from torch.autograd import Function
14
+ except ImportError:
15
+ _IS_TORCH_AVAILABLE = False
16
+
17
+ from .qrack_simulator import QrackSimulator
18
+ from .qrack_neuron import QrackNeuron
19
+ from .neuron_activation_fn import NeuronActivationFn
20
+
21
+ from itertools import chain, combinations
22
+
23
+
24
+ # From https://stackoverflow.com/questions/1482308/how-to-get-all-subsets-of-a-set-powerset#answer-1482316
25
+ def powerset(iterable):
26
+ "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3,) (1,2,3)"
27
+ s = list(iterable)
28
+ return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
29
+
30
+
31
+ class QrackTorchNeuron(nn.Module):
32
+ """Torch wrapper for QrackNeuron
33
+
34
+ Attributes:
35
+ neuron(QrackNeuron): QrackNeuron backing this torch wrapper
36
+ """
37
+ def __init__(self, neuron: QrackNeuron) -> None:
38
+ super().__init__()
39
+ self.neuron = neuron
40
+
41
+ def forward(self, x):
42
+ neuron = self.neuron
43
+ neuron.predict(True, False)
44
+
45
+ return neuron.simulator.prob(neuron.target)
46
+
47
+
48
+ class QrackNeuronFunction(Function if _IS_TORCH_AVAILABLE else object):
49
+ """Static forward/backward/apply functions for QrackTorchNeuron"""
50
+ @staticmethod
51
+ def forward(ctx, neuron: object):
52
+ # Save for backward
53
+ ctx.neuron = neuron
54
+
55
+ init_prob = neuron.simulator.prob(neuron.target)
56
+ neuron.predict(True, False)
57
+ final_prob = neuron.simulator.prob(neuron.target)
58
+ ctx.delta = final_prob - init_prob
59
+
60
+ return torch.tensor([ctx.delta], dtype=torch.float32) if _IS_TORCH_AVAILABLE else ctx.delta
61
+
62
+ @staticmethod
63
+ def backward(ctx, grad_output):
64
+ neuron = ctx.neuron
65
+
66
+ pre_unpredict = neuron.simulator.prob(neuron.output_id)
67
+ neuron.unpredict()
68
+ post_unpredict = neuron.simulator.prob(neuron.output_id)
69
+ reverse_delta = pre_unpredict - post_unpredict
70
+
71
+ grad = reverse_delta - ctx.delta
72
+
73
+ return torch.tensor([grad], dtype=torch.float32) if _IS_TORCH_AVAILABLE else grad
74
+
75
+
76
+ class QrackNeuronTorchLayer(nn.Module if _IS_TORCH_AVAILABLE else object):
77
+ """Torch layer wrapper for QrackNeuron (with power set of neurons between inputs and outputs)"""
78
+ def __init__(self, simulator: object, input_indices: list[int], output_indices: list[int],
79
+ activation: int = int(NeuronActivationFn.Generalized_Logistic), parameters: list[float] = None):
80
+ """
81
+ Initialize a QrackNeuron layer for PyTorch with a power set of neurons connecting inputs to outputs.
82
+ The inputs and outputs must take the form of discrete, binary features (loaded manually into the backing QrackSimulator)
83
+
84
+ Args:
85
+ sim (QrackSimulator): Simulator into which predictor features are loaded
86
+ input_indices (list[int]): List of input bits
87
+ output_indices (list[int]): List of output bits
88
+ activation (int): Integer corresponding to choice of activation function from NeuronActivationFn
89
+ parameters (list[float]): (Optional) Flat list of initial neuron parameters, corresponding to little-endian basis states of power set of input indices, repeated for each output index (with empty set being constant bias)
90
+ """
91
+ super(QrackNeuronTorchLayer, self).__init__()
92
+ self.simulator = simulator
93
+ self.input_indices = input_indices
94
+ self.output_indices = output_indices
95
+ self.activation = NeuronActivationFn(activation)
96
+ self.fn = QrackNeuronFunction.apply if _IS_TORCH_AVAILABLE else lambda x: QrackNeuronFunction.forward(object(), x)
97
+
98
+ # Create neurons from all powerset input combinations, projecting to coherent output qubits
99
+ self.neurons = nn.ModuleList([
100
+ QrackTorchNeuron(QrackNeuron(simulator, list(input_subset), output_id, activation))
101
+ for input_subset in powerset(input_indices)
102
+ for output_id in output_indices
103
+ ])
104
+
105
+ # Set Qrack's internal parameters:
106
+ param_count = 0
107
+ for neuron_wrapper in self.neurons:
108
+ neuron = neuron_wrapper.neuron
109
+ p_count = 1 << len(neuron.controls)
110
+ neuron.set_angles(parameters[param_count:(param_count+p_count+1)] if parameters else ([0.0] * p_count))
111
+ param_count += p_count
112
+
113
+ self.weights = nn.ParameterList()
114
+ for pid in range(param_count):
115
+ self.weights.append(nn.Parameter(torch.tensor(parameters[pid] if parameters else 0.0)))
116
+
117
+ def forward(self, _):
118
+ # Assume quantum outputs should overwrite the simulator state
119
+ for output_id in self.output_indices:
120
+ if self.simulator.m(output_id):
121
+ self.simulator.x(output_id)
122
+ self.simulator.h(output_id)
123
+
124
+ # Set Qrack's internal parameters:
125
+ param_count = 0
126
+ for neuron_wrapper in self.neurons:
127
+ neuron = neuron_wrapper.neuron
128
+ p_count = 1 << len(neuron.controls)
129
+ angles = [w.item() for w in self.weights[param_count:(param_count+p_count)]]
130
+ neuron.set_angles(angles)
131
+ param_count += p_count
132
+
133
+ # Assume quantum inputs already loaded into simulator state
134
+ for neuron_wrapper in self.neurons:
135
+ self.fn(neuron_wrapper.neuron)
136
+
137
+ # These are classical views over quantum state; simulator still maintains full coherence
138
+ outputs = [
139
+ self.simulator.prob(output_id)
140
+ for output_id in self.output_indices
141
+ ]
142
+
143
+ return torch.tensor(outputs, dtype=torch.float32)
144
+
@@ -1,4 +1,4 @@
1
- # (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style license that can be
4
4
  # found in the LICENSE file or at https://opensource.org/licenses/MIT.
@@ -1,4 +1,4 @@
1
- # (C) Daniel Strano and the Qrack contributors 2017-2021. All rights reserved.
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
2
  #
3
3
  # Pauli operators are specified for "b" (or "basis") parameters.
4
4
  #
@@ -0,0 +1,6 @@
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
+ #
3
+ # Use of this source code is governed by an MIT-style license that can be
4
+ # found in the LICENSE file or at https://opensource.org/licenses/MIT.
5
+
6
+ from .quantize_by_range import quantize_by_range
@@ -0,0 +1,33 @@
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
+ #
3
+ # Load quantized data into a QrackSimulator
4
+ #
5
+ # Use of this source code is governed by an MIT-style license that can be
6
+ # found in the LICENSE file or at https://opensource.org/licenses/MIT.
7
+
8
+
9
+ def load_data(sim, index_bits, value_bits, data):
10
+ """
11
+ Take discretized features from quantize_by_range and load into a QrackSimulator
12
+
13
+ Args:
14
+ sim (QrackSimulator): Simulator into which to load data
15
+ index_bits (list[int]): List of index bits, least-to-most significant
16
+ value_bits (list[int]): List of value bits, least-to-most significant
17
+ data (list[list[bool]]): Data to load, row-major
18
+
19
+ Raises:
20
+ Value error: Length of value_bits does not match data feature column count!
21
+ """
22
+ if (len(data) > 0) and (len(value_bits) != len(data[0])):
23
+ raise ValueError("Length of value_bits does not match data feature column count!")
24
+
25
+ for i in range(index_bits):
26
+ if sim.m(i):
27
+ sim.x(i)
28
+ sim.h(i)
29
+
30
+ if len(data) == 0:
31
+ return
32
+
33
+ sim.lda(list(range(index_bits)), list(range(value_bits)), data)
@@ -0,0 +1,51 @@
1
+ # (C) Daniel Strano and the Qrack contributors 2017-2025. All rights reserved.
2
+ #
3
+ # Use of this source code is governed by an MIT-style license that can be
4
+ # found in the LICENSE file or at https://opensource.org/licenses/MIT.
5
+
6
+ try:
7
+ # Written by Elara (custom OpenAI GPT)
8
+ import numpy as np
9
+
10
+ def quantize_by_range(data: np.ndarray, feature_indices: list[int], bits: int) -> np.ndarray:
11
+ """
12
+ Discretize selected features of a dataset into binary variables using numpy.linspace binning.
13
+
14
+ Args:
15
+ data (np.ndarray): Input data of shape (n_samples, n_features).
16
+ feature_indices (list[int]): Indices of features to discretize.
17
+ bits (int): Number of bits to represent each discretized feature (e.g., 2 bits = 4 quantiles).
18
+
19
+ Returns:
20
+ np.ndarray: Transformed data with selected features replaced by binary bit columns.
21
+ """
22
+ n_samples, n_features = data.shape
23
+ n_bins = 2 ** bits
24
+
25
+ new_features = []
26
+ for i in range(n_features):
27
+ if i in feature_indices:
28
+ min_val, max_val = data[:, i].min(), data[:, i].max()
29
+ thresholds = np.linspace(min_val, max_val, n_bins + 1)[1:-1]
30
+ bins = np.digitize(data[:, i], bins=thresholds)
31
+ bin_bits = ((bins[:, None] & (1 << np.arange(bits)[::-1])) > 0).astype(int)
32
+ new_features.append(bin_bits)
33
+ else:
34
+ new_features.append(data[:, i][:, None]) # Keep original
35
+
36
+ return np.hstack(new_features)
37
+ except ImportError:
38
+ def quantize_by_range(data, feature_indices: list[int], bits: int):
39
+ """
40
+ Discretize selected features of a dataset into binary variables using numpy.linspace binning.
41
+
42
+ Args:
43
+ data (np.ndarray): Input data of shape (n_samples, n_features).
44
+ feature_indices (list[int]): Indices of features to discretize.
45
+ bits (int): Number of bits to represent each discretized feature (e.g., 2 bits = 4 quantiles).
46
+
47
+ Returns:
48
+ np.ndarray: Transformed data with selected features replaced by binary bit columns.
49
+ """
50
+ raise NotImplementedError("You must have numpy installed to use quantize_by_percentile()!")
51
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cuda
3
- Version: 1.40.3
3
+ Version: 1.42.0
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -9,10 +9,14 @@ pyqrack/neuron_activation_fn.py
9
9
  pyqrack/pauli.py
10
10
  pyqrack/qrack_circuit.py
11
11
  pyqrack/qrack_neuron.py
12
+ pyqrack/qrack_neuron_torch_layer.py
12
13
  pyqrack/qrack_simulator.py
13
14
  pyqrack/quimb_circuit_type.py
14
15
  pyqrack/qrack_system/__init__.py
15
16
  pyqrack/qrack_system/qrack_system.py
17
+ pyqrack/stats/__init__.py
18
+ pyqrack/stats/load_quantized_data.py
19
+ pyqrack/stats/quantize_by_range.py
16
20
  pyqrack_cuda.egg-info/PKG-INFO
17
21
  pyqrack_cuda.egg-info/SOURCES.txt
18
22
  pyqrack_cuda.egg-info/dependency_links.txt
@@ -7,7 +7,7 @@ from setuptools import setup
7
7
  from setuptools.command.build_py import build_py
8
8
 
9
9
 
10
- VERSION = "1.40.3"
10
+ VERSION = "1.42.0"
11
11
 
12
12
  # Read long description from README.
13
13
  README_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md')
@@ -27,7 +27,7 @@ class Build(build_py):
27
27
  setup(
28
28
  name='pyqrack-cuda',
29
29
  version=VERSION,
30
- packages=['pyqrack', 'pyqrack.qrack_system'],
30
+ packages=['pyqrack', 'pyqrack.qrack_system', 'pyqrack.stats'],
31
31
  cmdclass={"build_py": Build},
32
32
  description="pyqrack - Pure Python vm6502q/qrack Wrapper",
33
33
  long_description=README,
File without changes
File without changes
File without changes
File without changes
File without changes