0.21.0 - 2026-08-25
- Added the
strategyargument toGroupGatesIntoBoxesto determine how to to assign two-qubit gates to boxes, allowing for new strategies like"alap". The default behavior has not changed and corresponds to the"asap"strategy. This can also be specified with the newboxing_strategyargument ofgenerate_boxing_pass_manager. (#380) - Added support for
delayinGroupGatesIntoBoxes,GroupMeasIntoBoxes, andAddTerminalRightDressedBoxes. Added support forresetinGroupGatesIntoBoxesandAddTerminalRightDressedBoxes. (#381) - Added support for
Delayoperations withStretchdurations. (#384) - Added
decompositionargument toAddTerminalRightDressedBoxes. (#392) - Added
samplomatic.quantum_programmodule to storeQuantumProgram,QuantumProgramResults, and all the related classes. (#396)
- Fixed a crash in
generate_boxing_pass_managerwhen the input circuit contained inlineGlobalPhaseGate(or other zero-bit) instructions. TheGroupGatesIntoBoxesandGroupMeasIntoBoxespasses now treat zero-qubit standard gates as pass-through and no longer fail on operations with emptyqargsandcargs(such as a zero-width barrier). Note that, independently,build()does not and has never preservedQuantumCircuit.global_phasein the template circuit; this expected behavior is now documented in thebuild()docstring. (#377) - Fixed
samplomatic.visualization.plot_graph()to draw straight lines between nodes when the edge data is missing. Prior to this fix, it used a spline that sometimes ended up curved in strange ways. (#378) - The
decompositionargument now applies to terminal right dressed-boxes ingenerate_boxing_pass_manager. Previously, it would always userzsx. (#392) - When the boxing pass manager encounters an instruction whose name starts with
"meas", it treats it as a standard measurement instruction. (#399) - Named reset instructions, such as
"reset_2", are now recognized by the boxing passes and by :class:~.BoxKey. (#400)
0.20.0 - 2026-06-23
- The default value for the inject noise site for the
generate_boxing_pass_manager,AddInjectNoise, andInjectNoisehas been updated from'before'toNone, which results in a future warning and sets the value to'before'. In a future release, the default will be updated to'after'. (#372)
-
Added support for propagating Pauli twirls past single-qubit Clifford gates (
s,sx,sdg,sxdg, and compositions withh) and through single-qubit rotations (rz,p,rx) at Clifford angles when they appear between entangling gates inside aTwirlbox. (#351) -
Exposed three primitives that together let consumers of
build()evaluate deterministic template parameters (e.g.,RZZangles) without invokingSamplex.sample:Samplex.param_table— return the underlyingParameterExpressionTable.Samplex.passthrough_params— a tuple(template_idxs, expression_idxs)mapping each passthrough template parameter to its expression-table index.ParameterExpressionTable.evaluate— gained an optionalindicesargument so callers can evaluate only a chosen subset of the table's expressions.
(#367)
-
Random phases are now applied to qubits after mid-circuit measurement twirling. (#369)
-
Added reset twirling. Rather than propagating virtual registers, a reset in a twirl‑annotated box discards them and instead samples and injects a new random phase following the reset. (#371)
- Twirl emissions are now inserted at the easy-hard boundary of boxes with a
Twirlannotation"left"dressing when building. Previously, they were inserted after the content of the box. (#368)
- Measurement twirling is now implemented using virtual gate propagation. A virtual Pauli is propagated past a measure by discarding its
zcomponent, while propagating itsxcomponent and recording it as a bit flip. Previously, measurement twirling was implemented by collecting bit flips associated with virtual gates exclusively in the right hand side of a left-dressed box. The new approach allows for more flexible measurement twirling, e.g., sequential measurements of the same qubit to different clbits in the same box and measurement twirling in right-dressed boxes. (#369) - Removed the restriction of having a single entangler type when using
Group.local_c1. (#370)
- Fixed an issue when using
GroupMode.local_paulitwirling where the fallback for Clifford gates to the Pauli group would not trigger when a fractional gate was also present. (#370) - Fixed a bug where untwirled measurements in annotated boxes did not block leftwards virtual gate propagation. (#373)
0.19.0 - 2026-05-19
- Removed the warn-on-import about beta versions. (#353)
- Added support for
delayinstructions inside ofutils.BoxKeyobjects. (#350) - Added Pauli twirling for
rzzinstructions for non-zero Clifford angles. (#356) - Added local C1 twirling support for
rzzinstructions for non-zero Clifford angles. Added thelocal_paulitwirling group mode. This group mode will twirl gates with the subgroup of Paulis that remain local Paulis under conjugation. In particular, this allows for twirling of parametric and non-Cliffordrzzinstructions. When anrzzis encountered, the samples are drawn from the Pauli subgroup that commutes withrzz. For Cliffords, it defaults back to the Pauli group. This mode is set by annotating a box with aTwirlthat hasTwirl.group_mode = local_paulior by using a boxing pass manager withtwirling_group = local_pauli. Added thephasegroup mode that samples uniformly from Paulis I and Z. (#357)
- Increased the SSV from 3 to 4. (#357)
- Fixed a per-sample sign error in samplex sampling that occurred when an
InjectLocalClifford-annotated box body contained multiple parallel multi-qubit gates (e.g.cz(0,1)andcz(2,3)in the same box). The parallel-propagate merge optimization inPreSamplexre-created the merged node with a fresh high graph index, which caused the loweredCombineRegistersNodeto receive its operands in the wrong order and silently apply the basis-change Clifford in the wrong position of the matrix product. (#356)
0.18.0 - 2026-04-09
- Added the
add_tagsoption to :func:~samplomatic.transpiler.generate_boxing_pass_managerand the :class:~samplomatic.transpiler.passes.AddTagstranspiler pass. When enabled, a :class:~samplomatic.annotations.Tagannotation is automatically added to every box. Two modes are supported:'unique_box'assigns the same hash-based ref to structurally equivalent boxes, and'unique_instance'assigns a unique incrementing ref (t0,t1, ...) to every box in the circuit. (#342) - Added the
debugoption tobuild()that populates debug/trace information on samplex nodes, enabling users to trace nodes back to their originating box annotations. (#345) - Added
map_annotations(),strip_annotations(),filter_annotations(),extend_annotations(), andreplace_annotations()utilities tosamplomtic.utilsfor modifying annotations on existing circuits. (#347)
- Improved the two synthesizers
RzRxSynthandRzSxSynthto always generate Clifford angles when given a U2 gate that is Clifford. It is only possible to end up with non-Clifford angles when the gate being synthesized is a Z rotation, or a pi-gate of some angle. Either case leads to a degree of freedom in how to distribute the angle between the first and last RZ gate of the synthesis. This was fixed by enforcing the last angle be 0 in both cases. (#341)
- Fixed
samplomatic.utils.default_normalize_annotations()to also keepTagannotations, in addition toInjectNoiseandTwirlannotations. (#343)
0.17.1 - 2026-03-16
- Fixed a serialization issue with
LeftMultiplicationNodeandRightMultiplicationNodewhere the current SSV was used when serializing the operand, causing backwards compatibility issues. (#337)
0.17.0 - 2026-03-12
- Removed
TWIRLING_GROUPSandGroupLiteralfromannotationsin favor ofGroupMode. (#300)
- Added
BalancedUniformPaulidistribution that ensures the same number of X/Y and I/Z are chosen on each qubit. (#264) - Added
GroupModeenum to configure the twirling distribution onTwirlannotations. (#300) - Added serialization support for
BalancedUniformPaulidistribution (SSV 3). (#301) - Added the local Clifford twirling group. This group twirls a two-qubit entangling gate with the subgroup of single-qubit Cliffords that remain single-qubit Clifford under conjugation. This feature is enabled by using a
Twirlannotation withGroupMode.LOCAL_C1or"local_c1"as the group. To support new groups like the local Clifford twirling group, added thetwirling_groupkeyword argument to thegenerate_boxing_pass_managerfunction with default"pauli". Added thePropagateLocalC1Nodeand supporting lookup tables in the newtablesmodule. Added theUniformLocalC1distribution. (#308) - Added
samplomatic.utils.unbox()utility function for inlining box operations from a circuit. (#318) - Added the
Tagannotation to provide trace information of a box on corresponding barriers after thebuildprocess. The same mechanism is used to include theInjectNoise.refon corresponding barriers as well. (#319) - Added the
UniformPauliSubsetdistribution that samples from a given subset of Paulis. (#332) - Added
DistributionSamplingNodethat samples from any distribution and places the result into a register. This differs fromTwirlSamplingNodein that we do not instantiate a sample and inverse-sample pair, just a sample. (#334)
- Increased the default SSV from
2to3. (#336) - Changed
Twirl.groupparameter to acceptGroupModevalues instead ofVirtualType. (#300) - Updated minimum qiskit version to 2.3.0. (#304)
- Lookup tables for single-qubit Cliffords,
C1_LOOKUP_TABLEandC1_INVERSE_TABLE, that were in thevirtual_registers.tablessubmodule have been moved to the top-leveltablesmodule. (#308) - SSV 3 serializes
Distributions using dedicated serializers. Previously, they were specified ad-hoc by the serializer ofTwirlSamplingNode. (#332)
- Updated noise injection to use the new and improved method. (#304)
- Reduced the number of
SliceRegisterNodes thatbuild()puts into samplexes by eliminating those slices that act trivially on their inputs. (#311)
- Fixed an issue where unsupported virtual types could be serialized for SSV 1. (#315)
- Made
BoxKeyhashing deterministic across Python processes by using SHA-256 instead of the built-inhash(), which is randomized byPYTHONHASHSEED. This causedAddInjectNoiseto generate differentrefnames for identical boxes across runs, since it derived short hash keys fromBoxKey.__hash__. Also fixed a bug inAddInjectNoise._get_ref()where the computed ref was not being cached correctly. It is expected that these bugs were only visible when this pass was being run in parallel by the qiskit pass manager. (#322)
0.16.1 - 2026-01-22
- Fixed handling of building of
BoxOps appended directly to aqiskit.QuantumCircuit. This fixes issues where theBoxOp.body.qubitsare different than those on the containing circuit, and ensures arguments on aSamplexare in the correct order. (#297)
0.16.0 - 2026-01-19
- Added the
InjectNoise.siteattribute to specify whether the noise should be injected before or after the hard content of a dressed box. Added theinject_noise_siteargument to thegenerate_boxing_pass_managerfunction to specify where noise should be injected. (#280) - Added the
decompositionargument to thesamplomatic.transpiler.generate_boxing_pass_manager()function that causes allTwirlandChangeBasisannotations added by the pass manager to have the specified dressing gate decomposition. The current allowed values are'rzsx'(default) and'rzrx'. The same argument was also added to theGroupMeasIntoBoxespass, and theGroupGatesIntoBoxespass similarly gained an argumentannotations. (#284) - Added the
num_bytesattribute toSpecification,TensorSpecification, andPauliLindbladMapSpecification, and thenum_bytes()method toTensorInterface, to estimate memory usage for interface data. (#289)
- The constructor of the
GroupMeasIntoBoxestranspiler pass now only accepts keyword arguments. (#284) - The
ChangeBasisannotation now acceptsdressingandmodeas independent arguments. Peviously, amodeofpreparewould result in arightdressing, while ameasurewould result in aleftdressing. (#285) - The
AddInjectNoisepass now generates references based on the hash of a box'sBoxKey, resulting in the same reference from run to run of the pass. Additionally, it increments individual modifier references starting from0in each run. (#291)
- Fixed imports to not assume that the
typingsubpackage exists in thenumpynamespace; the lineimport numpy; numpy.typingfails in some environments, whereasimport numpy.typing; numpy.typingalways succeeds under the current version restrictions. (#286) - Fixed a bug where parametric gates with fixed parameters outside of boxes caused building to fail. (#294)
0.15.0 - 2025-12-15
- Added the
TemplateState.finalizeandTemplateState.qubitsmethods to facilitate constructing the template circuit as aqiskit.dagcircuit.DAGCircuitduring thebuildprocess. (#270) - Added the
Builder.yield_from_dagmethod. This method provides an iteration order such that all of the easy gates and hard gates will be yielded topologically in two separate groups separated by a sentinel, defining the easy-hard boundary of a dressed box. (#273) - Added the
InjectLocalCliffordannotation. This annotation allows for the specification of single-qubit Clifford frame changes atSamplex.sampletime by adding alocal_clifford.refargument to its inputs. The input expects an integer array following the same convention as theC1Register. (#275)
- The
pre_buildfunction now constructs the template as aqiskit.dagcircuit.DAGCircuitas opposed to aqiskit.QuantumCircuit. Methods onBoxBuilder,PassthroughBuilder,PreSamplex, andTemplateStatethat previously hadqiskit.circuit.CircuitInstructionin their signature now haveqiskit.dagcircuit.DAGOpNodeinstead. The signature of thebuildfunction has not changed, but now calls theTemplateState.finalizemethod to construct theqiskit.QuantumCircuit. (#270)
- Fixed the samplex serializer to encode all information in the header at the specified SSV, rather than encoding some of it at the most recent SSV irrespective of the specified version. (#276)
0.14.0 - 2025-12-09
- Removed the
VirtualRegister.to_json_dictand thevirtual_register_from_jsonfunction. (#223) - Removed support for Python 3.9 following its end-of-life date. (#244)
- The modules
.transpiler.noise_injection_strategies,.transpiler.twirling_strategies, and their contents have been removed. These files contained enum classes for specifying arguments to some of the transpiler passes; these arguments must now be specified as strings. (#257) - Temporarily removed support for
IfElseOpinstructions inside of boxes---we are in the middle of refactoring this to make it more general, but we cannot wait for it to be complete to make a new release. Please refrain from upgrading if this breaks your workflow, and apologies.
- Deprecated boolean values for the
remove_barriersargument ofsamplomatic.transpiler.generate_boxing_pass_manager. Now, the four options are'immediately','finally,,'after_stratification', and'never', whereTrueandFalseare equivalent to the first and last string values, respectively. The default value is'after_stratification'which is a change in behavior, but should be a better choice in most cases. (#238)
- Added SSV
2serializers forBasisChangeandChangeBasisNode. (#223) - Added
C1Register, a virtual register of single-qubit Cliffords, and theUniformC1distribution. - Added
FiniteGroupRegister. (#224) - Added support to
samplomatic.utils.get_annotationfor specifying multiple annotation types. (#237)
- Increased the default SSV from
1to2. (#224) - Changed the scope of the transpiler passes
GroupGatesIntoBoxes,GroupMeasIntoBoxes, andAddTerminalRightDressedBoxes. Formerly, all three of these passes were responsible for discovering single-qubit gates in the input circuit and moving them into newly created boxes. Now, to simplify their implementations and make the pass manager more modular, these three passes no longer have this responsibility, which has instead been delegated to the new passAbsorbSingleQubitGates. In particular,GroupGatesIntoBoxesandGroupMeasIntoBoxesare now responsible only for inserting new left-dressed boxes populated only with entangling and measurement instructions. Similarly,AddTerminalRightDressedBoxesinserts empty right-dressed boxes boxes. Thegenerate_boxing_pass_managerfunction has been updated to includeAbsorbSingleQubitGates. (#237) - Changed the behaviour of the pass manager returned by
samplomatic.transpiler.generate_boxing_pass_managerunder default settings with respect to how it treats barriers. Before, it would discard all barriers before attempting to put entangling gates into boxes. Now, it discards barriers after entangling gates are put into boxes, but before single-qubit gates are moved into adjacent boxes. This means that barriers can effectively be used as hints to choose how to stratify entangling gates without constraining single-qubit gates to end up in their own boxes. This also has better interaction with the Qiskit transpiler in the case that the original circuit is programmed in terms of a different entangling gate than the target. See the new possible values of the argumentremove_barriersfor details. (#238) - The
DataSerializer.serializenow requires the SSV as an argument. (#254) - Arguments to
samplomatic.transpiler.generate_boxing_pass_managerare now required to be keyword arguments. Moreover, all string-valued selection arguments (e.g.twirling_strategy) are required to be specified as strings because the enum classes have been removed. (#257) - Changed the default
twirling_strategyofsamplomatic.transpiler.generate_boxing_pass_managerfrom"active"to"active_circit". This was done because the latter is a safer default. Typically, when twirling, one wants to eliminate all coherent error on active qubits. The"active"strategy is only able to do this under certain assumptions about noise processes. (#265)
0.13.0 - 2025-11-06
- A samplex built with
buildalways returnsparameter_valuesas an output. If it does not generate parameter values, theparameter_valueswill have shape("num_randomizations", 0). Previously,parameter_valueswould not be included in its outputs. (#225)
- Fixed a bug where the slicing indices of
SliceRegisterNodeswere wrong, causing circuits with non-standard ordering to sample incorrectly (particularly withmerge_parallel_pre_propagate_nodesenabled). (#229)
0.12.0 - 2025-11-03
- Added a new serialization versioning system, the Samplex Serialization Version (SSV), that decouples the
serialization version from the package version. The current version is stored in
samplomatic.ssv.SSV. See thesamplomatic.serializationmodule for details. (#216) - Added a
Serializablemetaclass to record which classes should be serializable. (#216) - Added
DataSerializer,TypeSerializer, andTypeSerializerMetato provide serialization for objects inheriting fromSerializable. (#216)
- The samplex serialization functions
samplex_to_jsonandsamplex_from_jsonwere moved to thesamplomatic.serializationmodule. (#216) - Classes that are serializable now inherit from
Serializablerather than implementingto_json/from_jsonmethods. ATypeSerializerwith the corresponding type will then contain methods to serialize and deserialize the object. (#216)
0.11.0 - 2025-10-28
- Added the ability to provide inputs to
Samplex.sample()as arbitrary mappings. (#186)
- Changed the serialization format of
qiskit.circuit.ParameterExpressions within the samplex serializer. (#185) - Negated the convention for what boolean outputs mean when sampling Pauli Lindblad maps with negative
rates. Following this change, the
InjectNoiseNodesamplex node intentionally uses the opposite convention as :meth:qiskit.quantum_info.PauliLindbladMap.signed_samplefor representing signs as boolean values. In particular, values written by this node now represent the parity of the number of non-trivial factors in the sampled error that arise from negative rates. In other words, when using the boolean written by this node to implement basic PEC, the sign used to correct expectation values should be(-1)**bool_value. (#188)
- Fixed a bug that prevented
qiskit.circuit.ParameterExpressions from being decoded when present in a samplex' expression table. (#185)
0.10.1 - 2025-10-22
- Fixed a bug where the
build()process was mishandling an optimization step in the case the base circuit contains multiplerx(orrz) gates in the same layer with distinct bound numeric values (e.g.circuit.rx(0.123, 0)). (#179)
0.10.0 - 2025-10-20
- Removed the
NoiseModelRequirementclass and the associated methodSamplex.add_noise_requirement()and attributeSamplex.noise_requirements. Instead, all noise model requirements are integrated intoSamplex.inputs(). (#164) - Removed
samplomatic.tensor_interface.ValueType. (#164)
- Added a new subclass
samplomatic.tensor_interface.PauliLindbladNoiseSpecificationofsamplomatic.tensor_interface.Specification. (#164) - Added the concept of
free_dimensionstosamplomatic.tensor_inteface.Specification, which comes with assocated methods and attributes. A free dimension is a string name of an integer quantity whose value is not known until values have been bound to the specification in asamplomatic.tensor_interface.TensorInterface, and all free dimensions with the same name in the interface need to have a consistent value or an error will be raised during binding. (#164)
- Throughout the library, the terms noise map and noise model have been replaced with the more descriptive Pauli Lindblad map. (#126)
- Replace
generate_boxing_pass_manager's argumentenable_measurewithenable_measures. (#153) - The
twirling_strategyof pass managers no longer supportsactive-circuitandactive-accum, useactive_circuitandactive_accuminstead. (#156) - Overhauled how noise models are specified on the
Samplex. Rates and Pauli lists that define Pauli Lindblad maps are no longer separated into the respective distinct entries"noise_maps.rates.<ref>"and"noise_maps.paulis.<ref>"ofSamplex.inputs(). Instead, they are specified as a single entry"pauli_lindblad_maps.<ref>"that expects typeqiskit.quantum_info.PauliLindbladMap. Moreover,Samplex.noise_requirementsis removed (along with the concept ofNoiseModelRequirement). Instead, the specification for"pauli_lindblad_maps<ref>"withinSamplex.inputs()dictates the required number of qubits the noise model should act on, and the number of terms can be chosen at the time thatSamplex.sample()is called so long as it is consistent. (#164) - Converted
samplomatic.tensor_interface.Specificationto an abstract class. (#164) - Changed
samplomatic.samplex.interfaces.SamplexOutputto not construct empty data arrays on construction, it is now the caller's responsibility to populate the data. This does not affect users ofSamplex.sample(). (#164) - The format returned by
samplomatic.samplex.samplex_serialization.samplex_to_json()changed to accomodate the absense of noise requirements, and it (and the reverse functionsamplex_from_json()) are not backwards compatible with the previous minor version. (#164) - Renamed
samplomatic.BasisTransformtosamplomatic.ChangeBasisin order to make all annotations start with a verb, and to consolidate all names around "change" rather than "transform". Likewise, renamedsamplomatic.samplex.nodes.BasisTransformNodetosamplomatic.samplex.nodes.ChangeBasisNode. - Renamed string literal option for from
"basis_transform"to"change_basis"in bothsamplomatic.transpiler.generate_boxing_pass_managerandsamplomatic.transpiler.passes.GroupMeasIntoBoxes. (#172)
- Made
TwirlingStrategyLiteralconsistent withTwirlingStrategyenum by replacingactive-circuitwithactive_circuitandactive-accumandactive_accum. (#156) - Fixed the basis changing gates for
ChangeBasisNodefor Pauli Y. (#161) - Fixed the ordering of
ChangeBasisNodeto conform with the rest of the library. (#161)
0.9.0 - 2025-09-30
- Added the
targetsinput to theAddInjectNoisepass to specify boxes to add anInjectNoiseannotation to. - Added the
inject_noise_targetsinput togenerate_boxing_pass_manager()to trigger this ability in the boxing transpiler. (#143) - Added a warning at import time about the beta status of this project. The warning should only be raised once per version, see
CONTRIBUTING.mdfor details. (#132)
- Removed
NoiseInjectionStrategy.NONEas it is now redundant with one of the supported values forAddInjectNoise.targets. (#143)
- Fixed a bug where
Samplex.__str__()would raise an error for samplexes that require a noise model. (#124)
0.8.0 - 2025-09-22
- Added
add_twirling,add_basis_transform, andprefix_refarguments toGroupMeasIntoBoxesto allow specifying what annotations should be placed on the boxes containing measurements. Addedmeasure_annotationsargument to the boxing passmanager to allow specifying what annotations should be placed on the boxes containing measurements. (#96) - Added
InlineBoxespass to inline every box in the input circuit, replacing it with its content. (#123)
- Changed the minimal supported Python version to 3.9. (#119)
- Changed
parameter_valuesoutput type ofSamplex.samplefromnp.float64tonp.float32. (#120)
- Fixed a bug where
GroupGatesIntoBoxeswould group gates in a suboptimal way (#110)
0.7.0 - 2025-09-15
- Removed the
PauliRegister.from_paulismethod. (#14)
- Added a
widthargument toTensorInterface.describe()for text wrapping, and added this description toSamplex.__str__(). (#104) - Added a
NoiseModelRequirementclass that describes a noise model required by aSamplexat sample time. Added aSamplex.noise_modelsproperty containing a dictionary ofNoiseModelRequirements. (#112) - Added
InjectNoiseandBasisTransformto the top-level module, allowing, for example,from samplomatic import InjectNoise, BasisTransform. (#117)
- Measurement flips are now returned with shape
(num_randomizations, 1, num_qubits)to facilitate processing against a shots axis. Previously, they would be returned as(num_randomizations, num_qubits). (#105) - In order to facilitate broadcasting,
Samplex.sample()now expects an array of rates and aqiskit.quantum_info.QubitSparsePauliListfor each noise reference. Previously, it expected aqiskit.quantum_info.PauliLindbladMap. This change is reflected inSamplex.inputs()which now requires aqiskit.quantum_info.QubitSparsePauliListfor each element ofSamplex.noise_models. The returnedTensorInterfaceobject then contains the boundQubitSparsePauliLists, as well asTensorSpecifications for the rates, the scale, and the local scales. (#112)
Samplex.samplearguments corresponding toBasisTransformandInjectNoiseannotations are indexed in physical qubit order, in other words, the order of the qubits in the outer-most circuit, restricted to those used by the box. Previously, they followed the order ofCircuitInstruction.qubits. (#116)
- The
ParameterExpressionTable.evaluatemethod now usesParameterExpression.bind_allto increase performance. (#13) - The
InjectNoise.samplenow uses theQubitSparsePauliList.to_dense_arraymethod for increased performance. (#14)
0.6.0 - 2025-09-03
- Added an
optionalfield toSpecification. (#94)
- Modified
undress_boxso that if the input box contains noTwirlannotation, it returns a copy of the box rather than the box itself. (#98)
- Fixed a bug where the
modifier_refs ofInjectNoiseannotations were not being added to a samplex. (#94) - Fixed a bug with imports for
numpyversions older than2.0.0. (#99)
0.5.0 - 2025-08-26
- Added new boolean option
remove_barrierstogenerate_boxing_pass_manager()that adds theRemoveBarrierspass to the returned pass manager when true. (#88)
- The pass manager returned by
generate_boxing_pass_manager()now removes all pre-existing barriers, by default. (#88)
0.4.0 - 2025-08-26
- Added support for measurements after twirled measurements. (#82)
- Moved
num_randomizationsback to a kwarg ofSamplex.sample(). This has flip-flopped a couple of times as we optimize workflow. (#84)
- Fixed a bug in
TensorInterface.__getitem__for non-string inputs where it was incorrectly attempting to slice arrays whose shape did not match the full broadcasted shape of the interface. (#83) - Fixed serialization of
Samplexby including the passthrough parameters field. Previously, this would result in inconsistent output parameter values when sampling from the same samplex with the same input arguments. (#86)
0.3.0 - 2025-08-22
- Removed
samplomatic.samplex.interfaces.SamplexInput, just usesamplomatic.tensor_interface.TensorInterfaceinstead. (#79)
- Added the
broadcastableattribute toTensorSpecification, with the behaviour that all broadcastable tensor values given to aTensorInterfaceare allowed to be mutually broadcastable. (#79)
- Measurement bit-flips included in the output of
Samplex.sampleare now stored per classical register rather than a single array, for example, the former single entry"measurement_flips"will now be two entries"measurement_flips.alpha"and"measurement_flips.beta"if the underlying circuit has two classical registers named"alpha"and"beta". (#78) - Renamed and moved
samplomatic.samplex.interfaces.Interfacetosamplomatic.tensor_interface.TensorInterface. Likewise movedSpecificationandTensorSpecificationtosamplomatic.tensor_interface. ChangedSamplex.inputs()to return aTensorSpecification, populated with what used to be the defaults ofSamplexInput. (#79)
0.2.0 - 2025-08-20
- Added the
Samplex.inputs()andSamplex.outputs()methods to query the required inputs and promised outputs ofSamplex.sample(). (#75)
- Renamed the parameter
sizetonum_randomizationsin theSamplex.sample()method. (#69) - The
build()function now callsSamplex.finalize()so that it does not need to be called afterwards manually. Additionally, theSamplex.finalize()method now returns itself for chaining calls. (#72) - The
Samplex.sample()method now takes aSamplexInputas argument rather than keyword arguments. This object can be constructed with the newSamplex.inputs()method and only includes arguments pertinent to a given instance ofSamplex. (#75)
0.1.0 - 2025-08-15
- Initial population of the library with features, including:
- transpiler passes to aid in the boxing of circuits with annotations
- the
samplomatic.Samplexobject and all necessary infrastructure to describe certain types of basic Pauli randomization and noise injection - certain but not comprehensive support for dynamic circuits
- the
build()method for interpretting boxed-up circuits into template/samplex pairs (#38)