Exemplo n.º 1
0
        /// <summary>
        /// Modifies the elements at the given indices and returns the QArray.
        /// Note that the modification is an in-place modification!
        /// If the Length of the given values does not match the number of indices,
        /// or if an index is outside the array bounds, it throws
        /// and ArgumentOutOfRangeException.
        /// </summary>
        /// <param name="index">The long index of the element to access</param>
        /// <returns>The element</returns>
        public QArray <T> Modify(QRange indices, IQArray <T> values)
        {
            if (values.Length != indices.Count())
            {
                throw new ArgumentOutOfRangeException();
            }

            var index = 0;

            foreach (var i in indices)
            {
                this.Modify(i, values[index++]);
            }
            return(this);
        }
Exemplo n.º 2
0
 public override void Apply(IQArray <Qubit> qubits)
 {
     // Note that we need to handle null array pointers (as opposed to empty arrays)
     if (qubits != null)
     {
         foreach (var q in qubits)
         {
             if (simulator.State[q.Id])
             {
                 throw new ReleasedQubitsAreNotInZeroState();
             }
         }
     }
     manager.Release(qubits);
 }
Exemplo n.º 3
0
        public virtual long StartConditionalStatement(IQArray <Result> measurementResults, IQArray <Result> resultsValues)
        {
            Debug.Assert(measurementResults.Count == resultsValues.Count);

            int equal = 1;

            for (int i = 0; i < measurementResults.Count; i++)
            {
                if (measurementResults[i] != resultsValues[i])
                {
                    equal = 0;
                }
            }

            return(equal);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Converts matrix from Q# array to C# array.
        /// </summary>
        public static Complex[,] MatrixFromQs(IQArray <IQArray <Quantum.Math.Complex> > a)
        {
            long n1 = a.Length;
            long n2 = a[0].Length;
            var  b  = new Complex[n1, n2];

            for (long i = 0; i < n1; i++)
            {
                Debug.Assert(a[i].Length == n2);
                for (long j = 0; j < n2; j++)
                {
                    b[i, j] = new Complex(a[i][j].Real, a[i][j].Imag);
                }
            }
            return(b);
        }
Exemplo n.º 5
0
        /// <summary>
        ///     Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that
        ///         - none of the qubits are null
        ///         - there are no duplicated qubits
        ///     Also sets the isMeasured flag to false for each qubit
        /// </summary>
        bool[] CheckQubits(IQArray <Qubit> ctrls, IQArray <Qubit> targets)
        {
            bool[] used = CheckQubits(targets);

            if (ctrls != null)
            {
                foreach (var q in ctrls)
                {
                    CheckQubitInUse(q, used);
                    //setting qubit as not measured to not allow release in case of gate operation on qubit
                    q.IsMeasured = false;
                }
            }

            return(used);
        }
Exemplo n.º 6
0
        /// <summary>
        /// The implementation of the controlled specialization of the operation.
        /// For the Toffoli simulator, the implementation flips the target qubit
        /// if the rotation is effectively an X gate and all of the control qubits
        /// are in the One state.
        /// </summary>
        public void R__ControlledBody(IQArray <Qubit> controls, Pauli pauli, double angle, Qubit target)
        {
            if (target == null)
            {
                return;
            }

            this.CheckControlQubits(controls, target);

            var(isX, safe) = CheckRotation(pauli, angle / 2.0);
            if (!safe)
            {
                throw new InvalidOperationException($"The Toffoli simulator can only perform controlled rotations of multiples of 2*pi.");
            }
            // We never need to do anything since only the identity is safe to control
        }
Exemplo n.º 7
0
        /// <summary>
        ///     Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that
        ///         - none of the qubits are null
        ///         - there are no duplicated qubits
        /// </summary>
        bool[] CheckQubits(IQArray <Qubit> ctrls, Qubit q1)
        {
            bool[] used = new bool[((QSimQubitManager)QubitManager).MaxId];

            CheckQubitInUse(q1, used);

            if (ctrls != null && ctrls.Length > 0)
            {
                foreach (var q in ctrls)
                {
                    CheckQubitInUse(q, used);
                }
            }

            return(used);
        }
Exemplo n.º 8
0
        public virtual void IsingXX__ControlledBody(IQArray <Qubit> controls, double angle, Qubit target1, Qubit target2)
        {
            if (controls == null || controls.Length == 0)
            {
                IsingXX__Body(angle, target1, target2);
            }
            else
            {
                var targets = new QArray <Qubit>(new Qubit[] { target1, target2 });
                var paulis  = new Pauli[] { Pauli.PauliX, Pauli.PauliX };
                CheckAngle(angle);
                this.CheckQubits(QArray <Qubit> .Add(controls, targets));

                MCExp(this.Id, (uint)targets.Length, paulis, angle * 2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
            }
        }
Exemplo n.º 9
0
        static void Main(string[] args)
        {
            using var qsim = new QuantumSimulator();
            int n = 1000;

            System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
            string[] results = new string[n];
            for (int i = 0; i < n; i++)
            {
                IQArray <Result> res = QMPE.Run(qsim).Result;
                results[i] = res.ToString();
            }
            stopwatch.Stop();
            Console.WriteLine($"Elapsed time: {stopwatch.ElapsedMilliseconds / 1000.0} sec");
            PrintResults(results);
        }
Exemplo n.º 10
0
        void IIntrinsicIsingZZ.ControlledBody(IQArray <Qubit> controls, double angle, Qubit target1, Qubit target2)
        {
            if (controls == null || controls.Length == 0)
            {
                ((IIntrinsicIsingZZ)this).Body(angle, target1, target2);
            }
            else
            {
                var targets = new QArray <Qubit>(new Qubit[] { target1, target2 });
                var paulis  = new Pauli[] { Pauli.PauliZ, Pauli.PauliZ };
                CheckAngle(angle);
                this.CheckQubits(QArray <Qubit> .Add(controls, targets));

                MCExp(this.Id, (uint)targets.Length, paulis, angle * 2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
            }
        }
Exemplo n.º 11
0
        public override bool Dump(IQArray <Qubit>?qubits = null)
        {
            var count = qubits?.Length ?? Simulator.QubitManager !.GetAllocatedQubitsCount();
            var nQubitsPerRegister = ((int)count / 2);

            Data = np.empty(new Shape(1 << ((int)count), 2));
            var result = base.Dump(qubits);

            // At this point, _data should be filled with the full state
            // vector, so let's display it, counting on the right display
            // encoder to be there to pack it into a table.
            var scaleFactor = System.Math.Sqrt(1 << nQubitsPerRegister);

            Data = scaleFactor * Data.reshape(1 << nQubitsPerRegister, 1 << nQubitsPerRegister, 2);

            return(result);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Apply a permutation defined by a permutation table. This overload
        /// allows for perfomance optimizations like reuse of permutation
        /// tables.
        /// </summary>
        public static void ApplyOracle(QuantumSimulator simulator, Int64[] permutation,
                                       IQArray <Qubit> xbits, IQArray <Qubit> ybits, bool adjoint = false)
        {
            simulator.CheckQubits(xbits, "x");
            simulator.CheckQubits(ybits, "y");
            Debug.Assert(CheckPermutation(permutation));
            var qbits = QArray <Qubit> .Add(xbits, ybits).GetIds();

            if (adjoint)
            {
                AdjPermuteBasisTable(simulator.Id, (uint)qbits.Length, qbits, permutation.LongLength, permutation);
            }
            else
            {
                PermuteBasisTable(simulator.Id, (uint)qbits.Length, qbits, permutation.LongLength, permutation);
            }
        }
Exemplo n.º 13
0
        public IQArray <Qubit> Allocate(long count)
        {
            if (count == 0)
            {
                return(new QArray <Qubit>());
            }

            IQArray <Qubit> res = qubitManager.Allocate(count);

            object[][] tracingData = GetTracingData(res);
            for (int i = 0; i < listeners.Length; ++i)
            {
                listeners[i].OnAllocate(tracingData[i]);
            }

            return(res);
        }
Exemplo n.º 14
0
        private static QVoid ExecuteConditionalStatement(QuantumProcessorDispatcher Simulator,
                                                         Result measurementResult,
                                                         Result resultValue,
                                                         ICallable onEqualOp,
                                                         ICallable onNonEqualOp,
                                                         OperationFunctor type,
                                                         IQArray <Qubit>?ctrls)
        {
            long statement = Simulator.QuantumProcessor.StartConditionalStatement(measurementResult, resultValue);

            return(ExecuteConditionalStatementInternal(Simulator,
                                                       statement,
                                                       onEqualOp,
                                                       onNonEqualOp,
                                                       type,
                                                       ctrls));
        }
Exemplo n.º 15
0
        public override bool Dump(IQArray <Qubit>?qubits = null)
        {
            _count = qubits == null
                        ? this.Simulator?.QubitManager?.AllocatedQubitsCount ?? 0
                        : qubits.Length;
            _data = new Complex[1 << ((int)_count)];
            var result = base.Dump(qubits);

            // At this point, _data should be filled with the full state
            // vector, so let's display it, counting on the right display
            // encoder to be there to pack it into a table.

            var id    = System.Guid.NewGuid();
            var state = new DisplayableState
            {
                // We cast here as we don't support a large enough number
                // of qubits to saturate an int.
                QubitIds   = qubits?.Select(q => q.Id) ?? Simulator?.QubitIds.Select(q => (int)q) ?? Enumerable.Empty <int>(),
                NQubits    = (int)_count,
                Amplitudes = _data,
                DivId      = $"dump-machine-div-{id}"
            };

            Channel.Display(state);

            if (ShowMeasurementDisplayHistogram)
            {
                Channel.SendIoPubMessage(new Message
                {
                    Header = new MessageHeader()
                    {
                        MessageType = "iqsharp_state_dump"
                    },
                    Content = new MeasurementHistogramContent()
                    {
                        State = state
                    },
                });
            }

            // Clean up the state vector buffer.
            _data = null;

            return(result);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Determines if the given measurement results are pairwise-equal with the given comparison results.
        /// Pairwise-equality is where each element of the first array is equal to its corresponding element
        /// in the second array. For example:
        /// measurementResults[0] == comparisonResults[0] AND measurementResults[1] == comparisonResults[1] AND ...
        /// All pairwise comparisons must result in equality for the two arrays to be pairwise-equal.
        ///
        /// If either array is null or their lengths are unequal, this defaults to returning 'true'. This
        /// is done to be consistent with the logic found in QuantumProcessorBase.cs under the
        /// StartConditionalStatement method.
        /// </summary>
        private static bool AreEqual(IQArray <Result> measurementResults, IQArray <Result> comparisonResults)
        {
            if (measurementResults == null || comparisonResults == null || measurementResults.Count != comparisonResults.Count)
            {
                // Defaulting to true is based on the QuantumProcessorBase.cs behavior, under StartConditionalStatement.
                return(true);
            }

            for (int i = 0; i < measurementResults.Count; i++)
            {
                if (measurementResults[i] != comparisonResults[i])
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Returns a count of input qubits that have been allocated just for borrowing, borrowed exactly once,
        /// and thus will be released after they are returned.
        /// </summary>
        public virtual long ToBeReleasedAfterReturnCount(IQArray <Qubit> qubitsToReturn)
        {
            if (qubitsToReturn == null || qubitsToReturn.Length == 0)
            {
                return(0);
            }

            long count = 0;

            foreach (Qubit qubit in qubitsToReturn)
            {
                if (this.ToBeReleasedAfterReturn(qubit))
                {
                    count++;
                }
            }
            return(count);
        }
Exemplo n.º 18
0
            static long XBitsFunc(IQArray <Pauli> pauli)
            {
                if (pauli.Length > 63)
                {
                    throw new ExecutionFailException("Cannot pack X bits of Pauli array longer than 63");
                }
                ulong res = 0;

                for (long i = pauli.Length - 1; i >= 0; --i)
                {
                    res <<= 1;
                    if (pauli[i] == Pauli.PauliX || pauli[i] == Pauli.PauliY)
                    {
                        res |= 1;
                    }
                }
                return(System.Convert.ToInt64(res));
            }
Exemplo n.º 19
0
        /// <summary>
        /// Dumps the wave function for the given qubits into the given target.
        /// If the target is QVoid or an empty string, it dumps it to the console
        /// using the `Message` function, otherwise it dumps the content into a file
        /// with the given name.
        /// If the given qubits is null, it dumps the entire wave function, otherwise
        /// it attemps to create the wave function or the resulting subsystem; if it fails
        /// because the qubits are entangled with some external qubit, it just generates a message.
        /// </summary>
        protected virtual QVoid Dump <T>(T target, IQArray <Qubit>?qubits = null)
        {
            var filename = (target is QVoid) ? "" : target.ToString();

            QVoid process(Action <string> channel)
            {
                var ids = qubits?.Select(q => (uint)q.Id).ToArray() ?? QubitIds;

                var dumper = new SimpleDumper(this, channel);

                channel($"# wave function for qubits with ids (least to most significant): {string.Join(";", ids)}");

                if (!dumper.Dump(qubits))
                {
                    channel("## Qubits were entangled with an external qubit. Cannot dump corresponding wave function. ##");
                }

                return(QVoid.Instance);
            }

            var logMessage = this.Get <ICallable <string, QVoid>, Microsoft.Quantum.Intrinsic.Message>();

            // If no file provided, use `Message` to generate the message into the console;
            if (string.IsNullOrWhiteSpace(filename))
            {
                var op = this.Get <ICallable <string, QVoid>, Microsoft.Quantum.Intrinsic.Message>();
                return(process((msg) => op.Apply(msg)));
            }
            else
            {
                try
                {
                    using (var file = new StreamWriter(filename))
                    {
                        return(process(file.WriteLine));
                    }
                }
                catch (Exception e)
                {
                    logMessage.Apply($"[warning] Unable to write state to '{filename}' ({e.Message})");
                    return(QVoid.Instance);
                }
            }
        }
Exemplo n.º 20
0
        public virtual void SWAP__ControlledBody(IQArray <Qubit> controls, Qubit target1, Qubit target2)
        {
            if ((controls == null) || (controls.Count == 0))
            {
                SWAP__Body(target1, target2);
            }
            else
            {
                var ctrls_1 = QArray <Qubit> .Add(controls, new QArray <Qubit>(target1));

                var ctrls_2 = QArray <Qubit> .Add(controls, new QArray <Qubit>(target2));

                this.CheckQubits(ctrls_1, target2);

                MCX(this.Id, (uint)ctrls_1.Length, ctrls_1.GetIds(), (uint)target2.Id);
                MCX(this.Id, (uint)ctrls_2.Length, ctrls_2.GetIds(), (uint)target1.Id);
                MCX(this.Id, (uint)ctrls_1.Length, ctrls_1.GetIds(), (uint)target2.Id);
            }
        }
Exemplo n.º 21
0
        /// <summary>
        ///     Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that
        ///         - none of the qubits are null
        ///         - there are no duplicated qubits
        ///     Also sets the isMeasured flag to false for each qubit
        /// </summary>
        bool[] CheckQubits(IQArray <Qubit> ctrls, Qubit q1)
        {
            bool[] used = new bool[((QSimQubitManager)QubitManager).MaxId];

            CheckQubitInUse(q1, used);
            q1.IsMeasured = false;

            if (ctrls != null && ctrls.Length > 0)
            {
                foreach (var q in ctrls)
                {
                    CheckQubitInUse(q, used);
                    //setting qubit as not measured to not allow release in case of gate operation on qubit
                    q.IsMeasured = false;
                }
            }

            return(used);
        }
Exemplo n.º 22
0
        /// <summary>
        /// The main entry point for emulation of a permutation oracle:
        /// Apply the permutation defined by the oracle function
        ///     f: (x, y) -> (x, f(x, y)).
        /// </summary>
        public static void ApplyOracle(QuantumSimulator simulator, Func <Int64, Int64, Int64, Int64> oracle,
                                       Int64 nLayers, IQArray <Qubit> xbits, Qubit ybit, bool adjoint = false)
        {
            var permutation = BuildPermutationTable(oracle, nLayers, (int)xbits.Length, 1);

            simulator.CheckQubits(xbits, "x");
            simulator.CheckQubit(ybit, "y");
            Debug.Assert(CheckPermutation(permutation));
            IQArray <Qubit> ybits = new QArray <Qubit>(ybit);
            var             qbits = QArray <Qubit> .Add(xbits, ybits).GetIds();

            if (adjoint)
            {
                AdjPermuteBasisTable(simulator.Id, (uint)qbits.Length, qbits, permutation.LongLength, permutation);
            }
            else
            {
                PermuteBasisTable(simulator.Id, (uint)qbits.Length, qbits, permutation.LongLength, permutation);
            }
        }
Exemplo n.º 23
0
        internal void CheckControlQubits(IQArray <Qubit> ctrls, Qubit target)
        {
            CheckQubits(ctrls, "ctrls");

            CheckQubit(target, "target");

            var inUse = new HashSet <int>();

            foreach (var c in ctrls)
            {
                if (!inUse.Add(c.Id))
                {
                    throw new NotDistinctQubits(c);
                }
            }
            if (inUse.Contains(target.Id))
            {
                throw new NotDistinctQubits(target);
            }
        }
Exemplo n.º 24
0
        /// <summary>
        ///     Intended to be used with simulator functions like Dump, Assert, AssertProb
        ///     Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that
        ///         - none of the qubits are null
        ///         - there are no duplicated qubits
        /// </summary>
        bool[] CheckAndPreserveQubits(IQArray <Qubit> targets)
        {
            if (targets == null)
            {
                throw new ArgumentNullException(nameof(targets), "Trying to perform an intrinsic operation on a null Qubit array.");
            }
            if (targets.Length == 0)
            {
                throw new ArgumentNullException(nameof(targets), "Trying to perform an intrinsic operation on an empty Qubit array.");
            }

            bool[] used = new bool[((QSimQubitManager)QubitManager).MaxId];

            foreach (var q in targets)
            {
                CheckQubitInUse(q, used);
            }

            return(used);
        }
Exemplo n.º 25
0
        /// <summary>
        ///     Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that
        ///         - none of the qubits are null
        ///         - there are no duplicated qubits
        ///     Also sets the isMeasured flag to false for each qubit
        /// </summary>
        bool[] CheckQubits(IQArray <Qubit> targets)
        {
            if (targets == null)
            {
                throw new ArgumentNullException(nameof(targets), "Trying to perform an intrinsic operation on a null Qubit array.");
            }
            if (targets.Length == 0)
            {
                throw new ArgumentNullException(nameof(targets), "Trying to perform an intrinsic operation on an empty Qubit array.");
            }

            bool[] used = new bool[((QSimQubitManager)QubitManager).MaxId];

            foreach (var q in targets)
            {
                CheckQubitInUse(q, used);
                //setting qubit as not measured to not allow release in case of gate operation on qubit
                q.IsMeasured = false;
            }

            return(used);
        }
Exemplo n.º 26
0
        /// <summary>
        /// The implementation of the operation.
        /// For the Toffoli simulator, the implementation returns the joint parity of the
        /// states of the measured qubits.
        /// That is, Result.One is returned if an odd number of the measured qubits are
        /// in the One state.
        /// </summary>
        public Result Measure__Body(IQArray <Pauli> paulis, IQArray <Qubit> targets)
        {
            Qubit?f(Pauli p, Qubit q) =>
            p switch
            {
                Pauli.PauliI => null,
                Pauli.PauliZ => q,
                _ => throw new InvalidOperationException($"The Toffoli simulator can only Measure in the Z basis.")
            };

            if (paulis.Length != targets.Length)
            {
                throw new InvalidOperationException($"Both input arrays for Measure (paulis, targets), must be of same size");
            }

            var qubitsToMeasure = paulis.Zip(targets, f).WhereNotNull();

            var result = this.GetParity(qubitsToMeasure);

            return(result.ToResult());
        }
    }
Exemplo n.º 27
0
        internal void CheckControlQubits(IQArray <Qubit> ctrls, IQArray <Qubit> targets)
        {
            CheckQubits(ctrls, "ctrls");
            CheckQubits(targets, "targets");

            var inUse = new HashSet <int>();

            foreach (var c in ctrls)
            {
                if (!inUse.Add(c.Id))
                {
                    throw new NotDistinctQubits(c);
                }
            }
            foreach (var t in targets)
            {
                if (!inUse.Add(t.Id))
                {
                    throw new NotDistinctQubits(t);
                }
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// The implementation of the operation.
        /// For the Toffoli simulator, the implementation flips a target qubit
        /// if the respective rotation is effectively an X gate.
        /// </summary>
        void IIntrinsicExp.Body(IQArray <Pauli> paulis, double angle, IQArray <Qubit> targets)
        {
            if (targets == null)
            {
                return;
            }

            this.CheckQubits(targets, "targets");

            if (targets.Length != paulis.Length)
            {
                throw new InvalidOperationException($"Both input arrays for Exp (paulis,targets), must be of same size");
            }

            for (var i = 0; i < targets.Length; i++)
            {
                var(isX, safe) = CheckRotation(paulis[i], angle);
                if (isX)
                {
                    this.State[targets[i].Id] = !this.State[targets[i].Id];
                }
            }
        }
Exemplo n.º 29
0
        public override Result Measure(IQArray <Pauli> bases, IQArray <Qubit> qubits)
        {
            if (!bases.TryGetSingleZ(out var idx))
            {
                // throw new UnsupportedOperationException("Not yet implemented.");
                var aux = this.Simulator !.QubitManager?.Allocate();
                if (aux == null)
                {
                    throw new NullReferenceException("Qubit manager was null.");
                }

                try
                {
                    this.WriteToScratch(bases, qubits, aux);
                    return(this.MeasureByIndex(aux.Id));
                }
                finally
                {
                    this.Simulator !.QubitManager?.Release(aux);
                }
            }

            return(this.MeasureByIndex(qubits[idx].Id));
        }
Exemplo n.º 30
0
        /// <summary>
        /// The implementation of the controlled specialization of the operation.
        /// For the Toffoli simulator, the implementation flips the target qubit
        /// if the rotation is effectively an X gate and all of the control qubits
        /// are in the One state.
        /// </summary>
        void IIntrinsicExp.ControlledBody(IQArray <Qubit> controls, IQArray <Pauli> paulis, double angle, IQArray <Qubit> targets)
        {
            if (targets == null)
            {
                return;
            }

            this.CheckControlQubits(controls, targets);

            if (targets.Length != paulis.Length)
            {
                throw new InvalidOperationException($"Both input arrays for Exp (paulis,qubits), must be of same size");
            }

            for (var i = 0; i < targets.Length; i++)
            {
                var(id, safe) = CheckRotation(paulis[i], angle);
                if (!safe)
                {
                    throw new InvalidOperationException($"The Toffoli simulator can only perform controlled rotations of multiples of 2*pi.");
                }
                // We never need to do anything since only the identity is safe to control
            }
        }