2011-02-15 14 views
8

böylece bir fonksiyonu unflatten o [email protected]@[email protected] bir keyfi korkak iç içe liste expr harita için en basit yolu nedir dümdüz sonra keyfi bir iç içe liste yeniden?Mathematica:

Motivasyon: Compile sadece tam diziler (bir şey ben sadece öğrenilen - ancak hata mesajından) işleyebilir, böylece fikri düzleştirilmiş bir ifade derlenmiş sürümü ile birlikte unflatten kullanmaktır:

fPrivate=Compile[{x,y},[email protected]@expr]; 
f[x_?NumericQ,y_?NumericQ]:[email protected]@fPrivate[x,y] 

daha az genel sorununa çözüm örneği: ne aslında yapmanız gereken bazı düzene verilen bir değişkenli fonksiyonun kadar tüm türevleri hesaplamaktır. Bu işleri

expr=Table[D[x^2 y+y^3,{{x,y},k}],{k,0,2}]; 
unflatten=Module[{f,x,y,a,b,sslot,tt}, 
    tt=Table[D[f[x,y],{{x,y},k}],{k,0,2}] /. 
    {Derivative[a_,b_][_][__]-> x[a,b], f[__]-> x[0,0]}; 
    (Evaluate[tt/.MapIndexed[#1->sslot[#2[[1]]]&, 
      Flatten[tt]]/. sslot-> Slot]&) ] 

Out[1]= {x^2 y + y^3, {2 x y, x^2 + 3 y^2}, {{2 y, 2 x}, {2 x, 6 y}}} 
Out[2]= {#1, {#2, #3}, {{#4, #5}, {#5, #7}}} & 

ama şık ne de genel de: Bu durumda, ben şöyle boyunca yolumu kesmek. Düzenleme

: Burada AAZ tarafından sağlanan çözümün "iş güvenliği" sürümü:

In[2]= makeUnflatten[expr] 
Out[2]= {#1,{#2,#3},{{#4,#5},{#6,#7}}}& 
+0

Bunu test etmedim, ancak Leonid Shifrin'in 'rearrangeAs' modifikasyonu http://stackoverflow.com/questions/4811082/applying-transformation-of-gatherby-to-a-different-list/4811794# 4811794 –

+0

Teşekkürler, Yaroslav: Bu kesinlikle ilgili görünüyor - ama grok için biraz zor :). Ben hiç kimse ısırırsa göndereceğim bir şey kendimi yapıyorum sona erdi ... Aynı hikaye her zaman: 1) özel durum için sorunu çözmek, 2) daha genel bir çözüm eğlenceli olabilir, 3) teğet üzerinde zaman israf önlemek için Diğerleri için teğet çalışmalarınızı yapmak için SO üzerine gönderin, 4) kendiniz de yapın. – Janus

+0

Sigh Bu soru görünüyor ilgili http://stackoverflow.com/questions/3807976/inverse-of-flatten-in-mathematica – dbjohn

cevap

6

Liste yapısıyla ilgili bazı bilgileri kaydetmeniz gerekir, çünkü Flatten[{a,{b,c}}]==Flatten[{{a,b},c}].

ArrayQ[expr] ise, liste yapısı Dimensions[expr] tarafından verilir ve Partition ile yeniden yapılandırabilirsiniz. Örneğin.

expr = {{a, b, c}, {d, e, f}}; 
dimensions = Dimensions[expr] 

    {2,3} 

