【Wolfram 到底有多厉害】- 神奇代码系列 03
在Programming Puzzles & Code Golf Stack Exchange上有人发起了这么一个游戏(popularity contest - Showcase your language one vote at a time ):每个回答者选一种编程语言,先说一点关于这门语言的有趣事实;然后,如果获得N个赞,就可以添上长度从1到N不等的至多N条代码片段(中间可以跳过一些数字)来展示这门语言的各种特性。
目前(北京时间2017年1月28日16时)排在第一位的语言是Mathematica,获得了427个赞,比起Python、MATLAB之类的更是不知高到哪里去了。
这个回答的作者是Martin Büttner, 由知乎回答者 AlephAlpha 汉化翻译, 这里已或授权转发, 并且我再整理补充一点内容, 中文链接您可以在最下阅读原文找到链接.
另外,这里的很多代码片段仅适用于Mathematica 10及以上版本。
猜猜看?这就是数学中神秘的常数圆周率 Pi。它不是用浮点数表示的近似值,它就是 Pi 的精确值,因此涉及到 Pi 的复变函数和三角函数的运算可以得到精确的结果。
你可以在 神奇代码 I 中的 2016 One-Linear Coding 大赛一等奖中见到另一个常数 E 的巧妙应用.
把两个东西放在一起,就可以做乘法,不需要添加*或者空格,只要能明确识别出一个标识符的结束和另一个标识符的开始。乘法的因数还可以是字符串或者未赋值的变量。
只是展示一下 "事实" 里说的:不需要知道 x 的值,也能算出结果是0, Wolfram 语言最强大的特性就是处理符号计算.
该展示一下Mathematica中各种疯狂的内建函数了。这段代码可以给出你所在的地理位置;比如说,最初作者的运行结果是GeoPosition[{51.51, -0.09}]。(看来作者在伦敦.)而正在编辑微博的我地址在.... (可以尝试找下)
也可以在【穿过半个地球去见你】见到 Here 的一个有趣应用.
Mathematica把颜色作为一种内建类型,还包含了一批预定义的颜色。更好的是,Mathematica会把它显示成一个这种颜色的小方块.
你可以复制这个小方块,把它用在你的代码当中,就像使用别的符号一样。更多颜色应用可以查看: 【颜色和字体样式】
让我们回到数学。在Mathematica中,你可以用从2到36的各种不同的进制来输入数字,可以用大写或小写字母,也可以混用。还可以用这种方法来输入浮点数。这里输入是23进制的H5,结果是396
Mathematica中不仅有表示阶乘的运算符(!),还有表示双阶乘的运算符(!!)(n的双阶乘是n*(n-2)*(n-4)*...)。而且,它还支持任意精度的整数,因此43!!可以算出精确值。此外,有理数也会被精确地计算。因此,这里Mathematica不会给出一个浮点数的结果,而是把它约分,最终给出上面的化简后的结果. 当然,只要你需要,也可以随时进行浮点数的运算。一般地,如果你的输入不含浮点数,就会得到精确的结果。
又一个疯狂的内建函数。不给任何参数的话,这个函数会返回你所在的地方的下一次日落的时间。也可以输入日期和地点作为参数。这是转载重新再次运行的结果.
到这里还没有做过复数运算。你可以看到,Pi 只是 Pi 的一个别名。这段代码会返回精确的答案:整数 - 1。
Mathematica 10 中新增了@*这个运算符来表示一个原有的函数:Composition。上面的代码把f定义为Exp和Cos的复合:先将Cos作用于参数,然后将Exp作用于其结果。因此 f[Pi] 会返回1/E。Mathematica 10 中还有 /* 这个运算符,表示的是RightComposition, 它先应用的是左边的函数,比如说Cos /* Exp就相当于Exp@*Cos。
来点组合数学。这段代码会给出以列表l中的元素为元素的所有n元组。比如说,如果l是{1, 2, 3},n是2,你就会得到上面的结果.
偏微分。D会给出第一个参数(某个表达式)对于后面的参数的偏导数,结果以符号表达式的形式给出。所以上面的代码的意思是对 x 和 y 求偏导,Mathematica算出来是上面的结果.
首先,这里展示了另一种调用双参数的函数的方式:x~f~y是f[x, y]的中缀表达式。其次,Riffle是一个相当使用的函数,它以一个列表和一个值作为参数,然后在那个列表每相邻两个元素间插入那个值。比如说,上面的例子会在l的每相邻两个元素间插入一个" "。
这是构造列表的一种方式。Array会对从1到它的第二个参数的每一个整数调用它的第一个参数(本身也是个函数)。上面的例子会给出前9个素数的列表.
这里展示了两个更强大的特性。这整个东西是一个未命名的纯函数。类似于Python中的lambda和Ruby中的Procs。纯函数以&结尾。&这个运算符的优先级非常低,因此往往会把左边的一切东西包含进去。纯函数的参数用#来表示,有时候会在#后面添上别的东西。第一个参数是#或者#1,第二个参数是#2,以此类推。
另一个特性是Sequence(序列)。它类似于某些语言中的*。你可以把它理解为两边的括弧的列表 -- 它只是一序列的值,可以用在列表或函数的参数中。##表示纯函数的全部参数的序列,##2则表示纯函数的从第二个开始的参数的序列。所以,如果我们把上面的例子中的纯函数命名为f,那么,上面就是第二部分的结果.
Partition是一个非常实用的处理列表的函数,它有一大堆的重载。上面是作者最常用的一种形式。它会给出列表l的所以长度为2的子列表(这里的1使得子列表互相交叠)。如果l是{1, 2, 3},你会得到上面的结果.
终于有足够的字符数可以画图了。这只是绘制一维图表的一个最简单的例子。后面还会展示一些更加酷炫的图表.
Mathematica 8引进了图这个内建类型,随之而来的是一大批图论方面的函数。如果它没有这么多内建函数,它就不是 Mathematica了。上面的代码生成了一个广义的佩特森图。
嗯...非常"有用"的函数..有时,Wolfram 支持各种可能的计算的意愿走得有点太远了.
回到内建的数据。Mathematica中有一大批以Data结尾的科学领域函数,包含了任何你可能想到的数据。使用这些函数的时候,你只需要输入你想要查找数据的东西,和你想要检索的属性。上面只是一个最短的例子,Sun、Star和Age都很短,因为作者等不及要展示这一特性。
从第9版开始,Mathematica支持带单位的量。上面的例子算出来是上面的结果, 内部表示形式为.
前面展示过了微分。现在该展示积分了。Mathematica能计算定积分和不定积分。Integrate会给你一个精确的解,它能处理很多种不同的积分;NIntegrate则会给出数值解。如果你学过微积分,你会记得上面的高斯积分并没有解析解,除非把误差函数也当作是解析解。Mathematica返回的是就是上面的个结果.
又一个内建的以Data结尾的函数。对于化学元素,你不仅可以得到原子序数、熔点、名字之类的东西,还可以得到它在室温下的颜色。上面的代码给出了锌的颜色.
嘿嘿。你以为你知道这段代码干的是什么,其实你不知道。Rectangle本身只是一个函数的名字。要真正地得到一个长方形,你必须调用这个函数,给它一些参数。所以这段代码是在干什么呢?其实就上面的结果.
又一个有趣的功能。Mathematica能够求出一个函数在任意点处的泰勒展开。上面的例子给出的是反正弦函数在0处的直到9次的泰勒展开.
终于有足够的字数可以展示向量的运算了。上面的代码展示了一个2x3的矩阵乘以一个2维的列向量.
又一个有趣的绘图功能。PolarPlot绘制的是极坐标下的图像。你需要的是对每个\[Theta]给出一个 r,而不是对每个 x 给出一个 y.
又一个Data类的函数。CountryData是一个相当强大的函数。获取国家的形状仅仅是其功能的冰山一角。关于国家的数据太多了,你可以为这个函数写一本书。比如说,有一个数据叫 FemaleLiteracyFraction (表示该国家或地区的女性识字率)。你甚至可以查询关于某个属性在不同时间的数据。
该是三维的图像了。这是绘制的是重叠起来的默认参数下的一个球面和一个圆锥,看起来像一个水晶球.
分段函数 Piecewice 让你可以定义在不同区域有不同定义的函数。它显示出来就跟标准的数学表达式一样. 如果绘制它从-5到5的图像,你会得到上面第二部分的图形.
跟别的东西一样,只要可能的话,傅立叶变换算出来也是精确解.
还有更好精彩的代码展示, 我们下次再继续探索......
祝各位春节假期愉快!