2016-07-15 48 views
2

我在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 

我想知道什麼是做一個返回朱莉婭所有的中間結果這樣的遞歸函數的緊湊和慣用的方法是什麼?有什麼想法嗎? (道歉,如果這是微不足道的,但我是新來的朱莉婭)

回答

3

的緊湊和慣用前不知道,但這是我怎麼會做它

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的性能指南,並特別注意在您的函數中使用類型轉換(爲簡化說明,此處我沒有這樣做)。 –

2

這裏是另一種方式就是有點更簡潔和更真實的遞歸,根據您的原始問題:

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是的,我與你在可讀性和簡單,直觀的代碼,而不是試圖找到最習慣和簡潔的方式做每一件事。我使用很多語言編寫代碼,所以一般更喜歡基於實現一些簡單而通用的編碼原則的解決方案。 –