unflatten = Fold[Partition, #1, Reverse[Drop[dimensions, 1]]]&; 
expr == unflatten @ Flatten[expr] 

(. Partition adam sayfa aslında unflatten adlı benzer bir örnek vardır)


expr bir dizi değil, bu deneyebilirsiniz:

expr = {a, {b, c}}; 
indexes = Module[{i=0}, If[ListQ[#1], Map[#0, #1], ++i]& @expr] 

    {1, {2, 3}} 

slots = indexes /. {i_Integer -> Slot[i]} 

    {#1, {#2, #3}} 

unflatten = Function[Release[slots]] 

    {#1, {#2, #3}} & 

expr == unflatten @@ Flatten[expr] 
+0

Evet, ilkini birkaç kez kullandım, ama ikinci versiyon ihtiyacım olan şey - ve çok güzel bitti! Anonim tekrarlama için Yuvayı [0] kullanma bana hiç olmadı :) Teşekkürler. – Janus

+0

Sadece bunu yazarken Yuvası [0] 'hakkında öğrendim; _Neat Example_ altında, belli ki :) – aaz

+0

'Release' belgelendi mi? Bana bazı bilgiler yollayabilir mi? Ben Mma 7 kullanıyorum (M. Trott, 'Programlama' belgesiz olduğunu, ancak görebildiğim kadarıyla daha fazla bilgi vermiyor). – tomd

1

Çabaladığını ne emin değilim:

makeUnflatten[expr_List]:=Module[{i=1}, 
    [email protected]@ReplaceAll[ 
     If[ListQ[#1],Map[#0,#1],i++]&@expr, 
     i_Integer-> Slot[i]]] 

Bir çekicilik işleri Derleme ile ilgili. İşlemsel veya işlevsel ifadeleri sayısal değerler üzerinde çok hızlı bir şekilde değerlendirmek istediğinizde kullanılır, bu yüzden burada yardımcı olacağını düşünmüyorum. D tekrarlanan hesaplamalar [f ...] senin getirilmesini engellemektedir varsa, precompute ve Table[d[k]=D[f,{{x,y},k}],{k,0,kk}];

Sonra sadece kth türevini almak için ç [k] diyoruz gibi bir şeyle bunları saklayabilir.

+1

Teşekkürler. Örnek vaka için derlemeye gerek duymayacağımı kesinlikle kabul ediyorum - ama hiç kimsenin benimle çalıştığım gerçek ifadeyi yazdığım için bana teşekkür edeceğini sanmıyorum :) Benim sorum ilk cümle, her şey arka plan. – Janus

1

Sadece istediğim aaz ve Janus'un mükemmel çözümlerini güncellemek. En azından Mac OSX üzerinde Mathematica 9.0.1.0 yılında, atama

{i_Integer -> Slot[i]} 

başarısız (AAZ en çözümünü bakınız), gibi görünüyor. Bununla birlikte, bunun yerine, biz

{i_Integer :> Slot[i]} 

kullanıyoruz. Aynı durum, Janus'un "iş güvenliği" sürümündeki ReplaceAll numaralı çağrı için de geçerlidir.

İyi ölçmek için kendi işlevlerimi dahil ediyorum.

unflatten[ex_List, exOriginal_List] := 
    Module[ 
    {indexes, slots, unflat}, 
    indexes = 
    Module[ 
     {i = 0}, 
     If[ListQ[#1], Map[#0, #1], ++i] &@exOriginal 
     ]; 
    slots = indexes /. {i_Integer :> Slot[i]}; 
    unflat = Function[Release[slots]]; 
    unflat @@ ex 
    ]; 

(* example *) 
expr = {a, {b, c}}; 
expr // Flatten // unflatten[#, expr] & 

Bu işlevde orijinal ifadeyi kullanmak için bir hile gibi küçük görünebilir, ama AAZ işaret ettiği gibi, biz orijinal ifadeden bazı bilgiler gerekiyor. Eğer unflatten can, tüm gerekli bir tek işlevi sahip olmak için, tüm bunu ihtiyacı olmamakla birlikte.

başvurum Janus adlı benzer: Bir tensör için Simplify çağrıları koşutlama ediyorum. ParallelTable'u kullanarak, performansı önemli ölçüde artırabilirim, ancak işlemdeki tensör yapısını bozarım. Bu bana orijinal tensörümü yeniden yapılandırmanın basit bir yolunu sunuyor.

+0

Orijinali hala benim için iyi çalışıyor v9. MakeUnflatten'in amacı, "expr" yapısına ilişkin bilgileri anonim paket açma işlevine tam olarak saklamaktır - bu yüzden orijinal ifadeyi tutmaya gerek yoktur. – Janus

İlgili konular