函数式编程和 J 编程语言 【已翻译100%】(3/3)

本文探讨了J语言在数学计算领域的强大表现力,包括实验性评估、统计分析、群论研究、多项式操作及数学证明。展示了J语言如何简化复杂的数学概念,如Fibonacci数列计算、统计图表绘制、欧拉定理验证和多项式矩阵乘法。
摘要由CSDN通过智能技术生成

5.2.1 实验

考虑一个实验,评估工作站上执行fibonacci需要多长时间。先估计fib_work 100,尽管上面已经给出递归过程的定义,但有必要给出一个迭代过程的定义以便于评估。考虑下面的函数定义:

fib_work_iter =: monad def 'fib_iter 1 1 , y.'

fib_iter =: monad define
('a' ; 'b' ; 'count') =. y.
if. count = 0
  do. b
  else. fib_iter (1 + a + b) , a , count - 1
end.
)

使用fib_work_iter可以得到与fib_work相同的统计递归次数结果:

fib_work_iter "0 i. 11
1 1 3 5 9 15 25 41 67 109 177

下面使用fib_work_iter 计算fib_work 100(精确的)。

fib_iter 100x
57887932245395525494200

最终,在工作站上执行一系列fibonacci 函数递归所使用的时间不超过20s。

使用3500 applications/sec作为估计:

0 3500 #: 57887932245395525494200x
16539409212970150141 700
   0 100 365 24 60 60 #: 16539409212970150141x
5244612256 77 234 16 49 1

最大结果是 5244612256 个世纪。

解决这一问题的一种可选的实验性方法是对递归的fibonacci定义进行计时,并从成果时间的倍数中寻找模式.

[ experiment =: (4 10 $'fibonacci ') ,. ": 4 1 $ 20 21 22 23
fibonacci 20
fibonacci 21
fibonacci 22
fibonacci 23
   t =: time "1 experiment
   t
2.75291 4.42869 7.15818 11.5908
   (1 }. t) % _1 }. t
1.60873 1.61632 1.61924

请注意赔率大概是一样的,这意味着计算fibonacci的时间应该是指数级的。执行下面的计算,作为对事件的一个估计值:

[ ratio =: (+/ % #) (1 }. t) % _1 }. t
1.61476
   0 100 365 24 60 60 rep x: ratio^100
205174677357 86 306 9 14 40

这一试验性质的方法产生了某种比 205174677357 更大的估计值. 同学们应该警惕任意试验性设计中的某些缺陷.

5.3 统计

假设我们有下面这些测试成绩.

[ scores =: 85 79 63 91 85 69 77 64 78 93 72 66 48 76 81 79
85 79 63 91 85 69 77 64 78 93 72 66 48 76 81 79
   /:~scores  NB. sort the scores
48 63 64 66 69 72 76 77 78 79 79 81 85 85 91 93

在干叶图上可以看到一条轴上有观察的单元数字值(页),还有其它轴上的更多重要的数字值(干). 这些可能是从如下这些分数中计算得来的:

stem =: 10&* @ <. @ %&10
   leaf =: 10&|
   sl_diagram =: ~.@stem ;"0 stem </. leaf
   sl_diagram /:~scores
+--+-----------+
|40|8          |
+--+-----------+
|60|3 4 6 9    |
+--+-----------+
|70|2 6 7 8 9 9|
+--+-----------+
|80|1 5 5      |
+--+-----------+
|90|1 3        |
+--+-----------+

一个更加传统的频率表可以由 fr =: +/"1 @ (=/) 的定义得出. 左边的参数是一个频率的范围,而右边的参数是一个观察值的列表.

4 5 6 7 8 9 fr <. scores%10
1 0 4 6 3 2

这个频率表可以用一个使用了内置统计库的柱形图来展示(图 4).

图 4: 分数频率的柱形图

image

pd 'new'
   pd 'type bar'
   pd 'xlabel "40" "50" "60" "70" "80" "90"'
   pd 4 5 6 7 8 9 fr <. scores%10
   pd 'show'

当掷硬币大量的次数,头朝上的数量比上投掷的总数应该会接近0.5. 然而,但是头朝上和底朝上的次数差的绝对值可能会非常巨大. 这可以使用下面的试验来描述, 结果显示在图 5 和 6 中.

toss =: >: i. n =: 500   NB. 500 coin tosses
   heads =: +/\?n$2
   ratio =: heads % toss
   diff =: |toss - 2*heads

   toss =: >: i. n =:10  NB. a small trial
   toss;ratio
+--------------------+------------------------------------------------------------+
|1 2 3 4 5 6 7 8 9 10|1 0.5 0.666667 0.75 0.6 0.666667 0.714286 0.625 0.555556 0.5|
+--------------------+------------------------------------------------------------+
   toss;diff
+--------------------+-------------------+
|1 2 3 4 5 6 7 8 9 10|1 0 1 2 1 2 3 2 1 0|
+--------------------+-------------------+

图 5: 头朝上的比率

image

图 6: 头朝上和底朝上的差值

image

5.4 Groups
我们可以从数论来试验一些基本的想法来证明J的表现力.

12 +. 5  NB. greatest common divisor
1
   27 +. 3
3
   1 2 3 4 5 6 7 8 9 10 11 12 +. 12
1 2 3 4 1 6 1 4 3 2 1 12
   NB. The numbers <: 12 which are coprime with 12
   (1 = 1 2 3 4 5 6 7 8 9 10 11 12 +. 12) #  1 2 3 4 5 6 7 8 9 10 11 12
1 5 7 11
   NB. The numbers <: 12 which have common factors with 12
   (-. 1 = 1 2 3 4 5 6 7 8 9 10 11 12 +. 12) #  1 2 3 4 5 6 7 8 9 10 11 12
2 3 4 6 8 9 10 12
   NB. 8 9 19 have common factors but do not divide 12
   ((-. 1 = 1 2 3 4 5 6 7 8 9 10 11 12 +. 12) #  1 2 3 4 5 6 7 8 9 10 11 12) | 12
0 0 0 0 4 3 2 0

接下来,我们概括这些表达式作为函数totatives和non_totatives。

totatives =: 3 : 0
p =. >: i. y.
(1 = p +. y.) # p
)
   non_totatives =: 3 : 0
p =. >: i. y.
(-. 1 = p +. y.) # p
)
   totatives 12
1 5 7 11
   totatives 28
1 3 5 9 11 13 15 17 19 23 25 27
   non_totatives 12
2 3 4 6 8 9 10 12
   non_totatives 15
3 5 6 9 10 12 15
   divisors =: 3 : 0
p =. non_totatives y.
(0 = p | y.) # p
)
   divisors "0 (12 27 100)
2 3  4  6 12  0  0   0
3 9 27  0  0  0  0   0
2 4  5 10 20 25 50 100

totatives 函数中n的数量被称为n的欧拉函数. 我们可以定义totient =: # @ totatives. 另一种隐形的定义是phi =: * -.@%@~.&.q:.

(totient "0) 100 12
40 4
   phi 100 12
40 4

欧拉定理指出给定一个整数 $i$ 与$n$互质, 然后 $modulo (n,i^{totient (n))}) = 1$. 这导致了定义:

euler =: 4 : 'x. (y.&| @ ^) totient y.'
   2 euler 19
1
   2 euler 35
1
   3 euler 28
1
   3 euler 205
1
   3 euler 200005
1

两个 totatives 中 $n$的产物 , $modulo(n)$ 是一个 totative 中 n. 我们可以使用J的表 (/) 副词看到这一点.

totatives 12
1 5 7 11
   12 | 1 5 7 11 */ 1 5 7 11
 1  5  7 11
 5  1 11  7
 7 11  1  5
11  7  5  1

我们注意到,我们有一组(封闭,单位元,逆,和关联性)。有一个表副词可以用来展示上述的结果。

table
1 : 0
u.table~ y.
:
(' ';,.x.),.({.;}.)":y.,x.u./y.
)
   12&|@* table totatives 12
+--+-----------+
|  | 1  5  7 11|
+--+-----------+
| 1| 1  5  7 11|
| 5| 5  1 11  7|
| 7| 7 11  1  5|
|11|11  7  5  1|
+--+-----------+

