前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Wolfram 语言 与 Mathematica 12.3 新功能

Wolfram 语言 与 Mathematica 12.3 新功能

作者头像
WolframChina
发布2021-08-24 14:38:06
1.2K0
发布2021-08-24 14:38:06
举报
文章被收录于专栏:WOLFRAMWOLFRAM

最新中英文版本已经上线,赶紧下载 (https://wolfram.com/get-upgrade/),和 Wolfram 博士一起来体验最新版本的强悍功能:

推动数学前沿、具有质感的图形可视化、符号优化、树、视频编辑、机器学习与神经网络、区块链与加密学、创建自己的"Oracles"、日期和时间与地球转速、欧几里得与笛卡尔、控制系统、化学、分布式并行计算、与外部语言的连接(Java, Shell, Octave, etc.)、支持更多的文件格式(SAS - SAS7BDAT, STATA - DTA, SPSS - POR )、编译器的可移植性、代码辅助分析等等等...... 不要错过本文中 Wolfram 的虚拟 Adventure!

看看我们 5 个月的成果!

很难相信我们已经这样做了 35 年,精心打造一座使我们能够走得更远的越来越高的思想和技术塔。早期,我们习惯于每隔几年发布一次新版本。但最近几年,我们开始进行增量(“.1”)发布,更频繁地发布我们最新的研发成果——既完全充实,又让你“憧憬未来”。

我们于2020 年 12 月 16 日发布了版本 12.2。而在五个月后的今天(2021年5月20日),我们发布了版本12.3。12.3 有一些突破和主流新方向。但 12.3 中的大部分内容只是让 Wolfram 语言和 Mathematica 更好、更流畅、更方便使用。计算更快了。处理了更多“但是___呢?”的情况。大框架更完整,还有很多新的便利性。

还有第一批将在未来成为大型结构的部分。早期的功能(本身已经非常有用)将在未来的版本中成为主要的系统范围框架的一部分。

评估一个版本的一种方法是谈论它包含多少新功能。对于版本 12.3,该数字是 111(或者说每个开发周大约 5 个新功能)。这是一个非常令人印象深刻的研发生产力水平。但特别是对于 12.3,这只是故事的一部分;还有 1190 个错误修复(外部报告的错误大约占四分之一)和 105 个大幅更新和增强的功能。

增量发布是我们对开放式开发承诺的一部分。我们还以开源形式分享了更多种类的功能(包括 Wolfram 函数库中的 300 多个新函数)。我们一直在做我们独树一帜的事情,直播我们的内部设计过程。对于版本 12.3,可以再次看到设计决策的制定地点和方式,以及它们背后的原因。而且我们还从我们的社区获得了大量意见(通常是在直播期间实时提供)——这极大地增强了我们今天交付的版本 12.3。

顺便说一下,当我们说 Wolfram 语言和 Mathematica 的“版本 12.3”时,我们指的是桌面 (desktop)、云 (cloud) 和引擎 (engine):这三个版本都在今天发布。

许多新的小便利

什么应该“正常工作”?什么应该变得更容易?自版本1.0以来,我们一直在努力找出可以添加哪些小便利来使 Wolfram 语言更加精简。

版本 12.3 具有我们最新的一批便利,分散在语言的许多部分。此版本中出现的新动态是在 Wolfram Function Repository (https://resources.wolframcloud.com/FunctionRepository) 中“原型化” 、然后“升级”构建到系统中的函数。

这是新的便捷函数的第一个示例:SolveValues。Solve 函数(最初在版本 1.0 中引入)有一种非常灵活的方式来表示其结果,允许不同数量的变量、不同数量的解决方案等。

但是通常您很乐意为解决方案假设一个固定的结构,而您只想知道变量的值。这就是SolveValues给出的:

顺便说一下,还有一个NSolveValues给出了近似的数值:

另一个新的便利函数的例子是NumberDigit。假设您想要 π 的第 10 位数字。你总是可以使用RealDigits然后选择你想要的数字:

但现在你也可以只使用NumberDigit(现在“第10位”我们假设你的意思是 10^-10的系数):

回到 1.0 版,我们只有Sort。在 10.3 (2015) 版中我们添加了AlphabeticSort,然后在11.1 (2017)版中我们添加了NumericalSort。现在在 12.3 版中(为了完善这个默认的排序类型系列)我们添加了LexicographicSort。默认排序排序(由 Sort 生成)是:

但这是真正的字典顺序,就像您在字典中找到的那样:

版本 12.3 中的另一个小新函数是StringTakeDrop:

将此作为单个函数可以更轻松地在如下函数式编程结构中使用:

使“标准工作流程”尽可能简单始终是一个重要目标。例如,在处理图形时,我们从8.0 版(2010 年)开始使用VertexOutComponent。它给出了可以从给定顶点到达的顶点列表。对于某些事情,这正是人们想要的。但有时获取子图会方便得多(事实上,在我们物理项目的形式主义中,子图(我们认为是“测地线球”)是一个相当重要的结构)。所以在12.3版中,我们添加了VertexOutComponentGraph:

另一个小“工作流程改进”的例子是在 HighlightImage 中。HighlightImage通常需要在图像中突出显示感兴趣区域的列表。但是像 MorphologicalComponents 这样的函数不只是制作图像中的区域列表;相反,他们生成一个“标签矩阵”,将数字标记为图像中的不同区域。所以为了让HighlightImage 工作流程更流畅,在 12.3 版本中我们让它直接使用标签矩阵,为不同的标签区域分配不同的颜色:

我们在 Wolfram 语言中努力确保的一件事是一致性和互操作性。(事实上,我们有一个完整的倡议,我们称之为“语言完整性和一致性”,我们定期直播每周会议。)互操作性的各个方面之一是我们希望函数能够“吃”任何合理的输入并将其变成他们可以“自然”处理的东西。

作为一个小例子,我们在 12.3 版中添加的功能是颜色空间之间的自动转换。Red 默认意味着红色RGB颜色(RGBColor[1,0,0] )。但现在

意味着将红色变为在色调空间中的红色:

假设您正在运行一个长时间的计算。您通常希望了解正在取得的进展。在版本 6.0 (2007) 中,我们添加了Monitor,在后续版本中,我们为某些功能添加了自动内置进度报告,例如NetTrain。但是现在我们正在进行一项计划,为最终可能会进行长时间计算的各种功能系统地添加进度报告。($ProgressReporting = False可以全局关闭它。)

我们为 Wolfram 语言辛勤工作着以确保我们选择好的默认值,例如如何显示事物。但有时你必须告诉系统你想要什么样的“外观”。在 12.3 版中,我们添加了选项 DatasetTheme 来指定Dataset对象应如何显示的“主题” 。

在下面,每个主题只是设置特定的选项,您可以自己设置。但主题是一种方便的“银行切换”选项。这是一个具有默认格式的基本数据集:

在这里,它的网络格式看起来更“明快”:

你也可以给出各种“主题指令”:

以及其他提示:

我不知道为什么我们之前没有想到它,但在11.3 (2018)版中,我们引入了一个非常好的“用户界面创新”:Iconize。在 12.3 版中,我们为图标化添加了另一项润色。如果您选择一个表达式,然后在上下文(“右键单击”)菜单中使用Iconize,表达式的适当子部分将被图标化,即使您所做的选择可能包含一个额外的逗号,或者是某些不可能是表达式的严格子部分:

假设您生成一个需要大量内存来存储的对象:

默认情况下,该对象保存在您的内核会话中,但它不会直接存储在您的笔记本中——因此在您结束当前的内核会话后它不会持续存在。在 12.3 版中,我们添加了一些用于存储数据的选项:

我们投入大量精力使事情“正常工作”的一个重要领域是数据的导入和导出。Wolfram 语言现在支持大约 250 种外部数据格式,例如在 12.3 版中添加了新的统计数据格式,如 SAS7BDAT、DTA、POR 和 SAV。

很多事情变得更快

除了我们为 Wolfram 语言创建新功能所做的所有努力之外,我们还一直在努力使现有功能更好、更快。在 12.3 版中,有很多东西现在变得更快了。由于我们的编译器技术的进步,可以将更广泛的 Wolfram 语言功能直接编译为优化的机器代码,这使得一大类事情变得更快。受益者的一个例子是Around。

这是使用Around的计算:

在版本 12.2 中,在我的计算机上执行此操作一万次大约需要 1.3 秒:

在 12.3 版中,它大约快了 100 倍:

在 12.3 版中速度变快的原因有很多。例如,在Permanent的情况下,我们能够使用一种新的更好的算法。这是 12.2:

现在在 12.3 中:

另一个例子是日期解析:将日期从文本形式转换为内部形式。这里的主要进步来自意识到日期解析通常是批量完成的,因此自适应地缓存部分操作是有意义的。结果,例如在解析一百万个日期时,过去需要花费几分钟的时间现在只需几秒钟。

另一个例子是Rasterize,它在 12.3 版中通常比在 12.2 版中快 2 到 4 倍。这种加速的原因有点微妙。当Rasterize在6.0 版(2007) 中首次引入时,进程之间的数据传输速度是一个问题,因此压缩任何正在传输的数据是一个很好的优化。但是今天的传输速度要快得多,而且我们已经更好地优化了数组数据结构——因此压缩不再有意义,而将其删除(与其他代码路径优化一起)允许Rasterize显着更快。

版本 12.1 的一个重要进步是引入了DataStructure,允许直接使用优化数据结构(通过我们的新编译器技术实现)。版本12.3引入了几种新的数据结构。有用于快速基于前缀的查找的“ByteTrie”(想想Autocomplete和GenomeLookup),还有用于快速几何查找的“KDTree”(想想Nearest)。现在还有"ImmutableVector",它基本上就像一个普通的 Wolfram 语言列表,但是它针对快速追加进行了优化。

除了计算内核的速度改进外,版本12.3还改进了用户界面速度。特别值得注意的是 Windows 平台上的渲染速度显着加快,这是通过使用 DirectWrite 和利用 GPU 功能实现的。

推动数学前沿

Mathematica 的第 1 版被标榜为“一个用计算机做数学的系统”,并且,三十多年来,在 Wolfram 语言和 Mathematica 的每个新版本中都有“用计算机做数学”的创新。

对于 12.3 版,让我们先谈谈符号方程求解。回到第 3 版(1996 年),我们引入了多项式根的隐式“根对象”表示的想法,即使没有根式方面的“显式公式”,我们也可以进行精确的符号计算。版本 7 (2008) 然后将Root推广到也适用于超越方程。

方程组呢?对于多项式,消元论意味着系统与单个方程并没有什么不同;可以使用相同的 Root对象。但是对于超越方程,这不再是真的。但是对于 12.3 版,我们现在已经想出了如何广义化 Root对象,以便它们可以与多元超越根一起使用:

并且因为这些Root对象是精确的,例如它们可以被计算为任何精度:

在版本 12.3 中还有一些新方程,涉及椭圆函数,即使没有Root对象,也可以给出精确的符号结果:

版本12.3的一个主要进步是能够以符号方式求解具有有理函数系数的ODE (常微分方程)的任何线性系统。

有时结果涉及显式数学函数:

有时,结果中有积分或微分根:

版本 12.3 中的另一个 ODE 进步是完全覆盖具有q -有理函数系数的线性 ODE ,其中变量可以显式或隐式出现在指数中。结果是准确的,尽管它们通常涉及微分根:

PDE 呢?对于版本 12.2,我们引入了一个主要的新框架,用于使用数值 PDE 进行建模。现在在 12.3 版中,我们制作了整本105 页的关于 PDE 符号解决方案的专著:(https://reference.wolfram.com/language/tutorial/SymbolicSolutionsOfPDEs.html)

这是一个在 12.2 版中可以数值求解的方程:

现在它也可以获得精确地符号解:

除了线性 PDE 之外,版本 12.3 将特殊解的覆盖范围扩展到非线性 PDE。这是使用 Jacobi 方法的一个(带有 4 个变量)例子:

12.3 中添加的既支持偏微分方程又为信号处理提供新功能的东西是双边拉普拉斯变换(即从 –∞ 到 +∞ 积分,如傅立叶变换):

从第 1 版开始,我们就以涵盖特殊函数而自豪。多年来,我们已经能够逐步将覆盖范围扩展到越来越多的一般特殊函数。12.3 版有几个新的长期寻求的特殊函数类。有卡尔森椭圆积分。然后是Fox H 函数。

回到第 3 版(1996 年),我们引入了MeijerG,它极大地扩展了我们可以用符号形式进行的定积分的范围。MeijerG是根据复平面中的 Mellin-Barnes 积分定义的。这是被积函数中的一个小变化,但是我们花了 25 年的时间来揭示必要的数学和算法,将其带到版本 12.3 FoxH 中。

FoxH是一个非常通用的函数——包括所有超几何 pFq 和 Meijer G函数,以及更多。现在FoxH在我们的语言中,我们能够开始使用它扩展我们的积分和其他符号功能。

符号优化突破

版本 12.0向前迈出的一大步是引入了工业强度凸优化,常规处理涉及线性情况下的数百万个变量和非线性情况下的数千个变量的问题。在 12.0 版中,一切都必须是数字(在 12.1 中,我们添加了整数优化)。在 12.3 版中,我们现在在大规模线性和二次问题中添加符号参数的可能性,如下面的小示例所示:

在不涉及符号参数的典型凸优化计算中,如果仅针对近似数值结果,之前大家并不清楚是否有任何通用方法可以获得精确数值结果。但是对于版本 12.3,我们已经找到了一个,现在我们可以给出精确的数值结果,例如,您可以计算到您想要的任何精度。

这是一个几何优化问题——现在可以根据超越根对象精确解决:

鉴于这样一个精确的解,现在可以对任何精度进行数值计算:

更多图形

如果有人怀疑图形的重要性,我们的Wolfram 物理项目在过去一年中已经非常清楚地表明,在最低级别的物理学就是关于图的。事实上,我们的整个物理项目基本上是由Wolfram 语言中丰富的图功能实现的。

在版本12.3中,我们继续扩展该功能。例如,这是一个新的3D可视化函图:

这是一个新的3D 图嵌入:

自第 10 版(2014 年)以来,我们已经能够在图中找到生成树。然而,在版本 12.3 中,我们将FindSpanningTree推广到直接处理具有某种坐标的对象(如地理位置)。这是一个基于欧洲首都城市位置的生成树:

现在在 12.3 版中,我们可以使用新的GeoGraphPlot将其绘制在地图上:

顺便说一句,在“地理图”中,有多种“地理”方式来连接边。例如,您可以指定它们遵循(如果可能)行车路线(由TravelDirections提供):

欧几里得遇见笛卡尔......

在过去的几年里,我们在几何方面做了很多工作,未来还会有更多。在版本 12.0中,我们引入了“欧几里得式”综合几何。在版本 12.3 中,我们连接到“笛卡尔式”解析几何,将几何描述转换为代数公式。

给定三个符号指定的点,GeometricTest可以给出它们共线的代数条件:

对于共线性的特殊情况,有一个特定的函数可以进行测试:

但是 GeometricTest 的范围要广泛得多——支持 30 多种谓词。这给出了多边形为凸面的条件:

这给出了多边形规则的条件:

这是三个圆相切的条件(而且,是的,∃ 有点“后笛卡尔”):

版本12.3还对核心计算几何进行了增强。最值得注意的是RegionDilation和RegionErosion,它们本质上是将区域相互卷积。区域扩张有效地找到了通过将一个区域平移到另一个区域中的每个点而获得的整体(“Minkowski 和”)“联合区域”。

为什么这很有用?事实证明有很多原因。一个例子是“钢琴搬运工问题”(又名机器人运动规划问题)。假设是一个矩形,有没有办法让它(在最简单的情况下,没有旋转)穿过有某些障碍物(如墙壁)的房子?

基本上你需要做的是采用矩形形状并用它“扩大房间”(和障碍物):

然后,如果从一个点到另一个点“留下”了一条连接路径,那么就有可能沿着该路径移动钢琴。(当然,工厂里的机器人也可以做同样的事情等等。)

RegionDilation对于“平滑”或“偏移”形状也很有用,例如,对于 CAD 应用程序:

至少在简单的情况下,人们可以用它“去笛卡尔”,并得到明确的公式:

而且,顺便说一下,这一切都适用于任意数量的维度——提供了一种生成各种“新形状”的有用方法(就像圆柱体是 3D 中的一条线膨胀的圆盘)。

更多的可视化

Wolfram 语言拥有大量内置的可视化函数——但我们总能发现可以添加更多。我们从 1.0 版(1988 年)开始就有ListPlot3D;我们在 6.0 版(2007 年)中添加了ListPointPlot3D,现在12.3版中我们添加了ListLinePlot3D。

这是使用ListLinePlot3D渲染的 3D 随机游走:

如果您提供多个数据列表,ListLinePlot3D 会分别绘制它们:

我们首先在7.0版(2008 年)中引入了矢量场的绘图,其中包含VectorPlot和StreamPlot等功能,这些功能在 12.1 和 12.2 版中得到了显著增强。在版本12.3中,我们现在添加了StreamPlot3D(以及ListStreamPlot3D)。这是 3D 矢量场的流线图,按场强着色:

画图是一回事;加轴是另一回事。在指定轴,以及它们的刻度和标签应该如何绘制时,有很多微妙之处。这将是一个更长的故事,但在版本 12.3 中,我们开始了符号轴规范(https://reference.wolfram.com/language/ref/AxisObject.html)。

轴的工作方式有点像箭头:首先给出“核心结构”,然后说明如何对其进行注释。这是一个在一条线上从 0 到 100 线性标记的轴:

这是一个螺旋轴(又名参数曲线上的标签):

而且,是的,它也适用于更装饰性的情况:

在许多微妙的问题中,有一个问题是刻度标签应该如何相对于轴定向:

谈到图形的微妙之处,这是 12.3 版中解决的另一个问题。假设你正在制作一条虚线:

Dashing 里面的数字指示每一虚线的长度和间隔。在 12.3 版中,您可以提供一个额外的数字:第一个虚线开始的偏移量:

还有一点是你可以控制每个虚线上的“帽子”,在这里使它们呈圆弧状:

这些可能看起来都像是微细节——但它们是使 Wolfram 语言图形看起来非常好的重要的东西。例如,如果您有两个交叉的虚线轴,您可能希望“虚线”对齐:

金结和其他材料事项

我们几乎从 1.0 版开始就讨论过它,现在终于在 12.3 版中了!作为材料的曲面逼真渲染。这是一个结,看起来好像是用金子做的:

这是一个天鹅绒表面:

在版本12.3中,我们支持十多种标准命名材料(未来还会有更多)。但MaterialShading也被设置为允许您详细指定材料的显式物理和几何属性 - 因此您可以获得如下效果:

顺便说一下,请注意Lighting的新“三点”设置——本质上是对摄影工作室中标准灯光布置的模拟。

建模光与表面相互作用的故事——以及“基于物理的渲染”——是一个复杂的故事,版本 12.3 有一整本专著关于这个:(https://reference.wolfram.com/language/tutorial/PhysicallyBasedRendering.html)

树!

根据新内置函数的数量,版本12.3中最大的新框架的明显赢家是树。十多来,我们一直能够将树作为图的一个特例来处理(当然,Wolfram 语言中的所有符号表达式最终都表示为树)。但是在版本 12.3 中,我们将树作为系统中的一流对象引入。

基本对象是Tree:

Tree有两个参数:一个“payload”(可以是任何表达式)和一个子树列表。(而且,是的,树默认呈现为略带绿色,以向它们的植物类似物致敬。)

有多种用于构造树的“Tree”函数,以及用于将树转换为其他事物的“Tree”函数。例如,RulesTree从嵌套的规则集合构造一棵树:

而TreeRules则相反,将树转换为嵌套的规则集合:

ExpressionTree根据表达式的结构创建一棵树:

从某种意义上说,这是FullForm表达式的直接表示,例如在TreeForm中所示。但是也有一些方法可以将表达式变成树。这需要树的节点包含完整的子表达式——因此树中给定级别上的表达式本质上是像Map这样的函数被认为是该级别的表达式(使用Heads → True):

这是另一个版本,现在有效地消除了嵌套子表达式的冗余,并将表达式的头部视为其他部分(“S 表达式风格”):

当我们有Graph时,为什么我们需要Tree?答案是树有几个重要的特殊征。例如,在Graph中,每个节点都有一个名称,并且名称必须是唯一的。在树中,节点不必命名,但它们可以具有不必是唯一的“有效载荷”。此外,在图中,给定节点的边不会以任何特定顺序出现;但在树中会安特定顺序出现。最后,树有一个特定的根节点;图不一定有这样的东西。

当我们设计Tree时,我们最初认为我们必须对整棵树、子树和叶节点进行单独的符号表示。但事实证明,我们能够单独使用Tree做出优雅的设计。树中的节点通常具有Tree [ payload , { child 1 , child 2 , ...}] 形式,其中 childi 是子树。节点不一定必须具有有效载荷,在这种情况下,它可以仅作为Tree [{ child 1 , child 2 , ...}] 给出。一个叶子节点则是Tree [ expr, 无] 或树[无]。

这种设计的一个非常好的特点是,树可以通过嵌套表达式立即从子树构建:

顺便说一下,我们可以用TreeGraph把它变成一个通用的Graph对象:

请注意,由于Graph不注意节点的排序,因此在此渲染中已有效地翻转了一些节点。为了保留树结构,还必须为节点指定不同的名称:

如果有一个通用图恰好是树,GraphTree会将其转换为显式Tree形式:

RandomTree生成给定大小的随机树:

还可以从嵌套函数生成树:NestTree通过从父节点的有效载荷嵌套生成子节点的有效载荷来生成一棵树:

好的,那么给定一棵树,我们可以用它做什么?有多种树函数可以直接模拟一般表达式的函数。例如,TreeDepth给出了树的深度:

TreeLevel直接类似于Level。在这里,我们得到了从树中的第 2 级开始的子树:

如何获得给定树的特定子树?基本上它有一个位置,就像子表达式在普通表达式中也有一个位置一样:

TreeSelect允许您选择给定树中的子树:

TreeData挑选有效载荷,默认情况下用于树根(TreeChildren挑选出子树):

还有TreeCases、TreeCount和TreePosition - 默认情况下搜索其有效负载与指定模式匹配的子树。可以像使用泛型表达式一样使用树进行函数式编程。TreeMap将函数映射到树(中的有效载荷)上:

TreeFold的操作稍微复杂一些。这里 f 通过扫描树有效地“累积数据”,将 g应用于每个叶子的有效载荷(以“初始化累积”):

有很多东西可以用树来表示。一个经典的例子是家谱。这是我们可以使用的内置数据的情况:

这构建了一个 2 级家谱:

顺便说一下,我们的Tree系统具有很强的可扩展性,可以愉快地处理具有数百万个节点的树。但在 12.3 版中,我们才刚刚开始;在后续版本中,将会有各种其他树功能,以及解析树、XML 树等的应用程序。

日期、时间以及地球转动的速度有多快?

日期和时间很复杂。不仅要处理不同的日历系统和不同的时区,而且在不同的语言和地区也有不同的约定。版本12.3增加了对 700 多种不同“语言环境”的日期和时间约定的支持。

这是瑞典使用的标准约定的日期:

这显示了英国和美国惯例之间的差异,它们都是英语:

在 12.3 版中,有一个关于如何构建日期格式的新的详细规范:

换一种方式怎么样:从日期字符串到日期对象?新的FromDateString这样做:

除了如何显示日期和时间的问题之外,还有一个如何准确确定时间的问题。自 1950年代以来,就有了“原子时间”的核心标准(其本身因相对论和引力效应而变得复杂)。但在此之前,对于各种应用,人们还是想从太阳或恒星确定时间。

我们在Version 10.0 (2014) 中引入了恒星(基于恒星的)时:

现在在 12.3 版中,我们添加了太阳时,它基于太阳在天空中的位置:

这与平时不太一致,主要是因为夏令时和观察者的经度:

如果我们想在天文学中获得精确的时间,事情会变得更加复杂。那里的一大问题是了解地球的精确方向。在版本12.3中——为更广泛地覆盖天文学做备——我们添加了GeoOrientationData。

这表明当前一天比 24 小时长多少:

1800 年,白天更短:

机器学习和神经网络的前沿

我们在 10.0 版(2014 年)中首次引入了自动机器学习(带有Predict和Classify)——从那时起我们一直在继续开发领先的机器学习功能。12.3 版引入了几个备受期待的新功能,特别是旨在更好地分析和控制机器学习。

训练预测器根据葡萄酒的化学成分预测“葡萄酒质量”:

使用特定葡萄酒的预测器:

一个常见的问题是:“它是如何得到这个结果的?”,或者更具体地说,“葡萄酒的不同特征对得到这个结果有多重要?” 在 12.3 版中,您可以使用 SHAP 值来查看不同特征的相对重要性:

这是这个“解释”的可视化版本:

计算 SHAP 值的方法基本上是查看如果删除数据中的不同特征,结果会发生多少变化。在版本 12.3 中,我们为Predict和Classify等函数添加了新选项,以便在训练和计算中控制如何处理数据中通常缺失(或丢弃)的元素,例如,提供一种方法来根据缺失的数据确定结果中的不确定性。

机器学习中一个微妙但重要的问题是校准分类器的“置信度”。如果分类器说某些图像有 60% 的概率是猫,这是否意味着其中 60% 实际上是猫?原始神经网络通常无法做到这一点。但是可以通过使用校准曲线重新校准概率来接近。在版本 12.3 中,除了自动重新校准之外,诸如 Classify 之类的功能还支持新的 RecalibrationFunction 选项,该选项允许您指定应如何进行重新校准。

我们机器学习框架的一个重要部分是对神经网络的深入符号支持。我们继续将研究文献中的最新神经网络放入我们的Neural Net Repository 中,在我们的框架中使用NetModel可以立即访问它们。

在12.3版本中,我们已经添加了一些额外的功能,我们的框架,例如ElementwiseLayer 的“swish”和“hardswish”激活功能。“幕后”发生了很多事情。我们增强了ONNX 导入和导出,我们大大简化了 MXNet 集成的软件工程,我们几乎完成了 Apple Silicon 框架的原生版本(在 12.3.0 中,框架可在 Rosetta 上运行)。

我们一直在努力使我们的机器学习框架尽可能自动化。为了实现这一点,非常重要的是,我们拥有如此多的精选网络编码器和解码器,您可以立即将其用于不同类型的数据。在 12.3 版中对此的扩展是使用任意特征提取器作为网络编码器,可以将其作为主要训练过程的一部分进行训练。为什么这很重要?好吧,它为您提供了一种可训练的方式来将不同类型的数据的任意集合输入到神经网络中,即使没有预定义的方式来了解如何将数据转换为适合输入的数字数组之类的东西输入到神经网络中。

除了提供对最先进机器学习的直接访问之外,Wolfram 语言还拥有越来越多的内置函数,这些函数可以在内部使用强大的机器学习。其中一个函数是TextCases。在 12.3 版中,TextCases变得更加强大,尤其是在支持不太常见的文本内容类型方面,例如"Protein"和"BoardGame":

新视频

我们在 12.1 版中首次将视频引入 Wolfram 语言,并在 12.2 中添加了许多额外的视频功能。在 12.3 中,我们添加了更多功能,还有更多功能即将推出。

12.3 中的一大组新功能围绕着程序化视频生成。有三个基本的新函数:FrameListVideo、SlideShowVideo和AnimationVideo。

FrameListVideo 获取图像的原始列表,并通过将它们视为连续的原始帧来组合视频。SlideShowVideo类似地获取图像列表,但现在它创建了一个“幻灯片视频”,其中每个图像都显示指定的持续时间。例如,在这里,每个图像在视频中显示 1 秒钟:

SlideShowVideo还可以执行一些操作,例如获取值为图像的TimeSeries,并将其转换为幻灯片视频。

AnimationVideo不采用存在的图像;相反,它接受一个表达式,然后为参数的一系列值计算“ Manipulate -style”。(实际上,它就像Animate的视频制作模拟。)

如果您想捕捉视频,例如从相机拍摄,该怎么办?最终会有一种交互式方式在笔记本中执行此操作。但在 12.3 版中,我们添加了底层编程功能,特别是VideoRecord函数。所以这记录了我默认相机的 5 秒:

代码语言:javascript
复制
sw = VideoRecord[$DefaultImagingDevice]; Pause[5]; VideoStop[];

这是生成的视频:(点击“阅读原文”观看视频,或在您自己的笔记本内敲码实现。)

代码语言:javascript
复制
swvid=Video[sw]

但是VideoRecord也可以使用其他来源。例如,如果您给它一个 NotebookObject,它将记录该笔记本中发生的事情。如果你给它一个 URL(比如网络摄像头),它会记录该 URL 传输的帧:

我们在12.3版本已经添加了一个备受请求的特征:对视频合并,例如能合成一个视频到另一个,或装配每一帧的拼贴。

因此,例如,这是我的绿屏与上面的流的合成:

请注意,在执行此操作时,我们使用了Parallelize — 它在 12.3 中新与VideoFrameMap 一起使用。

12.3 版还增加了一些新的视频编辑功能。VideoTimeStretch允许您通过任何指定的函数在视频中“扭曲(改变)时间”。VideoInsert可让您将视频剪辑插入视频,VideoReplace可让您用另一个视频替换部分视频。

Wolfram 语言中视频的最大优点之一是可以使用该语言中的所有工具立即对其进行分析。这包括机器学习,在 12.3 版中,我们已经开始允许对视频进行编码以进行神经网络计算。版本 12.3 包括一个简单的基于帧的视频网络编码器,以及几个内置的特征提取器。更多内容即将推出,包括Wolfram Neural Net Repository 中的各种视频处理和分析网络。

化学方面的更多功能

化学是 Wolfram 语言的一个主要新领域。在版本 12.0 中,我们引入了Molecule作为分子的符号表示,并且我们一直在稳步扩展可以用它做什么。

例如,在版本 12.3 中,Molecule有新属性,例如“TautomerList”(解中可能的重新配置):

还有像MoleculeName这样的便利函数:

而且,是的,使用MoleculeRecognize,您可以从出版物中剪下结构图并找到分子的名称:

给定一组分子,人们经常想问的一个问题是“这些分子之间有什么共同点?” 在版本 12.3中,我们现在有函数MoleculeMaximumCommonSubstructure,它是LongestCommonSubsequence分子结构的类似物:

下面是公共部分的示意图:

现在使用MoleculeAlign,我们可以看到分子如何在 3D 中实际对齐:

鉴于我们在化学和机器学习方面的实力,我们现在处于将这些领域结合在一起的有趣位置。在 12.3 版中,我们开始了内置化学机器学习。以下是两类化学品的样本:

FeatureSpacePlot现在有一个内置的分子特征提取器:

控制系统的闭环

这是我们十多年来一直在努力的事情。如何将我们表示和模拟大型工程和其他系统的能力与我们在控制理论方面的能力联系起来?或者,特别是,我们如何使用我们的控制系统功能来创建可以直接部署在工程系统中的实用设计?版本 12.3 采取了一些重要步骤来回答这个问题,并为控制系统设计开发越来越多的全自动工作流程。

让我们从导入在Wolfram System Modeler 中创建的模型开始。在这种特殊情况下,它是潜艇的简单模型:

给定模型(在本例中由 300 多个微分代数方程组成),我们可以计算系统在不同情况下的行为。就像这是我们的模拟潜艇如何响应冲击力的图——基本上表明潜艇的深度表现出阻尼振荡:

但现在的问题是:我们如何控制潜艇以防止这些振荡?基本上,我们想要建立一个闭环,其中控制器将采用观察到的潜艇行为并修改其动力学以使其稳定且阻尼良好,例如以特定特征值为特征。

那么给定底层系统模型,我们如何设计该控制器?好吧,在 12.3 版中,我们设法将其简化为几个功能。首先我们给出要控制的模型和参数,并通过给出我们想要的特征值来指定我们的设计目标:

现在我们可以将这个控制器连接到我们的系统模型中:

如图所示,这是一个闭环系统(原始系统模型已被省略到灰色圆圈中)。所以现在我们可以看看这个闭环系统的行为,例如给定与之前相同的输入:

现在没有振荡;我们的控制器成功地抑制了它们并“拒绝了干扰”。

那么这是如何工作的呢?嗯,正如在这种类型的控制系统设计中的典型情况,我们首先发现了底层模型的线性化,适用于我们将要操作的领域:

我们可以得到这个线性化模型的特征值:

控制器的目标是将这些移动到所需的设计位置:

那么找到的控制器究竟是什么呢?这是一个非线性状态空间模型:

现在它已准备好进行实际部署。例如,我们可以为 Arduino 编译控制器:

代码语言:javascript
复制
Needs["MicrocontrollerKit`"];

这是实际的 Arduino C 源代码:

毋庸置疑,对于真正的潜艇,人们不会使用 Arduino Uno(尽管这对于玩具潜艇来说可能没问题)。但这里的重点是,在版本 12.3 中,我们现在拥有一个非常自动化的工作流程,用于从复杂的系统模型到控制系统。

在笔记本中输入代码将变得更容易

从 3.0 版(1996 年)开始,当您输入代码时,->会自动变成→。并且我们逐渐添加了额外的“输入自动替换”,最近的是|->在 12.2 版中变成了↦ ( \ [Function] ) 。在 12.3 版中,我们正在推广整个机制(使用新的AutoOperatorRenderings选项),并且我们正在制作<| ... |>自动变成<| ... |>和[[ ... ]]变成〚 ... 〛。

所以这意味着例如,你的代码不会看上去像这样:

当您输入它时,它会立即变成这种更易读的形式:

听上去或许很奇怪经历了这么多年,从“自动 → ”到“自动〚 〛”。但它比您想象的要微妙得多,事实上,它需要一种全新的代码渲染方法。在 3.0 版中,我们的想法是在您键入时将->替换为→。因此,例如,如果您退格一个字符,您将删除整个→,而不是简单地“删除> ”并恢复为-。

但是,如果你正在处理 [[ ... ]] 你不能只是做这样的“局部更换”,这有可能使得一些 ]] 显示为 〛,而另一些作为常规编辑会分裂成 ]] 。

在 12.3 版中,我们所做的根本不是进行替换,而是以特殊方式呈现指定的字符序列(如]])。结果是我们可以支持非常普遍的“类似连字”的行为,并且退格将始终完全反转输入的字符。

