public void ArraysByIndex()
        {
            var longs = new QArray <long> (2, 1, 0);

            Assert.NotEmpty(longs);
            Assert.Equal(3, longs.Length);
            Assert.Equal(2, longs[0]);
            Assert.Equal(1, longs[1]);
            Assert.Equal(0, longs[2]);

            longs = new QArray <long>(new long[5]);
            longs.Modify(0, 5);
            longs.Modify(2, 3);
            longs.Modify(4, 1);
            Assert.Equal(5, longs.Length);
            Assert.Equal(5, longs[0]);
            Assert.Equal(0, longs[1]);
            Assert.Equal(3, longs[2]);
            Assert.Equal(0, longs[3]);
            Assert.Equal(1, longs[4]);

            OperationsTestHelper.IgnoreDebugAssert(() =>
            {
                // Make sure we can call it with a long index:
                Assert.Throws <ArgumentOutOfRangeException>(() => longs[-1]);
                Assert.Throws <ArgumentOutOfRangeException>(() => longs[int.MaxValue]);
                Assert.Throws <ArgumentOutOfRangeException>(() => longs[(long)int.MaxValue + 1]);
            });
        }
Esempio n. 2
0
        private long TryBorrow(long numToBorrow, QArray <Qubit> result, IEnumerable <Qubit> excludedQubitsSortedById)
        {
            long curQubit              = 0;
            long numBorrowed           = 0;
            long curBorrowed           = 0;
            IEnumerator <Qubit> enumer = excludedQubitsSortedById.GetEnumerator();
            bool exclusionsPresent     = enumer.MoveNext();

            numBorrowed = System.Math.Min(GetQubitsAvailableToBorrowCount(excludedQubitsSortedById), numToBorrow);

            while (curBorrowed < numBorrowed)
            {
                while (IsFree(curQubit) || IsDisabled(curQubit))
                {
                    curQubit++;
                    Debug.Assert(curQubit < NumQubits);
                }
                Debug.Assert((!exclusionsPresent) || (enumer.Current.Id >= curQubit));
                if ((!exclusionsPresent) || (enumer.Current.Id != curQubit))
                {
                    result.Modify(curBorrowed, BorrowOneQubit(curQubit));
                    curBorrowed++;
                }
                else
                {
                    exclusionsPresent = enumer.MoveNext();
                }
                curQubit++;
                Debug.Assert(curQubit < NumQubits);
            }
            return(numBorrowed);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        public IQArray <Qubit> Allocate(long numToAllocate)
        {
            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);

            if (!DisableBorrowing)
            {
                var locals = operationStack.Peek().Locals;
                locals.EnsureCapacity(locals.Count + (int)numToAllocate);
            }
            for (int i = 0; i < numToAllocate; i++)
            {
                Qubit?allocated = Allocate(usedOnlyForBorrowing: false);
                if (allocated == null)
                {
                    for (int k = 0; k < i; k++)
                    {
                        Release(result[k], wasUsedOnlyForBorrowing: false);
                    }
                    throw new NotEnoughQubits(numToAllocate, this.FreeQubitsCount);
                }
                result.Modify(i, allocated);
            }

            return(result);
        }
Esempio n. 5
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 negative number of qubits.");
            if (numToBorrow < 0)
            {
                throw new ArgumentException("Attempt to borrow negative number of qubits.");
            }
            else if (numToBorrow == 0)
            {
                return(QArray <Qubit> .Create(0));
            }

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

            if (excludedQubitsSortedById == null)
            {
                excludedQubitsSortedById = new Qubit[0];
            }

            QArray <Qubit> 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);
        }
        public void ArraySharing()
        {
            // Basic copy-on-write
            var array1 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            var array2 = new QArray <long>(array1);

            Assert.Equal(2, array1[2]);
            Assert.Equal(2, array2[2]);
            array1.Modify(2, 12);
            Assert.Equal(12, array1[2]);
            Assert.Equal(2, array2[2]);
            array2.Modify(2, 22);
            Assert.Equal(12, array1[2]);
            Assert.Equal(22, array2[2]);

            // Arrays of arrays
            array1 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            array2 = new QArray <long>(array1);
            var arrayArray1 = new QArray <QArray <long> >(array1, array2); // in generated C# code, QArray<IQArray<long>> is used
            var arrayArray2 = new QArray <QArray <long> >(arrayArray1);

            Assert.Equal(2, arrayArray1[0][2]);
            Assert.Equal(2, arrayArray1[1][2]);
            arrayArray1.Modify(0, arrayArray1[0].Modify(2, 12));
            Assert.Equal(12, arrayArray1[0][2]);
            Assert.Equal(2, arrayArray1[1][2]);
            Assert.Equal(12, array1[2]);
            arrayArray1.Modify(1, arrayArray1[1].Modify(2, 22));
            Assert.Equal(12, arrayArray1[0][2]);
            Assert.Equal(22, arrayArray1[1][2]);
            Assert.Equal(12, array1[2]);
            Assert.Equal(22, array2[2]);

            // Copy-on-write with slices
            var r        = new QRange(1, 2, 10);
            var array3   = array2.Slice(r);
            var expected = new QArray <long>(1, 3, 5, 7, 9);

            Assert.Equal(expected, array3);
            array3.Modify(0, 11);
            Assert.Equal(1, array2[1]);
            Assert.Equal(11, array3[0]);

            // Mixing slicing and joining
            array2 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            var expected2 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

            r      = new QRange(1, 2, 10);
            array3 = array2.Slice(r);
            var array4 = new QArray <long>(11, 13);
            var array5 = QArray <long> .Add(array3, array4);

            var expected3 = new QArray <long>(1, 3, 5, 7, 9);
            var expected4 = new QArray <long>(11, 13);
            var expected5 = new QArray <long>(1, 3, 5, 7, 9, 11, 13);

            Assert.Equal(expected2, array2);
            Assert.Equal(expected3, array3);
            Assert.Equal(expected4, array4);
            Assert.Equal(expected5, array5);

            // Self-joining
            array1 = new QArray <long>(0, 1, 2);
            array2 = new QArray <long>(QArray <long> .Add(array1, array1));
            var expected1 = new QArray <long>(0, 1, 2);

            expected2 = new QArray <long>(0, 1, 2, 0, 1, 2);
            Assert.Equal(expected1, array1);
            Assert.Equal(expected2, array2);
            array1.Modify(0, 10);
            Assert.Equal(10, array1[0]);
            Assert.Equal(0, array2[0]);
        }