当前位置:网站首页>Q_04_07 进一步探索
Q_04_07 进一步探索
2022-08-09 13:02:00 【MOVCat】
现在您已经看到了如何在Q#中编写有趣的量子程序,本节将进一步介绍几个更高级的主题,这些主题将在未来发挥作用。
通用操作和功能
我们可能希望定义的许多函数和操作实际上并不严重依赖于它们的输入类型,而只是通过其他函数或操作隐式地使用它们的类型。例如,考虑许多功能语言通用的地图概念;给定函数f(x)
和值集合x1,x2, dots,xn,map将返回一个新的集合f(x1),f(x2), ...,f(xn)。为了在Q#中实现这一点,我们可以利用这个功能是一流的。我们来写一个Map
的快速示例,使用*作为占位符,并找出我们需要的类型。
function Map(fn : * -> *, values : *[]) : *[] {
mutable mappedValues = new *[Length(values)];
for (idx in 0..Length(values) - 1) {
set mappedValues[idx] = fn(values[idx]);
}
return mappedValues;
}
注意,无论我们替换的实际类型如何,该函数看起来都非常相似。例如,从整数到Paulis的映射看起来与从浮点数到字符串的映射非常相似:
function MapIntsToPaulis(fn : Int -> Pauli, values : Int[]) : Pauli[] {
mutable mappedValues = new Pauli[Length(values)];
for (idx in 0..Length(values) - 1) {
set mappedValues[idx] = fn(values[idx]);
}
return mappedValues;
}
function MapDoublesToStrings(fn : Double -> String, values : Double[]) : String[] {
mutable mappedValues = new String[Length(values)];
for (idx in 0..Length(values) - 1) {
set mappedValues[idx] = fn(values[idx]);
}
return mappedValues;
}
原则上,我们可以为遇到的每一对类型编写一个Map
版本,但这会带来一些困难。例如,如果我们在Map
发现一个错误,那么我们必须确保修补程序在所有版本的Map
统一应用。而且,如果我们构造一个新的元组或UDT,那么现在我们还必须构建一个新的Map
来与新类型一起使用。虽然这对于少数这样的功能来说是容易处理的,但是由于我们收集了与Map
相同形式的越来越多的功能,所以引入新类型的成本在相当短的时间内变得不合理地大。
但是,这种困难的结果很多,因为我们没有给出编译器所需的信息来识别不同版本的Map
是如何相关的。实际上,我们希望编译器将Map
视为某种从Q# 类型到Q#函数的数学函数。这个概念通过允许函数和操作具有类型参数以及它们的普通元组参数来形式化。在上面的例子中,我们希望将Map
视为具有类型参数Int, Pauli
在第一种情况下为Int, Pauli
Double, String
在第二种情况下为Double, String
。大多数情况下,这些类型参数可以像使用普通类型一样使用:我们使用类型参数的值来创建数组和元组,调用函数和操作,并将其分配给普通变量或可变变量。
Tip
间接依赖的最极端情况是量子比特,其中Q#程序不能直接依赖Qubit
类型的结构,但必须将这些类型传递给其他操作和函数。
回到上面的例子,我们可以看到我们需要Map
有类型参数,一个表示fn
的输入,一个表示fn
的输出。在Q#中,这是通过在声明中的函数或操作的名称后添加尖括号(即<>
,不包括 braket
!),并列出每个类型参数来编写的。每个类型参数的名称必须以“tick '
开头,表示它是一个类型参数,而不是普通类型(也称为具体类型)。因此,对于Map
,我们写道:
function Map<'Input, 'Output>(fn : 'Input -> 'Output, values : 'Input[]) : 'Output {
mutable mappedValues = new 'Output[Length(values)];
for (idx in 0..Length(values) - 1) {
set mappedValues[idx] = fn(values[idx]);
}
return mappedValues;
}
请注意, Map<'Input, 'Output>
的定义与我们之前写出的版本非常相似。唯一的区别是我们已经明确告知编译器, Map
并不直接依赖于'Input
'Output
和'Output
,而是通过fn
间接使用它们来适用于任何两种类型。一旦我们以这种方式定义了Map<'Input, 'Output>
,我们就可以把它称为一个普通的函数:
// Represent Z₀ Z₁ X₂ Y₃ as a list of ints. let ints = [3; 3; 1; 2]; // Here, we assume IntToPauli : Int -> Pauli // looks up PauliI by 0, PauliX by 1, so forth. let paulis = Map(IntToPauli, ints);
Tip
编写泛型函数和操作是一个地方,“元组元组”是考虑Q#函数和操作的非常有用的方法。由于每个函数只需要一个输入并返回一个输出,所以类型'T -> 'U
的输入与任何 Q#函数都匹配。同样,任何操作都可以传递给'T => 'U
类型的输入。
作为第二个例子,考虑编写一个返回另外两个函数组合的函数的挑战:
function ComposeImpl(outerFn : (B -> C), innerFn : (A -> B), input : A) : C {
return outerFn(innerFn(input));
}
function Compose(outerFn : (B -> C), innerFn : (A -> B)) : (A -> C) {
return ComposeImpl(outerFn, innerFn, _);
}
在这里,我们必须明确指出A
, B
和C
是什么,因此严重限制了我们新的Compose
函数的效用。毕竟, Compose
只依赖于A
, B
和C
通过innerFn
和outerFn
。然后,作为替代,我们可以将类型参数添加到Compose
,以表明它适用于任何A
, B
和C
,只要这些参数与innerFn
和outerFn
所期望的匹配:
function ComposeImpl<'A, 'B, 'C>(outerFn : ('B -> 'C), innerFn : ('A -> 'B), input : 'A) : 'C {
return outerFn(innerFn(input));
}
function Compose<'A, 'B, 'C>(outerFn : ('B -> 'C), innerFn : ('A -> 'B)) : ('A -> 'C) {
return ComposeImpl(outerFn, innerFn, _);
}
提供Q#标准库的canon提供了一系列这种类型参数化的操作和功能,以便更容易地表达高阶控制流。这些将在Q#标准库指南中进一步讨论。
借用Qubits
借用机制允许分配在计算过程中可用作临时空间的量子位。这些量子位通常不处于干净状态,即它们不一定以已知状态(例如 ket0
)初始化。人们也会说“脏”的量子位,因为他们的状态是未知的,甚至可能与量子计算机存储器的其他部分纠缠在一起。众所周知的脏量子比特的使用情况是多重控制的CNOT门的实现,其只需要很少的量子位和实现增量。
在canon中有一些使用borrowing
关键字的例子,例如下面定义的MultiControlledXBorrow
函数。如果controls
表示应该添加到X
操作的控制量子位,那么通过该实现将添加总体的Length(controls)-2
许多脏的添加。
operation MultiControlledXBorrow ( controls : Qubit[] , target : Qubit ) : () {
body {
... // skipping some case handling here
let numberOfDirtyQubits = numberOfControls - 2;
borrowing( dirtyQubits = Qubit[ numberOfDirtyQubits ] ) {
let allQubits = [ target ] + dirtyQubits + controls;
let lastDirtyQubit = numberOfDirtyQubits;
let totalNumberOfQubits = Length(allQubits);
let outerOperation1 =
CCNOTByIndexLadder(
numberOfDirtyQubits + 1, 1, 0, numberOfDirtyQubits , _ );
let innerOperation =
CCNOTByIndex(
totalNumberOfQubits - 1, totalNumberOfQubits - 2, lastDirtyQubit, _ );
WithA(outerOperation1, innerOperation, allQubits);
let outerOperation2 =
CCNOTByIndexLadder(
numberOfDirtyQubits + 2, 2, 1, numberOfDirtyQubits - 1 , _ );
WithA(outerOperation2, innerOperation, allQubits);
}
}
adjoint auto
controlled( extraControls ) {
MultiControlledXBorrow( extraControls + controls, target );
}
controlled adjoint auto
}
请注意,在此示例中广泛使用了With
combinator ---以适用于支持伴随操作的形式(即WithA
---),这是一种良好的编程风格,因为将控制添加到涉及仅将传播控件内部操作。还要注意的是,除了操作的主体之外,明确提供了操作的controlled
机构的实现,而不是诉诸于controlled auto
语句。原因在于我们从电路结构中知道如何轻松添加进一步的控制,这与将控制添加到body
中的每个单独门控相比是有益的。
将此代码与另一个canon函数MultiControlledXClean
进行比较是MultiControlledXClean
,它实现了实现乘法控制的X
操作的相同目标,然而,它使用using
机制的几个干净的量子位。
应该注意的是,只有这样的量子位才能在操作范围内借用到,而操作还不在操作范围内,否则编译器会引发异常。
边栏推荐
- FFmpeg multimedia file processing (the basic concept of ffmpeg processing stream data)
- puzzle(016.5)逻辑电路
- Yocto 可以下载的第三方库
- 绘制混合密度函数图以及添加分位数线
- gin的中间件和路由分组
- 第六届”蓝帽杯“全国大学生网络安全技能大赛 半决赛
- R language kaggle game data exploration and visualization
- Bitmaps and bit operations
- GIN中GET POST PUT DELETE请求
- 乐东消防救援大队应邀为干部开展消防安全培训
猜你喜欢
npm install失败
#WeArePlay | 与更多开发者一起,探索新世界
GIN文件上传与返回
GET POST PUT DELETE request in GIN
jenkins api create custom pipeline
电脑重装系统还原0x80070005错误如何解决
Oracle Recovery Tools修复空闲坏块
搭建大型分布式服务(四)Docker搭建开发环境安装Mysql
关于做2D游戏时,Canvas边界显示在Game窗口的问题
How to reduce the size of desktop icons after the computer is reinstalled
随机推荐
七夕力扣刷不停,343. 整数拆分(剑指 Offer 14- I. 剪绳子、剑指 Offer 14- II. 剪绳子 II)
Oracle Recovery Tools修复空闲坏块
Draw a histogram with plot_hist_numeric()
The sword refers to the offer, cuts the rope 2
Deep Learning Based on R Language - Simple Regression Case
Ledong Fire Rescue Brigade was invited to carry out fire safety training for cadres
搭建大型分布式服务(四)Docker搭建开发环境安装Mysql
Sandbox中的进程/线程相关-1
GET POST PUT DELETE request in GIN
NFS pays special attention to the problem of permissions
GIN Bind mode to get parameters and form validation
剑指 Offer 43. 1~n 整数中 1 出现的次数(递归、数学)
FPGA中串口通信的时钟频率和波特率计数
read stream special attention
周末看点回顾|我国IPv6网络全面建成;2022昇腾AI开发者创享日·南京站成功举办…
[FPGA Tutorial Case 48] Image Case 8 - Realization of Converting RGB Image to HSV Image Based on FPGA, Assisted Verification by MATLAB
陈强教授《机器学习及R应用》课程 第十四章作业
WPF 实现带蒙版的 MessageBox 消息提示框
render解析
Uni - app - uview Swiper shuffling figure component, click on the links to jump (click to get the item after the row data, remove data operation)