AutoOperatorRenderings将使您键入的代码看起来更好,更易于阅读。但是现在在版本 12.3 中可用的输入代码的方式还有第二个更重要的变化。它仍然处于实验阶段,因此默认情况下尚未打开,但是您可以根据需要明确打开它,只需先运行:

代码语言:javascript
复制
CurrentValue[$FrontEnd, DelimiterAutoMatching] = True;

或通过选中“偏好设置”的“界面”选项卡中的复选框:

基本思想(正如DelimiterAutoMatching的名称所暗示的那样)是,当您键入代码时,您输入的分隔符会在您键入时自动匹配。

所以这意味着如果你输入

f[

你实际看到的是:

f[]

换句话说,您将自动获得匹配的分隔符。(“分隔符”是指[ ... ]、{ ... }、( ... )、“ ... ”、[[ ... ]]、<| ... |> 中的任何一个和(* ... *) .)

那么你旧的打字习惯会怎样呢?当然,你仍然可以使用它们。因为您可以敲入]以“输入”结束]。这意味着您输入的字符与以前完全相同。但重要的一点是你不需要。该 ] 已经在那了。

为什么这很重要?基本上是因为这意味着您不必再考虑匹配分隔符。它会自动为您完成。从 3.0 版(1996 年)开始,我们就有了语法着色来指示分隔符何时尚未配对 — 并建议您应该完成配对。但现在配对将自动发生。特别是这意味着您输入的表达式将始终“看起来完整”,并且不会在您输入每个字符时发生各种结构变化。

