You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
/// The maximum allowed error of the input value to the computation (i.e. |x'-x|)
47
45
/// ## epsOut
48
46
/// The maximum allowed error of the output without taking into account the error in input value (i.e. |f'(x')-f(x')|)
49
-
/// ## numSwapBits
50
-
/// The number of bits of the input register that will be used in the SWAP section of the circuits. Another way of looking
51
-
/// at this is that in step in the SELECT section of the circuit in Fig 1c of arXiv:1812.00954, we will encode 2^numSwapBits
52
-
/// encoded
53
47
///
54
48
/// # Example
55
-
/// The following code creates a quantum operation based on `ExpD` in the (inclusive) range from `-5.0` to `5.0` with an input error of `1e-3` and an output error of `1e-4`. It uses `2` SWAP bits for the implementation.
49
+
/// The following code creates a quantum operation based on `ExpD` in the (inclusive) range from `-5.0` to `5.0` with an input error of `1e-3` and an output error of `1e-4`.
56
50
///
57
51
/// ```qsharp
58
52
/// // Create operation from lookup table
59
53
/// let domain = (-5.0, 5.0);
60
54
/// let epsIn = 1e-3;
61
55
/// let epsOut = 1e-4;
62
56
///
63
-
/// let lookup = ApplyFunctionWithLookupTable(ExpD, domain, epsIn, epsOut, 2);
57
+
/// let lookup = ApplyFunctionWithLookupTable(ExpD, domain, epsIn, epsOut);
64
58
///
65
59
/// // Allocate qubits
66
60
/// use input = Qubit[lookup::IntegerBitsIn + lookup::FractionalBitsIn];
// For each input qubit we are using for swap qubits, we want to implement all the swaps
230
-
foriin0..Length(addressRegister)-1{
231
-
// for the ith input qubit, we need to have to swap qubit registers that are 2^i places apart, and we need to do this for every qubit that is 2^(i+1) qubits apart,
232
-
// and we need to swap atotal of 2^l/2^(i+1) registers, where l is the number of output registers. E.g.
// how many address bits do we need for `data`? We do this so that we optimize if Length(data) <= 2^(n-1) and don't have to use all the input qubits in the swap register
letaddressRegisterParts=Partitioned([k, l], addressRegisterFitted); //creates two parts of the array - 1 for the select and 1 for the swaps
322
-
323
-
usedataRegister=Qubit[m*2^l]; //create one register with m*2^l qubits to have all the outputs stored
324
-
325
-
// Now we want to create the data array for the select bit. This means that for the first array, we want all the outputs corresponding to the most sig bits = 00..00, then for the next array 00..01, then 00..10 etc.
326
-
letdataArray=CreatePaddedData(data, nRequired, m, k);
327
-
328
-
// Now we split up the register in to chunks of m
329
-
letchunkedDataRegister=Chunks(m, dataRegister); //Chunks(nElements, array): splits array into chunks, where each chunk has nElements, e.g. Chunks(2, [1, 2, 3, 4, 5, 6]) -> [[1, 2], [3, 4], [5, 6]]
330
-
331
-
// Perform select swap with the (1) dataArray for the select outputs and (2) chunkedDataRegister for the swap targets. We can think about improving the efficiency of these two steps by thinking of the fanout inner and outer controls more carefully.
332
-
within {
333
-
Select(dataArray, addressRegisterParts[0], dataRegister); // apply select using first part of address registers
334
-
SwapDataOutputs(addressRegisterParts[1], chunkedDataRegister); // apply swap using second part of address registers
335
-
} apply {
336
-
ApplyToEachA(CNOT, Zipped(chunkedDataRegister[0], outputRegister)); // apply CNOT from chunkedDataRegister[0] to outputRegister
337
-
}
338
-
}
339
-
}
340
-
341
-
/// # Summary
342
-
/// Helper function that creates a list of binary numbers were each number is a concatination of all the possible outputs of each
343
-
/// select function (i.e. combining all the possible outputs into a single bitstring which will then be used in the swap bit of the
344
-
/// select-swap)
345
-
///
346
-
/// # Input
347
-
/// ## data
348
-
/// The list of output values in bits in order, where the first value is the output for the value 00...0 and
349
-
/// the last value is the output for the value the largest integer value
350
-
/// ## nRequired
351
-
/// Minimum number of address bits required to ensure the largest data point can be stored
352
-
/// ## m
353
-
/// Size of final single output of lookup table
354
-
/// ## k
355
-
/// Number of bits from input that will be used in the select part
356
-
internalfunctionCreatePaddedData(data : Bool[][], nRequired : Int, m : Int, k : Int) : Bool[][] {
357
-
letdataPadded=Padded(-2^nRequired, [false, size=m], data); // Padded so that we don't have problems for powers of 2
358
-
mutabledataArray= [[], size=2^k];
359
-
foriin0..2^k-1 {
360
-
letrange=RangeAsIntArray(i..2^k..2^nRequired-1); // RangeAsIntArray(range) takes a Range and returns Int[], e.g., 1..3 -> [1, 2, 3], 1..3..9 -> [1, 4, 7]. In our case, for i=0 -> [0, 2^k, 2*2^k...]
361
-
setdataArrayw/=i<-Flattened(Subarray(range, dataPadded)); // Subarray(indices, array) takes indices Int[] and returns subarray of array subject to indices
0 commit comments