工作报告的写作方式

经常需要把ideas、半成品的工作、已经完成的工作整理出来,供后来人使用,就形成了工作报告的一个八股形式。忽然发现,学生没学会,尽管我已经分享过多次这样的报告。所以,整理一下,供学生使用。

  1. 工作报告,首先要交代研究问题。如果有必要也可以对研究问题稍微解释一下,加一点点背景。
  2. 然后,要交代大概研究思路。如果有必要也可以加一点点背景,说一下其他人怎么研究这个问题,做了什么,结论如何。
  3. 接着,在每一个阶段,交代我们做了什么,这个做了的事情能够如何回答一开始的研究问题。
  4. 再接着,要交代下一步做什么,为什么。
  5. 最后,是参考文献和文章草稿。如果有必要也可以附上实验记录和分析程序。

获取sci-hub数据

sci-hub是学术论文检索网站,提供了从文章doi等信息找到文章下载地址(这些地址又被libgen网站收集和保存)的信息。当然,这些文章基本上是有版权的。因此,实际上sci-hub和libgen是法律的边缘:没有直接保存原文(有的文件可能有原文,不清楚),但是提供了原文下载地址的集合。不过,我真的很喜欢这个网站的理念:知识应该属于全人类,应该尽量方便大家的获取。当然,也应该给写作、制作和出版这些知识的载体——也就是文章和书——的人一些利益。所以,我自己的文章和书的处理方式是在网上免费提供没有经过出版社处理的全文,但是经过出版社处理的文档,我不管。

最近纯粹出于好奇和学术研究兴趣,想看看sci-hub和libgen这个网站在促进学术交流上的效果,还想顺便用来匹配一下一堆我们自己有的文章的doi,就去找了找下载获取sci-hub和libgen数据的方法

首先,这个数据分成三个部分:第一、保存下载地址的文件,通常是torrent文件。第二、保存文章题录数据(metadata)的文件,通常是MySQL database dump文件。第三、提供这个网站的服务的源程序。第三部分仅仅在制作镜像的时候需要使用,就不需要下载了。这三部分文件都可以直接从libgen的主页上获取。

其次,获取了文件之后,需要从torrent文件的信息里面来下载和存储相应的文件。

接着,需要把题录数据和下载的文章对应整合起来。

最后,内部使用,也可以把libgen的服务系统建起来,或者自己做一个检索系统。

ProjectQ和IBMQ量子计算机

IBMQ提供了使用量子计算机的接口,ProjectQ用Python语言提供了一套量子计算描述语言,能够用于包含IBMQ真实量子计算机以及量子的经典模拟(通过算符运算)在内的多个后台。

由于教学(让学生做习题并且能够在实际量子计算机上验证)和研究(考虑量子博弈的真人实验)的需要,需要用量子计算机。就学习了一下。发现,非常简单易用,也很有系统性。

首先,在量子计算中,最基本的量子单位是自旋。于是,自旋的状态(二维Hilbert空间矢量)和算符(二维Hilbert空间矢量上的算符,例如Pauli矩阵、Hadamard门、围绕Z轴的旋转、测量等),就是这个ProjectQ的基本单元。当然,一些常用的高级功能例如CNOT门,以及Hadamard门和CNOT合起来的作用——称作纠缠算符等,也在ProjectQ中做了实现。

具体的文档见ProjectQIBMQ上的说明。下面用一个例子来说明一下整体结构,这样以后再一次学习起来简单。

这是我试着编写的程序quantum.py:

  1. 导入后台(模拟器、IBMQ、tex)和算符(H、测量、CNOT)

  2. from projectq import MainEngine
    from projectq.ops import H, Measure, CNOT
    from projectq.backends import CircuitDrawer
    import projectq.setups.ibm
    from projectq.backends import IBMBackend

  3. 这部分接收程序运行参数,在这里就是决定用什么后台。

  4. import sys, getopt

    def main(argv):
    s=1 #indicator of running this program via simulator or not
    tex=0 #indicator of converting this program into tex or not
    IBMQ=0 #indicator of running this program via IBMQ or not
    #take parameters from command-line input
    try:
    opts, args = getopt.getopt(argv, "s:", ["tex=", "IBMQ="])
    except getopt.GetoptError:
    print ("Error: please use the command as quantum.py -s --tex --IBMQ ")
    sys.exit(2)
    for opt, arg in opts:
    if opt == "-h":
    print("quantum.py -r --tex --IBMQ ")
    sys.exit()
    elif opt =="-s":
    s = int(arg) #when s=1, we need to run this program via simulator
    elif opt == "--IBMQ":
    IBMQ = int(arg) # when tex=1, we need to convert this program into a tex file
    s = 0 #when tex=1, we set s=0 (not to run this program in force)
    elif opt == "--tex":
    tex = int(arg) # when tex=1, we need to convert this program into a tex file
    s = 0 #when tex=1, we set s=0 (not to run this program in force)
    IBMQ = 0 #when tex=1, we set IBMQ=0 (not to run this program in force)
    #parameter input ends here

  5. 按照运行参数,开辟一个针对相应后台的环境。在这个环境之上,所有的命令不再需要关心后台的问题。

  6. # create a main compiler engine
    if(tex):
    drawing_engine = CircuitDrawer()
    eng = MainEngine(drawing_engine)
    elif(s):
    eng = MainEngine()
    elif(IBMQ):
    eng = MainEngine(IBMBackend(use_hardware=True, num_runs=1024, verbose=False, device='ibmqx4'))
    # allocate 2 qubit

  7. 在环境里面初始化qubit,并且把需要的算符一个个作用到这些个qubit上。

  8. qunum = eng.allocate_qureg(2)

    # put qubit 1 in superposition
    H | qunum[0]
    # put the two qubit in engtanglement
    CNOT | (qunum[0],qunum[1])
    # measure
    Measure | (qunum[0],qunum[1])

  9. 运行这些初始化状态和算符。

  10. eng.flush()

  11. 输出结果。

  12. if(tex):
    print(drawing_engine.get_latex())
    if(s):
    print("q1={}".format(int(qunum[0])))
    print("q2={}".format(int(qunum[1])))
    if(IBMQ):
    # access the probabilities via the back-end:
    results = eng.backend.get_probabilities(qunum)
    for state in results:
    print("Measured {} with p = {}.".format(state, results[state]))
    # return one (random) measurement outcome.
    return [int(q) for q in qunum]