不用说,这比乍一看要棘手得多。假设您已经输入了一个复杂的表达式,现在您在其中添加了一个开始分隔符,或者更糟的是,添加了好几个开始分隔符。结束定界符在哪里?他们应该包含多少已经存在的代码?有时这是相当明显的,但有时不是。您始终可以删除不适当添加的结束定界符,但我们正在努力使用适当的启发式方法在正确的位置添加或者根本不添加结束定界符它。

该代码有什么问题?代码分析与协助

“一切自动化”是我们试图用 Wolfram 语言实现的一个重要主题。那么调试呢?这是我们可以自动化的东西吗?我们已经考虑了很长时间,在 12.3 版中,我们引入了代码分析和辅助系统的第一步。

几十年来,我们一直在使用语法着色和^来表示缺少参数。这些都是非常有用的。但我们想要的是更全局化的东西。不像拼写检查,而是能够判断一段文本是否意味着正确的东西。

有人可能会认为这是一种哲学问题。在 Wolfram 语言中,任何一段代码——只要它在语法上是正确的——都是一个符号表达式,所以它在某种程度上意味着点什么。问题是那个“什么”是否是你想要的。关键是通过了解“正确代码”的典型结构,通常可以做出很好的猜测。这就是我们新的代码分析系统所做的。