请注意,12的totatives的另外残基12不形成一个组。

12&|@+ table 0 , totatives 12
+--+------------+
|  | 0 1  5 7 11|
+--+------------+
| 0| 0 1  5 7 11|
| 1| 1 2  6 8  0|
| 5| 5 6 10 0  4|
| 7| 7 8  0 2  6|
|11|11 0  4 6 10|
+--+------------+

首先要考虑 totatives的值

p: 6
17
   totatives 17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   17&|@* table totatives 17
+--+-----------------------------------------------+
|  | 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16|
+--+-----------------------------------------------+
| 1| 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16|
| 2| 2  4  6  8 10 12 14 16  1  3  5  7  9 11 13 15|
| 3| 3  6  9 12 15  1  4  7 10 13 16  2  5  8 11 14|
| 4| 4  8 12 16  3  7 11 15  2  6 10 14  1  5  9 13|
| 5| 5 10 15  3  8 13  1  6 11 16  4  9 14  2  7 12|
| 6| 6 12  1  7 13  2  8 14  3  9 15  4 10 16  5 11|
| 7| 7 14  4 11  1  8 15  5 12  2  9 16  6 13  3 10|
| 8| 8 16  7 15  6 14  5 13  4 12  3 11  2 10  1  9|
| 9| 9  1 10  2 11  3 12  4 13  5 14  6 15  7 16  8|
|10|10  3 13  6 16  9  2 12  5 15  8  1 11  4 14  7|
|11|11  5 16 10  4 15  9  3 14  8  2 13  7  1 12  6|
|12|12  7  2 14  9  4 16 11  6  1 13  8  3 15 10  5|
|13|13  9  5  1 14 10  6  2 15 11  7  3 16 12  8  4|
|14|14 11  8  5  2 16 13 10  7  4  1 15 12  9  6  3|
|15|15 13 11  9  7  5  3  1 16 14 12 10  8  6  4  2|
|16|16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1|
+--+-----------------------------------------------+
和

   17&|@+ table 0 , totatives 17
+--+--------------------------------------------------+
|  | 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16|
+--+--------------------------------------------------+
| 0| 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16|
| 1| 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16  0|
| 2| 2  3  4  5  6  7  8  9 10 11 12 13 14 15 16  0  1|
| 3| 3  4  5  6  7  8  9 10 11 12 13 14 15 16  0  1  2|
| 4| 4  5  6  7  8  9 10 11 12 13 14 15 16  0  1  2  3|
| 5| 5  6  7  8  9 10 11 12 13 14 15 16  0  1  2  3  4|
| 6| 6  7  8  9 10 11 12 13 14 15 16  0  1  2  3  4  5|
| 7| 7  8  9 10 11 12 13 14 15 16  0  1  2  3  4  5  6|
| 8| 8  9 10 11 12 13 14 15 16  0  1  2  3  4  5  6  7|
| 9| 9 10 11 12 13 14 15 16  0  1  2  3  4  5  6  7  8|
|10|10 11 12 13 14 15 16  0  1  2  3  4  5  6  7  8  9|
|11|11 12 13 14 15 16  0  1  2  3  4  5  6  7  8  9 10|
|12|12 13 14 15 16  0  1  2  3  4  5  6  7  8  9 10 11|
|13|13 14 15 16  0  1  2  3  4  5  6  7  8  9 10 11 12|
|14|14 15 16  0  1  2  3  4  5  6  7  8  9 10 11 12 13|
|15|15 16  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14|
|16|16  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15|
+--+--------------------------------------------------+

最后, 考虑到定义powers 来提高totatives到欧拉力.

powers =: 3 : '(totatives y.) (y.&| @ ^) / i. 1 + totient y.'
   powers 12
1  1 1  1 1
1  5 1  5 1
1  7 1  7 1
1 11 1 11 1
   powers 17
