视频 | 计算万物的理论

史蒂芬·沃尔弗拉姆(Stephen Wolfram)(生于1959年8月29日)是英、美籍 [1] 计算机科学家,物理学家,商人 [2] 。他因为计算机科学、数学和理论物理学杰出的贡献而闻名。他是《一种新科学》 [3-4] (A New Kind of Science)(2002年)一书的作者。他是Mathematica的首席设计师,设计软件应用和沃尔弗拉姆阿尔法计算知识引擎。同时,他还是著名大学UIUC的兼职教授 [5] 。2012年,他被任命为美国数学协会的首席研究员 [6] 。

作为一名商人,他是软件公司Wolfram Research的创始人兼首席执行官,他曾担任Mathematica和Wolfram Alpha应答引擎的首席设计师。他最近的工作是基于知识的编程,将Mathematica的编程语言扩展并改进为现在的Wolfram语言。他的书《Wolfram语言入门》(Wolfram语言入门)于2015年出版(中文版于2017年1月出版 [7] ),Idea Makers于2016年出版。

以上转载自 百度百科;下面的视频 来自腾讯视频;后面会从知乎摘取一些例子,看看他开发的 Mathematica 有多厉害!

20分钟视频《Stephen Wolfram:计算万物的理论》

里面介绍了WolframAlpha这个神奇的工具,有点类似 搜索+计算+人工智能的专家系统

感兴趣的朋友,可以去网站 https://www.wolframalpha.com 试一试。如下图是,我想尝试64开6次方,得到的结果为2 。它能做的远比这复杂、高明得多。

下面转载的文章来源于答主AlephAlpha 对问题 “Mathematica 到底有多厉害?