假设你有一段简单的代码:

代码语言:javascript
复制
If[x == y, f[e^2 + 4 e + 1], f[e^2 + 4 e + 1]]

在版本 12.3 中有一个新的上下文(“右键单击”)菜单项Analyze Cell。这是它的作用:

代码分析注意到If的两个分支上的表达式是相同的(如果您复制并粘贴它们,打算更改一个,但忘记了,可能会发生这种情况)。分支相同并不是严格的“错误”,但这几乎肯定不是你想要的,如果你一直想给出相同的表达式,那么如果你只是给出表达式,你的代码就不会那么晦涩了。

这是一个稍微复杂一点的例子:

现在我们点击了描述,并得到了关于如何解决问题的建议——我们可以通过点击建议立即实施。(代码分析框有效地为您提供预览;单击Apply Edits以实际更改您的原始代码。)

代码分析能发现真正的错误吗?是的,我们有证据证明这一点,因为我们已经在我们的内部代码以及我们文档中的示例上运行了它。例如,在 12.2 版中,FitRegularization 的文档包含以下示例:

运行代码分析,你会看到

是的,有一个错误:那里应该有一个逗号。

12.3 版中的代码分析只是一个开始。我们将添加更多来自符号分析和机器学习的案例和建议。分析界面将变得更加自动化——就像拼写检查一样。但我认为代码分析对于 Wolfram 语言的新手和有经验的用户都非常重要,将自动化注入另一个领域。

