15#ifndef _CIRCUIT_OPERATIONS_H_
16#define _CIRCUIT_OPERATIONS_H_
18#include "../Simulators/Simulator.h"
90 : bits(std::move(other.bits)) {}
126 bits.swap(other.bits);
160 bits.resize(bits.size() + numBits,
false);
186 if (index > bits.size())
return false;
198 std::vector<bool>
GetBits(
const std::vector<size_t> &indices)
const {
199 std::vector<bool> results(indices.size(),
false);
201 for (
size_t i = 0; i < indices.size(); ++i)
202 if (indices[i] < bits.size()) results[i] = bits[indices[i]];
230 void SetBit(
size_t index,
bool value =
true) {
231 if (index > bits.size())
return;
243 void Reset(
bool value =
false) { std::fill(bits.begin(), bits.end(), value); }
253 const size_t theSize = std::max(bits.size(), results.size());
256 bits.resize(theSize,
false);
267 void SetResults(
const std::vector<size_t> &indices,
size_t results) {
268 for (
int i = 0; i < static_cast<int>(indices.size()); ++i) {
269 if (indices[i] < bits.size()) bits[indices[i]] = results & 1;
296 void Remap(
const std::unordered_map<Types::qubit_t, Types::qubit_t> &mapping,
297 bool ignoreNotMapped =
false,
size_t newSize = 0) {
298 std::vector<bool> newBits(
299 newSize > 0 ? newSize
300 : (ignoreNotMapped ? mapping.size() : bits.size()),
303 for (
size_t i = 0; i < bits.size(); ++i) {
304 const auto it = mapping.find(i);
305 if (it != mapping.end())
306 newBits[it->second] = bits[i];
307 else if (!ignoreNotMapped && i < newBits.size())
308 newBits[i] = bits[i];
327 bool ignoreNotMapped =
false,
size_t newSize = 0) {
328 std::vector<bool> newBits(
329 newSize > 0 ? newSize
330 : (ignoreNotMapped ? mapping.size() : bits.size()),
333 for (
size_t i = 0; i < bits.size(); ++i) {
334 if (i < mapping.size())
335 newBits[mapping.at(i)] = bits[i];
336 else if (!ignoreNotMapped && i < newBits.size())
337 newBits[i] = bits[i];
344 std::vector<bool> bits;
356template <
typename Time = Types::time_type>
357class IOperation :
public std::enable_shared_from_this<IOperation<Time>> {
385 virtual void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
403 virtual std::shared_ptr<IOperation<Time>>
Clone()
const = 0;
415 virtual std::shared_ptr<IOperation<Time>>
Remap(
416 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
417 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
486 std::shared_ptr<IOperation<Time>>
getptr() {
487 return std::enable_shared_from_this<IOperation<Time>>::shared_from_this();
529template <
typename Time = Types::time_type>
552 void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
561 std::shared_ptr<IOperation<Time>>
Clone()
const override {
575 std::shared_ptr<IOperation<Time>>
Remap(
576 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
577 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap)
579 return this->
Clone();
602template <
typename Time = Types::time_type>
638 virtual void SetQubit(Types::qubit_t qubit,
unsigned long index = 0) = 0;
648 virtual Types::qubit_t
GetQubit(
unsigned int index = 0)
const = 0;
The gate operation interface.
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.
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 ...