第三轮回 跌入向量化

来源:互联网 发布:淘宝银泰百货是真是假 编辑:程序博客网 时间:2024/04/29 13:40

第三章 跌入向量化

我们到了第三个轮回,这里阴雨绵绵,令人不寒而栗.冥府守门狗用它的三个喉咙咆哮着.轮回里边站着布拉斯之神,穿着闪闪发光的金黄色斗篷,衣服里边充满了铅以使斗篷沉重地下垂-为了所有的永恒.这就是维吉尔告诉我的:”记住你的学识,一个事物越是完美,它就越是充满了痛苦或者快乐.”

这里是一个例子:

lsum <- 0  for(i in 1:length(x))   {    lsum <- lsum + log(x[i])  } 

不,不,不.
这是用C的口音说着R语言-浓烈的口音.我们可以用更简便的方式做这件事:

lsum <- sum(log(x))  

这不仅对你的腕骨非常棒(作者意思是代码量小,可以少动手指),而且运行地更快.(额外的奖励是它避免了当x为零时循环出现的bug).上面的命令能够运行是因为向量化.函数log()被用一种传统的方式向量化-它对一个向量中的元素的操作和它对每一个单独的值的操作时一样的.因此,命令:

log(c(23, 67.1)) 

和命令:

c(log(23), log(67.1))  

有相同的结果.

函数sum()以一种不同的方式被向量化–它加载整个向量并且基于整个向量产生结果.命令sum(x)和下面的命令是等同的:

x[1] + x[2] + ... + x[length(x)]  

函数prod()和sum()有点相似,但是输出更多的内容.输出内容经常上溢或者下溢(第一轮回的浮点郊区化)–使用log()和sum()普遍来讲是一种更稳定的计算.

你可以很轻易的使操作得以向量化.以第一轮回的quadratic.formula举例.如果你的操作是向量化的,那么它的结果也是向量化的如果你的输入也是向量化的.唯一的一点小瑕疵是如果你的每个输入是两个元素组成,那么函数cbind()会被用来保持跟踪这两个元素.

在双重操作像:

c(1,4) + 1:10  

向量化的过程中循环调用将会出现.
下面的代码结合了这个轮回和第二轮回:

ans <- NULLfor(i in 1:507980)  {   if(x[i] < 0) ans <- c(ans, y[i])  }  

双重循环往往是一个函数从另一种语言直接转换可以使你过来的结果.照字面意思的逐字翻译不可能是最好的主意.你最好用心想想在使用R的时候将会发生什么.照葫芦画瓢或许使你更了解其他语言.而高深的翻译或许使你对R的强大感到震惊.(为了更好地转换语言,重点是你得知道被转换语言的强大.)

如果你要转换成R语言的代码含有双重循环,三思.

如果你的函数是没有享量化的,你可以试试函数Vectorize()看看向量化后的结果.但这只是一个表面的版本-并不是本事就是向量化后的代码.Vectorize()使用了原始的函数表现出了一个循环.

一些函数引用了一个函数并且要求这个函数是被向量化-包括外部的或者集成的.

这是另一种形式的向量化:

> max(2, 100, -4, 3, 230, 5)  [1] 230> range(2, 100, -4, 3, 230, 5, c(4, -456, 9))  [1] -456 230 

这种形式的向量化把里面的参数集合当做向量.但它不是你所希望的向量化.本质上对R来讲,它是舶来品–min(),max(),range(),sum()和prod()是少有的例外.事实上,mean()并非继承自这种形式的向量化,并且不幸的是并下面的代码并不会给你报错:

> mean(2, -100, -4, 3, -230, 5)    [1] 2   

但是你稍微动三下手指就会得到正确的答案:

> mean(c(2, -100, -4, 3, -230, 5))    [1] -54  

向量化的一个原因是计算速度.对向量的操作往往存在一个循环.如果这个循环是用C实现的,那么它会比用R实现的循环快很多.在一些场合中,这是非常重要的.而在另一些场合并不是–很多年前,用R写的循环已经可以和C写的循环在速度上相媲美了.

另一个向量化的原因是它的简洁性. 命令:

volume <- width * depth * height    

清楚地表达了变量之间的关系.不管是有一个还是有一百万个变量,都将简洁地呈现.计算机的时间是廉价的,人类的时间是昂贵的.Uwe Ligges有一句格言不是这么说的吗?

Computers are cheap, and thinking hurts.   

新用户有一个非常常见的问题:” 我怎么给一组相似的对象命名?”是的,你可以这么做,但是你尽可能不要想着这么做–最好你可以向量化你的思维.把所有相似的对象放在一个列表.随后的分析和操作就会变得更加顺畅.

0 0
原创粉丝点击