编译器的进步:可移植性和库

我们有一个重要的长期项目,将 Wolfram 语言直接编译成高效的机器代码。随着项目的推进,使用编译器进行越来越多的核心开发变得可能。此外,在Wolfram Function Repository 之类的东西中,越来越多的函数或函数片段能够使用编译器。

在版本 12.3 中,我们采取了重要的步骤来简化此工作流程。假设您编译了一个非常简单的函数:

那是什么输出?在 12.3 版中,它是一个包含原始低级代码的符号对象:

但重要的一点是,一切都在这个符号的对象中。所以你可以拿起来就用:

然而,有一个小问题。默认情况下,FunctionCompile将为您运行的计算机类型生成原始的低级代码。但是,如果将生成的CompiledCodeFunction带到另一类型的计算机上,它将无法使用低级代码。(它在编译前保留了原始表达式的副本,因此它仍然可以运行,但不会具有编译代码的效率优势。)

在 12.3 版中,FunctionCompile有一个新选项:TargetSystem。使用TargetSystem → All你可以告诉FunctionCompile为所有当前系统创建交叉编译的低级代码:

不用说,完成所有这些编译会比较慢。但结果是一个包含可用于所有当前平台的低级代码的可移植对象:

因此,如果您有一个包含这种CompiledCodeFunction的笔记本或 Wolfram Function Repository 条目,您可以将其发送给任何人,它会自动在他们的系统上运行。