最后运行python quantum.py就可以在不同的后台运行了。如果需要在IBMQ上运行,需要IBMQ的帐号和密码。

数学和科学、生活

今天这个例子就发生在上一个帖子的作者——一个差不多懂了系联性思考的硕士学生身上。同样非常有借鉴意义。我整理出来,分享在这里。

我用doodle设立了一个投票来确定这个学期的研究小组讨论时间。需要每一个参与讨论的人来参加这个投票,提供对自己来说可以实现的时间,然后,doodle就会做好一张网页表格,把每一个选项放在列上,每一个参与者的选择放在行上。我这个创建投票的人只需要看这张表就可以确定一个对所有人或者大多数人都能够用的时间了。

然后,这个学生选了三个选项。我就很好奇。问:为什么这样选啊?具体选择什么当然我也关心,不过我更好奇为什么这样选,真的只有这三个时间是可行的对这个学生来说?经过一番努力的沟通,发现,这个学生是这样来理解这个投票的。所谓投票就是在一堆选项中选自己最喜欢的,然后,最后,统计每一个选项有多少人喜欢,创建人选择得票最多的就行了。

确实,一般的称为“投票”的东西确实如此。

然后,学生意识到,可能我这么问,则表示这个背后的确定最后的选项的过程可能并不是这样。就说,我觉得可能这个doodle的程序不是这样运作的,得去想想这个程序如何运作。

另两个学生这时候提示,确定讨论时间的运算,实际上是在做集合的交集:把每一个参与者的集合拿过来,计算所有人的交集。

于是,首先,这个程序背后的算法不用去猜的,那就是计算交集,而且这个计算的人,就是我,doodle仅仅提供这张大表而已。

其次,更加根本的问题是,数学描述、数学计算过程或者软件系统背后的算法,都是为了解决某个具体问题的。我们只需要从问题开始思考,而不是从计算过程、软件算法开始思考。如果这个算法或者过程不能解决这个问题,那么,是算法和过程错了,而不是问题错了。

在具体这个问题上,就是你只需要思考确定一群人讨论的时间是什么样一个问题就可以了:由于首先的要求是要找到满足绝大多数人的选项,而不是选择所有人合起来最喜欢的选项,集合的并是最好的数学描述,而不是数票数。当然,如果每一个参与者把自己的喜好完全地揭示出来,则数票数和求集合的并是等价的。但是,一旦参与者用数票数的思路来提供信息——也就是仅仅选择自己最喜欢的选项而不是所有可能的选项(当然,将来还可以做更复杂的赋权),则两者就不等价了。结果上,很有可能这个参与者的最喜欢的选项被完全忽视。

因此,除了没有从问题开始思考,从情景开始思考,而是去猜背后可能的计算过程或者算法,还有另一个层面的问题:套路。当一个学生面对一个叫做“投票”的问题的时候,很可能就会直接套用投票的思路,而不去思考实际问题和情景。套路,真的要不得啊。面对任何具体问题,都要去思考,这个问题中有哪些因素,这些因素决定了我们必须用什么样的计算或者分析,而不是生搬硬套。

后来,我发现,这样来做会议时间投票的人还不少。看来,看不到“数学就是对问题和思考的表达,对问题里面的关系的描述”的人,还是真不少啊。可能大多数人的思考方式,真的是套路——先看看有没有一个自己知道如何应对的相似的,尽管可能仅仅是名以上、名字上相似,而不是关系上相似,问题,然后把这个问题里面的应对方式直接照搬过来。