(https://www.zhihu.com/question/27834147/answer/855131318)

的回答

作者:AlephAlpha
链接:https://www.zhihu.com/question/27834147/answer/38337425
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

---Begin---

在Programming Puzzles & Code Golf Stack Exchange上,有人发起了这么一个游戏(popularity contest - Showcase your language one vote at a time ):每个回答者选一种编程语言,先说一点关于这门语言的有趣事实;然后,如果获得N个赞,就可以添上长度从1到N不等的至多N条代码片段(中间可以跳过一些数字)来展示这门语言的各种特性。

目前(北京时间2015年1月28日21时)排在第一位的语言是Mathematica,获得了144个赞,恰好是第二名的两倍,比起Python、MATLAB之类的更是不知高到哪里去了。

这个回答的作者是Martin Büttner。我就搬运一下,顺便翻译一下。原回答是按从长到短排列的,我把它倒了过来,还补上了若干作者已经删掉的代码片段。翻译得不好。欢迎去看原回答,有stackexchange帐号的话可以顺便点个赞。这个问题里其它语言的回答同样精彩。

另外,这里的很多代码片段仅适用于Mathematica 10。

-----

事实

Mathematica可以执行符号操作,所以在处理变量的时候变量不需要有值。

长度为1的代码片段

π

猜猜看?这就是π。它不是用浮点数表示的近似值,它就是π的精确值,因此涉及到π的复变函数和三角函数的运算可以得到精确的结果。

长度为2的代码片段

3x

把两个东西放在一起,就可以做乘法,不需要添加*或者空格,只要能明确识别出一个标识符的结束和另一个标识符的开始。乘法的因数还可以是字符串或者未赋值的变量。

长度为3的代码片段

x-x

只是展示一下“事实”里说的:不需要知道x的值,也能算出结果是0。

长度为4的代码片段

Here

该展示一下Mathematica中各种疯狂的内建函数了。这段代码可以给出你所在的地理位置;比如说,作者的运行结果是GeoPosition[{51.51, -0.09}]。(看来作者在伦敦……)

长度为5的代码片段

Green

Mathematica把颜色作为一种内建类型,还包含了一批预定义的颜色。更好的是,Mathematica会把它显示成一个这种颜色的小方块:

你可以复制这个小方块,把它用在你的代码当中,就像使用别的符号一样。

长度为6的代码片段

23^^H5

让我们回到数学。在Mathematica中,你可以用从2到36的各种不同的进制来输入数字,可以用大写或小写字母,也可以混用。还可以用这种方法来输入浮点数。这里输入是23进制的H5,结果是396。

长度为7的代码片段

9!/43!!

Mathematica中不仅有表示阶乘的运算符(!),还有表示双阶乘的运算符(!!)(n的双阶乘是n*(n-2)*(n-4)*…)。而且,它还支持任意精度的整数,因此43!!可以算出精确值。此外,有理数也会被精确地计算。因此,这里Mathematica不会给出一个浮点数的结果,而是把它约分,最终给出:

128/198893132162463319205625

当然,只要你需要,也可以随时进行浮点数的运算。一般地,如果你的输入不含浮点数,就会得到精确的结果。

长度为8的代码片段

Sunset[]

又一个疯狂的内建函数。不给任何参数的话,这个函数会返回你所在的地方的下一次日落的时间。也可以输入日期和地点作为参数。这是作者当时运行的结果:

长度为9的代码片段

Exp[I*Pi]

到这里还没有做过复数运算。你可以看到,π只是Pi的一个别名。这段代码会返回精确的答案:整数-1。

长度为10的代码片段

f=Exp@*Cos

Mathematica 10中新增了@*这个运算符来表示一个原有的函数:Composition。上面的代码把f定义为Exp和Cos的复合:先将Cos作用于参数,然后将Exp作用于其结果。因此f[Pi]会返回1/E。Mathematica 10中还有/*这个运算符,表示的是RightComposition,它先应用的是左边的函数,比如说Cos/*Exp就相当于Exp@*Cos。

长度为11的代码片段

Tuples[l,n]

来点组合数学。这段代码会给出以列表l中的元素为元素的所有n元组。比如说,如果l是{1, 2, 3},n是2,你就会得到:

{{1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {2, 3}, {3, 1}, {3, 2}, {3, 3}}

长度为12的代码片段

D[x^y^x,x,y]

偏微分。D会给出第一个参数(某个表达式)对于后面的参数的偏导数,结果以符号表达式的形式给出。所以上面的代码的意思是∂²(x^y^x)/∂x∂y,Mathematica算出来是:

x^y^x (y^(-1 + x) + y^(-1 + x) Log[x] + x y^(-1 + x) Log[x] Log[y]) + 
  x^(1 + y^x) y^(-1 + x) Log[x] (y^x/x + y^x Log[x] Log[y])

长度为13的代码片段

l~Riffle~" "

首先,这里展示了另一种调用双参数的函数的方式:x~f~y是f[x, y]的中缀表达式。其次,Riffle是一个相当使用的函数,它以一个列表和一个值作为参数,然后在那个列表每相邻两个元素间插入那个值。比如说,上面的例子会在l的每相邻两个元素间插入一个" "。

长度为14的代码片段

Prime~Array~9

这是构造列表的一种方式。Array会对从1到它的第二个参数的每一个整数调用它的第一个参数(本身也是个函数)。上面的例子会给出前9个素数的列表:

{2, 3, 5, 7, 11, 13, 17, 19, 23}

长度为15的代码片段

{##4,#,#2,#3}&

这里展示了两个更强大的特性。这整个东西是一个未命名的纯函数。类似于Python中的lambda和Ruby中的Procs。纯函数以&结尾。&这个运算符的优先级非常低,因此往往会把左边的一切东西包含进去。纯函数的参数用#来表示,有时候会在#后面添上别的东西。第一个参数是#或者#1,第二个参数是#2,以此类推。

另一个特性是Sequence(序列)。它类似于某些语言中的*。你可以把它理解为两边的括弧的列表——它只是一序列的值,可以用在列表或函数的参数中。##表示纯函数的全部参数的序列,##2则表示纯函数的从第二个开始的参数的序列。所以,如果我们把上面的例子中的纯函数命名为f,那么,

f[1,2,3,4,5]

的结果会是

{4,5,1,2,3}

所以这个函数只是把左边的三个参数挪到右边。注意这里##4表示的是序列4, 5,并且被压平到列表当中。

长度为16的代码片段

Partition[l,2,1]

Partition是一个非常实用的处理列表的函数,它有一大堆的重载。上面是作者最常用的一种形式。它会给出列表l的所以长度为2的子列表(这里的1使得子列表互相交叠)。如果l是{1, 2, 3},你会得到

{{1, 2}, {2, 3}, {3, 4}}

长度为17的代码片段

Plot[x^x,{x,0,2}]

终于有足够的字符数可以画图了。这只是绘制一维图表的一个最简单的例子。后面还会展示一些更加酷炫的图表。

长度为18的代码片段

PetersenGraph[7,2]

Mathematica 8引进了图这个内建类型,随之而来的是一大批图论方面的函数。如果它没有这么多内建函数,它就不是Mathematica了。上面的代码生成了一个广义的佩特森图。Mathematica生成的事实上是一个可以进行各种操作的数据结构,但显示出来的就是一幅……图:

长度为19的代码片段

MandelbrotSetPlot[]

嗯……非常“有用”的函数……有时,他们支持各种可能的计算的意愿走得有点太远了……

其实这函数比这个要更有用一些:可以指定作图的区域。

长度为20的代码片段

"Sun"~StarData~"Age"

回到内建的数据。Mathematica中有一大批以Data结尾的函数,包含了任何你可能想到的数据。使用这些函数的时候,你只需要输入你想要查找数据的东西,和你想要检索的属性。上面只是一个最短的例子,Sun、Star和Age都很短,因为作者等不及要展示这一特性。

从第9版开始,Mathematica支持带单位的量。上面的例子算出来是:

Quantity[4.57*10^9, "Years"]

在Mathematica中显示成:

长度为21的代码片段

Integrate[E^(-x^2),x]

前面展示过了微分。现在该展示积分了。Mathematica能计算定积分和不定积分。Integrate会给你一个精确的解,它能处理很多种不同的积分;NIntegrate则会给出数值解。如果你学过微积分,你会记得上面的高斯积分并没有解析解,除非把误差函数也当作是解析解。Mathematica返回的是:

1/2 Sqrt[π] Erf[x]

长度为22的代码片段

30~ElementData~"Color"

又一个内建的以Data结尾的函数。对于化学元素,你不仅可以得到原子序数、熔点、名字之类的东西,还可以得到它在室温下的颜色。上面的代码给出了锌的颜色:

SlateGray

长度为23的代码片段

Rotate[Rectangle, Pi/2]

嘿嘿。你以为你知道这段代码干的是什么,其实你不知道。Rectangle本身只是一个函数的名字。要真正地得到一个长方形,你必须调用这个函数,给它一些参数。所以这段代码是在干什么呢?其实:

长度为24的代码片段

Series[ArcSin@x,{x,0,9}]

又一个有趣的功能。Mathematica能够求出一个函数在任意点处的泰勒展开。上面的例子给出的是反正弦函数在0处的直到9次的泰勒展开:

SeriesData[x, 0, {1, 0, 
 Rational[1, 6], 0, 
 Rational[3, 40], 0, 
 Rational[5, 112], 0, 
 Rational[35, 1152]}, 1, 10, 1]

显示为:

长度为25的代码片段

{{1,5},{2,3},{7,4}}.{8,9}

终于有足够的字数可以展示向量的运算了。上面的代码展示了一个2x3的矩阵乘以一个2维的列向量:

{53, 43, 92}

长度为26的代码片段

PolarPlot[Sin[5θ],{θ,0,π}]

又一个有趣的绘图功能。PolarPlot绘制的是极坐标下的图像。你需要的是对每个θ给出一个r,而不是对每个x给出一个y。

长度为27的代码片段

CountryData["ITA", "Shape"]

又一个Data。CountryData是一个相当强大的函数。获取国家的形状仅仅是其功能的冰山一角。关于国家的数据太多了,你可以为这个函数写一本书。比如说,有一个数据叫FemaleLiteracyFraction。你甚至可以查询不同时间的数据。完整的列表见Mathematica参考资料中心。

长度为28的代码片段

Graphics3D@{Sphere[],Cone[]}

该是三维的图像了。这是绘制的是重叠起来的默认参数下的一个球面和一个圆锥,看起来像一个水晶球:

在Mathematica中,你可以点击并拖动来旋转这个图形。

长度为29的代码片段

Piecewise[{{13+2x^2,x>0}},13]

Piecewice让你可以定义在不同区域有不同定义的函数。它显示出来就跟标准的数学表达式一样:

作为展示,如果绘制它从-5到5的图像,你会得到:

长度为30的代码片段

FourierTransform[E^(-x^2),x,k]

跟别的东西一样,只要可能的话,傅立叶变换算出来也是精确解:

E^(-(k^2/4))/Sqrt[2]

长度为31的代码片段

Permutations[{1,1,2,3,3,4},{3}]

再来一点组合数学。这段代码给出了由这个列表的元素组成的所有3个元素的组合。即使列表中的元素有重复,给出的组合也不会重复:

{{1, 1, 1}, {1, 1, 3}, {1, 1, 4}, {1, 3, 1}, {1, 3, 3}, {1, 3, 4}, {1, 4, 1}, {1, 4, 3}, {3, 1, 1}, {3, 1, 3}, {3, 1, 4}, {3, 3, 1}, {3, 3, 4}, {3, 4, 1}, {3, 4, 3}, {4, 1, 1}, {4, 1, 3}, {4, 3, 1}, {4, 3, 3}}

长度为32的代码片段

NumberLinePlot[x^2<2^x,{x,-2,5}]

一个不太寻常的绘图。它可以在数轴上绘制一系列不同的东西,比如说点和区间。你还可以给出一个条件,它会绘制出使条件成立的区域:

这里的箭头表示这个区域会延伸到无穷大,空心的圈圈则表示这是开区间。如果是闭区间,圈圈会变成实心。

长度为33的代码片段

ExampleData[{"TestImage","Lena"}]

Mathematica包含了一系列的范例数据,从图片、纹理、声音片段到3D模型(比如说犹他茶壶)。Lena的名字相当短,也还算出名,所以作者选择了她:

长度为34的代码片段

Solve[a*x^4+b*x^3+c*x^2+d*x==0, x]

Mathematica可以用来解方程,或者方程组。和往常一样,给出的也是符号解:

{
  {x -> 0}, 
  {x -> -(b/(3 a)) - (2^(1/3) (-b^2 + 3 a c))/(3 a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) + (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)/(3 2^(1/3) a)}, 
  {x -> -(b/(3 a)) + ((1 + I Sqrt[3]) (-b^2 + 3 a c))/(3 2^(2/3) a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) - ((1 - I Sqrt[3]) (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3))/(6 2^(1/3) a)}, 
  {x -> -(b/(3 a)) + ((1 - I Sqrt[3]) (-b^2 + 3 a c))/(3 2^(2/3) a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) - ((1 + I Sqrt[3]) (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3))/( 6 2^(1/3) a)}
}

注意解是以规则的形式给出。后面可能会有关于规则的更具体的例子。

长度为35的代码片段

StreamPlot[{x^2,y},{x,0,3},{y,0,3}]

一个非常漂亮的绘图,绘制的是一个二维向量场的流线。类似于常规的向量图,它的每一个箭头都相切于向量场;不过,箭头不是按固定的点阵来排列,而是首尾相接连成流线。如果这个向量场是流体的速度场,这些线就是流体中粒子的轨迹(我觉得作者这里说得并不准确……)。上面的例子的输出为:

长度为36的代码片段

f[1]=1
f[2]=1
f[n_]:=f[n-1] + f[n-2]

又该展示新的语言特性了。Mathematica中有几个定义函数方面的好处。首先,你可以给一个函数名提供不同的定义,只要参数的数量或类型不同。你可以用模式来描述参数的类别。而且,你还可为给单独的值添加定义。调用函数的时候,Mathematica会自动选取最特殊的定义;如果没有符合的定义,则会不进行任何计算。这使得可以以更自然的方式来定义递归函数,而不必用If来在不同情况间切换。

另一点要注意的是这里同时用到了=和:=。不同之处在于=的右边只是在定义的时候计算一次,而:=的右边则是在每次调用的时候计算。其实在定义变量的时候也可以用:=,这时变量就会有动态的值。

因此上面定义的就是斐波那契数列。不过这是一个非常低效的定义,在作者的电脑上计算前30个数就画了4秒。在后面我们会看到,只要稍作改进,甚至不用改掉递归,便能大大提高其性能。

长度为37的代码片段

l//.{a___,x_,b___,x_,c___}:>{a,x,b,c}

上一个代码片段中提到了模式。模式常被用在规则中,规则则常用于修改匹配某一模式的结构。让我们来看看这个代码片段。

{a___,x_,b___,x_,c___}:>{a,x,b,c}是一个规则。x后面跟着一个下划线(x_)是一个模式,它可以代表任意的值(这个值本身也可以是一个列表或者类似的东西)。a___则是一个序列模式(参见长度为15的代码片段),它可以代表长度为0或者更长的序列。这里x_出现了两次,说明其代表的是相同的值。因此,整个模式{a___,x_,b___,x_,c___}匹配的是一个有重复元素的列表,两个x代表的是重复的元素,a、b和c代表的是围绕这两个元素的序列。根据规则,它被替换为{a,x,b,c},也就是去掉了第二个x。

//.会重复地执行一个规则,直到找不到可以匹配这个模式的结构。因此,上面的代码会去掉列表l中所有重复的元素。不过,它的功能并不仅限于此://.会在任何层次上运用规则,因此如果l中的某个元素也是列表,这个列表中重复的元素也会被去掉。

长度为38的代码片段

RegionPlot[x^y>2&&y<x,{x,0,3},{y,0,3}]

又回到绘图。它绘制的是是条件成立的二维区域。当你想绘制一个不以显式表示区域的话,这个函数非常有用。上面的代码画出来是:

长度为39的代码片段

f[1]=1
f[2]=1
f[n_]:=f[n]=f[n-1]+f[n-2]

前面说过要把斐波那契数列的定义改得更高效。这段代码展示了menmoization在Mathematica中是多么平凡。这里唯一的改动就是在第三行增加一个f[n]=。这样,每次f计算一个新的值,比如说f[3]的时候,执行了f[3]=f[3-1]+f[3-2]。这计算了f[2]+f[1],然后把结果赋值给f[3](注意这里用的是=而非:=)。因此,每次调用f计算一个没计算过的值的时候,它就会为这个值添加一条新的定义;这一定义显然比一般的定义更特殊,因此在再次计算这个值的时候就会直接使用这个定义。

在长度为36的代码片段中,计算前30个斐波那契数画了4秒;而这里计算前300000个只需要3秒(请勿在内存太小的计算机上尝试)。

长度为40的代码片段

SortBy[PlanetData[#, "EscapeVelocity"]&]

和你预料的一样,SortBy的功能是根据一个列表中每个元素应用某个给定的函数的结果来给列表排序。不过等等,这里调用SortBy的时候并没有给它一个列表!其实,在Mathematica 10中,某些函数开始支持柯里化和部分应用。与某些纯函数式的语言不同,这不是一个语言特性,只是一批特定的函数的功能。上面这段代码返回的是一个新的函数,这个函数仅仅以一个列表为参数,并且根据前面给定的函数来为这个列表排序。当你在代码中要多次用到同一个排序规则的时候,这个用法会非常有用。

另外,这里又出现了一个Data。这是根据逃逸速度来给行星的名字排序。

长度为41的代码片段

Thread[{"foo","bar","hm"}<>{"a","b","c"}]

差点忘了Thread。如果你有两个长度相同的列表,想对位置相应的每一对元素进行某个操作。当然,你可以对列表长度进行迭代;也可以连接两个列表,转置这个矩阵,然后对每对元素进行操作。不过Thread让这一切变得更加简单。大致上,它就是把最顶层的Head(函数或类型)往下“推”一层。所以上面的代码算出来是:

{"foo"<>"a","bar"<>"b","hm"<>"c"}

而<>表示字符串的连接,因此最终的结果是:

{"fooa","barb","hmc"}

Thread这个函数非常实用。比如,如果你有一组“左边”和一组“右边”,可以用它来生成一个方程组。

长度为42的代码片段

Animate[Plot[Sin[t-x],{x,0,10}], {t,0,10}]

在Mathematica中,让东西动起来很简单,它们甚至不必是图像。你只要给出一个在每帧进行计算的表达式,以及随帧数变化的变量。上面的代码会生成一个正弦波的动画,看起来就像下面这个gif一样(啊,知乎不支持动图?那我贴图片地址好了:http://i.stack.imgur.com/EOPuu.gif):

长度为43的代码片段

HighlightGraph[graph,FindVertexCover@graph]

前面提到过图。Mathematica中有大量常用的图论方面的功能,除了解决各种图论问题的函数外,还有漂亮的可视化工具。例如上面的代码,对于给定的图graph,找出一个顶点数最小的顶点覆盖,并且将图中的这些顶点突出显示。例如,如果graph是长度为18的代码片段中的PetersenGraph[7,2]的话,会得到:

长度为44的代码片段

ArrayPlot@CellularAutomaton[110,{{1},0},100]

终于有足够多的字数来用上CellularAutomaton这个函数并画出其结果了。据作者所知,这是Mathematica中唯一一个关于元胞自动机的函数。但Stephen Wolfram似乎认为自己是元胞自动机领域的第一人,因此这个函数尤其强大。这里展示的只是它最简单的用法。它模拟的是一个一维元胞自动机的前100步,事实上它返回的是每一步的状态,因此结果是一个二维的数组。函数的第一个参数是元胞自动机的规则,可以用一个列表来详细地指定,也可以只用一个简单的数字编码。在这个例子中,作者选择了著名的图灵完备元胞自动机,Rule 110。{{1},0}定义了初始条件:单独的一个1,以及作为背景的0。在后面会展示CellularAutomaton的更多特性:它可以模拟更高维数、更大邻域、更多状态的元胞自动机。

ArrayPlot是又一个绘图的工具,用于绘制二维数组,以不同颜色的方块表示数组中不同的值。在最简单的情形下,0对应于白色,1对应于黑色。这段代码的运行结果是:

长度为45的代码片段

EdgeDetect@ExampleData@{"TestImage","Splash"}

然后是图像处理。Mathematica包含了一系列的范例数据,包括图像(例如Lena)、纹理、3D模型和声音片段。我们首先加载其中一个范例图像:

想要查找边缘?只要调用一个函数!

长度为48的代码片段

Import["http://www.google.com/doodles","Images"]

Import是一个相当强大的命令。它既可以导入磁盘中的文件,也可以下载网上的文件。它懂得很多种不同的文件格式,还可以从其中的一些(例如HTML)直接提取数据。上面的代码会下载Google Doodle页面的所有图片。

长度为52的代码片段

Manipulate[Plot[x^2a+x*b,{x,-3,3}],{a,.1,3},{b,0,3}]

这个相当好玩。你给Manipulate函数任意一个表达式,它会通过一组变量来把这个表达式参数化,然后返回一个小部件,让你可以调整这些参数,并实时地看到表达式怎样随参数的变化而变化。这里的表达式可以是某种图表。如果你要在讲座中用Mathematica演示一组解怎样随参数的变化而变化,Manipulate会特别有用。上面的代码展示了抛物线如何随系数a和b的变化而缩放和平移。

长度为59的代码片段

SphericalPlot3D[Re[Sin[θ]Cos[θ]Exp[2I*φ]],{θ,0,π},{φ,0,2π}]

还记得长度为29的代码片段里的极坐标绘图吗?我们还可以在三维中干类似的事情。事实上,Mathematica中有两个相关的函数:用于柱面坐标的RevolutionPlot3D和用于球面坐标的SphericalPlot3D。和Graphics3D一样,Mathematica中所有的三维绘图都可以自动旋转,因此你无须为寻找一个好的角度而烦恼。上面的代码绘制的是一个类似于球谐函数的东西。

长度为64的代码片段

CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},{2,2,2}}},{1,1}},i,n]

之前说过会为大家展示更多CellularAutomaton的魔法。这一代码片段计算了康威生命游戏在初始条件i下的前n步,并返回中间每一步的结果。

关于函数参数的一点说明:2是细胞状态的数量。{{2,2,2},{2,1,2},{2,2,2}}为3x3邻域中的9个细胞加权,这确保了细胞本身的状态与其周围8个细胞之和有所区分。{1,1}指的是这个元胞自动机规则取决于两个方向上距离不超过一格的细胞。最后,224是这个元胞自动机规则的数字编码。算出这个数字并不是一件容易的事情,不过Mathematica的文档里有一份还不错的教程。更复杂的元胞自动机往往不会使用数字编码,因为这个数字会特别大。后面会有相关的例子。

总之,如果令i为一个随机的点阵,n为200,用ArrayPlot绘制出结果并制成动画,就是这个样子:

(动图,图片地址:http://i.stack.imgur.com/ny4Fw.gif)

长度为69的代码片段

DSolve[r^2*R''[r]+2r*R'[r]-R[r]==0&&(R[r]==1&&R'[r]==2/.r->1),R[r],r]

回到实用的功能。除了一般的方程组,Mathematica还能解微分方程组。这个例子中的严格说来只是一个微分方程的边值问题, 不过你可以把它当成由3条方程组成的方程组来提交给DSolve。就像积分一样,DSolve用来求精确解,NDSolve则用来求数值解。上面的方程解出来是:

{{R[r] -> 1/2 r^(-(1/2) - Sqrt[5]/2) (1 - Sqrt[5] + r^Sqrt[5] + Sqrt[5] r^Sqrt[5])}}

你可以用它来进行进一步的计算或绘图。

长度为81的代码片段

CellularAutomaton[{{0,2,3,If[0<Count[#,1,2]<3,1,3]}[[#[[2,2]]+1]]&,{},{1,1}},i,n]

这是最后一个元胞自动机的例子。这是一种叫Wireworld的元胞自动机。这次不再将规则编码成一个简单的数字,一来是因为这个数字很可能会大得离谱(作者懒得把它算出来),二来是为了展示CellularAutomaton的另一种用法。这次的规则用一个纯函数来指定,这个函数接收一个细胞的邻域的状态并返回这个细胞的新状态。对于超过两种颜色/状态的元胞自动机,这是更可行的用法。

总之,下图中的i用的维基百科里的例子(两个时钟发生器和一个异或门),并让它走了50步:

(动图,图片地址:http://i.stack.imgur.com/yMhPe.gif)

事实上,这里的绘图和动画可以用一个长度为77的代码片段来完成:

ListAnimate[ArrayPlot[#,ColorRules->{0->Black,1->Blue,2->Red,3->Yellow}]&/@w]

长度为100的代码片段

GeoGraphics[{GeoStyling[Opacity[0.5]], NightHemisphere[]}, GeoBackground -> GeoStyling["ReliefMap"]]

作者一直想着以某些漂亮的Geo函数作为长度为100的代码片段,但最终在Tweet-a-Program上找到了一个漂亮的例子,因此只需要把它偷过来。上面的代码生成了一幅展示当前地球上能被太阳找到的地方的地图。它在一个浮雕地图上为夜半球覆盖上了一层半透明的阴影。

长度为143和144的代码片段

(感谢评论中

@公孙立夏

 的翻译)

最后这一刻我等了好久,有些迫不及待了。我之前提到Mathematica可以求方程的数值解,也可以解微分方程。现在我想举一个很有价值的例子。

假设在一杆上的双摆问题(即两个单摆连在一起),并且每个杆都是单位长度。每个单摆都是单位质量。在此,我也用到单位重力来缩短公式。下面143个字符的代码片段解出了这个系统运动所遵循的拉格朗日方程(未知参量为单摆的角度和角动量)。更详细的戳这里,当然,如果你熟悉拉格朗日理论的话,这只是个很简单的练习。

代码很难读,是为了这143字符的长度

d=θ@t-φ@t;NDSolve[{#''@t==-#4#2''[t]Cos@d-##3#2'@t^2Sin@d-Sin@#@t&@@@{{θ,φ,1,.5},{φ,θ,-1,1}},θ@0==2,φ@0==1,θ'@t==φ'@t==0/.t->0},{θ,φ},{t,0,60}]

Mathematica立即给出了一个非常整齐的答案,用缩略图像展示了方程的解:

但上述结果有些生硬,我们想知道双摆的运动实际是什么样子的。因此,我写了这个144个字符的代码片段,它动态展示了双摆的运动和位于下部的单摆运动的轨迹。

Graphics@{Line@{{0,0},p=θ~(h={Sin@#@#2,-Cos@#@#2}&)~t,p+φ~h~t},White,{0,0}~Circle~2.2}~Show~ParametricPlot[θ~h~u+φ~h~u,{u,0,t}]~Animate~{t,0,60}

结果如图:(动图,图片地址:http://i.stack.imgur.com/3WS9q.gif)

PS:我不得不作点弊:如果画图超过t=30,ParametricPlot将会画很少的点,并且线条将会变成锯齿状。但有趣的动力学刚好发生在这个时
间后,因此我用了这个选项PlotPoints -> 200 来使下半部分的运动更顺滑。没什么实质的区别,而且上半部分会看不出什么不同。

(译者注:如果要尝试运行这两段代码,在运行143之后,144之前,应该要加一个{θ, φ} = {θ, φ} /. %[[1]] 。作者省去了这一步。)

---

以上是全文。

最后,有兴趣的可以关注一下我的这个收藏夹,专门收集Mathematica在知乎里的各种奇妙应用:Mathematica - 收藏夹

编辑于 2018-04-17

---End---

扩展阅读:

杂谈:奇点真的临近吗?兼聊AI、区块链、类脑计算、量子计算等

朱嘉明:“元宇宙”和“后人类社会”

两个视频 | 剖析英伟达CEO真假直播的背后 - 迎接元宇宙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值