From c956426a7f4ca6cdf2ae14264320623419fef0b2 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 26 Jul 2020 10:28:26 +0200 Subject: [PATCH 01/61] QAOA files added. --- QAOA.sln | 31 ++ QAOA/.gitattributes | 63 ++++ QAOA/.gitignore | 340 ++++++++++++++++++ .../ClassicalOptimizationUtils.cs | 177 +++++++++ QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs | 267 ++++++++++++++ .../ClassicalOptimization/ProblemInstance.cs | 18 + QAOA/QAOA/Driver.cs | 65 ++++ QAOA/QAOA/Hamiltonians.qs | 61 ++++ QAOA/QAOA/QAOA.csproj | 14 + QAOA/QAOA/QAOARunner.qs | 46 +++ QAOA/QAOA/Utils.qs | 33 ++ QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs | 83 +++++ .../ClassicalOptimizationTests.cs | 71 ++++ .../ClassicalOptimizationTests/UtilsTests.cs | 51 +++ QAOA/QAOATest/QAOATest.csproj | 20 ++ QAOA/README.md | 30 ++ 16 files changed, 1370 insertions(+) create mode 100644 QAOA.sln create mode 100644 QAOA/.gitattributes create mode 100644 QAOA/.gitignore create mode 100644 QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs create mode 100644 QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs create mode 100644 QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs create mode 100644 QAOA/QAOA/Driver.cs create mode 100644 QAOA/QAOA/Hamiltonians.qs create mode 100644 QAOA/QAOA/QAOA.csproj create mode 100644 QAOA/QAOA/QAOARunner.qs create mode 100644 QAOA/QAOA/Utils.qs create mode 100644 QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs create mode 100644 QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs create mode 100644 QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs create mode 100644 QAOA/QAOATest/QAOATest.csproj create mode 100644 QAOA/README.md diff --git a/QAOA.sln b/QAOA.sln new file mode 100644 index 00000000000..4e52096cef2 --- /dev/null +++ b/QAOA.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29920.165 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\QAOA\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\QAOATest\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.Build.0 = Release|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {09481F99-E1AC-44CE-A892-7331820661DF} + EndGlobalSection +EndGlobal diff --git a/QAOA/.gitattributes b/QAOA/.gitattributes new file mode 100644 index 00000000000..1ff0c423042 --- /dev/null +++ b/QAOA/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/QAOA/.gitignore b/QAOA/.gitignore new file mode 100644 index 00000000000..4ce6fddec96 --- /dev/null +++ b/QAOA/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file diff --git a/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs b/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs new file mode 100644 index 00000000000..8c481e9810b --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs @@ -0,0 +1,177 @@ +using Microsoft.Quantum.Simulation.Core; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Quantum.QAOA +{ + public class ClassicalOptimizationUtils + { + + public struct FreeParamsVector + { + public Double[] beta; + public Double[] gamma; + } + + /// # Summary + /// Returns a vector of random doubles in a range from 0 to maximum. + /// + /// # Input + /// ## length + /// Length of a random vector. + /// ## maximum + /// Maximum value of a random double. + /// + /// # Output + /// A random vector of doubles. + + public static double[] getRandomVector(int length, double maximum) + { + var rand = new Random(); + double[] randomVector = new double[length]; + for (int i = 0; i < length; i++) + { + randomVector[i] = maximum * rand.NextDouble(); + } + + return randomVector; + } + + /// # Summary + /// Return the most common boolean string from a list of boolean values. + /// + /// # Input + /// ## list + /// List of boolean values. + /// + /// # Output + /// The most common boolean string. + + public static String getModeFromBoolList(List list) + { + Dictionary counter = new Dictionary(); + foreach (bool[] boolArray in list) + { + String boolString = getBoolStringFromBoolArray(boolArray); + if (counter.ContainsKey(boolString)) + { + counter[boolString] += 1; + } + else + { + counter[boolString] = 1; + } + + } + int maximum = 0; + String result = null; + foreach (string key in counter.Keys) + { + if (counter[key] > maximum) + { + maximum = counter[key]; + result = key; + } + } + + return result; + } + + /// # Summary + /// Converts an array of bools to a boolean string. + /// + /// # Input + /// ## boolArray + /// An array of bools. + /// + /// # Output + /// A boolean string. + + public static string getBoolStringFromBoolArray(bool[] boolArray) + { + System.Text.StringBuilder sb = new StringBuilder(); + foreach (bool b in boolArray) + { + sb.Append(b ? "1" : "0"); + } + return sb.ToString(); + } + + /// # Summary + /// Converts concatenated beta and gamma vectors into separate beta and gamma vector. + /// + /// # Input + /// ## bigfreeParamsVector + /// Concatenated beta and gamma vectors. + /// + /// # Output + /// FreeParamsVector that contains beta and gamma vectors. + /// + /// # Remarks + /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. + + public static FreeParamsVector convertVectorIntoHalves(double[] bigfreeParamsVector) + { + int size = bigfreeParamsVector.Length; + int vectorTermsNumber = size / 2; + FreeParamsVector freeParamsVector = new FreeParamsVector + { + + beta = bigfreeParamsVector[0..vectorTermsNumber], + gamma = bigfreeParamsVector[vectorTermsNumber..(2*vectorTermsNumber)], + + }; + + return freeParamsVector; + } + + /// # Summary + /// Prints current values of beta and gamma vectors as optimization is being performed. + /// + /// # Input + /// ## beta + /// Beta vector of coefficients. + /// ## gamma + /// Gamma vector of coefficients. + public static void printCurrentBetaGamma(QArray beta, QArray gamma) + { + Console.WriteLine("Current beta vector:"); + Console.WriteLine(beta); + + Console.WriteLine("Current gamma vector:"); + Console.WriteLine(gamma); + + } + + /// # Summary + /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. + /// + /// # Input + /// ## bestHamiltonian + /// Best value of a Hamiltonian so far. + /// ## bestVector + /// Best solution vector that generates the above value of a Hamiltonian so far. + public static void printCurrentBestSolution(double bestHamiltonian, String bestVector) + { + Console.WriteLine("Current best fidelity"); + Console.WriteLine(bestHamiltonian); + Console.WriteLine("Current best string"); + Console.WriteLine(bestVector); + } + + /// # Summary + /// Prints whether an optimization finished successfully. + /// + /// # Input + /// ## success + /// A flag that indiciates whether an optimization finished successfully. + public static void printSuccess(bool success) + { + Console.WriteLine("Was optimization successful?"); + Console.WriteLine(success); + Console.WriteLine("##################################"); + } + + } +} \ No newline at end of file diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs new file mode 100644 index 00000000000..e636f3f3fbd --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Accord.Math; +using Accord.Math.Optimization; +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators; + +namespace Quantum.QAOA + +{ + public struct OptimalSolution + { + public String optimalVector; + public Double optimalValue; + public Double[] optimalBeta; + public Double[] optimalGamma; + } + + public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later + { + ClassicalOptimizationUtils.FreeParamsVector FreeParamsVector; + int numberOfIterations; + int p; + ProblemInstance problemInstance; + Double bestHamiltonian; + String bestVector; + Double[] bestBeta; + Double[] bestGamma; + int numberOfRandomStartingPoints; + + + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null) + { + + this.numberOfIterations = numberOfIterations; + this.p = p; + this.problemInstance = problemInstance; + FreeParamsVector.beta = initialBeta; + FreeParamsVector.gamma = initialGamma; + bestHamiltonian = Double.MaxValue; + bestVector = null; + this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; + } + + + + public Double evaluateCostFunction(string result, double[] costs) + { + double costFunctionValue = 0; + for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + { + costFunctionValue += costs[i] * Char.GetNumericValue(result[i]); + } + + return costFunctionValue; + } + + /// # Summary + /// Calculates the value of the objective function Hamiltonian for a binary string provided. + /// + /// # Input + /// ## result + /// A binary string. In this context it is a result that we get after measuring the QAOA state. + /// + /// # Output + /// The value of the objective function Hamiltonian. + /// + /// # Remarks + /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. + + public double evaluateHamiltonian(string result) + { + double hamiltonianValue = 0; + for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + { + hamiltonianValue += problemInstance.OneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); + } + + for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + { + for (int j = i + 1; j < problemInstance.ProblemSizeInBits; j++) + { + hamiltonianValue += problemInstance.TwoLocalHamiltonianCoefficients[i * problemInstance.ProblemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); + } + } + + return hamiltonianValue; + } + + /// # 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) + { + ClassicalOptimizationUtils.FreeParamsVector freeParamsVector = ClassicalOptimizationUtils.convertVectorIntoHalves(bigfreeParamsVector); + double hamiltonianExpectationValue = 0; + List allSolutionVectors = new List(); + + var beta = new QArray(freeParamsVector.beta); + var gamma = new QArray(freeParamsVector.gamma); + + ClassicalOptimizationUtils.printCurrentBetaGamma(beta, gamma); + + var oneLocalHamiltonianCoefficients = new QArray(problemInstance.OneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(problemInstance.TwoLocalHamiltonianCoefficients); + + using (var qsim = new QuantumSimulator()) + { + + for (int i = 0; i < numberOfIterations; i++) + { + IQArray result = RunQaoa.Run(qsim, problemInstance.ProblemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; + allSolutionVectors.Add(result.ToArray()); + string solutionVector = ClassicalOptimizationUtils.getBoolStringFromBoolArray(result.ToArray()); + double hamiltonianValue = evaluateHamiltonian(solutionVector); + hamiltonianExpectationValue += (hamiltonianValue/numberOfIterations); + + } + + } + + updateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); + ClassicalOptimizationUtils.printCurrentBestSolution(this.bestHamiltonian, this.bestVector); + + return hamiltonianExpectationValue; + } + + /// # Summary + /// Updates the currently best solution if a new solution is better. + /// + /// # Input + /// ## hamiltonianExpectationValue + /// Expectation value of a Hamiltonian. + /// ## allSolutionVectors + /// A vector of all binary solutions that were found by a QAOA. + /// ## freeParamsVector + /// A vector of beta and gamma coefficients. + private void updateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, ClassicalOptimizationUtils.FreeParamsVector freeParamsVector) + { + if (hamiltonianExpectationValue < this.bestHamiltonian) + { + String mostProbableSolutionVectorTemp = ClassicalOptimizationUtils.getModeFromBoolList(allSolutionVectors); + bestHamiltonian = hamiltonianExpectationValue; + bestVector = mostProbableSolutionVectorTemp; + bestBeta = freeParamsVector.beta; + bestGamma = freeParamsVector.gamma; + } + } + + + /// # Summary + /// Generates constraints for elements in beta and gamma vectors. + /// + /// # Output + /// Generated constraints. + /// + /// # Remarks + /// For the canonical choice of the mixing Hamiltonian (i.e. the sum of X operators acting on single qubits), the range of values in the beta vector is 0 <= beta_i <= PI. + /// For the objective function Hamiltonian based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. + private NonlinearConstraint[] generateConstraints() + { + + NonlinearConstraint[] constraints = new NonlinearConstraint[4*p]; + foreach (var i in Enumerable.Range(0, p).Select(x => x * 2)) + { + int gammaIndex = 2 * p + i; + constraints[i] = new NonlinearConstraint(2 * p, x => x[i/2] >= 0); + constraints[i + 1] = new NonlinearConstraint(2 * p, x => x[i/2] <= Math.PI); + constraints[gammaIndex] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] >= 0); + constraints[gammaIndex + 1] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] <= 2 * Math.PI); + } + return constraints; + + } + + /// # Summary + /// We create beta and gamma vectors. If the user provided their set of parameters, we use them for the first run. Otherwise, we use randomly generated parameters. + /// + /// # Output + /// Initialized beta and gamma vectors concatenated. + private double[] setUpFreeParameters() + { + double[] betaCoefficients; + if (FreeParamsVector.beta != null) + { + betaCoefficients = FreeParamsVector.beta; + FreeParamsVector.beta = null; + } + else + { + betaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, Math.PI); + } + + double[] gammaCoefficients; + if (FreeParamsVector.gamma != null) + { + gammaCoefficients = FreeParamsVector.gamma; + FreeParamsVector.gamma = null; + } + else + { + gammaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, 2 * Math.PI); + } + + return betaCoefficients.Concat(gammaCoefficients).ToArray(); + } + + /// # Summary + /// Returns the optimal solution found by a QAOA. + /// + /// # Output + /// Optimal solution found by a QAOA. + public OptimalSolution getOptimalSolution() + { + OptimalSolution optimalSolution = new OptimalSolution + { + optimalVector = this.bestVector, + optimalValue = this.bestHamiltonian, + optimalBeta = this.bestBeta, + optimalGamma = this.bestGamma, + }; + + return optimalSolution; + } + + /// # Summary + /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum. + /// + /// # Output + /// Optimal solution to the optimization problem input by the user. + /// + /// # Remarks + /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. + /// The objective function Hamiltonian is based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. + public OptimalSolution runOptimization() + { + + Func objectiveFunction = calculateObjectiveFunction; + + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction); + + NonlinearConstraint[] constraints = generateConstraints(); + + for (int i = 0; i < numberOfRandomStartingPoints; i++) + { + var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); + double[] freeParameters = setUpFreeParameters(); + bool success = cobyla.Minimize(freeParameters); + ClassicalOptimizationUtils.printSuccess(success); + + } + + return getOptimalSolution(); + } + + + } +} diff --git a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs new file mode 100644 index 00000000000..911efb115e3 --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs @@ -0,0 +1,18 @@ +using System; + +namespace Quantum.QAOA +{ + public class ProblemInstance + { + public Double[] OneLocalHamiltonianCoefficients { get; } + public Double[] TwoLocalHamiltonianCoefficients { get; } + public int ProblemSizeInBits { get; } + + public ProblemInstance(Double[] oneLocalHamiltonianCoefficients, Double[] twoLocalHamiltonianCoefficients) + { + OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; + TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; + ProblemSizeInBits = OneLocalHamiltonianCoefficients.Length; + } + } +} diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Driver.cs new file mode 100644 index 00000000000..2e9ad11c90f --- /dev/null +++ b/QAOA/QAOA/Driver.cs @@ -0,0 +1,65 @@ +using System; + +namespace Quantum.QAOA +{ + class Driver + { + + + static void Main(string[] args) + { + //PARAMETERS + int numberOfIterations = 200; + int p = 3; + int numberOfRandomStartingPoints = 3; + + //EXAMPLES + + //Quantum Santa (http://quantumalgorithmzoo.org/traveling_santa/) + double[] dtx = { 0.619193, 0.742566, 0.060035, -1.568955, 0.045490 }; + double[] dtz = { 3.182203, -1.139045, 0.221082, 0.537753, -0.417222 }; + double[] segmentCosts = { 4.70, 9.09, 9.03, 5.70, 8.02, 1.71 }; + double[] dh = { 4 * 20 - 0.5 * 4.7, 4 * 20 - 0.5 * 9.09, 4 * 20 - 0.5 * 9.03, 4 * 20 - 0.5 * 5.70, 4 * 20 - 0.5 * 8.02, 4 * 20 - 0.5 * 1.71 }; + double[] dJ = { 40.0,40.0,20.0,40.0,40.0,40.0, + 40.0,40.0,40.0,20.0,40.0,40.0, + 40.0,40.0,40.0,40.0,40.0,40.0, + 40.0,40.0,40.0,40.0,40.0,40.0, + 40.0,40.0,40.0,40.0,40.0,20.0, + 40.0,40.0,40.0,40.0,40.0,40.0}; + ProblemInstance quantumSanta = new ProblemInstance(dh, dJ); + + + //MaxCut (medium.com/mdr-inc/qaoa-maxcut-using-blueqat-aaf33038f46e) + dh = new Double[] { 0,0,0,0,0}; + dJ = new Double[]{ 0,1,0,1,0, + 0,0,1,0,0, + 0,0,0,1,1, + 0,0,0,0,1, + 0,0,0,0,0}; + ProblemInstance maxCut1 = new ProblemInstance(dh, dJ); + + + //Rigetti MaxCut unit tests + dh = new Double[]{-0.5,0,-1,0.5}; + dJ = new Double[]{0,1,2,0, + 0,0,0.5,0, + 0,0,0,2.5, + 0,0,0,0}; + ProblemInstance maxCut2 = new ProblemInstance(dh, dJ); + + + dh = new Double[] { 0.8, -0.5 }; + dJ = new Double[]{ 0, -1, + 0, 0}; + ProblemInstance maxCut3 = new ProblemInstance(dh, dJ); + + //END EXAMPLES + + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut1, numberOfRandomStartingPoints); + + OptimalSolution res = cop.runOptimization(); + Console.WriteLine(res.optimalVector); + + } + } +} \ No newline at end of file diff --git a/QAOA/QAOA/Hamiltonians.qs b/QAOA/QAOA/Hamiltonians.qs new file mode 100644 index 00000000000..f36be87de7f --- /dev/null +++ b/QAOA/QAOA/Hamiltonians.qs @@ -0,0 +1,61 @@ +namespace Quantum.QAOA { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + + /// # Summary + /// Implements a unitary based on the mixing hamiltonian and applies it to qubits. + /// + /// # Input + /// ## qubits + /// Qubits that will be transformed by a unitary. + /// ## beta + /// Vector of coefficents for the unitary based on the mixing Hamiltonian. + /// + /// # References + /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. + + + operation EvolveWithMixingHamiltonian(qubits: Qubit[], beta: Double) : Unit + { + for(i in 0..Length(qubits)-1) + { + R(PauliX, -2.0*beta, qubits[i]); + } + } + + /// # Summary + /// Implements a unitary based on the objective function hamiltonian and applies it to qubits. + /// + /// # Input + /// ## qubits + /// Qubits that will be transformed by a unitary. + /// ## gamma + /// Vector of coefficents for the unitary based on the objective function Hamiltonian. + /// ## h + /// Array of 1-local coefficents of the objective function Hamiltonian. + /// ## J + /// Array of 2-local coefficents of the objective function Hamiltonian. + /// + /// # References + /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. + + operation EvolveWithObjectiveHamiltonian(qubits: Qubit[], gamma: Double, h: Double[], J: Double[]) : Unit + { + let numberOfQubits = Length(qubits); + using (ancillaQubit = Qubit[1]) + { + for(i in 0..numberOfQubits-1) + { + R(PauliZ, 2.0*gamma*h[i],qubits[i]); + } + for(i in 0..numberOfQubits-1) + { + for (j in i+1..numberOfQubits-1) + { + RunPhaseKickback(qubits, ancillaQubit, [i,j], 2.0*gamma*J[numberOfQubits*i+j]); + } + } + } + } +} diff --git a/QAOA/QAOA/QAOA.csproj b/QAOA/QAOA/QAOA.csproj new file mode 100644 index 00000000000..4994ceb6c9a --- /dev/null +++ b/QAOA/QAOA/QAOA.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + + diff --git a/QAOA/QAOA/QAOARunner.qs b/QAOA/QAOA/QAOARunner.qs new file mode 100644 index 00000000000..af8db6eb782 --- /dev/null +++ b/QAOA/QAOA/QAOARunner.qs @@ -0,0 +1,46 @@ +namespace Quantum.QAOA { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + + + /// # Summary + /// Prepares and measures the quantum state in the QAOA. + /// + /// # Input + /// ## problemSize + /// Number of qubits. + /// ## beta + /// Vector of coefficents for the unitary based on the mixing Hamiltonian. + /// ## gamma + /// Vector of coefficents for the unitary based on the objective function Hamiltonian. + /// ## h + /// Array of 1-local coefficents of the objective function Hamiltonian. + /// ## J + /// Array of 2-local coefficents of the objective function Hamiltonian. + /// ## p + /// Depth of the QAOA circuit. + /// + /// # Output + /// Array of boolean values that represent results of measurements on the QAOA state. + /// + /// # References + /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. + + operation RunQaoa(problemSize: Int, beta: Double[], gamma: Double[], h: Double[], J: Double[], p: Int) : Bool[] + { + + mutable result = new Bool[problemSize]; + using (x = Qubit[problemSize]) + { + ApplyToEach(H, x); // prepare the uniform distribution + for (i in 0..p-1) + { + EvolveWithObjectiveHamiltonian(x, gamma[i], h, J); // do Exp(-i H_C tz[i]) + EvolveWithMixingHamiltonian(x, beta[i]); // do Exp(-i H_0 tx[i]) + } + set result = MeasureAllAndReset(x); // measure in the computational basis + } + return result; + } +} diff --git a/QAOA/QAOA/Utils.qs b/QAOA/QAOA/Utils.qs new file mode 100644 index 00000000000..4ec42e366a8 --- /dev/null +++ b/QAOA/QAOA/Utils.qs @@ -0,0 +1,33 @@ +namespace Quantum.QAOA { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Measurement; + + + operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] + { + let N = Length(qubits); + mutable results = new Bool[N]; + for (i in 0..N-1) + { + set results w/= i <- (MResetZ(qubits[i]) == One); + } + return results; + } + + operation RunPhaseKickback(qubits: Qubit[], ancillaQubit: Qubit[], controlQubitsIndices: Int[], phaseExponent: Double) : Unit + { + for(i in 0..Length(controlQubitsIndices)-1) + { + CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); + } + + R(PauliZ, phaseExponent, ancillaQubit[0]); + + for(i in 0..Length(controlQubitsIndices)-1) + { + CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); + } + } +} \ No newline at end of file diff --git a/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs b/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs new file mode 100644 index 00000000000..05bdacbc7b9 --- /dev/null +++ b/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs @@ -0,0 +1,83 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Newtonsoft.Json; +using Quantum.QAOA; + +namespace QAOA.magicCommand +{ + public class HybridQaoaRunMagic : MagicSymbol + { + + public HybridQaoaRunMagic() + { + this.Name = $"%standard.hybridqaoa.run"; + this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json" }; + this.Kind = SymbolKind.Magic; + this.Execute = this.Run; + } + + /// + /// List of arguments + /// + public class Arguments + { + /// + /// Number of iterations in the fidelity sampling. + /// + [JsonProperty(PropertyName = "number_of_iterations")] + public int NumberOfIterations { get; set; } + + /// + /// Depth of a QAOA circuit. + /// + [JsonProperty(PropertyName = "p")] + public int p { get; set; } + + /// + /// Description of a combinatorial problem to be solved. + /// + [JsonProperty(PropertyName = "problem_instance")] + public ProblemInstance ProblemInstance { get; set; } + + /// + /// Number of random starting points in the angles parameters spaces. + /// + [JsonProperty(PropertyName = "number_of_random_starting_points")] + public int NumberOfRandomStartingPoints { get; set; } = 1; + + /// + /// Initial beta angles. + /// + [JsonProperty(PropertyName = "initial_beta")] + public Double[] InitialBeta { get; set; } = null; + + /// + /// Initial gamma angles. + /// + [JsonProperty(PropertyName = "initial_gamma")] + public Double[] InitialGamma { get; set; } = null; + } + + /// + /// Runs a hybrid QAOA. + /// + public async Task Run(string input, IChannel channel) + { + if (string.IsNullOrWhiteSpace(input)) + { + channel.Stderr("Please provide correct arguments"); + return ExecuteStatus.Error.ToExecutionResult(); + } + + var args = JsonConvert.DeserializeObject(input); + + + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance); //deal with optional params + + return hybridQaoa.runOptimization().ToExecutionResult(); + } + + + } +} diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs new file mode 100644 index 00000000000..00d7ebcd38d --- /dev/null +++ b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs @@ -0,0 +1,71 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using Quantum.QAOA; +using System; +using System.Reflection; + +namespace QAOATest.ClassicalOptimizationTests +{ + + [TestClass] + public class ClassicalOptimizationTest + { + + [TestMethod] + public void convertDataVectorToVectorsTest() + { + + ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); + + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); + + ClassicalOptimizationUtils.FreeParamsVector result = ClassicalOptimizationUtils.convertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); + + ClassicalOptimizationUtils.FreeParamsVector dataVectors = new ClassicalOptimizationUtils.FreeParamsVector(); + dataVectors.beta = new double[] { 1, 2, 3 }; + dataVectors.gamma = new double[] { 4, 5, 6 }; + + ClassicalOptimizationUtils.FreeParamsVector expectedResult = dataVectors; + + CollectionAssert.AreEqual(expectedResult.beta, result.beta, "Hamiltonian beta value not calculated correctly."); + CollectionAssert.AreEqual(expectedResult.gamma, result.gamma, "Hamiltonian gamma value not calculated correctly."); + + } + + [TestMethod] + public void evaluateHamiltonianTest() + { + ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); + + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); + + Double result = classicalOptimization.evaluateHamiltonian("0011"); + + Double expectedResult = -1; + + Assert.AreEqual(expectedResult, result, "Hamiltonian value not calculated correctly."); + + } + + [TestMethod] + public void evaluateCostFunctionTest() + { + ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); + + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, new double[] { 2 }, new double[] { 3 }); + + + string optimizationResult = "0101"; + + Double result = classicalOptimization.evaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); + + Double expectedResult = 4; + + Assert.AreEqual(expectedResult, result, "Cost function not calculated correctly."); + + + } + + + } +} diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs b/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs new file mode 100644 index 00000000000..85c66c00b29 --- /dev/null +++ b/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs @@ -0,0 +1,51 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using Quantum.QAOA; +using System.Collections.Generic; +using System.Text; + +namespace QAOATest.ClassicalOptimizationTests +{ + [TestClass] + public class UtilsTests + { + [TestMethod] + public void modeOfABoolListTest() + { + bool[] boolsArray1 = { false, false, true }; + bool[] boolsArray2 = { false, false, true }; + bool[] boolsArray3 = { false, false, false }; + bool[] boolsArray4 = { false, true, true }; + + List listOfBools = new List(); + listOfBools.Add(boolsArray1); + listOfBools.Add(boolsArray3); + listOfBools.Add(boolsArray2); + listOfBools.Add(boolsArray4); + + string expectedResult = "001"; + + string result = ClassicalOptimizationUtils.getModeFromBoolList(listOfBools); + + Assert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); + + + } + + [TestMethod] + public void boolStringFromBoolArrayTest() + { + bool[] boolsArray = { false, false, true }; + + + string expectedResult = "001"; + + string result = ClassicalOptimizationUtils.getBoolStringFromBoolArray(boolsArray); + + Assert.AreEqual(expectedResult, result, "Bool string not created correctly."); + + + } + } +} + diff --git a/QAOA/QAOATest/QAOATest.csproj b/QAOA/QAOATest/QAOATest.csproj new file mode 100644 index 00000000000..9a25671a4af --- /dev/null +++ b/QAOA/QAOATest/QAOATest.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + diff --git a/QAOA/README.md b/QAOA/README.md new file mode 100644 index 00000000000..3a2eb847794 --- /dev/null +++ b/QAOA/README.md @@ -0,0 +1,30 @@ +[![Unitary Fund](https://img.shields.io/badge/Supported%20By-UNITARY%20FUND-brightgreen.svg?style=for-the-badge)](http://unitary.fund) + +# QAOA in Q# + +The project is still in progress. This readme will be extended as the project develops. + +This project provides a hybrid quantum-classical algorithm for solving optimization problems. +It includes a Q# implementation of the Quantum Approximate Optimization Algorithm ([QAOA](https://arxiv.org/abs/1411.4028)) together with a classical optimizer in C#. +The classical optimizer uses a quantum objective function to choose hopefully optimal parameters for running the QAOA. +The quantum objective function is currently evaluated on a simulator backend provided by Q#. + +How to run it? +1) Import this project to Microsoft Visual Studio or similar. +2) Use Driver.cs to prepare your ProblemInstance and run the project (some examples also provided). + +Current limitations: + +- an optimization problem shall be encoded into a Hamiltonian consisting of Z operators, +- support for up to 2-local Hamiltonians, +- input consists of arrays of coefficients for 1-local and 2-local Hamiltonian terms, +- a gradient-free Cobyla optimizer is used for finding good QAOA input parameters. + +The high-level diagram of the implementation (notation comes from the [QAOA paper](https://arxiv.org/abs/1411.4028)): + +[![QAOA diagram](https://i.postimg.cc/sgryqr80/IMG-0202.jpg)](https://postimg.cc/XpQTBTnw) + +Dependencies: + +1) [Q# and Microsoft Quantum Libraries](https://docs.microsoft.com/en-us/quantum/language/) +2) [C# Accord Math library](http://accord-framework.net/docs/html/N_Accord_Math.htm) From 46acecab477aa2611f71825fb353e0eb69556a0a Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 26 Jul 2020 11:42:18 +0200 Subject: [PATCH 02/61] Unit test for running the hybrid QAOA added. --- QAOA/QAOA/Driver.cs | 11 +++++++--- .../ClassicalOptimizationTests.cs | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Driver.cs index 2e9ad11c90f..348cc95c976 100644 --- a/QAOA/QAOA/Driver.cs +++ b/QAOA/QAOA/Driver.cs @@ -9,9 +9,9 @@ class Driver static void Main(string[] args) { //PARAMETERS - int numberOfIterations = 200; + int numberOfIterations = 50; int p = 3; - int numberOfRandomStartingPoints = 3; + int numberOfRandomStartingPoints = 1; //EXAMPLES @@ -53,9 +53,14 @@ static void Main(string[] args) 0, 0}; ProblemInstance maxCut3 = new ProblemInstance(dh, dJ); + dh = new Double[] {0, 0 }; + dJ = new Double[]{ 0, 1, + 0, 0}; + ProblemInstance maxCut4 = new ProblemInstance(dh, dJ); + //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut1, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); OptimalSolution res = cop.runOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs index 00d7ebcd38d..264a6aa89ec 100644 --- a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs +++ b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs @@ -66,6 +66,28 @@ public void evaluateCostFunctionTest() } + [TestMethod] + public void runOptimizationTest() + { + double[] dh = new Double[] { 0, 0 }; + double[] dJ = new Double[]{ 0, 1, + 0, 0}; + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + + HybridQaoa classicalOptimization = new HybridQaoa(50, 2, simpleMaxCut, 2); + OptimalSolution optimalSolution = classicalOptimization.runOptimization(); + + string optimizationResult1 = "01"; + string optimizationResult2 = "10"; + + string result = optimalSolution.optimalVector; + Console.WriteLine(result); + + Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + + + } + } } From e39f121d83b944e7105c59153ec576fdde04346d Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 26 Jul 2020 14:47:52 +0200 Subject: [PATCH 03/61] Unit test for hybrid qaoa added. Code refactoring. --- .../HybridQaoaTests.cs} | 34 ++++++++++++++++++- .../UtilsTests.cs | 0 2 files changed, 33 insertions(+), 1 deletion(-) rename QAOA/QAOATest/{ClassicalOptimizationTests/ClassicalOptimizationTests.cs => HybridQaoaTests/HybridQaoaTests.cs} (72%) rename QAOA/QAOATest/{ClassicalOptimizationTests => HybridQaoaTests}/UtilsTests.cs (100%) diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs similarity index 72% rename from QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs rename to QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs index 264a6aa89ec..1b5953a7b06 100644 --- a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs @@ -72,9 +72,14 @@ public void runOptimizationTest() double[] dh = new Double[] { 0, 0 }; double[] dJ = new Double[]{ 0, 1, 0, 0}; + + int numberOfIterations = 50; + int p = 2; + int numberOfRandomStartingPoints = 2; + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); - HybridQaoa classicalOptimization = new HybridQaoa(50, 2, simpleMaxCut, 2); + HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); OptimalSolution optimalSolution = classicalOptimization.runOptimization(); string optimizationResult1 = "01"; @@ -85,6 +90,33 @@ public void runOptimizationTest() Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + } + + [TestMethod] + public void runOptimizationTest2() + { + double[] dh = new Double[] { 0, 0 ,0}; + double[] dJ = new Double[]{ 0, 1, 5, + 0, 0, 2, + 0, 0, 0}; + + int numberOfIterations = 50; + int p = 2; + int numberOfRandomStartingPoints = 2; + + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + + HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); + OptimalSolution optimalSolution = classicalOptimization.runOptimization(); + + string optimizationResult1 = "110"; + string optimizationResult2 = "001"; + + string result = optimalSolution.optimalVector; + Console.WriteLine(result); + + Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + } diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs b/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs similarity index 100% rename from QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs rename to QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs From f8f63699c903a3b15e37570613bd955b12f85e8d Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 2 Aug 2020 21:25:58 +0200 Subject: [PATCH 04/61] QAOA magic added with unit tests. --- .gitignore | 1 + QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs | 21 ++----- .../ClassicalOptimization/OptimalSolution.cs | 25 ++++++++ QAOA/QAOA/Driver.cs | 5 +- .../HybridQaoaMagic.cs} | 60 +++++++++++++++++-- .../HybridQaoaTests/HybridQaoaTests.cs | 33 +--------- .../HybridQaoaProblemInstanceMagicTests.cs | 44 ++++++++++++++ .../HybridQaoaRunMagicTests.cs | 51 ++++++++++++++++ .../QAOATest/MagicCommandTests/MockChannel.cs | 22 +++++++ QAOA/QAOATest/QAOATest.csproj | 6 ++ 10 files changed, 214 insertions(+), 54 deletions(-) create mode 100644 QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs rename QAOA/QAOA/{magicCommand/HybridQaoaRunMagic.cs => MagicCommand/HybridQaoaMagic.cs} (52%) create mode 100644 QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs create mode 100644 QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs create mode 100644 QAOA/QAOATest/MagicCommandTests/MockChannel.cs diff --git a/.gitignore b/.gitignore index 232a25886d2..99d456ffa56 100644 --- a/.gitignore +++ b/.gitignore @@ -330,3 +330,4 @@ __pycache__/ *.odx.cs *.xsd.cs +/QAOA/QAOATest/MagicCommandTests/sample.py diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs index e636f3f3fbd..65348fd9769 100644 --- a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs +++ b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs @@ -5,17 +5,11 @@ using Accord.Math.Optimization; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; +using QAOA.ClassicalOptimization; namespace Quantum.QAOA { - public struct OptimalSolution - { - public String optimalVector; - public Double optimalValue; - public Double[] optimalBeta; - public Double[] optimalGamma; - } public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later { @@ -219,17 +213,10 @@ private double[] setUpFreeParameters() /// /// # Output /// Optimal solution found by a QAOA. - public OptimalSolution getOptimalSolution() + public OptimalSolution GetOptimalSolution() { - OptimalSolution optimalSolution = new OptimalSolution - { - optimalVector = this.bestVector, - optimalValue = this.bestHamiltonian, - optimalBeta = this.bestBeta, - optimalGamma = this.bestGamma, - }; - return optimalSolution; + return new OptimalSolution(this.bestVector, this.bestHamiltonian, this.bestBeta, this.bestGamma); } /// # Summary @@ -259,7 +246,7 @@ public OptimalSolution runOptimization() } - return getOptimalSolution(); + return GetOptimalSolution(); } diff --git a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs new file mode 100644 index 00000000000..cc6904df95a --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace QAOA.ClassicalOptimization +{ + public class OptimalSolution + { + + public String OptimalVector { get; } + public Double OptimalValue { get; } + public Double[] OptimalBeta { get; } + public Double[] OptimalGamma { get; } + + public OptimalSolution(String optimalVector, Double optimalValue, Double[] optimalBeta, Double[] optimalGamma) + { + OptimalVector = optimalVector; + OptimalValue = optimalValue; + OptimalBeta = optimalBeta; + OptimalGamma = optimalGamma; + + } + + } +} diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Driver.cs index 348cc95c976..03b64c86eb1 100644 --- a/QAOA/QAOA/Driver.cs +++ b/QAOA/QAOA/Driver.cs @@ -1,4 +1,5 @@ -using System; +using QAOA.ClassicalOptimization; +using System; namespace Quantum.QAOA { @@ -63,7 +64,7 @@ static void Main(string[] args) HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); OptimalSolution res = cop.runOptimization(); - Console.WriteLine(res.optimalVector); + Console.WriteLine(res.OptimalVector); } } diff --git a/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs similarity index 52% rename from QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs rename to QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs index 05bdacbc7b9..ebf1c12cd53 100644 --- a/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs +++ b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs @@ -11,7 +11,7 @@ public class HybridQaoaRunMagic : MagicSymbol public HybridQaoaRunMagic() { - this.Name = $"%standard.hybridqaoa.run"; + this.Name = $"%qaoa.hybridqaoa.run"; this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json" }; this.Kind = SymbolKind.Magic; this.Execute = this.Run; @@ -72,12 +72,64 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance); //deal with optional params + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.InitialBeta, args.InitialGamma); return hybridQaoa.runOptimization().ToExecutionResult(); } + } + public class HybridQaoaProblemInstanceMagic : MagicSymbol + { + public HybridQaoaProblemInstanceMagic() + { + this.Name = $"%qaoa.hybridqaoa.create.problem.instance"; + this.Documentation = new Documentation() { Summary = "Prepares a problem instance objects that serves as one of arguments to %qaoa.hybridqaoa.run." }; + this.Kind = SymbolKind.Magic; + this.Execute = this.Run; + } - } + /// + /// List of arguments + /// + public class Arguments + { + /// + /// Coefficents for one-local Hamiltonian terms. + /// + [JsonProperty(PropertyName = "one_local_hamiltonian_coefficients")] + public Double[] OneLocalHamiltonianCoefficients { get; set; } + + /// + /// Coefficents for one-local Hamiltonian terms. + /// + [JsonProperty(PropertyName = "two_local_hamiltonian_coefficients")] + public Double[] TwoLocalHamiltonianCoefficients { get; set; } + + /// + /// Depth of a QAOA circuit. + /// + [JsonProperty(PropertyName = "problem_size_in_bits")] + public int ProblemSizeInBits { get; set; } + + } + + /// + /// Prepares a ProblemInstance object for a hybrid QAOA. + /// + public async Task Run(string input, IChannel channel) + { + if (string.IsNullOrWhiteSpace(input)) + { + channel.Stderr("Please provide correct arguments"); + return ExecuteStatus.Error.ToExecutionResult(); + } + + var args = JsonConvert.DeserializeObject(input); + + ProblemInstance problemInstance = new ProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); + + return problemInstance.ToExecutionResult(); + } + + } } diff --git a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs index 1b5953a7b06..6560f1a2d86 100644 --- a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs @@ -3,6 +3,7 @@ using Quantum.QAOA; using System; using System.Reflection; +using QAOA.ClassicalOptimization; namespace QAOATest.ClassicalOptimizationTests { @@ -85,41 +86,11 @@ public void runOptimizationTest() string optimizationResult1 = "01"; string optimizationResult2 = "10"; - string result = optimalSolution.optimalVector; + string result = optimalSolution.OptimalVector; Console.WriteLine(result); Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); } - - [TestMethod] - public void runOptimizationTest2() - { - double[] dh = new Double[] { 0, 0 ,0}; - double[] dJ = new Double[]{ 0, 1, 5, - 0, 0, 2, - 0, 0, 0}; - - int numberOfIterations = 50; - int p = 2; - int numberOfRandomStartingPoints = 2; - - ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); - - HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); - OptimalSolution optimalSolution = classicalOptimization.runOptimization(); - - string optimizationResult1 = "110"; - string optimizationResult2 = "001"; - - string result = optimalSolution.optimalVector; - Console.WriteLine(result); - - Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); - - - } - - } } diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs new file mode 100644 index 00000000000..0cf8d92359a --- /dev/null +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Newtonsoft.Json; +using Xunit; +using QAOA.magicCommand; +using Quantum.QAOA; +using System; + +namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +{ + + public class HybridQaoaProblemInstanceMagicTests + { + public (HybridQaoaProblemInstanceMagic, MockChannel) Init() => + (new HybridQaoaProblemInstanceMagic(), new MockChannel()); + + [Fact] + public async Task HybridQaoaProblemInstance() + { + var (magic, channel) = Init(); + Assert.Equal("%qaoa.hybridqaoa.create.problem.instance", magic.Name); + + double[] dh = new Double[] { 0, 0 }; + double[] dJ = new Double[]{ 0, 1, + 0, 0}; + + var args = JsonConvert.SerializeObject(new HybridQaoaProblemInstanceMagic.Arguments + { + OneLocalHamiltonianCoefficients = dh, + TwoLocalHamiltonianCoefficients = dJ + }); + + var result = await magic.Run(args, channel); + var problemInstance = result.Output as ProblemInstance; + Assert.Equal(ExecuteStatus.Ok, result.Status); + + Assert.True(problemInstance.ProblemSizeInBits.Equals(2)); + } + + } +} \ No newline at end of file diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs new file mode 100644 index 00000000000..20f725b19ce --- /dev/null +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Newtonsoft.Json; +using Xunit; +using QAOA.magicCommand; +using Quantum.QAOA; +using System; +using QAOA.ClassicalOptimization; + +namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +{ + public class HybridQaoaRunMagicTests + { + public (HybridQaoaRunMagic, MockChannel) Init() => + (new HybridQaoaRunMagic(), new MockChannel()); + + [Fact] + public async Task HybridQaoaRun() + { + var (magic, channel) = Init(); + Assert.Equal("%qaoa.hybridqaoa.run", magic.Name); + + var numberOfIterations = 50; + var p = 2; + double[] dh = new Double[] { 0, 0 }; + double[] dJ = new Double[]{ 0, 1, + 0, 0}; + + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + + var args = JsonConvert.SerializeObject(new HybridQaoaRunMagic.Arguments + { + NumberOfIterations = numberOfIterations, + p = p, + ProblemInstance = simpleMaxCut + }); + + var result = await magic.Run(args, channel); + var optimalSolution = result.Output as OptimalSolution; + Assert.Equal(ExecuteStatus.Ok, result.Status); + string optimizationResult1 = "01"; + string optimizationResult2 = "10"; + + Assert.True(optimalSolution.OptimalVector.Equals(optimizationResult1) || optimalSolution.OptimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + } + } + + } \ No newline at end of file diff --git a/QAOA/QAOATest/MagicCommandTests/MockChannel.cs b/QAOA/QAOATest/MagicCommandTests/MockChannel.cs new file mode 100644 index 00000000000..e63f19d56c9 --- /dev/null +++ b/QAOA/QAOATest/MagicCommandTests/MockChannel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +using Microsoft.Jupyter.Core; + +namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +{ + public class MockChannel : IChannel + { + public List errors = new List(); + public List msgs = new List(); + + public void Display(object displayable) + { + throw new NotImplementedException(); + } + + public void Stderr(string message) => errors.Add(message); + + public void Stdout(string message) => msgs.Add(message); + } +} diff --git a/QAOA/QAOATest/QAOATest.csproj b/QAOA/QAOATest/QAOATest.csproj index 9a25671a4af..42ee5e81325 100644 --- a/QAOA/QAOATest/QAOATest.csproj +++ b/QAOA/QAOATest/QAOATest.csproj @@ -11,6 +11,12 @@ + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From 227623a86957dc6430c82d1ef274d35e763c4ae9 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Mon, 3 Aug 2020 11:59:05 +0200 Subject: [PATCH 05/61] Code refactoring. --- QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs | 85 ++++++++----------- .../ClassicalOptimization/OptimalSolution.cs | 16 ++-- .../ClassicalOptimization/ProblemInstance.cs | 12 +-- ...ClassicalOptimizationUtils.cs => Utils.cs} | 20 ++--- QAOA/QAOA/{Driver.cs => Examples.cs} | 6 +- QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs | 2 +- .../HybridQaoaTests/HybridQaoaTests.cs | 24 +++--- QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs | 10 +-- .../HybridQaoaProblemInstanceMagicTests.cs | 4 +- .../HybridQaoaRunMagicTests.cs | 2 +- 10 files changed, 84 insertions(+), 97 deletions(-) rename QAOA/QAOA/ClassicalOptimization/{ClassicalOptimizationUtils.cs => Utils.cs} (88%) rename QAOA/QAOA/{Driver.cs => Examples.cs} (95%) diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs index 65348fd9769..1318181e411 100644 --- a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs +++ b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs @@ -13,11 +13,11 @@ namespace Quantum.QAOA public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later { - ClassicalOptimizationUtils.FreeParamsVector FreeParamsVector; + Utils.FreeParamsVector FreeParamsVector; int numberOfIterations; int p; ProblemInstance problemInstance; - Double bestHamiltonian; + Double bestHamiltonianValue; String bestVector; Double[] bestBeta; Double[] bestGamma; @@ -30,19 +30,19 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance this.numberOfIterations = numberOfIterations; this.p = p; this.problemInstance = problemInstance; - FreeParamsVector.beta = initialBeta; - FreeParamsVector.gamma = initialGamma; - bestHamiltonian = Double.MaxValue; + this.FreeParamsVector.beta = initialBeta; + this.FreeParamsVector.gamma = initialGamma; + bestHamiltonianValue = Double.MaxValue; bestVector = null; this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; } - public Double evaluateCostFunction(string result, double[] costs) + public Double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; - for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + for (int i = 0; i < problemInstance.problemSizeInBits; i++) { costFunctionValue += costs[i] * Char.GetNumericValue(result[i]); } @@ -63,19 +63,19 @@ public Double evaluateCostFunction(string result, double[] costs) /// # Remarks /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. - public double evaluateHamiltonian(string result) + public double EvaluateHamiltonian(string result) { double hamiltonianValue = 0; - for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + for (int i = 0; i < problemInstance.problemSizeInBits; i++) { - hamiltonianValue += problemInstance.OneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); + hamiltonianValue += problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); } - for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + for (int i = 0; i < problemInstance.problemSizeInBits; i++) { - for (int j = i + 1; j < problemInstance.ProblemSizeInBits; j++) + for (int j = i + 1; j < problemInstance.problemSizeInBits; j++) { - hamiltonianValue += problemInstance.TwoLocalHamiltonianCoefficients[i * problemInstance.ProblemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); + hamiltonianValue += problemInstance.twoLocalHamiltonianCoefficients[i * problemInstance.problemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); } } @@ -93,37 +93,37 @@ public double evaluateHamiltonian(string result) /// /// # Output /// The expected value of a Hamiltonian that we calculated in this run. - public Double calculateObjectiveFunction(double[] bigfreeParamsVector) + public Double CalculateObjectiveFunction(double[] bigfreeParamsVector) { - ClassicalOptimizationUtils.FreeParamsVector freeParamsVector = ClassicalOptimizationUtils.convertVectorIntoHalves(bigfreeParamsVector); + Utils.FreeParamsVector freeParamsVector = Utils.ConvertVectorIntoHalves(bigfreeParamsVector); double hamiltonianExpectationValue = 0; List allSolutionVectors = new List(); var beta = new QArray(freeParamsVector.beta); var gamma = new QArray(freeParamsVector.gamma); - ClassicalOptimizationUtils.printCurrentBetaGamma(beta, gamma); + Utils.PrintCurrentBetaGamma(beta, gamma); - var oneLocalHamiltonianCoefficients = new QArray(problemInstance.OneLocalHamiltonianCoefficients); - var twoLocalHamiltonianCoefficients = new QArray(problemInstance.TwoLocalHamiltonianCoefficients); + var oneLocalHamiltonianCoefficients = new QArray(problemInstance.oneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(problemInstance.twoLocalHamiltonianCoefficients); using (var qsim = new QuantumSimulator()) { for (int i = 0; i < numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, problemInstance.ProblemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; + IQArray result = RunQaoa.Run(qsim, problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; allSolutionVectors.Add(result.ToArray()); - string solutionVector = ClassicalOptimizationUtils.getBoolStringFromBoolArray(result.ToArray()); - double hamiltonianValue = evaluateHamiltonian(solutionVector); + string solutionVector = Utils.GetBoolStringFromBoolArray(result.ToArray()); + double hamiltonianValue = EvaluateHamiltonian(solutionVector); hamiltonianExpectationValue += (hamiltonianValue/numberOfIterations); } } - updateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); - ClassicalOptimizationUtils.printCurrentBestSolution(this.bestHamiltonian, this.bestVector); + UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); + Utils.PrintCurrentBestSolution(this.bestHamiltonianValue, this.bestVector); return hamiltonianExpectationValue; } @@ -138,12 +138,12 @@ public Double calculateObjectiveFunction(double[] bigfreeParamsVector) /// A vector of all binary solutions that were found by a QAOA. /// ## freeParamsVector /// A vector of beta and gamma coefficients. - private void updateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, ClassicalOptimizationUtils.FreeParamsVector freeParamsVector) + private void UpdateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, Utils.FreeParamsVector freeParamsVector) { - if (hamiltonianExpectationValue < this.bestHamiltonian) + if (hamiltonianExpectationValue < this.bestHamiltonianValue) { - String mostProbableSolutionVectorTemp = ClassicalOptimizationUtils.getModeFromBoolList(allSolutionVectors); - bestHamiltonian = hamiltonianExpectationValue; + String mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); + bestHamiltonianValue = hamiltonianExpectationValue; bestVector = mostProbableSolutionVectorTemp; bestBeta = freeParamsVector.beta; bestGamma = freeParamsVector.gamma; @@ -160,7 +160,7 @@ private void updateBestSolution(double hamiltonianExpectationValue, List /// # Remarks /// For the canonical choice of the mixing Hamiltonian (i.e. the sum of X operators acting on single qubits), the range of values in the beta vector is 0 <= beta_i <= PI. /// For the objective function Hamiltonian based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. - private NonlinearConstraint[] generateConstraints() + private NonlinearConstraint[] GenerateConstraints() { NonlinearConstraint[] constraints = new NonlinearConstraint[4*p]; @@ -181,7 +181,7 @@ private NonlinearConstraint[] generateConstraints() /// /// # Output /// Initialized beta and gamma vectors concatenated. - private double[] setUpFreeParameters() + private double[] SetUpFreeParameters() { double[] betaCoefficients; if (FreeParamsVector.beta != null) @@ -191,7 +191,7 @@ private double[] setUpFreeParameters() } else { - betaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, Math.PI); + betaCoefficients = Utils.GetRandomVector(p, Math.PI); } double[] gammaCoefficients; @@ -202,23 +202,12 @@ private double[] setUpFreeParameters() } else { - gammaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, 2 * Math.PI); + gammaCoefficients = Utils.GetRandomVector(p, 2 * Math.PI); } return betaCoefficients.Concat(gammaCoefficients).ToArray(); } - /// # Summary - /// Returns the optimal solution found by a QAOA. - /// - /// # Output - /// Optimal solution found by a QAOA. - public OptimalSolution GetOptimalSolution() - { - - return new OptimalSolution(this.bestVector, this.bestHamiltonian, this.bestBeta, this.bestGamma); - } - /// # Summary /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum. /// @@ -228,25 +217,25 @@ public OptimalSolution GetOptimalSolution() /// # Remarks /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. /// The objective function Hamiltonian is based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. - public OptimalSolution runOptimization() + public OptimalSolution RunOptimization() { - Func objectiveFunction = calculateObjectiveFunction; + Func objectiveFunction = CalculateObjectiveFunction; var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction); - NonlinearConstraint[] constraints = generateConstraints(); + NonlinearConstraint[] constraints = GenerateConstraints(); for (int i = 0; i < numberOfRandomStartingPoints; i++) { var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - double[] freeParameters = setUpFreeParameters(); + double[] freeParameters = SetUpFreeParameters(); bool success = cobyla.Minimize(freeParameters); - ClassicalOptimizationUtils.printSuccess(success); + Utils.PrintSuccess(success); } - return GetOptimalSolution(); + return new OptimalSolution(this.bestVector, this.bestHamiltonianValue, this.bestBeta, this.bestGamma); } diff --git a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs index cc6904df95a..3cd67d67d4a 100644 --- a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs +++ b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs @@ -7,17 +7,17 @@ namespace QAOA.ClassicalOptimization public class OptimalSolution { - public String OptimalVector { get; } - public Double OptimalValue { get; } - public Double[] OptimalBeta { get; } - public Double[] OptimalGamma { get; } + public String optimalVector { get; } + public Double optimalValue { get; } + public Double[] optimalBeta { get; } + public Double[] optimalGamma { get; } public OptimalSolution(String optimalVector, Double optimalValue, Double[] optimalBeta, Double[] optimalGamma) { - OptimalVector = optimalVector; - OptimalValue = optimalValue; - OptimalBeta = optimalBeta; - OptimalGamma = optimalGamma; + this.optimalVector = optimalVector; + this.optimalValue = optimalValue; + this.optimalBeta = optimalBeta; + this.optimalGamma = optimalGamma; } diff --git a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs index 911efb115e3..abab91b22e2 100644 --- a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs +++ b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs @@ -4,15 +4,15 @@ namespace Quantum.QAOA { public class ProblemInstance { - public Double[] OneLocalHamiltonianCoefficients { get; } - public Double[] TwoLocalHamiltonianCoefficients { get; } - public int ProblemSizeInBits { get; } + public Double[] oneLocalHamiltonianCoefficients { get; } + public Double[] twoLocalHamiltonianCoefficients { get; } + public int problemSizeInBits { get; } public ProblemInstance(Double[] oneLocalHamiltonianCoefficients, Double[] twoLocalHamiltonianCoefficients) { - OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; - TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; - ProblemSizeInBits = OneLocalHamiltonianCoefficients.Length; + this.oneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; + this.twoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; + this.problemSizeInBits = oneLocalHamiltonianCoefficients.Length; } } } diff --git a/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs b/QAOA/QAOA/ClassicalOptimization/Utils.cs similarity index 88% rename from QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs rename to QAOA/QAOA/ClassicalOptimization/Utils.cs index 8c481e9810b..d61dcbe9050 100644 --- a/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs +++ b/QAOA/QAOA/ClassicalOptimization/Utils.cs @@ -5,7 +5,7 @@ namespace Quantum.QAOA { - public class ClassicalOptimizationUtils + public class Utils { public struct FreeParamsVector @@ -26,13 +26,13 @@ public struct FreeParamsVector /// # Output /// A random vector of doubles. - public static double[] getRandomVector(int length, double maximum) + public static double[] GetRandomVector(int length, double maximumValue) { var rand = new Random(); double[] randomVector = new double[length]; for (int i = 0; i < length; i++) { - randomVector[i] = maximum * rand.NextDouble(); + randomVector[i] = maximumValue * rand.NextDouble(); } return randomVector; @@ -48,12 +48,12 @@ public static double[] getRandomVector(int length, double maximum) /// # Output /// The most common boolean string. - public static String getModeFromBoolList(List list) + public static String GetModeFromBoolList(List list) { Dictionary counter = new Dictionary(); foreach (bool[] boolArray in list) { - String boolString = getBoolStringFromBoolArray(boolArray); + String boolString = GetBoolStringFromBoolArray(boolArray); if (counter.ContainsKey(boolString)) { counter[boolString] += 1; @@ -88,7 +88,7 @@ public static String getModeFromBoolList(List list) /// # Output /// A boolean string. - public static string getBoolStringFromBoolArray(bool[] boolArray) + public static string GetBoolStringFromBoolArray(bool[] boolArray) { System.Text.StringBuilder sb = new StringBuilder(); foreach (bool b in boolArray) @@ -111,7 +111,7 @@ public static string getBoolStringFromBoolArray(bool[] boolArray) /// # Remarks /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. - public static FreeParamsVector convertVectorIntoHalves(double[] bigfreeParamsVector) + public static FreeParamsVector ConvertVectorIntoHalves(double[] bigfreeParamsVector) { int size = bigfreeParamsVector.Length; int vectorTermsNumber = size / 2; @@ -134,7 +134,7 @@ public static FreeParamsVector convertVectorIntoHalves(double[] bigfreeParamsVec /// Beta vector of coefficients. /// ## gamma /// Gamma vector of coefficients. - public static void printCurrentBetaGamma(QArray beta, QArray gamma) + public static void PrintCurrentBetaGamma(QArray beta, QArray gamma) { Console.WriteLine("Current beta vector:"); Console.WriteLine(beta); @@ -152,7 +152,7 @@ public static void printCurrentBetaGamma(QArray beta, QArray gam /// Best value of a Hamiltonian so far. /// ## bestVector /// Best solution vector that generates the above value of a Hamiltonian so far. - public static void printCurrentBestSolution(double bestHamiltonian, String bestVector) + public static void PrintCurrentBestSolution(double bestHamiltonian, String bestVector) { Console.WriteLine("Current best fidelity"); Console.WriteLine(bestHamiltonian); @@ -166,7 +166,7 @@ public static void printCurrentBestSolution(double bestHamiltonian, String bestV /// # Input /// ## success /// A flag that indiciates whether an optimization finished successfully. - public static void printSuccess(bool success) + public static void PrintSuccess(bool success) { Console.WriteLine("Was optimization successful?"); Console.WriteLine(success); diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Examples.cs similarity index 95% rename from QAOA/QAOA/Driver.cs rename to QAOA/QAOA/Examples.cs index 03b64c86eb1..e001b854b06 100644 --- a/QAOA/QAOA/Driver.cs +++ b/QAOA/QAOA/Examples.cs @@ -3,7 +3,7 @@ namespace Quantum.QAOA { - class Driver + class Examples { @@ -63,8 +63,8 @@ static void Main(string[] args) HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); - OptimalSolution res = cop.runOptimization(); - Console.WriteLine(res.OptimalVector); + OptimalSolution res = cop.RunOptimization(); + Console.WriteLine(res.optimalVector); } } diff --git a/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs index ebf1c12cd53..ee52d456db8 100644 --- a/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs +++ b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs @@ -74,7 +74,7 @@ public async Task Run(string input, IChannel channel) HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.InitialBeta, args.InitialGamma); - return hybridQaoa.runOptimization().ToExecutionResult(); + return hybridQaoa.RunOptimization().ToExecutionResult(); } } diff --git a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs index 6560f1a2d86..8b90f911cfd 100644 --- a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs @@ -1,8 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using Quantum.QAOA; using System; -using System.Reflection; using QAOA.ClassicalOptimization; namespace QAOATest.ClassicalOptimizationTests @@ -13,20 +11,20 @@ public class ClassicalOptimizationTest { [TestMethod] - public void convertDataVectorToVectorsTest() + public void ConvertDataVectorToVectorsTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); - ClassicalOptimizationUtils.FreeParamsVector result = ClassicalOptimizationUtils.convertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); + Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); - ClassicalOptimizationUtils.FreeParamsVector dataVectors = new ClassicalOptimizationUtils.FreeParamsVector(); + Utils.FreeParamsVector dataVectors = new Utils.FreeParamsVector(); dataVectors.beta = new double[] { 1, 2, 3 }; dataVectors.gamma = new double[] { 4, 5, 6 }; - ClassicalOptimizationUtils.FreeParamsVector expectedResult = dataVectors; + Utils.FreeParamsVector expectedResult = dataVectors; CollectionAssert.AreEqual(expectedResult.beta, result.beta, "Hamiltonian beta value not calculated correctly."); CollectionAssert.AreEqual(expectedResult.gamma, result.gamma, "Hamiltonian gamma value not calculated correctly."); @@ -34,13 +32,13 @@ public void convertDataVectorToVectorsTest() } [TestMethod] - public void evaluateHamiltonianTest() + public void EvaluateHamiltonianTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); - Double result = classicalOptimization.evaluateHamiltonian("0011"); + Double result = classicalOptimization.EvaluateHamiltonian("0011"); Double expectedResult = -1; @@ -49,7 +47,7 @@ public void evaluateHamiltonianTest() } [TestMethod] - public void evaluateCostFunctionTest() + public void EvaluateCostFunctionTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); @@ -58,7 +56,7 @@ public void evaluateCostFunctionTest() string optimizationResult = "0101"; - Double result = classicalOptimization.evaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); + Double result = classicalOptimization.EvaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); Double expectedResult = 4; @@ -68,7 +66,7 @@ public void evaluateCostFunctionTest() } [TestMethod] - public void runOptimizationTest() + public void RunHybridQaoaTest() { double[] dh = new Double[] { 0, 0 }; double[] dJ = new Double[]{ 0, 1, @@ -81,12 +79,12 @@ public void runOptimizationTest() ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); - OptimalSolution optimalSolution = classicalOptimization.runOptimization(); + OptimalSolution optimalSolution = classicalOptimization.RunOptimization(); string optimizationResult1 = "01"; string optimizationResult2 = "10"; - string result = optimalSolution.OptimalVector; + string result = optimalSolution.optimalVector; Console.WriteLine(result); Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); diff --git a/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs b/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs index 85c66c00b29..b2a13ffc153 100644 --- a/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs @@ -1,8 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; using Quantum.QAOA; using System.Collections.Generic; -using System.Text; namespace QAOATest.ClassicalOptimizationTests { @@ -10,7 +8,7 @@ namespace QAOATest.ClassicalOptimizationTests public class UtilsTests { [TestMethod] - public void modeOfABoolListTest() + public void ModeOfABoolListTest() { bool[] boolsArray1 = { false, false, true }; bool[] boolsArray2 = { false, false, true }; @@ -25,7 +23,7 @@ public void modeOfABoolListTest() string expectedResult = "001"; - string result = ClassicalOptimizationUtils.getModeFromBoolList(listOfBools); + string result = Utils.GetModeFromBoolList(listOfBools); Assert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); @@ -33,14 +31,14 @@ public void modeOfABoolListTest() } [TestMethod] - public void boolStringFromBoolArrayTest() + public void BoolStringFromBoolArrayTest() { bool[] boolsArray = { false, false, true }; string expectedResult = "001"; - string result = ClassicalOptimizationUtils.getBoolStringFromBoolArray(boolsArray); + string result = Utils.GetBoolStringFromBoolArray(boolsArray); Assert.AreEqual(expectedResult, result, "Bool string not created correctly."); diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs index 0cf8d92359a..7d35e1f1ca7 100644 --- a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs @@ -37,7 +37,9 @@ public async Task HybridQaoaProblemInstance() var problemInstance = result.Output as ProblemInstance; Assert.Equal(ExecuteStatus.Ok, result.Status); - Assert.True(problemInstance.ProblemSizeInBits.Equals(2)); + Assert.Equal(problemInstance.problemSizeInBits, dh.Length); + Assert.Equal(problemInstance.oneLocalHamiltonianCoefficients, dh); + Assert.Equal(problemInstance.twoLocalHamiltonianCoefficients,dJ); } } diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs index 20f725b19ce..7c3258c6ffb 100644 --- a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs @@ -44,7 +44,7 @@ public async Task HybridQaoaRun() string optimizationResult1 = "01"; string optimizationResult2 = "10"; - Assert.True(optimalSolution.OptimalVector.Equals(optimizationResult1) || optimalSolution.OptimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + Assert.True(optimalSolution.optimalVector.Equals(optimizationResult1) || optimalSolution.optimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); } } From 9c9bb7435d2c3ff0d4c6fb2b3b31aeed9bfc524e Mon Sep 17 00:00:00 2001 From: Dariusz Date: Mon, 3 Aug 2020 21:38:49 +0200 Subject: [PATCH 06/61] Code refactoring --- QAOA.sln | 4 ++-- QAOA/{QAOA => src}/Examples.cs | 0 .../ClassicalOptimization => src/HybridQaoa}/HybridQaoa.cs | 0 .../HybridQaoa}/OptimalSolution.cs | 0 .../HybridQaoa}/ProblemInstance.cs | 0 QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/Utils.cs | 0 QAOA/{QAOA => src}/MagicCommand/HybridQaoaMagic.cs | 0 QAOA/{QAOA => src}/QAOA.csproj | 0 QAOA/{QAOA => src/Qaoa}/Hamiltonians.qs | 0 QAOA/{QAOA/QAOARunner.qs => src/Qaoa/QaoaRunner.qs} | 0 QAOA/{QAOA => src/Qaoa}/Utils.qs | 0 QAOA/{QAOATest => tests}/HybridQaoaTests/HybridQaoaTests.cs | 0 QAOA/{QAOATest => tests}/HybridQaoaTests/UtilsTests.cs | 0 .../MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs | 2 +- .../MagicCommandTests/HybridQaoaRunMagicTests.cs | 0 QAOA/{QAOATest => tests}/MagicCommandTests/MockChannel.cs | 0 QAOA/{QAOATest => tests}/QAOATest.csproj | 2 +- 17 files changed, 4 insertions(+), 4 deletions(-) rename QAOA/{QAOA => src}/Examples.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/HybridQaoa.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/OptimalSolution.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/ProblemInstance.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/Utils.cs (100%) rename QAOA/{QAOA => src}/MagicCommand/HybridQaoaMagic.cs (100%) rename QAOA/{QAOA => src}/QAOA.csproj (100%) rename QAOA/{QAOA => src/Qaoa}/Hamiltonians.qs (100%) rename QAOA/{QAOA/QAOARunner.qs => src/Qaoa/QaoaRunner.qs} (100%) rename QAOA/{QAOA => src/Qaoa}/Utils.qs (100%) rename QAOA/{QAOATest => tests}/HybridQaoaTests/HybridQaoaTests.cs (100%) rename QAOA/{QAOATest => tests}/HybridQaoaTests/UtilsTests.cs (100%) rename QAOA/{QAOATest => tests}/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs (100%) rename QAOA/{QAOATest => tests}/MagicCommandTests/HybridQaoaRunMagicTests.cs (100%) rename QAOA/{QAOATest => tests}/MagicCommandTests/MockChannel.cs (100%) rename QAOA/{QAOATest => tests}/QAOATest.csproj (94%) diff --git a/QAOA.sln b/QAOA.sln index 4e52096cef2..17160aba520 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\QAOA\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\src\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\QAOATest\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\tests\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/QAOA/QAOA/Examples.cs b/QAOA/src/Examples.cs similarity index 100% rename from QAOA/QAOA/Examples.cs rename to QAOA/src/Examples.cs diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/src/HybridQaoa/HybridQaoa.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs rename to QAOA/src/HybridQaoa/HybridQaoa.cs diff --git a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs b/QAOA/src/HybridQaoa/OptimalSolution.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs rename to QAOA/src/HybridQaoa/OptimalSolution.cs diff --git a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs b/QAOA/src/HybridQaoa/ProblemInstance.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs rename to QAOA/src/HybridQaoa/ProblemInstance.cs diff --git a/QAOA/QAOA/ClassicalOptimization/Utils.cs b/QAOA/src/HybridQaoa/Utils.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/Utils.cs rename to QAOA/src/HybridQaoa/Utils.cs diff --git a/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs b/QAOA/src/MagicCommand/HybridQaoaMagic.cs similarity index 100% rename from QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs rename to QAOA/src/MagicCommand/HybridQaoaMagic.cs diff --git a/QAOA/QAOA/QAOA.csproj b/QAOA/src/QAOA.csproj similarity index 100% rename from QAOA/QAOA/QAOA.csproj rename to QAOA/src/QAOA.csproj diff --git a/QAOA/QAOA/Hamiltonians.qs b/QAOA/src/Qaoa/Hamiltonians.qs similarity index 100% rename from QAOA/QAOA/Hamiltonians.qs rename to QAOA/src/Qaoa/Hamiltonians.qs diff --git a/QAOA/QAOA/QAOARunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs similarity index 100% rename from QAOA/QAOA/QAOARunner.qs rename to QAOA/src/Qaoa/QaoaRunner.qs diff --git a/QAOA/QAOA/Utils.qs b/QAOA/src/Qaoa/Utils.qs similarity index 100% rename from QAOA/QAOA/Utils.qs rename to QAOA/src/Qaoa/Utils.qs diff --git a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs similarity index 100% rename from QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs rename to QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs diff --git a/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs similarity index 100% rename from QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs rename to QAOA/tests/HybridQaoaTests/UtilsTests.cs diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs similarity index 100% rename from QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs rename to QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs index 7d35e1f1ca7..ca3614556a0 100644 --- a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs @@ -5,9 +5,9 @@ using Microsoft.Jupyter.Core; using Newtonsoft.Json; using Xunit; +using System; using QAOA.magicCommand; using Quantum.QAOA; -using System; namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests { diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs similarity index 100% rename from QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs rename to QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs diff --git a/QAOA/QAOATest/MagicCommandTests/MockChannel.cs b/QAOA/tests/MagicCommandTests/MockChannel.cs similarity index 100% rename from QAOA/QAOATest/MagicCommandTests/MockChannel.cs rename to QAOA/tests/MagicCommandTests/MockChannel.cs diff --git a/QAOA/QAOATest/QAOATest.csproj b/QAOA/tests/QAOATest.csproj similarity index 94% rename from QAOA/QAOATest/QAOATest.csproj rename to QAOA/tests/QAOATest.csproj index 42ee5e81325..c5eec1be40b 100644 --- a/QAOA/QAOATest/QAOATest.csproj +++ b/QAOA/tests/QAOATest.csproj @@ -20,7 +20,7 @@ - + From 6a3b06dbd8cb225956aefc855ebb239a0d63b639 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Tue, 4 Aug 2020 09:15:20 +0200 Subject: [PATCH 07/61] Build files updated. --- Build/build.ps1 | 3 +++ Build/manifest.ps1 | 2 ++ Build/pack.ps1 | 3 +++ Build/test.ps1 | 3 +++ QAOA.sln | 2 +- QAOA/tests/{QAOATest.csproj => QAOATests.csproj} | 0 6 files changed, 12 insertions(+), 1 deletion(-) rename QAOA/tests/{QAOATest.csproj => QAOATests.csproj} (100%) diff --git a/Build/build.ps1 b/Build/build.ps1 index 4cc20d6404e..7fe64b92a97 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -40,6 +40,9 @@ Build-One 'publish' '../MachineLearning.sln' Write-Host "##[info]Build Jupyter magic library" Build-One 'publish' '../Magic.sln' +Write-Host "##[info]Build QAOA library" +Build-One 'publish' '../QAOA.sln' + if (-not $all_ok) { throw "At least one test failed execution. Check the logs." } \ No newline at end of file diff --git a/Build/manifest.ps1 b/Build/manifest.ps1 index f4b4ab285ed..00d4c91f19b 100644 --- a/Build/manifest.ps1 +++ b/Build/manifest.ps1 @@ -9,6 +9,7 @@ "Microsoft.Quantum.Chemistry", "Microsoft.Quantum.Numerics", "Microsoft.Quantum.MachineLearning" + "Microsoft.Quantum.QAOA" ); Assemblies = @( ".\Standard\src\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Standard.dll", @@ -17,5 +18,6 @@ ".\Chemistry\src\DataModel\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.DataModel.dll", ".\Chemistry\src\Runtime\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.Runtime.dll", ".\Chemistry\src\Tools\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\qdk-chem.dll" + ".\QAOA\src\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\QAOA.dll" ) | ForEach-Object { Get-Item (Join-Path $PSScriptRoot ".." $_) }; } | Write-Output; diff --git a/Build/pack.ps1 b/Build/pack.ps1 index ec9563561f9..711224c9088 100644 --- a/Build/pack.ps1 +++ b/Build/pack.ps1 @@ -42,6 +42,9 @@ Pack-One '../Chemistry/src/Jupyter/Jupyter.csproj' Write-Host "##[info]Pack chemistry tool" Pack-One '../Chemistry/src/Tools/Tools.csproj' +Write-Host "##[info]Pack QAOA library" +Pack-One '../QAOA/src/QAOA.csproj' + if (-not $all_ok) { throw "At least one test failed execution. Check the logs." } diff --git a/Build/test.ps1 b/Build/test.ps1 index 5337d4b0fba..1c7e886748d 100644 --- a/Build/test.ps1 +++ b/Build/test.ps1 @@ -40,6 +40,9 @@ Test-One '../Chemistry/tests/JupyterTests/JupyterTests.csproj' Write-Host "##[info]Testing Numerics/tests/NumericsTests.csproj" Test-One '../Numerics/tests/NumericsTests.csproj' +Write-Host "##[info]Testing QAOA/tests/QAOATests.csproj" +Test-One '../QAOA/tests/QAOATests.csproj' + if (-not $all_ok) { throw "At least one test failed execution. Check the logs." } diff --git a/QAOA.sln b/QAOA.sln index 17160aba520..0cca796c148 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\src\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\tests\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOATests", "QAOA\tests\QAOATests.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/QAOA/tests/QAOATest.csproj b/QAOA/tests/QAOATests.csproj similarity index 100% rename from QAOA/tests/QAOATest.csproj rename to QAOA/tests/QAOATests.csproj From 7facf12c52667a705ebfd09d59ef48587f694b41 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Tue, 4 Aug 2020 20:07:28 +0200 Subject: [PATCH 08/61] Project structure improved. Basic quantum unit tests added. --- QAOA.sln | 35 +++++++++++++++--- QAOA/src/HybridQaoa/HybridQaoa.cs | 1 + QAOA/src/Qaoa/Hamiltonians.qs | 2 +- QAOA/src/Qaoa/QaoaRunner.qs | 2 +- QAOA/src/Qaoa/Utils.qs | 2 +- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 2 +- .../HybridQaoaTests.csproj} | 8 +---- QAOA/tests/HybridQaoaTests/UtilsTests.cs | 2 +- .../HybridQaoaProblemInstanceMagicTests.cs | 3 +- .../HybridQaoaRunMagicTests.cs | 4 +-- QAOA/tests/JupyterTests/JupyterTests.csproj | 26 ++++++++++++++ .../MockChannel.cs | 2 +- QAOA/tests/QaoaTests/QaoaTests.csproj | 20 +++++++++++ QAOA/tests/QaoaTests/Tests.qs | 17 +++++++++ QAOA/tests/QaoaTests/UtilsTests.qs | 36 +++++++++++++++++++ 15 files changed, 141 insertions(+), 21 deletions(-) rename QAOA/tests/{QAOATests.csproj => HybridQaoaTests/HybridQaoaTests.csproj} (55%) rename QAOA/tests/{MagicCommandTests => JupyterTests}/HybridQaoaProblemInstanceMagicTests.cs (94%) rename QAOA/tests/{MagicCommandTests => JupyterTests}/HybridQaoaRunMagicTests.cs (96%) create mode 100644 QAOA/tests/JupyterTests/JupyterTests.csproj rename QAOA/tests/{MagicCommandTests => JupyterTests}/MockChannel.cs (89%) create mode 100644 QAOA/tests/QaoaTests/QaoaTests.csproj create mode 100644 QAOA/tests/QaoaTests/Tests.qs create mode 100644 QAOA/tests/QaoaTests/UtilsTests.qs diff --git a/QAOA.sln b/QAOA.sln index 0cca796c148..4de26b7640b 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -5,7 +5,17 @@ VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\src\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOATests", "QAOA\tests\QAOATests.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HybridQaoaTests", "QAOA\tests\HybridQaoaTests\HybridQaoaTests.csproj", "{1623F038-210A-4BA2-8D4E-9AF611610829}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JupyterTests", "QAOA\tests\JupyterTests\JupyterTests.csproj", "{3C8B4AF6-5495-4F23-B7B2-634E5A667837}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QaoaTests", "QAOA\tests\QaoaTests\QaoaTests.csproj", "{208C0012-D62F-4F29-8738-394A62BBE842}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HybridQaoa", "HybridQaoa", "{A6612841-F6D1-4A8E-A8F8-4430F9FF7992}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AD73B607-0EF5-4C11-8832-22D584939780}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{80082123-4392-4F0E-8F87-26183C620693}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,14 +27,29 @@ Global {159D83BF-56A2-41B7-951B-35292F5A9F23}.Debug|Any CPU.Build.0 = Debug|Any CPU {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.ActiveCfg = Release|Any CPU {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.Build.0 = Release|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.Build.0 = Release|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Release|Any CPU.Build.0 = Release|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Release|Any CPU.Build.0 = Release|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Debug|Any CPU.Build.0 = Debug|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Release|Any CPU.ActiveCfg = Release|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {159D83BF-56A2-41B7-951B-35292F5A9F23} = {AD73B607-0EF5-4C11-8832-22D584939780} + {1623F038-210A-4BA2-8D4E-9AF611610829} = {80082123-4392-4F0E-8F87-26183C620693} + {3C8B4AF6-5495-4F23-B7B2-634E5A667837} = {80082123-4392-4F0E-8F87-26183C620693} + {208C0012-D62F-4F29-8738-394A62BBE842} = {80082123-4392-4F0E-8F87-26183C620693} + {AD73B607-0EF5-4C11-8832-22D584939780} = {A6612841-F6D1-4A8E-A8F8-4430F9FF7992} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {09481F99-E1AC-44CE-A892-7331820661DF} EndGlobalSection diff --git a/QAOA/src/HybridQaoa/HybridQaoa.cs b/QAOA/src/HybridQaoa/HybridQaoa.cs index 1318181e411..8ebffdb0936 100644 --- a/QAOA/src/HybridQaoa/HybridQaoa.cs +++ b/QAOA/src/HybridQaoa/HybridQaoa.cs @@ -3,6 +3,7 @@ using System.Linq; using Accord.Math; using Accord.Math.Optimization; +using Microsoft.Quantum.QAOA; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; using QAOA.ClassicalOptimization; diff --git a/QAOA/src/Qaoa/Hamiltonians.qs b/QAOA/src/Qaoa/Hamiltonians.qs index f36be87de7f..0e514d4529e 100644 --- a/QAOA/src/Qaoa/Hamiltonians.qs +++ b/QAOA/src/Qaoa/Hamiltonians.qs @@ -1,4 +1,4 @@ -namespace Quantum.QAOA { +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index af8db6eb782..5bd0334b73a 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -1,4 +1,4 @@ -namespace Quantum.QAOA { +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index 4ec42e366a8..d553e38b63f 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -1,4 +1,4 @@ -namespace Quantum.QAOA { +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 8b90f911cfd..60ba806590b 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -3,7 +3,7 @@ using System; using QAOA.ClassicalOptimization; -namespace QAOATest.ClassicalOptimizationTests +namespace Microsoft.Quantum.QAOA.HybridQaoaTests { [TestClass] diff --git a/QAOA/tests/QAOATests.csproj b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj similarity index 55% rename from QAOA/tests/QAOATests.csproj rename to QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj index c5eec1be40b..7a5759a0de3 100644 --- a/QAOA/tests/QAOATests.csproj +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj @@ -11,16 +11,10 @@ - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs index b2a13ffc153..0856270e784 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/UtilsTests.cs @@ -2,7 +2,7 @@ using Quantum.QAOA; using System.Collections.Generic; -namespace QAOATest.ClassicalOptimizationTests +namespace Microsoft.Quantum.QAOA.HybridQaoaTests { [TestClass] public class UtilsTests diff --git a/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs similarity index 94% rename from QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs rename to QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index ca3614556a0..fa6913901f0 100644 --- a/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -8,8 +8,9 @@ using System; using QAOA.magicCommand; using Quantum.QAOA; +using Microsoft.Quantum.QAOA.JupyterTests; -namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +namespace Microsoft.Quantum.QAOA.HybridQaoaTests { public class HybridQaoaProblemInstanceMagicTests diff --git a/QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs similarity index 96% rename from QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs rename to QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 7c3258c6ffb..d0e7a7dd9ed 100644 --- a/QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -4,13 +4,13 @@ using System.Threading.Tasks; using Microsoft.Jupyter.Core; using Newtonsoft.Json; -using Xunit; using QAOA.magicCommand; using Quantum.QAOA; using System; using QAOA.ClassicalOptimization; +using Xunit; -namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +namespace Microsoft.Quantum.QAOA.JupyterTests { public class HybridQaoaRunMagicTests { diff --git a/QAOA/tests/JupyterTests/JupyterTests.csproj b/QAOA/tests/JupyterTests/JupyterTests.csproj new file mode 100644 index 00000000000..b157f4abf10 --- /dev/null +++ b/QAOA/tests/JupyterTests/JupyterTests.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/QAOA/tests/MagicCommandTests/MockChannel.cs b/QAOA/tests/JupyterTests/MockChannel.cs similarity index 89% rename from QAOA/tests/MagicCommandTests/MockChannel.cs rename to QAOA/tests/JupyterTests/MockChannel.cs index e63f19d56c9..b56b38f196b 100644 --- a/QAOA/tests/MagicCommandTests/MockChannel.cs +++ b/QAOA/tests/JupyterTests/MockChannel.cs @@ -3,7 +3,7 @@ using Microsoft.Jupyter.Core; -namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +namespace Microsoft.Quantum.QAOA.JupyterTests { public class MockChannel : IChannel { diff --git a/QAOA/tests/QaoaTests/QaoaTests.csproj b/QAOA/tests/QaoaTests/QaoaTests.csproj new file mode 100644 index 00000000000..f514d649463 --- /dev/null +++ b/QAOA/tests/QaoaTests/QaoaTests.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + false + + + + + + + + + + + + + + + diff --git a/QAOA/tests/QaoaTests/Tests.qs b/QAOA/tests/QaoaTests/Tests.qs new file mode 100644 index 00000000000..9d4f36f7b0e --- /dev/null +++ b/QAOA/tests/QaoaTests/Tests.qs @@ -0,0 +1,17 @@ +namespace Quantum.QaoaTests { + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.QAOA; + + + @Test("QuantumSimulator") + operation AllocateQubit () : Unit { + + using (q = Qubit()) { + Assert([PauliZ], [q], Zero, "Newly allocated qubit must be in |0> state."); + } + + Message("Test passed."); + } +} diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs new file mode 100644 index 00000000000..2b66b129f32 --- /dev/null +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Tests { + open Microsoft.Quantum.Logical; + open Microsoft.Quantum.Arrays; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Math; + open Microsoft.Quantum.QAOA; + + @Test("QuantumSimulator") + operation RunPhaseKickbackTest() : Unit { + + let numberOfQubits = 1; + let ancillaQubits = 1; + let controlQubitsIndices = [0]; + let phaseExponent = 0.5; + let complexOne = Complex(1.0, 0.0); + let complexZero = Complex(0.0, 0.0); + + using (qubits = Qubit[numberOfQubits+ancillaQubits]) + { + RunPhaseKickback(qubits[...1], qubits[1...],controlQubitsIndices,phaseExponent); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[0], 1E-06); + ResetAll(qubits); + } + } + + @Test("QuantumSimulator") + operation MeasureAllAndResetTest() : Unit { + + + } + +} From 300495c3db9e26dc5db9037f0f2bc497dc005b16 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Thu, 6 Aug 2020 20:50:38 +0200 Subject: [PATCH 09/61] Qaoa unit tests extended. Code refactoring. --- Build/test.ps1 | 10 +++- QAOA.sln | 2 - QAOA/src/Examples.cs | 2 +- .../HybridQaoaMagic.cs | 0 QAOA/src/QAOA.csproj | 2 +- QAOA/src/Qaoa/Utils.qs | 2 + QAOA/tests/QaoaTests/Tests.qs | 17 ------- QAOA/tests/QaoaTests/UtilsTests.qs | 46 +++++++++++++++++-- 8 files changed, 55 insertions(+), 26 deletions(-) rename QAOA/src/{MagicCommand => Jupyter}/HybridQaoaMagic.cs (100%) delete mode 100644 QAOA/tests/QaoaTests/Tests.qs diff --git a/Build/test.ps1 b/Build/test.ps1 index 1c7e886748d..ca544930561 100644 --- a/Build/test.ps1 +++ b/Build/test.ps1 @@ -40,8 +40,14 @@ Test-One '../Chemistry/tests/JupyterTests/JupyterTests.csproj' Write-Host "##[info]Testing Numerics/tests/NumericsTests.csproj" Test-One '../Numerics/tests/NumericsTests.csproj' -Write-Host "##[info]Testing QAOA/tests/QAOATests.csproj" -Test-One '../QAOA/tests/QAOATests.csproj' +Write-Host "##[info]Testing QAOA/tests/QaoaTests/QaoaTests.csproj" +Test-One '../QAOA/tests//QaoaTests/QaoaTests.csproj' + +Write-Host "##[info]Testing QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj" +Test-One '../QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj' + +Write-Host "##[info]Testing QAOA/tests/JupyterTests/JupyterTests.csproj" +Test-One '../QAOA/tests/JupyterTests/JupyterTests.csproj' if (-not $all_ok) { throw "At least one test failed execution. Check the logs." diff --git a/QAOA.sln b/QAOA.sln index 4de26b7640b..3bfbe8607d4 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JupyterTests", "QAOA\tests\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QaoaTests", "QAOA\tests\QaoaTests\QaoaTests.csproj", "{208C0012-D62F-4F29-8738-394A62BBE842}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HybridQaoa", "HybridQaoa", "{A6612841-F6D1-4A8E-A8F8-4430F9FF7992}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AD73B607-0EF5-4C11-8832-22D584939780}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{80082123-4392-4F0E-8F87-26183C620693}" diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index e001b854b06..7f762a5a62d 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -61,7 +61,7 @@ static void Main(string[] args) //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, quantumSanta, numberOfRandomStartingPoints); OptimalSolution res = cop.RunOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/src/MagicCommand/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs similarity index 100% rename from QAOA/src/MagicCommand/HybridQaoaMagic.cs rename to QAOA/src/Jupyter/HybridQaoaMagic.cs diff --git a/QAOA/src/QAOA.csproj b/QAOA/src/QAOA.csproj index 4994ceb6c9a..541726519c0 100644 --- a/QAOA/src/QAOA.csproj +++ b/QAOA/src/QAOA.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index d553e38b63f..7d3a8a83a8b 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -3,6 +3,7 @@ open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; + open Microsoft.Quantum.Diagnostics; operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] @@ -29,5 +30,6 @@ { CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); } + } } \ No newline at end of file diff --git a/QAOA/tests/QaoaTests/Tests.qs b/QAOA/tests/QaoaTests/Tests.qs deleted file mode 100644 index 9d4f36f7b0e..00000000000 --- a/QAOA/tests/QaoaTests/Tests.qs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Quantum.QaoaTests { - open Microsoft.Quantum.Canon; - open Microsoft.Quantum.Diagnostics; - open Microsoft.Quantum.Intrinsic; - open Microsoft.Quantum.QAOA; - - - @Test("QuantumSimulator") - operation AllocateQubit () : Unit { - - using (q = Qubit()) { - Assert([PauliZ], [q], Zero, "Newly allocated qubit must be in |0> state."); - } - - Message("Test passed."); - } -} diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs index 2b66b129f32..7b8a2628c2f 100644 --- a/QAOA/tests/QaoaTests/UtilsTests.qs +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -16,20 +16,60 @@ namespace Microsoft.Quantum.Tests { let ancillaQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; - let complexOne = Complex(1.0, 0.0); - let complexZero = Complex(0.0, 0.0); + let complexZero = Complex(1.0, 0.0); + let complexOne = Complex(0.0, 0.0); using (qubits = Qubit[numberOfQubits+ancillaQubits]) { RunPhaseKickback(qubits[...1], qubits[1...],controlQubitsIndices,phaseExponent); - AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[0], 1E-06); + AssertQubitIsInStateWithinTolerance((complexZero,complexOne), qubits[0], 1E-05); + ResetAll(qubits); + } + } + + @Test("QuantumSimulator") + operation RunPhaseKickbackTest2() : Unit { + + let numberOfQubits = 1; + let ancillaQubits = 1; + let controlQubitsIndices = [0]; + let phaseExponent = 0.5; + + let complexZero = Complex(0.685125,-0.174941); + let complexOne = Complex(0.685125,0.174941); + + using (qubits = Qubit[numberOfQubits+ancillaQubits]) + { + H(qubits[0]); + RunPhaseKickback([qubits[0]], [qubits[1]],controlQubitsIndices,phaseExponent); + AssertQubitIsInStateWithinTolerance((complexZero,complexOne), qubits[0], 1E-05); ResetAll(qubits); } } @Test("QuantumSimulator") operation MeasureAllAndResetTest() : Unit { + let numberOfQubits = 4; + let complexOne = Complex(1.0, 0.0); + let complexZero = Complex(0.0, 0.0); + using (qubits = Qubit[numberOfQubits]) + { + X(qubits[0]); + X(qubits[2]); + let result = MeasureAllAndReset(qubits); + + EqualityFactB(result[0], true, "Expected |1> state."); + EqualityFactB(result[1], false, "Expected |0> state."); + EqualityFactB(result[2], true, "Expected |1> state."); + EqualityFactB(result[3], false, "Expected |0> state."); + + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[0], 1E-06); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[1], 1E-06); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[2], 1E-06); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[3], 1E-06); + + } } From 0f4789fccae11e83d0155ff74ed913a82f17deb5 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Fri, 7 Aug 2020 20:42:01 +0200 Subject: [PATCH 10/61] Logger class added. Code refactoring. --- QAOA/src/Examples.cs | 13 +- QAOA/src/Jupyter/HybridQaoaMagic.cs | 14 +- QAOA/src/Qaoa/Utils.qs | 1 - .../{HybridQaoa => QaoaHybrid}/HybridQaoa.cs | 144 +++++++++--------- .../OptimalSolution.cs | 10 +- .../ProblemInstance.cs | 6 +- QAOA/src/QaoaHybrid/QaoaLogger.cs | 53 +++++++ QAOA/src/{HybridQaoa => QaoaHybrid}/Utils.cs | 59 +------ QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 3 +- QAOA/tests/HybridQaoaTests/UtilsTests.cs | 2 +- .../HybridQaoaProblemInstanceMagicTests.cs | 4 +- .../JupyterTests/HybridQaoaRunMagicTests.cs | 5 +- 12 files changed, 161 insertions(+), 153 deletions(-) rename QAOA/src/{HybridQaoa => QaoaHybrid}/HybridQaoa.cs (62%) rename QAOA/src/{HybridQaoa => QaoaHybrid}/OptimalSolution.cs (83%) rename QAOA/src/{HybridQaoa => QaoaHybrid}/ProblemInstance.cs (92%) create mode 100644 QAOA/src/QaoaHybrid/QaoaLogger.cs rename QAOA/src/{HybridQaoa => QaoaHybrid}/Utils.cs (65%) diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index 7f762a5a62d..7e7b981f6a9 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -1,12 +1,11 @@ -using QAOA.ClassicalOptimization; -using System; - -namespace Quantum.QAOA +namespace Quantum.QAOA { - class Examples - { + using global::QAOA.QaoaHybrid; + using System; + class Examples + { static void Main(string[] args) { //PARAMETERS @@ -61,7 +60,7 @@ static void Main(string[] args) //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, quantumSanta, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); OptimalSolution res = cop.RunOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index ee52d456db8..3e10781a2be 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -1,11 +1,11 @@ -using System; -using System.Threading.Tasks; -using Microsoft.Jupyter.Core; -using Newtonsoft.Json; -using Quantum.QAOA; - -namespace QAOA.magicCommand +namespace QAOA.Jupyter { + using System; + using System.Threading.Tasks; + using Microsoft.Jupyter.Core; + using Newtonsoft.Json; + using QAOA.QaoaHybrid; + public class HybridQaoaRunMagic : MagicSymbol { diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index 7d3a8a83a8b..23e723c5bdf 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -3,7 +3,6 @@ open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; - open Microsoft.Quantum.Diagnostics; operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] diff --git a/QAOA/src/HybridQaoa/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs similarity index 62% rename from QAOA/src/HybridQaoa/HybridQaoa.cs rename to QAOA/src/QaoaHybrid/HybridQaoa.cs index 8ebffdb0936..33b2a432095 100644 --- a/QAOA/src/HybridQaoa/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -1,41 +1,47 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Accord.Math; -using Accord.Math.Optimization; -using Microsoft.Quantum.QAOA; -using Microsoft.Quantum.Simulation.Core; -using Microsoft.Quantum.Simulation.Simulators; -using QAOA.ClassicalOptimization; - -namespace Quantum.QAOA +namespace QAOA.QaoaHybrid { - - public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later + using System; + using System.Collections.Generic; + using System.Linq; + using Accord.Math; + using Accord.Math.Optimization; + using Microsoft.Quantum.QAOA; + using Microsoft.Quantum.Simulation.Core; + using Microsoft.Quantum.Simulation.Simulators; + + //currently support up to 2-local Hamiltonians; will be generalized later + public class HybridQaoa { - Utils.FreeParamsVector FreeParamsVector; - int numberOfIterations; - int p; - ProblemInstance problemInstance; - Double bestHamiltonianValue; - String bestVector; - Double[] bestBeta; - Double[] bestGamma; - int numberOfRandomStartingPoints; - - - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null) + private Utils.FreeParamsVector freeParamsVector; + private int numberOfIterations; + private int p; + private ProblemInstance problemInstance; + private Double bestHamiltonianValue; + private String bestVector; + private Double[] bestBeta; + private Double[] bestGamma; + private int numberOfRandomStartingPoints; + private QaoaLogger logger; + private String loggerFilePath; + + + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null, String loggerFilePath = null) { this.numberOfIterations = numberOfIterations; this.p = p; this.problemInstance = problemInstance; - this.FreeParamsVector.beta = initialBeta; - this.FreeParamsVector.gamma = initialGamma; - bestHamiltonianValue = Double.MaxValue; - bestVector = null; + this.freeParamsVector.beta = initialBeta; + this.freeParamsVector.gamma = initialGamma; + this.bestHamiltonianValue = double.MaxValue; + this.bestVector = null; this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; + this.loggerFilePath = loggerFilePath; + if (loggerFilePath != null) + { + this.logger = new QaoaLogger(loggerFilePath); + } } @@ -43,7 +49,7 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance public Double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; - for (int i = 0; i < problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { costFunctionValue += costs[i] * Char.GetNumericValue(result[i]); } @@ -67,16 +73,16 @@ public Double EvaluateCostFunction(string result, double[] costs) public double EvaluateHamiltonian(string result) { double hamiltonianValue = 0; - for (int i = 0; i < problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { - hamiltonianValue += problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); + hamiltonianValue += this.problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); } - for (int i = 0; i < problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { - for (int j = i + 1; j < problemInstance.problemSizeInBits; j++) + for (int j = i + 1; j < this.problemInstance.problemSizeInBits; j++) { - hamiltonianValue += problemInstance.twoLocalHamiltonianCoefficients[i * problemInstance.problemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); + hamiltonianValue += this.problemInstance.twoLocalHamiltonianCoefficients[i * this.problemInstance.problemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); } } @@ -85,7 +91,7 @@ public double EvaluateHamiltonian(string result) /// # 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. + /// 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 @@ -103,29 +109,29 @@ public Double CalculateObjectiveFunction(double[] bigfreeParamsVector) var beta = new QArray(freeParamsVector.beta); var gamma = new QArray(freeParamsVector.gamma); - Utils.PrintCurrentBetaGamma(beta, gamma); - - var oneLocalHamiltonianCoefficients = new QArray(problemInstance.oneLocalHamiltonianCoefficients); - var twoLocalHamiltonianCoefficients = new QArray(problemInstance.twoLocalHamiltonianCoefficients); + var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.oneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.twoLocalHamiltonianCoefficients); using (var qsim = new QuantumSimulator()) { for (int i = 0; i < numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; + IQArray result = RunQaoa.Run(qsim, this.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); + double hamiltonianValue = this.EvaluateHamiltonian(solutionVector); + hamiltonianExpectationValue += hamiltonianValue/ this.numberOfIterations; } - } - - UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); - Utils.PrintCurrentBestSolution(this.bestHamiltonianValue, this.bestVector); + this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); + + if (this.loggerFilePath != null) + { + this.logger.LogCurrentBestSolution(beta, gamma, this.bestHamiltonianValue, this.bestVector); + } return hamiltonianExpectationValue; } @@ -143,11 +149,11 @@ private void UpdateBestSolution(double hamiltonianExpectationValue, List { if (hamiltonianExpectationValue < this.bestHamiltonianValue) { - String mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); - bestHamiltonianValue = hamiltonianExpectationValue; - bestVector = mostProbableSolutionVectorTemp; - bestBeta = freeParamsVector.beta; - bestGamma = freeParamsVector.gamma; + string mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); + this.bestHamiltonianValue = hamiltonianExpectationValue; + this.bestVector = mostProbableSolutionVectorTemp; + this.bestBeta = freeParamsVector.beta; + this.bestGamma = freeParamsVector.gamma; } } @@ -174,7 +180,6 @@ private NonlinearConstraint[] GenerateConstraints() constraints[gammaIndex + 1] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] <= 2 * Math.PI); } return constraints; - } /// # Summary @@ -185,10 +190,10 @@ private NonlinearConstraint[] GenerateConstraints() private double[] SetUpFreeParameters() { double[] betaCoefficients; - if (FreeParamsVector.beta != null) + if (this.freeParamsVector.beta != null) { - betaCoefficients = FreeParamsVector.beta; - FreeParamsVector.beta = null; + betaCoefficients = this.freeParamsVector.beta; + this.freeParamsVector.beta = null; } else { @@ -196,17 +201,17 @@ private double[] SetUpFreeParameters() } double[] gammaCoefficients; - if (FreeParamsVector.gamma != null) + if (this.freeParamsVector.gamma != null) { - gammaCoefficients = FreeParamsVector.gamma; - FreeParamsVector.gamma = null; + gammaCoefficients = this.freeParamsVector.gamma; + this.freeParamsVector.gamma = null; } else { gammaCoefficients = Utils.GetRandomVector(p, 2 * Math.PI); } - return betaCoefficients.Concat(gammaCoefficients).ToArray(); + return betaCoefficients.Concat(gammaCoefficients).ToArray(); } /// # Summary @@ -221,24 +226,27 @@ private double[] SetUpFreeParameters() public OptimalSolution RunOptimization() { - Func objectiveFunction = CalculateObjectiveFunction; - + Func objectiveFunction = this.CalculateObjectiveFunction; + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction); - NonlinearConstraint[] constraints = GenerateConstraints(); + NonlinearConstraint[] constraints = this.GenerateConstraints(); - for (int i = 0; i < numberOfRandomStartingPoints; i++) + for (int i = 0; i < this.numberOfRandomStartingPoints; i++) { var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - double[] freeParameters = SetUpFreeParameters(); + double[] freeParameters = this.SetUpFreeParameters(); bool success = cobyla.Minimize(freeParameters); - Utils.PrintSuccess(success); + + if (this.loggerFilePath != null) + { + this.logger.LogSuccess(success); + this.logger.Close(); + } } return new OptimalSolution(this.bestVector, this.bestHamiltonianValue, this.bestBeta, this.bestGamma); } - - } } diff --git a/QAOA/src/HybridQaoa/OptimalSolution.cs b/QAOA/src/QaoaHybrid/OptimalSolution.cs similarity index 83% rename from QAOA/src/HybridQaoa/OptimalSolution.cs rename to QAOA/src/QaoaHybrid/OptimalSolution.cs index 3cd67d67d4a..2f00365a8b5 100644 --- a/QAOA/src/HybridQaoa/OptimalSolution.cs +++ b/QAOA/src/QaoaHybrid/OptimalSolution.cs @@ -1,9 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace QAOA.ClassicalOptimization +namespace QAOA.QaoaHybrid { + using System; + using System.Collections.Generic; + using System.Text; + public class OptimalSolution { diff --git a/QAOA/src/HybridQaoa/ProblemInstance.cs b/QAOA/src/QaoaHybrid/ProblemInstance.cs similarity index 92% rename from QAOA/src/HybridQaoa/ProblemInstance.cs rename to QAOA/src/QaoaHybrid/ProblemInstance.cs index abab91b22e2..1839f0b9c5d 100644 --- a/QAOA/src/HybridQaoa/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/ProblemInstance.cs @@ -1,7 +1,7 @@ -using System; - -namespace Quantum.QAOA +namespace QAOA.QaoaHybrid { + using System; + public class ProblemInstance { public Double[] oneLocalHamiltonianCoefficients { get; } diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs new file mode 100644 index 00000000000..b786a02fd97 --- /dev/null +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -0,0 +1,53 @@ +namespace QAOA.QaoaHybrid +{ + using System; + using System.IO; + using Microsoft.Quantum.Simulation.Core; + + class QaoaLogger + { + private StreamWriter logger; + public QaoaLogger(string filePath = "") + { + this.logger = new StreamWriter(@filePath+"hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); + } + + /// # Summary + /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. + /// + /// # Input + /// ## bestHamiltonian + /// Best value of a Hamiltonian so far. + /// ## bestVector + /// Best solution vector that generates the above value of a Hamiltonian so far. + public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, String bestVector) + { + this.logger.WriteLine("Current beta vector:"); + this.logger.WriteLine(beta); + this.logger.WriteLine("Current gamma vector:"); + this.logger.WriteLine(gamma); + this.logger.WriteLine("Current best fidelity"); + this.logger.WriteLine(bestHamiltonian); + this.logger.WriteLine("Current best string"); + this.logger.WriteLine(bestVector); + } + + /// # Summary + /// Prints whether an optimization finished successfully. + /// + /// # Input + /// ## success + /// A flag that indiciates whether an optimization finished successfully. + public void LogSuccess(bool success) + { + this.logger.WriteLine("Was optimization successful?"); + this.logger.WriteLine(success); + this.logger.WriteLine("##################################"); + } + + public void Close() + { + this.logger.Close(); + } + } +} diff --git a/QAOA/src/HybridQaoa/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs similarity index 65% rename from QAOA/src/HybridQaoa/Utils.cs rename to QAOA/src/QaoaHybrid/Utils.cs index d61dcbe9050..aa6967c48d5 100644 --- a/QAOA/src/HybridQaoa/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -1,10 +1,9 @@ -using Microsoft.Quantum.Simulation.Core; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Quantum.QAOA +namespace QAOA.QaoaHybrid { + using System; + using System.Collections.Generic; + using System.Text; + public class Utils { @@ -125,53 +124,5 @@ public static FreeParamsVector ConvertVectorIntoHalves(double[] bigfreeParamsVec return freeParamsVector; } - - /// # Summary - /// Prints current values of beta and gamma vectors as optimization is being performed. - /// - /// # Input - /// ## beta - /// Beta vector of coefficients. - /// ## gamma - /// Gamma vector of coefficients. - public static void PrintCurrentBetaGamma(QArray beta, QArray gamma) - { - Console.WriteLine("Current beta vector:"); - Console.WriteLine(beta); - - Console.WriteLine("Current gamma vector:"); - Console.WriteLine(gamma); - - } - - /// # Summary - /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. - /// - /// # Input - /// ## bestHamiltonian - /// Best value of a Hamiltonian so far. - /// ## bestVector - /// Best solution vector that generates the above value of a Hamiltonian so far. - public static void PrintCurrentBestSolution(double bestHamiltonian, String bestVector) - { - Console.WriteLine("Current best fidelity"); - Console.WriteLine(bestHamiltonian); - Console.WriteLine("Current best string"); - Console.WriteLine(bestVector); - } - - /// # Summary - /// Prints whether an optimization finished successfully. - /// - /// # Input - /// ## success - /// A flag that indiciates whether an optimization finished successfully. - public static void PrintSuccess(bool success) - { - Console.WriteLine("Was optimization successful?"); - Console.WriteLine(success); - Console.WriteLine("##################################"); - } - } } \ No newline at end of file diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 60ba806590b..6ac96ce05e5 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -1,7 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using Quantum.QAOA; +using QAOA.QaoaHybrid; using System; -using QAOA.ClassicalOptimization; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs index 0856270e784..fe05bce294a 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/UtilsTests.cs @@ -1,5 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using Quantum.QAOA; +using QAOA.QaoaHybrid; using System.Collections.Generic; namespace Microsoft.Quantum.QAOA.HybridQaoaTests diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index fa6913901f0..45c48476362 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -6,9 +6,9 @@ using Newtonsoft.Json; using Xunit; using System; -using QAOA.magicCommand; -using Quantum.QAOA; using Microsoft.Quantum.QAOA.JupyterTests; +using QAOA.Jupyter; +using QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index d0e7a7dd9ed..341a64eb0b9 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -4,11 +4,10 @@ using System.Threading.Tasks; using Microsoft.Jupyter.Core; using Newtonsoft.Json; -using QAOA.magicCommand; -using Quantum.QAOA; using System; -using QAOA.ClassicalOptimization; using Xunit; +using QAOA.Jupyter; +using QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.JupyterTests { From 5b3f95b986d69c4d20f7239e73d7534b48dd8e9a Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 10:36:11 +0200 Subject: [PATCH 11/61] Code refactoring. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 2 +- QAOA/src/QaoaHybrid/HybridQaoa.cs | 2 +- QAOA/src/QaoaHybrid/QaoaLogger.cs | 24 ++++++++++--------- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 6 ++--- QAOA/tests/QaoaTests/UtilsTests.qs | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 3e10781a2be..8445370b96d 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -72,7 +72,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.InitialBeta, args.InitialGamma); + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, null, args.InitialBeta, args.InitialGamma); return hybridQaoa.RunOptimization().ToExecutionResult(); } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 33b2a432095..3942013b40e 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -26,7 +26,7 @@ public class HybridQaoa private String loggerFilePath; - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null, String loggerFilePath = null) + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, String loggerFilePath = null, Double[] initialBeta = null, Double[] initialGamma = null) { this.numberOfIterations = numberOfIterations; diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index b786a02fd97..7931cced0dd 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -22,14 +22,15 @@ public QaoaLogger(string filePath = "") /// Best solution vector that generates the above value of a Hamiltonian so far. public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, String bestVector) { - this.logger.WriteLine("Current beta vector:"); - this.logger.WriteLine(beta); - this.logger.WriteLine("Current gamma vector:"); - this.logger.WriteLine(gamma); - this.logger.WriteLine("Current best fidelity"); - this.logger.WriteLine(bestHamiltonian); - this.logger.WriteLine("Current best string"); - this.logger.WriteLine(bestVector); + + this.logger.WriteLine("Current beta vector:"); + this.logger.WriteLine(beta); + this.logger.WriteLine("Current gamma vector:"); + this.logger.WriteLine(gamma); + this.logger.WriteLine("Current best fidelity"); + this.logger.WriteLine(bestHamiltonian); + this.logger.WriteLine("Current best string"); + this.logger.WriteLine(bestVector); } /// # Summary @@ -40,9 +41,10 @@ public void LogCurrentBestSolution(QArray beta, QArray gamma, do /// A flag that indiciates whether an optimization finished successfully. public void LogSuccess(bool success) { - this.logger.WriteLine("Was optimization successful?"); - this.logger.WriteLine(success); - this.logger.WriteLine("##################################"); + this.logger.WriteLine("Was optimization successful?"); + this.logger.WriteLine(success); + this.logger.WriteLine("##################################"); + } public void Close() diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 6ac96ce05e5..7d291e7c665 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -15,7 +15,7 @@ public void ConvertDataVectorToVectorsTest() ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); @@ -35,7 +35,7 @@ public void EvaluateHamiltonianTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); Double result = classicalOptimization.EvaluateHamiltonian("0011"); @@ -50,7 +50,7 @@ public void EvaluateCostFunctionTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, new double[] { 2 }, new double[] { 3 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, null, new double[] { 2 }, new double[] { 3 }); string optimizationResult = "0101"; diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs index 7b8a2628c2f..229921a9871 100644 --- a/QAOA/tests/QaoaTests/UtilsTests.qs +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -28,7 +28,7 @@ namespace Microsoft.Quantum.Tests { } @Test("QuantumSimulator") - operation RunPhaseKickbackTest2() : Unit { + operation RunPhaseKickbackOneControlQubitTest() : Unit { let numberOfQubits = 1; let ancillaQubits = 1; From b811a8167d8eba5d5656a2dc2cfd7e7e890c77bc Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 10:41:32 +0200 Subject: [PATCH 12/61] Code refactoring. --- QAOA/src/QaoaHybrid/HybridQaoa.cs | 14 ++++++++++++-- QAOA/src/QaoaHybrid/QaoaLogger.cs | 7 +++++-- QAOA/src/QaoaHybrid/Utils.cs | 4 ---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 3942013b40e..e0b35f11797 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -45,7 +45,18 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance } - + /// # Summary + /// Calculates the value of the cost function based on costs provided. + /// + /// # Input + /// ## result + /// A binary string. In this context it is a result that we get after measuring the QAOA state. + /// + /// ## costs + /// A list of costs for the cost function. + /// + /// # Output + /// The value of the costfunction. public Double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; @@ -69,7 +80,6 @@ public Double EvaluateCostFunction(string result, double[] costs) /// /// # Remarks /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. - public double EvaluateHamiltonian(string result) { double hamiltonianValue = 0; diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 7931cced0dd..f2c2e80e8be 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -7,13 +7,14 @@ class QaoaLogger { private StreamWriter logger; + public QaoaLogger(string filePath = "") { this.logger = new StreamWriter(@filePath+"hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); } /// # Summary - /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. + /// Writes current values of the best fidelity and the best solution vector to a file. /// /// # Input /// ## bestHamiltonian @@ -34,7 +35,7 @@ public void LogCurrentBestSolution(QArray beta, QArray gamma, do } /// # Summary - /// Prints whether an optimization finished successfully. + /// Writes to a file whether an optimization finished successfully. /// /// # Input /// ## success @@ -47,6 +48,8 @@ public void LogSuccess(bool success) } + /// # Summary + /// Closes a logger. public void Close() { this.logger.Close(); diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs index aa6967c48d5..cb9b66548bc 100644 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -24,7 +24,6 @@ public struct FreeParamsVector /// /// # Output /// A random vector of doubles. - public static double[] GetRandomVector(int length, double maximumValue) { var rand = new Random(); @@ -46,7 +45,6 @@ public static double[] GetRandomVector(int length, double maximumValue) /// /// # Output /// The most common boolean string. - public static String GetModeFromBoolList(List list) { Dictionary counter = new Dictionary(); @@ -86,7 +84,6 @@ public static String GetModeFromBoolList(List list) /// /// # Output /// A boolean string. - public static string GetBoolStringFromBoolArray(bool[] boolArray) { System.Text.StringBuilder sb = new StringBuilder(); @@ -109,7 +106,6 @@ public static string GetBoolStringFromBoolArray(bool[] boolArray) /// /// # Remarks /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. - public static FreeParamsVector ConvertVectorIntoHalves(double[] bigfreeParamsVector) { int size = bigfreeParamsVector.Length; From d5b74098b3dd0b3e39802f64e2b58eaa7afefaa5 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 11:03:45 +0200 Subject: [PATCH 13/61] Code refactoring. --- QAOA/src/Examples.cs | 2 +- QAOA/src/Jupyter/HybridQaoaMagic.cs | 8 +++++++- QAOA/src/QaoaHybrid/HybridQaoa.cs | 15 +++++++-------- QAOA/src/QaoaHybrid/QaoaLogger.cs | 5 +++-- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 6 +++--- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index 7e7b981f6a9..d888ef62d6a 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -60,7 +60,7 @@ static void Main(string[] args) //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints, true); OptimalSolution res = cop.RunOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 8445370b96d..8249e9739ae 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -46,6 +46,12 @@ public class Arguments [JsonProperty(PropertyName = "number_of_random_starting_points")] public int NumberOfRandomStartingPoints { get; set; } = 1; + /// + /// Flag whether optimization should be logged into a file. + /// + [JsonProperty(PropertyName = "should_log")] + public Boolean ShouldLog { get; set; } = false; + /// /// Initial beta angles. /// @@ -72,7 +78,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, null, args.InitialBeta, args.InitialGamma); + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.ShouldLog, args.InitialBeta, args.InitialGamma); return hybridQaoa.RunOptimization().ToExecutionResult(); } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index e0b35f11797..fac409942ff 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -23,10 +23,9 @@ public class HybridQaoa private Double[] bestGamma; private int numberOfRandomStartingPoints; private QaoaLogger logger; - private String loggerFilePath; + private Boolean shouldLog; - - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, String loggerFilePath = null, Double[] initialBeta = null, Double[] initialGamma = null) + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Boolean shouldLog = false, Double[] initialBeta = null, Double[] initialGamma = null) { this.numberOfIterations = numberOfIterations; @@ -37,10 +36,10 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance this.bestHamiltonianValue = double.MaxValue; this.bestVector = null; this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; - this.loggerFilePath = loggerFilePath; - if (loggerFilePath != null) + this.shouldLog = shouldLog; + if (shouldLog) { - this.logger = new QaoaLogger(loggerFilePath); + this.logger = new QaoaLogger(); } } @@ -138,7 +137,7 @@ public Double CalculateObjectiveFunction(double[] bigfreeParamsVector) this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); - if (this.loggerFilePath != null) + if (this.shouldLog) { this.logger.LogCurrentBestSolution(beta, gamma, this.bestHamiltonianValue, this.bestVector); } @@ -248,7 +247,7 @@ public OptimalSolution RunOptimization() double[] freeParameters = this.SetUpFreeParameters(); bool success = cobyla.Minimize(freeParameters); - if (this.loggerFilePath != null) + if (this.shouldLog) { this.logger.LogSuccess(success); this.logger.Close(); diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index f2c2e80e8be..7698f802405 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -8,9 +8,10 @@ class QaoaLogger { private StreamWriter logger; - public QaoaLogger(string filePath = "") + public QaoaLogger() { - this.logger = new StreamWriter(@filePath+"hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); + + this.logger = new StreamWriter("hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); } /// # Summary diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 7d291e7c665..766e04a2a27 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -15,7 +15,7 @@ public void ConvertDataVectorToVectorsTest() ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); @@ -35,7 +35,7 @@ public void EvaluateHamiltonianTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); Double result = classicalOptimization.EvaluateHamiltonian("0011"); @@ -50,7 +50,7 @@ public void EvaluateCostFunctionTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, null, new double[] { 2 }, new double[] { 3 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, false, new double[] { 2 }, new double[] { 3 }); string optimizationResult = "0101"; From 20ced98241f2ea25ebee3a6f5e5b453ba4be57a2 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 11:46:57 +0200 Subject: [PATCH 14/61] gitignore update --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 99d456ffa56..b815351418e 100644 --- a/.gitignore +++ b/.gitignore @@ -329,5 +329,3 @@ __pycache__/ *.btm.cs *.odx.cs *.xsd.cs - -/QAOA/QAOATest/MagicCommandTests/sample.py From 8c3452535b389abce4830ea87bfc512072f3f6a6 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 11:49:31 +0200 Subject: [PATCH 15/61] Unnecessary files removed. --- QAOA/.gitattributes | 63 -------- QAOA/.gitignore | 340 -------------------------------------------- QAOA/README.md | 30 ---- 3 files changed, 433 deletions(-) delete mode 100644 QAOA/.gitattributes delete mode 100644 QAOA/.gitignore delete mode 100644 QAOA/README.md diff --git a/QAOA/.gitattributes b/QAOA/.gitattributes deleted file mode 100644 index 1ff0c423042..00000000000 --- a/QAOA/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain diff --git a/QAOA/.gitignore b/QAOA/.gitignore deleted file mode 100644 index 4ce6fddec96..00000000000 --- a/QAOA/.gitignore +++ /dev/null @@ -1,340 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- Backup*.rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file diff --git a/QAOA/README.md b/QAOA/README.md deleted file mode 100644 index 3a2eb847794..00000000000 --- a/QAOA/README.md +++ /dev/null @@ -1,30 +0,0 @@ -[![Unitary Fund](https://img.shields.io/badge/Supported%20By-UNITARY%20FUND-brightgreen.svg?style=for-the-badge)](http://unitary.fund) - -# QAOA in Q# - -The project is still in progress. This readme will be extended as the project develops. - -This project provides a hybrid quantum-classical algorithm for solving optimization problems. -It includes a Q# implementation of the Quantum Approximate Optimization Algorithm ([QAOA](https://arxiv.org/abs/1411.4028)) together with a classical optimizer in C#. -The classical optimizer uses a quantum objective function to choose hopefully optimal parameters for running the QAOA. -The quantum objective function is currently evaluated on a simulator backend provided by Q#. - -How to run it? -1) Import this project to Microsoft Visual Studio or similar. -2) Use Driver.cs to prepare your ProblemInstance and run the project (some examples also provided). - -Current limitations: - -- an optimization problem shall be encoded into a Hamiltonian consisting of Z operators, -- support for up to 2-local Hamiltonians, -- input consists of arrays of coefficients for 1-local and 2-local Hamiltonian terms, -- a gradient-free Cobyla optimizer is used for finding good QAOA input parameters. - -The high-level diagram of the implementation (notation comes from the [QAOA paper](https://arxiv.org/abs/1411.4028)): - -[![QAOA diagram](https://i.postimg.cc/sgryqr80/IMG-0202.jpg)](https://postimg.cc/XpQTBTnw) - -Dependencies: - -1) [Q# and Microsoft Quantum Libraries](https://docs.microsoft.com/en-us/quantum/language/) -2) [C# Accord Math library](http://accord-framework.net/docs/html/N_Accord_Math.htm) From b3fd8bbc89ae4e62163e32e0e14b49281f4ae24d Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 12:47:40 +0200 Subject: [PATCH 16/61] Files added. --- QAOA/.gitattributes | 63 ++++++++ QAOA/.gitignore | 340 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 QAOA/.gitattributes create mode 100644 QAOA/.gitignore diff --git a/QAOA/.gitattributes b/QAOA/.gitattributes new file mode 100644 index 00000000000..1ff0c423042 --- /dev/null +++ b/QAOA/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/QAOA/.gitignore b/QAOA/.gitignore new file mode 100644 index 00000000000..4ce6fddec96 --- /dev/null +++ b/QAOA/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file From eb7c0e563fe85d24684f211694c33a28bdb8b34f Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 26 Jul 2020 10:28:26 +0200 Subject: [PATCH 17/61] QAOA files added. --- QAOA.sln | 31 ++ QAOA/.gitattributes | 63 ++++ QAOA/.gitignore | 340 ++++++++++++++++++ .../ClassicalOptimizationUtils.cs | 177 +++++++++ QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs | 267 ++++++++++++++ .../ClassicalOptimization/ProblemInstance.cs | 18 + QAOA/QAOA/Driver.cs | 65 ++++ QAOA/QAOA/Hamiltonians.qs | 61 ++++ QAOA/QAOA/QAOA.csproj | 14 + QAOA/QAOA/QAOARunner.qs | 46 +++ QAOA/QAOA/Utils.qs | 33 ++ QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs | 83 +++++ .../ClassicalOptimizationTests.cs | 71 ++++ .../ClassicalOptimizationTests/UtilsTests.cs | 51 +++ QAOA/QAOATest/QAOATest.csproj | 20 ++ QAOA/README.md | 30 ++ 16 files changed, 1370 insertions(+) create mode 100644 QAOA.sln create mode 100644 QAOA/.gitattributes create mode 100644 QAOA/.gitignore create mode 100644 QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs create mode 100644 QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs create mode 100644 QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs create mode 100644 QAOA/QAOA/Driver.cs create mode 100644 QAOA/QAOA/Hamiltonians.qs create mode 100644 QAOA/QAOA/QAOA.csproj create mode 100644 QAOA/QAOA/QAOARunner.qs create mode 100644 QAOA/QAOA/Utils.qs create mode 100644 QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs create mode 100644 QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs create mode 100644 QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs create mode 100644 QAOA/QAOATest/QAOATest.csproj create mode 100644 QAOA/README.md diff --git a/QAOA.sln b/QAOA.sln new file mode 100644 index 00000000000..4e52096cef2 --- /dev/null +++ b/QAOA.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29920.165 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\QAOA\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\QAOATest\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.Build.0 = Release|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {09481F99-E1AC-44CE-A892-7331820661DF} + EndGlobalSection +EndGlobal diff --git a/QAOA/.gitattributes b/QAOA/.gitattributes new file mode 100644 index 00000000000..1ff0c423042 --- /dev/null +++ b/QAOA/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/QAOA/.gitignore b/QAOA/.gitignore new file mode 100644 index 00000000000..4ce6fddec96 --- /dev/null +++ b/QAOA/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file diff --git a/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs b/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs new file mode 100644 index 00000000000..8c481e9810b --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs @@ -0,0 +1,177 @@ +using Microsoft.Quantum.Simulation.Core; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Quantum.QAOA +{ + public class ClassicalOptimizationUtils + { + + public struct FreeParamsVector + { + public Double[] beta; + public Double[] gamma; + } + + /// # Summary + /// Returns a vector of random doubles in a range from 0 to maximum. + /// + /// # Input + /// ## length + /// Length of a random vector. + /// ## maximum + /// Maximum value of a random double. + /// + /// # Output + /// A random vector of doubles. + + public static double[] getRandomVector(int length, double maximum) + { + var rand = new Random(); + double[] randomVector = new double[length]; + for (int i = 0; i < length; i++) + { + randomVector[i] = maximum * rand.NextDouble(); + } + + return randomVector; + } + + /// # Summary + /// Return the most common boolean string from a list of boolean values. + /// + /// # Input + /// ## list + /// List of boolean values. + /// + /// # Output + /// The most common boolean string. + + public static String getModeFromBoolList(List list) + { + Dictionary counter = new Dictionary(); + foreach (bool[] boolArray in list) + { + String boolString = getBoolStringFromBoolArray(boolArray); + if (counter.ContainsKey(boolString)) + { + counter[boolString] += 1; + } + else + { + counter[boolString] = 1; + } + + } + int maximum = 0; + String result = null; + foreach (string key in counter.Keys) + { + if (counter[key] > maximum) + { + maximum = counter[key]; + result = key; + } + } + + return result; + } + + /// # Summary + /// Converts an array of bools to a boolean string. + /// + /// # Input + /// ## boolArray + /// An array of bools. + /// + /// # Output + /// A boolean string. + + public static string getBoolStringFromBoolArray(bool[] boolArray) + { + System.Text.StringBuilder sb = new StringBuilder(); + foreach (bool b in boolArray) + { + sb.Append(b ? "1" : "0"); + } + return sb.ToString(); + } + + /// # Summary + /// Converts concatenated beta and gamma vectors into separate beta and gamma vector. + /// + /// # Input + /// ## bigfreeParamsVector + /// Concatenated beta and gamma vectors. + /// + /// # Output + /// FreeParamsVector that contains beta and gamma vectors. + /// + /// # Remarks + /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. + + public static FreeParamsVector convertVectorIntoHalves(double[] bigfreeParamsVector) + { + int size = bigfreeParamsVector.Length; + int vectorTermsNumber = size / 2; + FreeParamsVector freeParamsVector = new FreeParamsVector + { + + beta = bigfreeParamsVector[0..vectorTermsNumber], + gamma = bigfreeParamsVector[vectorTermsNumber..(2*vectorTermsNumber)], + + }; + + return freeParamsVector; + } + + /// # Summary + /// Prints current values of beta and gamma vectors as optimization is being performed. + /// + /// # Input + /// ## beta + /// Beta vector of coefficients. + /// ## gamma + /// Gamma vector of coefficients. + public static void printCurrentBetaGamma(QArray beta, QArray gamma) + { + Console.WriteLine("Current beta vector:"); + Console.WriteLine(beta); + + Console.WriteLine("Current gamma vector:"); + Console.WriteLine(gamma); + + } + + /// # Summary + /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. + /// + /// # Input + /// ## bestHamiltonian + /// Best value of a Hamiltonian so far. + /// ## bestVector + /// Best solution vector that generates the above value of a Hamiltonian so far. + public static void printCurrentBestSolution(double bestHamiltonian, String bestVector) + { + Console.WriteLine("Current best fidelity"); + Console.WriteLine(bestHamiltonian); + Console.WriteLine("Current best string"); + Console.WriteLine(bestVector); + } + + /// # Summary + /// Prints whether an optimization finished successfully. + /// + /// # Input + /// ## success + /// A flag that indiciates whether an optimization finished successfully. + public static void printSuccess(bool success) + { + Console.WriteLine("Was optimization successful?"); + Console.WriteLine(success); + Console.WriteLine("##################################"); + } + + } +} \ No newline at end of file diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs new file mode 100644 index 00000000000..e636f3f3fbd --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Accord.Math; +using Accord.Math.Optimization; +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators; + +namespace Quantum.QAOA + +{ + public struct OptimalSolution + { + public String optimalVector; + public Double optimalValue; + public Double[] optimalBeta; + public Double[] optimalGamma; + } + + public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later + { + ClassicalOptimizationUtils.FreeParamsVector FreeParamsVector; + int numberOfIterations; + int p; + ProblemInstance problemInstance; + Double bestHamiltonian; + String bestVector; + Double[] bestBeta; + Double[] bestGamma; + int numberOfRandomStartingPoints; + + + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null) + { + + this.numberOfIterations = numberOfIterations; + this.p = p; + this.problemInstance = problemInstance; + FreeParamsVector.beta = initialBeta; + FreeParamsVector.gamma = initialGamma; + bestHamiltonian = Double.MaxValue; + bestVector = null; + this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; + } + + + + public Double evaluateCostFunction(string result, double[] costs) + { + double costFunctionValue = 0; + for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + { + costFunctionValue += costs[i] * Char.GetNumericValue(result[i]); + } + + return costFunctionValue; + } + + /// # Summary + /// Calculates the value of the objective function Hamiltonian for a binary string provided. + /// + /// # Input + /// ## result + /// A binary string. In this context it is a result that we get after measuring the QAOA state. + /// + /// # Output + /// The value of the objective function Hamiltonian. + /// + /// # Remarks + /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. + + public double evaluateHamiltonian(string result) + { + double hamiltonianValue = 0; + for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + { + hamiltonianValue += problemInstance.OneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); + } + + for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + { + for (int j = i + 1; j < problemInstance.ProblemSizeInBits; j++) + { + hamiltonianValue += problemInstance.TwoLocalHamiltonianCoefficients[i * problemInstance.ProblemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); + } + } + + return hamiltonianValue; + } + + /// # 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) + { + ClassicalOptimizationUtils.FreeParamsVector freeParamsVector = ClassicalOptimizationUtils.convertVectorIntoHalves(bigfreeParamsVector); + double hamiltonianExpectationValue = 0; + List allSolutionVectors = new List(); + + var beta = new QArray(freeParamsVector.beta); + var gamma = new QArray(freeParamsVector.gamma); + + ClassicalOptimizationUtils.printCurrentBetaGamma(beta, gamma); + + var oneLocalHamiltonianCoefficients = new QArray(problemInstance.OneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(problemInstance.TwoLocalHamiltonianCoefficients); + + using (var qsim = new QuantumSimulator()) + { + + for (int i = 0; i < numberOfIterations; i++) + { + IQArray result = RunQaoa.Run(qsim, problemInstance.ProblemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; + allSolutionVectors.Add(result.ToArray()); + string solutionVector = ClassicalOptimizationUtils.getBoolStringFromBoolArray(result.ToArray()); + double hamiltonianValue = evaluateHamiltonian(solutionVector); + hamiltonianExpectationValue += (hamiltonianValue/numberOfIterations); + + } + + } + + updateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); + ClassicalOptimizationUtils.printCurrentBestSolution(this.bestHamiltonian, this.bestVector); + + return hamiltonianExpectationValue; + } + + /// # Summary + /// Updates the currently best solution if a new solution is better. + /// + /// # Input + /// ## hamiltonianExpectationValue + /// Expectation value of a Hamiltonian. + /// ## allSolutionVectors + /// A vector of all binary solutions that were found by a QAOA. + /// ## freeParamsVector + /// A vector of beta and gamma coefficients. + private void updateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, ClassicalOptimizationUtils.FreeParamsVector freeParamsVector) + { + if (hamiltonianExpectationValue < this.bestHamiltonian) + { + String mostProbableSolutionVectorTemp = ClassicalOptimizationUtils.getModeFromBoolList(allSolutionVectors); + bestHamiltonian = hamiltonianExpectationValue; + bestVector = mostProbableSolutionVectorTemp; + bestBeta = freeParamsVector.beta; + bestGamma = freeParamsVector.gamma; + } + } + + + /// # Summary + /// Generates constraints for elements in beta and gamma vectors. + /// + /// # Output + /// Generated constraints. + /// + /// # Remarks + /// For the canonical choice of the mixing Hamiltonian (i.e. the sum of X operators acting on single qubits), the range of values in the beta vector is 0 <= beta_i <= PI. + /// For the objective function Hamiltonian based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. + private NonlinearConstraint[] generateConstraints() + { + + NonlinearConstraint[] constraints = new NonlinearConstraint[4*p]; + foreach (var i in Enumerable.Range(0, p).Select(x => x * 2)) + { + int gammaIndex = 2 * p + i; + constraints[i] = new NonlinearConstraint(2 * p, x => x[i/2] >= 0); + constraints[i + 1] = new NonlinearConstraint(2 * p, x => x[i/2] <= Math.PI); + constraints[gammaIndex] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] >= 0); + constraints[gammaIndex + 1] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] <= 2 * Math.PI); + } + return constraints; + + } + + /// # Summary + /// We create beta and gamma vectors. If the user provided their set of parameters, we use them for the first run. Otherwise, we use randomly generated parameters. + /// + /// # Output + /// Initialized beta and gamma vectors concatenated. + private double[] setUpFreeParameters() + { + double[] betaCoefficients; + if (FreeParamsVector.beta != null) + { + betaCoefficients = FreeParamsVector.beta; + FreeParamsVector.beta = null; + } + else + { + betaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, Math.PI); + } + + double[] gammaCoefficients; + if (FreeParamsVector.gamma != null) + { + gammaCoefficients = FreeParamsVector.gamma; + FreeParamsVector.gamma = null; + } + else + { + gammaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, 2 * Math.PI); + } + + return betaCoefficients.Concat(gammaCoefficients).ToArray(); + } + + /// # Summary + /// Returns the optimal solution found by a QAOA. + /// + /// # Output + /// Optimal solution found by a QAOA. + public OptimalSolution getOptimalSolution() + { + OptimalSolution optimalSolution = new OptimalSolution + { + optimalVector = this.bestVector, + optimalValue = this.bestHamiltonian, + optimalBeta = this.bestBeta, + optimalGamma = this.bestGamma, + }; + + return optimalSolution; + } + + /// # Summary + /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum. + /// + /// # Output + /// Optimal solution to the optimization problem input by the user. + /// + /// # Remarks + /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. + /// The objective function Hamiltonian is based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. + public OptimalSolution runOptimization() + { + + Func objectiveFunction = calculateObjectiveFunction; + + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction); + + NonlinearConstraint[] constraints = generateConstraints(); + + for (int i = 0; i < numberOfRandomStartingPoints; i++) + { + var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); + double[] freeParameters = setUpFreeParameters(); + bool success = cobyla.Minimize(freeParameters); + ClassicalOptimizationUtils.printSuccess(success); + + } + + return getOptimalSolution(); + } + + + } +} diff --git a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs new file mode 100644 index 00000000000..911efb115e3 --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs @@ -0,0 +1,18 @@ +using System; + +namespace Quantum.QAOA +{ + public class ProblemInstance + { + public Double[] OneLocalHamiltonianCoefficients { get; } + public Double[] TwoLocalHamiltonianCoefficients { get; } + public int ProblemSizeInBits { get; } + + public ProblemInstance(Double[] oneLocalHamiltonianCoefficients, Double[] twoLocalHamiltonianCoefficients) + { + OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; + TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; + ProblemSizeInBits = OneLocalHamiltonianCoefficients.Length; + } + } +} diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Driver.cs new file mode 100644 index 00000000000..2e9ad11c90f --- /dev/null +++ b/QAOA/QAOA/Driver.cs @@ -0,0 +1,65 @@ +using System; + +namespace Quantum.QAOA +{ + class Driver + { + + + static void Main(string[] args) + { + //PARAMETERS + int numberOfIterations = 200; + int p = 3; + int numberOfRandomStartingPoints = 3; + + //EXAMPLES + + //Quantum Santa (http://quantumalgorithmzoo.org/traveling_santa/) + double[] dtx = { 0.619193, 0.742566, 0.060035, -1.568955, 0.045490 }; + double[] dtz = { 3.182203, -1.139045, 0.221082, 0.537753, -0.417222 }; + double[] segmentCosts = { 4.70, 9.09, 9.03, 5.70, 8.02, 1.71 }; + double[] dh = { 4 * 20 - 0.5 * 4.7, 4 * 20 - 0.5 * 9.09, 4 * 20 - 0.5 * 9.03, 4 * 20 - 0.5 * 5.70, 4 * 20 - 0.5 * 8.02, 4 * 20 - 0.5 * 1.71 }; + double[] dJ = { 40.0,40.0,20.0,40.0,40.0,40.0, + 40.0,40.0,40.0,20.0,40.0,40.0, + 40.0,40.0,40.0,40.0,40.0,40.0, + 40.0,40.0,40.0,40.0,40.0,40.0, + 40.0,40.0,40.0,40.0,40.0,20.0, + 40.0,40.0,40.0,40.0,40.0,40.0}; + ProblemInstance quantumSanta = new ProblemInstance(dh, dJ); + + + //MaxCut (medium.com/mdr-inc/qaoa-maxcut-using-blueqat-aaf33038f46e) + dh = new Double[] { 0,0,0,0,0}; + dJ = new Double[]{ 0,1,0,1,0, + 0,0,1,0,0, + 0,0,0,1,1, + 0,0,0,0,1, + 0,0,0,0,0}; + ProblemInstance maxCut1 = new ProblemInstance(dh, dJ); + + + //Rigetti MaxCut unit tests + dh = new Double[]{-0.5,0,-1,0.5}; + dJ = new Double[]{0,1,2,0, + 0,0,0.5,0, + 0,0,0,2.5, + 0,0,0,0}; + ProblemInstance maxCut2 = new ProblemInstance(dh, dJ); + + + dh = new Double[] { 0.8, -0.5 }; + dJ = new Double[]{ 0, -1, + 0, 0}; + ProblemInstance maxCut3 = new ProblemInstance(dh, dJ); + + //END EXAMPLES + + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut1, numberOfRandomStartingPoints); + + OptimalSolution res = cop.runOptimization(); + Console.WriteLine(res.optimalVector); + + } + } +} \ No newline at end of file diff --git a/QAOA/QAOA/Hamiltonians.qs b/QAOA/QAOA/Hamiltonians.qs new file mode 100644 index 00000000000..f36be87de7f --- /dev/null +++ b/QAOA/QAOA/Hamiltonians.qs @@ -0,0 +1,61 @@ +namespace Quantum.QAOA { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + + /// # Summary + /// Implements a unitary based on the mixing hamiltonian and applies it to qubits. + /// + /// # Input + /// ## qubits + /// Qubits that will be transformed by a unitary. + /// ## beta + /// Vector of coefficents for the unitary based on the mixing Hamiltonian. + /// + /// # References + /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. + + + operation EvolveWithMixingHamiltonian(qubits: Qubit[], beta: Double) : Unit + { + for(i in 0..Length(qubits)-1) + { + R(PauliX, -2.0*beta, qubits[i]); + } + } + + /// # Summary + /// Implements a unitary based on the objective function hamiltonian and applies it to qubits. + /// + /// # Input + /// ## qubits + /// Qubits that will be transformed by a unitary. + /// ## gamma + /// Vector of coefficents for the unitary based on the objective function Hamiltonian. + /// ## h + /// Array of 1-local coefficents of the objective function Hamiltonian. + /// ## J + /// Array of 2-local coefficents of the objective function Hamiltonian. + /// + /// # References + /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. + + operation EvolveWithObjectiveHamiltonian(qubits: Qubit[], gamma: Double, h: Double[], J: Double[]) : Unit + { + let numberOfQubits = Length(qubits); + using (ancillaQubit = Qubit[1]) + { + for(i in 0..numberOfQubits-1) + { + R(PauliZ, 2.0*gamma*h[i],qubits[i]); + } + for(i in 0..numberOfQubits-1) + { + for (j in i+1..numberOfQubits-1) + { + RunPhaseKickback(qubits, ancillaQubit, [i,j], 2.0*gamma*J[numberOfQubits*i+j]); + } + } + } + } +} diff --git a/QAOA/QAOA/QAOA.csproj b/QAOA/QAOA/QAOA.csproj new file mode 100644 index 00000000000..4994ceb6c9a --- /dev/null +++ b/QAOA/QAOA/QAOA.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + + diff --git a/QAOA/QAOA/QAOARunner.qs b/QAOA/QAOA/QAOARunner.qs new file mode 100644 index 00000000000..af8db6eb782 --- /dev/null +++ b/QAOA/QAOA/QAOARunner.qs @@ -0,0 +1,46 @@ +namespace Quantum.QAOA { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + + + /// # Summary + /// Prepares and measures the quantum state in the QAOA. + /// + /// # Input + /// ## problemSize + /// Number of qubits. + /// ## beta + /// Vector of coefficents for the unitary based on the mixing Hamiltonian. + /// ## gamma + /// Vector of coefficents for the unitary based on the objective function Hamiltonian. + /// ## h + /// Array of 1-local coefficents of the objective function Hamiltonian. + /// ## J + /// Array of 2-local coefficents of the objective function Hamiltonian. + /// ## p + /// Depth of the QAOA circuit. + /// + /// # Output + /// Array of boolean values that represent results of measurements on the QAOA state. + /// + /// # References + /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. + + operation RunQaoa(problemSize: Int, beta: Double[], gamma: Double[], h: Double[], J: Double[], p: Int) : Bool[] + { + + mutable result = new Bool[problemSize]; + using (x = Qubit[problemSize]) + { + ApplyToEach(H, x); // prepare the uniform distribution + for (i in 0..p-1) + { + EvolveWithObjectiveHamiltonian(x, gamma[i], h, J); // do Exp(-i H_C tz[i]) + EvolveWithMixingHamiltonian(x, beta[i]); // do Exp(-i H_0 tx[i]) + } + set result = MeasureAllAndReset(x); // measure in the computational basis + } + return result; + } +} diff --git a/QAOA/QAOA/Utils.qs b/QAOA/QAOA/Utils.qs new file mode 100644 index 00000000000..4ec42e366a8 --- /dev/null +++ b/QAOA/QAOA/Utils.qs @@ -0,0 +1,33 @@ +namespace Quantum.QAOA { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Measurement; + + + operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] + { + let N = Length(qubits); + mutable results = new Bool[N]; + for (i in 0..N-1) + { + set results w/= i <- (MResetZ(qubits[i]) == One); + } + return results; + } + + operation RunPhaseKickback(qubits: Qubit[], ancillaQubit: Qubit[], controlQubitsIndices: Int[], phaseExponent: Double) : Unit + { + for(i in 0..Length(controlQubitsIndices)-1) + { + CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); + } + + R(PauliZ, phaseExponent, ancillaQubit[0]); + + for(i in 0..Length(controlQubitsIndices)-1) + { + CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); + } + } +} \ No newline at end of file diff --git a/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs b/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs new file mode 100644 index 00000000000..05bdacbc7b9 --- /dev/null +++ b/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs @@ -0,0 +1,83 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Newtonsoft.Json; +using Quantum.QAOA; + +namespace QAOA.magicCommand +{ + public class HybridQaoaRunMagic : MagicSymbol + { + + public HybridQaoaRunMagic() + { + this.Name = $"%standard.hybridqaoa.run"; + this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json" }; + this.Kind = SymbolKind.Magic; + this.Execute = this.Run; + } + + /// + /// List of arguments + /// + public class Arguments + { + /// + /// Number of iterations in the fidelity sampling. + /// + [JsonProperty(PropertyName = "number_of_iterations")] + public int NumberOfIterations { get; set; } + + /// + /// Depth of a QAOA circuit. + /// + [JsonProperty(PropertyName = "p")] + public int p { get; set; } + + /// + /// Description of a combinatorial problem to be solved. + /// + [JsonProperty(PropertyName = "problem_instance")] + public ProblemInstance ProblemInstance { get; set; } + + /// + /// Number of random starting points in the angles parameters spaces. + /// + [JsonProperty(PropertyName = "number_of_random_starting_points")] + public int NumberOfRandomStartingPoints { get; set; } = 1; + + /// + /// Initial beta angles. + /// + [JsonProperty(PropertyName = "initial_beta")] + public Double[] InitialBeta { get; set; } = null; + + /// + /// Initial gamma angles. + /// + [JsonProperty(PropertyName = "initial_gamma")] + public Double[] InitialGamma { get; set; } = null; + } + + /// + /// Runs a hybrid QAOA. + /// + public async Task Run(string input, IChannel channel) + { + if (string.IsNullOrWhiteSpace(input)) + { + channel.Stderr("Please provide correct arguments"); + return ExecuteStatus.Error.ToExecutionResult(); + } + + var args = JsonConvert.DeserializeObject(input); + + + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance); //deal with optional params + + return hybridQaoa.runOptimization().ToExecutionResult(); + } + + + } +} diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs new file mode 100644 index 00000000000..00d7ebcd38d --- /dev/null +++ b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs @@ -0,0 +1,71 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using Quantum.QAOA; +using System; +using System.Reflection; + +namespace QAOATest.ClassicalOptimizationTests +{ + + [TestClass] + public class ClassicalOptimizationTest + { + + [TestMethod] + public void convertDataVectorToVectorsTest() + { + + ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); + + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); + + ClassicalOptimizationUtils.FreeParamsVector result = ClassicalOptimizationUtils.convertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); + + ClassicalOptimizationUtils.FreeParamsVector dataVectors = new ClassicalOptimizationUtils.FreeParamsVector(); + dataVectors.beta = new double[] { 1, 2, 3 }; + dataVectors.gamma = new double[] { 4, 5, 6 }; + + ClassicalOptimizationUtils.FreeParamsVector expectedResult = dataVectors; + + CollectionAssert.AreEqual(expectedResult.beta, result.beta, "Hamiltonian beta value not calculated correctly."); + CollectionAssert.AreEqual(expectedResult.gamma, result.gamma, "Hamiltonian gamma value not calculated correctly."); + + } + + [TestMethod] + public void evaluateHamiltonianTest() + { + ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); + + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); + + Double result = classicalOptimization.evaluateHamiltonian("0011"); + + Double expectedResult = -1; + + Assert.AreEqual(expectedResult, result, "Hamiltonian value not calculated correctly."); + + } + + [TestMethod] + public void evaluateCostFunctionTest() + { + ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); + + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, new double[] { 2 }, new double[] { 3 }); + + + string optimizationResult = "0101"; + + Double result = classicalOptimization.evaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); + + Double expectedResult = 4; + + Assert.AreEqual(expectedResult, result, "Cost function not calculated correctly."); + + + } + + + } +} diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs b/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs new file mode 100644 index 00000000000..85c66c00b29 --- /dev/null +++ b/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs @@ -0,0 +1,51 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using Quantum.QAOA; +using System.Collections.Generic; +using System.Text; + +namespace QAOATest.ClassicalOptimizationTests +{ + [TestClass] + public class UtilsTests + { + [TestMethod] + public void modeOfABoolListTest() + { + bool[] boolsArray1 = { false, false, true }; + bool[] boolsArray2 = { false, false, true }; + bool[] boolsArray3 = { false, false, false }; + bool[] boolsArray4 = { false, true, true }; + + List listOfBools = new List(); + listOfBools.Add(boolsArray1); + listOfBools.Add(boolsArray3); + listOfBools.Add(boolsArray2); + listOfBools.Add(boolsArray4); + + string expectedResult = "001"; + + string result = ClassicalOptimizationUtils.getModeFromBoolList(listOfBools); + + Assert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); + + + } + + [TestMethod] + public void boolStringFromBoolArrayTest() + { + bool[] boolsArray = { false, false, true }; + + + string expectedResult = "001"; + + string result = ClassicalOptimizationUtils.getBoolStringFromBoolArray(boolsArray); + + Assert.AreEqual(expectedResult, result, "Bool string not created correctly."); + + + } + } +} + diff --git a/QAOA/QAOATest/QAOATest.csproj b/QAOA/QAOATest/QAOATest.csproj new file mode 100644 index 00000000000..9a25671a4af --- /dev/null +++ b/QAOA/QAOATest/QAOATest.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + diff --git a/QAOA/README.md b/QAOA/README.md new file mode 100644 index 00000000000..3a2eb847794 --- /dev/null +++ b/QAOA/README.md @@ -0,0 +1,30 @@ +[![Unitary Fund](https://img.shields.io/badge/Supported%20By-UNITARY%20FUND-brightgreen.svg?style=for-the-badge)](http://unitary.fund) + +# QAOA in Q# + +The project is still in progress. This readme will be extended as the project develops. + +This project provides a hybrid quantum-classical algorithm for solving optimization problems. +It includes a Q# implementation of the Quantum Approximate Optimization Algorithm ([QAOA](https://arxiv.org/abs/1411.4028)) together with a classical optimizer in C#. +The classical optimizer uses a quantum objective function to choose hopefully optimal parameters for running the QAOA. +The quantum objective function is currently evaluated on a simulator backend provided by Q#. + +How to run it? +1) Import this project to Microsoft Visual Studio or similar. +2) Use Driver.cs to prepare your ProblemInstance and run the project (some examples also provided). + +Current limitations: + +- an optimization problem shall be encoded into a Hamiltonian consisting of Z operators, +- support for up to 2-local Hamiltonians, +- input consists of arrays of coefficients for 1-local and 2-local Hamiltonian terms, +- a gradient-free Cobyla optimizer is used for finding good QAOA input parameters. + +The high-level diagram of the implementation (notation comes from the [QAOA paper](https://arxiv.org/abs/1411.4028)): + +[![QAOA diagram](https://i.postimg.cc/sgryqr80/IMG-0202.jpg)](https://postimg.cc/XpQTBTnw) + +Dependencies: + +1) [Q# and Microsoft Quantum Libraries](https://docs.microsoft.com/en-us/quantum/language/) +2) [C# Accord Math library](http://accord-framework.net/docs/html/N_Accord_Math.htm) From ce4d776320246f0cedf6456ebd9d28c7606c0cb5 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 26 Jul 2020 11:42:18 +0200 Subject: [PATCH 18/61] Unit test for running the hybrid QAOA added. --- QAOA/QAOA/Driver.cs | 11 +++++++--- .../ClassicalOptimizationTests.cs | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Driver.cs index 2e9ad11c90f..348cc95c976 100644 --- a/QAOA/QAOA/Driver.cs +++ b/QAOA/QAOA/Driver.cs @@ -9,9 +9,9 @@ class Driver static void Main(string[] args) { //PARAMETERS - int numberOfIterations = 200; + int numberOfIterations = 50; int p = 3; - int numberOfRandomStartingPoints = 3; + int numberOfRandomStartingPoints = 1; //EXAMPLES @@ -53,9 +53,14 @@ static void Main(string[] args) 0, 0}; ProblemInstance maxCut3 = new ProblemInstance(dh, dJ); + dh = new Double[] {0, 0 }; + dJ = new Double[]{ 0, 1, + 0, 0}; + ProblemInstance maxCut4 = new ProblemInstance(dh, dJ); + //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut1, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); OptimalSolution res = cop.runOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs index 00d7ebcd38d..264a6aa89ec 100644 --- a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs +++ b/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs @@ -66,6 +66,28 @@ public void evaluateCostFunctionTest() } + [TestMethod] + public void runOptimizationTest() + { + double[] dh = new Double[] { 0, 0 }; + double[] dJ = new Double[]{ 0, 1, + 0, 0}; + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + + HybridQaoa classicalOptimization = new HybridQaoa(50, 2, simpleMaxCut, 2); + OptimalSolution optimalSolution = classicalOptimization.runOptimization(); + + string optimizationResult1 = "01"; + string optimizationResult2 = "10"; + + string result = optimalSolution.optimalVector; + Console.WriteLine(result); + + Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + + + } + } } From 06a04bacf47e0ad8a25e549a56ee78fc9552646f Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 26 Jul 2020 14:47:52 +0200 Subject: [PATCH 19/61] Unit test for hybrid qaoa added. Code refactoring. --- .../HybridQaoaTests.cs} | 34 ++++++++++++++++++- .../UtilsTests.cs | 0 2 files changed, 33 insertions(+), 1 deletion(-) rename QAOA/QAOATest/{ClassicalOptimizationTests/ClassicalOptimizationTests.cs => HybridQaoaTests/HybridQaoaTests.cs} (72%) rename QAOA/QAOATest/{ClassicalOptimizationTests => HybridQaoaTests}/UtilsTests.cs (100%) diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs similarity index 72% rename from QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs rename to QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs index 264a6aa89ec..1b5953a7b06 100644 --- a/QAOA/QAOATest/ClassicalOptimizationTests/ClassicalOptimizationTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs @@ -72,9 +72,14 @@ public void runOptimizationTest() double[] dh = new Double[] { 0, 0 }; double[] dJ = new Double[]{ 0, 1, 0, 0}; + + int numberOfIterations = 50; + int p = 2; + int numberOfRandomStartingPoints = 2; + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); - HybridQaoa classicalOptimization = new HybridQaoa(50, 2, simpleMaxCut, 2); + HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); OptimalSolution optimalSolution = classicalOptimization.runOptimization(); string optimizationResult1 = "01"; @@ -85,6 +90,33 @@ public void runOptimizationTest() Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + } + + [TestMethod] + public void runOptimizationTest2() + { + double[] dh = new Double[] { 0, 0 ,0}; + double[] dJ = new Double[]{ 0, 1, 5, + 0, 0, 2, + 0, 0, 0}; + + int numberOfIterations = 50; + int p = 2; + int numberOfRandomStartingPoints = 2; + + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + + HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); + OptimalSolution optimalSolution = classicalOptimization.runOptimization(); + + string optimizationResult1 = "110"; + string optimizationResult2 = "001"; + + string result = optimalSolution.optimalVector; + Console.WriteLine(result); + + Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + } diff --git a/QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs b/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs similarity index 100% rename from QAOA/QAOATest/ClassicalOptimizationTests/UtilsTests.cs rename to QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs From 07765ded102b9daceeb349b540601013f3c9aa46 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 2 Aug 2020 21:25:58 +0200 Subject: [PATCH 20/61] QAOA magic added with unit tests. --- .gitignore | 1 + QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs | 21 ++----- .../ClassicalOptimization/OptimalSolution.cs | 25 ++++++++ QAOA/QAOA/Driver.cs | 5 +- .../HybridQaoaMagic.cs} | 60 +++++++++++++++++-- .../HybridQaoaTests/HybridQaoaTests.cs | 33 +--------- .../HybridQaoaProblemInstanceMagicTests.cs | 44 ++++++++++++++ .../HybridQaoaRunMagicTests.cs | 51 ++++++++++++++++ .../QAOATest/MagicCommandTests/MockChannel.cs | 22 +++++++ QAOA/QAOATest/QAOATest.csproj | 6 ++ 10 files changed, 214 insertions(+), 54 deletions(-) create mode 100644 QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs rename QAOA/QAOA/{magicCommand/HybridQaoaRunMagic.cs => MagicCommand/HybridQaoaMagic.cs} (52%) create mode 100644 QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs create mode 100644 QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs create mode 100644 QAOA/QAOATest/MagicCommandTests/MockChannel.cs diff --git a/.gitignore b/.gitignore index 232a25886d2..99d456ffa56 100644 --- a/.gitignore +++ b/.gitignore @@ -330,3 +330,4 @@ __pycache__/ *.odx.cs *.xsd.cs +/QAOA/QAOATest/MagicCommandTests/sample.py diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs index e636f3f3fbd..65348fd9769 100644 --- a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs +++ b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs @@ -5,17 +5,11 @@ using Accord.Math.Optimization; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; +using QAOA.ClassicalOptimization; namespace Quantum.QAOA { - public struct OptimalSolution - { - public String optimalVector; - public Double optimalValue; - public Double[] optimalBeta; - public Double[] optimalGamma; - } public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later { @@ -219,17 +213,10 @@ private double[] setUpFreeParameters() /// /// # Output /// Optimal solution found by a QAOA. - public OptimalSolution getOptimalSolution() + public OptimalSolution GetOptimalSolution() { - OptimalSolution optimalSolution = new OptimalSolution - { - optimalVector = this.bestVector, - optimalValue = this.bestHamiltonian, - optimalBeta = this.bestBeta, - optimalGamma = this.bestGamma, - }; - return optimalSolution; + return new OptimalSolution(this.bestVector, this.bestHamiltonian, this.bestBeta, this.bestGamma); } /// # Summary @@ -259,7 +246,7 @@ public OptimalSolution runOptimization() } - return getOptimalSolution(); + return GetOptimalSolution(); } diff --git a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs new file mode 100644 index 00000000000..cc6904df95a --- /dev/null +++ b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace QAOA.ClassicalOptimization +{ + public class OptimalSolution + { + + public String OptimalVector { get; } + public Double OptimalValue { get; } + public Double[] OptimalBeta { get; } + public Double[] OptimalGamma { get; } + + public OptimalSolution(String optimalVector, Double optimalValue, Double[] optimalBeta, Double[] optimalGamma) + { + OptimalVector = optimalVector; + OptimalValue = optimalValue; + OptimalBeta = optimalBeta; + OptimalGamma = optimalGamma; + + } + + } +} diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Driver.cs index 348cc95c976..03b64c86eb1 100644 --- a/QAOA/QAOA/Driver.cs +++ b/QAOA/QAOA/Driver.cs @@ -1,4 +1,5 @@ -using System; +using QAOA.ClassicalOptimization; +using System; namespace Quantum.QAOA { @@ -63,7 +64,7 @@ static void Main(string[] args) HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); OptimalSolution res = cop.runOptimization(); - Console.WriteLine(res.optimalVector); + Console.WriteLine(res.OptimalVector); } } diff --git a/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs similarity index 52% rename from QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs rename to QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs index 05bdacbc7b9..ebf1c12cd53 100644 --- a/QAOA/QAOA/magicCommand/HybridQaoaRunMagic.cs +++ b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs @@ -11,7 +11,7 @@ public class HybridQaoaRunMagic : MagicSymbol public HybridQaoaRunMagic() { - this.Name = $"%standard.hybridqaoa.run"; + this.Name = $"%qaoa.hybridqaoa.run"; this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json" }; this.Kind = SymbolKind.Magic; this.Execute = this.Run; @@ -72,12 +72,64 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance); //deal with optional params + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.InitialBeta, args.InitialGamma); return hybridQaoa.runOptimization().ToExecutionResult(); } + } + public class HybridQaoaProblemInstanceMagic : MagicSymbol + { + public HybridQaoaProblemInstanceMagic() + { + this.Name = $"%qaoa.hybridqaoa.create.problem.instance"; + this.Documentation = new Documentation() { Summary = "Prepares a problem instance objects that serves as one of arguments to %qaoa.hybridqaoa.run." }; + this.Kind = SymbolKind.Magic; + this.Execute = this.Run; + } - } + /// + /// List of arguments + /// + public class Arguments + { + /// + /// Coefficents for one-local Hamiltonian terms. + /// + [JsonProperty(PropertyName = "one_local_hamiltonian_coefficients")] + public Double[] OneLocalHamiltonianCoefficients { get; set; } + + /// + /// Coefficents for one-local Hamiltonian terms. + /// + [JsonProperty(PropertyName = "two_local_hamiltonian_coefficients")] + public Double[] TwoLocalHamiltonianCoefficients { get; set; } + + /// + /// Depth of a QAOA circuit. + /// + [JsonProperty(PropertyName = "problem_size_in_bits")] + public int ProblemSizeInBits { get; set; } + + } + + /// + /// Prepares a ProblemInstance object for a hybrid QAOA. + /// + public async Task Run(string input, IChannel channel) + { + if (string.IsNullOrWhiteSpace(input)) + { + channel.Stderr("Please provide correct arguments"); + return ExecuteStatus.Error.ToExecutionResult(); + } + + var args = JsonConvert.DeserializeObject(input); + + ProblemInstance problemInstance = new ProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); + + return problemInstance.ToExecutionResult(); + } + + } } diff --git a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs index 1b5953a7b06..6560f1a2d86 100644 --- a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs @@ -3,6 +3,7 @@ using Quantum.QAOA; using System; using System.Reflection; +using QAOA.ClassicalOptimization; namespace QAOATest.ClassicalOptimizationTests { @@ -85,41 +86,11 @@ public void runOptimizationTest() string optimizationResult1 = "01"; string optimizationResult2 = "10"; - string result = optimalSolution.optimalVector; + string result = optimalSolution.OptimalVector; Console.WriteLine(result); Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); } - - [TestMethod] - public void runOptimizationTest2() - { - double[] dh = new Double[] { 0, 0 ,0}; - double[] dJ = new Double[]{ 0, 1, 5, - 0, 0, 2, - 0, 0, 0}; - - int numberOfIterations = 50; - int p = 2; - int numberOfRandomStartingPoints = 2; - - ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); - - HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); - OptimalSolution optimalSolution = classicalOptimization.runOptimization(); - - string optimizationResult1 = "110"; - string optimizationResult2 = "001"; - - string result = optimalSolution.optimalVector; - Console.WriteLine(result); - - Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); - - - } - - } } diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs new file mode 100644 index 00000000000..0cf8d92359a --- /dev/null +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Newtonsoft.Json; +using Xunit; +using QAOA.magicCommand; +using Quantum.QAOA; +using System; + +namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +{ + + public class HybridQaoaProblemInstanceMagicTests + { + public (HybridQaoaProblemInstanceMagic, MockChannel) Init() => + (new HybridQaoaProblemInstanceMagic(), new MockChannel()); + + [Fact] + public async Task HybridQaoaProblemInstance() + { + var (magic, channel) = Init(); + Assert.Equal("%qaoa.hybridqaoa.create.problem.instance", magic.Name); + + double[] dh = new Double[] { 0, 0 }; + double[] dJ = new Double[]{ 0, 1, + 0, 0}; + + var args = JsonConvert.SerializeObject(new HybridQaoaProblemInstanceMagic.Arguments + { + OneLocalHamiltonianCoefficients = dh, + TwoLocalHamiltonianCoefficients = dJ + }); + + var result = await magic.Run(args, channel); + var problemInstance = result.Output as ProblemInstance; + Assert.Equal(ExecuteStatus.Ok, result.Status); + + Assert.True(problemInstance.ProblemSizeInBits.Equals(2)); + } + + } +} \ No newline at end of file diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs new file mode 100644 index 00000000000..20f725b19ce --- /dev/null +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Newtonsoft.Json; +using Xunit; +using QAOA.magicCommand; +using Quantum.QAOA; +using System; +using QAOA.ClassicalOptimization; + +namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +{ + public class HybridQaoaRunMagicTests + { + public (HybridQaoaRunMagic, MockChannel) Init() => + (new HybridQaoaRunMagic(), new MockChannel()); + + [Fact] + public async Task HybridQaoaRun() + { + var (magic, channel) = Init(); + Assert.Equal("%qaoa.hybridqaoa.run", magic.Name); + + var numberOfIterations = 50; + var p = 2; + double[] dh = new Double[] { 0, 0 }; + double[] dJ = new Double[]{ 0, 1, + 0, 0}; + + ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + + var args = JsonConvert.SerializeObject(new HybridQaoaRunMagic.Arguments + { + NumberOfIterations = numberOfIterations, + p = p, + ProblemInstance = simpleMaxCut + }); + + var result = await magic.Run(args, channel); + var optimalSolution = result.Output as OptimalSolution; + Assert.Equal(ExecuteStatus.Ok, result.Status); + string optimizationResult1 = "01"; + string optimizationResult2 = "10"; + + Assert.True(optimalSolution.OptimalVector.Equals(optimizationResult1) || optimalSolution.OptimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + } + } + + } \ No newline at end of file diff --git a/QAOA/QAOATest/MagicCommandTests/MockChannel.cs b/QAOA/QAOATest/MagicCommandTests/MockChannel.cs new file mode 100644 index 00000000000..e63f19d56c9 --- /dev/null +++ b/QAOA/QAOATest/MagicCommandTests/MockChannel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +using Microsoft.Jupyter.Core; + +namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +{ + public class MockChannel : IChannel + { + public List errors = new List(); + public List msgs = new List(); + + public void Display(object displayable) + { + throw new NotImplementedException(); + } + + public void Stderr(string message) => errors.Add(message); + + public void Stdout(string message) => msgs.Add(message); + } +} diff --git a/QAOA/QAOATest/QAOATest.csproj b/QAOA/QAOATest/QAOATest.csproj index 9a25671a4af..42ee5e81325 100644 --- a/QAOA/QAOATest/QAOATest.csproj +++ b/QAOA/QAOATest/QAOATest.csproj @@ -11,6 +11,12 @@ + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From 2133c2cde9815e1f0527352d0c04a03975581777 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Mon, 3 Aug 2020 11:59:05 +0200 Subject: [PATCH 21/61] Code refactoring. --- QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs | 85 ++++++++----------- .../ClassicalOptimization/OptimalSolution.cs | 16 ++-- .../ClassicalOptimization/ProblemInstance.cs | 12 +-- ...ClassicalOptimizationUtils.cs => Utils.cs} | 20 ++--- QAOA/QAOA/{Driver.cs => Examples.cs} | 6 +- QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs | 2 +- .../HybridQaoaTests/HybridQaoaTests.cs | 24 +++--- QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs | 10 +-- .../HybridQaoaProblemInstanceMagicTests.cs | 4 +- .../HybridQaoaRunMagicTests.cs | 2 +- 10 files changed, 84 insertions(+), 97 deletions(-) rename QAOA/QAOA/ClassicalOptimization/{ClassicalOptimizationUtils.cs => Utils.cs} (88%) rename QAOA/QAOA/{Driver.cs => Examples.cs} (95%) diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs index 65348fd9769..1318181e411 100644 --- a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs +++ b/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs @@ -13,11 +13,11 @@ namespace Quantum.QAOA public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later { - ClassicalOptimizationUtils.FreeParamsVector FreeParamsVector; + Utils.FreeParamsVector FreeParamsVector; int numberOfIterations; int p; ProblemInstance problemInstance; - Double bestHamiltonian; + Double bestHamiltonianValue; String bestVector; Double[] bestBeta; Double[] bestGamma; @@ -30,19 +30,19 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance this.numberOfIterations = numberOfIterations; this.p = p; this.problemInstance = problemInstance; - FreeParamsVector.beta = initialBeta; - FreeParamsVector.gamma = initialGamma; - bestHamiltonian = Double.MaxValue; + this.FreeParamsVector.beta = initialBeta; + this.FreeParamsVector.gamma = initialGamma; + bestHamiltonianValue = Double.MaxValue; bestVector = null; this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; } - public Double evaluateCostFunction(string result, double[] costs) + public Double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; - for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + for (int i = 0; i < problemInstance.problemSizeInBits; i++) { costFunctionValue += costs[i] * Char.GetNumericValue(result[i]); } @@ -63,19 +63,19 @@ public Double evaluateCostFunction(string result, double[] costs) /// # Remarks /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. - public double evaluateHamiltonian(string result) + public double EvaluateHamiltonian(string result) { double hamiltonianValue = 0; - for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + for (int i = 0; i < problemInstance.problemSizeInBits; i++) { - hamiltonianValue += problemInstance.OneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); + hamiltonianValue += problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); } - for (int i = 0; i < problemInstance.ProblemSizeInBits; i++) + for (int i = 0; i < problemInstance.problemSizeInBits; i++) { - for (int j = i + 1; j < problemInstance.ProblemSizeInBits; j++) + for (int j = i + 1; j < problemInstance.problemSizeInBits; j++) { - hamiltonianValue += problemInstance.TwoLocalHamiltonianCoefficients[i * problemInstance.ProblemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); + hamiltonianValue += problemInstance.twoLocalHamiltonianCoefficients[i * problemInstance.problemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); } } @@ -93,37 +93,37 @@ public double evaluateHamiltonian(string result) /// /// # Output /// The expected value of a Hamiltonian that we calculated in this run. - public Double calculateObjectiveFunction(double[] bigfreeParamsVector) + public Double CalculateObjectiveFunction(double[] bigfreeParamsVector) { - ClassicalOptimizationUtils.FreeParamsVector freeParamsVector = ClassicalOptimizationUtils.convertVectorIntoHalves(bigfreeParamsVector); + Utils.FreeParamsVector freeParamsVector = Utils.ConvertVectorIntoHalves(bigfreeParamsVector); double hamiltonianExpectationValue = 0; List allSolutionVectors = new List(); var beta = new QArray(freeParamsVector.beta); var gamma = new QArray(freeParamsVector.gamma); - ClassicalOptimizationUtils.printCurrentBetaGamma(beta, gamma); + Utils.PrintCurrentBetaGamma(beta, gamma); - var oneLocalHamiltonianCoefficients = new QArray(problemInstance.OneLocalHamiltonianCoefficients); - var twoLocalHamiltonianCoefficients = new QArray(problemInstance.TwoLocalHamiltonianCoefficients); + var oneLocalHamiltonianCoefficients = new QArray(problemInstance.oneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(problemInstance.twoLocalHamiltonianCoefficients); using (var qsim = new QuantumSimulator()) { for (int i = 0; i < numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, problemInstance.ProblemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; + IQArray result = RunQaoa.Run(qsim, problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; allSolutionVectors.Add(result.ToArray()); - string solutionVector = ClassicalOptimizationUtils.getBoolStringFromBoolArray(result.ToArray()); - double hamiltonianValue = evaluateHamiltonian(solutionVector); + string solutionVector = Utils.GetBoolStringFromBoolArray(result.ToArray()); + double hamiltonianValue = EvaluateHamiltonian(solutionVector); hamiltonianExpectationValue += (hamiltonianValue/numberOfIterations); } } - updateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); - ClassicalOptimizationUtils.printCurrentBestSolution(this.bestHamiltonian, this.bestVector); + UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); + Utils.PrintCurrentBestSolution(this.bestHamiltonianValue, this.bestVector); return hamiltonianExpectationValue; } @@ -138,12 +138,12 @@ public Double calculateObjectiveFunction(double[] bigfreeParamsVector) /// A vector of all binary solutions that were found by a QAOA. /// ## freeParamsVector /// A vector of beta and gamma coefficients. - private void updateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, ClassicalOptimizationUtils.FreeParamsVector freeParamsVector) + private void UpdateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, Utils.FreeParamsVector freeParamsVector) { - if (hamiltonianExpectationValue < this.bestHamiltonian) + if (hamiltonianExpectationValue < this.bestHamiltonianValue) { - String mostProbableSolutionVectorTemp = ClassicalOptimizationUtils.getModeFromBoolList(allSolutionVectors); - bestHamiltonian = hamiltonianExpectationValue; + String mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); + bestHamiltonianValue = hamiltonianExpectationValue; bestVector = mostProbableSolutionVectorTemp; bestBeta = freeParamsVector.beta; bestGamma = freeParamsVector.gamma; @@ -160,7 +160,7 @@ private void updateBestSolution(double hamiltonianExpectationValue, List /// # Remarks /// For the canonical choice of the mixing Hamiltonian (i.e. the sum of X operators acting on single qubits), the range of values in the beta vector is 0 <= beta_i <= PI. /// For the objective function Hamiltonian based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. - private NonlinearConstraint[] generateConstraints() + private NonlinearConstraint[] GenerateConstraints() { NonlinearConstraint[] constraints = new NonlinearConstraint[4*p]; @@ -181,7 +181,7 @@ private NonlinearConstraint[] generateConstraints() /// /// # Output /// Initialized beta and gamma vectors concatenated. - private double[] setUpFreeParameters() + private double[] SetUpFreeParameters() { double[] betaCoefficients; if (FreeParamsVector.beta != null) @@ -191,7 +191,7 @@ private double[] setUpFreeParameters() } else { - betaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, Math.PI); + betaCoefficients = Utils.GetRandomVector(p, Math.PI); } double[] gammaCoefficients; @@ -202,23 +202,12 @@ private double[] setUpFreeParameters() } else { - gammaCoefficients = ClassicalOptimizationUtils.getRandomVector(p, 2 * Math.PI); + gammaCoefficients = Utils.GetRandomVector(p, 2 * Math.PI); } return betaCoefficients.Concat(gammaCoefficients).ToArray(); } - /// # Summary - /// Returns the optimal solution found by a QAOA. - /// - /// # Output - /// Optimal solution found by a QAOA. - public OptimalSolution GetOptimalSolution() - { - - return new OptimalSolution(this.bestVector, this.bestHamiltonian, this.bestBeta, this.bestGamma); - } - /// # Summary /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum. /// @@ -228,25 +217,25 @@ public OptimalSolution GetOptimalSolution() /// # Remarks /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. /// The objective function Hamiltonian is based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. - public OptimalSolution runOptimization() + public OptimalSolution RunOptimization() { - Func objectiveFunction = calculateObjectiveFunction; + Func objectiveFunction = CalculateObjectiveFunction; var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction); - NonlinearConstraint[] constraints = generateConstraints(); + NonlinearConstraint[] constraints = GenerateConstraints(); for (int i = 0; i < numberOfRandomStartingPoints; i++) { var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - double[] freeParameters = setUpFreeParameters(); + double[] freeParameters = SetUpFreeParameters(); bool success = cobyla.Minimize(freeParameters); - ClassicalOptimizationUtils.printSuccess(success); + Utils.PrintSuccess(success); } - return GetOptimalSolution(); + return new OptimalSolution(this.bestVector, this.bestHamiltonianValue, this.bestBeta, this.bestGamma); } diff --git a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs index cc6904df95a..3cd67d67d4a 100644 --- a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs +++ b/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs @@ -7,17 +7,17 @@ namespace QAOA.ClassicalOptimization public class OptimalSolution { - public String OptimalVector { get; } - public Double OptimalValue { get; } - public Double[] OptimalBeta { get; } - public Double[] OptimalGamma { get; } + public String optimalVector { get; } + public Double optimalValue { get; } + public Double[] optimalBeta { get; } + public Double[] optimalGamma { get; } public OptimalSolution(String optimalVector, Double optimalValue, Double[] optimalBeta, Double[] optimalGamma) { - OptimalVector = optimalVector; - OptimalValue = optimalValue; - OptimalBeta = optimalBeta; - OptimalGamma = optimalGamma; + this.optimalVector = optimalVector; + this.optimalValue = optimalValue; + this.optimalBeta = optimalBeta; + this.optimalGamma = optimalGamma; } diff --git a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs index 911efb115e3..abab91b22e2 100644 --- a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs +++ b/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs @@ -4,15 +4,15 @@ namespace Quantum.QAOA { public class ProblemInstance { - public Double[] OneLocalHamiltonianCoefficients { get; } - public Double[] TwoLocalHamiltonianCoefficients { get; } - public int ProblemSizeInBits { get; } + public Double[] oneLocalHamiltonianCoefficients { get; } + public Double[] twoLocalHamiltonianCoefficients { get; } + public int problemSizeInBits { get; } public ProblemInstance(Double[] oneLocalHamiltonianCoefficients, Double[] twoLocalHamiltonianCoefficients) { - OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; - TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; - ProblemSizeInBits = OneLocalHamiltonianCoefficients.Length; + this.oneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; + this.twoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; + this.problemSizeInBits = oneLocalHamiltonianCoefficients.Length; } } } diff --git a/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs b/QAOA/QAOA/ClassicalOptimization/Utils.cs similarity index 88% rename from QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs rename to QAOA/QAOA/ClassicalOptimization/Utils.cs index 8c481e9810b..d61dcbe9050 100644 --- a/QAOA/QAOA/ClassicalOptimization/ClassicalOptimizationUtils.cs +++ b/QAOA/QAOA/ClassicalOptimization/Utils.cs @@ -5,7 +5,7 @@ namespace Quantum.QAOA { - public class ClassicalOptimizationUtils + public class Utils { public struct FreeParamsVector @@ -26,13 +26,13 @@ public struct FreeParamsVector /// # Output /// A random vector of doubles. - public static double[] getRandomVector(int length, double maximum) + public static double[] GetRandomVector(int length, double maximumValue) { var rand = new Random(); double[] randomVector = new double[length]; for (int i = 0; i < length; i++) { - randomVector[i] = maximum * rand.NextDouble(); + randomVector[i] = maximumValue * rand.NextDouble(); } return randomVector; @@ -48,12 +48,12 @@ public static double[] getRandomVector(int length, double maximum) /// # Output /// The most common boolean string. - public static String getModeFromBoolList(List list) + public static String GetModeFromBoolList(List list) { Dictionary counter = new Dictionary(); foreach (bool[] boolArray in list) { - String boolString = getBoolStringFromBoolArray(boolArray); + String boolString = GetBoolStringFromBoolArray(boolArray); if (counter.ContainsKey(boolString)) { counter[boolString] += 1; @@ -88,7 +88,7 @@ public static String getModeFromBoolList(List list) /// # Output /// A boolean string. - public static string getBoolStringFromBoolArray(bool[] boolArray) + public static string GetBoolStringFromBoolArray(bool[] boolArray) { System.Text.StringBuilder sb = new StringBuilder(); foreach (bool b in boolArray) @@ -111,7 +111,7 @@ public static string getBoolStringFromBoolArray(bool[] boolArray) /// # Remarks /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. - public static FreeParamsVector convertVectorIntoHalves(double[] bigfreeParamsVector) + public static FreeParamsVector ConvertVectorIntoHalves(double[] bigfreeParamsVector) { int size = bigfreeParamsVector.Length; int vectorTermsNumber = size / 2; @@ -134,7 +134,7 @@ public static FreeParamsVector convertVectorIntoHalves(double[] bigfreeParamsVec /// Beta vector of coefficients. /// ## gamma /// Gamma vector of coefficients. - public static void printCurrentBetaGamma(QArray beta, QArray gamma) + public static void PrintCurrentBetaGamma(QArray beta, QArray gamma) { Console.WriteLine("Current beta vector:"); Console.WriteLine(beta); @@ -152,7 +152,7 @@ public static void printCurrentBetaGamma(QArray beta, QArray gam /// Best value of a Hamiltonian so far. /// ## bestVector /// Best solution vector that generates the above value of a Hamiltonian so far. - public static void printCurrentBestSolution(double bestHamiltonian, String bestVector) + public static void PrintCurrentBestSolution(double bestHamiltonian, String bestVector) { Console.WriteLine("Current best fidelity"); Console.WriteLine(bestHamiltonian); @@ -166,7 +166,7 @@ public static void printCurrentBestSolution(double bestHamiltonian, String bestV /// # Input /// ## success /// A flag that indiciates whether an optimization finished successfully. - public static void printSuccess(bool success) + public static void PrintSuccess(bool success) { Console.WriteLine("Was optimization successful?"); Console.WriteLine(success); diff --git a/QAOA/QAOA/Driver.cs b/QAOA/QAOA/Examples.cs similarity index 95% rename from QAOA/QAOA/Driver.cs rename to QAOA/QAOA/Examples.cs index 03b64c86eb1..e001b854b06 100644 --- a/QAOA/QAOA/Driver.cs +++ b/QAOA/QAOA/Examples.cs @@ -3,7 +3,7 @@ namespace Quantum.QAOA { - class Driver + class Examples { @@ -63,8 +63,8 @@ static void Main(string[] args) HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); - OptimalSolution res = cop.runOptimization(); - Console.WriteLine(res.OptimalVector); + OptimalSolution res = cop.RunOptimization(); + Console.WriteLine(res.optimalVector); } } diff --git a/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs index ebf1c12cd53..ee52d456db8 100644 --- a/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs +++ b/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs @@ -74,7 +74,7 @@ public async Task Run(string input, IChannel channel) HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.InitialBeta, args.InitialGamma); - return hybridQaoa.runOptimization().ToExecutionResult(); + return hybridQaoa.RunOptimization().ToExecutionResult(); } } diff --git a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs index 6560f1a2d86..8b90f911cfd 100644 --- a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs @@ -1,8 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; using Quantum.QAOA; using System; -using System.Reflection; using QAOA.ClassicalOptimization; namespace QAOATest.ClassicalOptimizationTests @@ -13,20 +11,20 @@ public class ClassicalOptimizationTest { [TestMethod] - public void convertDataVectorToVectorsTest() + public void ConvertDataVectorToVectorsTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); - ClassicalOptimizationUtils.FreeParamsVector result = ClassicalOptimizationUtils.convertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); + Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); - ClassicalOptimizationUtils.FreeParamsVector dataVectors = new ClassicalOptimizationUtils.FreeParamsVector(); + Utils.FreeParamsVector dataVectors = new Utils.FreeParamsVector(); dataVectors.beta = new double[] { 1, 2, 3 }; dataVectors.gamma = new double[] { 4, 5, 6 }; - ClassicalOptimizationUtils.FreeParamsVector expectedResult = dataVectors; + Utils.FreeParamsVector expectedResult = dataVectors; CollectionAssert.AreEqual(expectedResult.beta, result.beta, "Hamiltonian beta value not calculated correctly."); CollectionAssert.AreEqual(expectedResult.gamma, result.gamma, "Hamiltonian gamma value not calculated correctly."); @@ -34,13 +32,13 @@ public void convertDataVectorToVectorsTest() } [TestMethod] - public void evaluateHamiltonianTest() + public void EvaluateHamiltonianTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); - Double result = classicalOptimization.evaluateHamiltonian("0011"); + Double result = classicalOptimization.EvaluateHamiltonian("0011"); Double expectedResult = -1; @@ -49,7 +47,7 @@ public void evaluateHamiltonianTest() } [TestMethod] - public void evaluateCostFunctionTest() + public void EvaluateCostFunctionTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); @@ -58,7 +56,7 @@ public void evaluateCostFunctionTest() string optimizationResult = "0101"; - Double result = classicalOptimization.evaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); + Double result = classicalOptimization.EvaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); Double expectedResult = 4; @@ -68,7 +66,7 @@ public void evaluateCostFunctionTest() } [TestMethod] - public void runOptimizationTest() + public void RunHybridQaoaTest() { double[] dh = new Double[] { 0, 0 }; double[] dJ = new Double[]{ 0, 1, @@ -81,12 +79,12 @@ public void runOptimizationTest() ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); - OptimalSolution optimalSolution = classicalOptimization.runOptimization(); + OptimalSolution optimalSolution = classicalOptimization.RunOptimization(); string optimizationResult1 = "01"; string optimizationResult2 = "10"; - string result = optimalSolution.OptimalVector; + string result = optimalSolution.optimalVector; Console.WriteLine(result); Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); diff --git a/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs b/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs index 85c66c00b29..b2a13ffc153 100644 --- a/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs @@ -1,8 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; using Quantum.QAOA; using System.Collections.Generic; -using System.Text; namespace QAOATest.ClassicalOptimizationTests { @@ -10,7 +8,7 @@ namespace QAOATest.ClassicalOptimizationTests public class UtilsTests { [TestMethod] - public void modeOfABoolListTest() + public void ModeOfABoolListTest() { bool[] boolsArray1 = { false, false, true }; bool[] boolsArray2 = { false, false, true }; @@ -25,7 +23,7 @@ public void modeOfABoolListTest() string expectedResult = "001"; - string result = ClassicalOptimizationUtils.getModeFromBoolList(listOfBools); + string result = Utils.GetModeFromBoolList(listOfBools); Assert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); @@ -33,14 +31,14 @@ public void modeOfABoolListTest() } [TestMethod] - public void boolStringFromBoolArrayTest() + public void BoolStringFromBoolArrayTest() { bool[] boolsArray = { false, false, true }; string expectedResult = "001"; - string result = ClassicalOptimizationUtils.getBoolStringFromBoolArray(boolsArray); + string result = Utils.GetBoolStringFromBoolArray(boolsArray); Assert.AreEqual(expectedResult, result, "Bool string not created correctly."); diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs index 0cf8d92359a..7d35e1f1ca7 100644 --- a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs @@ -37,7 +37,9 @@ public async Task HybridQaoaProblemInstance() var problemInstance = result.Output as ProblemInstance; Assert.Equal(ExecuteStatus.Ok, result.Status); - Assert.True(problemInstance.ProblemSizeInBits.Equals(2)); + Assert.Equal(problemInstance.problemSizeInBits, dh.Length); + Assert.Equal(problemInstance.oneLocalHamiltonianCoefficients, dh); + Assert.Equal(problemInstance.twoLocalHamiltonianCoefficients,dJ); } } diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs index 20f725b19ce..7c3258c6ffb 100644 --- a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs @@ -44,7 +44,7 @@ public async Task HybridQaoaRun() string optimizationResult1 = "01"; string optimizationResult2 = "10"; - Assert.True(optimalSolution.OptimalVector.Equals(optimizationResult1) || optimalSolution.OptimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + Assert.True(optimalSolution.optimalVector.Equals(optimizationResult1) || optimalSolution.optimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); } } From 9e16671cfaa4af7cc8bc47a288b1c4acb0a0e062 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Mon, 3 Aug 2020 21:38:49 +0200 Subject: [PATCH 22/61] Code refactoring --- QAOA.sln | 4 ++-- QAOA/{QAOA => src}/Examples.cs | 0 .../ClassicalOptimization => src/HybridQaoa}/HybridQaoa.cs | 0 .../HybridQaoa}/OptimalSolution.cs | 0 .../HybridQaoa}/ProblemInstance.cs | 0 QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/Utils.cs | 0 QAOA/{QAOA => src}/MagicCommand/HybridQaoaMagic.cs | 0 QAOA/{QAOA => src}/QAOA.csproj | 0 QAOA/{QAOA => src/Qaoa}/Hamiltonians.qs | 0 QAOA/{QAOA/QAOARunner.qs => src/Qaoa/QaoaRunner.qs} | 0 QAOA/{QAOA => src/Qaoa}/Utils.qs | 0 QAOA/{QAOATest => tests}/HybridQaoaTests/HybridQaoaTests.cs | 0 QAOA/{QAOATest => tests}/HybridQaoaTests/UtilsTests.cs | 0 .../MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs | 2 +- .../MagicCommandTests/HybridQaoaRunMagicTests.cs | 0 QAOA/{QAOATest => tests}/MagicCommandTests/MockChannel.cs | 0 QAOA/{QAOATest => tests}/QAOATest.csproj | 2 +- 17 files changed, 4 insertions(+), 4 deletions(-) rename QAOA/{QAOA => src}/Examples.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/HybridQaoa.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/OptimalSolution.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/ProblemInstance.cs (100%) rename QAOA/{QAOA/ClassicalOptimization => src/HybridQaoa}/Utils.cs (100%) rename QAOA/{QAOA => src}/MagicCommand/HybridQaoaMagic.cs (100%) rename QAOA/{QAOA => src}/QAOA.csproj (100%) rename QAOA/{QAOA => src/Qaoa}/Hamiltonians.qs (100%) rename QAOA/{QAOA/QAOARunner.qs => src/Qaoa/QaoaRunner.qs} (100%) rename QAOA/{QAOA => src/Qaoa}/Utils.qs (100%) rename QAOA/{QAOATest => tests}/HybridQaoaTests/HybridQaoaTests.cs (100%) rename QAOA/{QAOATest => tests}/HybridQaoaTests/UtilsTests.cs (100%) rename QAOA/{QAOATest => tests}/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs (100%) rename QAOA/{QAOATest => tests}/MagicCommandTests/HybridQaoaRunMagicTests.cs (100%) rename QAOA/{QAOATest => tests}/MagicCommandTests/MockChannel.cs (100%) rename QAOA/{QAOATest => tests}/QAOATest.csproj (94%) diff --git a/QAOA.sln b/QAOA.sln index 4e52096cef2..17160aba520 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\QAOA\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\src\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\QAOATest\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\tests\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/QAOA/QAOA/Examples.cs b/QAOA/src/Examples.cs similarity index 100% rename from QAOA/QAOA/Examples.cs rename to QAOA/src/Examples.cs diff --git a/QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs b/QAOA/src/HybridQaoa/HybridQaoa.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/HybridQaoa.cs rename to QAOA/src/HybridQaoa/HybridQaoa.cs diff --git a/QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs b/QAOA/src/HybridQaoa/OptimalSolution.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/OptimalSolution.cs rename to QAOA/src/HybridQaoa/OptimalSolution.cs diff --git a/QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs b/QAOA/src/HybridQaoa/ProblemInstance.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/ProblemInstance.cs rename to QAOA/src/HybridQaoa/ProblemInstance.cs diff --git a/QAOA/QAOA/ClassicalOptimization/Utils.cs b/QAOA/src/HybridQaoa/Utils.cs similarity index 100% rename from QAOA/QAOA/ClassicalOptimization/Utils.cs rename to QAOA/src/HybridQaoa/Utils.cs diff --git a/QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs b/QAOA/src/MagicCommand/HybridQaoaMagic.cs similarity index 100% rename from QAOA/QAOA/MagicCommand/HybridQaoaMagic.cs rename to QAOA/src/MagicCommand/HybridQaoaMagic.cs diff --git a/QAOA/QAOA/QAOA.csproj b/QAOA/src/QAOA.csproj similarity index 100% rename from QAOA/QAOA/QAOA.csproj rename to QAOA/src/QAOA.csproj diff --git a/QAOA/QAOA/Hamiltonians.qs b/QAOA/src/Qaoa/Hamiltonians.qs similarity index 100% rename from QAOA/QAOA/Hamiltonians.qs rename to QAOA/src/Qaoa/Hamiltonians.qs diff --git a/QAOA/QAOA/QAOARunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs similarity index 100% rename from QAOA/QAOA/QAOARunner.qs rename to QAOA/src/Qaoa/QaoaRunner.qs diff --git a/QAOA/QAOA/Utils.qs b/QAOA/src/Qaoa/Utils.qs similarity index 100% rename from QAOA/QAOA/Utils.qs rename to QAOA/src/Qaoa/Utils.qs diff --git a/QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs similarity index 100% rename from QAOA/QAOATest/HybridQaoaTests/HybridQaoaTests.cs rename to QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs diff --git a/QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs similarity index 100% rename from QAOA/QAOATest/HybridQaoaTests/UtilsTests.cs rename to QAOA/tests/HybridQaoaTests/UtilsTests.cs diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs similarity index 100% rename from QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs rename to QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs index 7d35e1f1ca7..ca3614556a0 100644 --- a/QAOA/QAOATest/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs @@ -5,9 +5,9 @@ using Microsoft.Jupyter.Core; using Newtonsoft.Json; using Xunit; +using System; using QAOA.magicCommand; using Quantum.QAOA; -using System; namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests { diff --git a/QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs similarity index 100% rename from QAOA/QAOATest/MagicCommandTests/HybridQaoaRunMagicTests.cs rename to QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs diff --git a/QAOA/QAOATest/MagicCommandTests/MockChannel.cs b/QAOA/tests/MagicCommandTests/MockChannel.cs similarity index 100% rename from QAOA/QAOATest/MagicCommandTests/MockChannel.cs rename to QAOA/tests/MagicCommandTests/MockChannel.cs diff --git a/QAOA/QAOATest/QAOATest.csproj b/QAOA/tests/QAOATest.csproj similarity index 94% rename from QAOA/QAOATest/QAOATest.csproj rename to QAOA/tests/QAOATest.csproj index 42ee5e81325..c5eec1be40b 100644 --- a/QAOA/QAOATest/QAOATest.csproj +++ b/QAOA/tests/QAOATest.csproj @@ -20,7 +20,7 @@ - + From a2603b6c104a070436fde5fad9c90c01116c34e3 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Tue, 4 Aug 2020 09:15:20 +0200 Subject: [PATCH 23/61] Build files updated. --- Build/build.ps1 | 3 +++ Build/manifest.ps1 | 2 ++ Build/pack.ps1 | 3 +++ Build/test.ps1 | 3 +++ QAOA.sln | 2 +- QAOA/tests/{QAOATest.csproj => QAOATests.csproj} | 0 6 files changed, 12 insertions(+), 1 deletion(-) rename QAOA/tests/{QAOATest.csproj => QAOATests.csproj} (100%) diff --git a/Build/build.ps1 b/Build/build.ps1 index 4cc20d6404e..7fe64b92a97 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -40,6 +40,9 @@ Build-One 'publish' '../MachineLearning.sln' Write-Host "##[info]Build Jupyter magic library" Build-One 'publish' '../Magic.sln' +Write-Host "##[info]Build QAOA library" +Build-One 'publish' '../QAOA.sln' + if (-not $all_ok) { throw "At least one test failed execution. Check the logs." } \ No newline at end of file diff --git a/Build/manifest.ps1 b/Build/manifest.ps1 index f4b4ab285ed..00d4c91f19b 100644 --- a/Build/manifest.ps1 +++ b/Build/manifest.ps1 @@ -9,6 +9,7 @@ "Microsoft.Quantum.Chemistry", "Microsoft.Quantum.Numerics", "Microsoft.Quantum.MachineLearning" + "Microsoft.Quantum.QAOA" ); Assemblies = @( ".\Standard\src\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Standard.dll", @@ -17,5 +18,6 @@ ".\Chemistry\src\DataModel\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.DataModel.dll", ".\Chemistry\src\Runtime\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.Runtime.dll", ".\Chemistry\src\Tools\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\qdk-chem.dll" + ".\QAOA\src\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\QAOA.dll" ) | ForEach-Object { Get-Item (Join-Path $PSScriptRoot ".." $_) }; } | Write-Output; diff --git a/Build/pack.ps1 b/Build/pack.ps1 index d32e5108b1b..e52a8e7df24 100644 --- a/Build/pack.ps1 +++ b/Build/pack.ps1 @@ -72,6 +72,9 @@ if ($Env:ENABLE_PYTHON -eq "false") { Pack-Wheel '../Python/qsharp' } +Write-Host "##[info]Pack QAOA library" +Pack-One '../QAOA/src/QAOA.csproj' + if (-not $all_ok) { throw "At least one test failed execution. Check the logs." } diff --git a/Build/test.ps1 b/Build/test.ps1 index 5337d4b0fba..1c7e886748d 100644 --- a/Build/test.ps1 +++ b/Build/test.ps1 @@ -40,6 +40,9 @@ Test-One '../Chemistry/tests/JupyterTests/JupyterTests.csproj' Write-Host "##[info]Testing Numerics/tests/NumericsTests.csproj" Test-One '../Numerics/tests/NumericsTests.csproj' +Write-Host "##[info]Testing QAOA/tests/QAOATests.csproj" +Test-One '../QAOA/tests/QAOATests.csproj' + if (-not $all_ok) { throw "At least one test failed execution. Check the logs." } diff --git a/QAOA.sln b/QAOA.sln index 17160aba520..0cca796c148 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\src\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAOATest", "QAOA\tests\QAOATest.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOATests", "QAOA\tests\QAOATests.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/QAOA/tests/QAOATest.csproj b/QAOA/tests/QAOATests.csproj similarity index 100% rename from QAOA/tests/QAOATest.csproj rename to QAOA/tests/QAOATests.csproj From 06e184260fc720a5f92766da66c6c1c51a34f498 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Tue, 4 Aug 2020 20:07:28 +0200 Subject: [PATCH 24/61] Project structure improved. Basic quantum unit tests added. --- QAOA.sln | 35 +++++++++++++++--- QAOA/src/HybridQaoa/HybridQaoa.cs | 1 + QAOA/src/Qaoa/Hamiltonians.qs | 2 +- QAOA/src/Qaoa/QaoaRunner.qs | 2 +- QAOA/src/Qaoa/Utils.qs | 2 +- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 2 +- .../HybridQaoaTests.csproj} | 8 +---- QAOA/tests/HybridQaoaTests/UtilsTests.cs | 2 +- .../HybridQaoaProblemInstanceMagicTests.cs | 3 +- .../HybridQaoaRunMagicTests.cs | 4 +-- QAOA/tests/JupyterTests/JupyterTests.csproj | 26 ++++++++++++++ .../MockChannel.cs | 2 +- QAOA/tests/QaoaTests/QaoaTests.csproj | 20 +++++++++++ QAOA/tests/QaoaTests/Tests.qs | 17 +++++++++ QAOA/tests/QaoaTests/UtilsTests.qs | 36 +++++++++++++++++++ 15 files changed, 141 insertions(+), 21 deletions(-) rename QAOA/tests/{QAOATests.csproj => HybridQaoaTests/HybridQaoaTests.csproj} (55%) rename QAOA/tests/{MagicCommandTests => JupyterTests}/HybridQaoaProblemInstanceMagicTests.cs (94%) rename QAOA/tests/{MagicCommandTests => JupyterTests}/HybridQaoaRunMagicTests.cs (96%) create mode 100644 QAOA/tests/JupyterTests/JupyterTests.csproj rename QAOA/tests/{MagicCommandTests => JupyterTests}/MockChannel.cs (89%) create mode 100644 QAOA/tests/QaoaTests/QaoaTests.csproj create mode 100644 QAOA/tests/QaoaTests/Tests.qs create mode 100644 QAOA/tests/QaoaTests/UtilsTests.qs diff --git a/QAOA.sln b/QAOA.sln index 0cca796c148..4de26b7640b 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -5,7 +5,17 @@ VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\src\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOATests", "QAOA\tests\QAOATests.csproj", "{D9BB6E07-427A-4A8D-9652-B4E310F803E5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HybridQaoaTests", "QAOA\tests\HybridQaoaTests\HybridQaoaTests.csproj", "{1623F038-210A-4BA2-8D4E-9AF611610829}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JupyterTests", "QAOA\tests\JupyterTests\JupyterTests.csproj", "{3C8B4AF6-5495-4F23-B7B2-634E5A667837}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QaoaTests", "QAOA\tests\QaoaTests\QaoaTests.csproj", "{208C0012-D62F-4F29-8738-394A62BBE842}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HybridQaoa", "HybridQaoa", "{A6612841-F6D1-4A8E-A8F8-4430F9FF7992}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AD73B607-0EF5-4C11-8832-22D584939780}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{80082123-4392-4F0E-8F87-26183C620693}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,14 +27,29 @@ Global {159D83BF-56A2-41B7-951B-35292F5A9F23}.Debug|Any CPU.Build.0 = Debug|Any CPU {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.ActiveCfg = Release|Any CPU {159D83BF-56A2-41B7-951B-35292F5A9F23}.Release|Any CPU.Build.0 = Release|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9BB6E07-427A-4A8D-9652-B4E310F803E5}.Release|Any CPU.Build.0 = Release|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1623F038-210A-4BA2-8D4E-9AF611610829}.Release|Any CPU.Build.0 = Release|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3C8B4AF6-5495-4F23-B7B2-634E5A667837}.Release|Any CPU.Build.0 = Release|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Debug|Any CPU.Build.0 = Debug|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Release|Any CPU.ActiveCfg = Release|Any CPU + {208C0012-D62F-4F29-8738-394A62BBE842}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {159D83BF-56A2-41B7-951B-35292F5A9F23} = {AD73B607-0EF5-4C11-8832-22D584939780} + {1623F038-210A-4BA2-8D4E-9AF611610829} = {80082123-4392-4F0E-8F87-26183C620693} + {3C8B4AF6-5495-4F23-B7B2-634E5A667837} = {80082123-4392-4F0E-8F87-26183C620693} + {208C0012-D62F-4F29-8738-394A62BBE842} = {80082123-4392-4F0E-8F87-26183C620693} + {AD73B607-0EF5-4C11-8832-22D584939780} = {A6612841-F6D1-4A8E-A8F8-4430F9FF7992} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {09481F99-E1AC-44CE-A892-7331820661DF} EndGlobalSection diff --git a/QAOA/src/HybridQaoa/HybridQaoa.cs b/QAOA/src/HybridQaoa/HybridQaoa.cs index 1318181e411..8ebffdb0936 100644 --- a/QAOA/src/HybridQaoa/HybridQaoa.cs +++ b/QAOA/src/HybridQaoa/HybridQaoa.cs @@ -3,6 +3,7 @@ using System.Linq; using Accord.Math; using Accord.Math.Optimization; +using Microsoft.Quantum.QAOA; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; using QAOA.ClassicalOptimization; diff --git a/QAOA/src/Qaoa/Hamiltonians.qs b/QAOA/src/Qaoa/Hamiltonians.qs index f36be87de7f..0e514d4529e 100644 --- a/QAOA/src/Qaoa/Hamiltonians.qs +++ b/QAOA/src/Qaoa/Hamiltonians.qs @@ -1,4 +1,4 @@ -namespace Quantum.QAOA { +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index af8db6eb782..5bd0334b73a 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -1,4 +1,4 @@ -namespace Quantum.QAOA { +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index 4ec42e366a8..d553e38b63f 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -1,4 +1,4 @@ -namespace Quantum.QAOA { +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 8b90f911cfd..60ba806590b 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -3,7 +3,7 @@ using System; using QAOA.ClassicalOptimization; -namespace QAOATest.ClassicalOptimizationTests +namespace Microsoft.Quantum.QAOA.HybridQaoaTests { [TestClass] diff --git a/QAOA/tests/QAOATests.csproj b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj similarity index 55% rename from QAOA/tests/QAOATests.csproj rename to QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj index c5eec1be40b..7a5759a0de3 100644 --- a/QAOA/tests/QAOATests.csproj +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj @@ -11,16 +11,10 @@ - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs index b2a13ffc153..0856270e784 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/UtilsTests.cs @@ -2,7 +2,7 @@ using Quantum.QAOA; using System.Collections.Generic; -namespace QAOATest.ClassicalOptimizationTests +namespace Microsoft.Quantum.QAOA.HybridQaoaTests { [TestClass] public class UtilsTests diff --git a/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs similarity index 94% rename from QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs rename to QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index ca3614556a0..fa6913901f0 100644 --- a/QAOA/tests/MagicCommandTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -8,8 +8,9 @@ using System; using QAOA.magicCommand; using Quantum.QAOA; +using Microsoft.Quantum.QAOA.JupyterTests; -namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +namespace Microsoft.Quantum.QAOA.HybridQaoaTests { public class HybridQaoaProblemInstanceMagicTests diff --git a/QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs similarity index 96% rename from QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs rename to QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 7c3258c6ffb..d0e7a7dd9ed 100644 --- a/QAOA/tests/MagicCommandTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -4,13 +4,13 @@ using System.Threading.Tasks; using Microsoft.Jupyter.Core; using Newtonsoft.Json; -using Xunit; using QAOA.magicCommand; using Quantum.QAOA; using System; using QAOA.ClassicalOptimization; +using Xunit; -namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +namespace Microsoft.Quantum.QAOA.JupyterTests { public class HybridQaoaRunMagicTests { diff --git a/QAOA/tests/JupyterTests/JupyterTests.csproj b/QAOA/tests/JupyterTests/JupyterTests.csproj new file mode 100644 index 00000000000..b157f4abf10 --- /dev/null +++ b/QAOA/tests/JupyterTests/JupyterTests.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/QAOA/tests/MagicCommandTests/MockChannel.cs b/QAOA/tests/JupyterTests/MockChannel.cs similarity index 89% rename from QAOA/tests/MagicCommandTests/MockChannel.cs rename to QAOA/tests/JupyterTests/MockChannel.cs index e63f19d56c9..b56b38f196b 100644 --- a/QAOA/tests/MagicCommandTests/MockChannel.cs +++ b/QAOA/tests/JupyterTests/MockChannel.cs @@ -3,7 +3,7 @@ using Microsoft.Jupyter.Core; -namespace Microsoft.Quantum.QAOA.QAOATest.HybridQaoaTests +namespace Microsoft.Quantum.QAOA.JupyterTests { public class MockChannel : IChannel { diff --git a/QAOA/tests/QaoaTests/QaoaTests.csproj b/QAOA/tests/QaoaTests/QaoaTests.csproj new file mode 100644 index 00000000000..f514d649463 --- /dev/null +++ b/QAOA/tests/QaoaTests/QaoaTests.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + false + + + + + + + + + + + + + + + diff --git a/QAOA/tests/QaoaTests/Tests.qs b/QAOA/tests/QaoaTests/Tests.qs new file mode 100644 index 00000000000..9d4f36f7b0e --- /dev/null +++ b/QAOA/tests/QaoaTests/Tests.qs @@ -0,0 +1,17 @@ +namespace Quantum.QaoaTests { + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.QAOA; + + + @Test("QuantumSimulator") + operation AllocateQubit () : Unit { + + using (q = Qubit()) { + Assert([PauliZ], [q], Zero, "Newly allocated qubit must be in |0> state."); + } + + Message("Test passed."); + } +} diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs new file mode 100644 index 00000000000..2b66b129f32 --- /dev/null +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Tests { + open Microsoft.Quantum.Logical; + open Microsoft.Quantum.Arrays; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Math; + open Microsoft.Quantum.QAOA; + + @Test("QuantumSimulator") + operation RunPhaseKickbackTest() : Unit { + + let numberOfQubits = 1; + let ancillaQubits = 1; + let controlQubitsIndices = [0]; + let phaseExponent = 0.5; + let complexOne = Complex(1.0, 0.0); + let complexZero = Complex(0.0, 0.0); + + using (qubits = Qubit[numberOfQubits+ancillaQubits]) + { + RunPhaseKickback(qubits[...1], qubits[1...],controlQubitsIndices,phaseExponent); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[0], 1E-06); + ResetAll(qubits); + } + } + + @Test("QuantumSimulator") + operation MeasureAllAndResetTest() : Unit { + + + } + +} From 25cf02cbf1906d4a224ce4e7f95f43d9f95186bf Mon Sep 17 00:00:00 2001 From: Dariusz Date: Thu, 6 Aug 2020 20:50:38 +0200 Subject: [PATCH 25/61] Qaoa unit tests extended. Code refactoring. --- Build/test.ps1 | 10 +++- QAOA.sln | 2 - QAOA/src/Examples.cs | 2 +- .../HybridQaoaMagic.cs | 0 QAOA/src/QAOA.csproj | 2 +- QAOA/src/Qaoa/Utils.qs | 2 + QAOA/tests/QaoaTests/Tests.qs | 17 ------- QAOA/tests/QaoaTests/UtilsTests.qs | 46 +++++++++++++++++-- 8 files changed, 55 insertions(+), 26 deletions(-) rename QAOA/src/{MagicCommand => Jupyter}/HybridQaoaMagic.cs (100%) delete mode 100644 QAOA/tests/QaoaTests/Tests.qs diff --git a/Build/test.ps1 b/Build/test.ps1 index 1c7e886748d..ca544930561 100644 --- a/Build/test.ps1 +++ b/Build/test.ps1 @@ -40,8 +40,14 @@ Test-One '../Chemistry/tests/JupyterTests/JupyterTests.csproj' Write-Host "##[info]Testing Numerics/tests/NumericsTests.csproj" Test-One '../Numerics/tests/NumericsTests.csproj' -Write-Host "##[info]Testing QAOA/tests/QAOATests.csproj" -Test-One '../QAOA/tests/QAOATests.csproj' +Write-Host "##[info]Testing QAOA/tests/QaoaTests/QaoaTests.csproj" +Test-One '../QAOA/tests//QaoaTests/QaoaTests.csproj' + +Write-Host "##[info]Testing QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj" +Test-One '../QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj' + +Write-Host "##[info]Testing QAOA/tests/JupyterTests/JupyterTests.csproj" +Test-One '../QAOA/tests/JupyterTests/JupyterTests.csproj' if (-not $all_ok) { throw "At least one test failed execution. Check the logs." diff --git a/QAOA.sln b/QAOA.sln index 4de26b7640b..3bfbe8607d4 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JupyterTests", "QAOA\tests\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QaoaTests", "QAOA\tests\QaoaTests\QaoaTests.csproj", "{208C0012-D62F-4F29-8738-394A62BBE842}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HybridQaoa", "HybridQaoa", "{A6612841-F6D1-4A8E-A8F8-4430F9FF7992}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AD73B607-0EF5-4C11-8832-22D584939780}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{80082123-4392-4F0E-8F87-26183C620693}" diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index e001b854b06..7f762a5a62d 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -61,7 +61,7 @@ static void Main(string[] args) //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, quantumSanta, numberOfRandomStartingPoints); OptimalSolution res = cop.RunOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/src/MagicCommand/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs similarity index 100% rename from QAOA/src/MagicCommand/HybridQaoaMagic.cs rename to QAOA/src/Jupyter/HybridQaoaMagic.cs diff --git a/QAOA/src/QAOA.csproj b/QAOA/src/QAOA.csproj index 4994ceb6c9a..541726519c0 100644 --- a/QAOA/src/QAOA.csproj +++ b/QAOA/src/QAOA.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index d553e38b63f..7d3a8a83a8b 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -3,6 +3,7 @@ open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; + open Microsoft.Quantum.Diagnostics; operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] @@ -29,5 +30,6 @@ { CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); } + } } \ No newline at end of file diff --git a/QAOA/tests/QaoaTests/Tests.qs b/QAOA/tests/QaoaTests/Tests.qs deleted file mode 100644 index 9d4f36f7b0e..00000000000 --- a/QAOA/tests/QaoaTests/Tests.qs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Quantum.QaoaTests { - open Microsoft.Quantum.Canon; - open Microsoft.Quantum.Diagnostics; - open Microsoft.Quantum.Intrinsic; - open Microsoft.Quantum.QAOA; - - - @Test("QuantumSimulator") - operation AllocateQubit () : Unit { - - using (q = Qubit()) { - Assert([PauliZ], [q], Zero, "Newly allocated qubit must be in |0> state."); - } - - Message("Test passed."); - } -} diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs index 2b66b129f32..7b8a2628c2f 100644 --- a/QAOA/tests/QaoaTests/UtilsTests.qs +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -16,20 +16,60 @@ namespace Microsoft.Quantum.Tests { let ancillaQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; - let complexOne = Complex(1.0, 0.0); - let complexZero = Complex(0.0, 0.0); + let complexZero = Complex(1.0, 0.0); + let complexOne = Complex(0.0, 0.0); using (qubits = Qubit[numberOfQubits+ancillaQubits]) { RunPhaseKickback(qubits[...1], qubits[1...],controlQubitsIndices,phaseExponent); - AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[0], 1E-06); + AssertQubitIsInStateWithinTolerance((complexZero,complexOne), qubits[0], 1E-05); + ResetAll(qubits); + } + } + + @Test("QuantumSimulator") + operation RunPhaseKickbackTest2() : Unit { + + let numberOfQubits = 1; + let ancillaQubits = 1; + let controlQubitsIndices = [0]; + let phaseExponent = 0.5; + + let complexZero = Complex(0.685125,-0.174941); + let complexOne = Complex(0.685125,0.174941); + + using (qubits = Qubit[numberOfQubits+ancillaQubits]) + { + H(qubits[0]); + RunPhaseKickback([qubits[0]], [qubits[1]],controlQubitsIndices,phaseExponent); + AssertQubitIsInStateWithinTolerance((complexZero,complexOne), qubits[0], 1E-05); ResetAll(qubits); } } @Test("QuantumSimulator") operation MeasureAllAndResetTest() : Unit { + let numberOfQubits = 4; + let complexOne = Complex(1.0, 0.0); + let complexZero = Complex(0.0, 0.0); + using (qubits = Qubit[numberOfQubits]) + { + X(qubits[0]); + X(qubits[2]); + let result = MeasureAllAndReset(qubits); + + EqualityFactB(result[0], true, "Expected |1> state."); + EqualityFactB(result[1], false, "Expected |0> state."); + EqualityFactB(result[2], true, "Expected |1> state."); + EqualityFactB(result[3], false, "Expected |0> state."); + + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[0], 1E-06); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[1], 1E-06); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[2], 1E-06); + AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[3], 1E-06); + + } } From 3ecf43a816fb81826bf722b843b5ddc74cee3b61 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Fri, 7 Aug 2020 20:42:01 +0200 Subject: [PATCH 26/61] Logger class added. Code refactoring. --- QAOA/src/Examples.cs | 13 +- QAOA/src/Jupyter/HybridQaoaMagic.cs | 14 +- QAOA/src/Qaoa/Utils.qs | 1 - .../{HybridQaoa => QaoaHybrid}/HybridQaoa.cs | 144 +++++++++--------- .../OptimalSolution.cs | 10 +- .../ProblemInstance.cs | 6 +- QAOA/src/QaoaHybrid/QaoaLogger.cs | 53 +++++++ QAOA/src/{HybridQaoa => QaoaHybrid}/Utils.cs | 59 +------ QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 3 +- QAOA/tests/HybridQaoaTests/UtilsTests.cs | 2 +- .../HybridQaoaProblemInstanceMagicTests.cs | 4 +- .../JupyterTests/HybridQaoaRunMagicTests.cs | 5 +- 12 files changed, 161 insertions(+), 153 deletions(-) rename QAOA/src/{HybridQaoa => QaoaHybrid}/HybridQaoa.cs (62%) rename QAOA/src/{HybridQaoa => QaoaHybrid}/OptimalSolution.cs (83%) rename QAOA/src/{HybridQaoa => QaoaHybrid}/ProblemInstance.cs (92%) create mode 100644 QAOA/src/QaoaHybrid/QaoaLogger.cs rename QAOA/src/{HybridQaoa => QaoaHybrid}/Utils.cs (65%) diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index 7f762a5a62d..7e7b981f6a9 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -1,12 +1,11 @@ -using QAOA.ClassicalOptimization; -using System; - -namespace Quantum.QAOA +namespace Quantum.QAOA { - class Examples - { + using global::QAOA.QaoaHybrid; + using System; + class Examples + { static void Main(string[] args) { //PARAMETERS @@ -61,7 +60,7 @@ static void Main(string[] args) //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, quantumSanta, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); OptimalSolution res = cop.RunOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index ee52d456db8..3e10781a2be 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -1,11 +1,11 @@ -using System; -using System.Threading.Tasks; -using Microsoft.Jupyter.Core; -using Newtonsoft.Json; -using Quantum.QAOA; - -namespace QAOA.magicCommand +namespace QAOA.Jupyter { + using System; + using System.Threading.Tasks; + using Microsoft.Jupyter.Core; + using Newtonsoft.Json; + using QAOA.QaoaHybrid; + public class HybridQaoaRunMagic : MagicSymbol { diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index 7d3a8a83a8b..23e723c5bdf 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -3,7 +3,6 @@ open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; - open Microsoft.Quantum.Diagnostics; operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] diff --git a/QAOA/src/HybridQaoa/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs similarity index 62% rename from QAOA/src/HybridQaoa/HybridQaoa.cs rename to QAOA/src/QaoaHybrid/HybridQaoa.cs index 8ebffdb0936..33b2a432095 100644 --- a/QAOA/src/HybridQaoa/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -1,41 +1,47 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Accord.Math; -using Accord.Math.Optimization; -using Microsoft.Quantum.QAOA; -using Microsoft.Quantum.Simulation.Core; -using Microsoft.Quantum.Simulation.Simulators; -using QAOA.ClassicalOptimization; - -namespace Quantum.QAOA +namespace QAOA.QaoaHybrid { - - public class HybridQaoa //currently support up to 2-local Hamiltonians; will be generalized later + using System; + using System.Collections.Generic; + using System.Linq; + using Accord.Math; + using Accord.Math.Optimization; + using Microsoft.Quantum.QAOA; + using Microsoft.Quantum.Simulation.Core; + using Microsoft.Quantum.Simulation.Simulators; + + //currently support up to 2-local Hamiltonians; will be generalized later + public class HybridQaoa { - Utils.FreeParamsVector FreeParamsVector; - int numberOfIterations; - int p; - ProblemInstance problemInstance; - Double bestHamiltonianValue; - String bestVector; - Double[] bestBeta; - Double[] bestGamma; - int numberOfRandomStartingPoints; - - - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null) + private Utils.FreeParamsVector freeParamsVector; + private int numberOfIterations; + private int p; + private ProblemInstance problemInstance; + private Double bestHamiltonianValue; + private String bestVector; + private Double[] bestBeta; + private Double[] bestGamma; + private int numberOfRandomStartingPoints; + private QaoaLogger logger; + private String loggerFilePath; + + + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null, String loggerFilePath = null) { this.numberOfIterations = numberOfIterations; this.p = p; this.problemInstance = problemInstance; - this.FreeParamsVector.beta = initialBeta; - this.FreeParamsVector.gamma = initialGamma; - bestHamiltonianValue = Double.MaxValue; - bestVector = null; + this.freeParamsVector.beta = initialBeta; + this.freeParamsVector.gamma = initialGamma; + this.bestHamiltonianValue = double.MaxValue; + this.bestVector = null; this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; + this.loggerFilePath = loggerFilePath; + if (loggerFilePath != null) + { + this.logger = new QaoaLogger(loggerFilePath); + } } @@ -43,7 +49,7 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance public Double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; - for (int i = 0; i < problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { costFunctionValue += costs[i] * Char.GetNumericValue(result[i]); } @@ -67,16 +73,16 @@ public Double EvaluateCostFunction(string result, double[] costs) public double EvaluateHamiltonian(string result) { double hamiltonianValue = 0; - for (int i = 0; i < problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { - hamiltonianValue += problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); + hamiltonianValue += this.problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); } - for (int i = 0; i < problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { - for (int j = i + 1; j < problemInstance.problemSizeInBits; j++) + for (int j = i + 1; j < this.problemInstance.problemSizeInBits; j++) { - hamiltonianValue += problemInstance.twoLocalHamiltonianCoefficients[i * problemInstance.problemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); + hamiltonianValue += this.problemInstance.twoLocalHamiltonianCoefficients[i * this.problemInstance.problemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); } } @@ -85,7 +91,7 @@ public double EvaluateHamiltonian(string result) /// # 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. + /// 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 @@ -103,29 +109,29 @@ public Double CalculateObjectiveFunction(double[] bigfreeParamsVector) var beta = new QArray(freeParamsVector.beta); var gamma = new QArray(freeParamsVector.gamma); - Utils.PrintCurrentBetaGamma(beta, gamma); - - var oneLocalHamiltonianCoefficients = new QArray(problemInstance.oneLocalHamiltonianCoefficients); - var twoLocalHamiltonianCoefficients = new QArray(problemInstance.twoLocalHamiltonianCoefficients); + var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.oneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.twoLocalHamiltonianCoefficients); using (var qsim = new QuantumSimulator()) { for (int i = 0; i < numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; + IQArray result = RunQaoa.Run(qsim, this.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); + double hamiltonianValue = this.EvaluateHamiltonian(solutionVector); + hamiltonianExpectationValue += hamiltonianValue/ this.numberOfIterations; } - } - - UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); - Utils.PrintCurrentBestSolution(this.bestHamiltonianValue, this.bestVector); + this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); + + if (this.loggerFilePath != null) + { + this.logger.LogCurrentBestSolution(beta, gamma, this.bestHamiltonianValue, this.bestVector); + } return hamiltonianExpectationValue; } @@ -143,11 +149,11 @@ private void UpdateBestSolution(double hamiltonianExpectationValue, List { if (hamiltonianExpectationValue < this.bestHamiltonianValue) { - String mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); - bestHamiltonianValue = hamiltonianExpectationValue; - bestVector = mostProbableSolutionVectorTemp; - bestBeta = freeParamsVector.beta; - bestGamma = freeParamsVector.gamma; + string mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); + this.bestHamiltonianValue = hamiltonianExpectationValue; + this.bestVector = mostProbableSolutionVectorTemp; + this.bestBeta = freeParamsVector.beta; + this.bestGamma = freeParamsVector.gamma; } } @@ -174,7 +180,6 @@ private NonlinearConstraint[] GenerateConstraints() constraints[gammaIndex + 1] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] <= 2 * Math.PI); } return constraints; - } /// # Summary @@ -185,10 +190,10 @@ private NonlinearConstraint[] GenerateConstraints() private double[] SetUpFreeParameters() { double[] betaCoefficients; - if (FreeParamsVector.beta != null) + if (this.freeParamsVector.beta != null) { - betaCoefficients = FreeParamsVector.beta; - FreeParamsVector.beta = null; + betaCoefficients = this.freeParamsVector.beta; + this.freeParamsVector.beta = null; } else { @@ -196,17 +201,17 @@ private double[] SetUpFreeParameters() } double[] gammaCoefficients; - if (FreeParamsVector.gamma != null) + if (this.freeParamsVector.gamma != null) { - gammaCoefficients = FreeParamsVector.gamma; - FreeParamsVector.gamma = null; + gammaCoefficients = this.freeParamsVector.gamma; + this.freeParamsVector.gamma = null; } else { gammaCoefficients = Utils.GetRandomVector(p, 2 * Math.PI); } - return betaCoefficients.Concat(gammaCoefficients).ToArray(); + return betaCoefficients.Concat(gammaCoefficients).ToArray(); } /// # Summary @@ -221,24 +226,27 @@ private double[] SetUpFreeParameters() public OptimalSolution RunOptimization() { - Func objectiveFunction = CalculateObjectiveFunction; - + Func objectiveFunction = this.CalculateObjectiveFunction; + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction); - NonlinearConstraint[] constraints = GenerateConstraints(); + NonlinearConstraint[] constraints = this.GenerateConstraints(); - for (int i = 0; i < numberOfRandomStartingPoints; i++) + for (int i = 0; i < this.numberOfRandomStartingPoints; i++) { var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - double[] freeParameters = SetUpFreeParameters(); + double[] freeParameters = this.SetUpFreeParameters(); bool success = cobyla.Minimize(freeParameters); - Utils.PrintSuccess(success); + + if (this.loggerFilePath != null) + { + this.logger.LogSuccess(success); + this.logger.Close(); + } } return new OptimalSolution(this.bestVector, this.bestHamiltonianValue, this.bestBeta, this.bestGamma); } - - } } diff --git a/QAOA/src/HybridQaoa/OptimalSolution.cs b/QAOA/src/QaoaHybrid/OptimalSolution.cs similarity index 83% rename from QAOA/src/HybridQaoa/OptimalSolution.cs rename to QAOA/src/QaoaHybrid/OptimalSolution.cs index 3cd67d67d4a..2f00365a8b5 100644 --- a/QAOA/src/HybridQaoa/OptimalSolution.cs +++ b/QAOA/src/QaoaHybrid/OptimalSolution.cs @@ -1,9 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace QAOA.ClassicalOptimization +namespace QAOA.QaoaHybrid { + using System; + using System.Collections.Generic; + using System.Text; + public class OptimalSolution { diff --git a/QAOA/src/HybridQaoa/ProblemInstance.cs b/QAOA/src/QaoaHybrid/ProblemInstance.cs similarity index 92% rename from QAOA/src/HybridQaoa/ProblemInstance.cs rename to QAOA/src/QaoaHybrid/ProblemInstance.cs index abab91b22e2..1839f0b9c5d 100644 --- a/QAOA/src/HybridQaoa/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/ProblemInstance.cs @@ -1,7 +1,7 @@ -using System; - -namespace Quantum.QAOA +namespace QAOA.QaoaHybrid { + using System; + public class ProblemInstance { public Double[] oneLocalHamiltonianCoefficients { get; } diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs new file mode 100644 index 00000000000..b786a02fd97 --- /dev/null +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -0,0 +1,53 @@ +namespace QAOA.QaoaHybrid +{ + using System; + using System.IO; + using Microsoft.Quantum.Simulation.Core; + + class QaoaLogger + { + private StreamWriter logger; + public QaoaLogger(string filePath = "") + { + this.logger = new StreamWriter(@filePath+"hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); + } + + /// # Summary + /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. + /// + /// # Input + /// ## bestHamiltonian + /// Best value of a Hamiltonian so far. + /// ## bestVector + /// Best solution vector that generates the above value of a Hamiltonian so far. + public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, String bestVector) + { + this.logger.WriteLine("Current beta vector:"); + this.logger.WriteLine(beta); + this.logger.WriteLine("Current gamma vector:"); + this.logger.WriteLine(gamma); + this.logger.WriteLine("Current best fidelity"); + this.logger.WriteLine(bestHamiltonian); + this.logger.WriteLine("Current best string"); + this.logger.WriteLine(bestVector); + } + + /// # Summary + /// Prints whether an optimization finished successfully. + /// + /// # Input + /// ## success + /// A flag that indiciates whether an optimization finished successfully. + public void LogSuccess(bool success) + { + this.logger.WriteLine("Was optimization successful?"); + this.logger.WriteLine(success); + this.logger.WriteLine("##################################"); + } + + public void Close() + { + this.logger.Close(); + } + } +} diff --git a/QAOA/src/HybridQaoa/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs similarity index 65% rename from QAOA/src/HybridQaoa/Utils.cs rename to QAOA/src/QaoaHybrid/Utils.cs index d61dcbe9050..aa6967c48d5 100644 --- a/QAOA/src/HybridQaoa/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -1,10 +1,9 @@ -using Microsoft.Quantum.Simulation.Core; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Quantum.QAOA +namespace QAOA.QaoaHybrid { + using System; + using System.Collections.Generic; + using System.Text; + public class Utils { @@ -125,53 +124,5 @@ public static FreeParamsVector ConvertVectorIntoHalves(double[] bigfreeParamsVec return freeParamsVector; } - - /// # Summary - /// Prints current values of beta and gamma vectors as optimization is being performed. - /// - /// # Input - /// ## beta - /// Beta vector of coefficients. - /// ## gamma - /// Gamma vector of coefficients. - public static void PrintCurrentBetaGamma(QArray beta, QArray gamma) - { - Console.WriteLine("Current beta vector:"); - Console.WriteLine(beta); - - Console.WriteLine("Current gamma vector:"); - Console.WriteLine(gamma); - - } - - /// # Summary - /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. - /// - /// # Input - /// ## bestHamiltonian - /// Best value of a Hamiltonian so far. - /// ## bestVector - /// Best solution vector that generates the above value of a Hamiltonian so far. - public static void PrintCurrentBestSolution(double bestHamiltonian, String bestVector) - { - Console.WriteLine("Current best fidelity"); - Console.WriteLine(bestHamiltonian); - Console.WriteLine("Current best string"); - Console.WriteLine(bestVector); - } - - /// # Summary - /// Prints whether an optimization finished successfully. - /// - /// # Input - /// ## success - /// A flag that indiciates whether an optimization finished successfully. - public static void PrintSuccess(bool success) - { - Console.WriteLine("Was optimization successful?"); - Console.WriteLine(success); - Console.WriteLine("##################################"); - } - } } \ No newline at end of file diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 60ba806590b..6ac96ce05e5 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -1,7 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using Quantum.QAOA; +using QAOA.QaoaHybrid; using System; -using QAOA.ClassicalOptimization; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs index 0856270e784..fe05bce294a 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/UtilsTests.cs @@ -1,5 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using Quantum.QAOA; +using QAOA.QaoaHybrid; using System.Collections.Generic; namespace Microsoft.Quantum.QAOA.HybridQaoaTests diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index fa6913901f0..45c48476362 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -6,9 +6,9 @@ using Newtonsoft.Json; using Xunit; using System; -using QAOA.magicCommand; -using Quantum.QAOA; using Microsoft.Quantum.QAOA.JupyterTests; +using QAOA.Jupyter; +using QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index d0e7a7dd9ed..341a64eb0b9 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -4,11 +4,10 @@ using System.Threading.Tasks; using Microsoft.Jupyter.Core; using Newtonsoft.Json; -using QAOA.magicCommand; -using Quantum.QAOA; using System; -using QAOA.ClassicalOptimization; using Xunit; +using QAOA.Jupyter; +using QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.JupyterTests { From 0f35f5d494f9c1a4ce708c9758eb5ce4cbc09be2 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 10:36:11 +0200 Subject: [PATCH 27/61] Code refactoring. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 2 +- QAOA/src/QaoaHybrid/HybridQaoa.cs | 2 +- QAOA/src/QaoaHybrid/QaoaLogger.cs | 24 ++++++++++--------- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 6 ++--- QAOA/tests/QaoaTests/UtilsTests.qs | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 3e10781a2be..8445370b96d 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -72,7 +72,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.InitialBeta, args.InitialGamma); + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, null, args.InitialBeta, args.InitialGamma); return hybridQaoa.RunOptimization().ToExecutionResult(); } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 33b2a432095..3942013b40e 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -26,7 +26,7 @@ public class HybridQaoa private String loggerFilePath; - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Double[] initialBeta = null, Double[] initialGamma = null, String loggerFilePath = null) + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, String loggerFilePath = null, Double[] initialBeta = null, Double[] initialGamma = null) { this.numberOfIterations = numberOfIterations; diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index b786a02fd97..7931cced0dd 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -22,14 +22,15 @@ public QaoaLogger(string filePath = "") /// Best solution vector that generates the above value of a Hamiltonian so far. public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, String bestVector) { - this.logger.WriteLine("Current beta vector:"); - this.logger.WriteLine(beta); - this.logger.WriteLine("Current gamma vector:"); - this.logger.WriteLine(gamma); - this.logger.WriteLine("Current best fidelity"); - this.logger.WriteLine(bestHamiltonian); - this.logger.WriteLine("Current best string"); - this.logger.WriteLine(bestVector); + + this.logger.WriteLine("Current beta vector:"); + this.logger.WriteLine(beta); + this.logger.WriteLine("Current gamma vector:"); + this.logger.WriteLine(gamma); + this.logger.WriteLine("Current best fidelity"); + this.logger.WriteLine(bestHamiltonian); + this.logger.WriteLine("Current best string"); + this.logger.WriteLine(bestVector); } /// # Summary @@ -40,9 +41,10 @@ public void LogCurrentBestSolution(QArray beta, QArray gamma, do /// A flag that indiciates whether an optimization finished successfully. public void LogSuccess(bool success) { - this.logger.WriteLine("Was optimization successful?"); - this.logger.WriteLine(success); - this.logger.WriteLine("##################################"); + this.logger.WriteLine("Was optimization successful?"); + this.logger.WriteLine(success); + this.logger.WriteLine("##################################"); + } public void Close() diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 6ac96ce05e5..7d291e7c665 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -15,7 +15,7 @@ public void ConvertDataVectorToVectorsTest() ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); @@ -35,7 +35,7 @@ public void EvaluateHamiltonianTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); Double result = classicalOptimization.EvaluateHamiltonian("0011"); @@ -50,7 +50,7 @@ public void EvaluateCostFunctionTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, new double[] { 2 }, new double[] { 3 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, null, new double[] { 2 }, new double[] { 3 }); string optimizationResult = "0101"; diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs index 7b8a2628c2f..229921a9871 100644 --- a/QAOA/tests/QaoaTests/UtilsTests.qs +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -28,7 +28,7 @@ namespace Microsoft.Quantum.Tests { } @Test("QuantumSimulator") - operation RunPhaseKickbackTest2() : Unit { + operation RunPhaseKickbackOneControlQubitTest() : Unit { let numberOfQubits = 1; let ancillaQubits = 1; From 63acbd41558874a7aeb4ad711a0d27525e101e11 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 10:41:32 +0200 Subject: [PATCH 28/61] Code refactoring. --- QAOA/src/QaoaHybrid/HybridQaoa.cs | 14 ++++++++++++-- QAOA/src/QaoaHybrid/QaoaLogger.cs | 7 +++++-- QAOA/src/QaoaHybrid/Utils.cs | 4 ---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 3942013b40e..e0b35f11797 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -45,7 +45,18 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance } - + /// # Summary + /// Calculates the value of the cost function based on costs provided. + /// + /// # Input + /// ## result + /// A binary string. In this context it is a result that we get after measuring the QAOA state. + /// + /// ## costs + /// A list of costs for the cost function. + /// + /// # Output + /// The value of the costfunction. public Double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; @@ -69,7 +80,6 @@ public Double EvaluateCostFunction(string result, double[] costs) /// /// # Remarks /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. - public double EvaluateHamiltonian(string result) { double hamiltonianValue = 0; diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 7931cced0dd..f2c2e80e8be 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -7,13 +7,14 @@ class QaoaLogger { private StreamWriter logger; + public QaoaLogger(string filePath = "") { this.logger = new StreamWriter(@filePath+"hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); } /// # Summary - /// Prints current values of the best fidelity and the best solution vector as optimization is being performed. + /// Writes current values of the best fidelity and the best solution vector to a file. /// /// # Input /// ## bestHamiltonian @@ -34,7 +35,7 @@ public void LogCurrentBestSolution(QArray beta, QArray gamma, do } /// # Summary - /// Prints whether an optimization finished successfully. + /// Writes to a file whether an optimization finished successfully. /// /// # Input /// ## success @@ -47,6 +48,8 @@ public void LogSuccess(bool success) } + /// # Summary + /// Closes a logger. public void Close() { this.logger.Close(); diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs index aa6967c48d5..cb9b66548bc 100644 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -24,7 +24,6 @@ public struct FreeParamsVector /// /// # Output /// A random vector of doubles. - public static double[] GetRandomVector(int length, double maximumValue) { var rand = new Random(); @@ -46,7 +45,6 @@ public static double[] GetRandomVector(int length, double maximumValue) /// /// # Output /// The most common boolean string. - public static String GetModeFromBoolList(List list) { Dictionary counter = new Dictionary(); @@ -86,7 +84,6 @@ public static String GetModeFromBoolList(List list) /// /// # Output /// A boolean string. - public static string GetBoolStringFromBoolArray(bool[] boolArray) { System.Text.StringBuilder sb = new StringBuilder(); @@ -109,7 +106,6 @@ public static string GetBoolStringFromBoolArray(bool[] boolArray) /// /// # Remarks /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. - public static FreeParamsVector ConvertVectorIntoHalves(double[] bigfreeParamsVector) { int size = bigfreeParamsVector.Length; From 172a9d99bd4ffa265ada778969dce5a934629d83 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 11:03:45 +0200 Subject: [PATCH 29/61] Code refactoring. --- QAOA/src/Examples.cs | 2 +- QAOA/src/Jupyter/HybridQaoaMagic.cs | 8 +++++++- QAOA/src/QaoaHybrid/HybridQaoa.cs | 15 +++++++-------- QAOA/src/QaoaHybrid/QaoaLogger.cs | 5 +++-- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 6 +++--- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index 7e7b981f6a9..d888ef62d6a 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -60,7 +60,7 @@ static void Main(string[] args) //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints); + HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints, true); OptimalSolution res = cop.RunOptimization(); Console.WriteLine(res.optimalVector); diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 8445370b96d..8249e9739ae 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -46,6 +46,12 @@ public class Arguments [JsonProperty(PropertyName = "number_of_random_starting_points")] public int NumberOfRandomStartingPoints { get; set; } = 1; + /// + /// Flag whether optimization should be logged into a file. + /// + [JsonProperty(PropertyName = "should_log")] + public Boolean ShouldLog { get; set; } = false; + /// /// Initial beta angles. /// @@ -72,7 +78,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, null, args.InitialBeta, args.InitialGamma); + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.ShouldLog, args.InitialBeta, args.InitialGamma); return hybridQaoa.RunOptimization().ToExecutionResult(); } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index e0b35f11797..fac409942ff 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -23,10 +23,9 @@ public class HybridQaoa private Double[] bestGamma; private int numberOfRandomStartingPoints; private QaoaLogger logger; - private String loggerFilePath; + private Boolean shouldLog; - - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, String loggerFilePath = null, Double[] initialBeta = null, Double[] initialGamma = null) + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Boolean shouldLog = false, Double[] initialBeta = null, Double[] initialGamma = null) { this.numberOfIterations = numberOfIterations; @@ -37,10 +36,10 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance this.bestHamiltonianValue = double.MaxValue; this.bestVector = null; this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; - this.loggerFilePath = loggerFilePath; - if (loggerFilePath != null) + this.shouldLog = shouldLog; + if (shouldLog) { - this.logger = new QaoaLogger(loggerFilePath); + this.logger = new QaoaLogger(); } } @@ -138,7 +137,7 @@ public Double CalculateObjectiveFunction(double[] bigfreeParamsVector) this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); - if (this.loggerFilePath != null) + if (this.shouldLog) { this.logger.LogCurrentBestSolution(beta, gamma, this.bestHamiltonianValue, this.bestVector); } @@ -248,7 +247,7 @@ public OptimalSolution RunOptimization() double[] freeParameters = this.SetUpFreeParameters(); bool success = cobyla.Minimize(freeParameters); - if (this.loggerFilePath != null) + if (this.shouldLog) { this.logger.LogSuccess(success); this.logger.Close(); diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index f2c2e80e8be..7698f802405 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -8,9 +8,10 @@ class QaoaLogger { private StreamWriter logger; - public QaoaLogger(string filePath = "") + public QaoaLogger() { - this.logger = new StreamWriter(@filePath+"hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); + + this.logger = new StreamWriter("hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); } /// # Summary diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 7d291e7c665..766e04a2a27 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -15,7 +15,7 @@ public void ConvertDataVectorToVectorsTest() ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); @@ -35,7 +35,7 @@ public void EvaluateHamiltonianTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, null, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); Double result = classicalOptimization.EvaluateHamiltonian("0011"); @@ -50,7 +50,7 @@ public void EvaluateCostFunctionTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, null, new double[] { 2 }, new double[] { 3 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, false, new double[] { 2 }, new double[] { 3 }); string optimizationResult = "0101"; From fe3a9684a12764c2ef465f52a48e5295d65ac64b Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 11:46:57 +0200 Subject: [PATCH 30/61] gitignore update --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 99d456ffa56..b815351418e 100644 --- a/.gitignore +++ b/.gitignore @@ -329,5 +329,3 @@ __pycache__/ *.btm.cs *.odx.cs *.xsd.cs - -/QAOA/QAOATest/MagicCommandTests/sample.py From 45c75f76df271a42ad3d859bc805e0571c5e7c25 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 11:49:31 +0200 Subject: [PATCH 31/61] Unnecessary files removed. --- QAOA/.gitattributes | 63 -------- QAOA/.gitignore | 340 -------------------------------------------- QAOA/README.md | 30 ---- 3 files changed, 433 deletions(-) delete mode 100644 QAOA/.gitattributes delete mode 100644 QAOA/.gitignore delete mode 100644 QAOA/README.md diff --git a/QAOA/.gitattributes b/QAOA/.gitattributes deleted file mode 100644 index 1ff0c423042..00000000000 --- a/QAOA/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain diff --git a/QAOA/.gitignore b/QAOA/.gitignore deleted file mode 100644 index 4ce6fddec96..00000000000 --- a/QAOA/.gitignore +++ /dev/null @@ -1,340 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- Backup*.rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file diff --git a/QAOA/README.md b/QAOA/README.md deleted file mode 100644 index 3a2eb847794..00000000000 --- a/QAOA/README.md +++ /dev/null @@ -1,30 +0,0 @@ -[![Unitary Fund](https://img.shields.io/badge/Supported%20By-UNITARY%20FUND-brightgreen.svg?style=for-the-badge)](http://unitary.fund) - -# QAOA in Q# - -The project is still in progress. This readme will be extended as the project develops. - -This project provides a hybrid quantum-classical algorithm for solving optimization problems. -It includes a Q# implementation of the Quantum Approximate Optimization Algorithm ([QAOA](https://arxiv.org/abs/1411.4028)) together with a classical optimizer in C#. -The classical optimizer uses a quantum objective function to choose hopefully optimal parameters for running the QAOA. -The quantum objective function is currently evaluated on a simulator backend provided by Q#. - -How to run it? -1) Import this project to Microsoft Visual Studio or similar. -2) Use Driver.cs to prepare your ProblemInstance and run the project (some examples also provided). - -Current limitations: - -- an optimization problem shall be encoded into a Hamiltonian consisting of Z operators, -- support for up to 2-local Hamiltonians, -- input consists of arrays of coefficients for 1-local and 2-local Hamiltonian terms, -- a gradient-free Cobyla optimizer is used for finding good QAOA input parameters. - -The high-level diagram of the implementation (notation comes from the [QAOA paper](https://arxiv.org/abs/1411.4028)): - -[![QAOA diagram](https://i.postimg.cc/sgryqr80/IMG-0202.jpg)](https://postimg.cc/XpQTBTnw) - -Dependencies: - -1) [Q# and Microsoft Quantum Libraries](https://docs.microsoft.com/en-us/quantum/language/) -2) [C# Accord Math library](http://accord-framework.net/docs/html/N_Accord_Math.htm) From 4edf93ad8f7f3a2641c213973a1fef02019f5245 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 12:47:40 +0200 Subject: [PATCH 32/61] Files added. --- QAOA/.gitattributes | 63 ++++++++ QAOA/.gitignore | 340 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 QAOA/.gitattributes create mode 100644 QAOA/.gitignore diff --git a/QAOA/.gitattributes b/QAOA/.gitattributes new file mode 100644 index 00000000000..1ff0c423042 --- /dev/null +++ b/QAOA/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/QAOA/.gitignore b/QAOA/.gitignore new file mode 100644 index 00000000000..4ce6fddec96 --- /dev/null +++ b/QAOA/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file From 915d62c8a46c3d0c4dbb37af8023d38c8e60a3c2 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 13:15:30 +0200 Subject: [PATCH 33/61] Documentation extended. --- QAOA/src/Qaoa/Utils.qs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index 23e723c5bdf..715129f7479 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -4,6 +4,15 @@ open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; + /// # Summary + /// Measures all qubits and resets them. + /// + /// # Input + /// ## qubits + /// Qubits to be measured. + /// + /// # Output + /// Results of the measurement. operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] { @@ -16,6 +25,19 @@ return results; } + /// # Summary + /// Runs a phase kickback routine on an ancilla qubit given indices of control qubits and a phase. + /// + /// # Input + /// ## qubits + /// Qubits that are to aquire a phase. + /// ## ancillaQubit + /// Ancilla qubit. + /// ## controlQubitsIndices + /// List of indices of control qubits. + /// ## phaseExponent + /// Phase to be applied. + operation RunPhaseKickback(qubits: Qubit[], ancillaQubit: Qubit[], controlQubitsIndices: Int[], phaseExponent: Double) : Unit { for(i in 0..Length(controlQubitsIndices)-1) From 2b6f42990f40bdddb4de9f948047b1792da73c4f Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 14:24:21 +0200 Subject: [PATCH 34/61] QAOA.sln modfied. --- QAOA.sln | 1 - 1 file changed, 1 deletion(-) diff --git a/QAOA.sln b/QAOA.sln index 3bfbe8607d4..67e820e4bf3 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -46,7 +46,6 @@ Global {1623F038-210A-4BA2-8D4E-9AF611610829} = {80082123-4392-4F0E-8F87-26183C620693} {3C8B4AF6-5495-4F23-B7B2-634E5A667837} = {80082123-4392-4F0E-8F87-26183C620693} {208C0012-D62F-4F29-8738-394A62BBE842} = {80082123-4392-4F0E-8F87-26183C620693} - {AD73B607-0EF5-4C11-8832-22D584939780} = {A6612841-F6D1-4A8E-A8F8-4430F9FF7992} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {09481F99-E1AC-44CE-A892-7331820661DF} From a33c6aad36c9b8d19598c1a1ae8144705811475f Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 17:56:59 +0200 Subject: [PATCH 35/61] Removed unnecessary files. --- QAOA/.gitattributes | 63 -------- QAOA/.gitignore | 340 -------------------------------------------- 2 files changed, 403 deletions(-) delete mode 100644 QAOA/.gitattributes delete mode 100644 QAOA/.gitignore diff --git a/QAOA/.gitattributes b/QAOA/.gitattributes deleted file mode 100644 index 1ff0c423042..00000000000 --- a/QAOA/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain diff --git a/QAOA/.gitignore b/QAOA/.gitignore deleted file mode 100644 index 4ce6fddec96..00000000000 --- a/QAOA/.gitignore +++ /dev/null @@ -1,340 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- Backup*.rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file From 7c189c520be608eb9758f7bf48643e0b20a434bc Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 18:49:33 +0200 Subject: [PATCH 36/61] Code refactoring. --- QAOA/src/Examples.cs | 6 +- QAOA/src/Jupyter/HybridQaoaMagic.cs | 2 +- QAOA/src/QaoaHybrid/HybridQaoa.cs | 72 +++++++++---------- QAOA/src/QaoaHybrid/OptimalSolution.cs | 14 ++-- QAOA/src/QaoaHybrid/ProblemInstance.cs | 8 +-- QAOA/src/QaoaHybrid/QaoaLogger.cs | 10 ++- QAOA/src/QaoaHybrid/Utils.cs | 12 ++-- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 18 ++--- QAOA/tests/HybridQaoaTests/UtilsTests.cs | 2 +- .../HybridQaoaProblemInstanceMagicTests.cs | 2 +- .../JupyterTests/HybridQaoaRunMagicTests.cs | 2 +- 11 files changed, 75 insertions(+), 73 deletions(-) diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index d888ef62d6a..40d6c2ca737 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -1,6 +1,8 @@ -namespace Quantum.QAOA + + +namespace Quantum.QAOA { - using global::QAOA.QaoaHybrid; + using Microsoft.Quantum.QAOA.QaoaHybrid; using System; diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 8249e9739ae..ea4eb70173b 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -3,8 +3,8 @@ using System; using System.Threading.Tasks; using Microsoft.Jupyter.Core; + using Microsoft.Quantum.QAOA.QaoaHybrid; using Newtonsoft.Json; - using QAOA.QaoaHybrid; public class HybridQaoaRunMagic : MagicSymbol { diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index fac409942ff..76edf222e26 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -1,12 +1,10 @@ -namespace QAOA.QaoaHybrid +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; using System.Collections.Generic; using System.Linq; - using Accord.Math; using Accord.Math.Optimization; - using Microsoft.Quantum.QAOA; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; @@ -14,18 +12,18 @@ public class HybridQaoa { private Utils.FreeParamsVector freeParamsVector; - private int numberOfIterations; - private int p; - private ProblemInstance problemInstance; - private Double bestHamiltonianValue; - private String bestVector; - private Double[] bestBeta; - private Double[] bestGamma; - private int numberOfRandomStartingPoints; - private QaoaLogger logger; - private Boolean shouldLog; - - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, Boolean shouldLog = false, Double[] initialBeta = null, Double[] initialGamma = null) + private readonly int numberOfIterations; + private readonly int p; + private readonly ProblemInstance problemInstance; + private double bestHamiltonianValue; + private string bestVector; + private double[] bestBeta; + private double[] bestGamma; + private readonly int numberOfRandomStartingPoints; + private readonly QaoaLogger logger; + private readonly bool shouldLog; + + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, bool shouldLog = false, double[] initialBeta = null, double[] initialGamma = null) { this.numberOfIterations = numberOfIterations; @@ -56,12 +54,12 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance /// /// # Output /// The value of the costfunction. - public Double EvaluateCostFunction(string result, double[] costs) + public double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { - costFunctionValue += costs[i] * Char.GetNumericValue(result[i]); + costFunctionValue += costs[i] * char.GetNumericValue(result[i]); } return costFunctionValue; @@ -84,14 +82,14 @@ public double EvaluateHamiltonian(string result) double hamiltonianValue = 0; for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { - hamiltonianValue += this.problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * Char.GetNumericValue(result[i])); + hamiltonianValue += this.problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * char.GetNumericValue(result[i])); } for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) { for (int j = i + 1; j < this.problemInstance.problemSizeInBits; j++) { - hamiltonianValue += this.problemInstance.twoLocalHamiltonianCoefficients[i * this.problemInstance.problemSizeInBits + j] * (1 - 2 * Char.GetNumericValue(result[i])) * (1 - 2 * Char.GetNumericValue(result[j])); + hamiltonianValue += this.problemInstance.twoLocalHamiltonianCoefficients[i * this.problemInstance.problemSizeInBits + j] * (1 - 2 * char.GetNumericValue(result[i])) * (1 - 2 * char.GetNumericValue(result[j])); } } @@ -101,7 +99,7 @@ public double EvaluateHamiltonian(string result) /// # 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. + /// 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 @@ -109,28 +107,28 @@ public double EvaluateHamiltonian(string result) /// /// # Output /// The expected value of a Hamiltonian that we calculated in this run. - public Double CalculateObjectiveFunction(double[] bigfreeParamsVector) + public double CalculateObjectiveFunction(double[] bigfreeParamsVector) { Utils.FreeParamsVector freeParamsVector = Utils.ConvertVectorIntoHalves(bigfreeParamsVector); double hamiltonianExpectationValue = 0; List allSolutionVectors = new List(); - var beta = new QArray(freeParamsVector.beta); - var gamma = new QArray(freeParamsVector.gamma); + var beta = new QArray(freeParamsVector.beta); + var gamma = new QArray(freeParamsVector.gamma); - var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.oneLocalHamiltonianCoefficients); - var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.twoLocalHamiltonianCoefficients); + var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.oneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.twoLocalHamiltonianCoefficients); using (var qsim = new QuantumSimulator()) { - for (int i = 0; i < numberOfIterations; i++) + for (int i = 0; i < this.numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, this.problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, p).Result; + IQArray result = RunQaoa.Run(qsim, this.problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; allSolutionVectors.Add(result.ToArray()); string solutionVector = Utils.GetBoolStringFromBoolArray(result.ToArray()); double hamiltonianValue = this.EvaluateHamiltonian(solutionVector); - hamiltonianExpectationValue += hamiltonianValue/ this.numberOfIterations; + hamiltonianExpectationValue += hamiltonianValue / this.numberOfIterations; } } @@ -179,14 +177,14 @@ private void UpdateBestSolution(double hamiltonianExpectationValue, List private NonlinearConstraint[] GenerateConstraints() { - NonlinearConstraint[] constraints = new NonlinearConstraint[4*p]; - foreach (var i in Enumerable.Range(0, p).Select(x => x * 2)) + NonlinearConstraint[] constraints = new NonlinearConstraint[4*this.p]; + foreach (var i in Enumerable.Range(0, this.p).Select(x => x * 2)) { int gammaIndex = 2 * p + i; - constraints[i] = new NonlinearConstraint(2 * p, x => x[i/2] >= 0); - constraints[i + 1] = new NonlinearConstraint(2 * p, x => x[i/2] <= Math.PI); + constraints[i] = new NonlinearConstraint(2 * p, x => x[i / 2] >= 0); + constraints[i + 1] = new NonlinearConstraint(2 * p, x => x[i / 2] <= Math.PI); constraints[gammaIndex] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] >= 0); - constraints[gammaIndex + 1] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] <= 2 * Math.PI); + constraints[gammaIndex + 1] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] <= 2 * Math.PI); } return constraints; } @@ -206,7 +204,7 @@ private double[] SetUpFreeParameters() } else { - betaCoefficients = Utils.GetRandomVector(p, Math.PI); + betaCoefficients = Utils.GetRandomVector(this.p, Math.PI); } double[] gammaCoefficients; @@ -217,7 +215,7 @@ private double[] SetUpFreeParameters() } else { - gammaCoefficients = Utils.GetRandomVector(p, 2 * Math.PI); + gammaCoefficients = Utils.GetRandomVector(this.p, 2 * Math.PI); } return betaCoefficients.Concat(gammaCoefficients).ToArray(); @@ -235,9 +233,9 @@ private double[] SetUpFreeParameters() public OptimalSolution RunOptimization() { - Func objectiveFunction = this.CalculateObjectiveFunction; + Func objectiveFunction = this.CalculateObjectiveFunction; - var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction); + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); NonlinearConstraint[] constraints = this.GenerateConstraints(); diff --git a/QAOA/src/QaoaHybrid/OptimalSolution.cs b/QAOA/src/QaoaHybrid/OptimalSolution.cs index 2f00365a8b5..9385df05054 100644 --- a/QAOA/src/QaoaHybrid/OptimalSolution.cs +++ b/QAOA/src/QaoaHybrid/OptimalSolution.cs @@ -1,18 +1,16 @@ -namespace QAOA.QaoaHybrid +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; - using System.Collections.Generic; - using System.Text; public class OptimalSolution { - public String optimalVector { get; } - public Double optimalValue { get; } - public Double[] optimalBeta { get; } - public Double[] optimalGamma { get; } + public string optimalVector { get; } + public double optimalValue { get; } + public double[] optimalBeta { get; } + public double[] optimalGamma { get; } - public OptimalSolution(String optimalVector, Double optimalValue, Double[] optimalBeta, Double[] optimalGamma) + public OptimalSolution(string optimalVector, double optimalValue, double[] optimalBeta, double[] optimalGamma) { this.optimalVector = optimalVector; this.optimalValue = optimalValue; diff --git a/QAOA/src/QaoaHybrid/ProblemInstance.cs b/QAOA/src/QaoaHybrid/ProblemInstance.cs index 1839f0b9c5d..485620fd01d 100644 --- a/QAOA/src/QaoaHybrid/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/ProblemInstance.cs @@ -1,14 +1,14 @@ -namespace QAOA.QaoaHybrid +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; public class ProblemInstance { - public Double[] oneLocalHamiltonianCoefficients { get; } - public Double[] twoLocalHamiltonianCoefficients { get; } + public double[] oneLocalHamiltonianCoefficients { get; } + public double[] twoLocalHamiltonianCoefficients { get; } public int problemSizeInBits { get; } - public ProblemInstance(Double[] oneLocalHamiltonianCoefficients, Double[] twoLocalHamiltonianCoefficients) + public ProblemInstance(double[] oneLocalHamiltonianCoefficients, double[] twoLocalHamiltonianCoefficients) { this.oneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; this.twoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 7698f802405..6fa166b2eea 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -1,4 +1,4 @@ -namespace QAOA.QaoaHybrid +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; using System.IO; @@ -6,7 +6,7 @@ class QaoaLogger { - private StreamWriter logger; + private readonly StreamWriter logger; public QaoaLogger() { @@ -18,11 +18,15 @@ public QaoaLogger() /// Writes current values of the best fidelity and the best solution vector to a file. /// /// # Input + /// ## beta + /// Best beta vector so far. + /// ## gamma + /// Best gamma vector so far. /// ## bestHamiltonian /// Best value of a Hamiltonian so far. /// ## bestVector /// Best solution vector that generates the above value of a Hamiltonian so far. - public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, String bestVector) + public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, string bestVector) { this.logger.WriteLine("Current beta vector:"); diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs index cb9b66548bc..07107e44a31 100644 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -1,4 +1,4 @@ -namespace QAOA.QaoaHybrid +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; using System.Collections.Generic; @@ -9,8 +9,8 @@ public class Utils public struct FreeParamsVector { - public Double[] beta; - public Double[] gamma; + public double[] beta; + public double[] gamma; } /// # Summary @@ -45,12 +45,12 @@ public static double[] GetRandomVector(int length, double maximumValue) /// /// # Output /// The most common boolean string. - public static String GetModeFromBoolList(List list) + public static string GetModeFromBoolList(List list) { Dictionary counter = new Dictionary(); foreach (bool[] boolArray in list) { - String boolString = GetBoolStringFromBoolArray(boolArray); + string boolString = GetBoolStringFromBoolArray(boolArray); if (counter.ContainsKey(boolString)) { counter[boolString] += 1; @@ -62,7 +62,7 @@ public static String GetModeFromBoolList(List list) } int maximum = 0; - String result = null; + string result = null; foreach (string key in counter.Keys) { if (counter[key] > maximum) diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 766e04a2a27..ff25a1b31ad 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -1,6 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using QAOA.QaoaHybrid; using System; +using Microsoft.Quantum.QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { @@ -15,7 +15,7 @@ public void ConvertDataVectorToVectorsTest() ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 } ); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 } ); Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); @@ -35,11 +35,11 @@ public void EvaluateHamiltonianTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new Double[] { 1, 2, 3 }, new Double[] { 4, 5, 6 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 }); - Double result = classicalOptimization.EvaluateHamiltonian("0011"); + double result = classicalOptimization.EvaluateHamiltonian("0011"); - Double expectedResult = -1; + double expectedResult = -1; Assert.AreEqual(expectedResult, result, "Hamiltonian value not calculated correctly."); @@ -55,9 +55,9 @@ public void EvaluateCostFunctionTest() string optimizationResult = "0101"; - Double result = classicalOptimization.EvaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); + double result = classicalOptimization.EvaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); - Double expectedResult = 4; + double expectedResult = 4; Assert.AreEqual(expectedResult, result, "Cost function not calculated correctly."); @@ -67,8 +67,8 @@ public void EvaluateCostFunctionTest() [TestMethod] public void RunHybridQaoaTest() { - double[] dh = new Double[] { 0, 0 }; - double[] dJ = new Double[]{ 0, 1, + double[] dh = new double[] { 0, 0 }; + double[] dJ = new double[]{ 0, 1, 0, 0}; int numberOfIterations = 50; diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs index fe05bce294a..5095d551b21 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/UtilsTests.cs @@ -1,6 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using QAOA.QaoaHybrid; using System.Collections.Generic; +using Microsoft.Quantum.QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index 45c48476362..be02624c796 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -7,8 +7,8 @@ using Xunit; using System; using Microsoft.Quantum.QAOA.JupyterTests; +using Microsoft.Quantum.QAOA.QaoaHybrid; using QAOA.Jupyter; -using QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 341a64eb0b9..df62cfc1e84 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -5,9 +5,9 @@ using Microsoft.Jupyter.Core; using Newtonsoft.Json; using System; +using Microsoft.Quantum.QAOA.QaoaHybrid; using Xunit; using QAOA.Jupyter; -using QAOA.QaoaHybrid; namespace Microsoft.Quantum.QAOA.JupyterTests { From c5a7f81eac986439e08688fa38e398b88fd4928e Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 8 Aug 2020 18:54:03 +0200 Subject: [PATCH 37/61] Code refactoring. --- QAOA/src/QaoaHybrid/HybridQaoa.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 76edf222e26..0d85195fe7a 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -107,7 +107,7 @@ public double EvaluateHamiltonian(string result) /// /// # Output /// The expected value of a Hamiltonian that we calculated in this run. - public double CalculateObjectiveFunction(double[] bigfreeParamsVector) + private double CalculateObjectiveFunction(double[] bigfreeParamsVector) { Utils.FreeParamsVector freeParamsVector = Utils.ConvertVectorIntoHalves(bigfreeParamsVector); double hamiltonianExpectationValue = 0; From edfc71ecf28f21adf20a39f076b5048d01a2f361 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Mon, 10 Aug 2020 13:05:25 +0200 Subject: [PATCH 38/61] Logger closing fix. --- QAOA/src/Qaoa/QaoaRunner.qs | 10 +++++----- QAOA/src/QaoaHybrid/HybridQaoa.cs | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index 5bd0334b73a..1fff30b1ce6 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -31,15 +31,15 @@ { mutable result = new Bool[problemSize]; - using (x = Qubit[problemSize]) + using (qubits = Qubit[problemSize]) { - ApplyToEach(H, x); // prepare the uniform distribution + ApplyToEach(H, qubits); for (i in 0..p-1) { - EvolveWithObjectiveHamiltonian(x, gamma[i], h, J); // do Exp(-i H_C tz[i]) - EvolveWithMixingHamiltonian(x, beta[i]); // do Exp(-i H_0 tx[i]) + EvolveWithObjectiveHamiltonian(qubits, gamma[i], h, J); + EvolveWithMixingHamiltonian(qubits, beta[i]); } - set result = MeasureAllAndReset(x); // measure in the computational basis + set result = MeasureAllAndReset(qubits); } return result; } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 0d85195fe7a..39ddbe5539b 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -248,11 +248,13 @@ public OptimalSolution RunOptimization() if (this.shouldLog) { this.logger.LogSuccess(success); - this.logger.Close(); } } - + if (this.shouldLog) + { + this.logger.Close(); + } return new OptimalSolution(this.bestVector, this.bestHamiltonianValue, this.bestBeta, this.bestGamma); } } From a664bd6671364557c9b2cd3999fb2b510a5fe278 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Tue, 11 Aug 2020 11:55:23 +0200 Subject: [PATCH 39/61] Code review edits. --- Build/test.ps1 | 2 +- QAOA/src/Examples.cs | 51 +++++++++---------- QAOA/src/Jupyter/HybridQaoaMagic.cs | 5 +- QAOA/src/QAOA.csproj | 2 +- ...Hamiltonians.qs => EvolutionOperations.qs} | 44 +++++++--------- QAOA/src/Qaoa/QaoaRunner.qs | 21 ++++---- QAOA/src/Qaoa/Utils.qs | 34 ++++++------- QAOA/src/QaoaHybrid/HybridQaoa.cs | 32 ++++++------ QAOA/src/QaoaHybrid/OptimalSolution.cs | 21 ++++---- QAOA/src/QaoaHybrid/ProblemInstance.cs | 17 ++++--- QAOA/src/QaoaHybrid/QaoaLogger.cs | 5 +- QAOA/src/QaoaHybrid/Utils.cs | 5 +- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 10 ++-- QAOA/tests/HybridQaoaTests/UtilsTests.cs | 6 ++- .../HybridQaoaProblemInstanceMagicTests.cs | 17 +++---- .../JupyterTests/HybridQaoaRunMagicTests.cs | 11 ++-- QAOA/tests/JupyterTests/MockChannel.cs | 4 +- QAOA/tests/QaoaTests/UtilsTests.qs | 37 ++++++-------- 18 files changed, 161 insertions(+), 163 deletions(-) rename QAOA/src/Qaoa/{Hamiltonians.qs => EvolutionOperations.qs} (52%) diff --git a/Build/test.ps1 b/Build/test.ps1 index ca544930561..088b204b0aa 100644 --- a/Build/test.ps1 +++ b/Build/test.ps1 @@ -41,7 +41,7 @@ Write-Host "##[info]Testing Numerics/tests/NumericsTests.csproj" Test-One '../Numerics/tests/NumericsTests.csproj' Write-Host "##[info]Testing QAOA/tests/QaoaTests/QaoaTests.csproj" -Test-One '../QAOA/tests//QaoaTests/QaoaTests.csproj' +Test-One '../QAOA/tests/QaoaTests/QaoaTests.csproj' Write-Host "##[info]Testing QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj" Test-One '../QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj' diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index 40d6c2ca737..5ac3d4508be 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -1,4 +1,5 @@ - +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. namespace Quantum.QAOA { @@ -11,61 +12,57 @@ class Examples static void Main(string[] args) { //PARAMETERS - int numberOfIterations = 50; - int p = 3; - int numberOfRandomStartingPoints = 1; + var numberOfIterations = 70; + var p = 5; + var numberOfRandomStartingPoints = 1; //EXAMPLES //Quantum Santa (http://quantumalgorithmzoo.org/traveling_santa/) double[] dtx = { 0.619193, 0.742566, 0.060035, -1.568955, 0.045490 }; double[] dtz = { 3.182203, -1.139045, 0.221082, 0.537753, -0.417222 }; - double[] segmentCosts = { 4.70, 9.09, 9.03, 5.70, 8.02, 1.71 }; - double[] dh = { 4 * 20 - 0.5 * 4.7, 4 * 20 - 0.5 * 9.09, 4 * 20 - 0.5 * 9.03, 4 * 20 - 0.5 * 5.70, 4 * 20 - 0.5 * 8.02, 4 * 20 - 0.5 * 1.71 }; - double[] dJ = { 40.0,40.0,20.0,40.0,40.0,40.0, + double[] oneLocalHamiltonianCoefficients = { 4 * 20 - 0.5 * 4.7, 4 * 20 - 0.5 * 9.09, 4 * 20 - 0.5 * 9.03, 4 * 20 - 0.5 * 5.70, 4 * 20 - 0.5 * 8.02, 4 * 20 - 0.5 * 1.71 }; + double[] twoLocalHamiltonianCoefficients = { 40.0,40.0,20.0,40.0,40.0,40.0, 40.0,40.0,40.0,20.0,40.0,40.0, 40.0,40.0,40.0,40.0,40.0,40.0, 40.0,40.0,40.0,40.0,40.0,40.0, 40.0,40.0,40.0,40.0,40.0,20.0, 40.0,40.0,40.0,40.0,40.0,40.0}; - ProblemInstance quantumSanta = new ProblemInstance(dh, dJ); + var quantumSanta = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); + double[] segmentCosts = { 4.70, 9.09, 9.03, 5.70, 8.02, 1.71 }; //MaxCut (medium.com/mdr-inc/qaoa-maxcut-using-blueqat-aaf33038f46e) - dh = new Double[] { 0,0,0,0,0}; - dJ = new Double[]{ 0,1,0,1,0, + oneLocalHamiltonianCoefficients = new Double[] { 0,0,0,0,0}; + twoLocalHamiltonianCoefficients = new Double[]{ 0,1,0,1,0, 0,0,1,0,0, 0,0,0,1,1, 0,0,0,0,1, 0,0,0,0,0}; - ProblemInstance maxCut1 = new ProblemInstance(dh, dJ); - + var maxCut1 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); //Rigetti MaxCut unit tests - dh = new Double[]{-0.5,0,-1,0.5}; - dJ = new Double[]{0,1,2,0, + oneLocalHamiltonianCoefficients = new Double[]{-0.5,0,-1,0.5}; + twoLocalHamiltonianCoefficients = new Double[]{0,1,2,0, 0,0,0.5,0, 0,0,0,2.5, 0,0,0,0}; - ProblemInstance maxCut2 = new ProblemInstance(dh, dJ); + var maxCut2 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - - dh = new Double[] { 0.8, -0.5 }; - dJ = new Double[]{ 0, -1, - 0, 0}; - ProblemInstance maxCut3 = new ProblemInstance(dh, dJ); + oneLocalHamiltonianCoefficients = new Double[] { 0.8, -0.5 }; + twoLocalHamiltonianCoefficients = new Double[]{ 0, -1, 0, 0}; + var maxCut3 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - dh = new Double[] {0, 0 }; - dJ = new Double[]{ 0, 1, - 0, 0}; - ProblemInstance maxCut4 = new ProblemInstance(dh, dJ); + oneLocalHamiltonianCoefficients = new Double[] {0, 0 }; + twoLocalHamiltonianCoefficients = new Double[]{ 0, 1, 0, 0}; + var maxCut4 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); //END EXAMPLES - HybridQaoa cop = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints, true); + var hybridQaoa = new HybridQaoa(numberOfIterations, p, quantumSanta, numberOfRandomStartingPoints, true, dtx, dtz); - OptimalSolution res = cop.RunOptimization(); - Console.WriteLine(res.optimalVector); + OptimalSolution result = hybridQaoa.RunOptimization(); + Console.WriteLine(result.OptimalVector); } } diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index ea4eb70173b..b6ca2487385 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -1,4 +1,7 @@ -namespace QAOA.Jupyter +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.Jupyter { using System; using System.Threading.Tasks; diff --git a/QAOA/src/QAOA.csproj b/QAOA/src/QAOA.csproj index 541726519c0..4d55f0743c3 100644 --- a/QAOA/src/QAOA.csproj +++ b/QAOA/src/QAOA.csproj @@ -7,7 +7,7 @@ - + diff --git a/QAOA/src/Qaoa/Hamiltonians.qs b/QAOA/src/Qaoa/EvolutionOperations.qs similarity index 52% rename from QAOA/src/Qaoa/Hamiltonians.qs rename to QAOA/src/Qaoa/EvolutionOperations.qs index 0e514d4529e..f646f6609b8 100644 --- a/QAOA/src/Qaoa/Hamiltonians.qs +++ b/QAOA/src/Qaoa/EvolutionOperations.qs @@ -1,10 +1,13 @@ -namespace Microsoft.Quantum.QAOA { +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. - open Microsoft.Quantum.Canon; +namespace Microsoft.Quantum.QAOA { + + open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; /// # Summary - /// Implements a unitary based on the mixing hamiltonian and applies it to qubits. + /// Implements a unitary based on the mixing Hamiltonian and applies it to qubits. /// /// # Input /// ## qubits @@ -16,44 +19,35 @@ /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - operation EvolveWithMixingHamiltonian(qubits: Qubit[], beta: Double) : Unit - { - for(i in 0..Length(qubits)-1) - { - R(PauliX, -2.0*beta, qubits[i]); - } + operation EvolveWithMixingHamiltonian(qubits: Qubit[], beta: Double) : Unit is Adj + Ctl { + ApplyToEachCA(R(PauliX, -2.0 * beta, _), qubits); } /// # Summary - /// Implements a unitary based on the objective function hamiltonian and applies it to qubits. + /// Implements a unitary based on the objective function Hamiltonian and applies it to qubits. /// /// # Input /// ## qubits /// Qubits that will be transformed by a unitary. /// ## gamma /// Vector of coefficents for the unitary based on the objective function Hamiltonian. - /// ## h + /// ## oneLocalHamiltonianCoefficients /// Array of 1-local coefficents of the objective function Hamiltonian. - /// ## J + /// ## twoLocalHamiltonianCoefficients /// Array of 2-local coefficents of the objective function Hamiltonian. /// /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - operation EvolveWithObjectiveHamiltonian(qubits: Qubit[], gamma: Double, h: Double[], J: Double[]) : Unit - { - let numberOfQubits = Length(qubits); - using (ancillaQubit = Qubit[1]) - { - for(i in 0..numberOfQubits-1) - { - R(PauliZ, 2.0*gamma*h[i],qubits[i]); + operation EvolveWithObjectiveHamiltonian(qubits: Qubit[], gamma: Double, oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[]) : Unit is Adj + Ctl{ + let numberOfQubits = Length(qubits); + using (auxiliaryQubit = Qubit()) { + for(i in 0..numberOfQubits-1) { + R(PauliZ, 2.0*gamma*oneLocalHamiltonianCoefficients[i],qubits[i]); } - for(i in 0..numberOfQubits-1) - { - for (j in i+1..numberOfQubits-1) - { - RunPhaseKickback(qubits, ancillaQubit, [i,j], 2.0*gamma*J[numberOfQubits*i+j]); + for(i in 0..numberOfQubits-1) { + for (j in i+1..numberOfQubits-1) { + RunPhaseKickback(qubits, auxiliaryQubit, [i,j], 2.0*gamma*twoLocalHamiltonianCoefficients[numberOfQubits*i+j]); } } } diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index 1fff30b1ce6..8795dc8ba49 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -1,4 +1,7 @@ -namespace Microsoft.Quantum.QAOA { +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; @@ -14,9 +17,9 @@ /// Vector of coefficents for the unitary based on the mixing Hamiltonian. /// ## gamma /// Vector of coefficents for the unitary based on the objective function Hamiltonian. - /// ## h + /// ## oneLocalHamiltonianCoefficients /// Array of 1-local coefficents of the objective function Hamiltonian. - /// ## J + /// ## twoLocalHamiltonianCoefficients /// Array of 2-local coefficents of the objective function Hamiltonian. /// ## p /// Depth of the QAOA circuit. @@ -26,17 +29,13 @@ /// /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - - operation RunQaoa(problemSize: Int, beta: Double[], gamma: Double[], h: Double[], J: Double[], p: Int) : Bool[] - { + operation RunQaoa(problemSize: Int, beta: Double[], gamma: Double[], oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[], p: Int) : Bool[] { mutable result = new Bool[problemSize]; - using (qubits = Qubit[problemSize]) - { + using (qubits = Qubit[problemSize]) { ApplyToEach(H, qubits); - for (i in 0..p-1) - { - EvolveWithObjectiveHamiltonian(qubits, gamma[i], h, J); + for (i in 0..p-1) { + EvolveWithObjectiveHamiltonian(qubits, gamma[i], oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); EvolveWithMixingHamiltonian(qubits, beta[i]); } set result = MeasureAllAndReset(qubits); diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index 715129f7479..4f28aae569a 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -1,4 +1,7 @@ -namespace Microsoft.Quantum.QAOA { +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; @@ -13,44 +16,37 @@ /// /// # Output /// Results of the measurement. - - operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] - { + operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] { let N = Length(qubits); mutable results = new Bool[N]; - for (i in 0..N-1) - { + for (i in 0..N-1) { set results w/= i <- (MResetZ(qubits[i]) == One); } return results; } /// # Summary - /// Runs a phase kickback routine on an ancilla qubit given indices of control qubits and a phase. + /// Runs a phase kickback routine on an auxiliary qubit given indices of control qubits and a phase. /// /// # Input /// ## qubits /// Qubits that are to aquire a phase. - /// ## ancillaQubit - /// Ancilla qubit. + /// ## auxiliaryQubit + /// auxiliary qubit. /// ## controlQubitsIndices /// List of indices of control qubits. /// ## phaseExponent /// Phase to be applied. + operation RunPhaseKickback(qubits: Qubit[], auxiliaryQubit: Qubit, controlQubitsIndices: Int[], phaseExponent: Double) : Unit is Adj + Ctl { - operation RunPhaseKickback(qubits: Qubit[], ancillaQubit: Qubit[], controlQubitsIndices: Int[], phaseExponent: Double) : Unit - { - for(i in 0..Length(controlQubitsIndices)-1) - { - CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); + for(i in 0..Length(controlQubitsIndices)-1) { + CNOT(qubits[controlQubitsIndices[i]], auxiliaryQubit); } - R(PauliZ, phaseExponent, ancillaQubit[0]); + R(PauliZ, phaseExponent, auxiliaryQubit); - for(i in 0..Length(controlQubitsIndices)-1) - { - CNOT(qubits[controlQubitsIndices[i]], ancillaQubit[0]); + for(i in 0..Length(controlQubitsIndices)-1) { + CNOT(qubits[controlQubitsIndices[i]], auxiliaryQubit); } - } } \ No newline at end of file diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 39ddbe5539b..48adff855d5 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -1,4 +1,7 @@ -namespace Microsoft.Quantum.QAOA.QaoaHybrid +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; @@ -8,7 +11,6 @@ using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; - //currently support up to 2-local Hamiltonians; will be generalized later public class HybridQaoa { private Utils.FreeParamsVector freeParamsVector; @@ -57,7 +59,7 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance public double EvaluateCostFunction(string result, double[] costs) { double costFunctionValue = 0; - for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.ProblemSizeInBits; i++) { costFunctionValue += costs[i] * char.GetNumericValue(result[i]); } @@ -80,16 +82,16 @@ public double EvaluateCostFunction(string result, double[] costs) public double EvaluateHamiltonian(string result) { double hamiltonianValue = 0; - for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.ProblemSizeInBits; i++) { - hamiltonianValue += this.problemInstance.oneLocalHamiltonianCoefficients[i] * (1 - 2 * char.GetNumericValue(result[i])); + hamiltonianValue += this.problemInstance.OneLocalHamiltonianCoefficients[i] * (1 - 2 * char.GetNumericValue(result[i])); } - for (int i = 0; i < this.problemInstance.problemSizeInBits; i++) + for (int i = 0; i < this.problemInstance.ProblemSizeInBits; i++) { - for (int j = i + 1; j < this.problemInstance.problemSizeInBits; j++) + for (int j = i + 1; j < this.problemInstance.ProblemSizeInBits; j++) { - hamiltonianValue += this.problemInstance.twoLocalHamiltonianCoefficients[i * this.problemInstance.problemSizeInBits + j] * (1 - 2 * char.GetNumericValue(result[i])) * (1 - 2 * char.GetNumericValue(result[j])); + hamiltonianValue += this.problemInstance.TwoLocalHamiltonianCoefficients[i * this.problemInstance.ProblemSizeInBits + j] * (1 - 2 * char.GetNumericValue(result[i])) * (1 - 2 * char.GetNumericValue(result[j])); } } @@ -116,15 +118,15 @@ private double CalculateObjectiveFunction(double[] bigfreeParamsVector) var beta = new QArray(freeParamsVector.beta); var gamma = new QArray(freeParamsVector.gamma); - var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.oneLocalHamiltonianCoefficients); - var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.twoLocalHamiltonianCoefficients); + var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.OneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.TwoLocalHamiltonianCoefficients); using (var qsim = new QuantumSimulator()) { for (int i = 0; i < this.numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, this.problemInstance.problemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; + IQArray result = RunQaoa.Run(qsim, this.problemInstance.ProblemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; allSolutionVectors.Add(result.ToArray()); string solutionVector = Utils.GetBoolStringFromBoolArray(result.ToArray()); double hamiltonianValue = this.EvaluateHamiltonian(solutionVector); @@ -180,10 +182,10 @@ private NonlinearConstraint[] GenerateConstraints() NonlinearConstraint[] constraints = new NonlinearConstraint[4*this.p]; foreach (var i in Enumerable.Range(0, this.p).Select(x => x * 2)) { - int gammaIndex = 2 * p + i; - constraints[i] = new NonlinearConstraint(2 * p, x => x[i / 2] >= 0); - constraints[i + 1] = new NonlinearConstraint(2 * p, x => x[i / 2] <= Math.PI); - constraints[gammaIndex] = new NonlinearConstraint(2 * p, x => x[gammaIndex / 2] >= 0); + int gammaIndex = 2 * this.p + i; + constraints[i] = new NonlinearConstraint(2 * this.p, x => x[i / 2] >= 0); + constraints[i + 1] = new NonlinearConstraint(2 * this.p, x => x[i / 2] <= Math.PI); + constraints[gammaIndex] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] >= 0); constraints[gammaIndex + 1] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] <= 2 * Math.PI); } return constraints; diff --git a/QAOA/src/QaoaHybrid/OptimalSolution.cs b/QAOA/src/QaoaHybrid/OptimalSolution.cs index 9385df05054..c043ba0c08e 100644 --- a/QAOA/src/QaoaHybrid/OptimalSolution.cs +++ b/QAOA/src/QaoaHybrid/OptimalSolution.cs @@ -1,21 +1,24 @@ -namespace Microsoft.Quantum.QAOA.QaoaHybrid +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; public class OptimalSolution { - public string optimalVector { get; } - public double optimalValue { get; } - public double[] optimalBeta { get; } - public double[] optimalGamma { get; } + public string OptimalVector { get; } + public double OptimalValue { get; } + public double[] OptimalBeta { get; } + public double[] OptimalGamma { get; } public OptimalSolution(string optimalVector, double optimalValue, double[] optimalBeta, double[] optimalGamma) { - this.optimalVector = optimalVector; - this.optimalValue = optimalValue; - this.optimalBeta = optimalBeta; - this.optimalGamma = optimalGamma; + this.OptimalVector = optimalVector; + this.OptimalValue = optimalValue; + this.OptimalBeta = optimalBeta; + this.OptimalGamma = optimalGamma; } diff --git a/QAOA/src/QaoaHybrid/ProblemInstance.cs b/QAOA/src/QaoaHybrid/ProblemInstance.cs index 485620fd01d..e60172d5b60 100644 --- a/QAOA/src/QaoaHybrid/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/ProblemInstance.cs @@ -1,18 +1,21 @@ -namespace Microsoft.Quantum.QAOA.QaoaHybrid +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; public class ProblemInstance { - public double[] oneLocalHamiltonianCoefficients { get; } - public double[] twoLocalHamiltonianCoefficients { get; } - public int problemSizeInBits { get; } + public double[] OneLocalHamiltonianCoefficients { get; } + public double[] TwoLocalHamiltonianCoefficients { get; } + public int ProblemSizeInBits { get; } public ProblemInstance(double[] oneLocalHamiltonianCoefficients, double[] twoLocalHamiltonianCoefficients) { - this.oneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; - this.twoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; - this.problemSizeInBits = oneLocalHamiltonianCoefficients.Length; + this.OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; + this.TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; + this.ProblemSizeInBits = oneLocalHamiltonianCoefficients.Length; } } } diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 6fa166b2eea..db5e4801e20 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -1,4 +1,7 @@ -namespace Microsoft.Quantum.QAOA.QaoaHybrid +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; using System.IO; diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs index 07107e44a31..9a7ce3d2725 100644 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -1,4 +1,7 @@ -namespace Microsoft.Quantum.QAOA.QaoaHybrid +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; using System.Collections.Generic; diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index ff25a1b31ad..49c5bb5c94a 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using Microsoft.Quantum.QAOA.QaoaHybrid; @@ -13,10 +16,6 @@ public class ClassicalOptimizationTest public void ConvertDataVectorToVectorsTest() { - ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 } ); - Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); Utils.FreeParamsVector dataVectors = new Utils.FreeParamsVector(); @@ -52,7 +51,6 @@ public void EvaluateCostFunctionTest() HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, false, new double[] { 2 }, new double[] { 3 }); - string optimizationResult = "0101"; double result = classicalOptimization.EvaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); @@ -83,7 +81,7 @@ public void RunHybridQaoaTest() string optimizationResult1 = "01"; string optimizationResult2 = "10"; - string result = optimalSolution.optimalVector; + string result = optimalSolution.OptimalVector; Console.WriteLine(result); Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs index 5095d551b21..7a876d527f3 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/UtilsTests.cs @@ -1,4 +1,7 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using Microsoft.Quantum.QAOA.QaoaHybrid; @@ -35,7 +38,6 @@ public void BoolStringFromBoolArrayTest() { bool[] boolsArray = { false, false, true }; - string expectedResult = "001"; string result = Utils.GetBoolStringFromBoolArray(boolsArray); diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index be02624c796..922148088d5 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -8,7 +8,7 @@ using System; using Microsoft.Quantum.QAOA.JupyterTests; using Microsoft.Quantum.QAOA.QaoaHybrid; -using QAOA.Jupyter; +using Microsoft.Quantum.QAOA.Jupyter; namespace Microsoft.Quantum.QAOA.HybridQaoaTests { @@ -24,23 +24,22 @@ public async Task HybridQaoaProblemInstance() var (magic, channel) = Init(); Assert.Equal("%qaoa.hybridqaoa.create.problem.instance", magic.Name); - double[] dh = new Double[] { 0, 0 }; - double[] dJ = new Double[]{ 0, 1, - 0, 0}; + double[] oneLocalHamiltonianCoefficients = new Double[] { 0, 0 }; + double[] twoLocalHamiltonianCoefficients = new Double[]{ 0, 1, 0, 0}; var args = JsonConvert.SerializeObject(new HybridQaoaProblemInstanceMagic.Arguments { - OneLocalHamiltonianCoefficients = dh, - TwoLocalHamiltonianCoefficients = dJ + OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients, + TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients }); var result = await magic.Run(args, channel); var problemInstance = result.Output as ProblemInstance; Assert.Equal(ExecuteStatus.Ok, result.Status); - Assert.Equal(problemInstance.problemSizeInBits, dh.Length); - Assert.Equal(problemInstance.oneLocalHamiltonianCoefficients, dh); - Assert.Equal(problemInstance.twoLocalHamiltonianCoefficients,dJ); + Assert.Equal(problemInstance.ProblemSizeInBits, oneLocalHamiltonianCoefficients.Length); + Assert.Equal(problemInstance.OneLocalHamiltonianCoefficients, oneLocalHamiltonianCoefficients); + Assert.Equal(problemInstance.TwoLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); } } diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index df62cfc1e84..c0e03caaf82 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -7,7 +7,7 @@ using System; using Microsoft.Quantum.QAOA.QaoaHybrid; using Xunit; -using QAOA.Jupyter; +using Microsoft.Quantum.QAOA.Jupyter; namespace Microsoft.Quantum.QAOA.JupyterTests { @@ -24,11 +24,10 @@ public async Task HybridQaoaRun() var numberOfIterations = 50; var p = 2; - double[] dh = new Double[] { 0, 0 }; - double[] dJ = new Double[]{ 0, 1, - 0, 0}; + double[] oneLocalHamiltonianCoefficients = new Double[] { 0, 0 }; + double[] twoLocalHamiltonianCoefficients = new Double[]{ 0, 1, 0, 0}; - ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + ProblemInstance simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); var args = JsonConvert.SerializeObject(new HybridQaoaRunMagic.Arguments { @@ -43,7 +42,7 @@ public async Task HybridQaoaRun() string optimizationResult1 = "01"; string optimizationResult2 = "10"; - Assert.True(optimalSolution.optimalVector.Equals(optimizationResult1) || optimalSolution.optimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + Assert.True(optimalSolution.OptimalVector.Equals(optimizationResult1) || optimalSolution.OptimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); } } diff --git a/QAOA/tests/JupyterTests/MockChannel.cs b/QAOA/tests/JupyterTests/MockChannel.cs index b56b38f196b..1a91649bcbc 100644 --- a/QAOA/tests/JupyterTests/MockChannel.cs +++ b/QAOA/tests/JupyterTests/MockChannel.cs @@ -1,6 +1,8 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + using System; using System.Collections.Generic; - using Microsoft.Jupyter.Core; namespace Microsoft.Quantum.QAOA.JupyterTests diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs index 229921a9871..b7df05a7cd3 100644 --- a/QAOA/tests/QaoaTests/UtilsTests.qs +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -13,16 +13,13 @@ namespace Microsoft.Quantum.Tests { operation RunPhaseKickbackTest() : Unit { let numberOfQubits = 1; - let ancillaQubits = 1; + let auxiliaryQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; - let complexZero = Complex(1.0, 0.0); - let complexOne = Complex(0.0, 0.0); - using (qubits = Qubit[numberOfQubits+ancillaQubits]) - { - RunPhaseKickback(qubits[...1], qubits[1...],controlQubitsIndices,phaseExponent); - AssertQubitIsInStateWithinTolerance((complexZero,complexOne), qubits[0], 1E-05); + using (qubits = Qubit[numberOfQubits+auxiliaryQubits]) { + RunPhaseKickback(qubits[...1], qubits[1],controlQubitsIndices,phaseExponent); + AssertQubit(Zero, Head(qubits)); ResetAll(qubits); } } @@ -31,17 +28,16 @@ namespace Microsoft.Quantum.Tests { operation RunPhaseKickbackOneControlQubitTest() : Unit { let numberOfQubits = 1; - let ancillaQubits = 1; + let auxiliaryQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; let complexZero = Complex(0.685125,-0.174941); let complexOne = Complex(0.685125,0.174941); - using (qubits = Qubit[numberOfQubits+ancillaQubits]) - { + using (qubits = Qubit[numberOfQubits+auxiliaryQubits]) { H(qubits[0]); - RunPhaseKickback([qubits[0]], [qubits[1]],controlQubitsIndices,phaseExponent); + RunPhaseKickback([qubits[0]], qubits[1],controlQubitsIndices,phaseExponent); AssertQubitIsInStateWithinTolerance((complexZero,complexOne), qubits[0], 1E-05); ResetAll(qubits); } @@ -53,21 +49,20 @@ namespace Microsoft.Quantum.Tests { let complexOne = Complex(1.0, 0.0); let complexZero = Complex(0.0, 0.0); - using (qubits = Qubit[numberOfQubits]) - { + using (qubits = Qubit[numberOfQubits]) { X(qubits[0]); X(qubits[2]); let result = MeasureAllAndReset(qubits); - EqualityFactB(result[0], true, "Expected |1> state."); - EqualityFactB(result[1], false, "Expected |0> state."); - EqualityFactB(result[2], true, "Expected |1> state."); - EqualityFactB(result[3], false, "Expected |0> state."); + Fact(result[0], "Expected |1> state."); + Fact(not result[1], "Expected |0> state."); + Fact(result[2], "Expected |1> state."); + Fact(not result[3], "Expected |0> state."); - AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[0], 1E-06); - AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[1], 1E-06); - AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[2], 1E-06); - AssertQubitIsInStateWithinTolerance((complexOne, complexZero), qubits[3], 1E-06); + AssertQubit(Zero, qubits[0]); + AssertQubit(Zero, qubits[1]); + AssertQubit(Zero, qubits[2]); + AssertQubit(Zero, qubits[3]); } From a21e53d157eba13bdd30ebbccd9da00483f6508a Mon Sep 17 00:00:00 2001 From: Dariusz Date: Thu, 13 Aug 2020 16:56:15 +0200 Subject: [PATCH 40/61] Code review edits. --- QAOA/src/Examples.cs | 26 ++- QAOA/src/Jupyter/HybridQaoaMagic.cs | 12 +- QAOA/src/Qaoa/EvolutionOperations.qs | 2 +- QAOA/src/Qaoa/QaoaRunner.qs | 6 +- QAOA/src/Qaoa/Utils.qs | 36 +-- QAOA/src/QaoaHybrid/HybridQaoa.cs | 214 +++++++++--------- QAOA/src/QaoaHybrid/OptimalSolution.cs | 26 --- QAOA/src/QaoaHybrid/ProblemInstance.cs | 42 ++++ QAOA/src/QaoaHybrid/QaoaLogger.cs | 41 ++-- QAOA/src/QaoaHybrid/Solution.cs | 43 ++++ QAOA/src/QaoaHybrid/Utils.cs | 105 +++++---- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 72 +++--- .../HybridQaoaTests/ProblemInstanceTests.cs | 30 +++ QAOA/tests/HybridQaoaTests/UtilsTests.cs | 24 +- .../HybridQaoaProblemInstanceMagicTests.cs | 4 +- .../JupyterTests/HybridQaoaRunMagicTests.cs | 23 +- QAOA/tests/QaoaTests/UtilsTests.qs | 26 --- 17 files changed, 392 insertions(+), 340 deletions(-) delete mode 100644 QAOA/src/QaoaHybrid/OptimalSolution.cs create mode 100644 QAOA/src/QaoaHybrid/Solution.cs create mode 100644 QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs index 5ac3d4508be..7b1fa86f767 100644 --- a/QAOA/src/Examples.cs +++ b/QAOA/src/Examples.cs @@ -13,7 +13,7 @@ static void Main(string[] args) { //PARAMETERS var numberOfIterations = 70; - var p = 5; + var p = 3; var numberOfRandomStartingPoints = 1; //EXAMPLES @@ -22,16 +22,20 @@ static void Main(string[] args) double[] dtx = { 0.619193, 0.742566, 0.060035, -1.568955, 0.045490 }; double[] dtz = { 3.182203, -1.139045, 0.221082, 0.537753, -0.417222 }; double[] oneLocalHamiltonianCoefficients = { 4 * 20 - 0.5 * 4.7, 4 * 20 - 0.5 * 9.09, 4 * 20 - 0.5 * 9.03, 4 * 20 - 0.5 * 5.70, 4 * 20 - 0.5 * 8.02, 4 * 20 - 0.5 * 1.71 }; - double[] twoLocalHamiltonianCoefficients = { 40.0,40.0,20.0,40.0,40.0,40.0, - 40.0,40.0,40.0,20.0,40.0,40.0, - 40.0,40.0,40.0,40.0,40.0,40.0, - 40.0,40.0,40.0,40.0,40.0,40.0, - 40.0,40.0,40.0,40.0,40.0,20.0, - 40.0,40.0,40.0,40.0,40.0,40.0}; + var twoLocalHamiltonianCoefficients = new[] + { + 40.0, 40.0, 20.0, 40.0, 40.0, 40.0, + 40.0, 40.0, 40.0, 20.0, 40.0, 40.0, + 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, + 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, + 40.0, 40.0, 40.0, 40.0, 40.0, 20.0, + 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, + }; var quantumSanta = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); double[] segmentCosts = { 4.70, 9.09, 9.03, 5.70, 8.02, 1.71 }; + //MaxCut (medium.com/mdr-inc/qaoa-maxcut-using-blueqat-aaf33038f46e) oneLocalHamiltonianCoefficients = new Double[] { 0,0,0,0,0}; twoLocalHamiltonianCoefficients = new Double[]{ 0,1,0,1,0, @@ -59,11 +63,9 @@ static void Main(string[] args) //END EXAMPLES - var hybridQaoa = new HybridQaoa(numberOfIterations, p, quantumSanta, numberOfRandomStartingPoints, true, dtx, dtz); + var hybridQaoa = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints, true); - OptimalSolution result = hybridQaoa.RunOptimization(); - Console.WriteLine(result.OptimalVector); - - } + Solution result = hybridQaoa.RunOptimization(); + } } } \ No newline at end of file diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index b6ca2487385..778bea3fb62 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -32,7 +32,7 @@ public class Arguments public int NumberOfIterations { get; set; } /// - /// Depth of a QAOA circuit. + /// A parameter related to the depth of a QAOA circuit. /// [JsonProperty(PropertyName = "p")] public int p { get; set; } @@ -87,7 +87,7 @@ public async Task Run(string input, IChannel channel) } } - public class HybridQaoaProblemInstanceMagic : MagicSymbol + public class HybridQaoaProblemInstanceMagic : MagicSymbol { public HybridQaoaProblemInstanceMagic() { @@ -106,16 +106,16 @@ public class Arguments /// Coefficents for one-local Hamiltonian terms. /// [JsonProperty(PropertyName = "one_local_hamiltonian_coefficients")] - public Double[] OneLocalHamiltonianCoefficients { get; set; } + public double[] OneLocalHamiltonianCoefficients { get; set; } /// /// Coefficents for one-local Hamiltonian terms. /// [JsonProperty(PropertyName = "two_local_hamiltonian_coefficients")] - public Double[] TwoLocalHamiltonianCoefficients { get; set; } + public double[] TwoLocalHamiltonianCoefficients { get; set; } /// - /// Depth of a QAOA circuit. + /// Size of the combinatorial problem in bits. /// [JsonProperty(PropertyName = "problem_size_in_bits")] public int ProblemSizeInBits { get; set; } @@ -135,7 +135,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - ProblemInstance problemInstance = new ProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); + var problemInstance = new ProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); return problemInstance.ToExecutionResult(); } diff --git a/QAOA/src/Qaoa/EvolutionOperations.qs b/QAOA/src/Qaoa/EvolutionOperations.qs index f646f6609b8..edc0f5eea26 100644 --- a/QAOA/src/Qaoa/EvolutionOperations.qs +++ b/QAOA/src/Qaoa/EvolutionOperations.qs @@ -47,7 +47,7 @@ namespace Microsoft.Quantum.QAOA { } for(i in 0..numberOfQubits-1) { for (j in i+1..numberOfQubits-1) { - RunPhaseKickback(qubits, auxiliaryQubit, [i,j], 2.0*gamma*twoLocalHamiltonianCoefficients[numberOfQubits*i+j]); + RunPhaseKickback(qubits, auxiliaryQubit, [i,j], 2.0*gamma*twoLocalHamiltonianCoefficients[i*numberOfQubits+j]); } } } diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index 8795dc8ba49..b7359843c0f 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -5,6 +5,9 @@ namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Measurement; + open Microsoft.Quantum.Arrays; + open Microsoft.Quantum.Convert; /// # Summary @@ -38,8 +41,7 @@ namespace Microsoft.Quantum.QAOA { EvolveWithObjectiveHamiltonian(qubits, gamma[i], oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); EvolveWithMixingHamiltonian(qubits, beta[i]); } - set result = MeasureAllAndReset(qubits); + return ResultArrayAsBoolArray(ForEach(MResetZ, qubits)); } - return result; } } diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/Utils.qs index 4f28aae569a..11c49c5859b 100644 --- a/QAOA/src/Qaoa/Utils.qs +++ b/QAOA/src/Qaoa/Utils.qs @@ -6,24 +6,7 @@ namespace Microsoft.Quantum.QAOA { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Measurement; - - /// # Summary - /// Measures all qubits and resets them. - /// - /// # Input - /// ## qubits - /// Qubits to be measured. - /// - /// # Output - /// Results of the measurement. - operation MeasureAllAndReset(qubits: Qubit[]) : Bool[] { - let N = Length(qubits); - mutable results = new Bool[N]; - for (i in 0..N-1) { - set results w/= i <- (MResetZ(qubits[i]) == One); - } - return results; - } + open Microsoft.Quantum.Arrays; /// # Summary /// Runs a phase kickback routine on an auxiliary qubit given indices of control qubits and a phase. @@ -39,14 +22,13 @@ namespace Microsoft.Quantum.QAOA { /// Phase to be applied. operation RunPhaseKickback(qubits: Qubit[], auxiliaryQubit: Qubit, controlQubitsIndices: Int[], phaseExponent: Double) : Unit is Adj + Ctl { - for(i in 0..Length(controlQubitsIndices)-1) { - CNOT(qubits[controlQubitsIndices[i]], auxiliaryQubit); - } - - R(PauliZ, phaseExponent, auxiliaryQubit); - - for(i in 0..Length(controlQubitsIndices)-1) { - CNOT(qubits[controlQubitsIndices[i]], auxiliaryQubit); - } + within { + ApplyToEachCA( + CNOT(_, auxiliaryQubit), + Subarray(controlQubitsIndices, qubits) + ); + } apply { + R(PauliZ, phaseExponent, auxiliaryQubit); + } } } \ No newline at end of file diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 48adff855d5..3db5f3d45aa 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -8,33 +8,53 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid using System.Collections.Generic; using System.Linq; using Accord.Math.Optimization; + using Microsoft.Quantum.QAOA; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; - - public class HybridQaoa + public class HybridQaoa { - private Utils.FreeParamsVector freeParamsVector; + private Utils.FreeParameters freeParameters; private readonly int numberOfIterations; private readonly int p; private readonly ProblemInstance problemInstance; - private double bestHamiltonianValue; - private string bestVector; - private double[] bestBeta; - private double[] bestGamma; + private Solution solution; private readonly int numberOfRandomStartingPoints; private readonly QaoaLogger logger; private readonly bool shouldLog; + /// + /// Initializes a new instance of the class. + /// + /// + /// The number of iterations for sampling the average value of the objective function Hamiltonian. + /// + /// + /// A parameter related to the depth of a QAOA circuit. It corresponds to the number of times evolution operators are applied. + /// + /// + /// An object that describes a combinatorial optimization problem to be solved by the algorithm. + /// + /// + /// A number of times the hybrid QAOA will be ran with randomly initiated values of beta and gamma. The bigger the number, the lower the chance of getting a solution that is a local minimum. + /// + /// + /// A flag that specifies whether a log from the hybrid QAOA should be saved in a text file. + /// + /// + /// A user-defined initial value of beta parameters. + /// + /// + /// A user-defined initial value of gamma parameters. + /// public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, bool shouldLog = false, double[] initialBeta = null, double[] initialGamma = null) { this.numberOfIterations = numberOfIterations; this.p = p; this.problemInstance = problemInstance; - this.freeParamsVector.beta = initialBeta; - this.freeParamsVector.gamma = initialGamma; - this.bestHamiltonianValue = double.MaxValue; - this.bestVector = null; + this.freeParameters.Beta = initialBeta; + this.freeParameters.Gamma = initialGamma; + this.solution = new Solution(null, double.MaxValue, null, null); this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; this.shouldLog = shouldLog; if (shouldLog) @@ -44,79 +64,48 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance } - /// # Summary + /// /// Calculates the value of the cost function based on costs provided. - /// - /// # Input - /// ## result + /// + /// /// A binary string. In this context it is a result that we get after measuring the QAOA state. - /// - /// ## costs + /// + /// /// A list of costs for the cost function. - /// - /// # Output + /// + /// /// The value of the costfunction. - public double EvaluateCostFunction(string result, double[] costs) + /// + public double EvaluateCostFunction(bool[] result, double[] costs) { double costFunctionValue = 0; - for (int i = 0; i < this.problemInstance.ProblemSizeInBits; i++) + for (var i = 0; i < this.problemInstance.ProblemSizeInBits; i++) { - costFunctionValue += costs[i] * char.GetNumericValue(result[i]); + costFunctionValue += costs[i] * Convert.ToInt32(result[i]); } return costFunctionValue; } - /// # Summary - /// Calculates the value of the objective function Hamiltonian for a binary string provided. - /// - /// # Input - /// ## result - /// A binary string. In this context it is a result that we get after measuring the QAOA state. - /// - /// # Output - /// The value of the objective function Hamiltonian. - /// - /// # Remarks - /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. - public double EvaluateHamiltonian(string result) - { - double hamiltonianValue = 0; - for (int i = 0; i < this.problemInstance.ProblemSizeInBits; i++) - { - hamiltonianValue += this.problemInstance.OneLocalHamiltonianCoefficients[i] * (1 - 2 * char.GetNumericValue(result[i])); - } - - for (int i = 0; i < this.problemInstance.ProblemSizeInBits; i++) - { - for (int j = i + 1; j < this.problemInstance.ProblemSizeInBits; j++) - { - hamiltonianValue += this.problemInstance.TwoLocalHamiltonianCoefficients[i * this.problemInstance.ProblemSizeInBits + j] * (1 - 2 * char.GetNumericValue(result[i])) * (1 - 2 * char.GetNumericValue(result[j])); - } - } - - return hamiltonianValue; - } - - /// # 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. - private double CalculateObjectiveFunction(double[] bigfreeParamsVector) + /// + private double CalculateObjectiveFunction(double[] bigFreeParamsVector) { - Utils.FreeParamsVector freeParamsVector = Utils.ConvertVectorIntoHalves(bigfreeParamsVector); + var freeParamsVector = Utils.ConvertVectorIntoHalves(bigFreeParamsVector); double hamiltonianExpectationValue = 0; - List allSolutionVectors = new List(); + var allSolutionVectors = new List(); - var beta = new QArray(freeParamsVector.beta); - var gamma = new QArray(freeParamsVector.gamma); + var beta = new QArray(freeParamsVector.Beta); + var gamma = new QArray(freeParamsVector.Gamma); var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.OneLocalHamiltonianCoefficients); var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.TwoLocalHamiltonianCoefficients); @@ -124,12 +113,11 @@ private double CalculateObjectiveFunction(double[] bigfreeParamsVector) using (var qsim = new QuantumSimulator()) { - for (int i = 0; i < this.numberOfIterations; i++) + for (var i = 0; i < this.numberOfIterations; i++) { IQArray result = RunQaoa.Run(qsim, this.problemInstance.ProblemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; allSolutionVectors.Add(result.ToArray()); - string solutionVector = Utils.GetBoolStringFromBoolArray(result.ToArray()); - double hamiltonianValue = this.EvaluateHamiltonian(solutionVector); + var hamiltonianValue = this.problemInstance.EvaluateHamiltonian(result.ToArray()); hamiltonianExpectationValue += hamiltonianValue / this.numberOfIterations; } @@ -139,70 +127,74 @@ private double CalculateObjectiveFunction(double[] bigfreeParamsVector) if (this.shouldLog) { - this.logger.LogCurrentBestSolution(beta, gamma, this.bestHamiltonianValue, this.bestVector); + this.logger.LogCurrentBestSolution(beta, gamma, this.solution.SolutionHamiltonianValue, this.solution.SolutionVector); } + return hamiltonianExpectationValue; } - /// # Summary + /// /// Updates the currently best solution if a new solution is better. - /// - /// # Input - /// ## hamiltonianExpectationValue + /// + /// /// Expectation value of a Hamiltonian. - /// ## allSolutionVectors + /// + /// /// A vector of all binary solutions that were found by a QAOA. - /// ## freeParamsVector + /// + /// /// A vector of beta and gamma coefficients. - private void UpdateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, Utils.FreeParamsVector freeParamsVector) + /// + private void UpdateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, Utils.FreeParameters freeParameters) { - if (hamiltonianExpectationValue < this.bestHamiltonianValue) + if (hamiltonianExpectationValue < this.solution.SolutionHamiltonianValue) { - string mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); - this.bestHamiltonianValue = hamiltonianExpectationValue; - this.bestVector = mostProbableSolutionVectorTemp; - this.bestBeta = freeParamsVector.beta; - this.bestGamma = freeParamsVector.gamma; + var mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); + this.solution.SolutionHamiltonianValue = hamiltonianExpectationValue; + this.solution.SolutionVector = mostProbableSolutionVectorTemp; + this.solution.SolutionBeta = freeParameters.Beta; + this.solution.SolutionGamma = freeParameters.Gamma; } } - - /// # Summary + /// /// Generates constraints for elements in beta and gamma vectors. - /// - /// # Output + /// + /// /// Generated constraints. - /// - /// # Remarks + /// + /// /// For the canonical choice of the mixing Hamiltonian (i.e. the sum of X operators acting on single qubits), the range of values in the beta vector is 0 <= beta_i <= PI. /// For the objective function Hamiltonian based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. + /// private NonlinearConstraint[] GenerateConstraints() { - - NonlinearConstraint[] constraints = new NonlinearConstraint[4*this.p]; + var constraints = new NonlinearConstraint[4*this.p]; foreach (var i in Enumerable.Range(0, this.p).Select(x => x * 2)) { - int gammaIndex = 2 * this.p + i; + int gammaIndex = (2 * this.p) + i; constraints[i] = new NonlinearConstraint(2 * this.p, x => x[i / 2] >= 0); constraints[i + 1] = new NonlinearConstraint(2 * this.p, x => x[i / 2] <= Math.PI); constraints[gammaIndex] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] >= 0); constraints[gammaIndex + 1] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] <= 2 * Math.PI); } + return constraints; } - /// # Summary + /// /// We create beta and gamma vectors. If the user provided their set of parameters, we use them for the first run. Otherwise, we use randomly generated parameters. - /// - /// # Output + /// + /// /// Initialized beta and gamma vectors concatenated. + /// private double[] SetUpFreeParameters() { double[] betaCoefficients; - if (this.freeParamsVector.beta != null) + if (this.freeParameters.Beta != null) { - betaCoefficients = this.freeParamsVector.beta; - this.freeParamsVector.beta = null; + betaCoefficients = this.freeParameters.Beta; + this.freeParameters.Beta = null; } else { @@ -210,10 +202,10 @@ private double[] SetUpFreeParameters() } double[] gammaCoefficients; - if (this.freeParamsVector.gamma != null) + if (this.freeParameters.Gamma != null) { - gammaCoefficients = this.freeParamsVector.gamma; - this.freeParamsVector.gamma = null; + gammaCoefficients = this.freeParameters.Gamma; + this.freeParameters.Gamma = null; } else { @@ -223,41 +215,43 @@ private double[] SetUpFreeParameters() return betaCoefficients.Concat(gammaCoefficients).ToArray(); } - /// # Summary + /// /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum. - /// - /// # Output + /// + /// /// Optimal solution to the optimization problem input by the user. - /// - /// # Remarks + /// + /// /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. /// The objective function Hamiltonian is based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. - public OptimalSolution RunOptimization() + /// + public Solution RunOptimization() { Func objectiveFunction = this.CalculateObjectiveFunction; var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); - NonlinearConstraint[] constraints = this.GenerateConstraints(); + var constraints = this.GenerateConstraints(); for (int i = 0; i < this.numberOfRandomStartingPoints; i++) { var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - double[] freeParameters = this.SetUpFreeParameters(); - bool success = cobyla.Minimize(freeParameters); + var freeParameters = this.SetUpFreeParameters(); + var success = cobyla.Minimize(freeParameters); if (this.shouldLog) { this.logger.LogSuccess(success); } - } + if (this.shouldLog) { this.logger.Close(); } - return new OptimalSolution(this.bestVector, this.bestHamiltonianValue, this.bestBeta, this.bestGamma); + + return this.solution; } } } diff --git a/QAOA/src/QaoaHybrid/OptimalSolution.cs b/QAOA/src/QaoaHybrid/OptimalSolution.cs deleted file mode 100644 index c043ba0c08e..00000000000 --- a/QAOA/src/QaoaHybrid/OptimalSolution.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Microsoft.Quantum.QAOA.QaoaHybrid -{ - using System; - - public class OptimalSolution - { - - public string OptimalVector { get; } - public double OptimalValue { get; } - public double[] OptimalBeta { get; } - public double[] OptimalGamma { get; } - - public OptimalSolution(string optimalVector, double optimalValue, double[] optimalBeta, double[] optimalGamma) - { - this.OptimalVector = optimalVector; - this.OptimalValue = optimalValue; - this.OptimalBeta = optimalBeta; - this.OptimalGamma = optimalGamma; - - } - - } -} diff --git a/QAOA/src/QaoaHybrid/ProblemInstance.cs b/QAOA/src/QaoaHybrid/ProblemInstance.cs index e60172d5b60..1ba7344fb9d 100644 --- a/QAOA/src/QaoaHybrid/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/ProblemInstance.cs @@ -8,14 +8,56 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid public class ProblemInstance { public double[] OneLocalHamiltonianCoefficients { get; } + public double[] TwoLocalHamiltonianCoefficients { get; } + public int ProblemSizeInBits { get; } + /// + /// Initializes a new instance of the class. + /// + /// + /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 1-local terms. + /// + /// + /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 2-local terms. + /// public ProblemInstance(double[] oneLocalHamiltonianCoefficients, double[] twoLocalHamiltonianCoefficients) { this.OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; this.TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; this.ProblemSizeInBits = oneLocalHamiltonianCoefficients.Length; } + + /// + /// Calculates the value of the objective function Hamiltonian for a binary string provided. + /// + /// + /// A binary string. In this context it is a result that we get after measuring the QAOA state. + /// + /// + /// The value of the objective function Hamiltonian. + /// + /// + /// In the binary string, 0 is mapped to 1 and 1 is mapped to -1 since (-1,1) are eigenvalues of the Z operator which is currently supported in this implementation. + /// + public double EvaluateHamiltonian(bool[] result) + { + double hamiltonianValue = 0; + for (var i = 0; i < this.ProblemSizeInBits; i++) + { + hamiltonianValue += this.OneLocalHamiltonianCoefficients[i] * (1 - (2 * Convert.ToInt32(result[i]))); + } + + for (var i = 0; i < this.ProblemSizeInBits; i++) + { + for (var j = i + 1; j < this.ProblemSizeInBits; j++) + { + hamiltonianValue += this.TwoLocalHamiltonianCoefficients[(i * this.ProblemSizeInBits) + j] * (1 - (2 * Convert.ToInt32(result[i]))) * (1 - (2 * Convert.ToInt32(result[j]))); + } + } + + return hamiltonianValue; + } } } diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index db5e4801e20..e04687955eb 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System.Linq; + namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; @@ -17,37 +19,41 @@ public QaoaLogger() this.logger = new StreamWriter("hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); } - /// # Summary + /// /// Writes current values of the best fidelity and the best solution vector to a file. - /// - /// # Input - /// ## beta + /// + /// /// Best beta vector so far. - /// ## gamma + /// + /// /// Best gamma vector so far. - /// ## bestHamiltonian + /// + /// /// Best value of a Hamiltonian so far. - /// ## bestVector + /// + /// /// Best solution vector that generates the above value of a Hamiltonian so far. - public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, string bestVector) + /// + public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, bool[] bestVector) { this.logger.WriteLine("Current beta vector:"); this.logger.WriteLine(beta); this.logger.WriteLine("Current gamma vector:"); this.logger.WriteLine(gamma); - this.logger.WriteLine("Current best fidelity"); + this.logger.WriteLine("Current best expected value of a Hamiltonian:"); this.logger.WriteLine(bestHamiltonian); - this.logger.WriteLine("Current best string"); - this.logger.WriteLine(bestVector); + this.logger.WriteLine("Current best solution vector:"); + var bestSolutionVector = string.Join(", ", bestVector.Select(x => x.ToString())); + this.logger.WriteLine("[" + bestSolutionVector + "]"); } - /// # Summary + /// /// Writes to a file whether an optimization finished successfully. - /// - /// # Input - /// ## success - /// A flag that indiciates whether an optimization finished successfully. + /// + /// + /// A flag that indicates whether an optimization finished successfully. + /// public void LogSuccess(bool success) { this.logger.WriteLine("Was optimization successful?"); @@ -56,8 +62,9 @@ public void LogSuccess(bool success) } - /// # Summary + /// /// Closes a logger. + /// public void Close() { this.logger.Close(); diff --git a/QAOA/src/QaoaHybrid/Solution.cs b/QAOA/src/QaoaHybrid/Solution.cs new file mode 100644 index 00000000000..31f63d51414 --- /dev/null +++ b/QAOA/src/QaoaHybrid/Solution.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid +{ + + public class Solution + { + + public bool[] SolutionVector { get; set; } + + public double SolutionHamiltonianValue { get; set; } + + public double[] SolutionBeta { get; set; } + + public double[] SolutionGamma { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// + /// A vector that is a solution of a combinatorial optimization problem found by a hybrid QAOA. + /// + /// + /// An expected value of an objective function Hamiltonian that corresponds to the solution stored in solutionVector. + /// + /// + /// Values of beta parameters that correspond to the solution stored in solutionVector. + /// + /// + /// Values of gamma parameters that corresponds to the solution stored in solutionVector. + /// + public Solution(bool[] solutionVector, double solutionHamiltonianValue, double[] solutionBeta, double[] solutionGamma) + { + this.SolutionVector = solutionVector; + this.SolutionHamiltonianValue = solutionHamiltonianValue; + this.SolutionBeta = solutionBeta; + this.SolutionGamma = solutionGamma; + + } + + } +} diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs index 9a7ce3d2725..2ad0f36c363 100644 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -5,33 +5,35 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; using System.Collections.Generic; + using System.Linq; using System.Text; public class Utils { - public struct FreeParamsVector + public struct FreeParameters { - public double[] beta; - public double[] gamma; + public double[] Beta; + public double[] Gamma; } - /// # Summary + /// /// Returns a vector of random doubles in a range from 0 to maximum. - /// - /// # Input - /// ## length + /// + /// /// Length of a random vector. - /// ## maximum + /// + /// /// Maximum value of a random double. - /// - /// # Output + /// + /// /// A random vector of doubles. + /// public static double[] GetRandomVector(int length, double maximumValue) { var rand = new Random(); double[] randomVector = new double[length]; - for (int i = 0; i < length; i++) + for (var i = 0; i < length; i++) { randomVector[i] = maximumValue * rand.NextDouble(); } @@ -39,21 +41,20 @@ public static double[] GetRandomVector(int length, double maximumValue) return randomVector; } - /// # Summary + /// /// Return the most common boolean string from a list of boolean values. - /// - /// # Input - /// ## list + /// + /// /// List of boolean values. - /// - /// # Output + /// + /// /// The most common boolean string. - public static string GetModeFromBoolList(List list) + /// + public static bool[] GetModeFromBoolList(List list) { - Dictionary counter = new Dictionary(); - foreach (bool[] boolArray in list) + var counter = new Dictionary(); + foreach (var boolString in list.Select(GetBoolStringFromBoolArray)) { - string boolString = GetBoolStringFromBoolArray(boolArray); if (counter.ContainsKey(boolString)) { counter[boolString] += 1; @@ -62,62 +63,60 @@ public static string GetModeFromBoolList(List list) { counter[boolString] = 1; } - } - int maximum = 0; + + var maximum = 0; string result = null; - foreach (string key in counter.Keys) + foreach (var key in counter.Keys.Where(key => counter[key] > maximum)) { - if (counter[key] > maximum) - { - maximum = counter[key]; - result = key; - } + maximum = counter[key]; + result = key; } - return result; + return result.Select(chr => chr == '1').ToArray(); } - /// # Summary + /// /// Converts an array of bools to a boolean string. - /// - /// # Input - /// ## boolArray + /// + /// /// An array of bools. - /// - /// # Output + /// + /// /// A boolean string. + /// public static string GetBoolStringFromBoolArray(bool[] boolArray) { - System.Text.StringBuilder sb = new StringBuilder(); - foreach (bool b in boolArray) + var sb = new StringBuilder(); + foreach (var b in boolArray) { sb.Append(b ? "1" : "0"); } + return sb.ToString(); } - /// # Summary + /// /// Converts concatenated beta and gamma vectors into separate beta and gamma vector. - /// - /// # Input - /// ## bigfreeParamsVector + /// + /// /// Concatenated beta and gamma vectors. - /// - /// # Output - /// FreeParamsVector that contains beta and gamma vectors. - /// - /// # Remarks + /// + /// + /// FreeParameters that contains beta and gamma vectors. + /// + /// /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. - public static FreeParamsVector ConvertVectorIntoHalves(double[] bigfreeParamsVector) + /// + public static FreeParameters ConvertVectorIntoHalves(double[] bigFreeParamsVector) { - int size = bigfreeParamsVector.Length; - int vectorTermsNumber = size / 2; - FreeParamsVector freeParamsVector = new FreeParamsVector + var size = bigFreeParamsVector.Length; + var vectorTermsNumber = size / 2; + var freeParamsVector = new FreeParameters { - beta = bigfreeParamsVector[0..vectorTermsNumber], - gamma = bigfreeParamsVector[vectorTermsNumber..(2*vectorTermsNumber)], + Beta = bigFreeParamsVector[0..vectorTermsNumber], + Gamma = bigFreeParamsVector[vectorTermsNumber..(2 * vectorTermsNumber)], }; diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 49c5bb5c94a..d1c1fe2f3df 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -16,34 +16,22 @@ public class ClassicalOptimizationTest public void ConvertDataVectorToVectorsTest() { - Utils.FreeParamsVector result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); + var result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); - Utils.FreeParamsVector dataVectors = new Utils.FreeParamsVector(); - dataVectors.beta = new double[] { 1, 2, 3 }; - dataVectors.gamma = new double[] { 4, 5, 6 }; + var dataVectors = new Utils.FreeParameters + { + Beta = new double[] { 1, 2, 3 }, + Gamma = new double[] { 4, 5, 6 } + }; - Utils.FreeParamsVector expectedResult = dataVectors; + var expectedResult = dataVectors; - CollectionAssert.AreEqual(expectedResult.beta, result.beta, "Hamiltonian beta value not calculated correctly."); - CollectionAssert.AreEqual(expectedResult.gamma, result.gamma, "Hamiltonian gamma value not calculated correctly."); - - } - - [TestMethod] - public void EvaluateHamiltonianTest() - { - ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - - HybridQaoa classicalOptimization = new HybridQaoa(2, 3, problemInstance, 1, false, new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 }); - - double result = classicalOptimization.EvaluateHamiltonian("0011"); - - double expectedResult = -1; - - Assert.AreEqual(expectedResult, result, "Hamiltonian value not calculated correctly."); + CollectionAssert.AreEqual(expectedResult.Beta, result.Beta, "Hamiltonian beta value not calculated correctly."); + CollectionAssert.AreEqual(expectedResult.Gamma, result.Gamma, "Hamiltonian gamma value not calculated correctly."); } + [TestMethod] public void EvaluateCostFunctionTest() { @@ -51,11 +39,11 @@ public void EvaluateCostFunctionTest() HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, false, new double[] { 2 }, new double[] { 3 }); - string optimizationResult = "0101"; + var optimizationResult = new []{false, true, false, true}; - double result = classicalOptimization.EvaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); + var result = classicalOptimization.EvaluateCostFunction(optimizationResult, new double[] { 5, 3, 2, 1 }); - double expectedResult = 4; + var expectedResult = 4; Assert.AreEqual(expectedResult, result, "Cost function not calculated correctly."); @@ -65,27 +53,31 @@ public void EvaluateCostFunctionTest() [TestMethod] public void RunHybridQaoaTest() { - double[] dh = new double[] { 0, 0 }; - double[] dJ = new double[]{ 0, 1, - 0, 0}; - - int numberOfIterations = 50; - int p = 2; - int numberOfRandomStartingPoints = 2; + var dh = new double[] { 0, 0 }; + var dJ = new double[]{ 0, 1, 0, 0}; - ProblemInstance simpleMaxCut = new ProblemInstance(dh, dJ); + var numberOfIterations = 50; + var p = 2; + var numberOfRandomStartingPoints = 2; - HybridQaoa classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); - OptimalSolution optimalSolution = classicalOptimization.RunOptimization(); + var simpleMaxCut = new ProblemInstance(dh, dJ); - string optimizationResult1 = "01"; - string optimizationResult2 = "10"; + var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); + var optimalSolution = classicalOptimization.RunOptimization(); - string result = optimalSolution.OptimalVector; - Console.WriteLine(result); + var optimizationResult1 = new[] {false, true}; + var optimizationResult2 = new[] {true, false}; - Assert.IsTrue(result.Equals(optimizationResult1) || result.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + var result = optimalSolution.SolutionVector; + if (result[0] == false) + { + CollectionAssert.AreEqual(result, optimizationResult1, "Hybrid QAOA produced incorrect result."); + } + else + { + CollectionAssert.AreEqual(result, optimizationResult2, "Hybrid QAOA produced incorrect result."); + } } } } diff --git a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs new file mode 100644 index 00000000000..063fa96307f --- /dev/null +++ b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Quantum.QAOA.QaoaHybrid; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.Quantum.QAOA.HybridQaoaTests +{ + + [TestClass] + class ProblemInstanceTests + { + + + [TestMethod] + public void EvaluateHamiltonianTest() + { + var problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); + + var result = problemInstance.EvaluateHamiltonian(new bool[] {false,false,true,true}); + + const int expectedResult = -1; + + Assert.AreEqual(expectedResult, result, "Hamiltonian value not calculated correctly."); + + + } + +} +} diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/UtilsTests.cs index 7a876d527f3..883ce71b284 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/UtilsTests.cs @@ -18,17 +18,19 @@ public void ModeOfABoolListTest() bool[] boolsArray3 = { false, false, false }; bool[] boolsArray4 = { false, true, true }; - List listOfBools = new List(); - listOfBools.Add(boolsArray1); - listOfBools.Add(boolsArray3); - listOfBools.Add(boolsArray2); - listOfBools.Add(boolsArray4); + var listOfBools = new List + { + boolsArray1, + boolsArray3, + boolsArray2, + boolsArray4 + }; - string expectedResult = "001"; + var expectedResult = new[] {false, false, true}; - string result = Utils.GetModeFromBoolList(listOfBools); + var result = Utils.GetModeFromBoolList(listOfBools); - Assert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); + CollectionAssert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); } @@ -36,11 +38,11 @@ public void ModeOfABoolListTest() [TestMethod] public void BoolStringFromBoolArrayTest() { - bool[] boolsArray = { false, false, true }; + var boolsArray = new [] { false, false, true }; - string expectedResult = "001"; + var expectedResult = "001"; - string result = Utils.GetBoolStringFromBoolArray(boolsArray); + var result = Utils.GetBoolStringFromBoolArray(boolsArray); Assert.AreEqual(expectedResult, result, "Bool string not created correctly."); diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index 922148088d5..73509393025 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -24,8 +24,8 @@ public async Task HybridQaoaProblemInstance() var (magic, channel) = Init(); Assert.Equal("%qaoa.hybridqaoa.create.problem.instance", magic.Name); - double[] oneLocalHamiltonianCoefficients = new Double[] { 0, 0 }; - double[] twoLocalHamiltonianCoefficients = new Double[]{ 0, 1, 0, 0}; + var oneLocalHamiltonianCoefficients = new double[] {0, 0}; + var twoLocalHamiltonianCoefficients = new double[] {0, 1, 0, 0}; var args = JsonConvert.SerializeObject(new HybridQaoaProblemInstanceMagic.Arguments { diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index c0e03caaf82..cfdf6f5490e 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -8,6 +8,8 @@ using Microsoft.Quantum.QAOA.QaoaHybrid; using Xunit; using Microsoft.Quantum.QAOA.Jupyter; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Assert = Xunit.Assert; namespace Microsoft.Quantum.QAOA.JupyterTests { @@ -24,10 +26,10 @@ public async Task HybridQaoaRun() var numberOfIterations = 50; var p = 2; - double[] oneLocalHamiltonianCoefficients = new Double[] { 0, 0 }; - double[] twoLocalHamiltonianCoefficients = new Double[]{ 0, 1, 0, 0}; + var oneLocalHamiltonianCoefficients = new double[] { 0, 0 }; + var twoLocalHamiltonianCoefficients = new double[] { 0, 1, 0, 0}; - ProblemInstance simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); + var simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); var args = JsonConvert.SerializeObject(new HybridQaoaRunMagic.Arguments { @@ -37,12 +39,19 @@ public async Task HybridQaoaRun() }); var result = await magic.Run(args, channel); - var optimalSolution = result.Output as OptimalSolution; + var optimalSolution = result.Output as Solution; Assert.Equal(ExecuteStatus.Ok, result.Status); - string optimizationResult1 = "01"; - string optimizationResult2 = "10"; + var optimizationResult1 = new[] {false, true}; + var optimizationResult2 = new[] {true, false}; - Assert.True(optimalSolution.OptimalVector.Equals(optimizationResult1) || optimalSolution.OptimalVector.Equals(optimizationResult2), "Hybrid QAOA produced incorrect result."); + if (optimalSolution.SolutionVector[0] == false) + { + CollectionAssert.AreEqual(optimalSolution.SolutionVector, optimizationResult1, "Hybrid QAOA produced incorrect result when running magic."); + } + else + { + CollectionAssert.AreEqual(optimalSolution.SolutionVector, optimizationResult2, "Hybrid QAOA produced incorrect result when running magic."); + } } } diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/UtilsTests.qs index b7df05a7cd3..5f0ca6c8197 100644 --- a/QAOA/tests/QaoaTests/UtilsTests.qs +++ b/QAOA/tests/QaoaTests/UtilsTests.qs @@ -42,30 +42,4 @@ namespace Microsoft.Quantum.Tests { ResetAll(qubits); } } - - @Test("QuantumSimulator") - operation MeasureAllAndResetTest() : Unit { - let numberOfQubits = 4; - let complexOne = Complex(1.0, 0.0); - let complexZero = Complex(0.0, 0.0); - - using (qubits = Qubit[numberOfQubits]) { - X(qubits[0]); - X(qubits[2]); - let result = MeasureAllAndReset(qubits); - - Fact(result[0], "Expected |1> state."); - Fact(not result[1], "Expected |0> state."); - Fact(result[2], "Expected |1> state."); - Fact(not result[3], "Expected |0> state."); - - AssertQubit(Zero, qubits[0]); - AssertQubit(Zero, qubits[1]); - AssertQubit(Zero, qubits[2]); - AssertQubit(Zero, qubits[3]); - - } - - } - } From 68869a4a5cd6f27be7b3eca4cc00e5592fcfe4fc Mon Sep 17 00:00:00 2001 From: Dariusz Date: Fri, 14 Aug 2020 18:34:27 +0200 Subject: [PATCH 41/61] Code review edits. --- QAOA/src/Examples.cs | 71 -------------------------- QAOA/src/QAOA.csproj | 2 +- QAOA/src/Qaoa/EvolutionOperations.qs | 5 -- QAOA/src/QaoaHybrid/HybridQaoa.cs | 4 ++ QAOA/src/QaoaHybrid/ProblemInstance.cs | 7 ++- QAOA/src/QaoaHybrid/QaoaLogger.cs | 3 ++ QAOA/src/QaoaHybrid/Solution.cs | 7 ++- QAOA/src/QaoaHybrid/Utils.cs | 3 ++ 8 files changed, 22 insertions(+), 80 deletions(-) delete mode 100644 QAOA/src/Examples.cs diff --git a/QAOA/src/Examples.cs b/QAOA/src/Examples.cs deleted file mode 100644 index 7b1fa86f767..00000000000 --- a/QAOA/src/Examples.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Quantum.QAOA -{ - using Microsoft.Quantum.QAOA.QaoaHybrid; - using System; - - - class Examples - { - static void Main(string[] args) - { - //PARAMETERS - var numberOfIterations = 70; - var p = 3; - var numberOfRandomStartingPoints = 1; - - //EXAMPLES - - //Quantum Santa (http://quantumalgorithmzoo.org/traveling_santa/) - double[] dtx = { 0.619193, 0.742566, 0.060035, -1.568955, 0.045490 }; - double[] dtz = { 3.182203, -1.139045, 0.221082, 0.537753, -0.417222 }; - double[] oneLocalHamiltonianCoefficients = { 4 * 20 - 0.5 * 4.7, 4 * 20 - 0.5 * 9.09, 4 * 20 - 0.5 * 9.03, 4 * 20 - 0.5 * 5.70, 4 * 20 - 0.5 * 8.02, 4 * 20 - 0.5 * 1.71 }; - var twoLocalHamiltonianCoefficients = new[] - { - 40.0, 40.0, 20.0, 40.0, 40.0, 40.0, - 40.0, 40.0, 40.0, 20.0, 40.0, 40.0, - 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, - 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, - 40.0, 40.0, 40.0, 40.0, 40.0, 20.0, - 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, - }; - var quantumSanta = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - - double[] segmentCosts = { 4.70, 9.09, 9.03, 5.70, 8.02, 1.71 }; - - - //MaxCut (medium.com/mdr-inc/qaoa-maxcut-using-blueqat-aaf33038f46e) - oneLocalHamiltonianCoefficients = new Double[] { 0,0,0,0,0}; - twoLocalHamiltonianCoefficients = new Double[]{ 0,1,0,1,0, - 0,0,1,0,0, - 0,0,0,1,1, - 0,0,0,0,1, - 0,0,0,0,0}; - var maxCut1 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - - //Rigetti MaxCut unit tests - oneLocalHamiltonianCoefficients = new Double[]{-0.5,0,-1,0.5}; - twoLocalHamiltonianCoefficients = new Double[]{0,1,2,0, - 0,0,0.5,0, - 0,0,0,2.5, - 0,0,0,0}; - var maxCut2 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - - oneLocalHamiltonianCoefficients = new Double[] { 0.8, -0.5 }; - twoLocalHamiltonianCoefficients = new Double[]{ 0, -1, 0, 0}; - var maxCut3 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - - oneLocalHamiltonianCoefficients = new Double[] {0, 0 }; - twoLocalHamiltonianCoefficients = new Double[]{ 0, 1, 0, 0}; - var maxCut4 = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - - //END EXAMPLES - - var hybridQaoa = new HybridQaoa(numberOfIterations, p, maxCut4, numberOfRandomStartingPoints, true); - - Solution result = hybridQaoa.RunOptimization(); - } - } -} \ No newline at end of file diff --git a/QAOA/src/QAOA.csproj b/QAOA/src/QAOA.csproj index 4d55f0743c3..15f81ea122f 100644 --- a/QAOA/src/QAOA.csproj +++ b/QAOA/src/QAOA.csproj @@ -1,7 +1,7 @@ - Exe + Library netcoreapp3.1 diff --git a/QAOA/src/Qaoa/EvolutionOperations.qs b/QAOA/src/Qaoa/EvolutionOperations.qs index edc0f5eea26..442126a3df5 100644 --- a/QAOA/src/Qaoa/EvolutionOperations.qs +++ b/QAOA/src/Qaoa/EvolutionOperations.qs @@ -14,11 +14,8 @@ namespace Microsoft.Quantum.QAOA { /// Qubits that will be transformed by a unitary. /// ## beta /// Vector of coefficents for the unitary based on the mixing Hamiltonian. - /// /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - - operation EvolveWithMixingHamiltonian(qubits: Qubit[], beta: Double) : Unit is Adj + Ctl { ApplyToEachCA(R(PauliX, -2.0 * beta, _), qubits); } @@ -35,10 +32,8 @@ namespace Microsoft.Quantum.QAOA { /// Array of 1-local coefficents of the objective function Hamiltonian. /// ## twoLocalHamiltonianCoefficients /// Array of 2-local coefficents of the objective function Hamiltonian. - /// /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - operation EvolveWithObjectiveHamiltonian(qubits: Qubit[], gamma: Double, oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[]) : Unit is Adj + Ctl{ let numberOfQubits = Length(qubits); using (auxiliaryQubit = Qubit()) { diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 3db5f3d45aa..5cad9ae5d02 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -11,6 +11,10 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid using Microsoft.Quantum.QAOA; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; + + /// + /// This class runs a hybrid (quantum-classical) QAOA given an instance of a combinatorial optimization problem encoded into a 2-local Hamiltonian. The classical part is used for optimizing QAOA input parameters and is implemented using the Cobyla optimizer. QAOA input parameters can be optionally specified by a user and they will be treated as a starting point for optimization. Otherwise, input parameters are initialized randomly (possibly many times, as specified by the numberOfRandomStartingPoints variable). + /// public class HybridQaoa { private Utils.FreeParameters freeParameters; diff --git a/QAOA/src/QaoaHybrid/ProblemInstance.cs b/QAOA/src/QaoaHybrid/ProblemInstance.cs index 1ba7344fb9d..2b8a363d5b5 100644 --- a/QAOA/src/QaoaHybrid/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/ProblemInstance.cs @@ -5,6 +5,9 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; + /// + /// This class is used for storing the encoding of a combinatorial optimization problem into a Hamiltonian. Currently, a Hamiltonian with locality of up to 2 is supported. + /// public class ProblemInstance { public double[] OneLocalHamiltonianCoefficients { get; } @@ -17,10 +20,10 @@ public class ProblemInstance /// Initializes a new instance of the class. /// /// - /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 1-local terms. + /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 1-local terms. Non-existent terms (excluding those that go beyond the size of a problem) shall be input with a coefficient that equals 0. /// /// - /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 2-local terms. + /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 2-local terms. Non-existent terms (excluding those that go beyond the size of a problem) shall be input with a coefficient that equals 0. /// public ProblemInstance(double[] oneLocalHamiltonianCoefficients, double[] twoLocalHamiltonianCoefficients) { diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index e04687955eb..ab7a3b519d3 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -9,6 +9,9 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid using System.IO; using Microsoft.Quantum.Simulation.Core; + /// + /// This class provides a simple capability for logging intermediate steps of a hybrid QAOA to a text file. + /// class QaoaLogger { private readonly StreamWriter logger; diff --git a/QAOA/src/QaoaHybrid/Solution.cs b/QAOA/src/QaoaHybrid/Solution.cs index 31f63d51414..e37b4c71170 100644 --- a/QAOA/src/QaoaHybrid/Solution.cs +++ b/QAOA/src/QaoaHybrid/Solution.cs @@ -3,7 +3,12 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid { - + /// + /// This class stores a solution that is found by a hybrid QAOA. It includes a boolean array that encodes the solution, a corresponding expected value of the objective function Hamiltonian and corresponding beta and gamma parameters that are input to a QAOA. + /// + /// + /// Note that given the nature of a QAOA and a hybrid QAOA, a solution produced by the algorithm is not necessarily feasible and not necessarily optimal. + /// public class Solution { diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs index 2ad0f36c363..e88c2c0c85c 100644 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -8,6 +8,9 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid using System.Linq; using System.Text; + /// + /// This class provides auxiliary methods for a hybrid QAOA. + /// public class Utils { From 9087d5ecb643347f44c25d731dd2b783d7e4f3ca Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 15 Aug 2020 21:29:25 +0200 Subject: [PATCH 42/61] Improved handling of a hybrid QAOA with user-defined input parameters and random input parameters. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 86 +++++++++++-- QAOA/src/QaoaHybrid/HybridQaoa.cs | 116 ++++++++++-------- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 44 ++++++- .../JupyterTests/HybridQaoaRunMagicTests.cs | 54 +++++++- 4 files changed, 225 insertions(+), 75 deletions(-) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 778bea3fb62..9fc770ecf4f 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -15,7 +15,7 @@ public class HybridQaoaRunMagic : MagicSymbol public HybridQaoaRunMagic() { this.Name = $"%qaoa.hybridqaoa.run"; - this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json" }; + this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json. Initial beta and gamma coefficients are provided by a user." }; this.Kind = SymbolKind.Magic; this.Execute = this.Run; } @@ -44,28 +44,88 @@ public class Arguments public ProblemInstance ProblemInstance { get; set; } /// - /// Number of random starting points in the angles parameters spaces. + /// Initial beta angles. /// - [JsonProperty(PropertyName = "number_of_random_starting_points")] - public int NumberOfRandomStartingPoints { get; set; } = 1; + [JsonProperty(PropertyName = "initial_beta")] + public Double[] InitialBeta { get; set; } + + /// + /// Initial gamma angles. + /// + [JsonProperty(PropertyName = "initial_gamma")] + public Double[] InitialGamma { get; set; } /// /// Flag whether optimization should be logged into a file. /// [JsonProperty(PropertyName = "should_log")] public Boolean ShouldLog { get; set; } = false; + } + + /// + /// Runs a hybrid QAOA. + /// + public async Task Run(string input, IChannel channel) + { + if (string.IsNullOrWhiteSpace(input)) + { + channel.Stderr("Please provide correct arguments"); + return ExecuteStatus.Error.ToExecutionResult(); + } + + var args = JsonConvert.DeserializeObject(input); + + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); + + return hybridQaoa.RunOptimization(args.InitialBeta, args.InitialGamma).ToExecutionResult(); + } + } + + public class HybridQaoaWithRandomParametersRunMagic : MagicSymbol + { + + public HybridQaoaWithRandomParametersRunMagic() + { + this.Name = $"%qaoa.hybridqaoa.random.params.run"; + this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json. Initial beta and gamma parameters are chosen randomly." }; + this.Kind = SymbolKind.Magic; + this.Execute = this.Run; + } + /// + /// List of arguments + /// + public class Arguments + { /// - /// Initial beta angles. + /// Number of iterations in the fidelity sampling. /// - [JsonProperty(PropertyName = "initial_beta")] - public Double[] InitialBeta { get; set; } = null; + [JsonProperty(PropertyName = "number_of_iterations")] + public int NumberOfIterations { get; set; } /// - /// Initial gamma angles. + /// A parameter related to the depth of a QAOA circuit. /// - [JsonProperty(PropertyName = "initial_gamma")] - public Double[] InitialGamma { get; set; } = null; + [JsonProperty(PropertyName = "p")] + public int p { get; set; } + + /// + /// Description of a combinatorial problem to be solved. + /// + [JsonProperty(PropertyName = "problem_instance")] + public ProblemInstance ProblemInstance { get; set; } + + /// + /// Number of random starting points in the angles parameters spaces. + /// + [JsonProperty(PropertyName = "number_of_random_starting_points")] + public int NumberOfRandomStartingPoints { get; set; } = 1; + + /// + /// Flag whether optimization should be logged into a file. + /// + [JsonProperty(PropertyName = "should_log")] + public Boolean ShouldLog { get; set; } = false; } /// @@ -81,9 +141,9 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.NumberOfRandomStartingPoints, args.ShouldLog, args.InitialBeta, args.InitialGamma); + HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); - return hybridQaoa.RunOptimization().ToExecutionResult(); + return hybridQaoa.RunOptimization(args.NumberOfRandomStartingPoints).ToExecutionResult(); } } @@ -98,7 +158,7 @@ public HybridQaoaProblemInstanceMagic() } /// - /// List of arguments + /// List of arguments. /// public class Arguments { diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 5cad9ae5d02..68c9c05ad72 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -17,14 +17,12 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid /// public class HybridQaoa { - private Utils.FreeParameters freeParameters; private readonly int numberOfIterations; private readonly int p; private readonly ProblemInstance problemInstance; - private Solution solution; - private readonly int numberOfRandomStartingPoints; - private readonly QaoaLogger logger; private readonly bool shouldLog; + private Solution solution; + private QaoaLogger logger; /// /// Initializes a new instance of the class. @@ -38,36 +36,17 @@ public class HybridQaoa /// /// An object that describes a combinatorial optimization problem to be solved by the algorithm. /// - /// - /// A number of times the hybrid QAOA will be ran with randomly initiated values of beta and gamma. The bigger the number, the lower the chance of getting a solution that is a local minimum. - /// /// /// A flag that specifies whether a log from the hybrid QAOA should be saved in a text file. /// - /// - /// A user-defined initial value of beta parameters. - /// - /// - /// A user-defined initial value of gamma parameters. - /// - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, int numberOfRandomStartingPoints = 1, bool shouldLog = false, double[] initialBeta = null, double[] initialGamma = null) + public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, bool shouldLog = false) { - this.numberOfIterations = numberOfIterations; this.p = p; this.problemInstance = problemInstance; - this.freeParameters.Beta = initialBeta; - this.freeParameters.Gamma = initialGamma; - this.solution = new Solution(null, double.MaxValue, null, null); - this.numberOfRandomStartingPoints = numberOfRandomStartingPoints; this.shouldLog = shouldLog; - if (shouldLog) - { - this.logger = new QaoaLogger(); - } } - /// /// Calculates the value of the cost function based on costs provided. /// @@ -187,34 +166,15 @@ private NonlinearConstraint[] GenerateConstraints() } /// - /// We create beta and gamma vectors. If the user provided their set of parameters, we use them for the first run. Otherwise, we use randomly generated parameters. + /// We create random beta and gamma vectors. /// /// /// Initialized beta and gamma vectors concatenated. /// - private double[] SetUpFreeParameters() + private double[] SetUpRandomFreeParameters() { - double[] betaCoefficients; - if (this.freeParameters.Beta != null) - { - betaCoefficients = this.freeParameters.Beta; - this.freeParameters.Beta = null; - } - else - { - betaCoefficients = Utils.GetRandomVector(this.p, Math.PI); - } - - double[] gammaCoefficients; - if (this.freeParameters.Gamma != null) - { - gammaCoefficients = this.freeParameters.Gamma; - this.freeParameters.Gamma = null; - } - else - { - gammaCoefficients = Utils.GetRandomVector(this.p, 2 * Math.PI); - } + var betaCoefficients = Utils.GetRandomVector(this.p, Math.PI); + var gammaCoefficients = Utils.GetRandomVector(this.p, 2 * Math.PI); return betaCoefficients.Concat(gammaCoefficients).ToArray(); } @@ -222,26 +182,34 @@ private double[] SetUpFreeParameters() /// /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum. /// + /// + /// A number of times the hybrid QAOA will be ran with randomly initiated values of beta and gamma. The bigger the number, the lower the chance of getting a solution that is a local minimum. + /// /// /// Optimal solution to the optimization problem input by the user. /// /// /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. - /// The objective function Hamiltonian is based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI. + /// The objective function Hamiltonian is based on Z operators, the range of values in the beta vector is 0 <= beta_i <= PI, the range of values in the gamma vector is 0 <= beta_i <= 2PI. /// - public Solution RunOptimization() + public Solution RunOptimization(int numberOfRandomStartingPoints) { + if (this.shouldLog) + { + this.logger = new QaoaLogger(); + } + + this.solution = new Solution(null, double.MaxValue, null, null); Func objectiveFunction = this.CalculateObjectiveFunction; var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); - var constraints = this.GenerateConstraints(); + var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - for (int i = 0; i < this.numberOfRandomStartingPoints; i++) + for (int i = 0; i < numberOfRandomStartingPoints; i++) { - var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - var freeParameters = this.SetUpFreeParameters(); + var freeParameters = this.SetUpRandomFreeParameters(); var success = cobyla.Minimize(freeParameters); if (this.shouldLog) @@ -257,5 +225,47 @@ public Solution RunOptimization() return this.solution; } + + /// + /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. Initial beta and gamma parameters are provided by a user. + /// + /// + /// A user-defined initial value of beta parameters. + /// + /// + /// A user-defined initial value of gamma parameters. + /// + /// + /// Optimal solution to the optimization problem input by the user. + /// + /// + /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. + /// The objective function Hamiltonian is based on Z operators, the range of values in the beta vector is 0 <= beta_i <= PI, the range of values in the gamma vector is 0 <= beta_i <= 2PI. + /// + public Solution RunOptimization(double[] initialBeta, double[] initialGamma) + { + if (this.shouldLog) + { + this.logger = new QaoaLogger(); + } + + this.solution = new Solution(null, double.MaxValue, null, null); + + Func objectiveFunction = this.CalculateObjectiveFunction; + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); + var constraints = this.GenerateConstraints(); + + var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); + var freeParameters = initialBeta.Concat(initialGamma).ToArray(); + var success = cobyla.Minimize(freeParameters); + + if (this.shouldLog) + { + this.logger.LogSuccess(success); + this.logger.Close(); + } + + return this.solution; + } } } diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index d1c1fe2f3df..d3637553859 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -37,7 +37,7 @@ public void EvaluateCostFunctionTest() { ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance, 1, false, new double[] { 2 }, new double[] { 3 }); + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance); var optimizationResult = new []{false, true, false, true}; @@ -51,7 +51,7 @@ public void EvaluateCostFunctionTest() } [TestMethod] - public void RunHybridQaoaTest() + public void RunOptimizationRandomParamsTest() { var dh = new double[] { 0, 0 }; var dJ = new double[]{ 0, 1, 0, 0}; @@ -62,8 +62,8 @@ public void RunHybridQaoaTest() var simpleMaxCut = new ProblemInstance(dh, dJ); - var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut, numberOfRandomStartingPoints); - var optimalSolution = classicalOptimization.RunOptimization(); + var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut); + var optimalSolution = classicalOptimization.RunOptimization(numberOfRandomStartingPoints); var optimizationResult1 = new[] {false, true}; var optimizationResult2 = new[] {true, false}; @@ -72,11 +72,43 @@ public void RunHybridQaoaTest() if (result[0] == false) { - CollectionAssert.AreEqual(result, optimizationResult1, "Hybrid QAOA produced incorrect result."); + CollectionAssert.AreEqual(result, optimizationResult1, "Hybrid QAOA with random parameters produced incorrect result."); } else { - CollectionAssert.AreEqual(result, optimizationResult2, "Hybrid QAOA produced incorrect result."); + CollectionAssert.AreEqual(result, optimizationResult2, "Hybrid QAOA with random parameters produced incorrect result."); + } + } + + [TestMethod] + public void RunOptimizationUserParamsTest() + { + var dh = new double[] { 0, 0 }; + var dJ = new double[] { 0, 1, 0, 0 }; + + var numberOfIterations = 60; + var p = 3; + + var simpleMaxCut = new ProblemInstance(dh, dJ); + + var initialBeta = new double[] { 0, 0, 0 }; + var initialGamma = new double[] { 0, 0, 0 }; + + var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut); + var optimalSolution = classicalOptimization.RunOptimization(initialBeta, initialGamma); + + var optimizationResult1 = new[] { false, true }; + var optimizationResult2 = new[] { true, false }; + + var result = optimalSolution.SolutionVector; + + if (result[0] == false) + { + CollectionAssert.AreEqual(result, optimizationResult1, "Hybrid QAOA with user's parameters produced incorrect result."); + } + else + { + CollectionAssert.AreEqual(result, optimizationResult2, "Hybrid QAOA with user's parameters produced incorrect result."); } } } diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index cfdf6f5490e..511dd02897c 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -28,6 +28,8 @@ public async Task HybridQaoaRun() var p = 2; var oneLocalHamiltonianCoefficients = new double[] { 0, 0 }; var twoLocalHamiltonianCoefficients = new double[] { 0, 1, 0, 0}; + var initialBeta = new double[] {0, 0}; + var initialGamma = new double[] { 0, 0 }; var simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); @@ -35,7 +37,9 @@ public async Task HybridQaoaRun() { NumberOfIterations = numberOfIterations, p = p, - ProblemInstance = simpleMaxCut + ProblemInstance = simpleMaxCut, + InitialBeta = initialBeta, + InitialGamma = initialGamma }); var result = await magic.Run(args, channel); @@ -54,5 +58,49 @@ public async Task HybridQaoaRun() } } } - - } \ No newline at end of file + + public class HybridQaoaWithRandomParametersMagicTests + { + public (HybridQaoaWithRandomParametersRunMagic, MockChannel) Init() => + (new HybridQaoaWithRandomParametersRunMagic(), new MockChannel()); + + [Fact] + public async Task HybridQaoaRun() + { + var (magic, channel) = Init(); + Assert.Equal("%qaoa.hybridqaoa.random.params.run", magic.Name); + + var numberOfIterations = 50; + var p = 2; + var oneLocalHamiltonianCoefficients = new double[] { 0, 0 }; + var twoLocalHamiltonianCoefficients = new double[] { 0, 1, 0, 0 }; + var numberOfRandomStartingPoints = 2; + + var simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); + + var args = JsonConvert.SerializeObject(new HybridQaoaWithRandomParametersRunMagic.Arguments + { + NumberOfIterations = numberOfIterations, + p = p, + ProblemInstance = simpleMaxCut, + NumberOfRandomStartingPoints = numberOfRandomStartingPoints + }); + + var result = await magic.Run(args, channel); + var optimalSolution = result.Output as Solution; + Assert.Equal(ExecuteStatus.Ok, result.Status); + var optimizationResult1 = new[] { false, true }; + var optimizationResult2 = new[] { true, false }; + + if (optimalSolution.SolutionVector[0] == false) + { + CollectionAssert.AreEqual(optimalSolution.SolutionVector, optimizationResult1, "Hybrid QAOA produced incorrect result when running magic."); + } + else + { + CollectionAssert.AreEqual(optimalSolution.SolutionVector, optimizationResult2, "Hybrid QAOA produced incorrect result when running magic."); + } + } + } + +} \ No newline at end of file From f32871316d663d12c5e630492060b2ad78253f1c Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 22 Aug 2020 12:46:32 +0200 Subject: [PATCH 43/61] Disposable pattern for QaoaLogger implemented. Code refactoring. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 69 ++----------------- QAOA/src/Jupyter/HybridQaoaParametersMagic.cs | 54 +++++++++++++++ .../Jupyter/HybridQaoaProblemInstanceMagic.cs | 60 ++++++++++++++++ QAOA/src/Qaoa/{Utils.qs => PhaseKickback.qs} | 0 QAOA/src/QaoaHybrid/HybridQaoa.cs | 61 ++++++---------- QAOA/src/QaoaHybrid/QaoaLogger.cs | 18 ++++- QAOA/src/QaoaHybrid/QaoaParameters.cs | 47 +++++++++++++ QAOA/src/QaoaHybrid/Solution.cs | 20 ++---- QAOA/src/QaoaHybrid/Utils.cs | 33 --------- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 24 +------ .../HybridQaoaTests/ProblemInstanceTests.cs | 2 +- .../HybridQaoaParametersMagicTests.cs | 45 ++++++++++++ .../HybridQaoaProblemInstanceMagicTests.cs | 3 +- .../JupyterTests/HybridQaoaRunMagicTests.cs | 4 +- .../{UtilsTests.qs => PhaseKickbackTests.qs} | 2 +- 15 files changed, 261 insertions(+), 181 deletions(-) create mode 100644 QAOA/src/Jupyter/HybridQaoaParametersMagic.cs create mode 100644 QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs rename QAOA/src/Qaoa/{Utils.qs => PhaseKickback.qs} (100%) create mode 100644 QAOA/src/QaoaHybrid/QaoaParameters.cs create mode 100644 QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs rename QAOA/tests/QaoaTests/{UtilsTests.qs => PhaseKickbackTests.qs} (97%) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 9fc770ecf4f..f28734ff733 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -44,16 +44,10 @@ public class Arguments public ProblemInstance ProblemInstance { get; set; } /// - /// Initial beta angles. + /// Initial QAOA parameters (beta and gamma angles). /// - [JsonProperty(PropertyName = "initial_beta")] - public Double[] InitialBeta { get; set; } - - /// - /// Initial gamma angles. - /// - [JsonProperty(PropertyName = "initial_gamma")] - public Double[] InitialGamma { get; set; } + [JsonProperty(PropertyName = "initial_qaoa_parameters")] + public QaoaParameters InitialQaoaParameters { get; set; } /// /// Flag whether optimization should be logged into a file. @@ -77,7 +71,7 @@ public async Task Run(string input, IChannel channel) HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); - return hybridQaoa.RunOptimization(args.InitialBeta, args.InitialGamma).ToExecutionResult(); + return hybridQaoa.RunOptimization(args.InitialQaoaParameters).ToExecutionResult(); } } @@ -146,59 +140,4 @@ public async Task Run(string input, IChannel channel) return hybridQaoa.RunOptimization(args.NumberOfRandomStartingPoints).ToExecutionResult(); } } - - public class HybridQaoaProblemInstanceMagic : MagicSymbol - { - public HybridQaoaProblemInstanceMagic() - { - this.Name = $"%qaoa.hybridqaoa.create.problem.instance"; - this.Documentation = new Documentation() { Summary = "Prepares a problem instance objects that serves as one of arguments to %qaoa.hybridqaoa.run." }; - this.Kind = SymbolKind.Magic; - this.Execute = this.Run; - } - - /// - /// List of arguments. - /// - public class Arguments - { - /// - /// Coefficents for one-local Hamiltonian terms. - /// - [JsonProperty(PropertyName = "one_local_hamiltonian_coefficients")] - public double[] OneLocalHamiltonianCoefficients { get; set; } - - /// - /// Coefficents for one-local Hamiltonian terms. - /// - [JsonProperty(PropertyName = "two_local_hamiltonian_coefficients")] - public double[] TwoLocalHamiltonianCoefficients { get; set; } - - /// - /// Size of the combinatorial problem in bits. - /// - [JsonProperty(PropertyName = "problem_size_in_bits")] - public int ProblemSizeInBits { get; set; } - - } - - /// - /// Prepares a ProblemInstance object for a hybrid QAOA. - /// - public async Task Run(string input, IChannel channel) - { - if (string.IsNullOrWhiteSpace(input)) - { - channel.Stderr("Please provide correct arguments"); - return ExecuteStatus.Error.ToExecutionResult(); - } - - var args = JsonConvert.DeserializeObject(input); - - var problemInstance = new ProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); - - return problemInstance.ToExecutionResult(); - } - - } } diff --git a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs new file mode 100644 index 00000000000..f6c5a2e472d --- /dev/null +++ b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs @@ -0,0 +1,54 @@ +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Microsoft.Quantum.QAOA.QaoaHybrid; +using Newtonsoft.Json; + +namespace Microsoft.Quantum.QAOA.Jupyter +{ + public class HybridQaoaParametersMagic : MagicSymbol + { + public HybridQaoaParametersMagic() + { + this.Name = $"%qaoa.hybridqaoa.create.parameters"; + this.Documentation = new Documentation() { Summary = "Prepares a QAOA parameters object that serves as one of arguments to %qaoa.hybridqaoa.run." }; + this.Kind = SymbolKind.Magic; + this.Execute = this.Run; + } + + /// + /// List of arguments. + /// + public class Arguments + { + /// + /// Beta QAOA coefficients. + /// + [JsonProperty(PropertyName = "beta")] + public double[] Beta { get; set; } + + /// + /// Gamma QAOA coefficients. + /// + [JsonProperty(PropertyName = "gamma")] + public double[] Gamma { get; set; } + } + + /// + /// Prepares a QaoaParameters object for a hybrid QAOA. + /// + public async Task Run(string input, IChannel channel) + { + if (string.IsNullOrWhiteSpace(input)) + { + channel.Stderr("Please provide correct arguments"); + return ExecuteStatus.Error.ToExecutionResult(); + } + + var args = JsonConvert.DeserializeObject(input); + + var qaoaParameters = new QaoaParameters(args.Beta, args.Gamma); + + return qaoaParameters.ToExecutionResult(); + } + } +} diff --git a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs new file mode 100644 index 00000000000..728d044925b --- /dev/null +++ b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs @@ -0,0 +1,60 @@ +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Microsoft.Quantum.QAOA.QaoaHybrid; +using Newtonsoft.Json; + +namespace Microsoft.Quantum.QAOA.Jupyter +{ + public class HybridQaoaProblemInstanceMagic : MagicSymbol + { + public HybridQaoaProblemInstanceMagic() + { + this.Name = $"%qaoa.hybridqaoa.create.problem.instance"; + this.Documentation = new Documentation() { Summary = "Prepares a problem instance object that serves as one of arguments to %qaoa.hybridqaoa.run." }; + this.Kind = SymbolKind.Magic; + this.Execute = this.Run; + } + + /// + /// List of arguments. + /// + public class Arguments + { + /// + /// Coefficents for one-local Hamiltonian terms. + /// + [JsonProperty(PropertyName = "one_local_hamiltonian_coefficients")] + public double[] OneLocalHamiltonianCoefficients { get; set; } + + /// + /// Coefficents for one-local Hamiltonian terms. + /// + [JsonProperty(PropertyName = "two_local_hamiltonian_coefficients")] + public double[] TwoLocalHamiltonianCoefficients { get; set; } + + /// + /// Size of the combinatorial problem in bits. + /// + [JsonProperty(PropertyName = "problem_size_in_bits")] + public int ProblemSizeInBits { get; set; } + } + + /// + /// Prepares a ProblemInstance object for a hybrid QAOA. + /// + public async Task Run(string input, IChannel channel) + { + if (string.IsNullOrWhiteSpace(input)) + { + channel.Stderr("Please provide correct arguments"); + return ExecuteStatus.Error.ToExecutionResult(); + } + + var args = JsonConvert.DeserializeObject(input); + + var problemInstance = new ProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); + + return problemInstance.ToExecutionResult(); + } + } +} diff --git a/QAOA/src/Qaoa/Utils.qs b/QAOA/src/Qaoa/PhaseKickback.qs similarity index 100% rename from QAOA/src/Qaoa/Utils.qs rename to QAOA/src/Qaoa/PhaseKickback.qs diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 68c9c05ad72..c2b31edeaa7 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -75,20 +75,20 @@ public double EvaluateCostFunction(bool[] result, double[] costs) /// 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. /// - /// + /// /// Beta and gamma vectors concatenated. /// /// /// The expected value of a Hamiltonian that we calculated in this run. /// - private double CalculateObjectiveFunction(double[] bigFreeParamsVector) + private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) { - var freeParamsVector = Utils.ConvertVectorIntoHalves(bigFreeParamsVector); + var qaoaParameters = new QaoaParameters(concatenatedQaoaParameters); double hamiltonianExpectationValue = 0; var allSolutionVectors = new List(); - var beta = new QArray(freeParamsVector.Beta); - var gamma = new QArray(freeParamsVector.Gamma); + var beta = new QArray(qaoaParameters.Beta); + var gamma = new QArray(qaoaParameters.Gamma); var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.OneLocalHamiltonianCoefficients); var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.TwoLocalHamiltonianCoefficients); @@ -106,7 +106,7 @@ private double CalculateObjectiveFunction(double[] bigFreeParamsVector) } } - this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, freeParamsVector); + this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, qaoaParameters); if (this.shouldLog) { @@ -125,18 +125,17 @@ private double CalculateObjectiveFunction(double[] bigFreeParamsVector) /// /// A vector of all binary solutions that were found by a QAOA. /// - /// - /// A vector of beta and gamma coefficients. + /// + /// Beta and gamma coefficients. /// - private void UpdateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, Utils.FreeParameters freeParameters) + private void UpdateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, QaoaParameters qaoaParameters) { if (hamiltonianExpectationValue < this.solution.SolutionHamiltonianValue) { var mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); this.solution.SolutionHamiltonianValue = hamiltonianExpectationValue; this.solution.SolutionVector = mostProbableSolutionVectorTemp; - this.solution.SolutionBeta = freeParameters.Beta; - this.solution.SolutionGamma = freeParameters.Gamma; + this.solution.SolutionQaoaParameters = qaoaParameters; } } @@ -165,20 +164,6 @@ private NonlinearConstraint[] GenerateConstraints() return constraints; } - /// - /// We create random beta and gamma vectors. - /// - /// - /// Initialized beta and gamma vectors concatenated. - /// - private double[] SetUpRandomFreeParameters() - { - var betaCoefficients = Utils.GetRandomVector(this.p, Math.PI); - var gammaCoefficients = Utils.GetRandomVector(this.p, 2 * Math.PI); - - return betaCoefficients.Concat(gammaCoefficients).ToArray(); - } - /// /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum. /// @@ -199,7 +184,7 @@ public Solution RunOptimization(int numberOfRandomStartingPoints) this.logger = new QaoaLogger(); } - this.solution = new Solution(null, double.MaxValue, null, null); + this.solution = new Solution(null, double.MaxValue, null); Func objectiveFunction = this.CalculateObjectiveFunction; @@ -209,8 +194,8 @@ public Solution RunOptimization(int numberOfRandomStartingPoints) for (int i = 0; i < numberOfRandomStartingPoints; i++) { - var freeParameters = this.SetUpRandomFreeParameters(); - var success = cobyla.Minimize(freeParameters); + var concatenatedQaoaParameters = new QaoaParameters(p).getConcatenatedQaoaParameters(); + var success = cobyla.Minimize(concatenatedQaoaParameters); if (this.shouldLog) { @@ -220,7 +205,7 @@ public Solution RunOptimization(int numberOfRandomStartingPoints) if (this.shouldLog) { - this.logger.Close(); + this.logger.Dispose(); } return this.solution; @@ -229,12 +214,8 @@ public Solution RunOptimization(int numberOfRandomStartingPoints) /// /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. Initial beta and gamma parameters are provided by a user. /// - /// - /// A user-defined initial value of beta parameters. - /// - /// - /// A user-defined initial value of gamma parameters. - /// + /// + /// User-defined initial values of beta and gamma parameters. /// /// Optimal solution to the optimization problem input by the user. /// @@ -242,27 +223,27 @@ public Solution RunOptimization(int numberOfRandomStartingPoints) /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. /// The objective function Hamiltonian is based on Z operators, the range of values in the beta vector is 0 <= beta_i <= PI, the range of values in the gamma vector is 0 <= beta_i <= 2PI. /// - public Solution RunOptimization(double[] initialBeta, double[] initialGamma) + public Solution RunOptimization(QaoaParameters qaoaParameters) { if (this.shouldLog) { this.logger = new QaoaLogger(); } - this.solution = new Solution(null, double.MaxValue, null, null); + this.solution = new Solution(null, double.MaxValue, null); Func objectiveFunction = this.CalculateObjectiveFunction; var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); var constraints = this.GenerateConstraints(); var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - var freeParameters = initialBeta.Concat(initialGamma).ToArray(); - var success = cobyla.Minimize(freeParameters); + var concatenatedQaoaParameters = qaoaParameters.getConcatenatedQaoaParameters(); + var success = cobyla.Minimize(concatenatedQaoaParameters); if (this.shouldLog) { this.logger.LogSuccess(success); - this.logger.Close(); + this.logger.Dispose(); } return this.solution; diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index ab7a3b519d3..599fc42c0ca 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -12,7 +12,7 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid /// /// This class provides a simple capability for logging intermediate steps of a hybrid QAOA to a text file. /// - class QaoaLogger + class QaoaLogger : IDisposable { private readonly StreamWriter logger; @@ -65,12 +65,24 @@ public void LogSuccess(bool success) } + protected virtual void Dispose(bool disposing) + { + + if (disposing) + { + if (logger != null) + { + logger.Dispose(); + } + } + } + /// /// Closes a logger. /// - public void Close() + public void Dispose() { - this.logger.Close(); + Dispose(true); } } } diff --git a/QAOA/src/QaoaHybrid/QaoaParameters.cs b/QAOA/src/QaoaHybrid/QaoaParameters.cs new file mode 100644 index 00000000000..06cfbaa0007 --- /dev/null +++ b/QAOA/src/QaoaHybrid/QaoaParameters.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Quantum.Math; +using Newtonsoft.Json; + +namespace Microsoft.Quantum.QAOA.QaoaHybrid +{ + public class QaoaParameters + { + public double[] Beta { get; } + public double[] Gamma { get; } + + public QaoaParameters(double[] concatenatedQaoaParameters) + { + var size = concatenatedQaoaParameters.Length; + var vectorTermsNumber = size / 2; + Beta = concatenatedQaoaParameters[0..vectorTermsNumber]; + Gamma = concatenatedQaoaParameters[vectorTermsNumber..(2 * vectorTermsNumber)]; + } + + [JsonConstructor] + public QaoaParameters(double[] beta, double[] gamma) + { + Beta = beta; + Gamma = gamma; + } + + public QaoaParameters(int p) + { + Beta = Utils.GetRandomVector(p, System.Math.PI); + Gamma = Utils.GetRandomVector(p, 2 * System.Math.PI); + } + + /// + /// Converts beta and gamma vectors into a concatenated vector. + /// + /// + /// Array of concatenated beta and gamma arrays. + /// + public double[] getConcatenatedQaoaParameters() + { + return Beta.Concat(Gamma).ToArray(); + } + } +} diff --git a/QAOA/src/QaoaHybrid/Solution.cs b/QAOA/src/QaoaHybrid/Solution.cs index e37b4c71170..747de0f5e36 100644 --- a/QAOA/src/QaoaHybrid/Solution.cs +++ b/QAOA/src/QaoaHybrid/Solution.cs @@ -16,9 +16,7 @@ public class Solution public double SolutionHamiltonianValue { get; set; } - public double[] SolutionBeta { get; set; } - - public double[] SolutionGamma { get; set; } + public QaoaParameters SolutionQaoaParameters { get; set; } /// /// Initializes a new instance of the class. @@ -29,18 +27,14 @@ public class Solution /// /// An expected value of an objective function Hamiltonian that corresponds to the solution stored in solutionVector. /// - /// - /// Values of beta parameters that correspond to the solution stored in solutionVector. - /// - /// - /// Values of gamma parameters that corresponds to the solution stored in solutionVector. + /// + /// Values of beta and gamma parameters that correspond to the solution stored in solutionVector. /// - public Solution(bool[] solutionVector, double solutionHamiltonianValue, double[] solutionBeta, double[] solutionGamma) + public Solution(bool[] solutionVector, double solutionHamiltonianValue, QaoaParameters solutionQaoaParameters) { - this.SolutionVector = solutionVector; - this.SolutionHamiltonianValue = solutionHamiltonianValue; - this.SolutionBeta = solutionBeta; - this.SolutionGamma = solutionGamma; + SolutionVector = solutionVector; + SolutionHamiltonianValue = solutionHamiltonianValue; + SolutionQaoaParameters = solutionQaoaParameters; } diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs index e88c2c0c85c..8b5316c1a9e 100644 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ b/QAOA/src/QaoaHybrid/Utils.cs @@ -14,12 +14,6 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid public class Utils { - public struct FreeParameters - { - public double[] Beta; - public double[] Gamma; - } - /// /// Returns a vector of random doubles in a range from 0 to maximum. /// @@ -98,32 +92,5 @@ public static string GetBoolStringFromBoolArray(bool[] boolArray) return sb.ToString(); } - - /// - /// Converts concatenated beta and gamma vectors into separate beta and gamma vector. - /// - /// - /// Concatenated beta and gamma vectors. - /// - /// - /// FreeParameters that contains beta and gamma vectors. - /// - /// - /// Useful for getting beta and gamma vectors from a concatenated vector inside the optimized function. - /// - public static FreeParameters ConvertVectorIntoHalves(double[] bigFreeParamsVector) - { - var size = bigFreeParamsVector.Length; - var vectorTermsNumber = size / 2; - var freeParamsVector = new FreeParameters - { - - Beta = bigFreeParamsVector[0..vectorTermsNumber], - Gamma = bigFreeParamsVector[vectorTermsNumber..(2 * vectorTermsNumber)], - - }; - - return freeParamsVector; - } } } \ No newline at end of file diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index d3637553859..513616650f5 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -12,26 +12,6 @@ namespace Microsoft.Quantum.QAOA.HybridQaoaTests public class ClassicalOptimizationTest { - [TestMethod] - public void ConvertDataVectorToVectorsTest() - { - - var result = Utils.ConvertVectorIntoHalves(new Double[] { 1, 2, 3, 4, 5, 6 }); - - var dataVectors = new Utils.FreeParameters - { - Beta = new double[] { 1, 2, 3 }, - Gamma = new double[] { 4, 5, 6 } - }; - - var expectedResult = dataVectors; - - CollectionAssert.AreEqual(expectedResult.Beta, result.Beta, "Hamiltonian beta value not calculated correctly."); - CollectionAssert.AreEqual(expectedResult.Gamma, result.Gamma, "Hamiltonian gamma value not calculated correctly."); - - } - - [TestMethod] public void EvaluateCostFunctionTest() { @@ -94,8 +74,10 @@ public void RunOptimizationUserParamsTest() var initialBeta = new double[] { 0, 0, 0 }; var initialGamma = new double[] { 0, 0, 0 }; + var qaoaParameters = new QaoaParameters(initialBeta, initialGamma); + var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut); - var optimalSolution = classicalOptimization.RunOptimization(initialBeta, initialGamma); + var optimalSolution = classicalOptimization.RunOptimization(qaoaParameters); var optimizationResult1 = new[] { false, true }; var optimizationResult2 = new[] { true, false }; diff --git a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs index 063fa96307f..8564c6711ae 100644 --- a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs +++ b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs @@ -17,7 +17,7 @@ public void EvaluateHamiltonianTest() { var problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); - var result = problemInstance.EvaluateHamiltonian(new bool[] {false,false,true,true}); + var result = problemInstance.EvaluateHamiltonian(new [] {false,false,true,true}); const int expectedResult = -1; diff --git a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs new file mode 100644 index 00000000000..433bddf89ee --- /dev/null +++ b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Newtonsoft.Json; +using Xunit; +using Microsoft.Quantum.QAOA.JupyterTests; +using Microsoft.Quantum.QAOA.QaoaHybrid; +using Microsoft.Quantum.QAOA.Jupyter; + +namespace Microsoft.Quantum.QAOA.JupyterTests +{ + + public class HybridQaoaParametersMagicTests + { + public (HybridQaoaParametersMagic, MockChannel) Init() => + (new HybridQaoaParametersMagic(), new MockChannel()); + + [Fact] + public async Task HybridQaoaProblemInstance() + { + var (magic, channel) = Init(); + Assert.Equal("%qaoa.hybridqaoa.create.parameters", magic.Name); + + var beta = new double[] { 1, 2, 3 }; + var gamma = new double[] { 5, 6, 7 }; + + + var args = JsonConvert.SerializeObject(new HybridQaoaParametersMagic.Arguments + { + Beta = beta, + Gamma = gamma + }); + + var result = await magic.Run(args, channel); + var qaoaParameters = result.Output as QaoaParameters; + Assert.Equal(ExecuteStatus.Ok, result.Status); + + Assert.Equal(qaoaParameters.Beta, beta); + Assert.Equal(qaoaParameters.Gamma, gamma); + } + + } +} \ No newline at end of file diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index 73509393025..4c3656f178d 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -5,12 +5,11 @@ using Microsoft.Jupyter.Core; using Newtonsoft.Json; using Xunit; -using System; using Microsoft.Quantum.QAOA.JupyterTests; using Microsoft.Quantum.QAOA.QaoaHybrid; using Microsoft.Quantum.QAOA.Jupyter; -namespace Microsoft.Quantum.QAOA.HybridQaoaTests +namespace Microsoft.Quantum.QAOA.JupyterTests { public class HybridQaoaProblemInstanceMagicTests diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 511dd02897c..46bd4db93a0 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -30,6 +30,7 @@ public async Task HybridQaoaRun() var twoLocalHamiltonianCoefficients = new double[] { 0, 1, 0, 0}; var initialBeta = new double[] {0, 0}; var initialGamma = new double[] { 0, 0 }; + var initialQaoaParameters = new QaoaParameters(initialBeta, initialGamma); var simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); @@ -38,8 +39,7 @@ public async Task HybridQaoaRun() NumberOfIterations = numberOfIterations, p = p, ProblemInstance = simpleMaxCut, - InitialBeta = initialBeta, - InitialGamma = initialGamma + InitialQaoaParameters = initialQaoaParameters, }); var result = await magic.Run(args, channel); diff --git a/QAOA/tests/QaoaTests/UtilsTests.qs b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs similarity index 97% rename from QAOA/tests/QaoaTests/UtilsTests.qs rename to QAOA/tests/QaoaTests/PhaseKickbackTests.qs index 5f0ca6c8197..6c6b1647e73 100644 --- a/QAOA/tests/QaoaTests/UtilsTests.qs +++ b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Microsoft.Quantum.Tests { From 2cf93caefc6f6656f6113c57b0a20da3320e9b4f Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sat, 22 Aug 2020 15:00:26 +0200 Subject: [PATCH 44/61] Code refactoring. --- QAOA/src/Jupyter/HybridQaoaParametersMagic.cs | 11 ++- .../Jupyter/HybridQaoaProblemInstanceMagic.cs | 11 ++- .../Helpers/ArrayToStringConverter.cs | 30 ++++++ QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs | 46 +++++++++ .../Helpers/RandomVectorGenerator.cs | 34 +++++++ QAOA/src/QaoaHybrid/HybridQaoa.cs | 13 +-- QAOA/src/QaoaHybrid/QaoaLogger.cs | 3 +- QAOA/src/QaoaHybrid/QaoaParameters.cs | 16 ++-- .../{Solution.cs => QaoaSolution.cs} | 6 +- QAOA/src/QaoaHybrid/Utils.cs | 96 ------------------- .../ArrayToStringConverterTests.cs | 27 ++++++ QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 6 +- .../{UtilsTests.cs => ModeFinderTests.cs} | 28 ++---- .../HybridQaoaTests/ProblemInstanceTests.cs | 9 +- .../HybridQaoaParametersMagicTests.cs | 14 ++- .../HybridQaoaProblemInstanceMagicTests.cs | 14 ++- .../JupyterTests/HybridQaoaRunMagicTests.cs | 23 +++-- QAOA/tests/JupyterTests/MockChannel.cs | 8 +- 18 files changed, 210 insertions(+), 185 deletions(-) create mode 100644 QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs create mode 100644 QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs create mode 100644 QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs rename QAOA/src/QaoaHybrid/{Solution.cs => QaoaSolution.cs} (87%) delete mode 100644 QAOA/src/QaoaHybrid/Utils.cs create mode 100644 QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs rename QAOA/tests/HybridQaoaTests/{UtilsTests.cs => ModeFinderTests.cs} (56%) diff --git a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs index f6c5a2e472d..c881f7d9181 100644 --- a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs @@ -1,10 +1,13 @@ -using System.Threading.Tasks; -using Microsoft.Jupyter.Core; -using Microsoft.Quantum.QAOA.QaoaHybrid; -using Newtonsoft.Json; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. namespace Microsoft.Quantum.QAOA.Jupyter { + using System.Threading.Tasks; + using Microsoft.Jupyter.Core; + using Microsoft.Quantum.QAOA.QaoaHybrid; + using Newtonsoft.Json; + public class HybridQaoaParametersMagic : MagicSymbol { public HybridQaoaParametersMagic() diff --git a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs index 728d044925b..40e47ce2ce4 100644 --- a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs @@ -1,10 +1,13 @@ -using System.Threading.Tasks; -using Microsoft.Jupyter.Core; -using Microsoft.Quantum.QAOA.QaoaHybrid; -using Newtonsoft.Json; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. namespace Microsoft.Quantum.QAOA.Jupyter { + using System.Threading.Tasks; + using Microsoft.Jupyter.Core; + using Microsoft.Quantum.QAOA.QaoaHybrid; + using Newtonsoft.Json; + public class HybridQaoaProblemInstanceMagic : MagicSymbol { public HybridQaoaProblemInstanceMagic() diff --git a/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs new file mode 100644 index 00000000000..e2ff95f7370 --- /dev/null +++ b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid.Helpers +{ + using System.Text; + + public class ArrayToStringConverter + { + /// + /// Converts an array of bools to a boolean string. + /// + /// + /// An array of bools. + /// + /// + /// A boolean string. + /// + public static string ConvertBoolArrayToString(bool[] boolArray) + { + var sb = new StringBuilder(); + foreach (var b in boolArray) + { + sb.Append(b ? "1" : "0"); + } + + return sb.ToString(); + } + } +} diff --git a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs new file mode 100644 index 00000000000..5ed5cb613fa --- /dev/null +++ b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid.Helpers +{ + using System.Collections.Generic; + using System.Linq; + + public class ModeFinder + { + /// + /// Return the most common boolean string from a list of boolean values. + /// + /// + /// List of boolean values. + /// + /// + /// The most common boolean string. + /// + public static bool[] FindModeInBoolList(List list) + { + var counter = new Dictionary(); + foreach (var boolString in list.Select(ArrayToStringConverter.ConvertBoolArrayToString)) + { + if (counter.ContainsKey(boolString)) + { + counter[boolString] += 1; + } + else + { + counter[boolString] = 1; + } + } + + var maximum = 0; + string result = null; + foreach (var key in counter.Keys.Where(key => counter[key] > maximum)) + { + maximum = counter[key]; + result = key; + } + + return result.Select(chr => chr == '1').ToArray(); + } + } +} \ No newline at end of file diff --git a/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs new file mode 100644 index 00000000000..d23d03d5b44 --- /dev/null +++ b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.QaoaHybrid.Helpers +{ + using System; + + public class RandomVectorGenerator + { + /// + /// Returns a vector of random doubles in a range from 0 to maximum. + /// + /// + /// Length of a random vector. + /// + /// + /// Maximum value of a random double. + /// + /// + /// A random vector of doubles. + /// + public static double[] GenerateRandomVector(int length, double maximumValue) + { + var rand = new Random(); + double[] randomVector = new double[length]; + for (var i = 0; i < length; i++) + { + randomVector[i] = maximumValue * rand.NextDouble(); + } + + return randomVector; + } + } +} diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index c2b31edeaa7..d5ca9871840 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -11,6 +11,7 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid using Microsoft.Quantum.QAOA; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; + using Microsoft.Quantum.QAOA.QaoaHybrid.Helpers; /// /// This class runs a hybrid (quantum-classical) QAOA given an instance of a combinatorial optimization problem encoded into a 2-local Hamiltonian. The classical part is used for optimizing QAOA input parameters and is implemented using the Cobyla optimizer. QAOA input parameters can be optionally specified by a user and they will be treated as a starting point for optimization. Otherwise, input parameters are initialized randomly (possibly many times, as specified by the numberOfRandomStartingPoints variable). @@ -21,7 +22,7 @@ public class HybridQaoa private readonly int p; private readonly ProblemInstance problemInstance; private readonly bool shouldLog; - private Solution solution; + private QaoaSolution solution; private QaoaLogger logger; /// @@ -132,7 +133,7 @@ private void UpdateBestSolution(double hamiltonianExpectationValue, List { if (hamiltonianExpectationValue < this.solution.SolutionHamiltonianValue) { - var mostProbableSolutionVectorTemp = Utils.GetModeFromBoolList(allSolutionVectors); + var mostProbableSolutionVectorTemp = ModeFinder.FindModeInBoolList(allSolutionVectors); this.solution.SolutionHamiltonianValue = hamiltonianExpectationValue; this.solution.SolutionVector = mostProbableSolutionVectorTemp; this.solution.SolutionQaoaParameters = qaoaParameters; @@ -177,14 +178,14 @@ private NonlinearConstraint[] GenerateConstraints() /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. /// The objective function Hamiltonian is based on Z operators, the range of values in the beta vector is 0 <= beta_i <= PI, the range of values in the gamma vector is 0 <= beta_i <= 2PI. /// - public Solution RunOptimization(int numberOfRandomStartingPoints) + public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) { if (this.shouldLog) { this.logger = new QaoaLogger(); } - this.solution = new Solution(null, double.MaxValue, null); + this.solution = new QaoaSolution(null, double.MaxValue, null); Func objectiveFunction = this.CalculateObjectiveFunction; @@ -223,14 +224,14 @@ public Solution RunOptimization(int numberOfRandomStartingPoints) /// Currently used optimizer is Cobyla which is a gradient-free optimization technique. /// The objective function Hamiltonian is based on Z operators, the range of values in the beta vector is 0 <= beta_i <= PI, the range of values in the gamma vector is 0 <= beta_i <= 2PI. /// - public Solution RunOptimization(QaoaParameters qaoaParameters) + public QaoaSolution RunOptimization(QaoaParameters qaoaParameters) { if (this.shouldLog) { this.logger = new QaoaLogger(); } - this.solution = new Solution(null, double.MaxValue, null); + this.solution = new QaoaSolution(null, double.MaxValue, null); Func objectiveFunction = this.CalculateObjectiveFunction; var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 599fc42c0ca..30bcbcaf991 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -1,13 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using System.Linq; - namespace Microsoft.Quantum.QAOA.QaoaHybrid { using System; using System.IO; using Microsoft.Quantum.Simulation.Core; + using System.Linq; /// /// This class provides a simple capability for logging intermediate steps of a hybrid QAOA to a text file. diff --git a/QAOA/src/QaoaHybrid/QaoaParameters.cs b/QAOA/src/QaoaHybrid/QaoaParameters.cs index 06cfbaa0007..b2118ab7013 100644 --- a/QAOA/src/QaoaHybrid/QaoaParameters.cs +++ b/QAOA/src/QaoaHybrid/QaoaParameters.cs @@ -1,12 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.Quantum.Math; -using Newtonsoft.Json; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. namespace Microsoft.Quantum.QAOA.QaoaHybrid { + using System.Linq; + using Newtonsoft.Json; + using Microsoft.Quantum.QAOA.QaoaHybrid.Helpers; + public class QaoaParameters { public double[] Beta { get; } @@ -29,8 +29,8 @@ public QaoaParameters(double[] beta, double[] gamma) public QaoaParameters(int p) { - Beta = Utils.GetRandomVector(p, System.Math.PI); - Gamma = Utils.GetRandomVector(p, 2 * System.Math.PI); + Beta = RandomVectorGenerator.GenerateRandomVector(p, System.Math.PI); + Gamma = RandomVectorGenerator.GenerateRandomVector(p, 2 * System.Math.PI); } /// diff --git a/QAOA/src/QaoaHybrid/Solution.cs b/QAOA/src/QaoaHybrid/QaoaSolution.cs similarity index 87% rename from QAOA/src/QaoaHybrid/Solution.cs rename to QAOA/src/QaoaHybrid/QaoaSolution.cs index 747de0f5e36..6e5f4e38753 100644 --- a/QAOA/src/QaoaHybrid/Solution.cs +++ b/QAOA/src/QaoaHybrid/QaoaSolution.cs @@ -9,7 +9,7 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid /// /// Note that given the nature of a QAOA and a hybrid QAOA, a solution produced by the algorithm is not necessarily feasible and not necessarily optimal. /// - public class Solution + public class QaoaSolution { public bool[] SolutionVector { get; set; } @@ -19,7 +19,7 @@ public class Solution public QaoaParameters SolutionQaoaParameters { get; set; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// A vector that is a solution of a combinatorial optimization problem found by a hybrid QAOA. @@ -30,7 +30,7 @@ public class Solution /// /// Values of beta and gamma parameters that correspond to the solution stored in solutionVector. /// - public Solution(bool[] solutionVector, double solutionHamiltonianValue, QaoaParameters solutionQaoaParameters) + public QaoaSolution(bool[] solutionVector, double solutionHamiltonianValue, QaoaParameters solutionQaoaParameters) { SolutionVector = solutionVector; SolutionHamiltonianValue = solutionHamiltonianValue; diff --git a/QAOA/src/QaoaHybrid/Utils.cs b/QAOA/src/QaoaHybrid/Utils.cs deleted file mode 100644 index 8b5316c1a9e..00000000000 --- a/QAOA/src/QaoaHybrid/Utils.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Microsoft.Quantum.QAOA.QaoaHybrid -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - - /// - /// This class provides auxiliary methods for a hybrid QAOA. - /// - public class Utils - { - - /// - /// Returns a vector of random doubles in a range from 0 to maximum. - /// - /// - /// Length of a random vector. - /// - /// - /// Maximum value of a random double. - /// - /// - /// A random vector of doubles. - /// - public static double[] GetRandomVector(int length, double maximumValue) - { - var rand = new Random(); - double[] randomVector = new double[length]; - for (var i = 0; i < length; i++) - { - randomVector[i] = maximumValue * rand.NextDouble(); - } - - return randomVector; - } - - /// - /// Return the most common boolean string from a list of boolean values. - /// - /// - /// List of boolean values. - /// - /// - /// The most common boolean string. - /// - public static bool[] GetModeFromBoolList(List list) - { - var counter = new Dictionary(); - foreach (var boolString in list.Select(GetBoolStringFromBoolArray)) - { - if (counter.ContainsKey(boolString)) - { - counter[boolString] += 1; - } - else - { - counter[boolString] = 1; - } - } - - var maximum = 0; - string result = null; - foreach (var key in counter.Keys.Where(key => counter[key] > maximum)) - { - maximum = counter[key]; - result = key; - } - - return result.Select(chr => chr == '1').ToArray(); - } - - /// - /// Converts an array of bools to a boolean string. - /// - /// - /// An array of bools. - /// - /// - /// A boolean string. - /// - public static string GetBoolStringFromBoolArray(bool[] boolArray) - { - var sb = new StringBuilder(); - foreach (var b in boolArray) - { - sb.Append(b ? "1" : "0"); - } - - return sb.ToString(); - } - } -} \ No newline at end of file diff --git a/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs b/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs new file mode 100644 index 00000000000..a71fc65cabc --- /dev/null +++ b/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.QAOA.HybridQaoaTests +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using QAOA.QaoaHybrid.Helpers; + + [TestClass] + class ArrayToStringConverterTests + { + [TestMethod] + public void ConvertBoolArrayToStringTest() + { + var boolsArray = new[] { false, false, true }; + + var expectedResult = "001"; + + var result = ArrayToStringConverter.ConvertBoolArrayToString(boolsArray); + + Assert.AreEqual(expectedResult, result, "Bool string not created correctly."); + + + } + + } +} diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index 513616650f5..f3ecae442d9 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -1,12 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using Microsoft.Quantum.QAOA.QaoaHybrid; - namespace Microsoft.Quantum.QAOA.HybridQaoaTests { + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Microsoft.Quantum.QAOA.QaoaHybrid; [TestClass] public class ClassicalOptimizationTest diff --git a/QAOA/tests/HybridQaoaTests/UtilsTests.cs b/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs similarity index 56% rename from QAOA/tests/HybridQaoaTests/UtilsTests.cs rename to QAOA/tests/HybridQaoaTests/ModeFinderTests.cs index 883ce71b284..da3e4d98f30 100644 --- a/QAOA/tests/HybridQaoaTests/UtilsTests.cs +++ b/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs @@ -1,17 +1,17 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Collections.Generic; -using Microsoft.Quantum.QAOA.QaoaHybrid; - namespace Microsoft.Quantum.QAOA.HybridQaoaTests { + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + using Microsoft.Quantum.QAOA.QaoaHybrid.Helpers; + [TestClass] - public class UtilsTests + public class ModeFinderTests { [TestMethod] - public void ModeOfABoolListTest() + public void FindModeInBoolListTest() { bool[] boolsArray1 = { false, false, true }; bool[] boolsArray2 = { false, false, true }; @@ -28,25 +28,11 @@ public void ModeOfABoolListTest() var expectedResult = new[] {false, false, true}; - var result = Utils.GetModeFromBoolList(listOfBools); + var result = ModeFinder.FindModeInBoolList(listOfBools); CollectionAssert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); - } - - [TestMethod] - public void BoolStringFromBoolArrayTest() - { - var boolsArray = new [] { false, false, true }; - - var expectedResult = "001"; - - var result = Utils.GetBoolStringFromBoolArray(boolsArray); - - Assert.AreEqual(expectedResult, result, "Bool string not created correctly."); - - } } } diff --git a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs index 8564c6711ae..e213246575e 100644 --- a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs +++ b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.Quantum.QAOA.QaoaHybrid; -using Microsoft.VisualStudio.TestTools.UnitTesting; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. namespace Microsoft.Quantum.QAOA.HybridQaoaTests { + using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] class ProblemInstanceTests diff --git a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs index 433bddf89ee..4ee1a21439d 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs @@ -1,16 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Threading.Tasks; -using Microsoft.Jupyter.Core; -using Newtonsoft.Json; -using Xunit; -using Microsoft.Quantum.QAOA.JupyterTests; -using Microsoft.Quantum.QAOA.QaoaHybrid; -using Microsoft.Quantum.QAOA.Jupyter; - namespace Microsoft.Quantum.QAOA.JupyterTests { + using System.Threading.Tasks; + using Microsoft.Jupyter.Core; + using Newtonsoft.Json; + using Xunit; + using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.QAOA.Jupyter; public class HybridQaoaParametersMagicTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index 4c3656f178d..d01f47ccb24 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -1,16 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Threading.Tasks; -using Microsoft.Jupyter.Core; -using Newtonsoft.Json; -using Xunit; -using Microsoft.Quantum.QAOA.JupyterTests; -using Microsoft.Quantum.QAOA.QaoaHybrid; -using Microsoft.Quantum.QAOA.Jupyter; - namespace Microsoft.Quantum.QAOA.JupyterTests { + using System.Threading.Tasks; + using Microsoft.Jupyter.Core; + using Newtonsoft.Json; + using Xunit; + using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.QAOA.Jupyter; public class HybridQaoaProblemInstanceMagicTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 46bd4db93a0..0483f654581 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -1,18 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Threading.Tasks; -using Microsoft.Jupyter.Core; -using Newtonsoft.Json; -using System; -using Microsoft.Quantum.QAOA.QaoaHybrid; -using Xunit; -using Microsoft.Quantum.QAOA.Jupyter; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Assert = Xunit.Assert; - namespace Microsoft.Quantum.QAOA.JupyterTests { + using System.Threading.Tasks; + using Microsoft.Jupyter.Core; + using Newtonsoft.Json; + using Microsoft.Quantum.QAOA.QaoaHybrid; + using Xunit; + using Microsoft.Quantum.QAOA.Jupyter; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Assert = Xunit.Assert; + public class HybridQaoaRunMagicTests { public (HybridQaoaRunMagic, MockChannel) Init() => @@ -43,7 +42,7 @@ public async Task HybridQaoaRun() }); var result = await magic.Run(args, channel); - var optimalSolution = result.Output as Solution; + var optimalSolution = result.Output as QaoaSolution; Assert.Equal(ExecuteStatus.Ok, result.Status); var optimizationResult1 = new[] {false, true}; var optimizationResult2 = new[] {true, false}; @@ -87,7 +86,7 @@ public async Task HybridQaoaRun() }); var result = await magic.Run(args, channel); - var optimalSolution = result.Output as Solution; + var optimalSolution = result.Output as QaoaSolution; Assert.Equal(ExecuteStatus.Ok, result.Status); var optimizationResult1 = new[] { false, true }; var optimizationResult2 = new[] { true, false }; diff --git a/QAOA/tests/JupyterTests/MockChannel.cs b/QAOA/tests/JupyterTests/MockChannel.cs index 1a91649bcbc..97224929150 100644 --- a/QAOA/tests/JupyterTests/MockChannel.cs +++ b/QAOA/tests/JupyterTests/MockChannel.cs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -using System; -using System.Collections.Generic; -using Microsoft.Jupyter.Core; - namespace Microsoft.Quantum.QAOA.JupyterTests { + using System; + using System.Collections.Generic; + using Microsoft.Jupyter.Core; + public class MockChannel : IChannel { public List errors = new List(); From 9db4c4e808f0dc04f45018fdac6fe377eba2c8e4 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 09:13:50 +0200 Subject: [PATCH 45/61] Copyright headers fix. --- QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs | 2 +- QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs | 2 +- QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs index 4ee1a21439d..829b4fe030b 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Microsoft.Quantum.QAOA.JupyterTests diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index d01f47ccb24..b4395343e9e 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Microsoft.Quantum.QAOA.JupyterTests diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 0483f654581..3df076ac35b 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Microsoft.Quantum.QAOA.JupyterTests From 7951491fbf1648b673a305fa3596022c3892a48a Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 09:24:58 +0200 Subject: [PATCH 46/61] Documentation and naming improved. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 10 ++++++-- QAOA/src/Jupyter/HybridQaoaParametersMagic.cs | 9 ++++--- .../Jupyter/HybridQaoaProblemInstanceMagic.cs | 5 +++- QAOA/src/Qaoa/EvolutionOperations.qs | 4 ++-- QAOA/src/Qaoa/QaoaRunner.qs | 10 ++++---- QAOA/src/QaoaHybrid/HybridQaoa.cs | 12 +++++----- QAOA/src/QaoaHybrid/QaoaParameters.cs | 24 +++++++++---------- .../HybridQaoaParametersMagicTests.cs | 4 ++-- 8 files changed, 45 insertions(+), 33 deletions(-) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index f28734ff733..0f55431561d 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -15,7 +15,10 @@ public class HybridQaoaRunMagic : MagicSymbol public HybridQaoaRunMagic() { this.Name = $"%qaoa.hybridqaoa.run"; - this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json. Initial beta and gamma coefficients are provided by a user." }; + this.Documentation = new Documentation() + { + Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as JSON input. Initial beta and gamma coefficients are provided by a user." + }; this.Kind = SymbolKind.Magic; this.Execute = this.Run; } @@ -81,7 +84,10 @@ public class HybridQaoaWithRandomParametersRunMagic : MagicSymbol public HybridQaoaWithRandomParametersRunMagic() { this.Name = $"%qaoa.hybridqaoa.random.params.run"; - this.Documentation = new Documentation() { Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a json. Initial beta and gamma parameters are chosen randomly." }; + this.Documentation = new Documentation() + { + Summary = "Runs a hybrid QAOA algorithm with a classical optimizer that chooses input angles. QAOA parameters are provided as a JSON. Initial beta and gamma parameters are chosen randomly." + }; this.Kind = SymbolKind.Magic; this.Execute = this.Run; } diff --git a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs index c881f7d9181..ea460b1b7b7 100644 --- a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs @@ -13,7 +13,10 @@ public class HybridQaoaParametersMagic : MagicSymbol public HybridQaoaParametersMagic() { this.Name = $"%qaoa.hybridqaoa.create.parameters"; - this.Documentation = new Documentation() { Summary = "Prepares a QAOA parameters object that serves as one of arguments to %qaoa.hybridqaoa.run." }; + this.Documentation = new Documentation() + { + Summary = "Prepares a QAOA parameters object that serves as one of arguments to %qaoa.hybridqaoa.run." + }; this.Kind = SymbolKind.Magic; this.Execute = this.Run; } @@ -24,13 +27,13 @@ public HybridQaoaParametersMagic() public class Arguments { /// - /// Beta QAOA coefficients. + /// Betas QAOA coefficients. /// [JsonProperty(PropertyName = "beta")] public double[] Beta { get; set; } /// - /// Gamma QAOA coefficients. + /// Gammas QAOA coefficients. /// [JsonProperty(PropertyName = "gamma")] public double[] Gamma { get; set; } diff --git a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs index 40e47ce2ce4..3136ee55bf6 100644 --- a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs @@ -13,7 +13,10 @@ public class HybridQaoaProblemInstanceMagic : MagicSymbol public HybridQaoaProblemInstanceMagic() { this.Name = $"%qaoa.hybridqaoa.create.problem.instance"; - this.Documentation = new Documentation() { Summary = "Prepares a problem instance object that serves as one of arguments to %qaoa.hybridqaoa.run." }; + this.Documentation = new Documentation() + { + Summary = "Prepares a problem instance object that serves as one of arguments to %qaoa.hybridqaoa.run." + }; this.Kind = SymbolKind.Magic; this.Execute = this.Run; } diff --git a/QAOA/src/Qaoa/EvolutionOperations.qs b/QAOA/src/Qaoa/EvolutionOperations.qs index 442126a3df5..72ac98ce3e0 100644 --- a/QAOA/src/Qaoa/EvolutionOperations.qs +++ b/QAOA/src/Qaoa/EvolutionOperations.qs @@ -13,7 +13,7 @@ namespace Microsoft.Quantum.QAOA { /// ## qubits /// Qubits that will be transformed by a unitary. /// ## beta - /// Vector of coefficents for the unitary based on the mixing Hamiltonian. + /// Coefficent for the unitary based on the mixing Hamiltonian. /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. operation EvolveWithMixingHamiltonian(qubits: Qubit[], beta: Double) : Unit is Adj + Ctl { @@ -27,7 +27,7 @@ namespace Microsoft.Quantum.QAOA { /// ## qubits /// Qubits that will be transformed by a unitary. /// ## gamma - /// Vector of coefficents for the unitary based on the objective function Hamiltonian. + /// Coefficent for the unitary based on the objective function Hamiltonian. /// ## oneLocalHamiltonianCoefficients /// Array of 1-local coefficents of the objective function Hamiltonian. /// ## twoLocalHamiltonianCoefficients diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index b7359843c0f..b4f1d1e6f0d 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -16,9 +16,9 @@ namespace Microsoft.Quantum.QAOA { /// # Input /// ## problemSize /// Number of qubits. - /// ## beta + /// ## betas /// Vector of coefficents for the unitary based on the mixing Hamiltonian. - /// ## gamma + /// ## gammas /// Vector of coefficents for the unitary based on the objective function Hamiltonian. /// ## oneLocalHamiltonianCoefficients /// Array of 1-local coefficents of the objective function Hamiltonian. @@ -32,14 +32,14 @@ namespace Microsoft.Quantum.QAOA { /// /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - operation RunQaoa(problemSize: Int, beta: Double[], gamma: Double[], oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[], p: Int) : Bool[] { + operation RunQaoa(problemSize: Int, betas: Double[], gammas: Double[], oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[], p: Int) : Bool[] { mutable result = new Bool[problemSize]; using (qubits = Qubit[problemSize]) { ApplyToEach(H, qubits); for (i in 0..p-1) { - EvolveWithObjectiveHamiltonian(qubits, gamma[i], oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - EvolveWithMixingHamiltonian(qubits, beta[i]); + EvolveWithObjectiveHamiltonian(qubits, gammas[i], oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); + EvolveWithMixingHamiltonian(qubits, betas[i]); } return ResultArrayAsBoolArray(ForEach(MResetZ, qubits)); } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index d5ca9871840..7acf4f092c1 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -77,7 +77,7 @@ public double EvaluateCostFunction(bool[] result, double[] costs) /// 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. /// /// - /// Beta and gamma vectors concatenated. + /// Betas and gamma vectors concatenated. /// /// /// The expected value of a Hamiltonian that we calculated in this run. @@ -88,8 +88,8 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) double hamiltonianExpectationValue = 0; var allSolutionVectors = new List(); - var beta = new QArray(qaoaParameters.Beta); - var gamma = new QArray(qaoaParameters.Gamma); + var betas = new QArray(qaoaParameters.Betas); + var gammas = new QArray(qaoaParameters.Gammas); var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.OneLocalHamiltonianCoefficients); var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.TwoLocalHamiltonianCoefficients); @@ -99,7 +99,7 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) for (var i = 0; i < this.numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, this.problemInstance.ProblemSizeInBits, beta, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; + IQArray result = RunQaoa.Run(qsim, this.problemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; allSolutionVectors.Add(result.ToArray()); var hamiltonianValue = this.problemInstance.EvaluateHamiltonian(result.ToArray()); hamiltonianExpectationValue += hamiltonianValue / this.numberOfIterations; @@ -111,7 +111,7 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) if (this.shouldLog) { - this.logger.LogCurrentBestSolution(beta, gamma, this.solution.SolutionHamiltonianValue, this.solution.SolutionVector); + this.logger.LogCurrentBestSolution(betas, gammas, this.solution.SolutionHamiltonianValue, this.solution.SolutionVector); } return hamiltonianExpectationValue; @@ -127,7 +127,7 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) /// A vector of all binary solutions that were found by a QAOA. /// /// - /// Beta and gamma coefficients. + /// Betas and gamma coefficients. /// private void UpdateBestSolution(double hamiltonianExpectationValue, List allSolutionVectors, QaoaParameters qaoaParameters) { diff --git a/QAOA/src/QaoaHybrid/QaoaParameters.cs b/QAOA/src/QaoaHybrid/QaoaParameters.cs index b2118ab7013..526f078252d 100644 --- a/QAOA/src/QaoaHybrid/QaoaParameters.cs +++ b/QAOA/src/QaoaHybrid/QaoaParameters.cs @@ -9,39 +9,39 @@ namespace Microsoft.Quantum.QAOA.QaoaHybrid public class QaoaParameters { - public double[] Beta { get; } - public double[] Gamma { get; } + public double[] Betas { get; } + public double[] Gammas { get; } public QaoaParameters(double[] concatenatedQaoaParameters) { var size = concatenatedQaoaParameters.Length; var vectorTermsNumber = size / 2; - Beta = concatenatedQaoaParameters[0..vectorTermsNumber]; - Gamma = concatenatedQaoaParameters[vectorTermsNumber..(2 * vectorTermsNumber)]; + Betas = concatenatedQaoaParameters[0..vectorTermsNumber]; + Gammas = concatenatedQaoaParameters[vectorTermsNumber..(2 * vectorTermsNumber)]; } [JsonConstructor] - public QaoaParameters(double[] beta, double[] gamma) + public QaoaParameters(double[] betas, double[] gammas) { - Beta = beta; - Gamma = gamma; + Betas = betas; + Gammas = gammas; } public QaoaParameters(int p) { - Beta = RandomVectorGenerator.GenerateRandomVector(p, System.Math.PI); - Gamma = RandomVectorGenerator.GenerateRandomVector(p, 2 * System.Math.PI); + Betas = RandomVectorGenerator.GenerateRandomVector(p, System.Math.PI); + Gammas = RandomVectorGenerator.GenerateRandomVector(p, 2 * System.Math.PI); } /// - /// Converts beta and gamma vectors into a concatenated vector. + /// Converts betas and gammas vectors into a concatenated vector. /// /// - /// Array of concatenated beta and gamma arrays. + /// Array of concatenated betas and gammas arrays. /// public double[] getConcatenatedQaoaParameters() { - return Beta.Concat(Gamma).ToArray(); + return Betas.Concat(Gammas).ToArray(); } } } diff --git a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs index 829b4fe030b..db6d174d5e3 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs @@ -35,8 +35,8 @@ public async Task HybridQaoaProblemInstance() var qaoaParameters = result.Output as QaoaParameters; Assert.Equal(ExecuteStatus.Ok, result.Status); - Assert.Equal(qaoaParameters.Beta, beta); - Assert.Equal(qaoaParameters.Gamma, gamma); + Assert.Equal(qaoaParameters.Betas, beta); + Assert.Equal(qaoaParameters.Gammas, gamma); } } From 2314b6c4865be75d7f138a3087a371018d6be914 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 09:39:01 +0200 Subject: [PATCH 47/61] Code refactoring. --- QAOA/src/Qaoa/QaoaRunner.qs | 6 ++-- QAOA/src/QaoaHybrid/HybridQaoa.cs | 13 ++++----- QAOA/src/QaoaHybrid/QaoaLogger.cs | 29 +++++++++---------- QAOA/tests/HybridQaoaTests/ModeFinderTests.cs | 12 +++----- 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index b4f1d1e6f0d..350530a2d0e 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -37,9 +37,9 @@ namespace Microsoft.Quantum.QAOA { mutable result = new Bool[problemSize]; using (qubits = Qubit[problemSize]) { ApplyToEach(H, qubits); - for (i in 0..p-1) { - EvolveWithObjectiveHamiltonian(qubits, gammas[i], oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - EvolveWithMixingHamiltonian(qubits, betas[i]); + for ((beta, gamma) in Zip(betas, gammas)) { + EvolveWithObjectiveHamiltonian(qubits, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); + EvolveWithMixingHamiltonian(qubits, beta); } return ResultArrayAsBoolArray(ForEach(MResetZ, qubits)); } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 7acf4f092c1..1540309ae53 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#nullable enable + namespace Microsoft.Quantum.QAOA.QaoaHybrid { @@ -23,7 +25,7 @@ public class HybridQaoa private readonly ProblemInstance problemInstance; private readonly bool shouldLog; private QaoaSolution solution; - private QaoaLogger logger; + private QaoaLogger? logger; /// /// Initializes a new instance of the class. @@ -85,7 +87,7 @@ public double EvaluateCostFunction(bool[] result, double[] costs) private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) { var qaoaParameters = new QaoaParameters(concatenatedQaoaParameters); - double hamiltonianExpectationValue = 0; + var hamiltonianExpectationValue = 0.0; var allSolutionVectors = new List(); var betas = new QArray(qaoaParameters.Betas); @@ -99,7 +101,7 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) for (var i = 0; i < this.numberOfIterations; i++) { - IQArray result = RunQaoa.Run(qsim, this.problemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; + var result = RunQaoa.Run(qsim, this.problemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; allSolutionVectors.Add(result.ToArray()); var hamiltonianValue = this.problemInstance.EvaluateHamiltonian(result.ToArray()); hamiltonianExpectationValue += hamiltonianValue / this.numberOfIterations; @@ -198,10 +200,7 @@ public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) var concatenatedQaoaParameters = new QaoaParameters(p).getConcatenatedQaoaParameters(); var success = cobyla.Minimize(concatenatedQaoaParameters); - if (this.shouldLog) - { - this.logger.LogSuccess(success); - } + this.logger?.LogSuccess(success); } if (this.shouldLog) diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 30bcbcaf991..cb150cbf00b 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -18,7 +18,7 @@ class QaoaLogger : IDisposable public QaoaLogger() { - this.logger = new StreamWriter("hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); + logger = new StreamWriter("hybrid_qaoa_log_" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", true); } /// @@ -39,15 +39,15 @@ public QaoaLogger() public void LogCurrentBestSolution(QArray beta, QArray gamma, double bestHamiltonian, bool[] bestVector) { - this.logger.WriteLine("Current beta vector:"); - this.logger.WriteLine(beta); - this.logger.WriteLine("Current gamma vector:"); - this.logger.WriteLine(gamma); - this.logger.WriteLine("Current best expected value of a Hamiltonian:"); - this.logger.WriteLine(bestHamiltonian); - this.logger.WriteLine("Current best solution vector:"); + logger.WriteLine("Current beta vector:"); + logger.WriteLine(beta); + logger.WriteLine("Current gamma vector:"); + logger.WriteLine(gamma); + logger.WriteLine("Current best expected value of a Hamiltonian:"); + logger.WriteLine(bestHamiltonian); + logger.WriteLine("Current best solution vector:"); var bestSolutionVector = string.Join(", ", bestVector.Select(x => x.ToString())); - this.logger.WriteLine("[" + bestSolutionVector + "]"); + logger.WriteLine("[" + bestSolutionVector + "]"); } /// @@ -58,9 +58,9 @@ public void LogCurrentBestSolution(QArray beta, QArray gamma, do /// public void LogSuccess(bool success) { - this.logger.WriteLine("Was optimization successful?"); - this.logger.WriteLine(success); - this.logger.WriteLine("##################################"); + logger.WriteLine("Was optimization successful?"); + logger.WriteLine(success); + logger.WriteLine("##################################"); } @@ -69,10 +69,7 @@ protected virtual void Dispose(bool disposing) if (disposing) { - if (logger != null) - { - logger.Dispose(); - } + logger?.Dispose(); } } diff --git a/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs b/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs index da3e4d98f30..7c5e1b08f70 100644 --- a/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs +++ b/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs @@ -13,17 +13,13 @@ public class ModeFinderTests [TestMethod] public void FindModeInBoolListTest() { - bool[] boolsArray1 = { false, false, true }; - bool[] boolsArray2 = { false, false, true }; - bool[] boolsArray3 = { false, false, false }; - bool[] boolsArray4 = { false, true, true }; var listOfBools = new List { - boolsArray1, - boolsArray3, - boolsArray2, - boolsArray4 + new[] { false, false, true }, + new[] { false, false, true }, + new[] { false, false, false }, + new[] { false, true, true } }; var expectedResult = new[] {false, false, true}; From 2ebf375f2c30ae1ecd9ff57b3e7decb30f1a9420 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 15:16:32 +0200 Subject: [PATCH 48/61] Namespace naming improved. --- Build/build.ps1 | 2 +- Build/manifest.ps1 | 4 ++-- Build/pack.ps1 | 4 ++-- Build/test.ps1 | 12 ++++++------ QAOA.sln | 2 +- QAOA/src/Jupyter/HybridQaoaMagic.cs | 8 ++++---- QAOA/src/Jupyter/HybridQaoaParametersMagic.cs | 4 ++-- QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs | 4 ++-- QAOA/src/Qaoa/EvolutionOperations.qs | 2 +- QAOA/src/Qaoa/PhaseKickback.qs | 2 +- QAOA/src/Qaoa/QaoaRunner.qs | 2 +- .../src/QaoaHybrid/Helpers/ArrayToStringConverter.cs | 2 +- QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs | 2 +- QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs | 2 +- QAOA/src/QaoaHybrid/HybridQaoa.cs | 6 +++--- QAOA/src/QaoaHybrid/ProblemInstance.cs | 2 +- QAOA/src/QaoaHybrid/QaoaLogger.cs | 2 +- QAOA/src/QaoaHybrid/QaoaParameters.cs | 4 ++-- QAOA/src/QaoaHybrid/QaoaSolution.cs | 2 +- .../HybridQaoaTests/ArrayToStringConverterTests.cs | 4 ++-- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 4 ++-- QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj | 2 +- QAOA/tests/HybridQaoaTests/ModeFinderTests.cs | 4 ++-- QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs | 4 ++-- .../JupyterTests/HybridQaoaParametersMagicTests.cs | 6 +++--- .../HybridQaoaProblemInstanceMagicTests.cs | 6 +++--- QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs | 6 +++--- QAOA/tests/JupyterTests/JupyterTests.csproj | 2 +- QAOA/tests/JupyterTests/MockChannel.cs | 2 +- QAOA/tests/QaoaTests/PhaseKickbackTests.qs | 2 +- QAOA/tests/QaoaTests/QaoaTests.csproj | 2 +- 31 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Build/build.ps1 b/Build/build.ps1 index 7fe64b92a97..1fbe7eb1950 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -41,7 +41,7 @@ Write-Host "##[info]Build Jupyter magic library" Build-One 'publish' '../Magic.sln' Write-Host "##[info]Build QAOA library" -Build-One 'publish' '../QAOA.sln' +Build-One 'publish' '../Qaoa.sln' if (-not $all_ok) { throw "At least one test failed execution. Check the logs." diff --git a/Build/manifest.ps1 b/Build/manifest.ps1 index 00d4c91f19b..4b7a89d7f8b 100644 --- a/Build/manifest.ps1 +++ b/Build/manifest.ps1 @@ -9,7 +9,7 @@ "Microsoft.Quantum.Chemistry", "Microsoft.Quantum.Numerics", "Microsoft.Quantum.MachineLearning" - "Microsoft.Quantum.QAOA" + "Microsoft.Quantum.Qaoa" ); Assemblies = @( ".\Standard\src\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Standard.dll", @@ -18,6 +18,6 @@ ".\Chemistry\src\DataModel\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.DataModel.dll", ".\Chemistry\src\Runtime\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.Runtime.dll", ".\Chemistry\src\Tools\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\qdk-chem.dll" - ".\QAOA\src\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\QAOA.dll" + ".\Qaoa\src\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\Microsoft.Quantum.Qaoa.dll" ) | ForEach-Object { Get-Item (Join-Path $PSScriptRoot ".." $_) }; } | Write-Output; diff --git a/Build/pack.ps1 b/Build/pack.ps1 index 0864c258285..15d98485871 100644 --- a/Build/pack.ps1 +++ b/Build/pack.ps1 @@ -73,10 +73,10 @@ if ($Env:ENABLE_PYTHON -eq "false") { } Write-Host "##[info]Pack QAOA library" -Pack-One '../QAOA/src/QAOA.csproj' +Pack-One '../Qaoa/src/Qaoa.csproj' Write-Host "##[info]Pack QAOA library" -Pack-One '../QAOA/src/QAOA.csproj' +Pack-One '../Qaoa/src/Qaoa.csproj' if (-not $all_ok) { throw "At least one test failed execution. Check the logs." diff --git a/Build/test.ps1 b/Build/test.ps1 index 088b204b0aa..5409ebef16a 100644 --- a/Build/test.ps1 +++ b/Build/test.ps1 @@ -40,14 +40,14 @@ Test-One '../Chemistry/tests/JupyterTests/JupyterTests.csproj' Write-Host "##[info]Testing Numerics/tests/NumericsTests.csproj" Test-One '../Numerics/tests/NumericsTests.csproj' -Write-Host "##[info]Testing QAOA/tests/QaoaTests/QaoaTests.csproj" -Test-One '../QAOA/tests/QaoaTests/QaoaTests.csproj' +Write-Host "##[info]Testing Qaoa/tests/QaoaTests/QaoaTests.csproj" +Test-One '../Qaoa/tests/QaoaTests/QaoaTests.csproj' -Write-Host "##[info]Testing QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj" -Test-One '../QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj' +Write-Host "##[info]Testing Qaoa/tests/HybridQaoaTests/HybridQaoaTests.csproj" +Test-One '../Qaoa/tests/HybridQaoaTests/HybridQaoaTests.csproj' -Write-Host "##[info]Testing QAOA/tests/JupyterTests/JupyterTests.csproj" -Test-One '../QAOA/tests/JupyterTests/JupyterTests.csproj' +Write-Host "##[info]Testing Qaoa/tests/JupyterTests/JupyterTests.csproj" +Test-One '../Qaoa/tests/JupyterTests/JupyterTests.csproj' if (-not $all_ok) { throw "At least one test failed execution. Check the logs." diff --git a/QAOA.sln b/QAOA.sln index 67e820e4bf3..f0db189db79 100644 --- a/QAOA.sln +++ b/QAOA.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAOA", "QAOA\src\QAOA.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Qaoa", "QAOA\src\Qaoa.csproj", "{159D83BF-56A2-41B7-951B-35292F5A9F23}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HybridQaoaTests", "QAOA\tests\HybridQaoaTests\HybridQaoaTests.csproj", "{1623F038-210A-4BA2-8D4E-9AF611610829}" EndProject diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 0f55431561d..93cc02ebb5f 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.Jupyter +namespace Microsoft.Quantum.Qaoa.Jupyter { using System; using System.Threading.Tasks; using Microsoft.Jupyter.Core; - using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.Qaoa.QaoaHybrid; using Newtonsoft.Json; public class HybridQaoaRunMagic : MagicSymbol @@ -72,7 +72,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); + var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); return hybridQaoa.RunOptimization(args.InitialQaoaParameters).ToExecutionResult(); } @@ -141,7 +141,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - HybridQaoa hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); + var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); return hybridQaoa.RunOptimization(args.NumberOfRandomStartingPoints).ToExecutionResult(); } diff --git a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs index ea460b1b7b7..c84e305475d 100644 --- a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.Jupyter +namespace Microsoft.Quantum.Qaoa.Jupyter { using System.Threading.Tasks; using Microsoft.Jupyter.Core; - using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.Qaoa.QaoaHybrid; using Newtonsoft.Json; public class HybridQaoaParametersMagic : MagicSymbol diff --git a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs index 3136ee55bf6..6c27c7b756d 100644 --- a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.Jupyter +namespace Microsoft.Quantum.Qaoa.Jupyter { using System.Threading.Tasks; using Microsoft.Jupyter.Core; - using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.Qaoa.QaoaHybrid; using Newtonsoft.Json; public class HybridQaoaProblemInstanceMagic : MagicSymbol diff --git a/QAOA/src/Qaoa/EvolutionOperations.qs b/QAOA/src/Qaoa/EvolutionOperations.qs index 72ac98ce3e0..0bdaf965a40 100644 --- a/QAOA/src/Qaoa/EvolutionOperations.qs +++ b/QAOA/src/Qaoa/EvolutionOperations.qs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA { +namespace Microsoft.Quantum.Qaoa { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/src/Qaoa/PhaseKickback.qs b/QAOA/src/Qaoa/PhaseKickback.qs index 11c49c5859b..3e9cb11265f 100644 --- a/QAOA/src/Qaoa/PhaseKickback.qs +++ b/QAOA/src/Qaoa/PhaseKickback.qs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA { +namespace Microsoft.Quantum.Qaoa { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index 350530a2d0e..f1f0447397d 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA { +namespace Microsoft.Quantum.Qaoa { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; diff --git a/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs index e2ff95f7370..53efdd1de75 100644 --- a/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs +++ b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.QaoaHybrid.Helpers +namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers { using System.Text; diff --git a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs index 5ed5cb613fa..693212033e1 100644 --- a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs +++ b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.QaoaHybrid.Helpers +namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers { using System.Collections.Generic; using System.Linq; diff --git a/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs index d23d03d5b44..b086ce4407c 100644 --- a/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs +++ b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.QaoaHybrid.Helpers +namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers { using System; diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 1540309ae53..9b16911495b 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -3,17 +3,17 @@ #nullable enable -namespace Microsoft.Quantum.QAOA.QaoaHybrid +namespace Microsoft.Quantum.Qaoa.QaoaHybrid { using System; using System.Collections.Generic; using System.Linq; using Accord.Math.Optimization; - using Microsoft.Quantum.QAOA; + using Microsoft.Quantum.Qaoa; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; - using Microsoft.Quantum.QAOA.QaoaHybrid.Helpers; + using Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers; /// /// This class runs a hybrid (quantum-classical) QAOA given an instance of a combinatorial optimization problem encoded into a 2-local Hamiltonian. The classical part is used for optimizing QAOA input parameters and is implemented using the Cobyla optimizer. QAOA input parameters can be optionally specified by a user and they will be treated as a starting point for optimization. Otherwise, input parameters are initialized randomly (possibly many times, as specified by the numberOfRandomStartingPoints variable). diff --git a/QAOA/src/QaoaHybrid/ProblemInstance.cs b/QAOA/src/QaoaHybrid/ProblemInstance.cs index 2b8a363d5b5..c56d5af7164 100644 --- a/QAOA/src/QaoaHybrid/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/ProblemInstance.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.QaoaHybrid +namespace Microsoft.Quantum.Qaoa.QaoaHybrid { using System; diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index cb150cbf00b..207f90cbca0 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.QaoaHybrid +namespace Microsoft.Quantum.Qaoa.QaoaHybrid { using System; using System.IO; diff --git a/QAOA/src/QaoaHybrid/QaoaParameters.cs b/QAOA/src/QaoaHybrid/QaoaParameters.cs index 526f078252d..d4cade12fb6 100644 --- a/QAOA/src/QaoaHybrid/QaoaParameters.cs +++ b/QAOA/src/QaoaHybrid/QaoaParameters.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.QaoaHybrid +namespace Microsoft.Quantum.Qaoa.QaoaHybrid { using System.Linq; using Newtonsoft.Json; - using Microsoft.Quantum.QAOA.QaoaHybrid.Helpers; + using Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers; public class QaoaParameters { diff --git a/QAOA/src/QaoaHybrid/QaoaSolution.cs b/QAOA/src/QaoaHybrid/QaoaSolution.cs index 6e5f4e38753..8c3cd1fd3bc 100644 --- a/QAOA/src/QaoaHybrid/QaoaSolution.cs +++ b/QAOA/src/QaoaHybrid/QaoaSolution.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.QaoaHybrid +namespace Microsoft.Quantum.Qaoa.QaoaHybrid { /// /// This class stores a solution that is found by a hybrid QAOA. It includes a boolean array that encodes the solution, a corresponding expected value of the objective function Hamiltonian and corresponding beta and gamma parameters that are input to a QAOA. diff --git a/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs b/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs index a71fc65cabc..cefc50b1ddd 100644 --- a/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs +++ b/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.HybridQaoaTests +namespace Microsoft.Quantum.Qaoa.HybridQaoaTests { using Microsoft.VisualStudio.TestTools.UnitTesting; - using QAOA.QaoaHybrid.Helpers; + using Qaoa.QaoaHybrid.Helpers; [TestClass] class ArrayToStringConverterTests diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index f3ecae442d9..eef38e41cb6 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.HybridQaoaTests +namespace Microsoft.Quantum.Qaoa.HybridQaoaTests { using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.Qaoa.QaoaHybrid; [TestClass] public class ClassicalOptimizationTest diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj index 7a5759a0de3..c60b2d4a6e8 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.csproj @@ -14,7 +14,7 @@ - + diff --git a/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs b/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs index 7c5e1b08f70..3f44f11f578 100644 --- a/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs +++ b/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.HybridQaoaTests +namespace Microsoft.Quantum.Qaoa.HybridQaoaTests { using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; - using Microsoft.Quantum.QAOA.QaoaHybrid.Helpers; + using Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers; [TestClass] public class ModeFinderTests diff --git a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs index e213246575e..ecc0e865265 100644 --- a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs +++ b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.HybridQaoaTests +namespace Microsoft.Quantum.Qaoa.HybridQaoaTests { - using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.Qaoa.QaoaHybrid; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] diff --git a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs index db6d174d5e3..f178f7f0c39 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaParametersMagicTests.cs @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.JupyterTests +namespace Microsoft.Quantum.Qaoa.JupyterTests { using System.Threading.Tasks; using Microsoft.Jupyter.Core; using Newtonsoft.Json; using Xunit; - using Microsoft.Quantum.QAOA.QaoaHybrid; - using Microsoft.Quantum.QAOA.Jupyter; + using Microsoft.Quantum.Qaoa.QaoaHybrid; + using Microsoft.Quantum.Qaoa.Jupyter; public class HybridQaoaParametersMagicTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index b4395343e9e..5de64da1ead 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.JupyterTests +namespace Microsoft.Quantum.Qaoa.JupyterTests { using System.Threading.Tasks; using Microsoft.Jupyter.Core; using Newtonsoft.Json; using Xunit; - using Microsoft.Quantum.QAOA.QaoaHybrid; - using Microsoft.Quantum.QAOA.Jupyter; + using Microsoft.Quantum.Qaoa.QaoaHybrid; + using Microsoft.Quantum.Qaoa.Jupyter; public class HybridQaoaProblemInstanceMagicTests { diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 3df076ac35b..e2811ff984e 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.JupyterTests +namespace Microsoft.Quantum.Qaoa.JupyterTests { using System.Threading.Tasks; using Microsoft.Jupyter.Core; using Newtonsoft.Json; - using Microsoft.Quantum.QAOA.QaoaHybrid; + using Microsoft.Quantum.Qaoa.QaoaHybrid; using Xunit; - using Microsoft.Quantum.QAOA.Jupyter; + using Microsoft.Quantum.Qaoa.Jupyter; using Microsoft.VisualStudio.TestTools.UnitTesting; using Assert = Xunit.Assert; diff --git a/QAOA/tests/JupyterTests/JupyterTests.csproj b/QAOA/tests/JupyterTests/JupyterTests.csproj index b157f4abf10..a5482530506 100644 --- a/QAOA/tests/JupyterTests/JupyterTests.csproj +++ b/QAOA/tests/JupyterTests/JupyterTests.csproj @@ -20,7 +20,7 @@ - + diff --git a/QAOA/tests/JupyterTests/MockChannel.cs b/QAOA/tests/JupyterTests/MockChannel.cs index 97224929150..157dcd4f85b 100644 --- a/QAOA/tests/JupyterTests/MockChannel.cs +++ b/QAOA/tests/JupyterTests/MockChannel.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Microsoft.Quantum.QAOA.JupyterTests +namespace Microsoft.Quantum.Qaoa.JupyterTests { using System; using System.Collections.Generic; diff --git a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs index 6c6b1647e73..20e6e46e6f3 100644 --- a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs +++ b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs @@ -7,7 +7,7 @@ namespace Microsoft.Quantum.Tests { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Diagnostics; open Microsoft.Quantum.Math; - open Microsoft.Quantum.QAOA; + open Microsoft.Quantum.Qaoa; @Test("QuantumSimulator") operation RunPhaseKickbackTest() : Unit { diff --git a/QAOA/tests/QaoaTests/QaoaTests.csproj b/QAOA/tests/QaoaTests/QaoaTests.csproj index f514d649463..272e2b2fb98 100644 --- a/QAOA/tests/QaoaTests/QaoaTests.csproj +++ b/QAOA/tests/QaoaTests/QaoaTests.csproj @@ -14,7 +14,7 @@ - + From 33f8e4b1abe1d3e176b9d806d70712f22e31c08d Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 15:31:22 +0200 Subject: [PATCH 49/61] Several classes made internal, code refactoring. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 8 ++++---- .../Jupyter/HybridQaoaProblemInstanceMagic.cs | 4 ++-- QAOA/src/Qaoa/QaoaRunner.qs | 2 +- .../Helpers/ArrayToStringConverter.cs | 2 +- QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs | 2 +- .../Helpers/RandomVectorGenerator.cs | 2 +- QAOA/src/QaoaHybrid/HybridQaoa.cs | 18 +++++++++--------- QAOA/src/QaoaHybrid/QaoaLogger.cs | 2 +- ...oblemInstance.cs => QaoaProblemInstance.cs} | 6 +++--- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 8 ++++---- .../HybridQaoaTests/ProblemInstanceTests.cs | 2 +- .../HybridQaoaProblemInstanceMagicTests.cs | 2 +- .../JupyterTests/HybridQaoaRunMagicTests.cs | 8 ++++---- 13 files changed, 33 insertions(+), 33 deletions(-) rename QAOA/src/QaoaHybrid/{ProblemInstance.cs => QaoaProblemInstance.cs} (92%) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 93cc02ebb5f..95b87acc41c 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -44,7 +44,7 @@ public class Arguments /// Description of a combinatorial problem to be solved. /// [JsonProperty(PropertyName = "problem_instance")] - public ProblemInstance ProblemInstance { get; set; } + public QaoaProblemInstance QaoaProblemInstance { get; set; } /// /// Initial QAOA parameters (beta and gamma angles). @@ -72,7 +72,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); + var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.QaoaProblemInstance, args.ShouldLog); return hybridQaoa.RunOptimization(args.InitialQaoaParameters).ToExecutionResult(); } @@ -113,7 +113,7 @@ public class Arguments /// Description of a combinatorial problem to be solved. /// [JsonProperty(PropertyName = "problem_instance")] - public ProblemInstance ProblemInstance { get; set; } + public QaoaProblemInstance QaoaProblemInstance { get; set; } /// /// Number of random starting points in the angles parameters spaces. @@ -141,7 +141,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.ProblemInstance, args.ShouldLog); + var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.QaoaProblemInstance, args.ShouldLog); return hybridQaoa.RunOptimization(args.NumberOfRandomStartingPoints).ToExecutionResult(); } diff --git a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs index 6c27c7b756d..108cdcf7c68 100644 --- a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs @@ -46,7 +46,7 @@ public class Arguments } /// - /// Prepares a ProblemInstance object for a hybrid QAOA. + /// Prepares a QaoaProblemInstance object for a hybrid QAOA. /// public async Task Run(string input, IChannel channel) { @@ -58,7 +58,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - var problemInstance = new ProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); + var problemInstance = new QaoaProblemInstance(args.OneLocalHamiltonianCoefficients, args.TwoLocalHamiltonianCoefficients); return problemInstance.ToExecutionResult(); } diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index f1f0447397d..bead706b95f 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -25,7 +25,7 @@ namespace Microsoft.Quantum.Qaoa { /// ## twoLocalHamiltonianCoefficients /// Array of 2-local coefficents of the objective function Hamiltonian. /// ## p - /// Depth of the QAOA circuit. + /// A parameter related to the depth of a QAOA circuit. It corresponds to the number of times evolution operators are applied. /// /// # Output /// Array of boolean values that represent results of measurements on the QAOA state. diff --git a/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs index 53efdd1de75..238ed0c4cb7 100644 --- a/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs +++ b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs @@ -5,7 +5,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers { using System.Text; - public class ArrayToStringConverter + internal class ArrayToStringConverter { /// /// Converts an array of bools to a boolean string. diff --git a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs index 693212033e1..1b8205492bb 100644 --- a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs +++ b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs @@ -6,7 +6,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers using System.Collections.Generic; using System.Linq; - public class ModeFinder + internal class ModeFinder { /// /// Return the most common boolean string from a list of boolean values. diff --git a/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs index b086ce4407c..9c2d9554f77 100644 --- a/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs +++ b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs @@ -5,7 +5,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers { using System; - public class RandomVectorGenerator + internal class RandomVectorGenerator { /// /// Returns a vector of random doubles in a range from 0 to maximum. diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 9b16911495b..fd969f1b03e 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -22,7 +22,7 @@ public class HybridQaoa { private readonly int numberOfIterations; private readonly int p; - private readonly ProblemInstance problemInstance; + private readonly QaoaProblemInstance qaoaProblemInstance; private readonly bool shouldLog; private QaoaSolution solution; private QaoaLogger? logger; @@ -36,17 +36,17 @@ public class HybridQaoa /// /// A parameter related to the depth of a QAOA circuit. It corresponds to the number of times evolution operators are applied. /// - /// + /// /// An object that describes a combinatorial optimization problem to be solved by the algorithm. /// /// /// A flag that specifies whether a log from the hybrid QAOA should be saved in a text file. /// - public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance, bool shouldLog = false) + public HybridQaoa(int numberOfIterations, int p, QaoaProblemInstance qaoaProblemInstance, bool shouldLog = false) { this.numberOfIterations = numberOfIterations; this.p = p; - this.problemInstance = problemInstance; + this.qaoaProblemInstance = qaoaProblemInstance; this.shouldLog = shouldLog; } @@ -65,7 +65,7 @@ public HybridQaoa(int numberOfIterations, int p, ProblemInstance problemInstance public double EvaluateCostFunction(bool[] result, double[] costs) { double costFunctionValue = 0; - for (var i = 0; i < this.problemInstance.ProblemSizeInBits; i++) + for (var i = 0; i < this.qaoaProblemInstance.ProblemSizeInBits; i++) { costFunctionValue += costs[i] * Convert.ToInt32(result[i]); } @@ -93,17 +93,17 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) var betas = new QArray(qaoaParameters.Betas); var gammas = new QArray(qaoaParameters.Gammas); - var oneLocalHamiltonianCoefficients = new QArray(this.problemInstance.OneLocalHamiltonianCoefficients); - var twoLocalHamiltonianCoefficients = new QArray(this.problemInstance.TwoLocalHamiltonianCoefficients); + var oneLocalHamiltonianCoefficients = new QArray(this.qaoaProblemInstance.OneLocalHamiltonianCoefficients); + var twoLocalHamiltonianCoefficients = new QArray(this.qaoaProblemInstance.TwoLocalHamiltonianCoefficients); using (var qsim = new QuantumSimulator()) { for (var i = 0; i < this.numberOfIterations; i++) { - var result = RunQaoa.Run(qsim, this.problemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; + var result = RunQaoa.Run(qsim, this.qaoaProblemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; allSolutionVectors.Add(result.ToArray()); - var hamiltonianValue = this.problemInstance.EvaluateHamiltonian(result.ToArray()); + var hamiltonianValue = this.qaoaProblemInstance.EvaluateHamiltonian(result.ToArray()); hamiltonianExpectationValue += hamiltonianValue / this.numberOfIterations; } diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 207f90cbca0..4faf4c9c25d 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -11,7 +11,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid /// /// This class provides a simple capability for logging intermediate steps of a hybrid QAOA to a text file. /// - class QaoaLogger : IDisposable + internal class QaoaLogger : IDisposable { private readonly StreamWriter logger; diff --git a/QAOA/src/QaoaHybrid/ProblemInstance.cs b/QAOA/src/QaoaHybrid/QaoaProblemInstance.cs similarity index 92% rename from QAOA/src/QaoaHybrid/ProblemInstance.cs rename to QAOA/src/QaoaHybrid/QaoaProblemInstance.cs index c56d5af7164..d2cd159f728 100644 --- a/QAOA/src/QaoaHybrid/ProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/QaoaProblemInstance.cs @@ -8,7 +8,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid /// /// This class is used for storing the encoding of a combinatorial optimization problem into a Hamiltonian. Currently, a Hamiltonian with locality of up to 2 is supported. /// - public class ProblemInstance + public class QaoaProblemInstance { public double[] OneLocalHamiltonianCoefficients { get; } @@ -17,7 +17,7 @@ public class ProblemInstance public int ProblemSizeInBits { get; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 1-local terms. Non-existent terms (excluding those that go beyond the size of a problem) shall be input with a coefficient that equals 0. @@ -25,7 +25,7 @@ public class ProblemInstance /// /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 2-local terms. Non-existent terms (excluding those that go beyond the size of a problem) shall be input with a coefficient that equals 0. /// - public ProblemInstance(double[] oneLocalHamiltonianCoefficients, double[] twoLocalHamiltonianCoefficients) + public QaoaProblemInstance(double[] oneLocalHamiltonianCoefficients, double[] twoLocalHamiltonianCoefficients) { this.OneLocalHamiltonianCoefficients = oneLocalHamiltonianCoefficients; this.TwoLocalHamiltonianCoefficients = twoLocalHamiltonianCoefficients; diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index eef38e41cb6..d0f18500068 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -13,9 +13,9 @@ public class ClassicalOptimizationTest [TestMethod] public void EvaluateCostFunctionTest() { - ProblemInstance problemInstance = new ProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); + QaoaProblemInstance qaoaProblemInstance = new QaoaProblemInstance(new double[] { 1, 1, 1, 1 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); - HybridQaoa classicalOptimization = new HybridQaoa(2, 1, problemInstance); + HybridQaoa classicalOptimization = new HybridQaoa(2, 1, qaoaProblemInstance); var optimizationResult = new []{false, true, false, true}; @@ -38,7 +38,7 @@ public void RunOptimizationRandomParamsTest() var p = 2; var numberOfRandomStartingPoints = 2; - var simpleMaxCut = new ProblemInstance(dh, dJ); + var simpleMaxCut = new QaoaProblemInstance(dh, dJ); var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut); var optimalSolution = classicalOptimization.RunOptimization(numberOfRandomStartingPoints); @@ -67,7 +67,7 @@ public void RunOptimizationUserParamsTest() var numberOfIterations = 60; var p = 3; - var simpleMaxCut = new ProblemInstance(dh, dJ); + var simpleMaxCut = new QaoaProblemInstance(dh, dJ); var initialBeta = new double[] { 0, 0, 0 }; var initialGamma = new double[] { 0, 0, 0 }; diff --git a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs index ecc0e865265..6483567569f 100644 --- a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs +++ b/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs @@ -14,7 +14,7 @@ class ProblemInstanceTests [TestMethod] public void EvaluateHamiltonianTest() { - var problemInstance = new ProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); + var problemInstance = new QaoaProblemInstance(new double[] { 1, 2, 2, -1 }, new double[] { 5, 0, 0, 1, 1, 5, 0, 0, 3, 4, -2, -2, 8, 7, -2, 12 }); var result = problemInstance.EvaluateHamiltonian(new [] {false,false,true,true}); diff --git a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs index 5de64da1ead..0da9b3d8983 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaProblemInstanceMagicTests.cs @@ -31,7 +31,7 @@ public async Task HybridQaoaProblemInstance() }); var result = await magic.Run(args, channel); - var problemInstance = result.Output as ProblemInstance; + var problemInstance = result.Output as QaoaProblemInstance; Assert.Equal(ExecuteStatus.Ok, result.Status); Assert.Equal(problemInstance.ProblemSizeInBits, oneLocalHamiltonianCoefficients.Length); diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index e2811ff984e..0332f43a3bd 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -31,13 +31,13 @@ public async Task HybridQaoaRun() var initialGamma = new double[] { 0, 0 }; var initialQaoaParameters = new QaoaParameters(initialBeta, initialGamma); - var simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); + var simpleMaxCut = new QaoaProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); var args = JsonConvert.SerializeObject(new HybridQaoaRunMagic.Arguments { NumberOfIterations = numberOfIterations, p = p, - ProblemInstance = simpleMaxCut, + QaoaProblemInstance = simpleMaxCut, InitialQaoaParameters = initialQaoaParameters, }); @@ -75,13 +75,13 @@ public async Task HybridQaoaRun() var twoLocalHamiltonianCoefficients = new double[] { 0, 1, 0, 0 }; var numberOfRandomStartingPoints = 2; - var simpleMaxCut = new ProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); + var simpleMaxCut = new QaoaProblemInstance(oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); var args = JsonConvert.SerializeObject(new HybridQaoaWithRandomParametersRunMagic.Arguments { NumberOfIterations = numberOfIterations, p = p, - ProblemInstance = simpleMaxCut, + QaoaProblemInstance = simpleMaxCut, NumberOfRandomStartingPoints = numberOfRandomStartingPoints }); From cbbba9bc97d00458e6339319609929f8130980b9 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 15:37:58 +0200 Subject: [PATCH 50/61] Code refactoring. --- QAOA/src/QaoaHybrid/HybridQaoa.cs | 4 ++-- QAOA/src/QaoaHybrid/QaoaParameters.cs | 8 +++----- QAOA/tests/QaoaTests/PhaseKickbackTests.qs | 20 +++++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index fd969f1b03e..ee84bc22f85 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -197,7 +197,7 @@ public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) for (int i = 0; i < numberOfRandomStartingPoints; i++) { - var concatenatedQaoaParameters = new QaoaParameters(p).getConcatenatedQaoaParameters(); + var concatenatedQaoaParameters = new QaoaParameters(p).ConcatenatedQaoaParameters(); var success = cobyla.Minimize(concatenatedQaoaParameters); this.logger?.LogSuccess(success); @@ -237,7 +237,7 @@ public QaoaSolution RunOptimization(QaoaParameters qaoaParameters) var constraints = this.GenerateConstraints(); var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - var concatenatedQaoaParameters = qaoaParameters.getConcatenatedQaoaParameters(); + var concatenatedQaoaParameters = qaoaParameters.ConcatenatedQaoaParameters(); var success = cobyla.Minimize(concatenatedQaoaParameters); if (this.shouldLog) diff --git a/QAOA/src/QaoaHybrid/QaoaParameters.cs b/QAOA/src/QaoaHybrid/QaoaParameters.cs index d4cade12fb6..1535b367f57 100644 --- a/QAOA/src/QaoaHybrid/QaoaParameters.cs +++ b/QAOA/src/QaoaHybrid/QaoaParameters.cs @@ -34,14 +34,12 @@ public QaoaParameters(int p) } /// - /// Converts betas and gammas vectors into a concatenated vector. + /// Gets betas and gammas vectors as a concatenated vector. /// /// /// Array of concatenated betas and gammas arrays. /// - public double[] getConcatenatedQaoaParameters() - { - return Betas.Concat(Gammas).ToArray(); - } + public double[] ConcatenatedQaoaParameters => + Betas.Concat(Gammas).ToArray(); } } diff --git a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs index 20e6e46e6f3..be1c2f3174f 100644 --- a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs +++ b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs @@ -17,10 +17,11 @@ namespace Microsoft.Quantum.Tests { let controlQubitsIndices = [0]; let phaseExponent = 0.5; - using (qubits = Qubit[numberOfQubits+auxiliaryQubits]) { - RunPhaseKickback(qubits[...1], qubits[1],controlQubitsIndices,phaseExponent); - AssertQubit(Zero, Head(qubits)); - ResetAll(qubits); + using ((register, aux) = (Qubit[numberOfQubits], Qubit())) { + RunPhaseKickback(register, aux, controlQubitsIndices, phaseExponent); + AssertQubit(Zero, register); + ResetAll(register); + ResetAll(aux); } } @@ -35,11 +36,12 @@ namespace Microsoft.Quantum.Tests { let complexZero = Complex(0.685125,-0.174941); let complexOne = Complex(0.685125,0.174941); - using (qubits = Qubit[numberOfQubits+auxiliaryQubits]) { - H(qubits[0]); - RunPhaseKickback([qubits[0]], qubits[1],controlQubitsIndices,phaseExponent); - AssertQubitIsInStateWithinTolerance((complexZero,complexOne), qubits[0], 1E-05); - ResetAll(qubits); + using ((register, aux) = (Qubit[numberOfQubits], Qubit())) { + H(register); + RunPhaseKickback([register], aux, controlQubitsIndices, phaseExponent); + AssertQubitIsInStateWithinTolerance((complexZero, complexOne), register, 1E-05); + ResetAll(register); + ResetAll(aux); } } } From 5c8e20dbe03ec0ebb163fd860d76b3a6c543b8c5 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 18:43:57 +0200 Subject: [PATCH 51/61] Starting point for a readme added. --- QAOA/README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 QAOA/README.md diff --git a/QAOA/README.md b/QAOA/README.md new file mode 100644 index 00000000000..b6bcee5a003 --- /dev/null +++ b/QAOA/README.md @@ -0,0 +1,31 @@ +# Microsoft Quantum QAOA Library + +This library provides a hybrid quantum-classical algorithm for solving optimization problems. +It includes a Q# implementation of the Quantum Approximate Optimization Algorithm ([QAOA](https://arxiv.org/abs/1411.4028)) together with a classical optimizer in C#. +The classical optimizer uses a quantum objective function to choose hopefully optimal parameters for running the QAOA. +The quantum objective function is currently evaluated on a simulator backend provided by Q#. + +## Building and testing ## + +The quantum QAOA library consists of a cross-platform project built using [.NET Core](https://docs.microsoft.com/en-us/dotnet/core/): + +- **Qaoa.csproj**: Q# and C# sources used to encode combinatorial optimization problems and run QAOA and hybrid QAOA algorithms. + +The high-level diagram of the implementation (notation comes from the [QAOA paper](https://arxiv.org/abs/1411.4028)): + +[![QAOA diagram](https://i.postimg.cc/sgryqr80/IMG-0202.jpg)](https://postimg.cc/XpQTBTnw) + +Once .NET Core is installed, you may build and run its tests by executing the following from a command line: + +```bash +dotnet test tests +``` + +For more details about creating and running tests in Q#, +see the [Testing and debugging](https://docs.microsoft.com/quantum/quantum-techniques-testinganddebugging) +section of the [developer's guide](https://docs.microsoft.com/quantum). + +Dependencies: + +1) [Q# and Microsoft Quantum Libraries](https://docs.microsoft.com/en-us/quantum/language/) +2) [C# Accord Math library](http://accord-framework.net/docs/html/N_Accord_Math.htm) From 84786152528d43c507268bc81ca09933252e04cc Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 19:36:14 +0200 Subject: [PATCH 52/61] Bug fixes. --- .../QaoaHybrid/Helpers/ArrayToStringConverter.cs | 2 +- QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs | 2 +- .../QaoaHybrid/Helpers/RandomVectorGenerator.cs | 2 +- QAOA/src/QaoaHybrid/HybridQaoa.cs | 4 ++-- QAOA/tests/QaoaTests/PhaseKickbackTests.qs | 16 +++++++--------- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs index 238ed0c4cb7..53efdd1de75 100644 --- a/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs +++ b/QAOA/src/QaoaHybrid/Helpers/ArrayToStringConverter.cs @@ -5,7 +5,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers { using System.Text; - internal class ArrayToStringConverter + public class ArrayToStringConverter { /// /// Converts an array of bools to a boolean string. diff --git a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs index 1b8205492bb..693212033e1 100644 --- a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs +++ b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs @@ -6,7 +6,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers using System.Collections.Generic; using System.Linq; - internal class ModeFinder + public class ModeFinder { /// /// Return the most common boolean string from a list of boolean values. diff --git a/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs index 9c2d9554f77..b086ce4407c 100644 --- a/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs +++ b/QAOA/src/QaoaHybrid/Helpers/RandomVectorGenerator.cs @@ -5,7 +5,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid.Helpers { using System; - internal class RandomVectorGenerator + public class RandomVectorGenerator { /// /// Returns a vector of random doubles in a range from 0 to maximum. diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index ee84bc22f85..a65c020b670 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -197,7 +197,7 @@ public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) for (int i = 0; i < numberOfRandomStartingPoints; i++) { - var concatenatedQaoaParameters = new QaoaParameters(p).ConcatenatedQaoaParameters(); + var concatenatedQaoaParameters = new QaoaParameters(p).ConcatenatedQaoaParameters; var success = cobyla.Minimize(concatenatedQaoaParameters); this.logger?.LogSuccess(success); @@ -237,7 +237,7 @@ public QaoaSolution RunOptimization(QaoaParameters qaoaParameters) var constraints = this.GenerateConstraints(); var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - var concatenatedQaoaParameters = qaoaParameters.ConcatenatedQaoaParameters(); + var concatenatedQaoaParameters = qaoaParameters.ConcatenatedQaoaParameters; var success = cobyla.Minimize(concatenatedQaoaParameters); if (this.shouldLog) diff --git a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs index be1c2f3174f..3ca993ef1ef 100644 --- a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs +++ b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs @@ -12,23 +12,21 @@ namespace Microsoft.Quantum.Tests { @Test("QuantumSimulator") operation RunPhaseKickbackTest() : Unit { - let numberOfQubits = 1; let auxiliaryQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; - using ((register, aux) = (Qubit[numberOfQubits], Qubit())) { - RunPhaseKickback(register, aux, controlQubitsIndices, phaseExponent); + using ((register, aux) = (Qubit(), Qubit())) { + RunPhaseKickback([register], aux, controlQubitsIndices, phaseExponent); AssertQubit(Zero, register); - ResetAll(register); - ResetAll(aux); + ResetAll([register]); + ResetAll([aux]); } } @Test("QuantumSimulator") operation RunPhaseKickbackOneControlQubitTest() : Unit { - let numberOfQubits = 1; let auxiliaryQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; @@ -36,12 +34,12 @@ namespace Microsoft.Quantum.Tests { let complexZero = Complex(0.685125,-0.174941); let complexOne = Complex(0.685125,0.174941); - using ((register, aux) = (Qubit[numberOfQubits], Qubit())) { + using ((register, aux) = (Qubit(), Qubit())) { H(register); RunPhaseKickback([register], aux, controlQubitsIndices, phaseExponent); AssertQubitIsInStateWithinTolerance((complexZero, complexOne), register, 1E-05); - ResetAll(register); - ResetAll(aux); + ResetAll([register]); + ResetAll([aux]); } } } From 67812c364cac4bc37fb44462f0a93628dadc3a3f Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 20:42:26 +0200 Subject: [PATCH 53/61] Improved assembly name added. --- QAOA/src/QAOA.csproj | 1 + QAOA/tests/QaoaTests/PhaseKickbackTests.qs | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/QAOA/src/QAOA.csproj b/QAOA/src/QAOA.csproj index 15f81ea122f..6bece22fd8c 100644 --- a/QAOA/src/QAOA.csproj +++ b/QAOA/src/QAOA.csproj @@ -3,6 +3,7 @@ Library netcoreapp3.1 + Microsoft.Quantum.Qaoa diff --git a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs index 3ca993ef1ef..964bec79954 100644 --- a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs +++ b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs @@ -12,7 +12,6 @@ namespace Microsoft.Quantum.Tests { @Test("QuantumSimulator") operation RunPhaseKickbackTest() : Unit { - let auxiliaryQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; @@ -27,7 +26,6 @@ namespace Microsoft.Quantum.Tests { @Test("QuantumSimulator") operation RunPhaseKickbackOneControlQubitTest() : Unit { - let auxiliaryQubits = 1; let controlQubitsIndices = [0]; let phaseExponent = 0.5; From 8be5bea18cccad7c230d0d15da9e9aabd2122581 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Wed, 26 Aug 2020 21:16:07 +0200 Subject: [PATCH 54/61] Build files fixed. --- Build/manifest.ps1 | 4 ++-- Build/pack.ps1 | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Build/manifest.ps1 b/Build/manifest.ps1 index 4b7a89d7f8b..cadf6d5f2bf 100644 --- a/Build/manifest.ps1 +++ b/Build/manifest.ps1 @@ -8,7 +8,7 @@ "Microsoft.Quantum.Standard", "Microsoft.Quantum.Chemistry", "Microsoft.Quantum.Numerics", - "Microsoft.Quantum.MachineLearning" + "Microsoft.Quantum.MachineLearning", "Microsoft.Quantum.Qaoa" ); Assemblies = @( @@ -17,7 +17,7 @@ ".\MachineLearning\src\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.MachineLearning.dll", ".\Chemistry\src\DataModel\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.DataModel.dll", ".\Chemistry\src\Runtime\bin\$Env:BUILD_CONFIGURATION\netstandard2.1\Microsoft.Quantum.Chemistry.Runtime.dll", - ".\Chemistry\src\Tools\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\qdk-chem.dll" + ".\Chemistry\src\Tools\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\qdk-chem.dll", ".\Qaoa\src\bin\$Env:BUILD_CONFIGURATION\netcoreapp3.1\Microsoft.Quantum.Qaoa.dll" ) | ForEach-Object { Get-Item (Join-Path $PSScriptRoot ".." $_) }; } | Write-Output; diff --git a/Build/pack.ps1 b/Build/pack.ps1 index 15d98485871..7b288ccfee6 100644 --- a/Build/pack.ps1 +++ b/Build/pack.ps1 @@ -73,10 +73,7 @@ if ($Env:ENABLE_PYTHON -eq "false") { } Write-Host "##[info]Pack QAOA library" -Pack-One '../Qaoa/src/Qaoa.csproj' - -Write-Host "##[info]Pack QAOA library" -Pack-One '../Qaoa/src/Qaoa.csproj' +Pack-One '../QAOA/src/Qaoa.csproj' if (-not $all_ok) { throw "At least one test failed execution. Check the logs." From f47381fe67fbcb5fa1024918db2846d282577ea3 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Thu, 27 Aug 2020 20:19:45 +0200 Subject: [PATCH 55/61] Classical arguments made first in function signatures. --- QAOA/src/Qaoa/EvolutionOperations.qs | 6 +++--- QAOA/src/Qaoa/PhaseKickback.qs | 2 +- QAOA/src/Qaoa/QaoaRunner.qs | 4 ++-- QAOA/src/QaoaHybrid/HybridQaoa.cs | 2 +- QAOA/tests/QaoaTests/PhaseKickbackTests.qs | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/QAOA/src/Qaoa/EvolutionOperations.qs b/QAOA/src/Qaoa/EvolutionOperations.qs index 0bdaf965a40..724da26962b 100644 --- a/QAOA/src/Qaoa/EvolutionOperations.qs +++ b/QAOA/src/Qaoa/EvolutionOperations.qs @@ -16,7 +16,7 @@ namespace Microsoft.Quantum.Qaoa { /// Coefficent for the unitary based on the mixing Hamiltonian. /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - operation EvolveWithMixingHamiltonian(qubits: Qubit[], beta: Double) : Unit is Adj + Ctl { + operation EvolveWithMixingHamiltonian(beta: Double, qubits: Qubit[]) : Unit is Adj + Ctl { ApplyToEachCA(R(PauliX, -2.0 * beta, _), qubits); } @@ -34,7 +34,7 @@ namespace Microsoft.Quantum.Qaoa { /// Array of 2-local coefficents of the objective function Hamiltonian. /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. - operation EvolveWithObjectiveHamiltonian(qubits: Qubit[], gamma: Double, oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[]) : Unit is Adj + Ctl{ + operation EvolveWithObjectiveHamiltonian(gamma: Double, oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[], qubits: Qubit[]) : Unit is Adj + Ctl{ let numberOfQubits = Length(qubits); using (auxiliaryQubit = Qubit()) { for(i in 0..numberOfQubits-1) { @@ -42,7 +42,7 @@ namespace Microsoft.Quantum.Qaoa { } for(i in 0..numberOfQubits-1) { for (j in i+1..numberOfQubits-1) { - RunPhaseKickback(qubits, auxiliaryQubit, [i,j], 2.0*gamma*twoLocalHamiltonianCoefficients[i*numberOfQubits+j]); + RunPhaseKickback([i,j], 2.0*gamma*twoLocalHamiltonianCoefficients[i*numberOfQubits+j], qubits, auxiliaryQubit); } } } diff --git a/QAOA/src/Qaoa/PhaseKickback.qs b/QAOA/src/Qaoa/PhaseKickback.qs index 3e9cb11265f..3769783ddef 100644 --- a/QAOA/src/Qaoa/PhaseKickback.qs +++ b/QAOA/src/Qaoa/PhaseKickback.qs @@ -20,7 +20,7 @@ namespace Microsoft.Quantum.Qaoa { /// List of indices of control qubits. /// ## phaseExponent /// Phase to be applied. - operation RunPhaseKickback(qubits: Qubit[], auxiliaryQubit: Qubit, controlQubitsIndices: Int[], phaseExponent: Double) : Unit is Adj + Ctl { + operation RunPhaseKickback(controlQubitsIndices: Int[], phaseExponent: Double, qubits: Qubit[], auxiliaryQubit: Qubit) : Unit is Adj + Ctl { within { ApplyToEachCA( diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index bead706b95f..7949ff2f792 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -38,8 +38,8 @@ namespace Microsoft.Quantum.Qaoa { using (qubits = Qubit[problemSize]) { ApplyToEach(H, qubits); for ((beta, gamma) in Zip(betas, gammas)) { - EvolveWithObjectiveHamiltonian(qubits, gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); - EvolveWithMixingHamiltonian(qubits, beta); + EvolveWithObjectiveHamiltonian(gamma, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, qubits); + EvolveWithMixingHamiltonian(beta, qubits); } return ResultArrayAsBoolArray(ForEach(MResetZ, qubits)); } diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index a65c020b670..6690207a4af 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -157,7 +157,7 @@ private NonlinearConstraint[] GenerateConstraints() var constraints = new NonlinearConstraint[4*this.p]; foreach (var i in Enumerable.Range(0, this.p).Select(x => x * 2)) { - int gammaIndex = (2 * this.p) + i; + var gammaIndex = (2 * this.p) + i; constraints[i] = new NonlinearConstraint(2 * this.p, x => x[i / 2] >= 0); constraints[i + 1] = new NonlinearConstraint(2 * this.p, x => x[i / 2] <= Math.PI); constraints[gammaIndex] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] >= 0); diff --git a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs index 964bec79954..8036b824b8b 100644 --- a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs +++ b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs @@ -16,7 +16,7 @@ namespace Microsoft.Quantum.Tests { let phaseExponent = 0.5; using ((register, aux) = (Qubit(), Qubit())) { - RunPhaseKickback([register], aux, controlQubitsIndices, phaseExponent); + RunPhaseKickback(controlQubitsIndices, phaseExponent, [register], aux); AssertQubit(Zero, register); ResetAll([register]); ResetAll([aux]); @@ -34,7 +34,7 @@ namespace Microsoft.Quantum.Tests { using ((register, aux) = (Qubit(), Qubit())) { H(register); - RunPhaseKickback([register], aux, controlQubitsIndices, phaseExponent); + RunPhaseKickback(controlQubitsIndices, phaseExponent, [register], aux); AssertQubitIsInStateWithinTolerance((complexZero, complexOne), register, 1E-05); ResetAll([register]); ResetAll([aux]); From 264c021b5c53f2944550485225b0c81b53c84435 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Thu, 27 Aug 2020 20:34:08 +0200 Subject: [PATCH 56/61] Improved usages of a logger. --- QAOA/src/QaoaHybrid/HybridQaoa.cs | 19 +++++-------------- QAOA/src/QaoaHybrid/QaoaLogger.cs | 1 - .../ArrayToStringConverterTests.cs | 0 .../{ => HelpersTests}/ModeFinderTests.cs | 0 .../ProblemInstanceTests.cs | 0 5 files changed, 5 insertions(+), 15 deletions(-) rename QAOA/tests/HybridQaoaTests/{ => HelpersTests}/ArrayToStringConverterTests.cs (100%) rename QAOA/tests/HybridQaoaTests/{ => HelpersTests}/ModeFinderTests.cs (100%) rename QAOA/tests/HybridQaoaTests/{ => HelpersTests}/ProblemInstanceTests.cs (100%) diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 6690207a4af..8c96e5b851c 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -111,10 +111,7 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, qaoaParameters); - if (this.shouldLog) - { - this.logger.LogCurrentBestSolution(betas, gammas, this.solution.SolutionHamiltonianValue, this.solution.SolutionVector); - } + this.logger?.LogCurrentBestSolution(betas, gammas, this.solution.SolutionHamiltonianValue, this.solution.SolutionVector); return hamiltonianExpectationValue; } @@ -195,7 +192,7 @@ public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) var constraints = this.GenerateConstraints(); var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - for (int i = 0; i < numberOfRandomStartingPoints; i++) + for (var i = 0; i < numberOfRandomStartingPoints; i++) { var concatenatedQaoaParameters = new QaoaParameters(p).ConcatenatedQaoaParameters; var success = cobyla.Minimize(concatenatedQaoaParameters); @@ -203,10 +200,7 @@ public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) this.logger?.LogSuccess(success); } - if (this.shouldLog) - { - this.logger.Dispose(); - } + this.logger?.Dispose(); return this.solution; } @@ -240,11 +234,8 @@ public QaoaSolution RunOptimization(QaoaParameters qaoaParameters) var concatenatedQaoaParameters = qaoaParameters.ConcatenatedQaoaParameters; var success = cobyla.Minimize(concatenatedQaoaParameters); - if (this.shouldLog) - { - this.logger.LogSuccess(success); - this.logger.Dispose(); - } + this.logger?.LogSuccess(success); + this.logger?.Dispose(); return this.solution; } diff --git a/QAOA/src/QaoaHybrid/QaoaLogger.cs b/QAOA/src/QaoaHybrid/QaoaLogger.cs index 4faf4c9c25d..22aad669044 100644 --- a/QAOA/src/QaoaHybrid/QaoaLogger.cs +++ b/QAOA/src/QaoaHybrid/QaoaLogger.cs @@ -61,7 +61,6 @@ public void LogSuccess(bool success) logger.WriteLine("Was optimization successful?"); logger.WriteLine(success); logger.WriteLine("##################################"); - } protected virtual void Dispose(bool disposing) diff --git a/QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs b/QAOA/tests/HybridQaoaTests/HelpersTests/ArrayToStringConverterTests.cs similarity index 100% rename from QAOA/tests/HybridQaoaTests/ArrayToStringConverterTests.cs rename to QAOA/tests/HybridQaoaTests/HelpersTests/ArrayToStringConverterTests.cs diff --git a/QAOA/tests/HybridQaoaTests/ModeFinderTests.cs b/QAOA/tests/HybridQaoaTests/HelpersTests/ModeFinderTests.cs similarity index 100% rename from QAOA/tests/HybridQaoaTests/ModeFinderTests.cs rename to QAOA/tests/HybridQaoaTests/HelpersTests/ModeFinderTests.cs diff --git a/QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs b/QAOA/tests/HybridQaoaTests/HelpersTests/ProblemInstanceTests.cs similarity index 100% rename from QAOA/tests/HybridQaoaTests/ProblemInstanceTests.cs rename to QAOA/tests/HybridQaoaTests/HelpersTests/ProblemInstanceTests.cs From dae62ca8dfd9a09f3e1964ba8a70e4a36d2324f2 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Fri, 28 Aug 2020 16:23:40 +0200 Subject: [PATCH 57/61] Made a method async. --- QAOA/src/QaoaHybrid/HybridQaoa.cs | 95 +++++++++++-------- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 18 +--- 2 files changed, 60 insertions(+), 53 deletions(-) diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 8c96e5b851c..5625f1ae27b 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -1,6 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; + #nullable enable namespace Microsoft.Quantum.Qaoa.QaoaHybrid @@ -84,11 +87,9 @@ public double EvaluateCostFunction(bool[] result, double[] costs) /// /// The expected value of a Hamiltonian that we calculated in this run. /// - private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) + private double CalculateObjectiveFunctionAsync(double[] concatenatedQaoaParameters) { var qaoaParameters = new QaoaParameters(concatenatedQaoaParameters); - var hamiltonianExpectationValue = 0.0; - var allSolutionVectors = new List(); var betas = new QArray(qaoaParameters.Betas); var gammas = new QArray(qaoaParameters.Gammas); @@ -96,24 +97,33 @@ private double CalculateObjectiveFunction(double[] concatenatedQaoaParameters) var oneLocalHamiltonianCoefficients = new QArray(this.qaoaProblemInstance.OneLocalHamiltonianCoefficients); var twoLocalHamiltonianCoefficients = new QArray(this.qaoaProblemInstance.TwoLocalHamiltonianCoefficients); + var (hamiltonianExpectationValue, allSolutionVectors) = this.CalculateHamiltonianExpectation(betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients).Result; + + this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, qaoaParameters); + + this.logger?.LogCurrentBestSolution(betas, gammas, this.solution.SolutionHamiltonianValue, this.solution.SolutionVector); + + return hamiltonianExpectationValue; + } + + private async Task<(double HamiltonianExpectationValue, List AllSolutionVectors)> CalculateHamiltonianExpectation(QArray betas, QArray gammas, QArray oneLocalHamiltonianCoefficients, QArray twoLocalHamiltonianCoefficients) + { + var hamiltonianExpectationValue = 0.0; + var allSolutionVectors = new List(); + using (var qsim = new QuantumSimulator()) { for (var i = 0; i < this.numberOfIterations; i++) { - var result = RunQaoa.Run(qsim, this.qaoaProblemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p).Result; + var result = await RunQaoa.Run(qsim, this.qaoaProblemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p); allSolutionVectors.Add(result.ToArray()); var hamiltonianValue = this.qaoaProblemInstance.EvaluateHamiltonian(result.ToArray()); hamiltonianExpectationValue += hamiltonianValue / this.numberOfIterations; - } } - this.UpdateBestSolution(hamiltonianExpectationValue, allSolutionVectors, qaoaParameters); - - this.logger?.LogCurrentBestSolution(betas, gammas, this.solution.SolutionHamiltonianValue, this.solution.SolutionVector); - - return hamiltonianExpectationValue; + return (hamiltonianExpectationValue, allSolutionVectors); } /// @@ -179,28 +189,33 @@ private NonlinearConstraint[] GenerateConstraints() /// public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) { - if (this.shouldLog) + try { - this.logger = new QaoaLogger(); - } + if (this.shouldLog) + { + this.logger = new QaoaLogger(); + } - this.solution = new QaoaSolution(null, double.MaxValue, null); + this.solution = new QaoaSolution(null, double.MaxValue, null); - Func objectiveFunction = this.CalculateObjectiveFunction; + Func objectiveFunction = this.CalculateObjectiveFunctionAsync; - var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); - var constraints = this.GenerateConstraints(); - var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); + var constraints = this.GenerateConstraints(); + var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - for (var i = 0; i < numberOfRandomStartingPoints; i++) - { - var concatenatedQaoaParameters = new QaoaParameters(p).ConcatenatedQaoaParameters; - var success = cobyla.Minimize(concatenatedQaoaParameters); + for (var i = 0; i < numberOfRandomStartingPoints; i++) + { + var concatenatedQaoaParameters = new QaoaParameters(p).ConcatenatedQaoaParameters; + var success = cobyla.Minimize(concatenatedQaoaParameters); - this.logger?.LogSuccess(success); + this.logger?.LogSuccess(success); + } + } + finally + { + this.logger?.Dispose(); } - - this.logger?.Dispose(); return this.solution; } @@ -219,23 +234,29 @@ public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) /// public QaoaSolution RunOptimization(QaoaParameters qaoaParameters) { - if (this.shouldLog) + try { - this.logger = new QaoaLogger(); - } + if (this.shouldLog) + { + this.logger = new QaoaLogger(); + } - this.solution = new QaoaSolution(null, double.MaxValue, null); + this.solution = new QaoaSolution(null, double.MaxValue, null); - Func objectiveFunction = this.CalculateObjectiveFunction; - var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); - var constraints = this.GenerateConstraints(); + Func objectiveFunction = this.CalculateObjectiveFunctionAsync; + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); + var constraints = this.GenerateConstraints(); - var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); - var concatenatedQaoaParameters = qaoaParameters.ConcatenatedQaoaParameters; - var success = cobyla.Minimize(concatenatedQaoaParameters); + var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); + var concatenatedQaoaParameters = qaoaParameters.ConcatenatedQaoaParameters; + var success = cobyla.Minimize(concatenatedQaoaParameters); - this.logger?.LogSuccess(success); - this.logger?.Dispose(); + this.logger?.LogSuccess(success); + } + finally + { + this.logger?.Dispose(); + } return this.solution; } diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index d0f18500068..bfe50d46cdb 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -48,14 +48,7 @@ public void RunOptimizationRandomParamsTest() var result = optimalSolution.SolutionVector; - if (result[0] == false) - { - CollectionAssert.AreEqual(result, optimizationResult1, "Hybrid QAOA with random parameters produced incorrect result."); - } - else - { - CollectionAssert.AreEqual(result, optimizationResult2, "Hybrid QAOA with random parameters produced incorrect result."); - } + CollectionAssert.AreEqual(result, result[0] ? optimizationResult2 : optimizationResult1, "Hybrid QAOA with random parameters produced incorrect result."); } [TestMethod] @@ -82,14 +75,7 @@ public void RunOptimizationUserParamsTest() var result = optimalSolution.SolutionVector; - if (result[0] == false) - { - CollectionAssert.AreEqual(result, optimizationResult1, "Hybrid QAOA with user's parameters produced incorrect result."); - } - else - { - CollectionAssert.AreEqual(result, optimizationResult2, "Hybrid QAOA with user's parameters produced incorrect result."); - } + CollectionAssert.AreEqual(result, result[0] ? optimizationResult2 : optimizationResult1, "Hybrid QAOA with random parameters produced incorrect result."); } } } From 3fc5d2a151d67d2840ad6f37dffeb8c29b65824c Mon Sep 17 00:00:00 2001 From: Dariusz Date: Fri, 28 Aug 2020 19:17:45 +0200 Subject: [PATCH 58/61] Code refactoring. --- QAOA/src/Qaoa/EvolutionOperations.qs | 23 ++++++++--------- QAOA/src/Qaoa/PhaseKickback.qs | 29 +++++++++++----------- QAOA/tests/QaoaTests/PhaseKickbackTests.qs | 16 +++++------- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/QAOA/src/Qaoa/EvolutionOperations.qs b/QAOA/src/Qaoa/EvolutionOperations.qs index 724da26962b..f79d28f8672 100644 --- a/QAOA/src/Qaoa/EvolutionOperations.qs +++ b/QAOA/src/Qaoa/EvolutionOperations.qs @@ -5,6 +5,7 @@ namespace Microsoft.Quantum.Qaoa { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Arrays; /// # Summary /// Implements a unitary based on the mixing Hamiltonian and applies it to qubits. @@ -24,26 +25,24 @@ namespace Microsoft.Quantum.Qaoa { /// Implements a unitary based on the objective function Hamiltonian and applies it to qubits. /// /// # Input - /// ## qubits - /// Qubits that will be transformed by a unitary. /// ## gamma /// Coefficent for the unitary based on the objective function Hamiltonian. /// ## oneLocalHamiltonianCoefficients - /// Array of 1-local coefficents of the objective function Hamiltonian. + /// Array of 1-local coefficents of the objective function Hamiltonian. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n. The i-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z. /// ## twoLocalHamiltonianCoefficients - /// Array of 2-local coefficents of the objective function Hamiltonian. + /// Array of 2-local coefficents of the objective function Hamiltonian. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n^2. The (i*n+j)-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z\sigma_j^z (other coefficients in an array can take any value of type double). + /// ## qubits + /// Qubits that will be transformed by a unitary. /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. operation EvolveWithObjectiveHamiltonian(gamma: Double, oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[], qubits: Qubit[]) : Unit is Adj + Ctl{ let numberOfQubits = Length(qubits); - using (auxiliaryQubit = Qubit()) { - for(i in 0..numberOfQubits-1) { - R(PauliZ, 2.0*gamma*oneLocalHamiltonianCoefficients[i],qubits[i]); - } - for(i in 0..numberOfQubits-1) { - for (j in i+1..numberOfQubits-1) { - RunPhaseKickback([i,j], 2.0*gamma*twoLocalHamiltonianCoefficients[i*numberOfQubits+j], qubits, auxiliaryQubit); - } + for(i in 0..numberOfQubits-1) { + R(PauliZ, 2.0*gamma*oneLocalHamiltonianCoefficients[i],qubits[i]); + } + for(i in 0..numberOfQubits-1) { + for (j in i+1..numberOfQubits-1) { + RunPhaseKickback(2.0*gamma*twoLocalHamiltonianCoefficients[i*numberOfQubits+j], Subarray([i,j], qubits)); } } } diff --git a/QAOA/src/Qaoa/PhaseKickback.qs b/QAOA/src/Qaoa/PhaseKickback.qs index 3769783ddef..13d19e49e5d 100644 --- a/QAOA/src/Qaoa/PhaseKickback.qs +++ b/QAOA/src/Qaoa/PhaseKickback.qs @@ -12,23 +12,22 @@ namespace Microsoft.Quantum.Qaoa { /// Runs a phase kickback routine on an auxiliary qubit given indices of control qubits and a phase. /// /// # Input - /// ## qubits + /// ## phaseExponent + /// Phase to be applied. + /// ## controlQubits /// Qubits that are to aquire a phase. /// ## auxiliaryQubit /// auxiliary qubit. - /// ## controlQubitsIndices - /// List of indices of control qubits. - /// ## phaseExponent - /// Phase to be applied. - operation RunPhaseKickback(controlQubitsIndices: Int[], phaseExponent: Double, qubits: Qubit[], auxiliaryQubit: Qubit) : Unit is Adj + Ctl { - - within { - ApplyToEachCA( - CNOT(_, auxiliaryQubit), - Subarray(controlQubitsIndices, qubits) - ); - } apply { - R(PauliZ, phaseExponent, auxiliaryQubit); - } + operation RunPhaseKickback(phaseExponent: Double, controlQubits: Qubit[]) : Unit is Adj + Ctl { + using(auxiliaryQubit = Qubit()){ + within { + ApplyToEachCA( + CNOT(_, auxiliaryQubit), + controlQubits + ); + } apply { + R(PauliZ, phaseExponent, auxiliaryQubit); + } + } } } \ No newline at end of file diff --git a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs index 8036b824b8b..dc7f4346121 100644 --- a/QAOA/tests/QaoaTests/PhaseKickbackTests.qs +++ b/QAOA/tests/QaoaTests/PhaseKickbackTests.qs @@ -12,32 +12,28 @@ namespace Microsoft.Quantum.Tests { @Test("QuantumSimulator") operation RunPhaseKickbackTest() : Unit { - let controlQubitsIndices = [0]; let phaseExponent = 0.5; - using ((register, aux) = (Qubit(), Qubit())) { - RunPhaseKickback(controlQubitsIndices, phaseExponent, [register], aux); + using (register = Qubit()) { + RunPhaseKickback(phaseExponent, [register]); AssertQubit(Zero, register); - ResetAll([register]); - ResetAll([aux]); + Reset(register); } } @Test("QuantumSimulator") operation RunPhaseKickbackOneControlQubitTest() : Unit { - let controlQubitsIndices = [0]; let phaseExponent = 0.5; let complexZero = Complex(0.685125,-0.174941); let complexOne = Complex(0.685125,0.174941); - using ((register, aux) = (Qubit(), Qubit())) { + using (register = Qubit()) { H(register); - RunPhaseKickback(controlQubitsIndices, phaseExponent, [register], aux); + RunPhaseKickback(phaseExponent, [register]); AssertQubitIsInStateWithinTolerance((complexZero, complexOne), register, 1E-05); - ResetAll([register]); - ResetAll([aux]); + Reset(register); } } } From c9623b8d34245d0ed3ed657ea74db4abb9f408c4 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 30 Aug 2020 15:48:10 +0200 Subject: [PATCH 59/61] Improved documentation. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 6 ++++++ QAOA/src/Jupyter/HybridQaoaParametersMagic.cs | 3 +++ QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs | 7 +++++-- QAOA/src/Qaoa/QaoaRunner.qs | 9 ++++++--- QAOA/src/QaoaHybrid/QaoaParameters.cs | 4 ++-- QAOA/src/QaoaHybrid/QaoaProblemInstance.cs | 4 ++-- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 95b87acc41c..521d1f4f68a 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -9,6 +9,9 @@ namespace Microsoft.Quantum.Qaoa.Jupyter using Microsoft.Quantum.Qaoa.QaoaHybrid; using Newtonsoft.Json; + /// + /// This class makes it possible to run the hybrid QAOA with user-defined input parameters in languages other than C# that are supported by this mechanism. + /// public class HybridQaoaRunMagic : MagicSymbol { @@ -78,6 +81,9 @@ public async Task Run(string input, IChannel channel) } } + /// + /// This class makes it possible to run the hybrid QAOA with randomly initialized input parameters in languages other than C# that are supported by this mechanism. + /// public class HybridQaoaWithRandomParametersRunMagic : MagicSymbol { diff --git a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs index c84e305475d..279d81dfb8b 100644 --- a/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaParametersMagic.cs @@ -8,6 +8,9 @@ namespace Microsoft.Quantum.Qaoa.Jupyter using Microsoft.Quantum.Qaoa.QaoaHybrid; using Newtonsoft.Json; + /// + /// This class makes it possible to initialize hybrid QAOA input parameters in languages other than C# that are supported by this mechanism. + /// public class HybridQaoaParametersMagic : MagicSymbol { public HybridQaoaParametersMagic() diff --git a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs index 108cdcf7c68..07dcbf749cb 100644 --- a/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaProblemInstanceMagic.cs @@ -8,6 +8,9 @@ namespace Microsoft.Quantum.Qaoa.Jupyter using Microsoft.Quantum.Qaoa.QaoaHybrid; using Newtonsoft.Json; + /// + /// This class makes it possible to create a problem instance for the hybrid QAOA in languages other than C# that are supported by this mechanism. + /// public class HybridQaoaProblemInstanceMagic : MagicSymbol { public HybridQaoaProblemInstanceMagic() @@ -27,13 +30,13 @@ public HybridQaoaProblemInstanceMagic() public class Arguments { /// - /// Coefficents for one-local Hamiltonian terms. + /// Coefficients for one-local Hamiltonian terms. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n. The i-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z. /// [JsonProperty(PropertyName = "one_local_hamiltonian_coefficients")] public double[] OneLocalHamiltonianCoefficients { get; set; } /// - /// Coefficents for one-local Hamiltonian terms. + /// Coefficients for two-local Hamiltonian terms. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n^2. The (i*n+j)-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z\sigma_j^z (other coefficients in an array can take any value of type double). /// [JsonProperty(PropertyName = "two_local_hamiltonian_coefficients")] public double[] TwoLocalHamiltonianCoefficients { get; set; } diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index 7949ff2f792..52d98a2bbee 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -21,17 +21,20 @@ namespace Microsoft.Quantum.Qaoa { /// ## gammas /// Vector of coefficents for the unitary based on the objective function Hamiltonian. /// ## oneLocalHamiltonianCoefficients - /// Array of 1-local coefficents of the objective function Hamiltonian. + /// Array of 1-local coefficents of the objective function Hamiltonian. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n. The i-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z. /// ## twoLocalHamiltonianCoefficients - /// Array of 2-local coefficents of the objective function Hamiltonian. + /// Array of 2-local coefficents of the objective function Hamiltonian. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n^2. The (i*n+j)-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z\sigma_j^z (other coefficients in an array can take any value of type double). /// ## p - /// A parameter related to the depth of a QAOA circuit. It corresponds to the number of times evolution operators are applied. + /// A parameter related to the depth of a QAOA circuit. It corresponds to the number of times evolution operators are applied. The bigger p, the better quality of a solution we might expect. /// /// # Output /// Array of boolean values that represent results of measurements on the QAOA state. /// /// # References /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. + /// + /// # Examples + /// Suppose we want to solve a MAXCUT problem on a simple weighted graph with two connected vertices. Then, problemSize = 2, the corresponding quantum Hamiltonian is \sigma_0^z\sigma_1^z and is expressed as oneLocalHamiltonianCoefficients = new Double[] {0, 0} and twoLocalHamiltonianCoefficients = new Double[]{0, 1, 0, 0}. betas and gammas are arrays with p double elements each (their actual values are difficult to choose upfront). operation RunQaoa(problemSize: Int, betas: Double[], gammas: Double[], oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[], p: Int) : Bool[] { mutable result = new Bool[problemSize]; diff --git a/QAOA/src/QaoaHybrid/QaoaParameters.cs b/QAOA/src/QaoaHybrid/QaoaParameters.cs index 1535b367f57..fb5aa7afe0e 100644 --- a/QAOA/src/QaoaHybrid/QaoaParameters.cs +++ b/QAOA/src/QaoaHybrid/QaoaParameters.cs @@ -9,8 +9,8 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid public class QaoaParameters { - public double[] Betas { get; } - public double[] Gammas { get; } + public double[] Betas { get; set; } + public double[] Gammas { get; set; } public QaoaParameters(double[] concatenatedQaoaParameters) { diff --git a/QAOA/src/QaoaHybrid/QaoaProblemInstance.cs b/QAOA/src/QaoaHybrid/QaoaProblemInstance.cs index d2cd159f728..4f7e91d2b01 100644 --- a/QAOA/src/QaoaHybrid/QaoaProblemInstance.cs +++ b/QAOA/src/QaoaHybrid/QaoaProblemInstance.cs @@ -20,10 +20,10 @@ public class QaoaProblemInstance /// Initializes a new instance of the class. /// /// - /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 1-local terms. Non-existent terms (excluding those that go beyond the size of a problem) shall be input with a coefficient that equals 0. + /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 1-local terms. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n. The i-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z. /// /// - /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 2-local terms. Non-existent terms (excluding those that go beyond the size of a problem) shall be input with a coefficient that equals 0. + /// Given a problem encoding into a Hamiltonian, this field corresponds to coefficients of 2-local terms. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n^2. The (i*n+j)-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z\sigma_j^z (other coefficients in an array can take any value of type double). /// public QaoaProblemInstance(double[] oneLocalHamiltonianCoefficients, double[] twoLocalHamiltonianCoefficients) { From 74ed626c704de5e82b07b54d01604d7705fcda32 Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 30 Aug 2020 16:00:12 +0200 Subject: [PATCH 60/61] Improved naming of the p parameter. --- QAOA/src/Jupyter/HybridQaoaMagic.cs | 12 ++++---- QAOA/src/Qaoa/QaoaRunner.qs | 6 ++-- QAOA/src/QaoaHybrid/HybridQaoa.cs | 30 +++++++++---------- QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs | 8 ++--- .../JupyterTests/HybridQaoaRunMagicTests.cs | 4 +-- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/QAOA/src/Jupyter/HybridQaoaMagic.cs b/QAOA/src/Jupyter/HybridQaoaMagic.cs index 521d1f4f68a..46ee6dde8ab 100644 --- a/QAOA/src/Jupyter/HybridQaoaMagic.cs +++ b/QAOA/src/Jupyter/HybridQaoaMagic.cs @@ -40,8 +40,8 @@ public class Arguments /// /// A parameter related to the depth of a QAOA circuit. /// - [JsonProperty(PropertyName = "p")] - public int p { get; set; } + [JsonProperty(PropertyName = "NHamiltonianApplications")] + public int NHamiltonianApplications { get; set; } /// /// Description of a combinatorial problem to be solved. @@ -75,7 +75,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.QaoaProblemInstance, args.ShouldLog); + var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.NHamiltonianApplications, args.QaoaProblemInstance, args.ShouldLog); return hybridQaoa.RunOptimization(args.InitialQaoaParameters).ToExecutionResult(); } @@ -112,8 +112,8 @@ public class Arguments /// /// A parameter related to the depth of a QAOA circuit. /// - [JsonProperty(PropertyName = "p")] - public int p { get; set; } + [JsonProperty(PropertyName = "NHamiltonianApplications")] + public int NHamiltonianApplications { get; set; } /// /// Description of a combinatorial problem to be solved. @@ -147,7 +147,7 @@ public async Task Run(string input, IChannel channel) var args = JsonConvert.DeserializeObject(input); - var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.p, args.QaoaProblemInstance, args.ShouldLog); + var hybridQaoa = new HybridQaoa(args.NumberOfIterations, args.NHamiltonianApplications, args.QaoaProblemInstance, args.ShouldLog); return hybridQaoa.RunOptimization(args.NumberOfRandomStartingPoints).ToExecutionResult(); } diff --git a/QAOA/src/Qaoa/QaoaRunner.qs b/QAOA/src/Qaoa/QaoaRunner.qs index 52d98a2bbee..d2324035785 100644 --- a/QAOA/src/Qaoa/QaoaRunner.qs +++ b/QAOA/src/Qaoa/QaoaRunner.qs @@ -24,8 +24,6 @@ namespace Microsoft.Quantum.Qaoa { /// Array of 1-local coefficents of the objective function Hamiltonian. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n. The i-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z. /// ## twoLocalHamiltonianCoefficients /// Array of 2-local coefficents of the objective function Hamiltonian. Assuming that a solution to a combinatorial optimization problem can be encoded into n bits (which then corresponds to an encoding into n qubits), this array must be of length n^2. The (i*n+j)-th coefficient in an array corresponds to the coefficient of a term \sigma_i^z\sigma_j^z (other coefficients in an array can take any value of type double). - /// ## p - /// A parameter related to the depth of a QAOA circuit. It corresponds to the number of times evolution operators are applied. The bigger p, the better quality of a solution we might expect. /// /// # Output /// Array of boolean values that represent results of measurements on the QAOA state. @@ -34,8 +32,8 @@ namespace Microsoft.Quantum.Qaoa { /// This implementation in inspired by https://github.com/stephenjordan/qaoa_tsp. /// /// # Examples - /// Suppose we want to solve a MAXCUT problem on a simple weighted graph with two connected vertices. Then, problemSize = 2, the corresponding quantum Hamiltonian is \sigma_0^z\sigma_1^z and is expressed as oneLocalHamiltonianCoefficients = new Double[] {0, 0} and twoLocalHamiltonianCoefficients = new Double[]{0, 1, 0, 0}. betas and gammas are arrays with p double elements each (their actual values are difficult to choose upfront). - operation RunQaoa(problemSize: Int, betas: Double[], gammas: Double[], oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[], p: Int) : Bool[] { + /// Suppose we want to solve a MAXCUT problem on a simple weighted graph with two connected vertices. Then, problemSize = 2, the corresponding quantum Hamiltonian is \sigma_0^z\sigma_1^z and is expressed as oneLocalHamiltonianCoefficients = new Double[] {0, 0} and twoLocalHamiltonianCoefficients = new Double[]{0, 1, 0, 0}. betas and gammas are arrays of p elements each (their actual values are difficult to choose upfront and p is related to the depth of the QAOA circuit). + operation RunQaoa(problemSize: Int, betas: Double[], gammas: Double[], oneLocalHamiltonianCoefficients: Double[], twoLocalHamiltonianCoefficients: Double[]) : Bool[] { mutable result = new Bool[problemSize]; using (qubits = Qubit[problemSize]) { diff --git a/QAOA/src/QaoaHybrid/HybridQaoa.cs b/QAOA/src/QaoaHybrid/HybridQaoa.cs index 5625f1ae27b..f877b424208 100644 --- a/QAOA/src/QaoaHybrid/HybridQaoa.cs +++ b/QAOA/src/QaoaHybrid/HybridQaoa.cs @@ -24,7 +24,7 @@ namespace Microsoft.Quantum.Qaoa.QaoaHybrid public class HybridQaoa { private readonly int numberOfIterations; - private readonly int p; + private readonly int NHamiltonianApplications; private readonly QaoaProblemInstance qaoaProblemInstance; private readonly bool shouldLog; private QaoaSolution solution; @@ -36,7 +36,7 @@ public class HybridQaoa /// /// The number of iterations for sampling the average value of the objective function Hamiltonian. /// - /// + /// /// A parameter related to the depth of a QAOA circuit. It corresponds to the number of times evolution operators are applied. /// /// @@ -45,10 +45,10 @@ public class HybridQaoa /// /// A flag that specifies whether a log from the hybrid QAOA should be saved in a text file. /// - public HybridQaoa(int numberOfIterations, int p, QaoaProblemInstance qaoaProblemInstance, bool shouldLog = false) + public HybridQaoa(int numberOfIterations, int nHamiltonianApplications, QaoaProblemInstance qaoaProblemInstance, bool shouldLog = false) { this.numberOfIterations = numberOfIterations; - this.p = p; + this.NHamiltonianApplications = nHamiltonianApplications; this.qaoaProblemInstance = qaoaProblemInstance; this.shouldLog = shouldLog; } @@ -116,7 +116,7 @@ private double CalculateObjectiveFunctionAsync(double[] concatenatedQaoaParamete for (var i = 0; i < this.numberOfIterations; i++) { - var result = await RunQaoa.Run(qsim, this.qaoaProblemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients, this.p); + var result = await RunQaoa.Run(qsim, this.qaoaProblemInstance.ProblemSizeInBits, betas, gammas, oneLocalHamiltonianCoefficients, twoLocalHamiltonianCoefficients); allSolutionVectors.Add(result.ToArray()); var hamiltonianValue = this.qaoaProblemInstance.EvaluateHamiltonian(result.ToArray()); hamiltonianExpectationValue += hamiltonianValue / this.numberOfIterations; @@ -161,14 +161,14 @@ private void UpdateBestSolution(double hamiltonianExpectationValue, List /// private NonlinearConstraint[] GenerateConstraints() { - var constraints = new NonlinearConstraint[4*this.p]; - foreach (var i in Enumerable.Range(0, this.p).Select(x => x * 2)) + var constraints = new NonlinearConstraint[4*this.NHamiltonianApplications]; + foreach (var i in Enumerable.Range(0, this.NHamiltonianApplications).Select(x => x * 2)) { - var gammaIndex = (2 * this.p) + i; - constraints[i] = new NonlinearConstraint(2 * this.p, x => x[i / 2] >= 0); - constraints[i + 1] = new NonlinearConstraint(2 * this.p, x => x[i / 2] <= Math.PI); - constraints[gammaIndex] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] >= 0); - constraints[gammaIndex + 1] = new NonlinearConstraint(2 * this.p, x => x[gammaIndex / 2] <= 2 * Math.PI); + var gammaIndex = (2 * this.NHamiltonianApplications) + i; + constraints[i] = new NonlinearConstraint(2 * this.NHamiltonianApplications, x => x[i / 2] >= 0); + constraints[i + 1] = new NonlinearConstraint(2 * this.NHamiltonianApplications, x => x[i / 2] <= Math.PI); + constraints[gammaIndex] = new NonlinearConstraint(2 * this.NHamiltonianApplications, x => x[gammaIndex / 2] >= 0); + constraints[gammaIndex + 1] = new NonlinearConstraint(2 * this.NHamiltonianApplications, x => x[gammaIndex / 2] <= 2 * Math.PI); } return constraints; @@ -200,13 +200,13 @@ public QaoaSolution RunOptimization(int numberOfRandomStartingPoints) Func objectiveFunction = this.CalculateObjectiveFunctionAsync; - var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.NHamiltonianApplications, objectiveFunction); var constraints = this.GenerateConstraints(); var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); for (var i = 0; i < numberOfRandomStartingPoints; i++) { - var concatenatedQaoaParameters = new QaoaParameters(p).ConcatenatedQaoaParameters; + var concatenatedQaoaParameters = new QaoaParameters(NHamiltonianApplications).ConcatenatedQaoaParameters; var success = cobyla.Minimize(concatenatedQaoaParameters); this.logger?.LogSuccess(success); @@ -244,7 +244,7 @@ public QaoaSolution RunOptimization(QaoaParameters qaoaParameters) this.solution = new QaoaSolution(null, double.MaxValue, null); Func objectiveFunction = this.CalculateObjectiveFunctionAsync; - var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.p, objectiveFunction); + var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * this.NHamiltonianApplications, objectiveFunction); var constraints = this.GenerateConstraints(); var cobyla = new Cobyla(optimizerObjectiveFunction, constraints); diff --git a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs index bfe50d46cdb..38d5fdb1c6c 100644 --- a/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs +++ b/QAOA/tests/HybridQaoaTests/HybridQaoaTests.cs @@ -35,12 +35,12 @@ public void RunOptimizationRandomParamsTest() var dJ = new double[]{ 0, 1, 0, 0}; var numberOfIterations = 50; - var p = 2; + var NHamiltonianApplications = 2; var numberOfRandomStartingPoints = 2; var simpleMaxCut = new QaoaProblemInstance(dh, dJ); - var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut); + var classicalOptimization = new HybridQaoa(numberOfIterations, NHamiltonianApplications, simpleMaxCut); var optimalSolution = classicalOptimization.RunOptimization(numberOfRandomStartingPoints); var optimizationResult1 = new[] {false, true}; @@ -58,7 +58,7 @@ public void RunOptimizationUserParamsTest() var dJ = new double[] { 0, 1, 0, 0 }; var numberOfIterations = 60; - var p = 3; + var NHamiltonianApplications = 3; var simpleMaxCut = new QaoaProblemInstance(dh, dJ); @@ -67,7 +67,7 @@ public void RunOptimizationUserParamsTest() var qaoaParameters = new QaoaParameters(initialBeta, initialGamma); - var classicalOptimization = new HybridQaoa(numberOfIterations, p, simpleMaxCut); + var classicalOptimization = new HybridQaoa(numberOfIterations, NHamiltonianApplications, simpleMaxCut); var optimalSolution = classicalOptimization.RunOptimization(qaoaParameters); var optimizationResult1 = new[] { false, true }; diff --git a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs index 0332f43a3bd..fa600987f84 100644 --- a/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs +++ b/QAOA/tests/JupyterTests/HybridQaoaRunMagicTests.cs @@ -36,7 +36,7 @@ public async Task HybridQaoaRun() var args = JsonConvert.SerializeObject(new HybridQaoaRunMagic.Arguments { NumberOfIterations = numberOfIterations, - p = p, + NHamiltonianApplications = p, QaoaProblemInstance = simpleMaxCut, InitialQaoaParameters = initialQaoaParameters, }); @@ -80,7 +80,7 @@ public async Task HybridQaoaRun() var args = JsonConvert.SerializeObject(new HybridQaoaWithRandomParametersRunMagic.Arguments { NumberOfIterations = numberOfIterations, - p = p, + NHamiltonianApplications = p, QaoaProblemInstance = simpleMaxCut, NumberOfRandomStartingPoints = numberOfRandomStartingPoints }); From f50e31d3183d9568cf41e49309c21bd22d92dbaf Mon Sep 17 00:00:00 2001 From: Dariusz Date: Mon, 31 Aug 2020 20:30:03 +0200 Subject: [PATCH 61/61] ModeFinder fixed. --- QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs | 8 +------ .../HelpersTests/ModeFinderTests.cs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs index 693212033e1..67f763eb43b 100644 --- a/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs +++ b/QAOA/src/QaoaHybrid/Helpers/ModeFinder.cs @@ -32,13 +32,7 @@ public static bool[] FindModeInBoolList(List list) } } - var maximum = 0; - string result = null; - foreach (var key in counter.Keys.Where(key => counter[key] > maximum)) - { - maximum = counter[key]; - result = key; - } + var result = counter.Aggregate((x, y) => x.Value > y.Value ? x : y).Key; return result.Select(chr => chr == '1').ToArray(); } diff --git a/QAOA/tests/HybridQaoaTests/HelpersTests/ModeFinderTests.cs b/QAOA/tests/HybridQaoaTests/HelpersTests/ModeFinderTests.cs index 3f44f11f578..44439834284 100644 --- a/QAOA/tests/HybridQaoaTests/HelpersTests/ModeFinderTests.cs +++ b/QAOA/tests/HybridQaoaTests/HelpersTests/ModeFinderTests.cs @@ -1,6 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System; +using System.Linq; + namespace Microsoft.Quantum.Qaoa.HybridQaoaTests { using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -27,8 +30,27 @@ public void FindModeInBoolListTest() var result = ModeFinder.FindModeInBoolList(listOfBools); CollectionAssert.AreEqual(expectedResult, result, "Mode bool string not found correctly."); + } + + [TestMethod] + public void FindModeInBoolListWithTieTest() + { + + var listOfBools = new List + { + new[] { false, true, true }, + new[] { false, false, true }, + new[] { false, false, false }, + new[] { false, false, true }, + new[] { false, false, false } + }; + + var expectedResult1 = new[] { false, false, true }; + var expectedResult2 = new[] { false, false, false }; + var result = ModeFinder.FindModeInBoolList(listOfBools); + Assert.IsTrue(expectedResult1.SequenceEqual(result) || expectedResult2.SequenceEqual(result), "Mode bool string not found correctly."); } } }