qsharp-lang 1.10.3-dev → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/dist/katas-content.generated.js +377 -377
  2. package/dist/katas-content.generated.md.js +377 -377
  3. package/dist/samples.generated.js +12 -12
  4. package/docs/Microsoft.Quantum.Core/Length.md +4 -4
  5. package/docs/Microsoft.Quantum.Core/Repeated.md +4 -4
  6. package/docs/Microsoft.Quantum.Core/index.md +3 -3
  7. package/docs/Std.Arithmetic/AddLE.md +1 -1
  8. package/docs/Std.Arithmetic/ApplyIfEqualL.md +1 -1
  9. package/docs/Std.Arithmetic/ApplyIfEqualLE.md +1 -1
  10. package/docs/Std.Arithmetic/ApplyIfGreaterL.md +1 -1
  11. package/docs/Std.Arithmetic/ApplyIfGreaterLE.md +1 -1
  12. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualL.md +1 -1
  13. package/docs/Std.Arithmetic/ApplyIfGreaterOrEqualLE.md +1 -1
  14. package/docs/Std.Arithmetic/ApplyIfLessL.md +1 -1
  15. package/docs/Std.Arithmetic/ApplyIfLessLE.md +1 -1
  16. package/docs/Std.Arithmetic/ApplyIfLessOrEqualL.md +1 -1
  17. package/docs/Std.Arithmetic/ApplyIfLessOrEqualLE.md +1 -1
  18. package/docs/Std.Arithmetic/FourierTDIncByLE.md +1 -1
  19. package/docs/Std.Arithmetic/IncByI.md +1 -1
  20. package/docs/Std.Arithmetic/IncByIUsingIncByLE.md +1 -1
  21. package/docs/Std.Arithmetic/IncByL.md +1 -1
  22. package/docs/Std.Arithmetic/IncByLE.md +1 -1
  23. package/docs/Std.Arithmetic/IncByLEUsingAddLE.md +1 -1
  24. package/docs/Std.Arithmetic/IncByLUsingIncByLE.md +1 -1
  25. package/docs/Std.Arithmetic/LookAheadDKRSAddLE.md +1 -1
  26. package/docs/Std.Arithmetic/MAJ.md +1 -1
  27. package/docs/Std.Arithmetic/ReflectAboutInteger.md +1 -1
  28. package/docs/Std.Arithmetic/RippleCarryCGAddLE.md +1 -1
  29. package/docs/Std.Arithmetic/RippleCarryCGIncByLE.md +1 -1
  30. package/docs/Std.Arithmetic/RippleCarryTTKIncByLE.md +1 -1
  31. package/docs/Std.Arithmetic/index.md +1 -1
  32. package/docs/Std.Arrays/All.md +1 -1
  33. package/docs/Std.Arrays/Any.md +1 -1
  34. package/docs/Std.Arrays/Chunks.md +1 -1
  35. package/docs/Std.Arrays/CircularlyShifted.md +1 -1
  36. package/docs/Std.Arrays/ColumnAt.md +3 -3
  37. package/docs/Std.Arrays/Count.md +1 -1
  38. package/docs/Std.Arrays/Diagonal.md +2 -2
  39. package/docs/Std.Arrays/DrawMany.md +2 -2
  40. package/docs/Std.Arrays/Enumerated.md +1 -1
  41. package/docs/Std.Arrays/Excluding.md +1 -1
  42. package/docs/Std.Arrays/Filtered.md +1 -1
  43. package/docs/Std.Arrays/FlatMapped.md +1 -1
  44. package/docs/Std.Arrays/Flattened.md +1 -1
  45. package/docs/Std.Arrays/Fold.md +1 -1
  46. package/docs/Std.Arrays/ForEach.md +2 -2
  47. package/docs/Std.Arrays/Head.md +1 -1
  48. package/docs/Std.Arrays/HeadAndRest.md +1 -1
  49. package/docs/Std.Arrays/IndexOf.md +1 -1
  50. package/docs/Std.Arrays/IndexRange.md +1 -1
  51. package/docs/Std.Arrays/Interleaved.md +1 -1
  52. package/docs/Std.Arrays/IsEmpty.md +1 -1
  53. package/docs/Std.Arrays/IsRectangularArray.md +2 -2
  54. package/docs/Std.Arrays/IsSorted.md +1 -1
  55. package/docs/Std.Arrays/IsSquareArray.md +2 -2
  56. package/docs/Std.Arrays/Mapped.md +2 -2
  57. package/docs/Std.Arrays/MappedByIndex.md +2 -2
  58. package/docs/Std.Arrays/MappedOverRange.md +2 -2
  59. package/docs/Std.Arrays/Most.md +1 -1
  60. package/docs/Std.Arrays/MostAndTail.md +1 -1
  61. package/docs/Std.Arrays/Padded.md +1 -1
  62. package/docs/Std.Arrays/Partitioned.md +1 -1
  63. package/docs/Std.Arrays/Rest.md +1 -1
  64. package/docs/Std.Arrays/Reversed.md +1 -1
  65. package/docs/Std.Arrays/SequenceI.md +1 -1
  66. package/docs/Std.Arrays/SequenceL.md +1 -1
  67. package/docs/Std.Arrays/Sorted.md +1 -1
  68. package/docs/Std.Arrays/Subarray.md +1 -1
  69. package/docs/Std.Arrays/Swapped.md +1 -1
  70. package/docs/Std.Arrays/Tail.md +1 -1
  71. package/docs/Std.Arrays/Transposed.md +1 -1
  72. package/docs/Std.Arrays/Unzipped.md +2 -2
  73. package/docs/Std.Arrays/Where.md +1 -1
  74. package/docs/Std.Arrays/Windows.md +1 -1
  75. package/docs/Std.Arrays/Zipped.md +2 -2
  76. package/docs/Std.Arrays/index.md +1 -1
  77. package/docs/Std.Canon/ApplyCNOTChain.md +1 -1
  78. package/docs/Std.Canon/ApplyControlledOnBitString.md +1 -1
  79. package/docs/Std.Canon/ApplyControlledOnInt.md +1 -1
  80. package/docs/Std.Canon/ApplyP.md +1 -1
  81. package/docs/Std.Canon/ApplyPauli.md +1 -1
  82. package/docs/Std.Canon/ApplyPauliFromBitString.md +1 -1
  83. package/docs/Std.Canon/ApplyPauliFromInt.md +1 -1
  84. package/docs/Std.Canon/ApplyQFT.md +1 -1
  85. package/docs/Std.Canon/ApplyToEach.md +1 -1
  86. package/docs/Std.Canon/ApplyToEachA.md +2 -2
  87. package/docs/Std.Canon/ApplyToEachC.md +2 -2
  88. package/docs/Std.Canon/ApplyToEachCA.md +2 -2
  89. package/docs/Std.Canon/ApplyXorInPlace.md +1 -1
  90. package/docs/Std.Canon/ApplyXorInPlaceL.md +1 -1
  91. package/docs/Std.Canon/CX.md +1 -1
  92. package/docs/Std.Canon/CY.md +1 -1
  93. package/docs/Std.Canon/CZ.md +1 -1
  94. package/docs/Std.Canon/Fst.md +1 -1
  95. package/docs/Std.Canon/Relabel.md +1 -1
  96. package/docs/Std.Canon/Snd.md +1 -1
  97. package/docs/Std.Canon/SwapReverseRegister.md +1 -1
  98. package/docs/Std.Canon/index.md +1 -1
  99. package/docs/Std.Convert/BigIntAsBoolArray.md +1 -1
  100. package/docs/Std.Convert/BoolArrayAsBigInt.md +1 -1
  101. package/docs/Std.Convert/BoolArrayAsInt.md +1 -1
  102. package/docs/Std.Convert/BoolArrayAsResultArray.md +1 -1
  103. package/docs/Std.Convert/BoolAsResult.md +1 -1
  104. package/docs/Std.Convert/ComplexAsComplexPolar.md +1 -1
  105. package/docs/Std.Convert/ComplexPolarAsComplex.md +1 -1
  106. package/docs/Std.Convert/DoubleAsStringWithPrecision.md +1 -1
  107. package/docs/Std.Convert/IntAsBigInt.md +1 -1
  108. package/docs/Std.Convert/IntAsBoolArray.md +1 -1
  109. package/docs/Std.Convert/IntAsDouble.md +1 -1
  110. package/docs/Std.Convert/ResultArrayAsBoolArray.md +1 -1
  111. package/docs/Std.Convert/ResultArrayAsInt.md +1 -1
  112. package/docs/Std.Convert/ResultAsBool.md +1 -1
  113. package/docs/Std.Convert/index.md +1 -1
  114. package/docs/Std.Core/Length.md +1 -1
  115. package/docs/Std.Core/Repeated.md +1 -1
  116. package/docs/Std.Core/index.md +1 -1
  117. package/docs/Std.Diagnostics/ApplyIdleNoise.md +1 -1
  118. package/docs/Std.Diagnostics/BitFlipNoise.md +1 -1
  119. package/docs/Std.Diagnostics/CheckAllZero.md +1 -1
  120. package/docs/Std.Diagnostics/CheckOperationsAreEqual.md +1 -1
  121. package/docs/Std.Diagnostics/CheckZero.md +1 -1
  122. package/docs/Std.Diagnostics/ConfigurePauliNoise.md +1 -1
  123. package/docs/Std.Diagnostics/DepolarizingNoise.md +1 -1
  124. package/docs/Std.Diagnostics/DumpMachine.md +1 -1
  125. package/docs/Std.Diagnostics/DumpOperation.md +1 -1
  126. package/docs/Std.Diagnostics/DumpRegister.md +1 -1
  127. package/docs/Std.Diagnostics/Fact.md +1 -1
  128. package/docs/Std.Diagnostics/NoNoise.md +1 -1
  129. package/docs/Std.Diagnostics/PhaseFlipNoise.md +1 -1
  130. package/docs/Std.Diagnostics/StartCountingFunction.md +1 -1
  131. package/docs/Std.Diagnostics/StartCountingOperation.md +1 -1
  132. package/docs/Std.Diagnostics/StartCountingQubits.md +1 -1
  133. package/docs/Std.Diagnostics/StopCountingFunction.md +1 -1
  134. package/docs/Std.Diagnostics/StopCountingOperation.md +1 -1
  135. package/docs/Std.Diagnostics/StopCountingQubits.md +1 -1
  136. package/docs/Std.Diagnostics/index.md +1 -1
  137. package/docs/Std.Intrinsic/AND.md +1 -1
  138. package/docs/Std.Intrinsic/CCNOT.md +1 -1
  139. package/docs/Std.Intrinsic/CNOT.md +1 -1
  140. package/docs/Std.Intrinsic/Exp.md +1 -1
  141. package/docs/Std.Intrinsic/H.md +1 -1
  142. package/docs/Std.Intrinsic/I.md +1 -1
  143. package/docs/Std.Intrinsic/M.md +1 -1
  144. package/docs/Std.Intrinsic/Measure.md +1 -1
  145. package/docs/Std.Intrinsic/Message.md +1 -1
  146. package/docs/Std.Intrinsic/R.md +1 -1
  147. package/docs/Std.Intrinsic/R1.md +1 -1
  148. package/docs/Std.Intrinsic/R1Frac.md +4 -4
  149. package/docs/Std.Intrinsic/RFrac.md +4 -4
  150. package/docs/Std.Intrinsic/Reset.md +1 -1
  151. package/docs/Std.Intrinsic/ResetAll.md +1 -1
  152. package/docs/Std.Intrinsic/Rx.md +1 -1
  153. package/docs/Std.Intrinsic/Rxx.md +1 -1
  154. package/docs/Std.Intrinsic/Ry.md +1 -1
  155. package/docs/Std.Intrinsic/Ryy.md +1 -1
  156. package/docs/Std.Intrinsic/Rz.md +1 -1
  157. package/docs/Std.Intrinsic/Rzz.md +1 -1
  158. package/docs/Std.Intrinsic/S.md +1 -1
  159. package/docs/Std.Intrinsic/SWAP.md +1 -1
  160. package/docs/Std.Intrinsic/T.md +1 -1
  161. package/docs/Std.Intrinsic/X.md +1 -1
  162. package/docs/Std.Intrinsic/Y.md +1 -1
  163. package/docs/Std.Intrinsic/Z.md +1 -1
  164. package/docs/Std.Intrinsic/index.md +3 -3
  165. package/docs/Std.Logical/Xor.md +1 -1
  166. package/docs/Std.Logical/index.md +1 -1
  167. package/docs/Std.Math/AbsComplex.md +1 -1
  168. package/docs/Std.Math/AbsComplexPolar.md +1 -1
  169. package/docs/Std.Math/AbsD.md +1 -1
  170. package/docs/Std.Math/AbsI.md +1 -1
  171. package/docs/Std.Math/AbsL.md +1 -1
  172. package/docs/Std.Math/AbsSquaredComplex.md +1 -1
  173. package/docs/Std.Math/AbsSquaredComplexPolar.md +1 -1
  174. package/docs/Std.Math/ApproximateFactorial.md +3 -3
  175. package/docs/Std.Math/ArcCos.md +1 -1
  176. package/docs/Std.Math/ArcCosh.md +1 -1
  177. package/docs/Std.Math/ArcSin.md +1 -1
  178. package/docs/Std.Math/ArcSinh.md +1 -1
  179. package/docs/Std.Math/ArcTan.md +1 -1
  180. package/docs/Std.Math/ArcTan2.md +1 -1
  181. package/docs/Std.Math/ArcTanh.md +1 -1
  182. package/docs/Std.Math/ArgComplex.md +1 -1
  183. package/docs/Std.Math/ArgComplexPolar.md +1 -1
  184. package/docs/Std.Math/Binom.md +1 -1
  185. package/docs/Std.Math/BitSizeI.md +1 -1
  186. package/docs/Std.Math/BitSizeL.md +1 -1
  187. package/docs/Std.Math/Ceiling.md +1 -1
  188. package/docs/Std.Math/Complex.md +1 -1
  189. package/docs/Std.Math/ComplexPolar.md +1 -1
  190. package/docs/Std.Math/ContinuedFractionConvergentI.md +1 -1
  191. package/docs/Std.Math/ContinuedFractionConvergentL.md +1 -1
  192. package/docs/Std.Math/Cos.md +1 -1
  193. package/docs/Std.Math/Cosh.md +1 -1
  194. package/docs/Std.Math/DivRemI.md +1 -1
  195. package/docs/Std.Math/DivRemL.md +1 -1
  196. package/docs/Std.Math/DividedByC.md +1 -1
  197. package/docs/Std.Math/DividedByCP.md +1 -1
  198. package/docs/Std.Math/E.md +2 -2
  199. package/docs/Std.Math/ExpModI.md +1 -1
  200. package/docs/Std.Math/ExpModL.md +1 -1
  201. package/docs/Std.Math/ExtendedGreatestCommonDivisorI.md +1 -1
  202. package/docs/Std.Math/ExtendedGreatestCommonDivisorL.md +1 -1
  203. package/docs/Std.Math/FactorialI.md +4 -4
  204. package/docs/Std.Math/FactorialL.md +3 -3
  205. package/docs/Std.Math/Floor.md +1 -1
  206. package/docs/Std.Math/GreatestCommonDivisorI.md +1 -1
  207. package/docs/Std.Math/GreatestCommonDivisorL.md +1 -1
  208. package/docs/Std.Math/HammingWeightI.md +1 -1
  209. package/docs/Std.Math/InverseModI.md +1 -1
  210. package/docs/Std.Math/InverseModL.md +1 -1
  211. package/docs/Std.Math/IsCoprimeI.md +1 -1
  212. package/docs/Std.Math/IsCoprimeL.md +1 -1
  213. package/docs/Std.Math/IsInfinite.md +2 -2
  214. package/docs/Std.Math/IsNaN.md +1 -1
  215. package/docs/Std.Math/LargestFixedPoint.md +1 -1
  216. package/docs/Std.Math/Lg.md +1 -1
  217. package/docs/Std.Math/Log.md +1 -1
  218. package/docs/Std.Math/Log10.md +1 -1
  219. package/docs/Std.Math/LogFactorialD.md +4 -4
  220. package/docs/Std.Math/LogGammaD.md +1 -1
  221. package/docs/Std.Math/LogOf2.md +1 -1
  222. package/docs/Std.Math/Max.md +1 -1
  223. package/docs/Std.Math/MaxD.md +1 -1
  224. package/docs/Std.Math/MaxI.md +1 -1
  225. package/docs/Std.Math/MaxL.md +1 -1
  226. package/docs/Std.Math/Min.md +1 -1
  227. package/docs/Std.Math/MinD.md +1 -1
  228. package/docs/Std.Math/MinI.md +1 -1
  229. package/docs/Std.Math/MinL.md +1 -1
  230. package/docs/Std.Math/MinusC.md +1 -1
  231. package/docs/Std.Math/MinusCP.md +1 -1
  232. package/docs/Std.Math/ModulusI.md +1 -1
  233. package/docs/Std.Math/ModulusL.md +1 -1
  234. package/docs/Std.Math/NegationC.md +1 -1
  235. package/docs/Std.Math/NegationCP.md +1 -1
  236. package/docs/Std.Math/PI.md +2 -2
  237. package/docs/Std.Math/PNorm.md +1 -1
  238. package/docs/Std.Math/PNormalized.md +1 -1
  239. package/docs/Std.Math/PlusC.md +1 -1
  240. package/docs/Std.Math/PlusCP.md +1 -1
  241. package/docs/Std.Math/PowC.md +1 -1
  242. package/docs/Std.Math/PowCP.md +1 -1
  243. package/docs/Std.Math/RealMod.md +1 -1
  244. package/docs/Std.Math/Round.md +1 -1
  245. package/docs/Std.Math/SignD.md +1 -1
  246. package/docs/Std.Math/SignI.md +1 -1
  247. package/docs/Std.Math/SignL.md +1 -1
  248. package/docs/Std.Math/Sin.md +1 -1
  249. package/docs/Std.Math/Sinh.md +1 -1
  250. package/docs/Std.Math/SmallestFixedPoint.md +1 -1
  251. package/docs/Std.Math/Sqrt.md +1 -1
  252. package/docs/Std.Math/SquaredNorm.md +1 -1
  253. package/docs/Std.Math/Tan.md +1 -1
  254. package/docs/Std.Math/Tanh.md +1 -1
  255. package/docs/Std.Math/TimesC.md +1 -1
  256. package/docs/Std.Math/TimesCP.md +1 -1
  257. package/docs/Std.Math/TrailingZeroCountI.md +1 -1
  258. package/docs/Std.Math/TrailingZeroCountL.md +1 -1
  259. package/docs/Std.Math/Truncate.md +1 -1
  260. package/docs/Std.Math/index.md +1 -1
  261. package/docs/Std.Measurement/MResetEachZ.md +2 -2
  262. package/docs/Std.Measurement/MResetX.md +1 -1
  263. package/docs/Std.Measurement/MResetY.md +1 -1
  264. package/docs/Std.Measurement/MResetZ.md +1 -1
  265. package/docs/Std.Measurement/MeasureAllZ.md +2 -2
  266. package/docs/Std.Measurement/MeasureEachZ.md +3 -3
  267. package/docs/Std.Measurement/MeasureInteger.md +1 -1
  268. package/docs/Std.Measurement/index.md +1 -1
  269. package/docs/Std.Random/DrawRandomBool.md +1 -1
  270. package/docs/Std.Random/DrawRandomDouble.md +1 -1
  271. package/docs/Std.Random/DrawRandomInt.md +1 -1
  272. package/docs/Std.Random/index.md +1 -1
  273. package/docs/Std.Range/IsRangeEmpty.md +1 -1
  274. package/docs/Std.Range/RangeEnd.md +1 -1
  275. package/docs/Std.Range/RangeReverse.md +1 -1
  276. package/docs/Std.Range/RangeStart.md +1 -1
  277. package/docs/Std.Range/RangeStep.md +1 -1
  278. package/docs/Std.Range/index.md +1 -1
  279. package/docs/Std.ResourceEstimation/AccountForEstimates.md +1 -1
  280. package/docs/Std.ResourceEstimation/AuxQubitCount.md +1 -1
  281. package/docs/Std.ResourceEstimation/BeginEstimateCaching.md +1 -1
  282. package/docs/Std.ResourceEstimation/BeginRepeatEstimates.md +1 -1
  283. package/docs/Std.ResourceEstimation/CczCount.md +1 -1
  284. package/docs/Std.ResourceEstimation/EndEstimateCaching.md +1 -1
  285. package/docs/Std.ResourceEstimation/EndRepeatEstimates.md +1 -1
  286. package/docs/Std.ResourceEstimation/MeasurementCount.md +1 -1
  287. package/docs/Std.ResourceEstimation/PSSPCLayout.md +1 -1
  288. package/docs/Std.ResourceEstimation/RepeatEstimates.md +1 -1
  289. package/docs/Std.ResourceEstimation/RotationCount.md +1 -1
  290. package/docs/Std.ResourceEstimation/RotationDepth.md +1 -1
  291. package/docs/Std.ResourceEstimation/SingleVariant.md +1 -1
  292. package/docs/Std.ResourceEstimation/TCount.md +1 -1
  293. package/docs/Std.ResourceEstimation/index.md +1 -1
  294. package/docs/Std.StatePreparation/ApproximatelyPreparePureStateCP.md +1 -1
  295. package/docs/Std.StatePreparation/PreparePureStateD.md +2 -2
  296. package/docs/Std.StatePreparation/index.md +1 -1
  297. package/docs/Std.TableLookup/Select.md +1 -1
  298. package/docs/Std.TableLookup/index.md +1 -1
  299. package/docs/index.md +1 -1
  300. package/lib/node/qsc_wasm_bg.wasm +0 -0
  301. package/lib/web/qsc_wasm_bg.wasm +0 -0
  302. package/package.json +1 -1
