16#ifndef _CIRCUIT_OPERATIONS_H_
17#define _CIRCUIT_OPERATIONS_H_
91 : bits(std::move(other.bits)) {}
127 bits.swap(other.bits);
161 bits.resize(bits.size() + numBits,
false);
187 if (index > bits.size())
return false;
199 std::vector<bool>
GetBits(
const std::vector<size_t> &indices)
const {
200 std::vector<bool> results(indices.size(),
false);
202 for (
size_t i = 0; i < indices.size(); ++i)
203 if (indices[i] < bits.size()) results[i] = bits[indices[i]];
231 void SetBit(
size_t index,
bool value =
true) {
232 if (index > bits.size())
return;
244 void Reset(
bool value =
false) { std::fill(bits.begin(), bits.end(), value); }
254 const size_t theSize = std::max(bits.size(), results.size());
257 bits.resize(theSize,
false);
268 void SetResults(
const std::vector<size_t> &indices,
size_t results) {
269 for (
int i = 0; i < static_cast<int>(indices.size()); ++i) {
270 if (indices[i] < bits.size()) bits[indices[i]] = results & 1;
297 void Remap(
const std::unordered_map<Types::qubit_t, Types::qubit_t> &mapping,
298 bool ignoreNotMapped =
false,
size_t newSize = 0) {
299 std::vector<bool> newBits(
300 newSize > 0 ? newSize
301 : (ignoreNotMapped ? mapping.size() : bits.size()),
304 for (
size_t i = 0; i < bits.size(); ++i) {
305 const auto it = mapping.find(i);
306 if (it != mapping.end())
307 newBits[it->second] = bits[i];
308 else if (!ignoreNotMapped && i < newBits.size())
309 newBits[i] = bits[i];
328 bool ignoreNotMapped =
false,
size_t newSize = 0) {
329 std::vector<bool> newBits(
330 newSize > 0 ? newSize
331 : (ignoreNotMapped ? mapping.size() : bits.size()),
334 for (
size_t i = 0; i < bits.size(); ++i) {
335 if (i < mapping.size())
336 newBits[mapping.at(i)] = bits[i];
337 else if (!ignoreNotMapped && i < newBits.size())
338 newBits[i] = bits[i];
345 std::vector<bool> bits;
357template <
typename Time = Types::time_type>
358class IOperation :
public std::enable_shared_from_this<IOperation<Time>> {
386 virtual void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
404 virtual std::shared_ptr<IOperation<Time>>
Clone()
const = 0;
416 virtual std::shared_ptr<IOperation<Time>>
Remap(
417 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
418 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
487 std::shared_ptr<IOperation<Time>>
getptr() {
488 return std::enable_shared_from_this<IOperation<Time>>::shared_from_this();
540template <
typename Time = Types::time_type>
563 void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
572 std::shared_ptr<IOperation<Time>>
Clone()
const override {
586 std::shared_ptr<IOperation<Time>>
Remap(
587 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
588 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap)
590 return this->
Clone();
613template <
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.
void SetDelay(Time d)
Set the delay of the operation.
virtual Types::qubits_vector AffectedQubits() const
Returns the affected qubits.
Time GetDelay() const
Get 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'
@ 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 ...
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.