这还有一些其他的微妙之处。FunctionCompile中默认创建的低级代码实际上是LLVM IR(中间表示)代码,而不是纯机器代码。LLVM IR 针对每个特定平台进行了优化,但是当代码加载到平台上时,还有一个小的额外步骤,即本地转换为实际机器代码。您可以使用UseEmbeddedLibrary → True来避免此步骤,并预先创建一个包含您的代码的完整库。

这将使在您的平台上加载编译代码的速度稍微快一些,但问题是创建完整的库只能在特定平台上完成。我们已经构建了一个基于云的编译即服务系统的原型,但目前尚不清楚速度提升是否值得。

12.3 版的另一个新编译器功能是FunctionCompile现在可以获取编译在一起的函数的列表或关联,利用它们的所有相互依赖性进行优化。

编译器继续变得更强大和更广泛,支持越来越多的函数和类型(比如 "Integer128" )。为了支持更大规模的编译项目,版本 12.3 中添加了CompilerEnvironmentObject。这是一个符号对象,表示整个编译资源集合(例如由FunctionDeclaration定义),其行为类似于库,可立即用于为正在进行的其他编译提供环境。

Shell、Java、...:新的内置外部连接

在过去的几个版本中,我们增加了对与一系列外部语言的直接交互的支持,既可以通过ExternalEvaluate 等函数以编程方式进行,也可以作为笔记本的一部分。版本12.3 增加了对多种其他语言的支持。