1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1 1
1  2  4  8 16 15 13  9  1  2  4  8 16 15 13  9 1
1  3  9 10 13  5 15 11 16 14  8  7  4 12  2  6 1
1  4 16 13  1  4 16 13  1  4 16 13  1  4 16 13 1
1  5  8  6 13 14  2 10 16 12  9 11  4  3 15  7 1
1  6  2 12  4  7  8 14 16 11 15  5 13 10  9  3 1
1  7 15  3  4 11  9 12 16 10  2 14 13  6  8  5 1
1  8 13  2 16  9  4 15  1  8 13  2 16  9  4 15 1
1  9 13 15 16  8  4  2  1  9 13 15 16  8  4  2 1
1 10 15 14  4  6  9  5 16  7  2  3 13 11  8 12 1
1 11  2  5  4 10  8  3 16  6 15 12 13  7  9 14 1
1 12  8 11 13  3  2  7 16  5  9  6  4 14 15 10 1
1 13 16  4  1 13 16  4  1 13 16  4  1 13 16  4 1
1 14  9  7 13 12 15  6 16  3  8 10  4  5  2 11 1
1 15  4  9 16  2 13  8  1 15  4  9 16  2 13  8 1
1 16  1 16  1 16  1 16  1 16  1 16  1 16  1 16 1

5.5 多项式

在这部分我们将讨论多项式的表示和操作。多项式由它的系数决定,所以我们将多项式表示成一个升序的列表而不是通常的降序。例如,多项式$x^3+2x+5$被表示为了5 2 0 1.

多项式求值,我们采用如下表示:

peval =: (#. |.) ~
   5 2 0 1 peval 3
38
p.用来表示多项式求值。 
  5 2 0 1 p. 3
38

多项式的加减转化为针对同类项系数的加减:

psum =: , @ (+/ @ ,: & ,:)
   pdif =: , @ (-/ @ ,: & ,:)
   1 2 psum 1 3 1
2 5 1
   3 psum 1 3 1
4 3 1
   1 2 pdif 1 3 1
0 _1 _1

下面我们考虑多项式的积和衍生的多项式。如果我们使用乘积表,同类项的系数在表的斜对角线倾斜。倾斜副词/.可以访问这些对角线上的值。

pprod =: +/ /. @ (*/)
   1 2 pprod 1 3 1
1 5 7 2
   pderiv =: 1: }. ] * i. @ #
   pderiv 1 3 3 1
3 6 3
   p.. 1 3 3 1  NB. There is a primitive for derivative
3 6 3

为易于表示高抽象级函数,可以考虑使用元素是多项式的矩阵。我们称这个为 boxed table。例如,

[ m =: 2 2 $ 1 2 ; 1 2 1 ; 1 3 3 1 ; 1 4 6 4 1
+-------+---------+
|1 2    |1 2 1    |
+-------+---------+
|1 3 3 1|1 4 6 4 1|
+-------+---------+
   [ n =: 2 3 $ 1 2 3 ; 3 2 1 ; 1 0 1 ; 3 3 3 3 ; _1 _2 3; 3 4 5
+-------+-------+-----+
|1 2 3  |3 2 1  |1 0 1|
+-------+-------+-----+
|3 3 3 3|_1 _2 3|3 4 5|
+-------+-------+-----+

下一步,我们将定义一个新版本的psum, pdif和pprod,假设它们的参数是boxed polynomials。

psumb =: psum &. >
   pdifb =: pdif &. >
   pprodb =: pprod &. >
之后我们可以为了这些元素是多项式的矩阵定义一个矩阵乘积: 

pmp =:  psumb / . pprodb
      m pmp n
+---------------------+---------------+------------------+
|4 13 19 18 9 3       |2 4 3 6 3      |4 12 17 16 5      |
+---------------------+---------------+------------------+
|4 20 45 61 56 36 15 3|2 5 5 8 14 11 3|4 19 43 60 52 25 5|
+---------------------+---------------+------------------+
   m pmp m
+--------------------+-----------------------+
|2 9 14 10 5 1       |2 10 20 22 15 6 1      |
+--------------------+-----------------------+
|2 12 30 42 37 21 7 1|2 13 38 66 75 57 28 8 1|
+--------------------+-----------------------+
   m pmp^:0 m
+-------+---------+
|1 2    |1 2 1    |
+-------+---------+
|1 3 3 1|1 4 6 4 1|
+-------+---------+
   m pmp^:1 m
+--------------------+-----------------------+
|2 9 14 10 5 1       |2 10 20 22 15 6 1      |
+--------------------+-----------------------+
|2 12 30 42 37 21 7 1|2 13 38 66 75 57 28 8 1|
+--------------------+-----------------------+
   m pmp^:2 m
+----------------------------------------+----------------------------------------------+
|4 29 88 152 176 148 88 36 9 1           |4 31 106 217 304 309 230 123 45 10 1          |
+----------------------------------------+----------------------------------------------+
|4 35 137 323 521 613 539 353 168 55 11 1|4 37 158 418 772 1055 1094 864 513 222 66 12 1|
+----------------------------------------+----------------------------------------------+
   m pmp^:10  x: &. > m
+-------------------------------------------------...
|1024 29952 424704 3899184 26124316 136500501 5803...
+-------------------------------------------------...
|1024 31488 471040 4577232 32551980 180983051 8205...
+-------------------------------------------------...

5.6 证明

Iverson和其它的作者已经使用J语言写了数本关于数学计算的书。其中一个[Ive 1995]在[Gra 1989]使用J语言描述算法和证明。下面的例子是从[Ive 1995]摘录的。

在定理声明中,一个表达式I和另外一个r相等。我们可以在J语言中使用如下方式表示两者关系:

t=: l -: r

这是我必须匹配r,t必须是常函数1所有输入。t有时叫做 同义反复。例如,

l =: +/ @ i.     NB. Sum of integers
r =: (] * ] - 1:) % 2:

如果我们定义n= : ],右边是一个恒等函数,我们可以转化最后一个等式:

r =: (n * n - 1:) % 2:

下一步,

t =: l -: r

注意实验上呈现的, 不管输入参数为何,t总是1.

t 1 2 3 4 5 6 7 8 9
1 1 1 1 1 1 1 1 1

定理证明是从l到r的一系列恒等表达式有序组合。

l
+/ @ i.                            Definition of l
+/ @ |. i.                         Sum is associative and commutative
                                   (|. is reverse)
((+/ @ i.) + (+/ @ |. @ i.)) % 2:  Half sum of equal values
+/ @ (i. + |. @ i.) % 2:           Summation distributes over addition
+/ @ (n # n - 1:) % 2:             Each term is n -1; there are n terms
(n * n - 1:) % 2:                  Definition of multiplication
r                                  Definition of r

当然,上述证明每个表达式是都是一个简单的程序,而证明是一系列有序验证可以将一个表达式转化成另一个。

5.7 J可以作为一种数学符号

Iverson讨论了数学符号在数学计算中的作用。在这篇文章他引用了

A. N. Whitehead

通过减轻大脑不必要的工作负担,一种好的数学符号可以把精力集中在更高级的问题上,事实上增加了脑力劳动的强度。

F. Cajori

一些诸如 $a^n$, $\sqrt{n}$, $log$ $n$的数学符号仅适用于正整数,如果应用于浮点数、负数和复数,则可能导致致命错误。

A. de Morgan

数学符号,就像语言一样,并没有严格的限制而得到广泛使用,它的便利性和规定得到了大多数人的认同。

其它著名的引用是与J语言的特性有关:

Friedrich Engels

在科学中,每一种新的术语都会引发革命性的改变

Bertrand Russell

好的符号有一种一种微妙和暗示性的作用,就像一位活生生的老师一般

A. N. Whitehead, 数学的序言作者

这里有一个众所周知的错误,重复已出版的书籍和那些名人的演讲,我们应该富有创新精神并且思考我们可以做什么。事实的情况可能与我们想象的不同,文明的进步提升了数学运算的重要性,但我们却没有深入的思考他们

当然,J语言符号正变得流行,让大脑从繁琐的计算中解放出来,集中精力思考运算背后的事情。它也移除了数学计算的多义性,不要被_3(十减三)和应用程序中的-3混淆。

一种好的数学符号扩展的例子可以在Cajori的外部乘积的引用中(spelled .)找到。+/ . (矩阵乘积)被表达成一种外部的乘积推导出其它有用的外部乘积诸如+./ . 

很遗憾,J语言并没有被计算机科学广泛接受,在数学上接受就更少了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值