2013-07-12 38 views
5

Daha sonra scipy nsolve işleviyle çözülecek bir dizi denklemde birleştirilecek bir işlev oluşturmak istiyorum. Böyle bir işlev oluşturmak isteyen:Python'da dinamik olarak bir lambda işlevi oluşturun

xi + Xı + 1 + xi + 3 = 1

olan değişken sayısı bileşenlerin sayısına bağlı olacaktır.

f = lambda x: x[0] + x[1] - 1 

3 için: fonksiyon argüman içinde bir dizi denecek

f = lambda x: x[0] + x[1] + x[2] - 1 

I bileşenleri belirtmek:

def my_func(components): 
     for component in components: 
     ..... 
     ..... 
     return f 

Örneğin, eğer 2 bileşenden Bunu yapmanın bir yolunu bulamıyorum. Bu fonksiyonu olarak bu şekilde yapabilmek için var, diğer fonksiyonlar nsolve birlikte çözülmesi gereken:

x0 = scipy.optimize.fsolve(f, [0, 0, 0, 0 ....]) 

Herhangi bir yardım

Teşekkür mutluluk duyacağız!


ben tamamen benim yapmaya çalıştığım şey bu açıklayacağız bunu yapmanın en iyi yolu olan emin değilim beri:

-Ben daha sonra olmasını iki işlevi oluşturmak için çalışıyor nsolved:

enter image description here

enter image description here

bu yüzden bir işlev Teste oluşturmak istiyorum ([bileşenlerin listesi]) beni dönebilmek Bu iki denklem (Psat (T), bileşene bağlı olarak çağırabileceğim bir işlevdir ve P bir sabittir (değer = 760)).

Örnek:

teste(['Benzene','Toluene']) 

döndürür:

xBenzene + xToluene = 1

xBenzene psát ('Benzen') + xToluene psát ('Toluen') = 760

numaralı telefon numarası:

teste(['Benzene','Toluene','Cumene']) 

bu döndürür:

xBenzene + xToluene + xCumene = 1

xBenzene psát ('Benzen') + xToluene psát ('Toluen') + xCumene * psát ('Kümen') = 760

Tüm bu x değerleri, hesaplayabileceğim ve özetleyebileceğim bir listeye dönüşen bir şey değildir. Onlar sistemde sahip olduğum bileşenlerin bir fonksiyonu olarak yaratılan değişkenlerdir ...

f = lambda *x: sum(x) - 1 

Ama bu gerçekten istediğiniz buysa emin değil:

Umut bu olurdu bu

+1

Bir lambda kullanmayın? – Ryan

+4

