2012-11-21 13 views
8

I bir işlevMatlab: bir fonksiyonu ikinci dönen değeri alıcı bir işlev kolu oluşturan

f = @(c)foo(c) 

, örneğin kullanılacak olan kolu düşünürsek bir işlev foo

[a b] = foo(c). 

olarak tanımlanan olduğunu varsayalım Bir cellfun çağrısında, ne olsun yani

a = foo(c) 

gibi tanımlanmış bir foo için eşit davranıyor bir f olduğunu döndürülen değer b kaybolur. Böyle bir f bir cellfun çağrı konduğunda

nedenle, çıkış hücresi sadece a s olacak ve (Şu anda umurumda) b s özleyeceğim. Görme

cellfun(f,input) 

    [a(input{1})]   ? 
    [a(input{2})]   ? 
    ....   b gets killed along the way 

Soru: nasıl foo hangi yakalar sadece b ler bir fonksiyon kolu tanımlamak için? yania s israf

b = foo(c) 

örneğin,^2, gibi foo bir tanımı benzer bir davranış veren.

Ayrıca, mümkündür (verimli) bir benzersizcellfun çağrısında hem a ve b yakalamak? Kaynaktan

cevap

4

documentation of cellfun:

[A1, ..., Am] = cellfun (işlev, C1, ..., Cn) işlevi kolu fonksiyon belirtilen işlevini çağırır ve hücre dizileri öğeler geçer C1, ..., Cn, burada n, func işlevini sağlayan girişlerin sayısıdır. Çıkış dizileri A1, ..., Am, burada m fonksiyonun işlevinden çıkış sayısıdır, işlev çağrılarından gelen çıktıları içerir.

Evet, cellfun çok çıkışlı bir işlevi kullanabilir ve bu durumda yalnızca birkaç çıktı döndürür. Sadece ikinci olanı kullanmak istiyorsanız, ilkini yok saymak için ~'u kullanabilirsiniz. Aynı anonim işlevlerin çoklu çıktıları için de geçerlidir - eğer specify multiple output arguments ise bunlar size iade edilecektir.

function test 
    x{1} = 1; 
    x{2} = 2; 
    [~, B] = cellfun(@foo, x); 
    [email protected](c)foo(c); 
    [A, B] = f(1); 

    function [a b] = foo(x) 
     a = x+1; 
     b = x+2; 
    end 
end 
+0

Güzel n'inci çıkışını döndüren bir kolu oluşturabilir; Benim durumumda [A, B] ve '[~, B]' değil, matlab versiyonum desteklemiyor. Yani ikinci noktaya başarıyla cevap verildi! Bir lambda tanımında ikinci döndürülen argümanı almanın genel problemini hala görebiliyorum. Öyle değil mi? – Acorbe

+0

@Acorbe Güncellenmiş yanıtlara bakın. Tam olarak aynıdır - bir işlevin bildirimini değiştiremezsiniz, ancak anonim işlev çağrınıza birden çok çıktı belirtebilirsiniz. – angainor

+0

Ben de görüyorum .. Hala [A, B] = foo 'şeyler yapmak gerekmez bir şey arıyorum. Özellikle retro uyumluluk sorunları için. Gerçekten de, bir fob'u başka bir fonksiyonda (non-function tutamacı), lambda aromasını kaybetmek de olabilir. Dikkatlice okumamış olduğum kılavuzun bir kısmını vurguladığınız için teşekkür ederiz. – Acorbe

0

on Bu, birden fazla çıkışa sahip bir fonksiyonun, fonksiyon bir çıkış olarak bir hücre dizisi kullanılarak yapılabilir: Basit bir koddur.

bir hücre dizisi dönmek için işlev tanımlayın (ya da orijinal çoklu-çıkış işlevini çağıran bir yardımcı işlev oluşturmak):

function F = foo2(x) 
    [a,b,c] = foo(x); 
    F = {a, b, c}; 
end 

Ve sonra işlevini çağırır ve tek alan bir kolu oluşturabilir Hücre dizisinden hücrelerin. Neredeyse tam olarak soran ne olduğunu

f = @(x) cell(foo2(x)){2} % This selects the second output 
g = @(x) cell(foo2(x)){3} % This selects the third output 

. Hatta o `cellfun` çağrıyı ilgilendiren her ne çalışmış,

f = @(x,n) cell(foo2(x)){n}