首先是外壳。早在 1.0 版中,就有“shell 转义”的概念:在一行的开头键入! ,它之后的所有内容都将发送到您的操作系统 shell。三分之一个世纪后,它变得更加精致和复杂,尽管它的基本思想是相同的。

在笔记本中键入>,然后选择Shell,然后键入您的 shell 命令:

shell 中的stdout将在生成时进行回显,然后返回的将是一个符号对象——从中可以提取诸如退出代码或 stdout 之类的内容:

在早期版本中,我们为 Python、Julia、R 等语言以及 SQL 添加了功能。在这个版本中,我们还添加了对 Octave 的支持(是的,函数名称不太好):

但这里的重点是数据结构已经连接,因此 Octave 数组作为适当的表达式返回,在这种情况下是一个列表的列表(包含近似数字,因为这都是 Octave 句柄)。

顺便说一下,虽然 notebook 中的外部语言单元很好,但您绝对不必使用它们,您可以使用ExternalEvaluate 或ExternalFunction 以纯编程方式做事。

20 多年来,我们通过J/Link与 Wolfram 语言中的 Java 紧密集成。但是在版本 12.3 中,我们已经进行了设置,因此您可以直接在ExternalEvaluate和外部语言单元格中输入 Java 代码,而不是使用 J/Link 复杂的 Java 符号接口:

基本 Java 数据结构作为标准 Wolfram 语言表达式返回:

Java 对象通过 J/Link 以符号形式表示:

一切都与 J/Link 无缝交互。例如,您可以直接使用 J/Link 创建 Java 对象——随后您可以将其与在外部语言单元格中输入的 Java 一起使用:

如果你定义一个 Java 函数,它会被符号式地表示为一个ExternalFunction对象:

以下这个特殊的函数接收一个数字列表和一个 Java 对象——我们上面用 J/Link 创建的那种:

(是的,这个特殊的操作在 Wolfram 语言中非常容易直接完成。)

区块链、存储、认证和密码学

我们首先在 11.3 版(2018 年)中将区块链功能引入 Wolfram 语言,并且在每个后续版本中,我们都添加了越来越多的区块链集成。12.3 版增加了与 Tezos 区块链的连接:

除了使用 Wolfram 语言进行区块链交易和区块链分析之外,我们还越来越多地使用计算合约——Wolfram 语言的全面计算语言特性为此提供了独特的机会(一个例子是基于我们对世界的计算知识创建“oracles ”)。

在 12.1 版中,我们引入了ExternalStorageObject,最初支持 IPFS 和 Dropbox。在 12.3 版中,我们添加了对 Amazon S3 的支持(是的,您可以一次存储和检索整个文件桶):

各种外部交互中的一个必要步骤是身份验证。在 12.3 版中,我们添加了对 OAuth 2.0 工作流程的支持。您创建一个SecuredAuthenticationKey:

然后您可以使用此密钥发出请求:

代码语言:javascript
复制
URLRead["https://oauth.reddit.com/api/search_subreddits" , 
 Authentication -> %]

您将看到一个浏览器窗口,要求您使用您的帐户登录,然后您就可以开始运行了。

对于许多常见的外部服务,我们有“预先打包”的ServiceConnect连接。这些通常需要身份验证。对于基于 OAuth 的 API(如 Reddit或 Twitter),我们有自己的 WolframConnector 应用程序来代理身份验证的外部部分。版本 12.3 的一个新功能是您还可以使用您自己的外部应用程序来代理该身份验证,因此您不受使用 WolframConnector 应用程序的外部服务所做的安排的限制。

我们在这里谈论的一切的背后都是密码学。在 12.3 版中,我们添加了一些新的加密功能;特别是,我们现在支持 NIST 数字签名 FIPS 186-4 标准中的所有椭圆曲线,以及将成为 FIPS 186-5 一部分的 Edwards 曲线。

我们已将所有这些打包,以便轻松创建区块链钱包、签署交易和为区块链编码数据:

分布式计算及其管理

我们在 1990 年代中期首次在 Wolfram 语言中引入了并行计算,并在 7.0 版(2008)中引入了如下函数 ParallelMap和Parallelize。在单台计算机的多个内核上设置并行计算一直很简单。但是当人们还想使用远程计算机时,情况就变得更加复杂了。

在 12.2 版中,我们引入了RemoteKernelObject作为远程 Wolfram 语言功能的符号表示。从版本 12.2 开始,这可用于一次性计算 RemoteEvaluate。在版本 12.3 中,我们已将RemoteKernelObject集成到并行计算中。

让我们在我的一台机器上试试这个。这是一个远程内核对象,代表其上的单个内核:

现在我们可以在那里进行计算,这里只要求处理器内核的数量:

RemoteEvaluate[%, $ProcessorCount]64

现在让我们创建一个使用这台机器上所有 64 个内核的远程内核对象:

现在我可以启动这些内核(是的,它比以前更快、更强健):

现在我可以用它来做并行计算:

对于像我这样经常参与并行计算的人来说,12.3 版中对这些功能的简化将产生很大的不同。

ParallelMap等函数的一项功能是它们基本上只是将计算的各个部分独立地发送到不同的处理器。当需要在处理器之间进行通信并且一切都异步发生时,事情会变得非常复杂。

这方面的基础科学与多向图的故事以及我们物理项目中量子力学的起源密切相关。但在软件工程的实用层面,它与竞争条件、线程安全、锁定等有关。在 12.3 版中,我们围绕此添加了一些功能。

特别是,我们添加了可以在计算过程中锁定文件(或本地对象)的WithLock函数,从而防止尝试写入文件的不同进程之间的干扰。WithLock提供了一种低级机制来确保操作的原子性和线程安全性。

在LocalSymbol 中有一个更高级别的版本。假设一个本地符号设置为 0:

代码语言:javascript
复制
LocalSymbol["/tmp/counter"] = 0
0

然后启动 40 个本地并行内核(它们需要是本地的,以便共享文件):

代码语言:javascript
复制
LaunchKernels[40];

现在,由于锁定,计数器将被迫在每个内核上按顺序更新:

代码语言:javascript
复制
LocalSymbol["/tmp/counter"]
40

想了解更多:

  • 观看 Wolfram 博士的12.3直播: https://www.youtube.com/watch?v=7e0R92lnxSs&ab_channel=wechat
  • 注册观看 Wolfram U 12.3 新功能培训讲座: https://www.bigmarker.com/series/new-in-12-3/series_details?utm_bmcr_source=wechat
  • 下载版本12.3(Wolfram 云已经是最新版本了!) https://wolfram.com/get-upgrade/
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WOLFRAM 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 许多新的小便利
  • 很多事情变得更快
  • 推动数学前沿
  • 符号优化突破
  • 更多图形
  • 欧几里得遇见笛卡尔......
  • 更多的可视化
  • 金结和其他材料事项
  • 树!
  • 日期、时间以及地球转动的速度有多快?
  • 机器学习和神经网络的前沿
  • 新视频
  • 化学方面的更多功能
  • 控制系统的闭环
  • 在笔记本中输入代码将变得更容易
  • 该代码有什么问题?代码分析与协助
  • 编译器的进步:可移植性和库
  • Shell、Java、...:新的内置外部连接
  • 区块链、存储、认证和密码学
  • 分布式计算及其管理
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档