qsharp-lang 1.0.23-dev → 1.0.24-dev

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.
@@ -7,6 +7,7 @@ export interface ICompiler {
7
7
  getHir(code: string): Promise<string>;
8
8
  run(code: string, expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
9
9
  getQir(code: string): Promise<string>;
10
+ getEstimates(code: string, params: string): Promise<string>;
10
11
  checkExerciseSolution(user_code: string, exercise_sources: string[], eventHandler: IQscEventTarget): Promise<boolean>;
11
12
  }
12
13
  export type ICompilerWorker = ICompiler & IServiceProxy;
@@ -16,6 +17,7 @@ export declare class Compiler implements ICompiler {
16
17
  constructor(wasm: Wasm);
17
18
  checkCode(code: string): Promise<VSDiagnostic[]>;
18
19
  getQir(code: string): Promise<string>;
20
+ getEstimates(code: string, params: string): Promise<string>;
19
21
  getHir(code: string): Promise<string>;
20
22
  run(code: string, expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
21
23
  checkExerciseSolution(user_code: string, exercise_sources: string[], eventHandler: IQscEventTarget): Promise<boolean>;
@@ -21,6 +21,9 @@ export class Compiler {
21
21
  async getQir(code) {
22
22
  return this.wasm.get_qir(code);
23
23
  }
24
+ async getEstimates(code, params) {
25
+ return this.wasm.get_estimates(code, params);
26
+ }
24
27
  async getHir(code) {
25
28
  return this.wasm.get_hir(code);
26
29
  }
@@ -29,7 +29,6 @@ export declare class QscEventTarget implements IQscEventTarget {
29
29
  private results;
30
30
  private shotActive;
31
31
  private animationFrameId;
32
- private supportsUiRefresh;
33
32
  addEventListener<T extends QscUiEvents["type"]>(type: T, listener: (event: Extract<QscEvents, {
34
33
  type: T;
35
34
  }>) => void): void;
@@ -31,9 +31,6 @@ export class QscEventTarget {
31
31
  this.results = [];
32
32
  this.shotActive = false;
33
33
  this.animationFrameId = 0;
34
- this.supportsUiRefresh = false;
35
- this.supportsUiRefresh =
36
- typeof globalThis.requestAnimationFrame === "function";
37
34
  if (captureEvents) {
38
35
  this.addEventListener("Message", (ev) => this.onMessage(ev.detail));
39
36
  this.addEventListener("DumpMachine", (ev) => this.onDumpMachine(ev.detail));
@@ -67,10 +64,10 @@ export class QscEventTarget {
67
64
  }
68
65
  }
69
66
  queueUiRefresh() {
70
- if (this.supportsUiRefresh && !this.animationFrameId) {
71
- this.animationFrameId = requestAnimationFrame(() => {
67
+ if (!this.animationFrameId) {
68
+ this.animationFrameId = setTimeout(() => {
72
69
  this.onUiRefresh();
73
- });
70
+ }, 50); // 20 fps is plenty for the rendering we do
74
71
  }
75
72
  }
76
73
  onUiRefresh() {
@@ -5,6 +5,7 @@ const requests = {
5
5
  checkCode: "request",
6
6
  getHir: "request",
7
7
  getQir: "request",
8
+ getEstimates: "request",
8
9
  run: "requestWithProgress",
9
10
  checkExerciseSolution: "requestWithProgress",
10
11
  };
@@ -32,22 +32,22 @@ export default [
32
32
  {
33
33
  "title": "Random Number Generator",
34
34
  "shots": 1000,
35
- "code": "/// # Sample\n/// Quantum Random Number Generator\n///\n/// # Description\n/// This program implements a quantum ranndom number generator by setting qubits\n/// in superposition and then using the measurement results as random bits.\nnamespace Sample {\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Intrinsic;\n\n @EntryPoint()\n operation Main() : Result[] {\n // Generate 5-bit random number.\n let nBits = 5;\n return GenerateNRandomBits(nBits);\n }\n\n /// # Summary\n /// Generates N random bits.\n operation GenerateNRandomBits(nBits : Int) : Result[] {\n // Allocate N qubits.\n use register = Qubit[nBits];\n\n // Set the qubits into superposition of 0 and 1 using the Hadamard\n // operation `H`.\n for qubit in register {\n H(qubit);\n }\n\n // At this point each has 50% chance of being measured in the |0〉 state\n // and 50% chance of being measured in the |1〉 state.\n // Measure each qubit and reset them all so they can be safely\n // deallocated.\n let results = MeasureEachZ(register);\n ResetAll(register);\n return results;\n }\n}\n"
35
+ "code": "/// # Sample\n/// Quantum Random Number Generator\n///\n/// # Description\n/// This program implements a quantum random number generator by setting qubits\n/// in superposition and then using the measurement results as random bits.\nnamespace Sample {\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Intrinsic;\n\n @EntryPoint()\n operation Main() : Result[] {\n // Generate 5-bit random number.\n let nBits = 5;\n return GenerateNRandomBits(nBits);\n }\n\n /// # Summary\n /// Generates N random bits.\n operation GenerateNRandomBits(nBits : Int) : Result[] {\n // Allocate N qubits.\n use register = Qubit[nBits];\n\n // Set the qubits into superposition of 0 and 1 using the Hadamard\n // operation `H`.\n for qubit in register {\n H(qubit);\n }\n\n // At this point each has 50% chance of being measured in the |0〉 state\n // and 50% chance of being measured in the |1〉 state.\n // Measure each qubit and reset them all so they can be safely\n // deallocated.\n let results = MeasureEachZ(register);\n ResetAll(register);\n return results;\n }\n}\n"
36
36
  },
37
37
  {
38
38
  "title": "Random Number Generator (Advanced)",
39
39
  "shots": 1000,
40
- "code": "/// # Sample\n/// Quantum Random Number Generator\n///\n/// # Description\n/// This program implements a quantum ranndom number generator by setting qubits\n/// in superposition and then using the measurement results as random bits.\nnamespace Sample {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation Main() : Int {\n let max = 100;\n Message($\"Sampling a random number between 0 and {max}: \");\n\n // Generate random number in the 0..max range.\n return GenerateRandomNumberInRange(max);\n }\n\n /// # Summary\n /// Generates a random number between 0 and `max`.\n operation GenerateRandomNumberInRange(max : Int) : Int {\n // Determine the number of bits needed to represent `max` and store it\n // in the `nBits` variable. Then generate `nBits` random bits which will\n // represent the generated random number.\n mutable bits = [];\n let nBits = BitSizeI(max);\n for idxBit in 1..nBits {\n set bits += [GenerateRandomBit()];\n }\n let sample = ResultArrayAsInt(bits);\n\n // Return random number if it is within the requested range.\n // Generate it again if it is outside the range.\n return sample > max ? GenerateRandomNumberInRange(max) | sample;\n }\n\n /// # Summary\n /// Generates a random bit.\n operation GenerateRandomBit() : Result {\n // Allocate a qubit.\n use q = Qubit();\n\n // Set the qubit into superposition of 0 and 1 using the Hadamard \n // operation `H`.\n H(q);\n\n // At this point the qubit `q` has 50% chance of being measured in the\n // |0〉 state and 50% chance of being measured in the |1〉 state.\n // Measure the qubit value using the `M` operation, and store the\n // measurement value in the `result` variable.\n let result = M(q);\n\n // Reset qubit to the |0〉 state.\n // Qubits must be in the |0〉 state by the time they are released.\n Reset(q);\n\n // Return the result of the measurement.\n return result;\n\n // Note that Qubit `q` is automatically released at the end of the block.\n }\n}\n"
40
+ "code": "/// # Sample\n/// Quantum Random Number Generator\n///\n/// # Description\n/// This program implements a quantum random number generator by setting qubits\n/// in superposition and then using the measurement results as random bits.\nnamespace Sample {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation Main() : Int {\n let max = 100;\n Message($\"Sampling a random number between 0 and {max}: \");\n\n // Generate random number in the 0..max range.\n return GenerateRandomNumberInRange(max);\n }\n\n /// # Summary\n /// Generates a random number between 0 and `max`.\n operation GenerateRandomNumberInRange(max : Int) : Int {\n // Determine the number of bits needed to represent `max` and store it\n // in the `nBits` variable. Then generate `nBits` random bits which will\n // represent the generated random number.\n mutable bits = [];\n let nBits = BitSizeI(max);\n for idxBit in 1..nBits {\n set bits += [GenerateRandomBit()];\n }\n let sample = ResultArrayAsInt(bits);\n\n // Return random number if it is within the requested range.\n // Generate it again if it is outside the range.\n return sample > max ? GenerateRandomNumberInRange(max) | sample;\n }\n\n /// # Summary\n /// Generates a random bit.\n operation GenerateRandomBit() : Result {\n // Allocate a qubit.\n use q = Qubit();\n\n // Set the qubit into superposition of 0 and 1 using the Hadamard \n // operation `H`.\n H(q);\n\n // At this point the qubit `q` has 50% chance of being measured in the\n // |0〉 state and 50% chance of being measured in the |1〉 state.\n // Measure the qubit value using the `M` operation, and store the\n // measurement value in the `result` variable.\n let result = M(q);\n\n // Reset qubit to the |0〉 state.\n // Qubits must be in the |0〉 state by the time they are released.\n Reset(q);\n\n // Return the result of the measurement.\n return result;\n\n // Note that Qubit `q` is automatically released at the end of the block.\n }\n}\n"
41
41
  },
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.\nnamespace Sample {\n\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : (Result[], Result[]) {\n // A Boolean function is a function that maps bits trings 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 reguster.\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)\n operation 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 = MeasureEachZ(queryRegister);\n ResetAll(queryRegister);\n Reset(target);\n return results;\n }\n\n // Simple constant Boolean function\n operation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n }\n\n // Simple balanced Boolean function\n operation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n }\n}\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.\nnamespace Sample {\n\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation 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 reguster.\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)\n operation 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 = MeasureEachZ(queryRegister);\n ResetAll(queryRegister);\n Reset(target);\n return results;\n }\n\n // Simple constant Boolean function\n operation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n }\n\n // Simple balanced Boolean function\n operation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n }\n}\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.\nnamespace Sample {\n open Microsoft.Quantum.Canon;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : (String, Bool)[] {\n // A Boolean function is a function that maps bits trings 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 ?\n \"constant\" | \n \"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)\n operation 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\n operation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n }\n\n // Simple balanced Boolean function\n operation 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.\n operation 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.\n operation 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}\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.\nnamespace Sample {\n open Microsoft.Quantum.Canon;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation 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 ?\n \"constant\" | \n \"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)\n operation 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\n operation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n }\n\n // Simple balanced Boolean function\n operation 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.\n operation 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.\n operation 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}\n"
51
51
  },
52
52
  {
53
53
  "title": "Bernstein–Vazirani",
@@ -77,6 +77,6 @@ export default [
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.\nnamespace Sample {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Random;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Arrays;\n\n @EntryPoint()\n operation 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`\n operation 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) =\n 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. \" +\n \"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 }\n until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" +\n \"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`.\n function 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.\n function 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 // 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 =\n (periodAbs * currentDivisor) /\n 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`\n operation 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 // 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, frequencyEstimate, bitsPrecision, 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.\n operation EstimateFrequency(generator : Int,modulus : Int, bitsize : Int)\n : 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 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 and\n /// performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where p is `power`, g is\n /// `generator` and N is `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 /// ## power\n /// Power of `generator` by which `target` is multiplied.\n /// ## target\n /// Register interpreted as little-endian which is multiplied by given power\n /// of the generator. The multiplication is performed modulo `modulus`.\n operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[])\n : Unit is Adj + Ctl {\n // Check that the parameters satisfy the requirements.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\");\n\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩.\n // We also use `ExpModI` to compute a by which x must be multiplied.\n // Also note that we interpret target as unsigned integer in\n // little-endian fromat.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target);\n }\n\n //\n // Arithmetic helper functions to implement order-finding oracle.\n //\n\n /// # Summary\n /// Returns the number of trailing zeroes of a number.\n ///\n /// ## Example\n /// let zeroes = NTrailingZeroes(21); // NTrailingZeroes(0b1101) = 0\n /// let zeroes = NTrailingZeroes(20); // NTrailingZeroes(0b1100) = 2\n function NTrailingZeroes(number : Int) : Int {\n Fact(number != 0, \"NTrailingZeroes: number cannot be 0.\");\n mutable nZeroes = 0;\n mutable copy = number;\n while (copy % 2 == 0) {\n set nZeroes += 1;\n set copy /= 2;\n }\n return nZeroes;\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\n operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[])\n : 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 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 /// # Summary\n /// Performs modular in-place addition of a classical constant into a\n /// quantum register.\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 /// `(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\n operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[])\n : 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(\n [control],\n (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled AddConstant(\n ctrls, (c, y + [carry]));\n Controlled Adjoint AddConstant(\n ctrls, (modulus, y + [carry]));\n Controlled AddConstant(\n [carry], (modulus, y));\n Controlled CompareGreaterThanOrEqualConstant(\n ctrls, (c, y, carry));\n }\n }\n }\n\n /// # Summary\n /// Performs in-place addition of a constant into a quantum register.\n ///\n /// # Description\n /// Given a non-empty quantum register |𝑦⟩ of length 𝑛+1 and a positive\n // constant 𝑐 < 2ⁿ, computes |𝑦 + c⟩ into |𝑦⟩.\n ///\n /// # Input\n /// ## c\n /// Constant number to add to |𝑦⟩.\n /// ## y\n /// Quantum register of second summand and target; must not be empty.\n operation AddConstant(c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n // We are using this version instead of the library version that is\n // based on Fourier angles to show an advantage of sparse simulation\n // in this sample.\n let n = Length(y);\n Fact(n > 0, \"Bit width must be at least 1\");\n Fact(c >= 0, \"constant must not be negative\");\n Fact(c < 2^n, \"constant must be smaller than {2^n)}\");\n if c != 0 {\n // If c has j trailing zeroes than the j least significant bits of y\n // won't be affected by the addition and can therefore be ignored by\n // applying the addition only to the other qubits and shifting c\n // accordingly.\n let j = NTrailingZeroes(c);\n use x = Qubit[n - j];\n within {\n ApplyXorInPlace(c >>> j, x);\n } apply {\n AddI(x, y[j...]);\n }\n }\n }\n\n /// # Summary\n /// Performs greater-than-or-equals comparison to a constant.\n ///\n /// # Description\n /// Toggles output qubit `target` if and only if input register `x` is\n /// greater than or equal to `c`.\n ///\n /// # Input\n /// ## c\n /// Constant value for comparison.\n /// ## x\n /// Quantum register to compare against.\n /// ## target\n /// Target qubit for comparison result.\n ///\n /// # Reference\n /// This construction is described in [Lemma 3, arXiv:2201.10200]\n operation CompareGreaterThanOrEqualConstant(\n c : Int,\n x : Qubit[],\n target : Qubit)\n : Unit is Adj+Ctl {\n let bitWidth = Length(x);\n if c == 0 {\n X(target);\n } elif c >= (2^bitWidth) {\n // do nothing\n } elif c == (2^(bitWidth - 1)) {\n CNOT(Tail(x), target);\n } else {\n // normalize constant\n let l = NTrailingZeroes(c);\n let cNormalized = c >>> l;\n let xNormalized = x[l...];\n let bitWidthNormalized = Length(xNormalized);\n use qs = Qubit[bitWidthNormalized - 1];\n let cs1 = [Head(xNormalized)] + Most(qs);\n Fact(Length(cs1) == Length(qs),\n \"Arrays should be of the same length.\");\n within {\n for i in 0..Length(cs1)-1 {\n let op =\n cNormalized &&& (1 <<< (i+1)) != 0 ?\n ApplyAnd | ApplyOr;\n op(cs1[i], xNormalized[i+1], qs[i]);\n }\n } apply {\n CNOT(Tail(qs), target);\n }\n }\n }\n\n /// # Summary\n /// Inverts a given target qubit if and only if both control qubits are in\n /// the 1 state, using measurement to perform the adjoint operation.\n ///\n /// # Description\n /// Inverts `target` if and only if both controls are 1, but assumes that\n /// `target` is in state 0. The operation has T-count 4, T-depth 2 and\n /// requires no helper qubit, and may therefore be preferable to a CCNOT\n /// operation, if `target` is known to be 0.\n /// The adjoint of this operation is measurement based and requires no T\n /// gates.\n /// Although the Toffoli gate (CCNOT) will perform faster in in simulations,\n /// this version has lower T gate requirements.\n ///\n /// # Input\n /// ## control1\n /// First control qubit\n /// ## control2\n /// Second control qubit\n /// ## target\n /// Target auxiliary qubit; must be in state 0\n ///\n /// # References\n /// - Cody Jones: \"Novel constructions for the fault-tolerant\n /// Toffoli gate\",\n /// Phys. Rev. A 87, 022328, 2013\n /// [arXiv:1212.5069](https://arxiv.org/abs/1212.5069)\n /// doi:10.1103/PhysRevA.87.022328\n /// - Craig Gidney: \"Halving the cost of quantum addition\",\n /// Quantum 2, page 74, 2018\n /// [arXiv:1709.06648](https://arxiv.org/abs/1709.06648)\n /// doi:10.1103/PhysRevA.85.044302\n /// - Mathias Soeken: \"Quantum Oracle Circuits and the Christmas\n /// Tree Pattern\",\n /// [Blog article from December 19, 2019](https://msoeken.github.io/blog_qac.html)\n /// (note: explains the multiple controlled construction)\n operation ApplyAnd(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n body (...) {\n H(target);\n T(target);\n CNOT(control1, target);\n CNOT(control2, target);\n within {\n CNOT(target, control1);\n CNOT(target, control2);\n }\n apply {\n Adjoint T(control1);\n Adjoint T(control2);\n T(target);\n }\n H(target);\n S(target);\n }\n adjoint (...) {\n H(target);\n if (M(target) == One) {\n X(target);\n CZ(control1, control2);\n }\n }\n }\n\n /// # Summary\n /// Applies X to the target if any of the controls are 1.\n operation ApplyOr(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n within {\n ApplyToEachA(X, [control1, control2]);\n } apply {\n ApplyAnd(control1, control2, target);\n X(target);\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.\nnamespace Sample {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Random;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Unstable.Arithmetic;\n open Microsoft.Quantum.Arrays;\n\n @EntryPoint()\n operation 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`\n operation 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) =\n 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. \" +\n \"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 }\n until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" +\n \"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`.\n function 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.\n function 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 // 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 =\n (periodAbs * currentDivisor) /\n 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`\n operation 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 // 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, frequencyEstimate, bitsPrecision, 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.\n operation EstimateFrequency(generator : Int,modulus : Int, bitsize : Int)\n : 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 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 and\n /// performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where p is `power`, g is\n /// `generator` and N is `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 /// ## power\n /// Power of `generator` by which `target` is multiplied.\n /// ## target\n /// Register interpreted as little-endian which is multiplied by given power\n /// of the generator. The multiplication is performed modulo `modulus`.\n operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[])\n : Unit is Adj + Ctl {\n // Check that the parameters satisfy the requirements.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\");\n\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩.\n // We also use `ExpModI` to compute a by which x must be multiplied.\n // Also note that we interpret target as unsigned integer in\n // little-endian fromat.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target);\n }\n\n //\n // Arithmetic helper functions to implement order-finding oracle.\n //\n\n /// # Summary\n /// Returns the number of trailing zeroes of a number.\n ///\n /// ## Example\n /// let zeroes = NTrailingZeroes(21); // NTrailingZeroes(0b1101) = 0\n /// let zeroes = NTrailingZeroes(20); // NTrailingZeroes(0b1100) = 2\n function NTrailingZeroes(number : Int) : Int {\n Fact(number != 0, \"NTrailingZeroes: number cannot be 0.\");\n mutable nZeroes = 0;\n mutable copy = number;\n while (copy % 2 == 0) {\n set nZeroes += 1;\n set copy /= 2;\n }\n return nZeroes;\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\n operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[])\n : 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 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 /// # Summary\n /// Performs modular in-place addition of a classical constant into a\n /// quantum register.\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 /// `(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\n operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[])\n : 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(\n [control],\n (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled AddConstant(\n ctrls, (c, y + [carry]));\n Controlled Adjoint AddConstant(\n ctrls, (modulus, y + [carry]));\n Controlled AddConstant(\n [carry], (modulus, y));\n Controlled CompareGreaterThanOrEqualConstant(\n ctrls, (c, y, carry));\n }\n }\n }\n\n /// # Summary\n /// Performs in-place addition of a constant into a quantum register.\n ///\n /// # Description\n /// Given a non-empty quantum register |𝑦⟩ of length 𝑛+1 and a positive\n // constant 𝑐 < 2ⁿ, computes |𝑦 + c⟩ into |𝑦⟩.\n ///\n /// # Input\n /// ## c\n /// Constant number to add to |𝑦⟩.\n /// ## y\n /// Quantum register of second summand and target; must not be empty.\n operation AddConstant(c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n // We are using this version instead of the library version that is\n // based on Fourier angles to show an advantage of sparse simulation\n // in this sample.\n let n = Length(y);\n Fact(n > 0, \"Bit width must be at least 1\");\n Fact(c >= 0, \"constant must not be negative\");\n Fact(c < 2^n, \"constant must be smaller than {2^n)}\");\n if c != 0 {\n // If c has j trailing zeroes than the j least significant bits of y\n // won't be affected by the addition and can therefore be ignored by\n // applying the addition only to the other qubits and shifting c\n // accordingly.\n let j = NTrailingZeroes(c);\n use x = Qubit[n - j];\n within {\n ApplyXorInPlace(c >>> j, x);\n } apply {\n IncByLE(x, y[j...]);\n }\n }\n }\n\n /// # Summary\n /// Performs greater-than-or-equals comparison to a constant.\n ///\n /// # Description\n /// Toggles output qubit `target` if and only if input register `x` is\n /// greater than or equal to `c`.\n ///\n /// # Input\n /// ## c\n /// Constant value for comparison.\n /// ## x\n /// Quantum register to compare against.\n /// ## target\n /// Target qubit for comparison result.\n ///\n /// # Reference\n /// This construction is described in [Lemma 3, arXiv:2201.10200]\n operation CompareGreaterThanOrEqualConstant(\n c : Int,\n x : Qubit[],\n target : Qubit)\n : Unit is Adj+Ctl {\n let bitWidth = Length(x);\n if c == 0 {\n X(target);\n } elif c >= (2^bitWidth) {\n // do nothing\n } elif c == (2^(bitWidth - 1)) {\n CNOT(Tail(x), target);\n } else {\n // normalize constant\n let l = NTrailingZeroes(c);\n let cNormalized = c >>> l;\n let xNormalized = x[l...];\n let bitWidthNormalized = Length(xNormalized);\n use qs = Qubit[bitWidthNormalized - 1];\n let cs1 = [Head(xNormalized)] + Most(qs);\n Fact(Length(cs1) == Length(qs),\n \"Arrays should be of the same length.\");\n within {\n for i in 0..Length(cs1)-1 {\n let op =\n cNormalized &&& (1 <<< (i+1)) != 0 ?\n ApplyAnd | ApplyOr;\n op(cs1[i], xNormalized[i+1], qs[i]);\n }\n } apply {\n CNOT(Tail(qs), target);\n }\n }\n }\n\n /// # Summary\n /// Inverts a given target qubit if and only if both control qubits are in\n /// the 1 state, using measurement to perform the adjoint operation.\n ///\n /// # Description\n /// Inverts `target` if and only if both controls are 1, but assumes that\n /// `target` is in state 0. The operation has T-count 4, T-depth 2 and\n /// requires no helper qubit, and may therefore be preferable to a CCNOT\n /// operation, if `target` is known to be 0.\n /// The adjoint of this operation is measurement based and requires no T\n /// gates.\n /// Although the Toffoli gate (CCNOT) will perform faster in in simulations,\n /// this version has lower T gate requirements.\n ///\n /// # Input\n /// ## control1\n /// First control qubit\n /// ## control2\n /// Second control qubit\n /// ## target\n /// Target auxiliary qubit; must be in state 0\n ///\n /// # References\n /// - Cody Jones: \"Novel constructions for the fault-tolerant\n /// Toffoli gate\",\n /// Phys. Rev. A 87, 022328, 2013\n /// [arXiv:1212.5069](https://arxiv.org/abs/1212.5069)\n /// doi:10.1103/PhysRevA.87.022328\n /// - Craig Gidney: \"Halving the cost of quantum addition\",\n /// Quantum 2, page 74, 2018\n /// [arXiv:1709.06648](https://arxiv.org/abs/1709.06648)\n /// doi:10.1103/PhysRevA.85.044302\n /// - Mathias Soeken: \"Quantum Oracle Circuits and the Christmas\n /// Tree Pattern\",\n /// [Blog article from December 19, 2019](https://msoeken.github.io/blog_qac.html)\n /// (note: explains the multiple controlled construction)\n operation ApplyAnd(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n body (...) {\n H(target);\n T(target);\n CNOT(control1, target);\n CNOT(control2, target);\n within {\n CNOT(target, control1);\n CNOT(target, control2);\n }\n apply {\n Adjoint T(control1);\n Adjoint T(control2);\n T(target);\n }\n H(target);\n S(target);\n }\n adjoint (...) {\n H(target);\n if (M(target) == One) {\n X(target);\n CZ(control1, control2);\n }\n }\n }\n\n /// # Summary\n /// Applies X to the target if any of the controls are 1.\n operation ApplyOr(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n within {\n ApplyToEachA(X, [control1, control2]);\n } apply {\n ApplyAnd(control1, control2, target);\n X(target);\n }\n }\n}\n"
81
81
  }
82
82
  ];
@@ -312,6 +312,40 @@ module.exports.get_qir = function(code) {
312
312
  }
313
313
  };
314
314
 
315
+ /**
316
+ * @param {string} code
317
+ * @param {string} params
318
+ * @returns {string}
319
+ */
320
+ module.exports.get_estimates = function(code, params) {
321
+ let deferred4_0;
322
+ let deferred4_1;
323
+ try {
324
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
325
+ const ptr0 = passStringToWasm0(code, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
326
+ const len0 = WASM_VECTOR_LEN;
327
+ const ptr1 = passStringToWasm0(params, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
328
+ const len1 = WASM_VECTOR_LEN;
329
+ wasm.get_estimates(retptr, ptr0, len0, ptr1, len1);
330
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
331
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
332
+ var r2 = getInt32Memory0()[retptr / 4 + 2];
333
+ var r3 = getInt32Memory0()[retptr / 4 + 3];
334
+ var ptr3 = r0;
335
+ var len3 = r1;
336
+ if (r3) {
337
+ ptr3 = 0; len3 = 0;
338
+ throw takeObject(r2);
339
+ }
340
+ deferred4_0 = ptr3;
341
+ deferred4_1 = len3;
342
+ return getStringFromWasm0(ptr3, len3);
343
+ } finally {
344
+ wasm.__wbindgen_add_to_stack_pointer(16);
345
+ wasm.__wbindgen_export_2(deferred4_0, deferred4_1, 1);
346
+ }
347
+ };
348
+
315
349
  /**
316
350
  * @param {string} name
317
351
  * @returns {string | undefined}
@@ -19,6 +19,12 @@ export function git_hash(): string;
19
19
  */
20
20
  export function get_qir(code: string): string;
21
21
  /**
22
+ * @param {string} code
23
+ * @param {string} params
24
+ * @returns {string}
25
+ */
26
+ export function get_estimates(code: string, params: string): string;
27
+ /**
22
28
  * @param {string} name
23
29
  * @returns {string | undefined}
24
30
  */
Binary file
@@ -19,6 +19,12 @@ export function git_hash(): string;
19
19
  */
20
20
  export function get_qir(code: string): string;
21
21
  /**
22
+ * @param {string} code
23
+ * @param {string} params
24
+ * @returns {string}
25
+ */
26
+ export function get_estimates(code: string, params: string): string;
27
+ /**
22
28
  * @param {string} name
23
29
  * @returns {string | undefined}
24
30
  */
@@ -359,6 +365,7 @@ export interface InitOutput {
359
365
  readonly setLogLevel: (a: number) => void;
360
366
  readonly git_hash: (a: number) => void;
361
367
  readonly get_qir: (a: number, b: number, c: number) => void;
368
+ readonly get_estimates: (a: number, b: number, c: number, d: number, e: number) => void;
362
369
  readonly get_library_source_content: (a: number, b: number, c: number) => void;
363
370
  readonly get_hir: (a: number, b: number, c: number) => void;
364
371
  readonly run: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
@@ -309,6 +309,40 @@ export function get_qir(code) {
309
309
  }
310
310
  }
311
311
 
312
+ /**
313
+ * @param {string} code
314
+ * @param {string} params
315
+ * @returns {string}
316
+ */
317
+ export function get_estimates(code, params) {
318
+ let deferred4_0;
319
+ let deferred4_1;
320
+ try {
321
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
322
+ const ptr0 = passStringToWasm0(code, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
323
+ const len0 = WASM_VECTOR_LEN;
324
+ const ptr1 = passStringToWasm0(params, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
325
+ const len1 = WASM_VECTOR_LEN;
326
+ wasm.get_estimates(retptr, ptr0, len0, ptr1, len1);
327
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
328
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
329
+ var r2 = getInt32Memory0()[retptr / 4 + 2];
330
+ var r3 = getInt32Memory0()[retptr / 4 + 3];
331
+ var ptr3 = r0;
332
+ var len3 = r1;
333
+ if (r3) {
334
+ ptr3 = 0; len3 = 0;
335
+ throw takeObject(r2);
336
+ }
337
+ deferred4_0 = ptr3;
338
+ deferred4_1 = len3;
339
+ return getStringFromWasm0(ptr3, len3);
340
+ } finally {
341
+ wasm.__wbindgen_add_to_stack_pointer(16);
342
+ wasm.__wbindgen_export_2(deferred4_0, deferred4_1, 1);
343
+ }
344
+ }
345
+
312
346
  /**
313
347
  * @param {string} name
314
348
  * @returns {string | undefined}
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "qsharp-lang",
3
3
  "description": "qsharp language package for quantum development",
4
- "version": "1.0.23-dev",
4
+ "version": "1.0.24-dev",
5
5
  "license": "MIT",
6
6
  "engines": {
7
7
  "node": ">=16.17.0"
@@ -19,7 +19,8 @@
19
19
  },
20
20
  "./compiler-worker": "./dist/compiler/worker-browser.js",
21
21
  "./language-service-worker": "./dist/language-service/worker-browser.js",
22
- "./debug-service-worker": "./dist/debug-service/worker-browser.js"
22
+ "./debug-service-worker": "./dist/debug-service/worker-browser.js",
23
+ "./ux": "./ux/index.ts"
23
24
  },
24
25
  "scripts": {
25
26
  "build": "npm run generate && npm run build:tsc",
@@ -31,6 +32,7 @@
31
32
  "type": "module",
32
33
  "files": [
33
34
  "dist",
34
- "lib"
35
+ "lib",
36
+ "ux"
35
37
  ]
36
38
  }
package/ux/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # qsharp-lang/ux
2
+
3
+ This directory contains files in source form to be included in other projects
4
+ to provide UI components. See `vscode/src/webview/webview.tsx` for an example.