/// # Summary
        /// Uses a quantum function to get a solution string from the QAOA that relies on the current values of beta and gamma vectors.
        ///To get a reasonable estimate for the expectation value of a Hamiltonian that encodes the problem, we run the QAOA many times and calculate the expectation based on solutions obtained.
        ///If the expectation of the Hamiltonian is smaller than our current best, we update our best solution to the current solution. The solution vector for the current best solution is the mode of boolean strings that we obtained from the QAOA.
        ///
        /// # Input
        /// ## bigfreeParamsVector
        /// Beta and gamma vectors concatenated.
        ///
        /// # Output
        /// The expected value of a Hamiltonian that we calculated in this run.
        public Double CalculateObjectiveFunction(double[] bigfreeParamsVector)
        {
            Utils.FreeParamsVector freeParamsVector   = Utils.ConvertVectorIntoHalves(bigfreeParamsVector);
            double        hamiltonianExpectationValue = 0;
            List <bool[]> allSolutionVectors          = new List <bool[]>();

            var beta  = new QArray <Double>(freeParamsVector.beta);
            var gamma = new QArray <Double>(freeParamsVector.gamma);

            Utils.PrintCurrentBetaGamma(beta, gamma);

            var oneLocalHamiltonianCoefficients = new QArray <Double>(problemInstance.oneLocalHamiltonianCoefficients);
            var twoLocalHamiltonianCoefficients = new QArray <Double>(problemInstance.twoLocalHamiltonianCoefficients);

            using (var qsim = new QuantumSimulator())
            {
                for (int i = 0; i < numberOfIterations; i++)
                {
                    IQArray <bool> result = RunQaoa.Run(qsim, problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result;
                    allSolutionVectors.Add(result.ToArray());
                    string solutionVector   = Utils.GetBoolStringFromBoolArray(result.ToArray());
                    double hamiltonianValue = EvaluateHamiltonian(solutionVector);
                    hamiltonianExpectationValue += (hamiltonianValue / numberOfIterations);
                }
            }

            UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector);
            Utils.PrintCurrentBestSolution(this.bestHamiltonianValue, this.bestVector);

            return(hamiltonianExpectationValue);
        }
Exemplo n.º 2
0
        void IIntrinsicExp.Body(IQArray <Pauli> paulis, double angle, IQArray <Qubit> targets)
        {
            this.CheckQubits(targets);
            CheckAngle(angle);

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

            Exp(this.Id, (uint)paulis.Length, paulis.ToArray(), angle, targets.GetIds());
        }
Exemplo n.º 3
0
        void IIntrinsicExp.ControlledBody(IQArray <Qubit> controls, IQArray <Pauli> paulis, double angle, IQArray <Qubit> targets)
        {
            this.CheckQubits(controls, targets);
            CheckAngle(angle);

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

            SafeControlled(controls,
                           () => ((IIntrinsicExp)this).Body(paulis, angle, targets),
                           (count, ids) => MCExp(this.Id, (uint)paulis.Length, paulis.ToArray(), angle, count, ids, targets.GetIds()));
        }
Exemplo n.º 4
0
 Result IIntrinsicMeasure.Body(IQArray <Pauli> paulis, IQArray <Qubit> targets)
 {
     this.CheckQubits(targets);
     if (paulis.Length != targets.Length)
     {
         throw new InvalidOperationException($"Both input arrays for Measure (paulis, targets), must be of same size");
     }
     if (targets.Length == 1)
     {
         // When we are operating on a single qubit we will collapse the state, so mark
         // that qubit as measured.
         targets[0].IsMeasured = true;
     }
     return(Measure(this.Id, (uint)paulis.Length, paulis.ToArray(), targets.GetIds()).ToResult());
 }