15#ifndef _CIRCUIT_OPERATIONS_H_
16#define _CIRCUIT_OPERATIONS_H_
90 : bits(std::move(other.bits)) {}
126 bits.swap(other.bits);
160 bits.resize(bits.size() + numBits,
false);
186 if (index > bits.size())
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())
204 results[i] = bits[indices[i]];
232 void SetBit(
size_t index,
bool value =
true) {
233 if (index > bits.size())
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())
273 bits[indices[i]] = results & 1;
300 void Remap(
const std::unordered_map<Types::qubit_t, Types::qubit_t> &mapping,
301 bool ignoreNotMapped =
false,
size_t newSize = 0) {
302 std::vector<bool> newBits(
303 newSize > 0 ? newSize
304 : (ignoreNotMapped ? mapping.size() : bits.size()),
307 for (
size_t i = 0; i < bits.size(); ++i) {
308 const auto it = mapping.find(i);
309 if (it != mapping.end())
310 newBits[it->second] = bits[i];
311 else if (!ignoreNotMapped && i < newBits.size())
312 newBits[i] = bits[i];
331 bool ignoreNotMapped =
false,
size_t newSize = 0) {
332 std::vector<bool> newBits(
333 newSize > 0 ? newSize
334 : (ignoreNotMapped ? mapping.size() : bits.size()),
337 for (
size_t i = 0; i < bits.size(); ++i) {
338 if (i < mapping.size())
339 newBits[mapping.at(i)] = bits[i];
340 else if (!ignoreNotMapped && i < newBits.size())
341 newBits[i] = bits[i];
348 std::vector<bool> bits;
360template <
typename Time = Types::time_type>
361class IOperation :
public std::enable_shared_from_this<IOperation<Time>> {
389 virtual void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
407 virtual std::shared_ptr<IOperation<Time>>
Clone()
const = 0;
419 virtual std::shared_ptr<IOperation<Time>>
420 Remap(
const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
421 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap = {})
490 std::shared_ptr<IOperation<Time>>
getptr() {
491 return std::enable_shared_from_this<IOperation<Time>>::shared_from_this();
533template <
typename Time = Types::time_type>
556 void Execute(
const std::shared_ptr<Simulators::ISimulator> &sim,
565 std::shared_ptr<IOperation<Time>>
Clone()
const override {
579 std::shared_ptr<IOperation<Time>>
580 Remap(
const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap,
581 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap)
583 return this->
Clone();
606template <
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.
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.