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]); }); }
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); }
/// <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); }
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); }
/// <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]); }