版本12——Wolfram语言和Mathematica的一次飞跃

(本文译自Stephen Wolfram于英文12.0版发布日2019年4月16日的博客。版本12不仅囊括了拿破仑定理,还有Wolfram公理以及欧几里得所著《几何原本》一书中所涉及的几何问题, N 体问题;机器学习、神经网络、图像处理、语音识别、NLP等AI功能,并集成Wolfram|Alpha的诸多功能;计算化学、大地测量学、大型数据库的处理、丰富的Wolfram知识库、提速数值优化、非线性有限元分析、与Python的接口、高级编译器、Wolfram Super Shell、操纵网页、独立的微控制器;与Unity游戏的集成,实现VR/AR 以及机器仿真环境;集成彭博和路透社的金融数据,支持Bloomberg Terminal服务,区块链等等等。)

通往版本12之路

今天(4/16/2019),我们将在桌面平台和Wolfram Cloud上发布Wolfram语言(和Mathematica)第12版。我们在2016年8月发布了11.0, 2017年3月发布了11.1,2017 年9月发布了11.2, 2018年3月发布了11.3。而从版本11.3到版本12.0,这是一次质的飞跃。最新版本共有278个全新函数,范围涉及约103个领域,以及遍及系统内部的数千个不同的更新:

在像版本12这样的“ 整数版本 ”中,我们的目标是填补全新的功能领域。但我们同时希望在每个版本中及时推出我们的最新研发成果。因此,在12.0的新函数中,大约有一半可以被认为是对之前“.1”版本中原有函数的完美收官,而另一半则开辟了新的领域。我将在这篇文章中对这两种类型的函数进行讨论,但重点将是从11.3到12.0的新功能。

回顾12.0从11.3一路走来,我不由得为它的功能之深之广感到惊叹。去年十月在Wolfram技术大会的主旨演讲中,我曾用将近4个小时总结了我们到当时为止所做的工作。现在要说的还有更多。

我们能够做的就是证明我们研发工作的实力,以及Wolfram语言作为开发环境的有效性。当然,这两点我们已经做了三十年。但是12.0的一个新特点是我们把幕后设计流程展示在了世人面前 - 我在内部设计会议中进行了300多个小时的直播。因此,除了功能之外,此举应该也开辟了软件开发之先河,使得版本12.0成为首个以这种方式开放的主要软件版本。

12.0汇集了很多令人叹为观止的重大突破,特别是在化学、几何、数值不确定性和数据库集成方面。总的来说,新功能涉及很多领域。事实上,即使参考文档中心的基本摘要已经有19页了:

欲了解Wolfram软件更多信息请联系 wolframchina@wolfram.com 或 Wolfram 的中国代理商

首先,数学方面

尽管对于现在的Wolfram语言(和Mathematica)而言,数学方面的功能仅是其众多功能的冰山一角,但我们仍然对此投入了巨大的研发力量。作为我要介绍的第一个例子,这里是多姿多彩的ComplexPlot3D

通过编写Wolfram语言代码在复平面上绘制图形是一直就有的功能。但是直到现在我们才终于解决了在复平面自动绘制病态函数过程中所涉及的数学和算法问题。

几年前,我记得绘制二重对数函数及其实部和虚部是多么困难。而现在用ReImPlot就可以轻松实现:

复函数的可视化说来话长,细节对于人们认识一个函数很重要。因此,我们在12.0中所做的一件事就是精心挑选所引入的标准化方法(例如命名的颜色函数),来突出显示不同的功能:

不确定性的微积分

现实世界中的测量值通常具有不确定性,用带有±误差的值来表示。我们早就有了用于处理这种“带误差值”的附加软件包。但是在版本12.0中,我们可以对这种不确定性进行计算,并且我们正在做正确的事情。

这一功能的关键是符号式对象Around[x, δ],它表示“x周围”的值,其不确定性为δ:

你可以对Around进行代数运算,对于不确定性的组合有一整套计算:

如果对Around数绘图,误差条也会随之显示:

有很多选项可用,比如这是同时显示x 和y不确定性的一种方法:

Around 可以带有单位:

也可以有符号式Around对象:

但究竟什么是Around对象?它是一种基于不相关的正态分布的东西,里面存在某些组合不确定性的规则。但没有任何声明表明Around[x, δ]代表实际遵循正态分布的任何事物,它不过是由Interval[{x - δ, x + δ}]定义的区间上的一个数。只是Around对象根据一致的一般规则传播他们的误差即不确定性,这些规则成功实现了实验科学通常所做的事情。

比方说,你对某个值进行了一组测量。你可以使用MeanAround来估算值及其不确定性(是的,如果测量值本身具有不确定性,则在对其贡献进行加权时将考虑这些因素):

整个系统的函数——特别是在机器学习中——开始出现选项ComputeUncertainty->True,这使得它们给出Around对象而不再是纯数字。

Around可能看起来像一个简单的概念,但它充满了微妙之处 - 这是它直到现在才被纳入入系统的主要原因。许多微妙之处围绕着不确定性之间的相关性。基本思想是假设每个Around对象的不确定性是独立的。但有时候一个值具有相关的不确定性——因此除了Around,还有VectorAround,它表示具有指定协方差矩阵的潜在相关值的向量。

当处理像代数公式这样的事情时,会更加微妙。如果用一个Around替换x ,那么,按照Around的规则,假设每个实例都是不相关的:

但是可能有人想在这里假设,即使x的值可能是不确定的,它对于每个实例都是相同的,并且可以使用函数AroundReplace来做到这一点(注意结果是不同的):

如何显示不确定的数字也值得推敲,就像应该输入多少尾随0:

或者应该包括多少精度的不确定性(当尾随数字是35时有一个传统的断点):

在少数情况下,大量数值已知(例如一些物理常数),人们想要采用不同的方式来指定不确定性:

这种例子不胜枚举。但渐渐地,Around将开始出现在整个系统中。顺便说一下,还有很多其他方法来指定Around数。这是一个相对误差为10%的数:

这是Around最擅长的表示区间:

对于分布,Around计算方差:

它还可以通过给出不对称的不确定性来考虑不对称性:

初级和高级经典数学

在进行数学计算时,在保证完全正确的同时而不迷惑或吓退初学者始终是一个挑战。版本12.0引入的一些东西可能会有用。首先,尝试求解不可约的五次方程式:

在过去,这会出现一堆显式的Root对象。但现在Root对象被格式化为显示其近似值的框体。计算工作完全相同,但这种显示效果让人们不用立即面对必须知道的代数数字。

当我们说Integrate时,我们的意思是在不定积分的意义上,“求一个积分”。但是在初等微积分中,人们希望看到显式的积分常数(因为它们总是在Wolfram|Alpha中),所以我们为它添加了一个选项(并且C[n]也有一个很好的新输出形式):

当我们对符号式积分功能进行基准测试时,结果非常理想。但总有更多的事情可以做,特别是在求最简积分形式方面(在理论层面,这是符号表达等价的不可判定性的必然结果)。在版本12.0中,我们继续在前沿探索,添加了如下情形:

在版本11.3中,我们引入了渐近分析,能够求积分的渐近值等。版本12.0增加了方程的渐近求和,渐近递归和渐近解:

在数学计算方面进行的研发,为我们提供了解释数学本身的新方法。我们一直在努力提升参考文档中心的实用性,使之不仅用来诠释函数用法,而且能够解释数学概念本身。例如,这是关于极限Limit的文档开篇,对核心数学思想的解释可以说是图文与示例并茂:

多边形更多功能

多边形是自版本1以来便是Wolfram语言的一部分。但是在版本12.0中,多边形得到进一步推广和延申:现在设有一种系统方法来指定多边形上的孔洞。一个典型的地理用例是南非,其中,国中国莱索托是南非多边形上的洞。

在版本12.0中,与Root相似, Polygon也有一种方便的新显示形式:

可以像以前一样进行计算:

RandomPolygon也是新的。例如,你可以在3D中得到5个随机凸多边形,每个多边形有10个顶点:

对多边形的运算也有很多新增功能。比方说PolygonDecomposition可以将多边形拆分为多个小的凸多边形:

带孔的多边形也需要其他类型的运算,如OuterPolygonSimplePolygonQCanonicalizePolygon等。