顺便,关于这个问题,我们正在设计一个实验研究:一个情景A,一个情景B,两者具有一定相似性,但是,如果真的想明白则两者不一样,而且,我们保证实验参与者真的两者都是之前就了解的,甚至教过的学过的,然后我们来让实验参与者做决策。在这里,我们想探讨两个问题,知道(学过的能通过考试的)到能用(能够面对实际情景)的距离,以及基于套路而不是基于理性思考的决策的普遍性。将来我来报高这个研究结果。

用这个例子,来体现什么是数学,以及数学和科学、生活的关系。

研究和教学中的数学建模

提出问题,把问题转化成一个数学问题是科学研究中非常非常重要的两步。当然,解决问题和检验,也是重要的,不过,我认为比不上前者。把一个问题用合适的数学结构来表达,需要考虑这个问题内在的结构——也就是这个问题里面有哪些关键因素,这些关键因素之间有什么关系,这个系统的状态如何描述,如果有变化呢,则还关心如何变化、什么导致的变化。而这一步,传统上,叫做数学建模。

采用什么样的数学结构来描述所面对的系统的状态,这是数学建模要解决的第一个问题。理想情况,我们希望这个表示是忠实的:任何这个系统的状态都可以用这个数学结构来描述,任何这个数学结构的状态都在所面对的系统上找得到对应的状态;任何一个对这个状态的操作,正好对应这个数学结构上的一种映射;任何一个这个数学结构上的映射,正好对应着对这个实际系统的一个操作。当然,这样的理想情况一般是做不到的,这个时候,我们只要在我们关心的范围内满足上面的忠实性就可以,甚至只要近似地满足忠实性就可以。

于是,这个时候,我们自然要通过了解系统的状态,以及可能的对这些状态的操作,来寻找合适的数学结构。另一方面,我们也必须考虑,某一个在这个数学结构上能够做的计算,对应着什么样的实际系统的性质或者操作。

实际上,我认为,大多数时候,理论科学家,尤其是理论物理学家、系统科学研究者,都在做这样的数学建模的事情。因此,我也打算什么时候来建设一门数学建模的课程。实际上,这个帖子就是供我自己慢慢整理,形成一个这样的课程用的。当然,也非常欢迎有人给我提供线索。

比如说,量子系统的数学模型——以Hilbert空间矢量为基础的量子力学,就是这样的数学模型的极好的例子。当然,经典力学的质点——刚体——弹性体——流体也是,甚至背后的确定性方程——随机性方程也是。不过,有一些可能需要比较多的数学和物理的基础,不一定适合当做数学建模的例子。

网络科学的例子应该有很多,例如网络上的传染病模型,以及我们自己的汉字学习和检测的工作,广义投入产出分析的工作等。另外,昨天偶然得到一个很好的小例子:一个学生在计算地铁网络在攻击下的抗毁能力,主要通过攻击之后剩下的最大连通集团的大小来当指标;这个时候,一个自然的问题就是,为什么选择这个指标是有实际意义的,在实际问题中意味着什么,如果要让这个指标有实际意义我们需要做什么假设,这个假设是否具有合理性。在实际问题中,这样的思考往往就能够创新性的来源,并且这也是任何数学模型必须解决的问题——为了这个表示具有合理的“忠实性”,我们的假设是什么,数学结构和实际对象之间的联系是什么。

有了这个大原则——数学建模就是找到能够忠实或者近似忠实地表示实际系统的数学结构,我们还有一些更小的典型思维方式。比如说,数学建模更多的是艺术,而不是技术,尽管我们会非常努力地技术化一般化。因此,在教和学数学建模的过程中,就必须采用欣赏、临摹、创作的方式,而不是做大量的习题求解的方式。再比如说,数学建模不应该按照模型解法来分类教学,而是按照建模的思想,建模所需要的思维方式来做教学。更多的其他思维方式以后再整理,或者等遇到合适的例子再总结在这里。

基于这个数学建模的典型思维方式的重要性,在系统科学和物理学导论里面,都应该增加一小节关于数学模型的介绍、讨论和欣赏,除了专门开设数学建模课程之外。其实,这个小节比较简单,只需要用之前讲过的例子,但是从数学模型的角度来再一次欣赏和讨论一下就可以,而且可以放在数学和科学的关系那个大标题下面。

顺便,数学模型应该由科学家来教,而不是数学家。当然,非常厉害的数学家是能够看到数学和实际问题之间的联系的,也是受实际问题启发的。这方面可以看看Gowers的《Mathematics, a very short introduction》,或者丘成桐、陶哲轩对这个问题的讨论。不过大多数数学家就会进入某一个已经数学化形式化的问题里面去做。这也是由数学的特性决定的——严密的逻辑演绎在数学里面的特殊重要性:不想科学还可以实践检验,数学就只能检验内在自洽性,于是自然也就更强调严密。因此,这个不是数学家或者数学的缺陷,而是自然使然。那么,谁来教数学建模?科学家,有具体领域背景的科学家和没有具体领域背景的计算机科学家,一起来完成。