@@ -42,42 +42,42 @@ export default [
42
42
  {
43
43
  "title": "Deutsch-Jozsa",
44
44
  "shots": 1,
45
- "code": "/// # Sample\n/// Deutsch–Jozsa algorithm\n///\n/// # Description\n/// Deutsch–Jozsa is a quantum algorithm that determines whether a given Boolean\n/// function 𝑓 is constant (0 on all inputs or 1 on all inputs) or balanced\n/// (1 for exactly half of the input domain and 0 for the other half).\n///\n/// This Q# program implements the Deutsch–Jozsa algorithm.\nimport Std.Measurement.*;\n\noperation Main() : (Result[], Result[]) {\n // A Boolean function is a function that maps bitstrings to a bit:\n // 𝑓 : {0, 1}^n → {0, 1}.\n\n // We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings 𝑥⃗ and\n // 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true for exactly half of\n // its inputs.\n\n // If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉 =\n // |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or is\n // balanced, then the Deutsch–Jozsa algorithm decides between these\n // cases with a single application of 𝑈.\n\n // Here, we demonstrate the use of the Deutsch-Jozsa algorithm by\n // determining the type (constant or balanced) of a couple of functions.\n let balancedResults = DeutschJozsa(SimpleBalancedBoolF, 5);\n let constantResults = DeutschJozsa(SimpleConstantBoolF, 5);\n return (balancedResults, constantResults);\n}\n\n/// # Summary\n/// This operation implements the DeutschJozsa algorithm.\n/// It returns the query register measurement results. If all the measurement\n/// results are `Zero`, the function is constant. If at least one measurement\n/// result is `One`, the function is balanced.\n/// It is assumed that the function is either constant or balanced.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, where 𝑓 is a\n/// Boolean function, 𝑥 is an 𝑛 bit register and 𝑦 is a single qubit.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// An array of measurement results for the query register.\n/// All `Zero` measurement results indicate that the function is constant.\n/// At least one `One` measurement result in the array indicates that the\n/// function is balanced.\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Michael A. Nielsen , Isaac L. Chuang*,\n/// Quantum Computation and Quantum Information ]\n/// (http://doi.org/10.1017/CBO9780511976667)\noperation DeutschJozsa(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Result[] {\n // We allocate n + 1 clean qubits. Note that the function `Uf` is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n // Now, a Hadamard transform is applied to each of the qubits.\n H(target);\n // We use a within-apply block to ensure that the Hadamard transform is\n // correctly inverted on the |𝑥〉 register.\n within {\n for q in queryRegister {\n H(q);\n }\n } apply {\n // We apply Uf to the n+1 qubits, computing |𝑥, 𝑦〉 ↦ |𝑥, 𝑦 ⊕ 𝑓(𝑥)〉.\n Uf(queryRegister, target);\n }\n\n // Measure the query register and reset all qubits so they can be safely\n // deallocated.\n let results = MResetEachZ(queryRegister);\n Reset(target);\n return results;\n}\n\n// Simple constant Boolean function\noperation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n}\n\n// Simple balanced Boolean function\noperation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n}\n"
45
+ "code": "/// # Sample\n/// Deutsch–Jozsa Algorithm\n///\n/// # Description\n/// Deutsch–Jozsa is a quantum algorithm that determines whether a given Boolean\n/// function 𝑓 is constant (0 on all inputs or 1 on all inputs) or balanced\n/// (1 for exactly half of the input domain and 0 for the other half).\n///\n/// This Q# program implements the Deutsch–Jozsa algorithm.\nimport Std.Measurement.*;\n\noperation Main() : (Result[], Result[]) {\n // A Boolean function is a function that maps bitstrings to a bit:\n // 𝑓 : {0, 1}^n → {0, 1}.\n\n // We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings 𝑥⃗ and\n // 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true for exactly half of\n // its inputs.\n\n // If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉 =\n // |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or is\n // balanced, then the Deutsch–Jozsa algorithm decides between these\n // cases with a single application of 𝑈.\n\n // Here, we demonstrate the use of the Deutsch-Jozsa algorithm by\n // determining the type (constant or balanced) of a couple of functions.\n let balancedResults = DeutschJozsa(SimpleBalancedBoolF, 5);\n let constantResults = DeutschJozsa(SimpleConstantBoolF, 5);\n return (balancedResults, constantResults);\n}\n\n/// # Summary\n/// This operation implements the DeutschJozsa algorithm.\n/// It returns the query register measurement results. If all the measurement\n/// results are `Zero`, the function is constant. If at least one measurement\n/// result is `One`, the function is balanced.\n/// It is assumed that the function is either constant or balanced.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, where 𝑓 is a\n/// Boolean function, 𝑥 is an 𝑛 bit register and 𝑦 is a single qubit.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// An array of measurement results for the query register.\n/// All `Zero` measurement results indicate that the function is constant.\n/// At least one `One` measurement result in the array indicates that the\n/// function is balanced.\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Michael A. Nielsen , Isaac L. Chuang*,\n/// Quantum Computation and Quantum Information ]\n/// (http://doi.org/10.1017/CBO9780511976667)\noperation DeutschJozsa(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Result[] {\n // We allocate n + 1 clean qubits. Note that the function `Uf` is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n // Now, a Hadamard transform is applied to each of the qubits.\n H(target);\n // We use a within-apply block to ensure that the Hadamard transform is\n // correctly inverted on the |𝑥〉 register.\n within {\n for q in queryRegister {\n H(q);\n }\n } apply {\n // We apply Uf to the n+1 qubits, computing |𝑥, 𝑦〉 ↦ |𝑥, 𝑦 ⊕ 𝑓(𝑥)〉.\n Uf(queryRegister, target);\n }\n\n // Measure the query register and reset all qubits so they can be safely\n // deallocated.\n let results = MResetEachZ(queryRegister);\n Reset(target);\n return results;\n}\n\n// Simple constant Boolean function\noperation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n}\n\n// Simple balanced Boolean function\noperation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n}\n"
46
46
  },
47
47
  {
48
48
  "title": "Deutsch-Jozsa (Advanced)",
49
49
  "shots": 1,
50
- "code": "/// # Sample\n/// Deutsch–Jozsa algorithm\n///\n/// # Description\n/// Deutsch–Jozsa is a quantum algorithm that determines whether a given Boolean\n/// function 𝑓 is constant (0 on all inputs or 1 on all inputs) or balanced\n/// (1 for exactly half of the input domain and 0 for the other half).\n///\n/// This Q# program implements the Deutsch–Jozsa algorithm.\nimport Std.Diagnostics.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\n\noperation Main() : (String, Bool)[] {\n // A Boolean function is a function that maps bitstrings to a bit:\n // 𝑓 : {0, 1}^n → {0, 1}.\n\n // We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings 𝑥⃗ and\n // 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true for exactly half of\n // its inputs.\n\n // If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉 =\n // |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or is\n // balanced, then the Deutsch–Jozsa algorithm decides between these\n // cases with a single application of 𝑈.\n\n // Here, we demonstrate the use of the Deutsch-Jozsa algorithm by\n // determining the type (constant or balanced) of various functions.\n let nameFunctionTypeTuples = [\n (\"SimpleConstantBoolF\", SimpleConstantBoolF, true),\n (\"SimpleBalancedBoolF\", SimpleBalancedBoolF, false),\n (\"ConstantBoolF\", ConstantBoolF, true),\n (\"BalancedBoolF\", BalancedBoolF, false)\n ];\n\n mutable results = [];\n for (name, fn, shouldBeConstant) in nameFunctionTypeTuples {\n let isConstant = DeutschJozsa(fn, 5);\n if (isConstant != shouldBeConstant) {\n let shouldBeConstantStr = shouldBeConstant ? \"constant\" | \"balanced\";\n fail $\"{name} should be detected as {shouldBeConstantStr}\";\n }\n\n let isConstantStr = isConstant ? \"constant\" | \"balanced\";\n Message($\"{name} is {isConstantStr}\");\n set results += [(name, isConstant)];\n }\n\n return results;\n}\n\n/// # Summary\n/// This operation implements the DeutschJozsa algorithm.\n/// It returns the Boolean value `true` if the function is constant and\n/// `false` if it is not.\n/// It is assumed that the function is either constant or balanced.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, where 𝑓 is a\n/// Boolean function, 𝑥 is an 𝑛 bit register and 𝑦 is a single qubit.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// A boolean value `true` that indicates that the function is constant and\n/// `false` that indicates that the function is balanced.\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Michael A. Nielsen , Isaac L. Chuang*,\n/// Quantum Computation and Quantum Information ]\n/// (http://doi.org/10.1017/CBO9780511976667)\noperation DeutschJozsa(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Bool {\n // We allocate n + 1 clean qubits. Note that the function `Uf` is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n // Now, a Hadamard transform is applied to each of the qubits.\n H(target);\n // We use a within-apply block to ensure that the Hadamard transform is\n // correctly inverted on the |𝑥〉 register.\n within {\n for q in queryRegister {\n H(q);\n }\n } apply {\n // We apply Uf to the n+1 qubits, computing |𝑥, 𝑦〉 ↦ |𝑥, 𝑦 ⊕ 𝑓(𝑥)〉.\n Uf(queryRegister, target);\n }\n\n // The following for-loop measures all qubits and resets them to the |0〉\n // state so that they can be safely deallocated at the end of the block.\n // The loop also sets `result` to `true` if all measurement results are\n // `Zero`, i.e. if the function is a constant function, and sets\n // `result` to `false` if not, which according to the assumption on 𝑓\n // means that it must be balanced.\n mutable result = true;\n for q in queryRegister {\n if MResetZ(q) == One {\n set result = false;\n }\n }\n\n // Finally, the last qubit, which held the 𝑦-register, is reset.\n Reset(target);\n return result;\n}\n\n// Simple constant Boolean function\noperation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n}\n\n// Simple balanced Boolean function\noperation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n}\n\n// A more complex constant Boolean function.\n// It applies X to every input basis vector.\noperation ConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n for i in 0..(2^Length(args)) - 1 {\n ApplyControlledOnInt(i, X, args, target);\n }\n}\n\n// A more complex balanced Boolean function.\n// It applies X to half of the input basis vectors.\noperation BalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n for i in 0..2..(2^Length(args)) - 1 {\n ApplyControlledOnInt(i, X, args, target);\n }\n}\n"
50
+ "code": "/// # Sample\n/// Deutsch–Jozsa Algorithm\n///\n/// # Description\n/// Deutsch–Jozsa is a quantum algorithm that determines whether a given Boolean\n/// function 𝑓 is constant (0 on all inputs or 1 on all inputs) or balanced\n/// (1 for exactly half of the input domain and 0 for the other half).\n///\n/// This Q# program implements the Deutsch–Jozsa algorithm.\nimport Std.Diagnostics.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\n\noperation Main() : (String, Bool)[] {\n // A Boolean function is a function that maps bitstrings to a bit:\n // 𝑓 : {0, 1}^n → {0, 1}.\n\n // We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings 𝑥⃗ and\n // 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true for exactly half of\n // its inputs.\n\n // If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉 =\n // |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or is\n // balanced, then the Deutsch–Jozsa algorithm decides between these\n // cases with a single application of 𝑈.\n\n // Here, we demonstrate the use of the Deutsch-Jozsa algorithm by\n // determining the type (constant or balanced) of various functions.\n let nameFunctionTypeTuples = [\n (\"SimpleConstantBoolF\", SimpleConstantBoolF, true),\n (\"SimpleBalancedBoolF\", SimpleBalancedBoolF, false),\n (\"ConstantBoolF\", ConstantBoolF, true),\n (\"BalancedBoolF\", BalancedBoolF, false)\n ];\n\n mutable results = [];\n for (name, fn, shouldBeConstant) in nameFunctionTypeTuples {\n let isConstant = DeutschJozsa(fn, 5);\n if (isConstant != shouldBeConstant) {\n let shouldBeConstantStr = shouldBeConstant ? \"constant\" | \"balanced\";\n fail $\"{name} should be detected as {shouldBeConstantStr}\";\n }\n\n let isConstantStr = isConstant ? \"constant\" | \"balanced\";\n Message($\"{name} is {isConstantStr}\");\n set results += [(name, isConstant)];\n }\n\n return results;\n}\n\n/// # Summary\n/// This operation implements the DeutschJozsa algorithm.\n/// It returns the Boolean value `true` if the function is constant and\n/// `false` if it is not.\n/// It is assumed that the function is either constant or balanced.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, where 𝑓 is a\n/// Boolean function, 𝑥 is an 𝑛 bit register and 𝑦 is a single qubit.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// A boolean value `true` that indicates that the function is constant and\n/// `false` that indicates that the function is balanced.\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Michael A. Nielsen , Isaac L. Chuang*,\n/// Quantum Computation and Quantum Information ]\n/// (http://doi.org/10.1017/CBO9780511976667)\noperation DeutschJozsa(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Bool {\n // We allocate n + 1 clean qubits. Note that the function `Uf` is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n // Now, a Hadamard transform is applied to each of the qubits.\n H(target);\n // We use a within-apply block to ensure that the Hadamard transform is\n // correctly inverted on the |𝑥〉 register.\n within {\n for q in queryRegister {\n H(q);\n }\n } apply {\n // We apply Uf to the n+1 qubits, computing |𝑥, 𝑦〉 ↦ |𝑥, 𝑦 ⊕ 𝑓(𝑥)〉.\n Uf(queryRegister, target);\n }\n\n // The following for-loop measures all qubits and resets them to the |0〉\n // state so that they can be safely deallocated at the end of the block.\n // The loop also sets `result` to `true` if all measurement results are\n // `Zero`, i.e. if the function is a constant function, and sets\n // `result` to `false` if not, which according to the assumption on 𝑓\n // means that it must be balanced.\n mutable result = true;\n for q in queryRegister {\n if MResetZ(q) == One {\n set result = false;\n }\n }\n\n // Finally, the last qubit, which held the 𝑦-register, is reset.\n Reset(target);\n return result;\n}\n\n// Simple constant Boolean function\noperation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n}\n\n// Simple balanced Boolean function\noperation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n}\n\n// A more complex constant Boolean function.\n// It applies X to every input basis vector.\noperation ConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n for i in 0..(2^Length(args)) - 1 {\n ApplyControlledOnInt(i, X, args, target);\n }\n}\n\n// A more complex balanced Boolean function.\n// It applies X to half of the input basis vectors.\noperation BalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n for i in 0..2..(2^Length(args)) - 1 {\n ApplyControlledOnInt(i, X, args, target);\n }\n}\n"
51
51
  },
52
52
  {
53
- "title": "BernsteinVazirani",
53
+ "title": "Bernstein-Vazirani",
54
54
  "shots": 1,
55
- "code": "/// # Sample\n/// Bernstein-Vazirani algorithm\n///\n/// # Description\n/// The Bernstein-Vazirani algorithm determines the value of a bit string\n/// encoded in a function.\n///\n/// This Q# program implements the Bernstein-Vazirani algorithm.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\n\noperation Main() : Result[] {\n // Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the form\n // 𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ\n // where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bit string that determines the\n // parity of 𝑓.\n\n // The Bernstein–Vazirani algorithm allows determining 𝑟 given a\n // quantum operation that implements\n // |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n\n // This entry point function of this program, `Main`, shows how to use\n // the `BernsteinVazirani` operation to determine the value of bitstring\n // 𝑟.\n let secretBitString = SecretBitStringAsBoolArray();\n let parityOperation = EncodeBitStringAsParityOperation(secretBitString);\n let decodedBitString = BernsteinVazirani(\n parityOperation,\n Length(secretBitString)\n );\n\n return decodedBitString;\n}\n\n/// # Summary\n/// This operation implements the Bernstein-Vazirani quantum algorithm.\n/// This algorithm computes for a given Boolean function that is promised to\n/// be a parity 𝑓(𝑥₀, …, 𝑥ₙ₋₁) = Σᵢ 𝑟ᵢ 𝑥ᵢ a result in the form of a bit\n/// vector (𝑟₀, …, 𝑟ₙ₋₁) corresponding to the parity function.\n/// Note that it is promised that the function is actually a parity\n/// function.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉,\n/// where 𝑓 is a Boolean function that implements a parity Σᵢ 𝑟ᵢ 𝑥ᵢ.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` that contains the parity 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁).\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Ethan Bernstein and Umesh Vazirani*,\n/// SIAM J. Comput., 26(5), 1411–1473, 1997 ]\n/// (https://doi.org/10.1137/S0097539796300921)\noperation BernsteinVazirani(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Result[] {\n // We allocate n + 1 clean qubits. Note that the function parameter Uf is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that a relative phase is\n // introduced when we apply a Hadamard gate later on and we can use\n // phase kickback when Uf is applied.\n X(target);\n\n within {\n // Now, a Hadamard transform is applied to each of the qubits. As\n // the last step before the measurement, a Hadamard transform is\n // applied to all qubits except the last one. We could also\n // transform the last qubit, but this would not affect the\n // final outcome.\n // We use a within-apply block to ensure that the Hadamard transform\n // is correctly inverted.\n ApplyToEachA(H, queryRegister);\n } apply {\n H(target);\n // We now apply Uf to the n+1 qubits, computing\n // |x, y〉 ↦ |x, y ⊕ f(x)〉.\n Uf(queryRegister, target);\n }\n\n // Measure all qubits and reset them to the |0〉 state so that they can\n // be safely deallocated at the end of the block.\n let resultArray = MResetEachZ(queryRegister);\n\n // Finally, the last qubit, which held the y-register, is reset.\n Reset(target);\n\n // The result is already contained in resultArray so no further\n // post-processing is necessary.\n return resultArray;\n}\n\n/// # Summary\n/// Given bit string 𝑟⃗ = (r₀, …, rₙ₋₁), represented as an array of Booleans,\n/// this operation applies a unitary 𝑈 that acts on 𝑛 + 1 qubits as:\n/// 𝑈 |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉\n/// where 𝑓(𝑥) = Σᵢ 𝑥ᵢ 𝑟ᵢ mod 2.\n///\n/// # Input\n/// ## bitStringAsBoolArray\n/// A bit string 𝑟⃗, represented as an array of Booleans, used to define the\n/// function 𝑓.\n/// ## xRegister\n/// Represents the |𝑥〉 register that 𝑈 acts on.\n/// ## yQubit\n/// Represents the |𝑦〉 qubit that 𝑈 acts on.\noperation ApplyParityOperation(\n bitStringAsBoolArray : Bool[],\n xRegister : Qubit[],\n yQubit : Qubit\n) : Unit {\n // `xRegister` muts have enough qubits to represent the integer.\n let requiredBits = Length(bitStringAsBoolArray);\n let availableQubits = Length(xRegister);\n Fact(\n availableQubits >= requiredBits,\n $\"The bitstring has {requiredBits} bits but the quantum register \" + $\"only has {availableQubits} qubits\"\n );\n\n // Apply the quantum operations that encode the bit string.\n for (index, bit) in Enumerated(bitStringAsBoolArray) {\n if bit {\n CNOT(xRegister[index], yQubit);\n }\n }\n}\n\n/// # Summary\n/// This is a higher-order operation which returns an operation (Qubit[], Qubit) => () of the form\n/// U_f |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n/// We define 𝑓 by providing the bit string 𝑟⃗ as an integer.\nfunction EncodeBitStringAsParityOperation(bitStringAsBoolArray : Bool[]) : (Qubit[], Qubit) => Unit {\n return ApplyParityOperation(bitStringAsBoolArray, _, _);\n}\n\n/// # Summary\n/// Returns a particular bit string as an array of Booleans.\nfunction SecretBitStringAsBoolArray() : Bool[] {\n return [true, false, true, false, true];\n}\n"
55
+ "code": "/// # Sample\n/// Bernstein-Vazirani Algorithm\n///\n/// # Description\n/// The Bernstein-Vazirani algorithm determines the value of a bit string\n/// encoded in a function.\n///\n/// This Q# program implements the Bernstein-Vazirani algorithm.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\n\noperation Main() : Result[] {\n // Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the form\n // 𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ\n // where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bit string that determines the\n // parity of 𝑓.\n\n // The Bernstein–Vazirani algorithm allows determining 𝑟 given a\n // quantum operation that implements\n // |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n\n // This entry point function of this program, `Main`, shows how to use\n // the `BernsteinVazirani` operation to determine the value of bitstring\n // 𝑟.\n let secretBitString = SecretBitStringAsBoolArray();\n let parityOperation = EncodeBitStringAsParityOperation(secretBitString);\n let decodedBitString = BernsteinVazirani(\n parityOperation,\n Length(secretBitString)\n );\n\n return decodedBitString;\n}\n\n/// # Summary\n/// This operation implements the Bernstein-Vazirani quantum algorithm.\n/// This algorithm computes for a given Boolean function that is promised to\n/// be a parity 𝑓(𝑥₀, …, 𝑥ₙ₋₁) = Σᵢ 𝑟ᵢ 𝑥ᵢ a result in the form of a bit\n/// vector (𝑟₀, …, 𝑟ₙ₋₁) corresponding to the parity function.\n/// Note that it is promised that the function is actually a parity\n/// function.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉,\n/// where 𝑓 is a Boolean function that implements a parity Σᵢ 𝑟ᵢ 𝑥ᵢ.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` that contains the parity 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁).\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Ethan Bernstein and Umesh Vazirani*,\n/// SIAM J. Comput., 26(5), 1411–1473, 1997 ]\n/// (https://doi.org/10.1137/S0097539796300921)\noperation BernsteinVazirani(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Result[] {\n // We allocate n + 1 clean qubits. Note that the function parameter Uf is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that a relative phase is\n // introduced when we apply a Hadamard gate later on and we can use\n // phase kickback when Uf is applied.\n X(target);\n\n within {\n // Now, a Hadamard transform is applied to each of the qubits. As\n // the last step before the measurement, a Hadamard transform is\n // applied to all qubits except the last one. We could also\n // transform the last qubit, but this would not affect the\n // final outcome.\n // We use a within-apply block to ensure that the Hadamard transform\n // is correctly inverted.\n ApplyToEachA(H, queryRegister);\n } apply {\n H(target);\n // We now apply Uf to the n+1 qubits, computing\n // |x, y〉 ↦ |x, y ⊕ f(x)〉.\n Uf(queryRegister, target);\n }\n\n // Measure all qubits and reset them to the |0〉 state so that they can\n // be safely deallocated at the end of the block.\n let resultArray = MResetEachZ(queryRegister);\n\n // Finally, the last qubit, which held the y-register, is reset.\n Reset(target);\n\n // The result is already contained in resultArray so no further\n // post-processing is necessary.\n return resultArray;\n}\n\n/// # Summary\n/// Given bit string 𝑟⃗ = (r₀, …, rₙ₋₁), represented as an array of Booleans,\n/// this operation applies a unitary 𝑈 that acts on 𝑛 + 1 qubits as:\n/// 𝑈 |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉\n/// where 𝑓(𝑥) = Σᵢ 𝑥ᵢ 𝑟ᵢ mod 2.\n///\n/// # Input\n/// ## bitStringAsBoolArray\n/// A bit string 𝑟⃗, represented as an array of Booleans, used to define the\n/// function 𝑓.\n/// ## xRegister\n/// Represents the |𝑥〉 register that 𝑈 acts on.\n/// ## yQubit\n/// Represents the |𝑦〉 qubit that 𝑈 acts on.\noperation ApplyParityOperation(\n bitStringAsBoolArray : Bool[],\n xRegister : Qubit[],\n yQubit : Qubit\n) : Unit {\n // `xRegister` muts have enough qubits to represent the integer.\n let requiredBits = Length(bitStringAsBoolArray);\n let availableQubits = Length(xRegister);\n Fact(\n availableQubits >= requiredBits,\n $\"The bitstring has {requiredBits} bits but the quantum register \" + $\"only has {availableQubits} qubits\"\n );\n\n // Apply the quantum operations that encode the bit string.\n for (index, bit) in Enumerated(bitStringAsBoolArray) {\n if bit {\n CNOT(xRegister[index], yQubit);\n }\n }\n}\n\n/// # Summary\n/// This is a higher-order operation which returns an operation (Qubit[], Qubit) => () of the form\n/// U_f |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n/// We define 𝑓 by providing the bit string 𝑟⃗ as an integer.\nfunction EncodeBitStringAsParityOperation(bitStringAsBoolArray : Bool[]) : (Qubit[], Qubit) => Unit {\n return ApplyParityOperation(bitStringAsBoolArray, _, _);\n}\n\n/// # Summary\n/// Returns a particular bit string as an array of Booleans.\nfunction SecretBitStringAsBoolArray() : Bool[] {\n return [true, false, true, false, true];\n}\n"
56
56
  },
57
57
  {
58
- "title": "BernsteinVazirani (Advanced)",
58
+ "title": "Bernstein-Vazirani (Advanced)",
59
59
  "shots": 1,
60
- "code": "/// # Sample\n/// Bernstein-Vazirani algorithm\n///\n/// # Description\n/// The Bernstein-Vazirani algorithm determines the value of a bit string\n/// encoded in a function.\n///\n/// This Q# program implements the Bernstein-Vazirani algorithm.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\n\noperation Main() : Int[] {\n // Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the form\n // 𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ\n // where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bitstring that determines the\n // parity of 𝑓.\n\n // The Bernstein–Vazirani algorithm allows determining 𝑟 given a\n // quantum operation that implements\n // |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n\n // The entry point function of this program, `Main`, shows how to use\n // the `BernsteinVazirani` operation to determine the value of various\n // integers whose bits describe 𝑟.\n let nQubits = 10;\n\n // Use the Bernstein–Vazirani algorithm to determine the bit strings\n // that various integers represent.\n let integers = [127, 238, 512];\n mutable decodedIntegers = [];\n for integer in integers {\n // Create an operation that encodes a bit string represented by an\n // integer as a parity operation.\n let parityOperation = EncodeIntegerAsParityOperation(integer);\n\n // Use the parity operation as input to the Bernstein-Vazirani\n // algorithm to determine the bit string.\n let decodedBitString = BernsteinVazirani(parityOperation, nQubits);\n let decodedInteger = ResultArrayAsInt(decodedBitString);\n Fact(\n decodedInteger == integer,\n $\"Decoded integer {decodedInteger}, but expected {integer}.\"\n );\n\n Message($\"Successfully decoded bit string as int: {decodedInteger}\");\n set decodedIntegers += [decodedInteger];\n }\n\n return decodedIntegers;\n}\n\n/// # Summary\n/// This operation implements the Bernstein-Vazirani quantum algorithm.\n/// This algorithm computes for a given Boolean function that is promised to\n/// be a parity 𝑓(𝑥₀, …, 𝑥ₙ₋₁) = Σᵢ 𝑟ᵢ 𝑥ᵢ a result in the form of a bit\n/// vector (𝑟₀, …, 𝑟ₙ₋₁) corresponding to the parity function.\n/// Note that it is promised that the function is actually a parity\n/// function.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉,\n/// where 𝑓 is a Boolean function that implements a parity Σᵢ 𝑟ᵢ 𝑥ᵢ.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` that contains the parity 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁).\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Ethan Bernstein and Umesh Vazirani*,\n/// SIAM J. Comput., 26(5), 1411–1473, 1997 ]\n/// (https://doi.org/10.1137/S0097539796300921)\noperation BernsteinVazirani(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Result[] {\n // We allocate n + 1 clean qubits. Note that the function Uf is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n within {\n // Now, a Hadamard transform is applied to each of the qubits. As\n // the last step before the measurement, a Hadamard transform is\n // applied to all qubits except last one. We could apply the\n // transform to the last qubit also, but this would not affect the\n // final outcome.\n // We use a within-apply block to ensure that the Hadamard transform\n // is correctly inverted.\n ApplyToEachA(H, queryRegister);\n } apply {\n H(target);\n // We now apply Uf to the n+1 qubits, computing\n // |x, y〉 ↦ |x, y ⊕ f(x)〉.\n Uf(queryRegister, target);\n }\n\n // Measure all qubits and reset them to the |0〉 state so that they can\n // be safely deallocated at the end of the block.\n let resultArray = MResetEachZ(queryRegister);\n\n // Finally, the last qubit, which held the y-register, is reset.\n Reset(target);\n\n // The result is already contained in resultArray so no further\n // post-processing is necessary.\n return resultArray;\n}\n\n/// # Summary\n/// Given an integer that can be represented as a bit string\n/// 𝑟⃗ = (r₀, …, rₙ₋₁), this operation applies a unitary 𝑈 that acts on 𝑛 + 1\n/// qubits as:\n/// 𝑈 |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉\n/// where 𝑓(𝑥) = Σᵢ 𝑥ᵢ 𝑟ᵢ mod 2.\n///\n/// # Input\n/// ## bitStringAsInt\n/// An integer that can be represented as a bit string 𝑟⃗ used to define the\n/// function 𝑓.\n/// ## xRegister\n/// Represents the |𝑥〉 register that 𝑈 acts on.\n/// ## yQubit\n/// Represents the |𝑦〉 qubit that 𝑈 acts on.\noperation ApplyParityOperation(\n bitStringAsInt : Int,\n xRegister : Qubit[],\n yQubit : Qubit\n) : Unit {\n // `xRegister` muts have enough qubits to represent the integer.\n let requiredBits = BitSizeI(bitStringAsInt);\n let availableQubits = Length(xRegister);\n Fact(\n availableQubits >= requiredBits,\n $\"Integer value {bitStringAsInt} requires {requiredBits} bits to be represented but the quantum register only has {availableQubits} qubits\"\n );\n\n // Apply the quantum operations that encode the bit string.\n for index in IndexRange(xRegister) {\n if ((bitStringAsInt &&& 2^index) != 0) {\n CNOT(xRegister[index], yQubit);\n }\n }\n}\n\n/// # Summary\n/// Returns black-box operations (Qubit[], Qubit) => () of the form\n/// U_f |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n/// We define 𝑓 by providing the bit string 𝑟⃗ as an integer.\nfunction EncodeIntegerAsParityOperation(bitStringAsInt : Int) : (Qubit[], Qubit) => Unit {\n return ApplyParityOperation(bitStringAsInt, _, _);\n}\n"
60
+ "code": "/// # Sample\n/// Bernstein-Vazirani Algorithm\n///\n/// # Description\n/// The Bernstein-Vazirani algorithm determines the value of a bit string\n/// encoded in a function.\n///\n/// This Q# program implements the Bernstein-Vazirani algorithm.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\n\noperation Main() : Int[] {\n // Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the form\n // 𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ\n // where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bitstring that determines the\n // parity of 𝑓.\n\n // The Bernstein–Vazirani algorithm allows determining 𝑟 given a\n // quantum operation that implements\n // |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n\n // The entry point function of this program, `Main`, shows how to use\n // the `BernsteinVazirani` operation to determine the value of various\n // integers whose bits describe 𝑟.\n let nQubits = 10;\n\n // Use the Bernstein–Vazirani algorithm to determine the bit strings\n // that various integers represent.\n let integers = [127, 238, 512];\n mutable decodedIntegers = [];\n for integer in integers {\n // Create an operation that encodes a bit string represented by an\n // integer as a parity operation.\n let parityOperation = EncodeIntegerAsParityOperation(integer);\n\n // Use the parity operation as input to the Bernstein-Vazirani\n // algorithm to determine the bit string.\n let decodedBitString = BernsteinVazirani(parityOperation, nQubits);\n let decodedInteger = ResultArrayAsInt(decodedBitString);\n Fact(\n decodedInteger == integer,\n $\"Decoded integer {decodedInteger}, but expected {integer}.\"\n );\n\n Message($\"Successfully decoded bit string as int: {decodedInteger}\");\n set decodedIntegers += [decodedInteger];\n }\n\n return decodedIntegers;\n}\n\n/// # Summary\n/// This operation implements the Bernstein-Vazirani quantum algorithm.\n/// This algorithm computes for a given Boolean function that is promised to\n/// be a parity 𝑓(𝑥₀, …, 𝑥ₙ₋₁) = Σᵢ 𝑟ᵢ 𝑥ᵢ a result in the form of a bit\n/// vector (𝑟₀, …, 𝑟ₙ₋₁) corresponding to the parity function.\n/// Note that it is promised that the function is actually a parity\n/// function.\n///\n/// # Input\n/// ## Uf\n/// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉,\n/// where 𝑓 is a Boolean function that implements a parity Σᵢ 𝑟ᵢ 𝑥ᵢ.\n/// ## n\n/// The number of bits in the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` that contains the parity 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁).\n///\n/// # See Also\n/// - For details see Section 1.4.3 of Nielsen & Chuang.\n///\n/// # References\n/// - [ *Ethan Bernstein and Umesh Vazirani*,\n/// SIAM J. Comput., 26(5), 1411–1473, 1997 ]\n/// (https://doi.org/10.1137/S0097539796300921)\noperation BernsteinVazirani(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Result[] {\n // We allocate n + 1 clean qubits. Note that the function Uf is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n within {\n // Now, a Hadamard transform is applied to each of the qubits. As\n // the last step before the measurement, a Hadamard transform is\n // applied to all qubits except last one. We could apply the\n // transform to the last qubit also, but this would not affect the\n // final outcome.\n // We use a within-apply block to ensure that the Hadamard transform\n // is correctly inverted.\n ApplyToEachA(H, queryRegister);\n } apply {\n H(target);\n // We now apply Uf to the n+1 qubits, computing\n // |x, y〉 ↦ |x, y ⊕ f(x)〉.\n Uf(queryRegister, target);\n }\n\n // Measure all qubits and reset them to the |0〉 state so that they can\n // be safely deallocated at the end of the block.\n let resultArray = MResetEachZ(queryRegister);\n\n // Finally, the last qubit, which held the y-register, is reset.\n Reset(target);\n\n // The result is already contained in resultArray so no further\n // post-processing is necessary.\n return resultArray;\n}\n\n/// # Summary\n/// Given an integer that can be represented as a bit string\n/// 𝑟⃗ = (r₀, …, rₙ₋₁), this operation applies a unitary 𝑈 that acts on 𝑛 + 1\n/// qubits as:\n/// 𝑈 |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉\n/// where 𝑓(𝑥) = Σᵢ 𝑥ᵢ 𝑟ᵢ mod 2.\n///\n/// # Input\n/// ## bitStringAsInt\n/// An integer that can be represented as a bit string 𝑟⃗ used to define the\n/// function 𝑓.\n/// ## xRegister\n/// Represents the |𝑥〉 register that 𝑈 acts on.\n/// ## yQubit\n/// Represents the |𝑦〉 qubit that 𝑈 acts on.\noperation ApplyParityOperation(\n bitStringAsInt : Int,\n xRegister : Qubit[],\n yQubit : Qubit\n) : Unit {\n // `xRegister` muts have enough qubits to represent the integer.\n let requiredBits = BitSizeI(bitStringAsInt);\n let availableQubits = Length(xRegister);\n Fact(\n availableQubits >= requiredBits,\n $\"Integer value {bitStringAsInt} requires {requiredBits} bits to be represented but the quantum register only has {availableQubits} qubits\"\n );\n\n // Apply the quantum operations that encode the bit string.\n for index in IndexRange(xRegister) {\n if ((bitStringAsInt &&& 2^index) != 0) {\n CNOT(xRegister[index], yQubit);\n }\n }\n}\n\n/// # Summary\n/// Returns black-box operations (Qubit[], Qubit) => () of the form\n/// U_f |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n/// We define 𝑓 by providing the bit string 𝑟⃗ as an integer.\nfunction EncodeIntegerAsParityOperation(bitStringAsInt : Int) : (Qubit[], Qubit) => Unit {\n return ApplyParityOperation(bitStringAsInt, _, _);\n}\n"
61
61
  },
62
62
  {
63
- "title": "Grover's search",
63
+ "title": "Grover's Search",
64
64
  "shots": 100,
65
- "code": "/// # Sample\n/// Grover's search algorithm\n///\n/// # Description\n/// Grover's search algorithm is a quantum algorithm that finds with high\n/// probability the unique input to a black box function that produces a\n/// particular output value.\n///\n/// This Q# program implements the Grover's search algorithm.\nimport Std.Convert.*;\nimport Std.Math.*;\nimport Std.Arrays.*;\nimport Std.Measurement.*;\nimport Std.Diagnostics.*;\n\noperation Main() : Result[] {\n let nQubits = 5;\n\n // Grover's algorithm relies on performing a \"Grover iteration\" an\n // optimal number of times to maximize the probability of finding the\n // value we are searching for.\n // You can set the number iterations to a value lower than optimal to\n // intentionally reduce precision.\n let iterations = CalculateOptimalIterations(nQubits);\n Message($\"Number of iterations: {iterations}\");\n\n // Use Grover's algorithm to find a particular marked state.\n let results = GroverSearch(nQubits, iterations, ReflectAboutMarked);\n return results;\n}\n\n/// # Summary\n/// Implements Grover's algorithm, which searches all possible inputs to an\n/// operation to find a particular marked state.\noperation GroverSearch(\n nQubits : Int,\n iterations : Int,\n phaseOracle : Qubit[] => Unit\n) : Result[] {\n\n use qubits = Qubit[nQubits];\n\n // Initialize a uniform superposition over all possible inputs.\n PrepareUniform(qubits);\n\n // The search itself consists of repeatedly reflecting about the marked\n // state and our start state, which we can write out in Q# as a for loop.\n for _ in 1..iterations {\n phaseOracle(qubits);\n ReflectAboutUniform(qubits);\n }\n\n // Measure and return the answer.\n return MResetEachZ(qubits);\n}\n\n/// # Summary\n/// Returns the optimal number of Grover iterations needed to find a marked\n/// item, given the number of qubits in a register.\nfunction CalculateOptimalIterations(nQubits : Int) : Int {\n if nQubits > 126 {\n fail \"This sample supports at most 126 qubits.\";\n }\n\n let nItems = 2.0^IntAsDouble(nQubits);\n let angle = ArcSin(1. / Sqrt(nItems));\n let iterations = Round(0.25 * PI() / angle - 0.5);\n iterations\n}\n\n/// # Summary\n/// Reflects about the basis state marked by alternating zeros and ones.\n/// This operation defines what input we are trying to find in the search.\noperation ReflectAboutMarked(inputQubits : Qubit[]) : Unit {\n Message(\"Reflecting about marked state...\");\n use outputQubit = Qubit();\n within {\n // We initialize the outputQubit to (|0⟩ - |1⟩) / √2, so that\n // toggling it results in a (-1) phase.\n X(outputQubit);\n H(outputQubit);\n // Flip the outputQubit for marked states.\n // Here, we get the state with alternating 0s and 1s by using the X\n // operation on every other qubit.\n for q in inputQubits[...2...] {\n X(q);\n }\n } apply {\n Controlled X(inputQubits, outputQubit);\n }\n}\n\n/// # Summary\n/// Given a register in the all-zeros state, prepares a uniform\n/// superposition over all basis states.\noperation PrepareUniform(inputQubits : Qubit[]) : Unit is Adj + Ctl {\n for q in inputQubits {\n H(q);\n }\n}\n\n/// # Summary\n/// Reflects about the all-ones state.\noperation ReflectAboutAllOnes(inputQubits : Qubit[]) : Unit {\n Controlled Z(Most(inputQubits), Tail(inputQubits));\n}\n\n/// # Summary\n/// Reflects about the uniform superposition state.\noperation ReflectAboutUniform(inputQubits : Qubit[]) : Unit {\n within {\n // Transform the uniform superposition to all-zero.\n Adjoint PrepareUniform(inputQubits);\n // Transform the all-zero state to all-ones\n for q in inputQubits {\n X(q);\n }\n } apply {\n // Now that we've transformed the uniform superposition to the\n // all-ones state, reflect about the all-ones state, then let the\n // within/apply block transform us back.\n ReflectAboutAllOnes(inputQubits);\n }\n}\n"
65
+ "code": "/// # Sample\n/// Grover's Search Algorithm\n///\n/// # Description\n/// Grover's search algorithm is a quantum algorithm that finds with high\n/// probability the unique input to a black box function that produces a\n/// particular output value.\n///\n/// This Q# program implements the Grover's search algorithm.\nimport Std.Convert.*;\nimport Std.Math.*;\nimport Std.Arrays.*;\nimport Std.Measurement.*;\nimport Std.Diagnostics.*;\n\noperation Main() : Result[] {\n let nQubits = 5;\n\n // Grover's algorithm relies on performing a \"Grover iteration\" an\n // optimal number of times to maximize the probability of finding the\n // value we are searching for.\n // You can set the number iterations to a value lower than optimal to\n // intentionally reduce precision.\n let iterations = CalculateOptimalIterations(nQubits);\n Message($\"Number of iterations: {iterations}\");\n\n // Use Grover's algorithm to find a particular marked state.\n let results = GroverSearch(nQubits, iterations, ReflectAboutMarked);\n return results;\n}\n\n/// # Summary\n/// Implements Grover's algorithm, which searches all possible inputs to an\n/// operation to find a particular marked state.\noperation GroverSearch(\n nQubits : Int,\n iterations : Int,\n phaseOracle : Qubit[] => Unit\n) : Result[] {\n\n use qubits = Qubit[nQubits];\n\n // Initialize a uniform superposition over all possible inputs.\n PrepareUniform(qubits);\n\n // The search itself consists of repeatedly reflecting about the marked\n // state and our start state, which we can write out in Q# as a for loop.\n for _ in 1..iterations {\n phaseOracle(qubits);\n ReflectAboutUniform(qubits);\n }\n\n // Measure and return the answer.\n return MResetEachZ(qubits);\n}\n\n/// # Summary\n/// Returns the optimal number of Grover iterations needed to find a marked\n/// item, given the number of qubits in a register.\nfunction CalculateOptimalIterations(nQubits : Int) : Int {\n if nQubits > 126 {\n fail \"This sample supports at most 126 qubits.\";\n }\n\n let nItems = 2.0^IntAsDouble(nQubits);\n let angle = ArcSin(1. / Sqrt(nItems));\n let iterations = Round(0.25 * PI() / angle - 0.5);\n iterations\n}\n\n/// # Summary\n/// Reflects about the basis state marked by alternating zeros and ones.\n/// This operation defines what input we are trying to find in the search.\noperation ReflectAboutMarked(inputQubits : Qubit[]) : Unit {\n Message(\"Reflecting about marked state...\");\n use outputQubit = Qubit();\n within {\n // We initialize the outputQubit to (|0⟩ - |1⟩) / √2, so that\n // toggling it results in a (-1) phase.\n X(outputQubit);\n H(outputQubit);\n // Flip the outputQubit for marked states.\n // Here, we get the state with alternating 0s and 1s by using the X\n // operation on every other qubit.\n for q in inputQubits[...2...] {\n X(q);\n }\n } apply {\n Controlled X(inputQubits, outputQubit);\n }\n}\n\n/// # Summary\n/// Given a register in the all-zeros state, prepares a uniform\n/// superposition over all basis states.\noperation PrepareUniform(inputQubits : Qubit[]) : Unit is Adj + Ctl {\n for q in inputQubits {\n H(q);\n }\n}\n\n/// # Summary\n/// Reflects about the all-ones state.\noperation ReflectAboutAllOnes(inputQubits : Qubit[]) : Unit {\n Controlled Z(Most(inputQubits), Tail(inputQubits));\n}\n\n/// # Summary\n/// Reflects about the uniform superposition state.\noperation ReflectAboutUniform(inputQubits : Qubit[]) : Unit {\n within {\n // Transform the uniform superposition to all-zero.\n Adjoint PrepareUniform(inputQubits);\n // Transform the all-zero state to all-ones\n for q in inputQubits {\n X(q);\n }\n } apply {\n // Now that we've transformed the uniform superposition to the\n // all-ones state, reflect about the all-ones state, then let the\n // within/apply block transform us back.\n ReflectAboutAllOnes(inputQubits);\n }\n}\n"
66
66
  },
67
67
  {
68
68
  "title": "Hidden Shift",
69
69
  "shots": 1,
70
- "code": "/// # Sample\n/// Hidden shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Measurement.*;\n\noperation Main() : Result[] {\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift encoded in the following array of\n // Booleans.\n let shiftAsBoolArray = [true, false, false, false, false, true];\n let shiftAsInt = BoolArrayAsInt(shiftAsBoolArray);\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shiftAsInt, register),\n Length(shiftAsBoolArray)\n );\n\n return hiddenShiftBitString;\n}\n\n/// # Summary\n/// Implements a correlation-based algorithm to solve the hidden shift\n/// problem for bent functions.\n///\n/// # Description\n/// Implements a solution for the hidden shift problem, which is to identify\n/// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n/// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n///\n/// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n/// it is as far from linear as possible. In particular, bent functions have\n/// flat Fourier (Walsh–Hadamard) spectra.\n///\n/// In this case, the Roetteler algorithm (see References, below) uses\n/// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n/// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n///\n/// # Input\n/// ## Ufstar\n/// A quantum operation that implements\n/// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n/// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n/// ## Ug\n/// A quantum operation that implements\n/// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n/// where 𝑔 is a Boolean function that is shifted by unknown\n/// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n/// ## n\n/// The number of bits of the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` which encodes the bit representation\n/// of the hidden shift.\n///\n/// # References\n/// - [*Martin Roetteler*,\n/// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n/// (https://doi.org/10.1137/1.9781611973075.37)\noperation FindHiddenShift(\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n : Int\n) : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return MResetEachZ(qubits);\n}\n\n/// # Summary\n/// Implements an oracle for a bent function constructed from the inner\n/// product of Boolean functions.\n///\n/// # Description\n/// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n/// is computed into the phase, i.e., a diagonal operator that maps\n/// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n/// the x_i are binary. The IP function is defined as\n/// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n/// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n/// of length u. Notice that the function IP is a Boolean function on n = 2u\n/// bits. IP is a special case of bent function. These are functions for\n/// which the Walsh-Hadamard transform is perfectly flat (in absolute\n/// value).\n/// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n/// function defines a +1/-1 function, i.e., gives rise to another Boolean\n/// function, called the dual bent function. Moreover, for the case of the\n/// IP function it can be shown that IP is equal to its own dual bent\n/// function.\n///\n/// # Remarks\n/// Notice that a diagonal operator implementing IP between 2 variables y_0\n/// and z_0 is nothing but the AND function between those variables, i.e.,\n/// in phase encoding it is computed by a Controlled-Z gate.\n/// Extending this to an XOR of the AND of more variables, as required in\n/// the definition of the IP function can then be accomplished by applying\n/// several Controlled-Z gates between the respective inputs.\noperation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0..u - 1];\n let ys = register[u...];\n for index in 0..u - 1 {\n CZ(xs[index], ys[index]);\n }\n}\n\n/// # Summary\n/// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n///\n/// # Description\n/// For the hidden shift problem we need another function g which is related\n/// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n/// IP function by a given shift. Notice that the '+' operation here is the\n/// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n/// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n/// shifted version by applying a bit flip to the |x〉 register first, then\n/// applying the diagonal operation, and then undoing the bit flips to the\n/// |x〉 register. We use this principle to define shifted versions of the IP\n/// operation.\noperation ShiftedBentFunction(shift : Int, register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n}\n"
70
+ "code": "/// # Sample\n/// Hidden Shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Measurement.*;\n\noperation Main() : Result[] {\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift encoded in the following array of\n // Booleans.\n let shiftAsBoolArray = [true, false, false, false, false, true];\n let shiftAsInt = BoolArrayAsInt(shiftAsBoolArray);\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shiftAsInt, register),\n Length(shiftAsBoolArray)\n );\n\n return hiddenShiftBitString;\n}\n\n/// # Summary\n/// Implements a correlation-based algorithm to solve the hidden shift\n/// problem for bent functions.\n///\n/// # Description\n/// Implements a solution for the hidden shift problem, which is to identify\n/// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n/// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n///\n/// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n/// it is as far from linear as possible. In particular, bent functions have\n/// flat Fourier (Walsh–Hadamard) spectra.\n///\n/// In this case, the Roetteler algorithm (see References, below) uses\n/// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n/// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n///\n/// # Input\n/// ## Ufstar\n/// A quantum operation that implements\n/// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n/// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n/// ## Ug\n/// A quantum operation that implements\n/// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n/// where 𝑔 is a Boolean function that is shifted by unknown\n/// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n/// ## n\n/// The number of bits of the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` which encodes the bit representation\n/// of the hidden shift.\n///\n/// # References\n/// - [*Martin Roetteler*,\n/// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n/// (https://doi.org/10.1137/1.9781611973075.37)\noperation FindHiddenShift(\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n : Int\n) : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return MResetEachZ(qubits);\n}\n\n/// # Summary\n/// Implements an oracle for a bent function constructed from the inner\n/// product of Boolean functions.\n///\n/// # Description\n/// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n/// is computed into the phase, i.e., a diagonal operator that maps\n/// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n/// the x_i are binary. The IP function is defined as\n/// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n/// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n/// of length u. Notice that the function IP is a Boolean function on n = 2u\n/// bits. IP is a special case of bent function. These are functions for\n/// which the Walsh-Hadamard transform is perfectly flat (in absolute\n/// value).\n/// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n/// function defines a +1/-1 function, i.e., gives rise to another Boolean\n/// function, called the dual bent function. Moreover, for the case of the\n/// IP function it can be shown that IP is equal to its own dual bent\n/// function.\n///\n/// # Remarks\n/// Notice that a diagonal operator implementing IP between 2 variables y_0\n/// and z_0 is nothing but the AND function between those variables, i.e.,\n/// in phase encoding it is computed by a Controlled-Z gate.\n/// Extending this to an XOR of the AND of more variables, as required in\n/// the definition of the IP function can then be accomplished by applying\n/// several Controlled-Z gates between the respective inputs.\noperation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0..u - 1];\n let ys = register[u...];\n for index in 0..u - 1 {\n CZ(xs[index], ys[index]);\n }\n}\n\n/// # Summary\n/// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n///\n/// # Description\n/// For the hidden shift problem we need another function g which is related\n/// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n/// IP function by a given shift. Notice that the '+' operation here is the\n/// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n/// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n/// shifted version by applying a bit flip to the |x〉 register first, then\n/// applying the diagonal operation, and then undoing the bit flips to the\n/// |x〉 register. We use this principle to define shifted versions of the IP\n/// operation.\noperation ShiftedBentFunction(shift : Int, register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n}\n"
71
71
  },
72
72
  {
73
73
  "title": "Hidden Shift (Advanced)",
74
74
  "shots": 1,
75
- "code": "/// # Sample\n/// Hidden shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Measurement.*;\n\noperation Main() : Int[] {\n let nQubits = 10;\n\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift for various pairs of bent functions.\n let shifts = [170, 512, 999];\n mutable hiddenShifts = [];\n for shift in shifts {\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shift, register),\n nQubits\n );\n let hiddenShift = ResultArrayAsInt(hiddenShiftBitString);\n Message($\"Found {shift} successfully!\");\n set hiddenShifts += [hiddenShift];\n }\n\n // Note: returned array should match shifts array\n return hiddenShifts;\n}\n\n/// # Summary\n/// Implements a correlation-based algorithm to solve the hidden shift\n/// problem for bent functions.\n///\n/// # Description\n/// Implements a solution for the hidden shift problem, which is to identify\n/// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n/// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n///\n/// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n/// it is as far from linear as possible. In particular, bent functions have\n/// flat Fourier (Walsh–Hadamard) spectra.\n///\n/// In this case, the Roetteler algorithm (see References, below) uses\n/// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n/// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n///\n/// # Input\n/// ## Ufstar\n/// A quantum operation that implements\n/// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n/// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n/// ## Ug\n/// A quantum operation that implements\n/// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n/// where 𝑔 is a Boolean function that is shifted by unknown\n/// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n/// ## n\n/// The number of bits of the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` which encodes the bit representation\n/// of the hidden shift.\n///\n/// # References\n/// - [*Martin Roetteler*,\n/// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n/// (https://doi.org/10.1137/1.9781611973075.37)\noperation FindHiddenShift(\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n : Int\n) : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return MResetEachZ(qubits);\n}\n\n/// # Summary\n/// Implements an oracle for a bent function constructed from the inner\n/// product of Boolean functions.\n///\n/// # Description\n/// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n/// is computed into the phase, i.e., a diagonal operator that maps\n/// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n/// the x_i are binary. The IP function is defined as\n/// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n/// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n/// of length u. Notice that the function IP is a Boolean function on n = 2u\n/// bits. IP is a special case of bent function. These are functions for\n/// which the Walsh-Hadamard transform is perfectly flat (in absolute\n/// value).\n/// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n/// function defines a +1/-1 function, i.e., gives rise to another Boolean\n/// function, called the dual bent function. Moreover, for the case of the\n/// IP function it can be shown that IP is equal to its own dual bent\n/// function.\n///\n/// # Remarks\n/// Notice that a diagonal operator implementing IP between 2 variables y_0\n/// and z_0 is nothing but the AND function between those variables, i.e.,\n/// in phase encoding it is computed by a Controlled-Z gate.\n/// Extending this to an XOR of the AND of more variables, as required in\n/// the definition of the IP function can then be accomplished by applying\n/// several Controlled-Z gates between the respective inputs.\noperation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0..u - 1];\n let ys = register[u...];\n for index in 0..u - 1 {\n CZ(xs[index], ys[index]);\n }\n}\n\n/// # Summary\n/// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n///\n/// # Description\n/// For the hidden shift problem we need another function g which is related\n/// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n/// IP function by a given shift. Notice that the '+' operation here is the\n/// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n/// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n/// shifted version by applying a bit flip to the |x〉 register first, then\n/// applying the diagonal operation, and then undoing the bit flips to the\n/// |x〉 register. We use this principle to define shifted versions of the IP\n/// operation.\noperation ShiftedBentFunction(shift : Int, register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n}\n"
75
+ "code": "/// # Sample\n/// Hidden Shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nimport Std.Arrays.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Measurement.*;\n\noperation Main() : Int[] {\n let nQubits = 10;\n\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift for various pairs of bent functions.\n let shifts = [170, 512, 999];\n mutable hiddenShifts = [];\n for shift in shifts {\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shift, register),\n nQubits\n );\n let hiddenShift = ResultArrayAsInt(hiddenShiftBitString);\n Message($\"Found {shift} successfully!\");\n set hiddenShifts += [hiddenShift];\n }\n\n // Note: returned array should match shifts array\n return hiddenShifts;\n}\n\n/// # Summary\n/// Implements a correlation-based algorithm to solve the hidden shift\n/// problem for bent functions.\n///\n/// # Description\n/// Implements a solution for the hidden shift problem, which is to identify\n/// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n/// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n///\n/// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n/// it is as far from linear as possible. In particular, bent functions have\n/// flat Fourier (Walsh–Hadamard) spectra.\n///\n/// In this case, the Roetteler algorithm (see References, below) uses\n/// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n/// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n///\n/// # Input\n/// ## Ufstar\n/// A quantum operation that implements\n/// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n/// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n/// ## Ug\n/// A quantum operation that implements\n/// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n/// where 𝑔 is a Boolean function that is shifted by unknown\n/// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n/// ## n\n/// The number of bits of the input register |𝑥〉.\n///\n/// # Output\n/// An array of type `Result[]` which encodes the bit representation\n/// of the hidden shift.\n///\n/// # References\n/// - [*Martin Roetteler*,\n/// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n/// (https://doi.org/10.1137/1.9781611973075.37)\noperation FindHiddenShift(\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n : Int\n) : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return MResetEachZ(qubits);\n}\n\n/// # Summary\n/// Implements an oracle for a bent function constructed from the inner\n/// product of Boolean functions.\n///\n/// # Description\n/// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n/// is computed into the phase, i.e., a diagonal operator that maps\n/// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n/// the x_i are binary. The IP function is defined as\n/// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n/// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n/// of length u. Notice that the function IP is a Boolean function on n = 2u\n/// bits. IP is a special case of bent function. These are functions for\n/// which the Walsh-Hadamard transform is perfectly flat (in absolute\n/// value).\n/// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n/// function defines a +1/-1 function, i.e., gives rise to another Boolean\n/// function, called the dual bent function. Moreover, for the case of the\n/// IP function it can be shown that IP is equal to its own dual bent\n/// function.\n///\n/// # Remarks\n/// Notice that a diagonal operator implementing IP between 2 variables y_0\n/// and z_0 is nothing but the AND function between those variables, i.e.,\n/// in phase encoding it is computed by a Controlled-Z gate.\n/// Extending this to an XOR of the AND of more variables, as required in\n/// the definition of the IP function can then be accomplished by applying\n/// several Controlled-Z gates between the respective inputs.\noperation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0..u - 1];\n let ys = register[u...];\n for index in 0..u - 1 {\n CZ(xs[index], ys[index]);\n }\n}\n\n/// # Summary\n/// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n///\n/// # Description\n/// For the hidden shift problem we need another function g which is related\n/// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n/// IP function by a given shift. Notice that the '+' operation here is the\n/// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n/// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n/// shifted version by applying a bit flip to the |x〉 register first, then\n/// applying the diagonal operation, and then undoing the bit flips to the\n/// |x〉 register. We use this principle to define shifted versions of the IP\n/// operation.\noperation ShiftedBentFunction(shift : Int, register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n}\n"
76
76
  },
77
77
  {
78
78
  "title": "Shor",
79
79
  "shots": 1,
80
- "code": "/// # Sample\n/// Shor's algorithm\n///\n/// # Description\n/// Shor's algorithm is a quantum algorithm for finding the prime factors of an\n/// integer.\n///\n/// This Q# program implements Shor's algorithm.\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Random.*;\nimport Std.Math.*;\nimport Microsoft.Quantum.Unstable.Arithmetic.*;\nimport Std.Arrays.*;\n\noperation Main() : (Int, Int) {\n let n = 143; // 11*13;\n // You can try these other examples for a lengthier computation.\n // let n = 16837; // = 113*149\n // let n = 22499; // = 149*151\n\n // Use Shor's algorithm to factor a semiprime integer.\n let (a, b) = FactorSemiprimeInteger(n);\n Message($\"Found factorization {n} = {a} * {b}\");\n return (a, b);\n}\n\n/// # Summary\n/// Uses Shor's algorithm to factor an input number.\n///\n/// # Input\n/// ## number\n/// A semiprime integer to be factored.\n///\n/// # Output\n/// Pair of numbers p > 1 and q > 1 such that p⋅q = `number`\noperation FactorSemiprimeInteger(number : Int) : (Int, Int) {\n // First check the most trivial case (the provided number is even).\n if number % 2 == 0 {\n Message(\"An even number has been given; 2 is a factor.\");\n return (number / 2, 2);\n }\n // These mutables will keep track of whether we found the factors, and\n // if so, what they are. The default value for the factors is (1,1).\n mutable foundFactors = false;\n mutable factors = (1, 1);\n mutable attempt = 1;\n repeat {\n Message($\"*** Factorizing {number}, attempt {attempt}.\");\n // Try to guess a number co-prime to `number` by getting a random\n // integer in the interval [1, number-1]\n let generator = DrawRandomInt(1, number - 1);\n\n // Check if the random integer is indeed co-prime.\n // If true use Quantum algorithm for Period finding.\n if GreatestCommonDivisorI(generator, number) == 1 {\n Message($\"Estimating period of {generator}.\");\n\n // Call Quantum Period finding algorithm for\n // `generator` mod `number`.\n let period = EstimatePeriod(generator, number);\n\n // Set the flag and factors values if the continued\n // fractions classical algorithm succeeds.\n set (foundFactors, factors) = MaybeFactorsFromPeriod(number, generator, period);\n }\n // In this case, we guessed a divisor by accident.\n else {\n // Find divisor.\n let gcd = GreatestCommonDivisorI(number, generator);\n Message($\"We have guessed a divisor {gcd} by accident. \" + \"No quantum computation was done.\");\n\n // Set the flag `foundFactors` to true, indicating that we\n // succeeded in finding factors.\n set foundFactors = true;\n set factors = (gcd, number / gcd);\n }\n set attempt = attempt + 1;\n if (attempt > 100) {\n fail \"Failed to find factors: too many attempts!\";\n }\n } until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" + \"Trying again.\");\n }\n\n // Return the factorization\n return factors;\n}\n\n/// # Summary\n/// Tries to find the factors of `modulus` given a `period` and `generator`.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## period\n/// The estimated period (multiplicative order) of the generator mod\n/// `modulus`.\n///\n/// # Output\n/// A tuple of a flag indicating whether factors were found successfully,\n/// and a pair of integers representing the factors that were found.\n/// Note that the second output is only meaningful when the first output is\n/// `true`.\nfunction MaybeFactorsFromPeriod(\n modulus : Int,\n generator : Int,\n period : Int\n) : (Bool, (Int, Int)) {\n\n // Period finding reduces to factoring only if period is even\n if period % 2 == 0 {\n // Compute `generator` ^ `period/2` mod `number`.\n let halfPower = ExpModI(generator, period / 2, modulus);\n\n // If we are unlucky, halfPower is just -1 mod N, which is a trivial\n // case and not useful for factoring.\n if halfPower != modulus - 1 {\n // When the halfPower is not -1 mod N, halfPower-1 or\n // halfPower+1 share non-trivial divisor with `number`. Find it.\n let factor = MaxI(\n GreatestCommonDivisorI(halfPower - 1, modulus),\n GreatestCommonDivisorI(halfPower + 1, modulus)\n );\n\n // Add a flag that we found the factors, and return only if computed\n // non-trivial factors (not like 1:n or n:1)\n if (factor != 1) and (factor != modulus) {\n Message($\"Found factor={factor}\");\n return (true, (factor, modulus / factor));\n }\n }\n // Return a flag indicating we hit a trivial case and didn't get\n // any factors.\n Message($\"Found trivial factors.\");\n return (false, (1, 1));\n } else {\n // When period is odd we have to pick another generator to estimate\n // period of and start over.\n Message($\"Estimated period {period} was odd, trying again.\");\n return (false, (1, 1));\n }\n}\n\n/// # Summary\n/// Find the period of a number from an input frequency.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## frequencyEstimate\n/// The frequency that we want to convert to a period.\n/// ## bitsPrecision\n/// Number of bits of precision with which we need to estimate s/r to\n/// recover period r using continued fractions algorithm.\n/// ## currentDivisor\n/// The divisor of the generator period found so far.\n///\n/// # Output\n/// The period as calculated from the estimated frequency via the continued\n/// fractions algorithm.\nfunction PeriodFromFrequency(\n modulus : Int,\n frequencyEstimate : Int,\n bitsPrecision : Int,\n currentDivisor : Int\n) : Int {\n // Now we use the ContinuedFractionConvergentI function to recover s/r\n // from dyadic fraction k/2^bitsPrecision.\n let (numerator, period) = ContinuedFractionConvergentI(\n (frequencyEstimate, 2^bitsPrecision),\n modulus\n );\n\n // ContinuedFractionConvergentI does not guarantee the signs of the\n // numerator and denominator. Here we make sure that both are positive\n // using AbsI.\n let (numeratorAbs, periodAbs) = (AbsI(numerator), AbsI(period));\n\n // Compute and return the newly found divisor.\n let period = (periodAbs * currentDivisor) / GreatestCommonDivisorI(currentDivisor, periodAbs);\n Message($\"Found period={period}\");\n return period;\n}\n\n/// # Summary\n/// Finds a multiplicative order of the generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n///\n/// # Output\n/// The period (multiplicative order) of the generator mod `modulus`\noperation EstimatePeriod(generator : Int, modulus : Int) : Int {\n // Here we check that the inputs to the EstimatePeriod operation are\n // valid.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\"\n );\n\n // Number of bits in the modulus with respect to which we are estimating\n // the period.\n let bitsize = BitSizeI(modulus);\n\n // The EstimatePeriod operation estimates the period r by finding an\n // approximation k/2^(bits precision) to a fraction s/r, where s is some\n // integer. Note that if s and r have common divisors we will end up\n // recovering a divisor of r and not r itself.\n\n // Number of bits of precision with which we need to estimate s/r to\n // recover period r, using continued fractions algorithm.\n let bitsPrecision = 2 * bitsize + 1;\n\n // Current estimate for the frequency of the form s/r.\n let frequencyEstimate = EstimateFrequency(generator, modulus, bitsize);\n if frequencyEstimate != 0 {\n return PeriodFromFrequency(\n modulus,\n frequencyEstimate,\n bitsPrecision,\n 1\n );\n } else {\n Message(\"The estimated frequency was 0, trying again.\");\n return 1;\n }\n}\n\n/// # Summary\n/// Estimates the frequency of a generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## bitsize\n/// Number of bits needed to represent the modulus.\n///\n/// # Output\n/// The numerator k of dyadic fraction k/2^bitsPrecision approximating s/r.\noperation EstimateFrequency(generator : Int, modulus : Int, bitsize : Int) : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n Message($\"Estimating frequency with bitsPrecision={bitsPrecision}.\");\n\n // Allocate qubits for the superposition of eigenstates of the oracle\n // that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of the\n // eigenstates we are estimating the phases of.\n // We are interpreting the register as encoding an unsigned integer in\n // little-endian format.\n ApplyXorInPlace(1, eigenstateRegister);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision - 1..-1..0 {\n H(c);\n Controlled ApplyOrderFindingOracle(\n [c],\n (generator, modulus, 1 <<< idx, eigenstateRegister)\n );\n R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c);\n H(c);\n if M(c) == One {\n X(c); // Reset\n set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using ResetAll.\n ResetAll(eigenstateRegister);\n Message($\"Estimated frequency={frequencyEstimate}\");\n return frequencyEstimate;\n}\n\n/// # Summary\n/// Interprets `target` as encoding unsigned little-endian integer k\n/// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where\n/// p is `power`, g is `generator` and N is `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## power\n/// Power of `generator` by which `target` is multiplied.\n/// ## target\n/// Register interpreted as little-endian which is multiplied by\n/// given power of the generator. The multiplication is performed modulo\n/// `modulus`.\ninternal operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[]\n) : Unit is Adj + Ctl {\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We\n // also use `ExpModI` to compute a by which x must be multiplied. Also\n // note that we interpret target as unsigned integer in little-endian\n // format.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target\n );\n}\n\n/// # Summary\n/// Performs modular in-place multiplication by a classical constant.\n///\n/// # Description\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(c*x) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular multiplication\n/// ## c\n/// Constant by which to multiply |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs)\n );\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs)\n );\n }\n}\n\n/// # Summary\n/// Performs modular in-place addition of a classical constant into a\n/// quantum register.\n///\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(x+c) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular addition\n/// ## c\n/// Constant to add to |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant([control], (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled IncByI(ctrls, (c, y + [carry]));\n Controlled Adjoint IncByI(ctrls, (modulus, y + [carry]));\n Controlled IncByI([carry], (modulus, y));\n Controlled ApplyIfLessOrEqualL(ctrls, (X, IntAsBigInt(c), y, carry));\n }\n }\n}\n"
80
+ "code": "/// # Sample\n/// Shor's Algorithm\n///\n/// # Description\n/// Shor's algorithm is a quantum algorithm for finding the prime factors of an\n/// integer.\n///\n/// This Q# program implements Shor's algorithm.\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Random.*;\nimport Std.Math.*;\nimport Std.Arithmetic.*;\nimport Std.Arrays.*;\n\noperation Main() : (Int, Int) {\n let n = 143; // 11*13;\n // You can try these other examples for a lengthier computation.\n // let n = 16837; // = 113*149\n // let n = 22499; // = 149*151\n\n // Use Shor's algorithm to factor a semiprime integer.\n let (a, b) = FactorSemiprimeInteger(n);\n Message($\"Found factorization {n} = {a} * {b}\");\n return (a, b);\n}\n\n/// # Summary\n/// Uses Shor's algorithm to factor an input number.\n///\n/// # Input\n/// ## number\n/// A semiprime integer to be factored.\n///\n/// # Output\n/// Pair of numbers p > 1 and q > 1 such that p⋅q = `number`\noperation FactorSemiprimeInteger(number : Int) : (Int, Int) {\n // First check the most trivial case (the provided number is even).\n if number % 2 == 0 {\n Message(\"An even number has been given; 2 is a factor.\");\n return (number / 2, 2);\n }\n // These mutables will keep track of whether we found the factors, and\n // if so, what they are. The default value for the factors is (1,1).\n mutable foundFactors = false;\n mutable factors = (1, 1);\n mutable attempt = 1;\n repeat {\n Message($\"*** Factorizing {number}, attempt {attempt}.\");\n // Try to guess a number co-prime to `number` by getting a random\n // integer in the interval [1, number-1]\n let generator = DrawRandomInt(1, number - 1);\n\n // Check if the random integer is indeed co-prime.\n // If true use Quantum algorithm for Period finding.\n if GreatestCommonDivisorI(generator, number) == 1 {\n Message($\"Estimating period of {generator}.\");\n\n // Call Quantum Period finding algorithm for\n // `generator` mod `number`.\n let period = EstimatePeriod(generator, number);\n\n // Set the flag and factors values if the continued\n // fractions classical algorithm succeeds.\n set (foundFactors, factors) = MaybeFactorsFromPeriod(number, generator, period);\n }\n // In this case, we guessed a divisor by accident.\n else {\n // Find divisor.\n let gcd = GreatestCommonDivisorI(number, generator);\n Message($\"We have guessed a divisor {gcd} by accident. \" + \"No quantum computation was done.\");\n\n // Set the flag `foundFactors` to true, indicating that we\n // succeeded in finding factors.\n set foundFactors = true;\n set factors = (gcd, number / gcd);\n }\n set attempt = attempt + 1;\n if (attempt > 100) {\n fail \"Failed to find factors: too many attempts!\";\n }\n } until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" + \"Trying again.\");\n }\n\n // Return the factorization\n return factors;\n}\n\n/// # Summary\n/// Tries to find the factors of `modulus` given a `period` and `generator`.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## period\n/// The estimated period (multiplicative order) of the generator mod\n/// `modulus`.\n///\n/// # Output\n/// A tuple of a flag indicating whether factors were found successfully,\n/// and a pair of integers representing the factors that were found.\n/// Note that the second output is only meaningful when the first output is\n/// `true`.\nfunction MaybeFactorsFromPeriod(\n modulus : Int,\n generator : Int,\n period : Int\n) : (Bool, (Int, Int)) {\n\n // Period finding reduces to factoring only if period is even\n if period % 2 == 0 {\n // Compute `generator` ^ `period/2` mod `number`.\n let halfPower = ExpModI(generator, period / 2, modulus);\n\n // If we are unlucky, halfPower is just -1 mod N, which is a trivial\n // case and not useful for factoring.\n if halfPower != modulus - 1 {\n // When the halfPower is not -1 mod N, halfPower-1 or\n // halfPower+1 share non-trivial divisor with `number`. Find it.\n let factor = MaxI(\n GreatestCommonDivisorI(halfPower - 1, modulus),\n GreatestCommonDivisorI(halfPower + 1, modulus)\n );\n\n // Add a flag that we found the factors, and return only if computed\n // non-trivial factors (not like 1:n or n:1)\n if (factor != 1) and (factor != modulus) {\n Message($\"Found factor={factor}\");\n return (true, (factor, modulus / factor));\n }\n }\n // Return a flag indicating we hit a trivial case and didn't get\n // any factors.\n Message($\"Found trivial factors.\");\n return (false, (1, 1));\n } else {\n // When period is odd we have to pick another generator to estimate\n // period of and start over.\n Message($\"Estimated period {period} was odd, trying again.\");\n return (false, (1, 1));\n }\n}\n\n/// # Summary\n/// Find the period of a number from an input frequency.\n///\n/// # Input\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## frequencyEstimate\n/// The frequency that we want to convert to a period.\n/// ## bitsPrecision\n/// Number of bits of precision with which we need to estimate s/r to\n/// recover period r using continued fractions algorithm.\n/// ## currentDivisor\n/// The divisor of the generator period found so far.\n///\n/// # Output\n/// The period as calculated from the estimated frequency via the continued\n/// fractions algorithm.\nfunction PeriodFromFrequency(\n modulus : Int,\n frequencyEstimate : Int,\n bitsPrecision : Int,\n currentDivisor : Int\n) : Int {\n // Now we use the ContinuedFractionConvergentI function to recover s/r\n // from dyadic fraction k/2^bitsPrecision.\n let (numerator, period) = ContinuedFractionConvergentI(\n (frequencyEstimate, 2^bitsPrecision),\n modulus\n );\n\n // ContinuedFractionConvergentI does not guarantee the signs of the\n // numerator and denominator. Here we make sure that both are positive\n // using AbsI.\n let (numeratorAbs, periodAbs) = (AbsI(numerator), AbsI(period));\n\n // Compute and return the newly found divisor.\n let period = (periodAbs * currentDivisor) / GreatestCommonDivisorI(currentDivisor, periodAbs);\n Message($\"Found period={period}\");\n return period;\n}\n\n/// # Summary\n/// Finds a multiplicative order of the generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n///\n/// # Output\n/// The period (multiplicative order) of the generator mod `modulus`\noperation EstimatePeriod(generator : Int, modulus : Int) : Int {\n // Here we check that the inputs to the EstimatePeriod operation are\n // valid.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\"\n );\n\n // Number of bits in the modulus with respect to which we are estimating\n // the period.\n let bitsize = BitSizeI(modulus);\n\n // The EstimatePeriod operation estimates the period r by finding an\n // approximation k/2^(bits precision) to a fraction s/r, where s is some\n // integer. Note that if s and r have common divisors we will end up\n // recovering a divisor of r and not r itself.\n\n // Number of bits of precision with which we need to estimate s/r to\n // recover period r, using continued fractions algorithm.\n let bitsPrecision = 2 * bitsize + 1;\n\n // Current estimate for the frequency of the form s/r.\n let frequencyEstimate = EstimateFrequency(generator, modulus, bitsize);\n if frequencyEstimate != 0 {\n return PeriodFromFrequency(\n modulus,\n frequencyEstimate,\n bitsPrecision,\n 1\n );\n } else {\n Message(\"The estimated frequency was 0, trying again.\");\n return 1;\n }\n}\n\n/// # Summary\n/// Estimates the frequency of a generator in the residue ring Z mod\n/// `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period) of which is being\n/// estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus` in which the\n/// multiplicative order of `generator` is being estimated.\n/// ## bitsize\n/// Number of bits needed to represent the modulus.\n///\n/// # Output\n/// The numerator k of dyadic fraction k/2^bitsPrecision approximating s/r.\noperation EstimateFrequency(generator : Int, modulus : Int, bitsize : Int) : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n Message($\"Estimating frequency with bitsPrecision={bitsPrecision}.\");\n\n // Allocate qubits for the superposition of eigenstates of the oracle\n // that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of the\n // eigenstates we are estimating the phases of.\n // We are interpreting the register as encoding an unsigned integer in\n // little-endian format.\n ApplyXorInPlace(1, eigenstateRegister);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision - 1..-1..0 {\n H(c);\n Controlled ApplyOrderFindingOracle(\n [c],\n (generator, modulus, 1 <<< idx, eigenstateRegister)\n );\n R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c);\n H(c);\n if M(c) == One {\n X(c); // Reset\n set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using ResetAll.\n ResetAll(eigenstateRegister);\n Message($\"Estimated frequency={frequencyEstimate}\");\n return frequencyEstimate;\n}\n\n/// # Summary\n/// Interprets `target` as encoding unsigned little-endian integer k\n/// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where\n/// p is `power`, g is `generator` and N is `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## power\n/// Power of `generator` by which `target` is multiplied.\n/// ## target\n/// Register interpreted as little-endian which is multiplied by\n/// given power of the generator. The multiplication is performed modulo\n/// `modulus`.\ninternal operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[]\n) : Unit is Adj + Ctl {\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We\n // also use `ExpModI` to compute a by which x must be multiplied. Also\n // note that we interpret target as unsigned integer in little-endian\n // format.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target\n );\n}\n\n/// # Summary\n/// Performs modular in-place multiplication by a classical constant.\n///\n/// # Description\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(c*x) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular multiplication\n/// ## c\n/// Constant by which to multiply |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs)\n );\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs)\n );\n }\n}\n\n/// # Summary\n/// Performs modular in-place addition of a classical constant into a\n/// quantum register.\n///\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(x+c) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular addition\n/// ## c\n/// Constant to add to |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant([control], (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled IncByI(ctrls, (c, y + [carry]));\n Controlled Adjoint IncByI(ctrls, (modulus, y + [carry]));\n Controlled IncByI([carry], (modulus, y));\n Controlled ApplyIfLessOrEqualL(ctrls, (X, IntAsBigInt(c), y, carry));\n }\n }\n}\n"
81
81
  },
82
82
  {
83
83
  "title": "Three Qubit Repetition Code",
@@ -99,7 +99,7 @@ export default [
99
99
  {
100
100
  "title": "Shor (Resource Estimation)",
101
101
  "shots": 1,
102
- "code": "/// # Sample\n/// Estimating Frequency for Shor's algorithm\n///\n/// # Description\n/// In this sample we concentrate on costing the `EstimateFrequency`\n/// operation, which is the core quantum operation in Shor's algorithm, and\n/// we omit the classical pre- and post-processing. This makes it ideal for\n/// use with the Azure Quantum Resource Estimator.\nimport Std.Arrays.*;\nimport Std.Canon.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Intrinsic.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\nimport Microsoft.Quantum.Unstable.Arithmetic.*;\nimport Std.ResourceEstimation.*;\n\noperation Main() : Unit {\n let bitsize = 31;\n\n // When chooseing parameters for `EstimateFrequency`, make sure that\n // generator and modules are not co-prime\n let _ = EstimateFrequency(11, 2^bitsize - 1, bitsize);\n}\n\n/// # Summary\n/// Estimates the frequency of a generator\n/// in the residue ring Z mod `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## bitsize\n/// Number of bits needed to represent the modulus.\n///\n/// # Output\n/// The numerator k of dyadic fraction k/2^bitsPrecision\n/// approximating s/r.\noperation EstimateFrequency(\n generator : Int,\n modulus : Int,\n bitsize : Int\n) : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n\n // Allocate qubits for the superposition of eigenstates of\n // the oracle that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of\n // the eigenstates we are estimating the phases of.\n // We first interpret the register as encoding an unsigned integer\n // in little endian encoding.\n ApplyXorInPlace(1, eigenstateRegister);\n let oracle = ApplyOrderFindingOracle(generator, modulus, _, _);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision - 1..-1..0 {\n within {\n H(c);\n } apply {\n // `BeginEstimateCaching` and `EndEstimateCaching` are the operations\n // exposed by Azure Quantum Resource Estimator. These will instruct\n // resource counting such that the if-block will be executed\n // only once, its resources will be cached, and appended in\n // every other iteration.\n if BeginEstimateCaching(\"ControlledOracle\", SingleVariant()) {\n Controlled oracle([c], (1 <<< idx, eigenstateRegister));\n EndEstimateCaching();\n }\n R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c);\n }\n if MResetZ(c) == One {\n set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using Std.Intrinsic.ResetAll.\n ResetAll(eigenstateRegister);\n\n return frequencyEstimate;\n}\n\n/// # Summary\n/// Interprets `target` as encoding unsigned little-endian integer k\n/// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where\n/// p is `power`, g is `generator` and N is `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## power\n/// Power of `generator` by which `target` is multiplied.\n/// ## target\n/// Register interpreted as little-endian which is multiplied by\n/// given power of the generator. The multiplication is performed modulo\n/// `modulus`.\ninternal operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[]\n) : Unit is Adj + Ctl {\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We\n // also use `ExpModI` to compute a by which x must be multiplied. Also\n // note that we interpret target as unsigned integer in little-endian\n // format.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target\n );\n}\n\n/// # Summary\n/// Performs modular in-place multiplication by a classical constant.\n///\n/// # Description\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(c*x) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular multiplication\n/// ## c\n/// Constant by which to multiply |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs)\n );\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs)\n );\n }\n}\n\n/// # Summary\n/// Performs modular in-place addition of a classical constant into a\n/// quantum register.\n///\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(x+c) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular addition\n/// ## c\n/// Constant to add to |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant([control], (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled IncByI(ctrls, (c, y + [carry]));\n Controlled Adjoint IncByI(ctrls, (modulus, y + [carry]));\n Controlled IncByI([carry], (modulus, y));\n Controlled ApplyIfLessOrEqualL(ctrls, (X, IntAsBigInt(c), y, carry));\n }\n }\n}\n",
102
+ "code": "/// # Sample\n/// Estimating Frequency for Shor's algorithm\n///\n/// # Description\n/// In this sample we concentrate on costing the `EstimateFrequency`\n/// operation, which is the core quantum operation in Shor's algorithm, and\n/// we omit the classical pre- and post-processing. This makes it ideal for\n/// use with the Azure Quantum Resource Estimator.\nimport Std.Arrays.*;\nimport Std.Canon.*;\nimport Std.Convert.*;\nimport Std.Diagnostics.*;\nimport Std.Intrinsic.*;\nimport Std.Math.*;\nimport Std.Measurement.*;\nimport Std.Arithmetic.*;\nimport Std.ResourceEstimation.*;\n\noperation Main() : Unit {\n let bitsize = 31;\n\n // When chooseing parameters for `EstimateFrequency`, make sure that\n // generator and modules are not co-prime\n let _ = EstimateFrequency(11, 2^bitsize - 1, bitsize);\n}\n\n/// # Summary\n/// Estimates the frequency of a generator\n/// in the residue ring Z mod `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## bitsize\n/// Number of bits needed to represent the modulus.\n///\n/// # Output\n/// The numerator k of dyadic fraction k/2^bitsPrecision\n/// approximating s/r.\noperation EstimateFrequency(\n generator : Int,\n modulus : Int,\n bitsize : Int\n) : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n\n // Allocate qubits for the superposition of eigenstates of\n // the oracle that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of\n // the eigenstates we are estimating the phases of.\n // We first interpret the register as encoding an unsigned integer\n // in little endian encoding.\n ApplyXorInPlace(1, eigenstateRegister);\n let oracle = ApplyOrderFindingOracle(generator, modulus, _, _);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision - 1..-1..0 {\n within {\n H(c);\n } apply {\n // `BeginEstimateCaching` and `EndEstimateCaching` are the operations\n // exposed by Azure Quantum Resource Estimator. These will instruct\n // resource counting such that the if-block will be executed\n // only once, its resources will be cached, and appended in\n // every other iteration.\n if BeginEstimateCaching(\"ControlledOracle\", SingleVariant()) {\n Controlled oracle([c], (1 <<< idx, eigenstateRegister));\n EndEstimateCaching();\n }\n R1Frac(frequencyEstimate, bitsPrecision - 1 - idx, c);\n }\n if MResetZ(c) == One {\n set frequencyEstimate += 1 <<< (bitsPrecision - 1 - idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using Std.Intrinsic.ResetAll.\n ResetAll(eigenstateRegister);\n\n return frequencyEstimate;\n}\n\n/// # Summary\n/// Interprets `target` as encoding unsigned little-endian integer k\n/// and performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where\n/// p is `power`, g is `generator` and N is `modulus`.\n///\n/// # Input\n/// ## generator\n/// The unsigned integer multiplicative order (period)\n/// of which is being estimated. Must be co-prime to `modulus`.\n/// ## modulus\n/// The modulus which defines the residue ring Z mod `modulus`\n/// in which the multiplicative order of `generator` is being estimated.\n/// ## power\n/// Power of `generator` by which `target` is multiplied.\n/// ## target\n/// Register interpreted as little-endian which is multiplied by\n/// given power of the generator. The multiplication is performed modulo\n/// `modulus`.\ninternal operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[]\n) : Unit is Adj + Ctl {\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩. We\n // also use `ExpModI` to compute a by which x must be multiplied. Also\n // note that we interpret target as unsigned integer in little-endian\n // format.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target\n );\n}\n\n/// # Summary\n/// Performs modular in-place multiplication by a classical constant.\n///\n/// # Description\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(c*x) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular multiplication\n/// ## c\n/// Constant by which to multiply |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs)\n );\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs)\n );\n }\n}\n\n/// # Summary\n/// Performs modular in-place addition of a classical constant into a\n/// quantum register.\n///\n/// Given the classical constants `c` and `modulus`, and an input quantum\n/// register |𝑦⟩ in little-endian format, this operation computes\n/// `(x+c) % modulus` into |𝑦⟩.\n///\n/// # Input\n/// ## modulus\n/// Modulus to use for modular addition\n/// ## c\n/// Constant to add to |𝑦⟩\n/// ## y\n/// Quantum register of target\ninternal operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant([control], (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled IncByI(ctrls, (c, y + [carry]));\n Controlled Adjoint IncByI(ctrls, (modulus, y + [carry]));\n Controlled IncByI([carry], (modulus, y));\n Controlled ApplyIfLessOrEqualL(ctrls, (X, IntAsBigInt(c), y, carry));\n }\n }\n}\n",
103
103
  "omitFromTests": true
104
104
  }
105
105
  ];
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  uid: Qdk.Microsoft.Quantum.Core.Length
3
3
  title: Length exported item
4
- description: "Q# Length exported item: This is an exported item. The actual definition is found here: [Length](xref:Qdk.Std.Core.Length)"
5
- ms.date: 11/15/2024
4
+ description: "Q# Length exported item: This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length)"
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: export
8
8
  qsharp.package: __Std__
9
9
  qsharp.namespace: Microsoft.Quantum.Core
10
10
  qsharp.name: Length
11
- qsharp.summary: "This is an exported item. The actual definition is found here: [Length](xref:Qdk.Std.Core.Length)"
11
+ qsharp.summary: "This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length)"
12
12
  ---
13
13
 
14
14
  # Length exported item
15
15
 
16
16
  Fully qualified name: Microsoft.Quantum.Core.Length
17
17
 
18
- This is an exported item. The actual definition is found here: [Length](xref:Qdk.Std.Core.Length)
18
+ This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length)
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  uid: Qdk.Microsoft.Quantum.Core.Repeated
3
3
  title: Repeated exported item
4
- description: "Q# Repeated exported item: This is an exported item. The actual definition is found here: [Repeated](xref:Qdk.Std.Core.Repeated)"
5
- ms.date: 11/15/2024
4
+ description: "Q# Repeated exported item: This is an exported item. The actual definition is found here: [Std.Core.Repeated](xref:Qdk.Std.Core.Repeated)"
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: export
8
8
  qsharp.package: __Std__
9
9
  qsharp.namespace: Microsoft.Quantum.Core
10
10
  qsharp.name: Repeated
11
- qsharp.summary: "This is an exported item. The actual definition is found here: [Repeated](xref:Qdk.Std.Core.Repeated)"
11
+ qsharp.summary: "This is an exported item. The actual definition is found here: [Std.Core.Repeated](xref:Qdk.Std.Core.Repeated)"
12
12
  ---
13
13
 
14
14
  # Repeated exported item
15
15
 
16
16
  Fully qualified name: Microsoft.Quantum.Core.Repeated
17
17
 
18
- This is an exported item. The actual definition is found here: [Repeated](xref:Qdk.Std.Core.Repeated)
18
+ This is an exported item. The actual definition is found here: [Std.Core.Repeated](xref:Qdk.Std.Core.Repeated)
@@ -4,7 +4,7 @@ title: Microsoft.Quantum.Core namespace
4
4
  description: Table of contents for the Q# Microsoft.Quantum.Core namespace
5
5
  author: {AUTHOR}
6
6
  ms.author: {MS_AUTHOR}
7
- ms.date: 11/15/2024
7
+ ms.date: 12/05/2024
8
8
  ms.topic: landing-page
9
9
  ---
10
10
 
@@ -14,5 +14,5 @@ The Microsoft.Quantum.Core namespace contains the following items:
14
14
 
15
15
  | Name | Description |
16
16
  |------|-------------|
17
- | [Length](xref:Qdk.Microsoft.Quantum.Core.Length) | This is an exported item. The actual definition is found here: [Length](xref:Qdk.Std.Core.Length) |
18
- | [Repeated](xref:Qdk.Microsoft.Quantum.Core.Repeated) | This is an exported item. The actual definition is found here: [Repeated](xref:Qdk.Std.Core.Repeated) |
17
+ | [Length](xref:Qdk.Microsoft.Quantum.Core.Length) | This is an exported item. The actual definition is found here: [Std.Core.Length](xref:Qdk.Std.Core.Length) |
18
+ | [Repeated](xref:Qdk.Microsoft.Quantum.Core.Repeated) | This is an exported item. The actual definition is found here: [Std.Core.Repeated](xref:Qdk.Std.Core.Repeated) |
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.AddLE
3
3
  title: AddLE operation
4
4
  description: "Q# AddLE operation: Sets a zero-initialized little-endian register zs to the sum of little-endian registers xs and ys"
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfEqualL
3
3
  title: ApplyIfEqualL operation
4
4
  description: "Q# ApplyIfEqualL operation: Computes `if (c == x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is equal to the little-endian qubit register `x`"
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfEqualLE
3
3
  title: ApplyIfEqualLE operation
4
4
  description: "Q# ApplyIfEqualLE operation: Computes `if x == y { action(target) }`, that is, applies `action` to `target` if register `x` is equal to the register `y`. Both qubit registers should be in a little-endian format."
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfGreaterL
3
3
  title: ApplyIfGreaterL operation
4
4
  description: "Q# ApplyIfGreaterL operation: Computes `if (c > x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is greater than the little-endian qubit register `x`"
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfGreaterLE
3
3
  title: ApplyIfGreaterLE operation
4
4
  description: "Q# ApplyIfGreaterLE operation: Computes `if x > y { action(target) }`, that is, applies `action` to `target` if register `x` is greater than the register `y`. Both qubit registers should be in a little-endian format."
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfGreaterOrEqualL
3
3
  title: ApplyIfGreaterOrEqualL operation
4
4
  description: "Q# ApplyIfGreaterOrEqualL operation: Computes `if (c >= x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is greater or equal to the little-endian qubit register `x`"
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfGreaterOrEqualLE
3
3
  title: ApplyIfGreaterOrEqualLE operation
4
4
  description: "Q# ApplyIfGreaterOrEqualLE operation: Computes `if x >= y { action(target) }`, that is, applies `action` to `target` if register `x` is greater or equal to the register `y`. Both qubit registers should be in a little-endian format."
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfLessL
3
3
  title: ApplyIfLessL operation
4
4
  description: "Q# ApplyIfLessL operation: Computes `if (c < x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is less than the little-endian qubit register `x`"
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfLessLE
3
3
  title: ApplyIfLessLE operation
4
4
  description: "Q# ApplyIfLessLE operation: Computes `if x < y { action(target) }`, that is, applies `action` to `target` if register `x` is less than the register `y`. Both qubit registers should be in a little-endian format."
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfLessOrEqualL
3
3
  title: ApplyIfLessOrEqualL operation
4
4
  description: "Q# ApplyIfLessOrEqualL operation: Computes `if (c <= x) { action(target) }`, that is, applies `action` to `target` if a BigInt value `c` is less or equal to the little-endian qubit register `x`"
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.ApplyIfLessOrEqualLE
3
3
  title: ApplyIfLessOrEqualLE operation
4
4
  description: "Q# ApplyIfLessOrEqualLE operation: Computes `if x <= y { action(target) }`, that is, applies `action` to `target` if register `x` is less or equal to the register `y`. Both qubit registers should be in a little-endian format."
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.FourierTDIncByLE
3
3
  title: FourierTDIncByLE operation
4
4
  description: "Q# FourierTDIncByLE operation: Increments a little-endian register ys by a little-endian register xs using Quantum Fourier Transform."
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.IncByI
3
3
  title: IncByI operation
4
4
  description: "Q# IncByI operation: Increments a little-endian register ys by an integer number c"
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__
@@ -2,7 +2,7 @@
2
2
  uid: Qdk.Std.Arithmetic.IncByIUsingIncByLE
3
3
  title: IncByIUsingIncByLE operation
4
4
  description: "Q# IncByIUsingIncByLE operation: Increments a little-endian register ys by an Int number c using provided adder."
5
- ms.date: 11/15/2024
5
+ ms.date: 12/05/2024
6
6
  ms.topic: managed-reference
7
7
  qsharp.kind: operation
8
8
  qsharp.package: __Std__