Bu bir [XY problemi] gibi kokuyor (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Tam olarak ne yapmaya çalışıyorsunuz, bu, lambda işlevini dinamik olarak oluşturmanın cevabın bir parçası olduğunu veya sadece yinelemek yerine bileşenlerin sayısını değiştirmenin cevabın bir parçası olduğunu düşünmenizi sağlar? Muhtemelen bunu yapmanın daha iyi bir yolu vardır. – abarnert

+1

Ayrıca, bu tür soruları soran birçok kişi, lambda işlevleri hakkında özel bir şey olduğunu düşünmektedir. Yok. "Lambda işlevi" diye bir şey bile yoktur. Bir fonksiyon, 'lambda' veya 'def' tarafından tanımlanan bir işlevdir. – abarnert

cevap

1

Ben Numpy yararlanmak ve böyle bir şey yapsın:

Aslında ne çözmeye çalıştığınız formun memesinin = b lineer denklem bir olasılıkla gereğinden az sistemidir
def teste(molecules): 
    P = np.array([Psat(molecule) for molecule in molecules]) 
    f1 = lambda x: np.sum(x) - 1 
    f2 = lambda x: np.dot(x, P) - 760 
    return f1, f2 

. aşağıdaki gibi A ve b inşa edebilirsiniz:

A = np.vstack((np.ones((len(molecules),)), 
       [Psat(molecule) for molecule in molecules])) 
b = np.array([1, 760]) 

Ve sonra bir 2 eleman vektör dönen tek lambda fonksiyonu oluşturabilirsiniz:

return lambda x: np.dot(A, x) - b 

Ama gerçekten en iyisidir sanmıyorum denklemlerinizi çözme yaklaşımı: ya da np.linalg.solve(A, b) ile alabileceğiniz tek bir çözümünüz var ya da sonsuz sayıda çözüm içeren lineer bir sisteminiz var. Bu durumda, bulmak istediğiniz şey çözüm alanında bir temel değil, tek bir nokta değil. Bu alan, girdi olarak bir işlev alan sayısal çözücüden alacağınız alan.

+0

Çok teşekkürler Jaime, tam olarak aradığım şey bu! Bu arada, bir scipy/numpy uzmanı gibi göründüğünden, kısıtları olan doğrusal olmayan denklemler sistemini çözmenin herhangi bir yolu olup olmadığını biliyor musunuz? Sorunumun çözümü bana 0 ve 1 arasında olması gerektiğinde x1 = 21 ve x2 = -22 verdi. – user2574761

2

doğrudan çeviri yapmanın en iyi yolu bulmak için yardımcı olur.

+0

Bence bu tam olarak istediği şey. +1 –

+0

Güncellenmiş soruya bir göz atın lütfen. – user2574761

+0

Bu güzel ve zarif, ben de benzer sorunlar hakkında düşünmekteyim ve * lambdalarda * x kullanmayı düşünmedim, (ya da aslında hiç kullanmadım, daha önce herhangi bir yerde, daha önce hiç kullanmadım Bunun nedeni) – usethedeathstar

0

Gerçekten bir işlevi yinelemeli olarak oluşturarak tanımlamak isterseniz, bunu yapabilirsiniz. Bunun en iyi yanıt, hatta makul bir olacağını her durumda düşünemiyorum, ama o kadar, istediğin ne:

def my_func(components): 
    f = lambda x: -1 
    for component in components: 
     def wrap(f): 
      return lambda x: component * x[0] + f(x[1:]) 
     f = wrap(f) 
    return f 

Şimdi: Tabii bu Of

>>> f = my_func([1, 2, 3]) 
>>> f([4,5,6]) 
44 

hata ayıklamak için eğlenceli olmaz. Örneğin, f([4,5]) numaralı telefonu arayarak izlemeye bakın.

4

dinamik sonra bir dize ile bir lambda inşa böyle eval fonksiyonu ile ayrıştırabilir:

a = [1, 2, 3] 

s = "lambda x: " 
s += " + ".join(["x[" + str(i) + "]" for i in xrange(0, 3)]) # Specify any range 
s += " - 1" 

print s 

f = eval(s) 
print f(a) 
+0

neden bu downvoted bir açıklama takdir edilecektir .. – cheeyos

+0

'eval' tehlikeli olabilir: http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html. Artı bu durumda, 'lambda' kullanmak mutlaka en iyi yöntem değildir. –

+1

eval yalnızca dizeyi kullanıcı girdisinden alırsanız tehlikelidir. Bu uygulamada açıkça böyle değil. Jon'un cevabı, x cinsinden tüm öğelerin toplanması gerektiğini varsayar ki bu da söz konusu olmayabilir. Sadece OP sunacak kadar esnek olan bir lambda dinamik olarak nasıl oluşturacağına dair bir örnek gösteriyorum. – cheeyos

-1
def make_constraint_function(components): 
    def constraint(vector): 
     return sum(vector[component] for component in components) - 1 
    return constraint 

Bir lambda'da yapabileceğini, ancak adlandırılmış işlev daha okunabilir olabilir. def beslenen fonksiyonlar lambda kutu ve daha fazlasını yapabilir. Fonksiyonu iyi bir doktora verdiğinizden ve programınız için uygun değişken ve fonksiyon adlarını kullandığınızdan emin olun.

İlgili konular