设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

函数式编程和J编程语言

2014-6-3 14:07| 发布者: joejoe0332| 查看: 8166| 评论: 0|原作者: 白文, LeoXu, zhych, 海王, 中奖啦, 无若|来自: oschina

摘要: 这里是一个使用J编程语言作为例子对函数式编程所做的一个简要介绍. 用几个示例来向您展示函数式语言令人影响深刻的能力,以及它们在数学领域的应用. 讨论了使用J语言作为数学符号替代品. ...


  单位圆的绘制在数字3中展示:

   'x y'=: |:  +. rotate ^: (i. 360) 1j0
   plot x;y


  Figure 3:  单位圆的绘制


5.2 算法和流程


  Howland [How 1998]经常使用递归的Fibonacci函数描述递归和迭代过程。在J语言中,递归Fibonacci 定义如下:


fibonacci =. monad define
if. y. < 2
  do. y.
  else. (fibonacci y. - 1) + fibonacci y. - 2 
end.
)


  使用 fibonacci 计算从0开始计算10个 fibonacci 整数:


 fibonacci "0 i.11
0 1 1 2 3 5 8 13 21 34 55


  Howland [ How 1998 ]也阐述了接续(即优先次序)的概念;在表达式中,一元表达式表示计算子表达式的结果


Given a compound expression  e and a sub-expression  f of  e, the  continuation of  f in  e is the computation in  e, written as a monad, which remains to be done after first evaluating  f.  When the continuation of  f in  e is applied to the result of evaluating  f, the result is the same as evaluating the expression  e.  Let  c be the continuation of  f in  e.  The expression  e may then be written as  c f.
Continuations provide a ``factorization'' of expressions into two parts;  f which is evaluated first and  c which is later applied to the result of  f.  Continuations are helpful in the analysis of algorithms.

  用定义分析递归的fibonacci函数,fibonacci 每次递归都包含一个fibonacci函数。因此,至少有一次递归过程不是单个过程,fibonacci 函数的执行是一个递归过程。 


  定义一个一元函数fib_work,统计fibonacci的执行次数并作出评估。fib_work 是一个J语言定义的序列函数。


ib_work =. monad define
if. y. < 2
  do. 1
  else. 1 + (fib_work y. - 1) + fib_work y. - 2
end.
)


  应用fib_work计算从0到10整数递归的次数:


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

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:  分数频率的柱形图

   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'



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部