用多面体计算

多边形的指定非常简单:您只需按顺序给出其顶点(如果有孔,也可以给出孔的顶点)。多面体则复杂一些:除了给出顶点之外,还必须说明这些顶点是如何形成面的。但是在版本12.0中,Polyhedron可以让你以相当普通的方式做到这一点,包括空洞(即二维空间上孔在三维空间上的对应)等。

但首先,要知道多面体有2000多年的历史,版本12.0引入了五个柏拉图立体的函数:

这些柏拉图立体可以直接计算:

这是在顶点1对着的立体角(因为它是柏拉图式的,所有顶点都给出相同的角度):

这是在多面体上完成的运算:

除了柏拉图式立体之外,版本12还构建了所有“均匀多面体”(每个顶点都有n个边和m个面相交),还可以从PolyhedronData获得已命名多面体的符号多面体版本:

可以制作任何多面体(包括“随机”多面体,通过RandomPolyhedron),然后对其进行各种计算:

可计算的欧氏几何

Mathematica和Wolfram语言在显式计算几何和代数几何方面功能卓越,但是对于欧几里得所著《几何原本》一书中所涉及的几何问题(其中,人们先做出几何断言,然后再看后果)的表现又如何呢?

凭借我们在技术上的积累和布局,第12版终于能够提供一种新的数学计算方式,将欧几里德2000多年前所做的事情自动化。一个关键的想法是引入符号“几何场景”,用符号表示诸如点之类的结构,然后根据它们来定义几何对象和关系。

例如,这是一个几何场景,表示一个三角形abc与一个圆心为o、通过三点a,b,c的圆,其约束是o位于从a到c的线段的中点:

就其本身而言,这只是一个符号表示。但我们可以对它进行运算。例如,我们可以要求它的随机实例,其中a,b,c和o是特定的:

您可以根据需要生成任意数量的随机实例。我们尽量使实例具有一般性,不出现不受约束制约的特殊情况:

好,现在我们来“玩欧几里得”,找到与我们的设置一致的几何猜想:

对于给定的几何场景,可能存在许多可能的猜想。我们试图找出我们感兴趣的。在这种情况下,我们得到两个 - 第一个如图所示:线段ba垂直于线段cb。这个结果恰好出现在《几何原本》在第3卷,作为命题31的一部分,它通常被称为泰勒斯定理。

在12.0中有一套完整的符号语言来表示出现在欧氏几何中的典型事物。这里是一个更复杂的情况,对应于所谓的拿破仑定理:

12.0新增了许多几何函数,可用于显式坐标:

支持12种“中心”类型的三角形,并且可以有符号坐标:

为了支持对几何命题的设定,我们还需要“ 几何断言”。在12.0中有29种不同的类型,例如“Parallel”,“Congruent”,“Tangent”,“Convex”等。这里是三个两两相切的圆:

公理化理论的超级符号化

版本11.3推出了FindEquationalProof,用于生成证明的符号表示。但应该用什么公理进行证明呢?12.0版引入了AxiomaticTheory,给出了各种常见公理化理论的公理。

这是我个人最喜爱的公理系统:

这是什么意思?在一定程度上这意味着更加符号化的符号表示。比如对于 1+x,我们不说x的值是什么,而是想象它可以有一个值。在上面的表达式中,a、b和c是纯“形式符号”,实际上起到的是结构的作用,甚至都不能把它想成具有什么实际值。

中心点·是做什么的呢?在1+x中我们知道加号+的意义。而·则是一个完全抽象的运算符。公理本质上是在·所能表示的事物上定义一个约束。在这个特例中,事实证明该公理是布尔代数的公理,因此·可以代表NandNor。但我们可以完全正式地推导公理的后果,例如通过FindEquationalProof

这其中有很多微妙之处。在上面的例子中,使用中心点·作为运算符很有用,首先因为它的显示美观。但它没有内在的含义,AxiomaticTheory让你给出其他的算符(这里是f) :

"Nand"的作用是什么?它是运算符的名称(但不应将其解释为与运算符的值有任何关系)。例如,在群论的公理中,出现了几个运算符:

这将给出此处各种运算符的默认表示形式:

AxiomaticTheory知道特定公理系统的著名定理:

形式符号的基本思想是在第7版引入的,用于表示诸如下式生成的结构中的虚拟变量:

形式符号可以使用\[FormalA] 或 Esc.aEsc 等输入。但在第7版中,\[FormalA] 被渲染为a. 而那意味着上述表达式会是这样:

我一直觉得这看起来太复杂了。在第12版中,我们希望将其简化。在尝试了各种可能后,最终定下来用单一的灰色下点表示,我认为这看起来好多了。

在AxiomaticTheory中,变量和运算符都是“纯符号的”。唯一确定的是各个算符的数量,这可以问AxiomaticTheory

方便的是,运算符和数量的表示都可以立即输入给Groupings,以得到涉及特殊变量的可能表达式:

N体问题

公理化理论代表了数学的一个经典历史领域。另一个经典历史区域--更多的是在应用方面--是N体问题。版本12.0引入了NBodySimulation,它提供对n体问题的模拟。这里有一个三体问题(想想地球-月球-太阳),具有一定的初始条件(和逆方力定律):

您可以询问解决方案的各个方面;这将位置绘制为时间的函数:

在底层,这不过是求解微分方程,但有点像SystemModelNBodySimulation提供了一种方便的方法来设方程并处理解。而且标准的力学定律是内置的,但也可以自己定义。

语言扩展与便捷性

30多年来,我们不断打磨Wolfram语言的内核,每次新版本的发布,都会引入一些新的扩展,并进一步增强其便捷性。

从1.0 版开始, 我们就有了函数Information,但在12.0 中,我们对它进行了极大的扩展。它以前只是提供有关符号的信息(当然这一功能也与时俱进了):

但现在它也提供各种对象的信息。以下是有关分类器的信息:

有关云对象的信息:

将鼠标悬停在 "信息框" 中的标签上,您可以得到相应属性的名称:

对于实体,Information提供已知属性值的摘要:

在之前的几个版本中,我们引入了很多新的摘要显示表单。在版本11.3 中, 我们引入了Iconize,它本质上是为任何事物创建摘要显示窗体的一种方式。事实证明,Iconize比我们最初预期的还要有用。它非常适用于在笔记本和Wolfram 语言代码中隐藏不必要的复杂性。在12.0 中,我们重新设计了Iconize的显示方式,使它在表达式和代码中“更好读”。

可以明确地对某些内容图标化:

+键,会看到一些细节:

会再次获得原始表达式:

如果要在计算中引用大量数据,你当然可以将其存储在文件或云端(甚至存储在数据存储库中)。但将它放在笔记本中通常会更方便,这样所有内容都放在同一个地方。避免数据“接管你的笔记本”的一种方法是放入封闭的单元格。但Iconize提供了一种更加灵活和优雅的方式来实现这一目的。

当您编写代码时,“随时图标化”通常很方便。现在您可以通过右键单击菜单进行:

说到显示,我们在12.0中添加了一些小巧方便的功能:

以下是对“数值便利”所新增的功能:

函数式编程一直是Wolfram语言的核心部分。但我们一直在不断扩展,并引入具有通用性的新基元。在版本12.0中,SubsetMap 就是一个例子:

函数通常可以有多个输入,但输出总是唯一的。然而,在量子计算等领域,人们对n输入和n输出更感兴趣。SubsetMap有效实现

->

函数,从列表中n个指定的位置选取输入,对它们应用一些运算,然后将结果分别放回原处。

我是大概一年前开始研发SubsetMap的。很快我就意识到,这个函数的功能我应该在很多地方使用过。但是,这个特殊的“计算工作包”应该叫什么?我最初拟定的名称是ArrayReplaceFunction(我在笔记中将其简称为ARF)。在一系列(现场直播)会议中,这个名称经历了反反复复地修改,比如ApplyAt (但它不是真的Apply)和MutateAt(但它没有左值意义上的突变),以及RewriteAtReplaceAtMultipartApplyConstructInPlace 等等。此外还有关于“函数装饰器”形式的想法,如PartAppliedFunctionPartwiseFunctionAppliedOntoAppliedAcrossMultipartCurry等。

