朱莉娅 - 相当于R中的递归sapply函数

问题描述:

我在R(onestep下面)中有一个函数,它将一个向量作为参数v,并返回一个新的向量v作为输出,它是输入向量的函数。然后我迭代这个功能niter倍,并保持每次迭代的输出向量(其不是所有具有相同的长度,并且可以偶尔也结束了具有长度为0)的另一功能iterate如下(最小示例):朱莉娅 - 相当于R中的递归sapply函数

onestep = function (v) c(v,2*v) 
iterate = function (v, niter) sapply(1:niter, function (iter) {v <<- onestep(v) 
                   return(v) }) 

例子:

v=c(1,2,3) 
iterate(v,3) 

[[1]] 
[1] 1 2 3 2 4 6 

[[2]] 
[1] 1 2 3 2 4 6 2 4 6 4 8 12 

[[3]] 
[1] 1 2 3 2 4 6 2 4 6 4 8 12 2 4 6 4 8 12 4 8 12 8 16 24 

我想知道什么是做一个返回朱莉娅所有的中间结果这样的递归函数的紧凑和惯用的方法是什么?有什么想法吗? (道歉,如果这是微不足道的,但我是新来的朱莉娅)

的紧凑和惯用前不知道,但这是我怎么会做它

onestep(v) = [v 2*v] 

function iterate(v, niter) 
    Results = Array(Array, niter) 
    Results[1] = onestep(v) 
    for idx = 2:niter 
     Results[idx] = onestep(Results[idx - 1]) 
    end 
    Results 
end 

v = [1 2 3] 
iterate(v, 3) 
+0

非常感谢 - 这对我来说非常完美!将v作为全局变量的sapply无论如何都是有点狡猾的:-)非常感谢您的善意帮助! –

+0

@TomWenseleers当然。另外,一般来说,当你从R到Julia时,你会发现你基于各种循环做了很多事情,这通常比矢量化更快。因此,在很多情况下,像'sapply'这样的东西就不会进入你的脑海。另外,如果您正在寻找性能并且来自R背景,我强烈建议您阅读Julia的性能指南,并特别注意在您的函数中使用类型转换(为简化说明,此处我没有这样做)。 –

这里是另一种方式就是有点更简洁和更真实的递归,根据您的原始问题:

v = Array[[1, 2, 3]] ## create v as an array of one dimensional arrays 
function iterate(v::Array{Array, 1}, niter::Int) 
    niter == 0 && return v[2:end] 
    push!(v, [v[end] ; 2v[end]]) 
    niter -= 1 
    iterate(v, niter) 
end 

iterate(v, 3) 
+0

感谢您的支持+1,尽管我认为我更喜欢您的其他解决方案,以提高可读性。我最后的小朱莉娅程序在这里,http://codereview.stackexchange.com/questions/134926/simulating-evolution-of-a-trait-in-an-asexual-population,如果你想评论的方式我编码它,或者如果你会看到任何明显的方式来提高性能... –

+0

@TomWenseleers是的,我与你在可读性和简单,直观的代码,而不是试图找到最习惯和简洁的方式做每一件事。我使用很多语言编写代码,所以一般更喜欢基于实现一些简单而通用的编码原则的解决方案。 –