Exemplo n.º 1
0
        /// <summary>
        /// Allocates numToAllocate new qubits.
        /// </summary>
        public virtual IQArray <Qubit> Allocate(long numToAllocate)
        {
            IgnorableAssert.Assert(numToAllocate >= 0, "Attempt to allocate negative number of qubits.");
            if (numToAllocate < 0)
            {
                throw new ArgumentException("Attempt to allocate negative number of qubits.");
            }
            else if (numToAllocate == 0)
            {
                return(QArray <Qubit> .Create(0));
            }

            QArray <Qubit> result = QArray <Qubit> .Create(numToAllocate);

            for (int i = 0; i < numToAllocate; i++)
            {
                result.Modify(i, AllocateOneQubit(usedOnlyForBorrowing: false));
                if (result[i] == null)
                {
                    for (int k = 0; k < i; k++)
                    {
                        Release(result[k]);
                    }
                    throw new NotEnoughQubits(numToAllocate, GetFreeQubitsCount());
                }
            }

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Borrows a number of qubits. Chooses them from among already allocated ones.
        /// Makes sure borrowed qubits are not on the exclusion list.
        /// Exclusion list is supposed to contain qubits that can not be borrowed,
        /// for example those, that are being used (or could be used) in the current context.
        /// If there are not enough qubits to borrow, allocates new ones.
        /// </summary>
        public virtual IQArray <Qubit> Borrow(long numToBorrow, IEnumerable <Qubit> excludedQubitsSortedById) // Note, excluded could be an array of Ids for efficiency, if it is convenient for compiler.
        {
            IgnorableAssert.Assert(numToBorrow > 0, "Attempt to borrow zero qubits.");
            if (numToBorrow <= 0)
            {
                throw new ArgumentException("Attempt to borrow zero qubits.");
            }

            if (DisableBorrowing)
            {
                return(Allocate(numToBorrow));
            }

            var result = QArray <Qubit> .Create(numToBorrow);

            long numBorrowed = TryBorrow(numToBorrow, result, excludedQubitsSortedById);

            if (numBorrowed < numToBorrow)
            { // Not enough qubits to borrow. Allocate what was not borrowed.
                for (long i = numBorrowed; i < numToBorrow; i++)
                {
                    result.Modify(i, AllocateOneQubit(usedOnlyForBorrowing: true));
                    if (result[(int)i] == null)
                    {
                        for (long k = numBorrowed; k < i; k++)
                        {
                            ReleaseOneQubit(result[(int)k], usedOnlyForBorrowing: true);
                        }
                        throw new NotEnoughQubits(numToBorrow, numBorrowed + GetFreeQubitsCount());
                    }
                }
            }

            return(result);
        }
Exemplo n.º 3
0
        protected virtual void DisableOneQubit(Qubit qubit)
        {
            // Note: Borrowed qubits cannot be disabled.
            IgnorableAssert.Assert(qubits[qubit.Id] == Allocated, "Attempt to disable qubit that has not been allocated.");
            qubits[qubit.Id] = Disabled;
            numDisabledQubits++;

            numAllocatedQubits--;
            Debug.Assert(numAllocatedQubits >= 0);
        }
Exemplo n.º 4
0
        /// <summary>
        ///     Makes sure the angle for a rotation or exp operation is not NaN or Infinity.
        /// </summary>
        static void CheckAngle(double angle)
        {
            IgnorableAssert.Assert(!(double.IsNaN(angle) || double.IsInfinity(angle)), "Invalid angle for rotation/exponentiation.");

            if (double.IsNaN(angle))
            {
                throw new ArgumentOutOfRangeException("angle", "Angle can't be NaN.");
            }
            if (double.IsInfinity(angle))
            {
                throw new ArgumentOutOfRangeException("angle", "Angle can't be Infity.");
            }
        }
Exemplo n.º 5
0
        protected virtual void ReleaseOneQubit(Qubit qubit, bool usedOnlyForBorrowing)
        {
            long Occupied = (usedOnlyForBorrowing? AllocatedForBorrowing : Allocated);

            IgnorableAssert.Assert(qubits[qubit.Id] == Occupied, "Attempt to free qubit that has not been allocated.");
            if (qubits[qubit.Id] != Occupied)
            {
                throw new ArgumentException("Attempt to free qubit that has not been allocated.");
            }
            qubits[qubit.Id] = free;
            free             = qubit.Id;

            numAllocatedQubits--;
            Debug.Assert(numAllocatedQubits >= 0);
        }
Exemplo n.º 6
0
        protected virtual void ReleaseOneQubit(Qubit qubit, bool usedOnlyForBorrowing)
        {
            if (qubits[qubit.Id] == Disabled)
            {
                // Nothing to do. It will stay disabled.
                // Alternatively, we could mark is as None here.
            }
            else
            {
                long Occupied = (usedOnlyForBorrowing ? AllocatedForBorrowing : Allocated);
                IgnorableAssert.Assert(qubits[qubit.Id] == Occupied, "Attempt to free qubit that has not been allocated.");
                if (qubits[qubit.Id] != Occupied)
                {
                    throw new ArgumentException("Attempt to free qubit that has not been allocated.");
                }
                qubits[qubit.Id] = free;
                free             = qubit.Id;

                numAllocatedQubits--;
                Debug.Assert(numAllocatedQubits >= 0);
            }
        }