但后来当我们解释这个函数如何在列表的一个子集运行,以及它和Map如何相像,只不过它是同时作用在多个元素上而已时,我们决定使用SubsetMap这个名字。而且这又一次体现了语言设计的重要性——由其名,故其义,并立刻看出它可以用于哪些地方,这一点是非常了不起的。

更多的机器学习超级函数

多年来,我们一直致力于使Wolfram语言成为机器学习前沿的最先进最自动化的系统。早期,我们引入了"超级函数"ClassifyPredict,以完全自动化的方式执行分类和预测任务,自动为给定的特定输入选择最佳方法。此后,我们又引入了其他超级函数,如SequencePredictActiveClassificationFeatureExtract等。

在版本12.0中,我们又引入了几个重要的机器学习超级函数。有FindAnomalies,它能找到数据中的“异常元素”:

此外还有DeleteAnomalies,删除它认为异常的元素:

SynthesizeMissingValues,它试图为丢失的数据生成合理的值:

这些函数如何运作?它们都基于一个名为LearnDistribution的新函数,该函数在给定一组示例的情况下尝试学习数据的基础分布。如果示例只是数字,这基本上是一个标准的统计问题,我们可以使用EstimatedDistribution这类函数。但重点是LearnDistribution适用于任何类型的数据,而不仅仅是数字。这里是学习颜色集合的基础分布:

一旦我们获得了这种“学习分布”,我们就可以用它做各种各样的事情。例如,从中生成20个随机样本:

现在考虑一下FindAnomalies。它需要做的是找出哪些数据点与预期相比异常。或者,换句话说,给定数据的基础分布,它会发现哪些数据点是异常值,因为根据分布它们出现的概率非常低。

就像普通的数值分布一样,我们可以计算特定数据的概率密度函数PDF 。根据我们从示例中学到的颜色分布,非常可能是紫色:

而红色则不太可能:

对于普通的数值分布,累积分布函数CDF阐述的是累积概率,比如说我们得到的结果“远离”某个特定值。而对于任意事物而言,实际上并没有“远离”的概念。但是我们已经有一个叫做RarerProbability的函数,它告诉我们生成一个例子--其概率密度函数比我们给出的更小--的总概率是多少:

现在我们有了一种描述异常的方法:它们只是概率非常小的的数据点。事实上,FindAnomalies有一个选项AcceptanceThreshold(默认值为0.001),它指定具体多少应该算作“非常小”。

现在让我们看一下比颜色更复杂的东西。让我们通过查看1000个手写数字示例来训练异常检测器:

现在FindAnomalies可以告诉我们哪些例子是异常的:

神经网络的最新进展

2016年,我们在第11版首次推出了构建、探索和使用神经网络的符号架构。在随后的每个版本中,各种前沿功能不断加入。在2018年6月,我们引入了神经网络存储库,使得从Wolfram语言访问最先进的神经网络模型更加轻松便捷,存储库中已经有近百个不同类型的模型,并且新的模型一直源源不断地加入进来。

因此,如何你需要最新的BERT“transformer”神经网络,可以从NetModel得到:

可以把它打开并查看它所涉及的网络(对了,第12版更新了网络图形的显示):

可以立即使用这个网络,这里生成了某种“意义特征”阵列:

在版本12.0中,我们引入了几种新的图层类型,特别是AttentionLayer,它可以让人们设置最新的“变换器”架构- 我们通过NetMapThreadOperator和多序列NetFoldOperator等函数增强了“神经网络功能编程”功能。除了这些“网内”增强功能之外,版本12.0还添加了各种新的NetEncoderNetDecoder实例,例如数百种语言文本的BPE标记化,以及能够纳入自定义函数以将数据输入和输出神经网络的功能。

但是,版本12.0中最重要的增强功能是更加基础架构化。NetTrain现在支持多GPU训练,以及处理混合精度算法和灵活的早期停止准则。我们将继续使用流行的MXNet低级神经网络框架(我们一直是其主要贡献者) - 因此我们可以利用最新的硬件优化。有新的选项可以查看训练期间发生的情况,还有NetMeasurements允许您对网络性能进行33种不同类型的测量:

当然,神经网络不是唯一甚至也不总是最好的机器学习方法。但在版本12.0中的一个创新是,我们现在能够在ClassifyPredict中自动使用自我规范化网络,因此可以在必要时轻松利用神经网络。

图像计算

我们在版本10.1中引入了ImageIdentify,用于识别图像是什么。在版本12.0中,我们设法将此推广,不仅要弄清楚图像是什么,还要弄清楚图像中有什么。因此,例如,ImageCases将向我们展示图像中的已知对象类型:

ImageContents提供有关图像内容的数据集,可以了解更多细节信息:

可以用ImageCases查找特定类型的内容:

还可以测试一下图像是否包含某种特定的事物:

在某种意义上,ImageCases就像是广义的FindFaces,用于在图像中找到人脸。版本12.0中,FindFacesFacialFeatures变得更加高效和鲁棒;FindFaces如今基于神经网络而不是经典图像处理,而FacialFeatures的网络从500MB 变为现在的10MB:

ImageCases这样的函数代表了“新式”图像处理,这种处理在几年前是不可想象的。虽然这样的函数可以处理各种各样的新生事物,在更经典的技术中仍然有很多价值。虽然在Wolfram语言中完备的图像处理功能已有很长一段时间,但我们仍在继续进行渐进式增强。

版本12.0中的一个示例是ImagePyramid框架,用于执行多尺度图像处理:

版本12.0中有几个与颜色计算有关的新函数。一个关键的想法是ColorsNear,它代表感知色彩空间中的一个邻域,这里的颜色为Pink

例如,可以在新的ImageRecolor函数中使用颜色邻域的概念:

语音识别及更多音频功能

当我坐在电脑前写这篇文章的时候,让我对电脑随便说句话,然后记录它:

这是我获得的音频频谱图:

此操作在版本11.3中即可执行(但在12.0中Spectrogram的速度提高了10倍)。而新功能是:

我们正在使用最先进的神经网络技术,实现从语音到文字的转变!它流线型的工作效果好得令我吃惊,并且完全能够处理很长的音频片段。在典型的计算机上,转录速度大约等于实际的语音速度,因此一小时的语音将需要大约一个小时来转录。

现在我们认为SpeechRecognize仍是实验性的,我们将继续增强它。但有趣的是看到另一个重要的计算任务现在变成了Wolfram语言的一个单个函数。

在12.0版中,还有其他增强功能。SpeechSynthesize支持新语言和新语音(由VoiceStyleData[]列出)。

WebAudioSearch——WebImageSearch的对照版,可以让你在网上搜索音频:

可以提取实际的音频对象:

然后制作光谱图或其他测量结果的图形:

版本12.0中的新功能在此:可以使用AudioIdentify来尝试识别声音的类别(这是一只会说话的公鸡吗?):

我们认为AudioIdentify仍在试验阶段。这只是一个有趣的开始,还不像ImageIdentify那样好用。

更成功的音频函数是PitchRecognize,它试图识别音频信号中的主导频率(它使用“经典”和神经网络方法)。虽然它还不能处理“和弦”,但它对“单音符”非常有效。

在处理音频时,人们通常不仅要识别音频中的内容,还要添加注释。版本12.0开始引入了大规模音频架构。现在AudioAnnotate可以标记静音的位置,或者有大声的地方。将来,我们将添加说话人识别和单词边界,以及其他许多内容。除此之外,我们还有像AudioAnnotationLookup这样的函数,用于挑选以特定方式注释的音频对象的部分。

所有上述高级音频功能都建立在一个完整的低级音频处理基础之上。版本12.0大大增强了AudioBlockMap(用于将滤波器应用于音频信号),并引入了ShortTimeFourier等函数。

频谱图看起来有点像乐谱的连续模拟,其中音高被绘制为时间的函数。在版本12.0中,现在有InverseSpectrogram,将一系列频谱图数据转成音频。从1991年的第2版开始就有了Play,根据一个函数生成声音(比如Sin[100 t])。现在使用InverseSpectrogram,我们可以将“频率-时间位图”转变为声音。(并且必须承认,当只有振幅信息时,关于相位的最佳猜测仍是棘手的问题。)

自然语言处理

