From 37d2a6871253aaca6450d46e76c4c7096e159c02 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Mon, 20 May 2019 00:01:16 +0200 Subject: [PATCH] Initial commit --- .gitignore | 350 ++++++++++++++++++++++++++++++++++++++++++++ .vscode/launch.json | 28 ++++ .vscode/tasks.json | 15 ++ Driver.cs | 57 ++++++++ First.csproj | 13 ++ Grover.qs | 55 +++++++ Tests.qs | 97 ++++++++++++ Util.qs | 60 ++++++++ 8 files changed, 675 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 Driver.cs create mode 100644 First.csproj create mode 100644 Grover.qs create mode 100644 Tests.qs create mode 100644 Util.qs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74cce04 --- /dev/null +++ b/.gitignore @@ -0,0 +1,350 @@ + +## 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 + +# Mono auto generated files +mono_crash.* + +# 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 +nunit-*.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 +# NuGet Symbol Packages +*.snupkg +# 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 +*.appxbundle +*.appxupload + +# 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 +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).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/ + +# 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 + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5b7d912 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/bin/Debug/netcoreapp2.0/First.dll", + "args": [], + "cwd": "${workspaceFolder}", + // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window + "console": "internalConsole", + "stopAtEntry": false, + "internalConsoleOptions": "openOnSessionStart" + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ,] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..484e6db --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/First.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Driver.cs b/Driver.cs new file mode 100644 index 0000000..a185c42 --- /dev/null +++ b/Driver.cs @@ -0,0 +1,57 @@ +using System; + +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Kadet.Quantum.Tests; + +namespace Kadet.Quantum +{ + class Driver + { + delegate T QuantumTest(IOperationFactory simulator); + + static string Ket(string thing) { + return $"|{thing}⟩"; + } + + static void Main(string[] args) + { + var results = new Dictionary<(bool, bool), long>(); + var rand = new Random(); + var rsim = new ResourcesEstimator(); + + using (var qsim = new QuantumSimulator()) + { + Console.Write("Search QuantumDB: "); + long index = int.Parse(Console.ReadLine()); + long[] database = { + 7, 44, 24, 2, 55, 35, 53, 4, + 17, 3, 58, 21, 15, 28, 50, 19 + }; + + QuantumTest solve = + sim => TestDatabaseSearch.Run(sim, new QArray(database), index).Result; + + var result = Enumerable + .Range(1, 100) + .Select(x => solve(qsim)) + .OrderBy(x => x) + .GroupBy(x => $"{x}"); + + foreach (var group in result) { + Console.WriteLine($"{Ket(group.Key.ToString())} ({group.Count()})"); + } + + + solve(rsim); + Console.WriteLine(); + Console.WriteLine("Resources usage:"); + Console.WriteLine(rsim.ToTSV()); + } + } + } +} \ No newline at end of file diff --git a/First.csproj b/First.csproj new file mode 100644 index 0000000..31a69d0 --- /dev/null +++ b/First.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp2.0 + x64 + + + + + + + diff --git a/Grover.qs b/Grover.qs new file mode 100644 index 0000000..1d3cb5b --- /dev/null +++ b/Grover.qs @@ -0,0 +1,55 @@ +namespace Kadet.Quantum.Grover +{ + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Convert; + + open Kadet.Quantum.Util; + + newtype FlipingOracle = ((Qubit[], Qubit) => Unit); + newtype Records = Int[]; + + operation IsEqualOracle(state: Qubit[], value: Int, output: Qubit): Unit { + ApplyIfEquals(state, value, X, output); + } + + operation GetFromDatabase(database: Records, input: Qubit[], output: Qubit[]): Unit is Adj { + let max = Length(database!) - 1; + + for (i in 0..max) { + let value = database![i]; + ApplyIfEquals(input, i, InitFromInt(_, value), output); + } + } + + function PrepareDatabase(database: Records): ((Qubit[], Qubit[]) => Unit is Adj) { + return GetFromDatabase(database, _, _); + } + + operation Diffusion(state: Qubit[], scratch: Qubit): Unit { + ApplyToEach(H, state); + IsEqualOracle(state, 0, scratch); + ApplyToEach(H, state); + } + + operation GroverOperator(oracle: FlipingOracle, state: Qubit[], scratch: Qubit): Unit { + oracle!(state, scratch); + Diffusion(state, scratch); + } + + function GroverLimit(state: Qubit[]): Int { + return Floor((PI() / 4.0) * PowD(2.0, IntAsDouble(Length(state)) / 2.0)); + } + + operation GroverSearch(state: Qubit[], oracle: FlipingOracle): Unit { + using (scratch = Qubit()) { + X(scratch); + H(scratch); // make scratch to be in |-> state + + ApplyMultipleTimes(GroverLimit(state), GroverOperator(oracle, _, scratch), state); + + Reset(scratch); + } + } +} diff --git a/Tests.qs b/Tests.qs new file mode 100644 index 0000000..1567659 --- /dev/null +++ b/Tests.qs @@ -0,0 +1,97 @@ +namespace Kadet.Quantum.Tests +{ + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Measurement; + + open Kadet.Quantum.Util; + open Kadet.Quantum.Grover; + + operation DatabaseOracle(value: Int, db: ((Qubit[], Qubit[]) => Unit is Adj), input: Qubit[], output: Qubit): Unit { + using (scratch = Qubit[6]) { + db(input, scratch); + IsEqualOracle(scratch, value, output); + Adjoint db(input, scratch); + } + } + + operation TestDatabaseSearch(database: Int[], value: Int): Int { + mutable result = 0; + let db = PrepareDatabase(Records(database)); + + using (input = Qubit[4]) { + ApplyToEach(H, input); + + GroverSearch(input, FlipingOracle(DatabaseOracle(value, db, _, _))); + set result = ResultArrayAsInt(MultiM(input)); + + ResetAll(input); + } + + return result; + } + + operation TestDatabaseSuperposition(database: Int[]): (Int, Int) { + mutable result = (0, 0); + + using ((input, output) = (Qubit[4], Qubit[6])) { + let db = PrepareDatabase(Records(database)); + + ApplyToEach(H, input); + db(input, output); + + set result = ( + ResultArrayAsInt(MultiM(input)), + ResultArrayAsInt(MultiM(output)) + ); + + ResetAll(input); + ResetAll(output); + } + + return result; + } + + operation TestDatabase(database: Int[], index: Int): Int { + mutable result = 0; + + + using ((input, output) = (Qubit[4], Qubit[6])) { + let db = PrepareDatabase(Records(database)); + + InitFromInt(input, index); + + db(input, output); + + set result = ResultArrayAsInt(MultiM(output)); + + ResetAll(input); + ResetAll(output); + } + + return result; + } + + operation TestAddition(a: Int, b: Int) : Int { + mutable result = 0; + + using ((aReg, bReg, sum) = (Qubit[5], Qubit[5], Qubit[6])) { + ResetAll(aReg); + ResetAll(bReg); + ResetAll(sum); + + InitFromInt(aReg, a); + InitFromInt(bReg, b); + + Add(aReg, bReg, sum); + set result = ResultArrayAsInt(MultiM(sum)); + + ResetAll(aReg); + ResetAll(bReg); + ResetAll(sum); + } + + return result; + } +} \ No newline at end of file diff --git a/Util.qs b/Util.qs new file mode 100644 index 0000000..85f8212 --- /dev/null +++ b/Util.qs @@ -0,0 +1,60 @@ +namespace Kadet.Quantum.Util +{ + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Convert; + + operation HalfAdd(a: Qubit, b: Qubit, carry: Qubit, sum: Qubit): Unit { + CNOT(a, sum); // entangle sum with a, so sum behaves in same way + CNOT(b, sum); // xor sum (entagled with a) with b + + CCNOT(a, b, carry); // carry is set only if a and b + } + + operation FullAdd(a: Qubit, b: Qubit, carry: Qubit, sum: Qubit): Unit { + CCNOT(a, b, sum); + CNOT(a, b); + CCNOT(b, carry, sum); + CNOT(b, carry); + CNOT(a, b); + SWAP(sum, carry); + } + + operation Add(a: Qubit[], b: Qubit[], sum: Qubit[]): Unit { + let max = Length(a) - 1; + let carry = sum[max + 1]; + + for (i in 0..max) { + FullAdd(a[i], b[i], carry, sum[i]); + } + } + + operation ApplyToMask<'T>(mask: Int, action: ('T => Unit is Ctl+Adj), target: 'T[]): Unit is Ctl+Adj { + let count = Length(target); + let bits = IntAsBoolArray(((1 <<< count) - 1) &&& mask, count); + + for (i in 0..count - 1) { + ApplyIfCA(action, bits[i], target[i]); + } + } + + operation ApplyIfEquals<'T>(input: Qubit[], value: Int, Action: ('T => Unit is Ctl+Adj), target: 'T): Unit is Adj { + let mask = ~~~value; + + ApplyToMask(mask, X, input); + Controlled Action(input, target); + ApplyToMask(mask, X, input); + } + + operation ApplyMultipleTimes<'T>(times: Int, op: ('T => Unit), target: 'T): Unit { + for (i in 0..times - 1) { + op(target); + } + } + + operation InitFromInt(reg: Qubit[], number: Int): Unit is Ctl+Adj { + let max = Length(reg) - 1; + + ApplyToMask(number, X, reg); + } +}