16#ifndef _CIRCUIT_OPERATIONS_H_
17#define _CIRCUIT_OPERATIONS_H_
93 : bits(std::move(other.bits)) {}
129 bits.swap(other.bits);
163 bits.resize(bits.size() + numBits,
false);
189 if (index > bits.size())
return false;
201 std::vector<bool>
GetBits(
const std::vector<size_t> &indices)
const {
202 std::vector<bool> results(indices.size(),
false);
204 for (
size_t i = 0; i < indices.size(); ++i)
205 if (indices[i] < bits.size()) results[i] = bits[indices[i]];
233 void SetBit(
size_t index,
bool value =
true) {
234 if (index > bits.size())
return;
246 void Reset(
bool value =
false) { std::fill(bits.begin(), bits.end(), value); }
256 const size_t theSize = std::max(bits.size(), results.size());
259 bits.resize(theSize,
false);
270 void SetResults(
const std::vector<size_t> &indices,
size_t results) {
271 for (
int i = 0; i < static_cast<int>(indices.size()); ++i) {
272 if (indices[i] < bits.size()) bits[indices[i]] = results & 1;
299 void Remap(
const std::unordered_map<Types::qubit_t, Types::qubit_t> &mapping,
300 bool ignoreNotMapped =
false,
size_t newSize = 0) {
301 std::vector<bool> newBits(
302 newSize > 0 ? newSize
303 : (ignoreNotMapped ? mapping.size() : bits.size()),
306 for (
size_t i = 0; i < bits.size(); ++i) {
307 const auto it = mapping.find(i);
308 if (it != mapping.end())
309 newBits[it->second] = bits[i];
310 else if (!ignoreNotMapped && i < newBits.size())
311 newBits[i] = bits[i];
330 bool ignoreNotMapped =
false,
size_t newSize = 0) {
331 std::vector<bool> newBits(
332 newSize > 0 ? newSize
333 : (ignoreNotMapped ? mapping.size() : bits.size()),
336 for (
size_t i = 0; i < bits.size(); ++i) {
337 if (i < mapping.size())
338 newBits[mapping.at(i)] = bits[i];
339 else if (!ignoreNotMapped && i < newBits.size())
340 newBits[i] = bits[i];
347 std::vector<bool> bits;
359template <
typename Time = Types::time_type>
360class IOperation :
public std::enable_shared_from_this<IOperation<Time>> {
388 virtual void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
406 virtual std::shared_ptr<IOperation<Time>>
Clone()
const = 0;
418 virtual std::shared_ptr<IOperation<Time>>
Remap(
419 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
420 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
491 std::shared_ptr<IOperation<Time>>
getptr() {
492 return std::enable_shared_from_this<IOperation<Time>>::shared_from_this();
544template <
typename Time = Types::time_type>
567 void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
576 std::shared_ptr<IOperation<Time>>
Clone()
const override {
590 std::shared_ptr<IOperation<Time>>
Remap(
591 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
592 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap)
594 return this->
Clone();
617template <
typename Time = Types::time_type>
virtual Types::qubit_t GetQubit(unsigned int index=0) const =0
Get the qubit involved.
OperationType GetType() const override
Get the type of the operation.
virtual void SetQubit(Types::qubit_t qubit, unsigned long index=0)=0
Set the qubits involved.
IGateOperation(Time delay=0)
Construct a new IGateOperation object.
virtual unsigned int GetNumQubits() const =0
Get the number of qubits.
virtual bool IsClifford() const
Checks if the operation is a Clifford one.
virtual std::vector< size_t > AffectedBits() const
Returns the affected bits.
virtual bool CanAffectQuantumState() const
Find if the operation can affect the quantum state.
virtual Types::qubits_vector AffectedQubits() const
Returns the affected qubits.
Time GetDelay() const
Get the delay of the operation.
virtual void SetDelay(Time d)
Set the delay of the operation.
virtual OperationType GetType() const
Get the type of the operation.
virtual bool IsBranching() const
Checks if the operation is a branching one.
IOperation(Time delay=0)
Construct a new IOperation object.
virtual bool IsConditional() const
Find if the operation is a conditional operation.
virtual ~IOperation()=default
Destroy the IOperation object.
virtual std::shared_ptr< IOperation< Time > > Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &qubitsMap, const std::unordered_map< Types::qubit_t, Types::qubit_t > &bitsMap={}) const =0
Get a shared pointer to a remapped operation.
virtual std::shared_ptr< IOperation< Time > > Clone() const =0
Get a shared pointer to a clone of this object.
virtual void Execute(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const =0
Execute the operation.
std::shared_ptr< IOperation< Time > > getptr()
Get a shared pointer to this object.
virtual bool NeedsEntanglementForDistribution() const
Find if the operation needs entanglement for distribution.
std::shared_ptr< IOperation< Time > > Clone() const override
Get a shared pointer to a clone of this object.
bool IsClifford() const override
Checks if the operation is a Clifford one.
NoOperation(Time delay=0)
Construct a new NoOperation object.
void Execute(const std::shared_ptr< Simulators::ISimulator > &sim, OperationState &state) const override
Execute the operation.
std::shared_ptr< IOperation< Time > > Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &qubitsMap, const std::unordered_map< Types::qubit_t, Types::qubit_t > &bitsMap) const override
Get a shared pointer to a remapped operation.
The state class that stores the classical state of a quantum circuit execution.
void Reset(bool value=false)
Set the classical bits with the specified value.
OperationState(const OperationState &other)
Construct a new Operation State object.
const std::vector< bool > & GetAllBits() const
Get the classical bits.
OperationState(size_t numBits=0)
Construct a new Operation State object.
void AllocateBits(size_t numBits)
Allocate more bits.
OperationState(std::vector< bool > &&b)
Construct a new Operation State object.
std::vector< bool > GetBits(const std::vector< size_t > &indices) const
Get the classical bits at the specified indices.
void SetBit(size_t index, bool value=true)
Set the classical bit at the specified index.
OperationState & operator=(const std::vector< bool > &b)
Assign the bits.
void Clear()
Clear the classical state.
OperationState(OperationState &&other) noexcept
Construct a new Operation State object.
void SetResultsInOrder(const std::vector< bool > &results)
Set the classical bits.
size_t GetNumBits() const
Get the number of classical bits.
void Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &mapping, bool ignoreNotMapped=false, size_t newSize=0)
Convert the state using the provided mapping.
OperationState(const std::vector< bool > &b)
Construct a new Operation State object.
std::vector< bool > GetAllBitsCopy() const
Get the classical bits.
bool GetBit(size_t index) const
Get the classical bit at the specified index.
void RemapWithVector(const std::vector< Types::qubit_t > &mapping, bool ignoreNotMapped=false, size_t newSize=0)
Convert the state using the provided mapping.
OperationState & operator=(OperationState &&other) noexcept
Assign the bits.
void Swap(OperationState &results)
Set results.
OperationState & operator=(const OperationState &other)
Assign the bits.
OperationState & operator=(std::vector< bool > &&b)
Assign the bits.
void SetResults(const std::vector< size_t > &indices, size_t results)
Set the classical bits at the specified indices.
OperationType
The type of operations.
@ kConditionalGate
conditional gate, similar with gate, but conditioned on something from 'OperationState'
@ kDelay
a delay or idle period on one or more qubits
@ kNoOp
no operation, just a placeholder, could be used to erase some operation from a circuit
@ kComposite
a composite operation, contains other operations - should not be used in the beginning,...
@ kRandomGen
random classical bit generator, result in 'OperationState'
@ kConditionalRandomGen
conditional random generator, similar with random gen, but conditioned on something from 'OperationSt...
@ kConditionalMeasurement
conditional measurement, similar with measurement, but conditioned on something from 'OperationState'
@ kMeasurement
measurement, result in 'OperationState'
@ kGate
the usual quantum gate, result stays in simulator's state
@ kReset
reset, no result in 'state', just apply measurement, then apply not on all qubits that were measured ...
@ kQuantumChannel
a non-unitary CPTP operation on the simulator state
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.