Wolfram|Alpha开始,我们长期以来拥有非常强大的自然语言理解(NLU)功能。这意味着,给定一种自然语言,我们擅长将其理解为Wolfram语言,然后由此进行计算:

但是在自然语言处理(NLP)方面,如果我们输入一大段自然语言,但不试图完全理解它们,而只是找到或处理它们的一些特定功能,又怎样呢?一段时间以来,像TextSentencesTextStructureTextCasesWordCounts这样的函数已经在这个方面为我们提供了基本功能。在版本12.0中,通过利用最新的机器学习技术,以及我们长期的NLU和知识库功能,强大的NLP功能已经开始崭露头角。

核心是TextCases的显著增强版本。TextCases的基本目标是在一段文本中查找不同类型内容的实例。一个例子是“实体识别”的经典NLP任务,在这里TextCases找到哪些国家名称出现在关于ocelots的维基百科文章中:

我们也可以问一下提到哪些岛屿,但现在我们不会要求Wolfram语言解释:

TextCases并不完美,但它确实表现出色:

它也支持许多不同的内容类型(https://reference.wolfram.com/language/guide/TextContentTypes.html)

您可以要它查找代词或简化关系从句,量词,电子邮件地址,或150种实体(如公司、植物或电影)中出现的任何一种。您还可以要求它挑选出特定人类语言或计算机语言的文本,或者关于特定主题(如旅行或健康)或具有正面或负面情绪的文本。您可以使用像Containing这样的结构要求这些东西的组合(如包含河流名称的名词短语):

例如,TextContents可以让您查看在特定文本中检测到的所有实体的详细信息:

并且,是的,原则上可以通过FindTextualAnswer使用这些功能来尝试回答文本中的问题。但在这种情况下,结果可能非常古怪:

当然,您可以从我们内置的策展知识库中获得真正的答案:

顺便说一句,在版本12.0中,我们添加了各种小的“自然语言便利功能”,如SynonymsAntonyms

计算化学

12.0版在计算化学方面带来了“惊喜”。我们的知识库中在很久以前就有了显式已知化学品数据。但是在版本12.0中,我们可以对指定为纯符号对象的分子进行计算。以下是我们如何指定最终成为水分子的方法:

以下是我们如何进行3D渲染:

可以处理“已知化学品”:

可以使用任意IUPAC名称:

或者可以“编造”一个化学品。例如通过其SMILES字符串指定它们:

但我们不仅能生成图片,还可以根据结构进行计算,如对称性:

给定一个分子,我们可以突出显示其碳氧键:

或者突出显示结构,例如由SMARTS字符串指定(这里是任何5个成员的环):

也可以搜索“分子模式”;结果以原子数表示:

我们在版本12.0中添加的计算化学功能颇具通用性并且功能强大(需要注意的是,到目前为止它们只涉及有机分子)。在最底层,它们将分子视为标号图,其中图的边对应于键。但他们也了解物理学,并正确地解释原子价和键配置。不用说,有很多细节(关于立体化学,对称性,芳香性,同位素等)。但最终结果是分子结构和分子计算现已成功地添加到整合到Wolfram语言的区域列表中。

地理计算扩展

Wolfram语言已具备强大的地理计算功能,但12.0版增加了更多功能,并对已有功能进行了增强。

例如,现在有RandomGeoPosition,它生成一个随机的维度-经度位置。这看上去似乎微不足道,但当人们不得不进行坐标变换时,就看到它的威力了,人们可以告诉它只在某个地区内选取点,这里是法国:

在版本12.0中,新地理功能的一个主题是不仅处理地理点和区域,还处理地理矢量。例如,这是当前在艾菲尔铁塔处的风矢量,表示为GeoVector,具有速度和方向(还有GeoVectorENU,它提供东,北和上分量,以及GeoGridVectorGeoVectorXYZ):

GeoGraphics这样的函数可以可视化离散的地理矢量。GeoStreamPlotStreamPlot(或ListStreamPlot)在地理方面的对照,并显示由地理向量(此处来自WindDirectionData)形成的流线:

大地测量学是一个在数学上相当复杂的领域,我们为Wolfram语言在此方面的卓越性能而感到自豪。在12.0版中,我们添加了一些新功能来填充一些细节。例如,我们现在有像GeoGridUnitDistanceGeoGridUnitArea这样的函数,它们提供与地球上每个位置(或月亮,火星等)的不同地理投影相关的失真(基本上是雅可比行星的特征值)。

增强的可视化功能

我们一直在稳步发展的一个可视化方向被人们称之为“元图形”:图形化事物的标注和注释。我们在版本11.0中引入了Callout;在版本12.0中,它已经扩展到3D图形:

即使对于比较复杂的物体,它也能很好地确定标记其位置:

为了让图形更加美观,对很多细节的改进非常重要。在版本12.0中增强的功能是确保图形各列沿边框排列,而不管其刻度标签的长度如何。我们还添加了LabelVisibility,它允许您指定不同标签应该可见的相对优先级。

版本12.0的另一个新功能是多面板绘图布局,其中不同的数据集显示在不同的面板中,但面板尽可能地共用坐标轴:

加强知识库集成

我们的策展知识库非常庞大且不断增长,它驱动着Wolfram|Alpha。随着Wolfram语言的每次版本发布,我们逐渐将其融入语言的核心。

在版本12.0中,我们直接在语言中公开了数百种类型的实体:

在12.0版之前,许多类型实体记录在Wolfram|Alpha的示例页面。但现在所有这些都收录在Wolfram语言参考文档中心:

仍有像SatelliteDataWeatherDataFinancialData这样的函数来处理通常需要复杂选择或计算的实体类型。但在版本12.0中,可以使用自然语言(“control+ =”)输入和“黄色框”实体和属性以相同方式访问每个实体类型:

顺便说一句,人们也可以隐性使用实体,比如这里求具有最高已知熔点的5个元素:

并且可以使用Dated获取时间序列值:

与外部数据库的大数据集成

使用Wolfram知识库中的内置数据非常方便。查询实体的相关属性非常方便:

但是如果你有自己的数据怎么办?能否对它进行设置,使其可以像这样轻松地使用吗?版本11的一个主要新功能是添加了EntityStore,可以定义一个自己的实体类型,然后指定实体、属性和值。

WolframData Repository 包含了一堆实体范例。这是其中一个:

它描述了单个实体类型:“SWLibraryBook”。为了能够像内置实体一样使用这种类型的实体,我们“注册”实体存储:

现在我们可以做一些事情,比如要求10个类型为“SWLibraryBook”的随机实体:

实体存储中的每个实体都具有各种属性。这是一个特定实体的属性值数据集:

通过这种设置,我们基本上是将实体存储的全部内容读入内存,这使得执行Wolfram语言运算非常有效。但是,对于大量数据而言,它并不是一个很好的可扩展解决方案- 例如数据太大而无法容纳在内存中。

但什么是大数据的典型来源?通常它是一个数据库,通常是一个可以使用SQL访问的关系数据库。我们使用DatabaseLink软件包对SQL数据库进行低级读写访问已有十多年。但是在版本12.0中,我们添加了一些主要的内置功能,允许在Wolfram语言中处理外部关系数据库,就像实体存储或Wolfram知识库的内置部分一样。

让我们从玩具示例开始吧。这是一个恰好存储在文件中的小型关系数据库的符号表示:

我们立即得到一个汇总数据库内容的框,并告诉我们这个数据库有8个表。如果我们打开框体,可以开始检查这些表的结构:

然后,我们可以将此关系数据库设置为Wolfram语言中的实体存储。它看起来与上面的库实体商店非常相似,但现在实际的数据没有被放内存;相反,它仍然在外部关系数据库中,我们只是在Wolfram语言中定义一个(“类ORM”)映射到实体:

现在我们可以注册这个实体存储,它设置了一堆实体类型(至少在默认情况下),以数据库中表的名称命名:

现在我们可以对这些实体进行“实体计算”,就像我们在Wolfram知识库中的内置实体一样。这里的每个实体都对应于数据库中“employees”表中的一行:

对于给定的实体类型,我们可以询问它具有哪些属性。这些“属性”对应于底层数据库中表的列:

现在我们可以询问特定实体的特定属性值:

我们也可以通过给定标准来挑选实体; 在这里,我们要求“payments”实体具有“amount”(金额)属性的4个最大值:

我们同样可以询问最大金额值:

但是在这里它变得更加有趣了:到目前为止,我们看见的是一个文件支持的小数据库。但我们也可以对外部服务器上的巨型数据库做同样的事情。

例如,让我们连接到TB级的OpenStreetMap PostgreSQL数据库,该数据库包含几乎全部世界街道地图的数据:

和以前一样,让我们将这个数据库中的表注册为实体类型。像大多数野外数据库一样,结构中存在一些小故障,这些故障已被绕过,但会产生警告:

但现在我们可以询问有关数据库的问题,比如世界上所有街道上有多少个地理点或“节点”(是的,这是一个很大的数字,这正是数据库很大的原因):

在这里,我们要求(101 GB)的planet_osm_polygon表中具有10个最大(投影)区域的对象的名称(是的,只需不到一秒):

这一切是如何运作的?过程基本是这样,我们的Wolfram语言表示被编译成低级SQL查询,然后将其发送以直接在数据库服务器上执行。

有时您需要的只是最终值(例如,上面的“amounts”)。但其他情况下,一些中间值也是需要的,比如以特定方式选择的实体集合。当然,这个系列可能有十亿个条目。因此,我们在版本12.0中引入的一个非常重要的功能是,我们可以纯符号式地表示和运算这些事物,仅在最后将它们解析为特定的事物。

回到我们的玩具数据库。下面这个例子可以说明我们如何通过聚合具有给定国家值的所有客户的总creditLimit来获得实体类别:

起初,这只是符号表示。但如果我们要求具体值,则执行实际的数据库查询,这样我们得到了具体的结果:

有一系列新功能可用于设置不同类型的查询。这些函数不仅适用于关系数据库,还适用于实体存储以及内置的Wolfram知识库。因此,我们可以在元素周期表中询问给定周期的平均原子质量:

一个重要的新结构是EntityFunctionEntityFunctionFunction类似,不同之处在于其变量表示实体(或实体类),并描述可以直接在外部数据库上执行的操作。这是一个内置数据的例子,我们在其中定义一个“筛选”实体类,其中筛选标准是一个检验总体值的函数。该FilteredEntityClass本身只是符号表示,但EntityList实际执行查询,并解析(这里为未排序)实体的显式列表:

除了EntityFunctionAggregatedEntityClassSortedEntityClass之外,版本12.0还包括SampledEntityClass(用于从类中获取一些实体),ExtendedEntityClass(用于添加计算属性)和CombinedEntityClass(用于组合来自不同类的属性)。通过这些原语,可以构建“关系代数”的所有标准运算。

在标准数据库编程中,人们通常最终会得到一整片由“joins”和“foreign keys”等组成的丛林。我们的Wolfram语言表示允许您进行更高级别的操作,其中“joins”(连接)变为函数组合,而“foreignkeys”(外键)只是不同的实体类型。(但如果要进行显式连接,则可以使用CombinedEntityClass。)

所有这些Wolfram语言结构都被编译成SQL,或者更准确地说,是与您正在使用的特定数据库相匹配的SQL的特定方言(我们目前支持SQLite、MySQLPostgreSQLMS-SQL,对OracleSQL的支持即将推出)。当我们进行编译时,会自动检查类型,以确保您获得有意义的查询。即使是相当简单的Wolfram语言规范也可能最终变成许多SQL行。例如,

将生成以下中间SQL(此处用于查询SQLite数据库):

12.0版的数据库集成系统非常复杂,为此我们已经奋斗多年。这是朝Wolfram语言直接处理大数据中的“大”迈出的重要一步,并让Wolfram语言直接在TB级别的数据集上进行数据科学研究。比如查找世界上哪些街头实体的名字中有“Wolfram”:

RDF、SPARQL及凡此种种

世界知识的最佳表示方式是什么?自古以来,哲学家(和其他人)一直对此争论不休。有时人们说逻辑是关键,有时说是数学,而有时又说是关系数据库。但现在我们至少有一个坚定的共识:一切都可以通过计算来表示。这是一个伟大的想法,从某种意义上说,这使得我们使用Wolfram语言所做的一切成为可能。

但是,是否存在一些通用的计算子集可用于表示至少某些类型的知识?我们在Wolfram知识库中广泛使用的是实体(“纽约市”),属性(“人口”)及其值(“860万人”)的概念。当然,这样的三元组并不代表世界上的所有知识(“明天火星的位置将在哪里?”)。但是当谈到不同事物的“静态”知识时,这是一个不错的开端。

那么如何将这类知识表示形式化呢?答案之一是通过图形数据库。与许多“语义网”项目一致,在版本12.0中,我们使用RDF支持图形数据库,并使用SPARQL对它们进行查询。在RDF中,中心对象是IRI(“国际化资源标识符”),它可以表示实体或属性。然后,“triplestore”由三元组(“主语”,“谓词”,“对象”)组成,每个三元组中的每个元素都是IRI(或文字,例如数字)。然后可以将整个对象视为图形数据库或图形存储(数学上称为超图)。(它是超图因为谓词“边”也可以是别处的顶点。)

您可以像构建EntityStore一样构建自己的RDFStore。事实上,您可以像查询RDFStore一样使用SPARQL查询任何Wolfram语言的EntityStore。由于Wolfram知识库的实体属性部分可以视为实体存储,因此您也可以对它进行查询。这是一个例子。国家-城市列表实体{Entity["Country"],Entity["City"]}实际上代表RDF存储。然后SPARQLSelect是一个操作此存储的运算符。它的作用是尝试找到符合要求的三元组,并使用“SPARQL变量”x的特定值:

当然,在Wolfram语言中还有一种更简单的方法:

但SPARQL可以让你做更多酷炫的事情,比如询问把美国与墨西哥联系起来的属性有哪些:

或者从葡萄牙到德国是否存一条基于国家边境关系的路径:

原则上您可以将SPARQL查询写作字符串(就像您可以写SQL字符串)。我们在版本12.0中所做的是引入SPARQL的符号表示,允许对表示本身进行计算。例如,可以轻松地自动生成复杂的SPARQL查询。(这样做尤为重要,因为实际的SPARQL查询本身就有一种变得冗长笨重的习惯。)

但有没有野生的RDF存储?长期以来,人们一直希望网络的大部分内容最终会被标记的足以“变成语义”,从而成为一个巨大的RDF存储。如果发生这种情况当然会很棒,但到目前为止它肯定还没有发生。尽管如此,还是有一些公共RDF存储,以及机构内部的一些RDF存储,而版本12.0中的新功能令我们处于一个独特的位置,可以与这些RDF存储一起做很多有趣的事情。

数值优化

数学工业应用中一个及其常见的问题形式是:“如果必须满足某些约束,什么配置可以最小化成本(或最大化收益)?”半个多世纪以前,发明了所谓的单纯形算法,用于求解这类问题的线性版本,其中目标函数(成本,支付)和约束都是问题中变量的线性函数。到了20世纪80年代,人们发明了更有效的(“内部点”)方法,而对此我们已经在Wolfram语言中进行了长期的“线性编程”。

而对于非线性问题,一般情况下可以使用像NMinimize这样的函数,这类函数是非常先进的。但这确实是一个难题。然而几年前,人们认识到,即使在非线性优化问题中,也存在一类所谓的凸优化问题,这些问题实际上可以像线性问题一样有效地求解。(“凸”意味着目标和约束都只涉及凸函数,因此当接近极值时,没有任何东西可以“摆动”,并且不存在任何不是全局最小值的局部最小值。)

在版本12.0中,我们现在已经为所有凸优化的标准类提供了强大的求解功能。这是一个简单的案例,涉及使用几个线性约束的最小化二次形式:

在版本11.3中,NMinimize已经能够求解此特定问题:

但如果变量更多,则旧的NMinimize会很快陷入困境。但在版本12.0中,QuadraticOptimization能继续正常工作,最多可达十万多个变量,超过十万个约束(只要它们相当稀疏)。

在版本12.0中,我们已经得到了像“原始凸优化”函数,如SemidefiniteOptimization(处理线性矩阵不等式)和ConicOptimization(处理线性向量不等式)。但像NMinimizeFindMinimum这样的函数也会对何时通过转换为凸优化形式来有效地解决问题进行自动识别。

如何设置凸优化问题?较大的问题将涉及对整个向量或变量矩阵的约束。在版本12.0中,我们现在可以使用VectorGreaterEqual(输入为≥)等函数来立即表示这些函数。

非线性有限元分析

偏微分方程很难求解。30多年来,我们一直在研究开发更高级更通用的求解方法。我们在1991年首次在版本2中引入了NDSolve(用于ODE)。到20世纪90年代中期,我们有了首个(1+1维)数值偏微分方程。2003年,我们引入了强大的模块化框架来处理数值微分方程。但就PDE而言,我们基本上只停留在简单的矩形区域内。要突破这个极限,需要构建我们在第10版中引入的整个计算几何系统。随后,我们发布了第一个有限元PDE求解器。在第11版中,我们将其推广到本征问题。

而今天,我们在第12版中实现了另一个重大的推广:非线性有限元分析。有限元分析涉及将区域分解成小的离散三角形、四面体等,其中原始PDE可以通过大量耦合方程来近似。当原始PDE为线性时,这些方程也将是线性的,这正是人们谈论“有限元分析”时所考虑的典型情况。

但是,有许多具有实际重要性的偏微分方法并不是线性的。要解决这些问题,需要进行非线性有限元分析,而这正是版本12.0版的新功能。

举例说,这是求解一个非线性PDE所要做的事情,该非线性PDF描述的是2D最小表面(例如理想化的肥皂膜,此处这里是环形的)的高度,具有(Dirichlet)边界条件,使其在边上做正弦曲线摆动(就像肥皂膜悬挂在电线上):

在我的电脑上,只需要四分之一秒就可解出这个方程,并获得插值函数。以下是表示解决方案的插值函数图:

新型高级编译器

多年来,我们为优化Wolfram语言程序的执行投入了大量的人力物力。早在1989年,我们就开始对高效虚拟机的指令自动编译简单的机器精度数值计算(事实上,原始代码是我本人亲自编写的)。多年来,我们将编译器功能不断扩展,但它总是局限于比较简单的程序。

在版本12.0中,我们向前迈进了一大步,我们发布的是一个全新的、功能更强大的编译器的第一个版本,为此我们已经奋斗了多年。这个编译器能够处理的程序范围更广泛(包括复杂的功能结构和控制流程),并且它也不再是编译到虚拟机,而是直接编译为优化的本机机器代码。

在版本12.0中,我们仍然考虑新的编译器试验。但它在迅速发展壮大,必将对Wolfram语言的效率产生巨大影响。在版本12.0中,我们只是公开了新编译器的“套件表单”,具有特定的编译功能。今后,我们会逐步让编译器的运行变得越来越自动化,用机器学习等手段搞清楚何时值得花时间去做编译,以及去做什么级别的编译。

在技术层面,12.0版编译器基于LLVM,并通过生成LLVM代码,链接Wolfram语言内核本身使用的同一低级运行时库,并调回完整的Wolfram语言内核来实现运行时库中不存在的功能。

这是在新编译器的当前版本中编译纯函数的基本方法:

生成的编译代码函数就像原始函数一样工作,但速度更快:

使FunctionCompile产生速度更快的函数的一个重要原因是,你要对将获得的参数类型做出假设。我们支持许多基本类型(如“Integer32”和“Real64”)。但是当使用FunctionCompile时,您将提交特定的参数类型,因此更加简化的代码才得以生成。

新编译器的许多复杂性与推断在程序执行中将生成什么类型的数据有关。(这要涉及到许多图论和其他算法,当然编译器的所有元编程都是用Wolfram语言完成的。)

这个例子涉及类型推断(fib的类型被推断为“Integer64”->“Integer64”:返回整数的整数函数):

在我的电脑上,cf[25]的运行速度比未编译函数快约300倍。(当然,当编译版本的输出不是“Integer64”类型时,编译版本会失败,但标准的Wolfram语言版本继续正常工作。)

编译器已经可以处理数百个Wolfram语言编程基元,适当地跟踪生成的类型,并生成直接实现这些基元的代码。然而有时候人们在Wolfram语言中使用复杂的函数时,并不希望生成自己编译的代码,而只是想要调用Wolfram语言内核来实现这些函数。在版本12.0中,可以使用KernelFunction实现:

现在假设有一个已编译的代码函数。人们可以用它来做什么?首先可以在Wolfram语言中运行它,也可以将其存储稍后再运行。对于特定的处理器架构(例如64位x86),任何特定编译已经完成,但CompiledCodeFunction会自动保留足够的信息,以便在需要时为不同的架构进行额外的编译。

但是给定一个CompiledCodeFunction,一个有趣的新可能性是可以直接生成甚至可以在Wolfram语言环境之外运行的代码。(我们的旧编译器具有CCodeGenerate包,它在简单的情况下提供了略微类似的功能,尽管那时依赖于C编译器精巧的工具链等。)

以下是如何导出原始LLVM代码(注意尾递归优化是自动完成的,并注意最后的符号函数和编译器选项):

如果使用的是 FunctionCompileExportLibrary,则得到一个库文件:在Mac上是.dylib,在Windows上是.dll,在Linux上是.so。它可以通过执行LibraryFunctionLoad在Wolfram语言中使用,也可以用于外部程序。

决定新编译器通用性的主要因素之一是其类型系统的丰富性。现在编译器支持14种原子类型(例如“Boolean”,“Integer8”,“Complex64”等)。它也支持类型结构如“PackedArray”,也就是说,例如TypeSpecifier [“PackedArray”] [“Real64”,2]对应于64位实数的秩为2的堆积阵列。

在Wolfram语言的内部实现中(顺便说一句,它本身主要使用Wolfram语言),我们早已拥有存储数组的一套优化方法。在版本12.0中,我们将其公开为NumericArray。与普通的Wolfram语言结构不同,您必须详细指定NumericArray应该如何存储数据。但它的工作方式极其优雅和优化:

调用Python及其它语言

在版本11.2中,我们引入了ExternalEvaluate,它允许您在Wolfram语言中使用PythonJavaScript等语言进行计算(在Python中,“^”表示BitXor):

在版本11.3中,我们引入了外部语言单元,以便直接在笔记本中输入外部语言程序或其他输入:

在版本12.0中,我们进一步强化了这种整合。例如,在外部语言字符串中,您可以使用<*... *>提供待运算的Wolfram语言代码:

这也适用于外部语言单元:

当然,Python不是Wolfram语言,所以很多时候不起作用:

但是ExternalEvaluate至少可以从Python返回许多类型的数据,包括列表(作为List),字典(作为Association),图像(作为Image),日期(作为DateObject),NumPy数组(作为NumericArray)和pandas数据集(作为TimeSeriesDataSet等)。(ExternalEvaluate也可以返回ExternalObject,它基本上可以控制发送回Python的对象。)

您也可以直接使用外部函数(这个略显古怪的命名ord基本上是ToCharacterCode的Python模拟):

这是一个Python纯函数在Wolfram语言中的符号式表示:

从Python或其它地方调用Wolfram语言

如何访问Wolfram语言?有很多方法。可以直接在笔记本中使用,可以调用它的API在云端执行,或者可以在命令行shell中使用WolframScriptWolframScript可以针对本地Wolfram引擎运行,也可以针对云中的Wolfram引擎运行。它允许您直接提供执行代码:

允许您执行函数定义之类的操作,例如使用文件中的代码:

随着版本12.0的发布,我们同时发布了第一个全新的Wolfram Language Client Library(Wolfram语言客户端库),用于Python。该库的基本理念是让Python程序可以轻松调用Wolfram语言。(值得指出的是,我们拥有C语言客户端库已经至少30年了,它就是现在大家知道的WSTP。)

语言客户端库的工作方式因语言而异。对于作为一种解释性语言(实际上是早期Wolfram语言的历史)的Python来说,这一点非常简单。在设置库并启动会话(本地或在云中)之后,您可以只执行Wolfram语言代码并将结果返回到Python:

还可以直接访问Wolfram语言函数(作为ExternalFunction的一种逆操作):

可以直接与pandas结构,NumPy数组等进行交互。实际上,您可以将整个Wolfram语言视为可以从Python访问的巨型库。当然了,您也可以直接使用优美的Wolfram语言,如果需要的话,还可以创建外部API。

Wolfram “Super Shell”

使用Wolfram语言的一个特点是,它可以让您尽可能不被计算机系统细节以及文件和进程等内容烦扰。但有时候人们希望在系统级别工作。对于比较简单的任务,可以使用操作系统GUI。但是对于更复杂的任务呢?在过去,我经常使用Unixshell。但是很长一段时间以来,我反而使用了Wolfram语言。

将所有内容都放在笔记本中当然非常方便,能够以编程方式使用FileNames(ls)、FindList(grep)、SystemProcessData(ps)、RemoteRunProcess(ssh)和FileSystemScan等函数非常棒。在版本12.0中,我们对Wolfram语言作为“超级shell”使用提供了更多函数以支持。

Remotefile用于符号式表示远程文件(必要时需身份验证),你可以在CopyFile等函数中立即使用。FileConvert用于不同格式文件的直接转换。

如果想要进一步了解,这里是你如何追踪用于读取Wolfram.com使用的端口80和443上的所有数据包:

操纵Web 浏览器

很久以来,在Wolfram语言内部与Web服务器交互很容易,方法是使用URLExecuteHTTPRequest等函数,以及$Cookies等。但在版本12.0中,我们添加了一些新功能:用Wolfram语言控制Web浏览器,并通过编程来对其掌控。最直接的事情就是获取在Web浏览器中一个网站的样子:

结果是一个图像,我们可以用于进行以下计算:

要做更具体的事情,我们必须启动浏览器会话(目前支持Firefox和Chrome):

屏幕上会立即出现一个空白的浏览器窗口。现在我们可以使用WebExecute打开一个网页:

现在页面已经打开,我们可以运行很多命令。单击包含文本“Programming Lab”的第一个超链接:

这将返回我们所到达页面的标题:

您可以键入字段,运行JavaScript,并且可以通过Web浏览器手动执行几乎任何操作。毋庸置疑,在我们公司内部,该技术的一个版本已被我们使用多年,来对我们的各种网站和网络服务进行测试。但在版本12.0中,呈献给您的是一个更加流畅和通用的版本。

独立的微控制器

今天,世界上微控制器的数量可能是普通计算机数量的10倍,它们在没有任何通用操作系统的情况下运行着特定计算,而成本可能只有几美分到几美元。一台中型轿车上微处理器的数量大概为30个。

在版本12.0中,我们为Wolfram语言引入了一个微控制器套件,它允许您提供符号规范,从而自动生成和部署代码以在微控制器中自主运行。在典型的设置中,微控制器不断对来自传感器的数据进行计算,并实时向执行器发出信号。最常见的计算类型是控制理论和信号处理中的有效计算。

很久以来,我们就对在Wolfram语言中进行控制理论和信号处理提供广泛深入的支持。而现在,我们可以把该语言指定的任何内容取出并将其作为嵌入式代码下载到独立微控制器,以实现在任何地方(设备、物联网等)的部署。

例如,以下是生成模拟信号处理滤波器的符号表示:

此过滤器可以直接在Wolfram语言中使用,比如使用RecurrenceFilter将其应用于音频信号。我们还可以绘制频率响应:

要在微控制器中部署该滤波器,首先必须从这个连续时间表示中推导出离散时间近似,它可以在微控制器中以紧密循环(此处为每0.1秒)运行:

现在一切就绪,可以使用微控制器套件将其实际部署到微控制器上。该套件支持超过一百种不同类型的微控制器。以下是如何将过滤器部署到一个已连接到计算机上串行端口的Arduino Uno:

MicrocontrollerEmbedCode的工作原理是生成适当的C类源代码,为想要的微控制器架构进行编译,然后通过其所谓的编程器将其部署到微控制器。这是在这种特定情况下生成的实际源代码:

现在我们就有了一个运行Butterworth滤波器的微处理器,可用于任何地方:

如果我们想检查它到底在做什么,可以使用DeviceOpen将它连接回Wolfram语言来打开它的串口,并从中读取和写入。

与Unity世界的链接

Wolfram语言和视频游戏之间有什么关系?多年来,Wolfram语言一直工作在游戏开发众多方面(模拟策略,创建几何,分析结果,等等)的幕后。但近年来,我们开始致力于在Wolfram语言和Unity游戏环境之间建立更紧密的链接,在版本12.0中我们发布了这个链接的第一个版本。

简单地说,基本方案是让Unity与Wolfram语言一起运行,然后设置双向通信,允许交换对象和命令,底层机理则非常复杂,但结果是实现了Wolfram语言和Unity的优势互补。

这将设置链接,然后在Unity中启动一个新项目:

现在创建一些复杂的形状:

然后只需要一个命令就可以将它作为一个名为“thingoid”的对象放入Unity游戏中:

Wolfram语言内部存在对象的符号表示,而UnityLink现提供数百种用于操作此类对象的函数,并且同时在Unity和Wolfram语言中进行版本维护。

人们可以从Wolfram语言中取出对象并立即将其置于Unity中,无论它是几何、图像、音频、地理地形、分子结构或3D解剖学对象,这是非常了不起的。同样了不起的是,这类对象可以通过游戏物理学或用户操作在Unity游戏中被操纵。(最终,我们可以期待类似Manipulate的功能,其中控件不仅仅是滑块和事物,而是复杂的游戏片段。)

将Wolfram语言生成的内容放入虚拟现实的实验,我们自20世纪90年代初就在做了。但是到了现代,Unity已成为设置VR/ AR环境的事实标准。现在通过UnityLink可以直接将Wolfram语言的内容放入任何现代XR环境中。

Wolfram语言可用来准备Unity游戏的原材料,但在Unity游戏内部,UnityLink基本上只允许插入Wolfram语言代码,该代码可在游戏过程中在本地计算机上或通过WolframCloud中的API执行。这使得在游戏中放入钩子(Hooks)变得简单,从而游戏可以发送“遥测”(比如WolframData Drop)以进行Wolfram语言分析。(也可以编写游戏运行的脚本,这对游戏测试非常有用。)

写游戏是一件复杂的事情。但UnityLink提供了一种有趣的新方法,可以更容易地对各种游戏进行原型设计,并学习游戏开发的奇思妙想。原因之一是它通过使用Wolfram语言中的符号结构有效地让创作者在更高级别上进行游戏开发。另一个原因是它允许在笔记本中逐步完成开发过程,并解释和记录每一步。例如,这是一篇介绍“钢琴游戏” (https://www.wolframcloud.com/objects/sw-blog/Version12/VirtualPiano.nb) 开发的计算型文章:

UnityLink并不简单:它包含600多个函数。但是通过这些功能,人们可以访问Unity的几乎所有功能,并设置几乎任何可以想象的游戏。

机器学习仿真环境

在对机器学习进行强化时,拥有一个可操纵的外部环境是至关重要的。例如,用ServiceExecute调用API(发布推文或进行交易的效果怎样?),用DeviceExecute启动实际设备(向左转动机器人)并从传感器获取数据(机器人是否倒下?)。

但是出于许多目的,人们想要拥有的却是一个模拟的外部环境。在某种程度上,纯Wolfram语言已经做到了这一点,例如提供对丰富“计算世界”的访问,这个“计算世界”里充满了可修改的程序和方程(元胞自动机,微分方程,......)。并且是的,在这个计算世界中的万物可以通过现实世界来告知,比如海洋、化学品或山脉的现实属性等。

但是对于我们现代人通常学习的、充满工程结构的环境呢?SystemModel可以非常方便地访问许多真实的工程系统。通过UnityLink,我们可以期待访问丰富的基于游戏的仿真世界。

但作为第一步,在版本12.0中,我们建立了与一些简单游戏(特别是来自OpenAI“gym”)的连接。界面与现实世界中的交互很相似,游戏像“设备”一样被访问(有时需要适当进行开源安装):

我们可以读取游戏状态:

将它显示为图像:

通过一点点努力,我们可以提取游戏中的100个随机动作(总是检查我们有没有“玩完”),然后显示观察到的游戏状态的特征空间图:

区块链(和CryptoKitty)计算

我们与区块链的第一个连接从版本11.3就开始了。版本12.0增加了许多新的特性和功能,其中最显著的大概要数写入公共区块链以及从中读取的能力。(我们还为Wolfram Cloud用户提供了自己的WolframBlockchain。)我们目前支持比特币、以太坊和ARK 区块链,包括主网和测试网(并且我们有自己的节点直接连接到这些区块链)。

版本11.3允许从区块链中原始读取交易。版本12.0在此基础上添加了一层分析。因此,您可以在以太坊区块链上请求“CK”(即CryptoKitties)代币(Token)的摘要:

可以快速查看历史记录中的所有代币交易,并制作一个关于不同代币活跃程度的文字云:

但是做我们自己的交易会怎样呢?假设我们想要使用比特币ATM(比方说,位于我附近的百吉饼商店中那台(注:参见https://coinatmradar.com/)将现金转移到一个比特币地址。首先我们创建加密密钥(务必记牢我们的私钥):

接下来,必须使用公钥并从中生成比特币地址:

从那里生成一个二维码,就可以去ATM了:

但如果我们想要自己写入区块链呢?在这里,我们将使用比特币测试网(所以并没真正花钱)。这显示了我们之前做过的交易,包括0.0002比特币,即20,000satoshi(中本聪):

现在我们可以设置一个获取此输出的交易,例如,向两个地址各发送8000个satoshi(就像ATM交易一样定义):

现在,我们就得到了一个区块链交易对象,这将提供一个费用(显示为红色,因为它是你将花费的“实际资金”),从剩余所有加密货币(此处为4000satoshi)转给愿意将该交易放入区块链的矿工。但在我们提交此交易(“真正花钱”)之前,我们必须用我们的私钥对其进行签名:

最后,只需应用BlockchainTransactionSubmit,就可将交易提交到区块链上:

这是它的交易ID:

如果是立即查询此交易,会收到该交易不在区块链中的消息:

但等几分钟后,它就传上去了,并很快会传播到比特币测试网区块链的每个副本:

如果你准备好了,可以在主网上进行真实的交易,使用的函数与上面完全相同。您也可以购买CryptoKitties等产品。像BlockchainContractValue 这样的函数可以用于任何智能合约(目前只限以太坊),并且设置为立即理解ERC-20和ERC-721代币。

普通加密功能

和区块链打交道涉及大量加密功能,其中一些是版本12.0中的新功能(特别是处理椭圆曲线)。版本12.0还扩展了非区块链加密功能。例如,我们现在有了直接处理数字签名的函数。这将使用上面的私钥创建数字签名:

现在任何人都可以使用相应的公钥验证消息:

在版本12.0中,我们为哈希函数添加了几种新的哈希类型,特别加强对各种加密货币的支持。此外,还添加了生成和验证派生密钥的方法。GenerateDerivedKey可以从任何密码开始产生更长的密码(为了更安全起见,应该再加点盐 (https://zh.wikipedia.org/wiki/%E7%9B%90_(%E5%AF%86%E7%A0%81%E5%AD%A6)):

这是派生密钥的一个版本,适用于各种身份验证方案:

与金融数据源连接

Wolfram知识库包含各种金融数据。通常有一个金融实体(如股票),然后有一个属性(如价格)。以下是Apple股票价格的完整日常历史记录(它在对数尺度上最令人印象深刻):

Wolfram知识库中的金融数据可以从Wolfram语言中直接获取,该金融数据库不断更新,但并不是实时的(大多有15分钟延迟),并且不会呈现许多金融交易者需要的所有细节。因此,对于专业的金融用途,我们开发了 Wolfram Finance Platform。在版本12.0中,可以直接访问Bloomberg和路透社的金融数据源。

Wolfram语言中具有与Bloomberg和路透社连接的架构,但必须拥有Wolfram Finance Platform及相应的Bloomberg或Reuters订阅才会被激活,这是我们构建Wolfram语言的方式。假设你有这些服务,下面连接到彭博终端(BloombergTerminal)服务:

由彭博终端负责的所有金融工具现在都可以作为Wolfram语言中的实体使用:

现在我们可以询问该实体的属性:

共有超过6万个实体可从彭博终端访问:

这里有5个随机示例(是的,看上去很详细;这些名字来自Bloomberg而不是我们):

我们支持Bloomberg Terminal服务,BloombergData License服务和Reuters Elektron服务。人们现在可以执行相当复杂的任务,比如设置一个连续的任务来异步接收数据,并在每次有新的数据进入时调用“Handler函数”:

软件工程和平台更新

关于Wolfram语言中的新函数和新功能我已经谈了很多。但是Wolfram语言的底层架构进展如何呢?在这方面,我们也一直在不懈努力。例如,从版本11.3到版本12.0,我们已设法修复了近8000个错误,使Wolfram语言的很多方面变得更快更鲁棒。总的来说,我们一直在强化系统的软件工程,例如将初始下载大小降低近10%(在已经添加了所有功能的情况下)。(我们还做了很多事情,比如改进从云中预取知识库元素的预测,使得您在需要类似数据时,它很可能已经缓存在到了您的计算机上。)

多年来,操作系统不断升级,为了利用其最新功能,应用程序也必须随之更新,这一直是计算领域发展的一大特点。针对Mac笔记本界面的重大更新,我们已经倾注了几年心血,最终在版本12.0中成型。作为更新的一部分,我们对20多年来开发和完善的大量代码进行了重写与重构,但结果是在版本12.0中,Mac上我们系统的所有内容都完全是64位,并使用最新的Cocoa API。这意味着笔记本前端速度明显更快,并且还可以超出之前的2GB内存限制。

对Linux平台也有更新,现在笔记本界面完全支持Qt 5,它允许所有渲染操作“无头”地进行,无需任何X服务器,这大大简化了Wolfram Engine在云端的部署。(对于Windows系统,版本12.0还尚未实现的高dpi支持,但很快就会到来。)

Wolfram Cloud的开发在某些方面与Wolfram语言和Wolfram Desktop应用程序的开发是分开的(尽管为了内部兼容性,我们在两个环境中同时发布了12.0版本)。但是自从版本11.3于去年发布以来,WolframCloud取得了巨大的进步。

特别值得一提的是,云笔记本现在支持更多的界面元素(包括如嵌入式网站和视频,这甚至在台式机笔记本中尚不可用),并且其稳健性和速度大大提高。(使我们的整个笔记本界面在Web浏览器中工作并非易事,甚至可以称为软件工程的一大壮举。在版本12.0中还有一些非常复杂的策略,用于维护一致的快速加载缓存,以及完整的符号DOM表示。)

在版本12.0中,现在只需一个简单的菜单项(文件>发布到云...)即可将任何笔记本发布到云端。一旦笔记本发布了,世界上任何人都可以与之互动,并制作自己的副本,从而进行编辑。

云技术已经深入到Wolfram语言的方方面面。除了与云知识库的无缝集成,与区块链连接的功能之外,还有一些便利功能,例如Send To ...通过电子邮件发送任何笔记本,如果没有直接的电子邮件服务器连接,则使用云。

还有很多

尽管我已经写了这么多,但还远远不能详尽版本12的所有新功能。与我们团队的其他成员一起,我已经在版本12.0上努力工作很久了,但是讲到这些新功能还是让人激动不已。

版本间的连贯一致性(Coherency)至关重要,这也令我们倾注了大量心血。我们所添加的所有内容都经过精心设计,使之与已经存在的内容保持一致。从30多年前Wolfram语言的第一个版本开始,我们一直遵循相同的核心原则,这也正是我们在保持长期兼容性的同时仍能不断成长的原因之一。

对于每个新版本,如何确定功能开发的优先顺序总是一件困难的事,但我对我们为版本12.0做出的选择非常满意。在过去的一年里,我做过很多场讲座,在谈到将要出现的功能时,我惊讶于自己多少次说到这一句:“好吧,碰巧这将是版本12.0的一部分!”

我个人一直在使用版本12.0的内部测试版,对它的许多新功能都已经了如指掌,并且受益良多。所以我很高兴今天终于到来,12.0的正式版本发布了,任何人都能够和我一样,随时随地使用它。

原文发布于微信公众号 - WOLFRAM(WolframChina)

原文发表时间:2019-06-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券