Mathematica alet çantanızda neler var? [kapalı]


152

Hepimiz Mathematica'nın harika olduğunu biliyoruz, ancak aynı zamanda kritik işlevsellikten yoksundur. Mathematica ile ne tür harici paketler / araçlar / kaynaklar kullanıyorsunuz?

Bu ana yazıyı, bilimsel araştırmalarda genel uygulanabilirliğe odaklanan ve mümkün olduğunca çok insanın yararlı bulacağı kaynakları içerecek şekilde düzenleyeceğim (ve başkalarını da davet etmeye). (Bir zamanlama rutini için aşağıda yaptığım gibi) küçük kod parçacıkları bile katkıda bulunmaktan çekinmeyin.

Ayrıca, Mathematica 7 ve ötesinde belgelenmemiş ve kullanışlı özellikler kendinizi buldunuz veya bazı kağıtlardan / sitelerden kazılmışlardır.

Lütfen kısa bir açıklama ekleyin veya bir şeyin neden harika olduğunu veya hangi yardımcı programı sağladığını yorumlayın. Amazon'daki bağlı kuruluş bağlantılarına sahip kitaplara bağlantı oluşturursanız, lütfen örneğin bağlantıdan sonra adınızı yazarak söz edin.


Paketler:

  1. LevelSchemeMathematica'nın iyi görünümlü grafikler üretme kabiliyetini büyük ölçüde artıran bir pakettir. Başka bir şey için değilse, o zaman çerçeve / eksen keneleri üzerinde çok daha gelişmiş kontrol için kullanırım. En yeni sürümüne SciDraw denir ve bu yıl bir süre sonra piyasaya sürülecektir.
  2. David Park's Presentation Package(50 ABD doları - güncelleme yok)
  3. Jeremy Michelson'un grassmannOpspaketi, Grassmann değişkenleri ve önemsiz olmayan iletişim ilişkileri olan operatörlerle cebir ve hesap yapmak için kaynaklar sağlar.
  4. John Brown'un GrassmannAlgebrapaketi ve Grassmann ve Clifford cebirleriyle çalışmak için kitap.
  5. RISC (Sembolik Hesaplama Araştırma Enstitüsü) Mathematica (ve diğer diller) için indirilebilecek çeşitli paketlere sahiptir. Özellikle, orada Theorema otomatik teorem ispatlamada ve en vb sembolik toplamı, fark denklemleri için paketlerin çok sayıda Algoritmik Kombinatorik grubun yazılım sayfası .

Araçlar:

  1. MASHDaniel Reeves , Mathematica v7 için betik desteği sağlayan mükemmel Perl betiğidir. (Şimdi Mathematica 8'den itibaren -scriptseçenek ile inşa edilmiştir .)
  2. Bir alternate Mathematica shellbir GNU taleb girişli (python kullanırken, * nix sadece)
  3. ColourMaths paketi, bir ifadenin parçalarını görsel olarak seçmenize ve bunları değiştirmenize olanak tanır. http://www.dbaileyconsultancy.co.uk/colour_maths/colour_maths.html

Kaynaklar:

  1. Wolfram'ın kendi deposunun MathSource, çeşitli uygulamalar için dar not defterleri varsa çok yararlıdır. Ayrıca diğer bölümlere de göz atın.

  2. Mathematica Vikikitap .

Kitabın:

  1. Mathematica programlama: gelişmiş bir giriş Leonid Shifrin (tarafından web, pdf) Eğer birden fazla şey yapmak istiyorsanız mutlaka okumalısınız için Mathematica döngüler. Burada Leonidsoruları cevaplamaktan mutluluk duyuyoruz .
  2. Mathematica ile Kuantum Yöntemleri James F. Feagin ( amazon )
  3. Stephen Wolfram'ın Matematik Kitabı ( Amazon ) ( web)
  4. Schaum'un Anahattı ( amazon )
  5. Matematiksel Hareket Halinde Stan Wagon ( amazon ) - 600 sayfa temiz örnek ve Mathematica sürüm 7'ye kadar çıkıyor. Görselleştirme teknikleri özellikle iyi, bazılarını yazarın üzerinde görebilirsiniz Demonstrations Page.
  6. Mathematica Programlama Temelleri Richard Gaylord ( pdf) - Mathematica programlama hakkında bilmeniz gerekenlerin çoğuna kısa ve öz bir giriş.
  7. Mathematica Yemek Kitabı Sal Mangano tarafından O'Reilly 2010 tarafından 832 sayfa yayınlandı. - İyi bilinen O'Reilly Yemek Kitabı tarzında yazılmıştır: Problem - Çözüm. Ara ürünler için.
  8. Mathematica ile Diferansiyel Denklemler, 3. Baskı. Elsevier 2004 Amsterdam, Martha L. Abell, James P. Braselton - 893 sayfa Yeni başlayanlar için, DE'leri ve Mathematica'yı aynı anda çözmeyi öğrenin.

Belgelenmemiş (veya nadiren belgelenmiş) özellikler:

  1. Mathematica klavye kısayollarını özelleştirme. Bkz this question.
  2. Mathematica'nın kendi işlevleri tarafından kullanılan desen ve işlevlerin nasıl denetleneceği. Görmekthis answer
  3. Mathematica'da GraphPlots için tutarlı boyut nasıl elde edilir? Bkz this question.
  4. Mathematica ile belge ve sunumlar nasıl üretilir. Bkz this question.

2
Mathematica 8 çok daha iyi kabuk komut dosyası entegrasyonu ile çıktı. wolfram.com/mathematica/new-in-8/mathematica-shell-scripts
Joshua Martell

2
+1, LevelScheme için. Bazen biraz yavaş. Ancak, onay işaretleri oluşturmak için aklı başında bir yöntemi vardır ve o zaman grafikler Gridveya buna benzer herhangi bir şey için günlük layık mizanpajlar oluşturmak çok daha kolaydır .
rcollyer

2
Bu soru yorumlarda Alexey önerdiği gibi stackoverflow.com/questions/5152551/... , burada Mathematica için etiket yeniden adlandırma önerdi: meta.stackexchange.com/questions/81152/... . Kabul ediyorsanız lütfen bir göz atın ve oy verin. Buraya gönderiyorum çünkü bu sorunun burada Mma topluluğunda çok fazla favorisi var.
Dr. belisarius

1
Hepsi, bu soru gerçekten her zamanki nedenlerden dolayı topluluk wiki olmalı: doğru cevabı yok ve her şeyden çok bir liste. Bu sorudan ötürü cömertçe kâr eden herkesten özür dilerim.
rcollyer

2
Bu sorunun cevapları yapıcıdır, yeniden açılması gerekir.
MR

Yanıtlar:


29

Daha önce de bahsettiğim bu daha önce ama en yararlı buluyorum aracı bir uygulamadır Reapve Sow/ hangi mimikler davranışını uzanır GatherBy:

SelectEquivalents[x_List,f_:Identity, g_:Identity, h_:(#2&)]:=
   Reap[Sow[g[#],{f[#]}]&/@x, _, h][[2]];

Bu, listeleri herhangi bir kritere göre gruplandırmamı ve bunları süreçte dönüştürmemi sağlar. Çalışma şekli, bir ölçüt işlevinin ( f) listedeki her öğeyi etiketlemesi, daha sonra her öğenin sağlanan ikinci bir işlev ( g) tarafından dönüştürülmesi ve belirli çıktının üçüncü bir işlev ( h) tarafından denetlenmesidir . İşlev hiki bağımsız değişkeni kabul eder: bir etiket ve o etikete sahip toplanan öğelerin listesi. Öğeleri ayarlamak varsa bunların orijinal siparişi korumak h = #1&o zaman sıralanmamış olsun Unionolduğu gibi örnekler için Reap. Ancak, ikincil işleme için kullanılabilir.

Yardımcı programının bir örneği olarak , uzamsal olarak bağımlı Hamiltonian'ı her satırın matristeki farklı bir öğe olduğu bir dosyaya çıkaran Wannier90 ile çalışıyorum.

rx ry rz i j Re[Hij] Im[Hij]

Bu listeyi bir matris kümesine dönüştürmek için aynı koordinatı içeren tüm alt listeleri topladım, eleman bilgilerini bir kurala çevirdim (yani {i, j} -> Re [Hij] + I Im [Hij]) ve daha sonra toplanan kuralları SparseArraytek bir astarla herkese dönüştürdü :

SelectEquivalents[hamlst, 
      #[[;; 3]] &, 
      #[[{4, 5}]] -> (Complex @@ #[[6 ;;]]) &, 
      {#1, SparseArray[#2]} &]

Dürüst olmak gerekirse, bu benim İsviçre Çakısı, ve karmaşık şeyleri çok basit hale getiriyor. Diğer araçlarımın çoğu alana özgüdür, bu yüzden muhtemelen bunları göndermeyeceğim. Ancak, hepsi olmasa da çoğu başvuruda bulunur SelectEquivalents.

Düzenleme : GatherByifadenin birden çok düzeyini olabildiğince basit bir şekilde gruplayamaması bakımından tamamen taklit etmez GatherBy. Ancak, Mapihtiyacım olanların çoğu için iyi çalışıyor.

Örnek : @Yaroslav Bulatov müstakil bir örnek istedi. İşte benim araştırmamdan büyük ölçüde basitleştirilmiş bir tane. Diyelim ki bir düzlemde bir takım noktalarımız var

In[1] := pts = {{-1, -1, 0}, {-1, 0, 0}, {-1, 1, 0}, {0, -1, 0}, {0, 0, 0}, 
 {0, 1, 0}, {1, -1, 0}, {1, 0, 0}, {1, 1, 0}}

ve bir dizi simetri işlemiyle nokta sayısını azaltmak istiyoruz. (Meraklı olarak, her noktanın küçük grubunu üretiyoruz .) Bu örnek için, z ekseni etrafında dört katlı bir dönüş ekseni kullanalım

In[2] := rots = RotationTransform[#, {0, 0, 1}] & /@ (Pi/2 Range[0, 3]);

Kullanarak SelectEquivalents, bu işlemler altında aynı görüntü kümesini üreten noktaları, yani eşdeğer olanları, aşağıdakileri kullanarak gruplandırabiliriz

In[3] := SelectEquivalents[ pts, Union[Through[rots[#] ] ]& ] (*<-- Note Union*)
Out[3]:= {{{-1, -1, 0}, {-1, 1, 0}, {1, -1, 0}, {1, 1, 0}},
          {{-1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {1, 0, 0}},
          {{0,0,0}}}

eşdeğer noktaları içeren 3 alt liste oluşturur. (Not, Unionburada aynı görüntünün her nokta tarafından üretilmesini sağladığından kesinlikle hayati önem taşıyor. Başlangıçta kullandım Sort, ancak bir nokta simetri ekseninde yatıyorsa, kendi ekseni etrafında ekstra bir görüntü veren rotasyonun altında değişmez. Böylece, Unionbu ekstra görüntüleri ortadan kaldırır. GatherByAynı sonucu verir.) Bu durumda, noktalar zaten kullanacağım bir formdadır, ancak her gruplamadan sadece temsili bir noktaya ihtiyacım var ve bir sayı istiyorum eşdeğer noktaların. Her noktayı dönüştürmem gerekmediği için,Identityişlevi ikinci konumda. Üçüncü işlev için dikkatli olmalıyız. Buraya iletilen ilk argüman, rotasyonun altındaki noktaların {0,0,0}, özdeş dört öğenin bir listesi olduğu ve onu kullanmanın sayıyı atacağı noktaların görüntüleri olacaktır. Bununla birlikte, ikinci argüman sadece bu etikete sahip tüm öğelerin bir listesidir, bu yüzden sadece içerecektir {0,0,0}. Kodda,

In[4] := SelectEquivalents[pts,  
             Union[Through[rots[#]]]&, #&, {#2[[1]], Length[#2]}& ]
Out[4]:= {{{-1, -1, 0}, 4}, {{-1, 0, 0}, 4}, {{0, 0, 0}, 1}}

Bu son adım,

In[5] := {#[[1]], Length[#]}& /@ Out[3]

Ancak, bu ve yukarıdaki daha az eksiksiz örnekle, minimum kodla ne kadar karmaşık dönüşümlerin mümkün olduğunu görmek kolaydır.


Orijinal Fortran77 kodu Şükran Günü 1996'da yeniden yapılandırıldı ve bu nedenle uzun yıllar türkiye olarak bilinir. F ...: D Çok güzel grafikler BTW. Beni Falicov'un canavarı hatırladı ...
Dr. belisarius

@belisarius, tarihi okumamıştım, bu komik. Wannier90'ı kullanmaya yeni başladım, ancak gördüğüm en iyi organize edilmiş ve iyi yazılmış Fortrankodlardan bazıları . Beni neredeyse kullanmayı düşünüyor Fortran...
rcollyer

Acaba SelectEquivalents'ın kendi kendine yeten bir örneğini eylemde ekleyip ekleyemeyeceğinizi merak ediyorum
Yaroslav Bulatov

@Yaroslav Bulatov, istek başına bir örnek ekledi. Bunun yardımcı olup olmadığını bana bildirin. Olmazsa ne yapabileceğimizi göreceğiz.
rcollyer

En ilginç kod snippet katkısı için bu "soru" onay işaretini alırsınız.
Timo

57

Mathematica dizüstü bilgisayar arayüzü ile ilgili güzel şeylerden biri, sadece Mathematica'yı değil herhangi bir dilde . Basit bir örnek olarak, içerilen ifadeyi değerlendirme için işletim sistemi kabuğuna geçiren yeni bir Kabuk giriş hücresi türü oluşturmayı düşünün .

İlk olarak, metinsel komutun değerlendirmesini dış kabuğa devreden bir işlev tanımlayın:

shellEvaluate[cmd_, _] := Import["!"~~cmd, "Text"]

İkinci argüman daha sonra ortaya çıkacak nedenlerden ötürü gerekli ve ihmal edilmiştir. Ardından, Shell adlı yeni bir stil oluşturmak istiyoruz :

  1. Yeni bir not defteri açın.
  2. Stil Sayfasını Biçimlendir / Düzenle ... menü öğesini seçin
  3. İletişim kutusunda, Stil adı girin: yazın Shell.
  4. Yeni stilin yanındaki hücre desteğini seçin.
  5. Hücre / İfadeyi Göster menü öğesini seçin
  6. Aşağıda verilen 6. Adım Metni ile hücre ifadesinin üzerine yazın .
  7. Bir kez daha Hücre / İfadeyi Göster menü öğesini seçin
  8. İletişim kutusunu kapatın.

6. Adım Metni olarak aşağıdaki hücre ifadesini kullanın :

Cell[StyleData["Shell"],
 CellFrame->{{0, 0}, {0.5, 0.5}},
 CellMargins->{{66, 4}, {0, 8}},
 Evaluatable->True,
 StripStyleOnPaste->True,
 CellEvaluationFunction->shellEvaluate,
 CellFrameLabels->{{None, "Shell"}, {None, None}},
 Hyphenation->False,
 AutoQuoteCharacters->{},
 PasteAutoQuoteCharacters->{},
 LanguageCategory->"Formula",
 ScriptLevel->1,
 MenuSortingValue->1800,
 FontFamily->"Courier"]

Bu ifadenin çoğu doğrudan yerleşik Program stilinden kopyalandı . Önemli değişiklikler şu satırlardır:

 Evaluatable->True,
 CellEvaluationFunction->shellEvaluate,
 CellFrameLabels->{{None, "Shell"}, {None, None}},

Evaluatablehücre için ÜSTKRKT + ENTER işlevlerini etkinleştirir. Değerlendirme CellEvaluationFunction, hücre içeriğinin ve içerik türünün bağımsız değişkenler olarak iletilmesini arayacaktır ( shellEvaluateikinci bağımsız değişkeni yoksayar). CellFrameLabelskullanıcı bu hücrenin alışılmadık olduğunu belirleyelim.

Tüm bunlar yerinde olduğunda, şimdi bir kabuk ifadesi girebilir ve değerlendirebiliriz:

  1. Yukarıdaki adımlarda oluşturulan not defterinde boş bir hücre oluşturun ve hücre desteğini seçin.
  2. Biçim / Stil / Kabuk menü öğesini seçin .
  3. Hücreye geçerli bir işletim sistemi kabuk komutu yazın (örn. Unix'te 'ls' veya Windows'ta 'dir').
  4. ÜST KARAKTER + ENTER tuşlarına basın.

Bu tanımlanmış stili merkezi olarak konumlandırılmış bir stil sayfasında tutmak en iyisidir. Ayrıca, değerlendirme fonksiyonları gibi shellEvaluateen iyi şekilde kullanarak koçanları gibi tanımlanmıştır DeclarePackage içindeinit.m . Bu iki faaliyetin de ayrıntıları bu yanıtın kapsamı dışındadır.

Bu işlevsellik ile, ilgilenilen herhangi bir sözdiziminde giriş ifadeleri içeren not defterleri oluşturulabilir. Değerlendirme işlevi saf Mathematica'da yazılabilir veya değerlendirmenin herhangi bir bölümünü veya tamamını harici bir acenteye devredebilir. Gibi değerlendirilmesini Hücre ilgili diğer kanca vardır unutmayın CellEpilog, CellPrologve CellDynamicExpression.

Yaygın bir örüntü, giriş ifadesi metnini geçici bir dosyaya yazmayı, dosyayı bir dilde derlemeyi, programı çalıştırmayı ve çıktı hücresinde nihai görüntüleme için çıktıyı yakalamayı içerir. Bu tür tam bir çözümü uygularken ele alınması gereken birçok ayrıntı vardır (hata mesajlarını düzgün bir şekilde yakalamak gibi), ancak sadece böyle şeyler yapmanın değil pratik olmanın mümkün olduğu gerçeğini takdir etmeliyiz.

Kişisel bir notta, dizüstü bilgisayar arayüzünü programlama evrenimin merkezi yapan bu gibi özellikler.

Güncelleme

Aşağıdaki yardımcı işlev bu tür hücreler oluşturmak için kullanışlıdır:

evaluatableCell[label_String, evaluationFunction_] :=
  ( CellPrint[
      TextCell[
        ""
      , "Program"
      , Evaluatable -> True
      , CellEvaluationFunction -> (evaluationFunction[#]&)
      , CellFrameLabels -> {{None, label}, {None, None}}
      , CellGroupingRules -> "InputGrouping"
      ]
    ]
  ; SelectionMove[EvaluationNotebook[], All, EvaluationCell]
  ; NotebookDelete[]
  ; SelectionMove[EvaluationNotebook[], Next, CellContents]
  )

Bu şekilde kullanılır:

shellCell[] := evaluatableCell["shell", Import["!"~~#, "Text"] &]

Şimdi, shellCell[]değerlendirilirse, giriş hücresi silinecek ve içeriğini kabuk komutu olarak değerlendiren yeni bir giriş hücresi ile değiştirilecektir.


3
@Weach +100! Keşke daha önce bilseydim! En azından benim için bu çok faydalı şeyler. Paylaşım için teşekkürler!
Leonid Shifrin

Bu oldukça şık görünüyor! CellEvaluationFunctionBen de düşük seviyeli sözdizimi kesmek için kullanılabilir.
Mr.Wizard

@Leonid En azından FrontEnd CellEvaluationFunctioniçin aradığınız kanca mı?
Mr.Wizard

2
Ek olarak: Cellhücre değerlendirmesi ile ilgili başka bir seçenek var - Evaluator -> "EvaluatorName". Anlamı "EvaluatorName"ile konfigüre edilebilir Değerlendirilmesi :: Çekirdek Yapılandırma Seçenekleri ... iletişim. Hala programlı olarak yapılandırmak mümkün olduğunu bilmiyorum ... Bu teknik Cellbir Notebook farklı s farklı MathKernels kullanmak için izin verir . Bu MathKernels, kurulu Mathematica'nın farklı sürümlerinden olabilir .
Alexey Popkov

1
@Szabolcs Bu tekniğin tüm kullanımlarım, yukarıda gösterildiği gibi bir stdin _ / _ stdout yaklaşımı veya SQL sorgusu veya HTTP işlemi gibi bağımsız bir uzaktan istek içeriyor. Sen (gibi bir Python REPL web uygulaması kurma deneyebilirsiniz bu ) kullanarak onunla etkileşim Import, ya da belki bir dış Python sürecini başlatma ve (Java kullanarak örneğin onun akışları aracılığıyla iletişim ProcessBuilder ). Eminim daha iyi bir Mathematica yolu vardır - iyi bir SO sorusu gibi geliyor :)
WReach

36

Todd Gayley (Wolfram Research) bana yerleşik işlevleri rasgele kodla "sarmayı" sağlayan güzel bir kesmek gönderdi. Bu yararlı aracı paylaşmam gerektiğini hissediyorum. Aşağıdaki Todd'un benim cevap question.

Biraz ilginç (?) Tarih: Yerleşik bir işlevi "sarmak" için bu tarz bir tarz 1994 yılında, Mathematica Journal için yazdığım ErrorHelp adlı bir pakette Robby Villegas ve ben, ironik olarak Message işlevi için icat edildi. o zamanlar. O zamandan beri birçok insan tarafından birçok kez kullanıldı. İçeriden bir hile biraz, ama bence bu yerleşik bir işlev tanımına kendi kodunu enjekte kanonik bir yol haline geldiğini söylemek adil. İşi güzel yapıyor. Elbette, $ inMsg değişkenini istediğiniz herhangi bir özel bağlama koyabilirsiniz.

Unprotect[Message];

Message[args___] := Block[{$inMsg = True, result},
   "some code here";
   result = Message[args];
   "some code here";
   result] /; ! TrueQ[$inMsg]

Protect[Message];

@Alexey Bunu anlamakta zorlanıyorum. Bunun nasıl çalıştığını açıklayabilir misiniz? Bir yerde Korumasız [Mesaj] olmamalı mı? Ve bu örnek sonsuz özyineleme içermiyor mu? Ve, ! TrueQ [$ inMsg], Block kapsamı içinde tanımlanmış ve Block dışında tanımsız $ inMsg ile anlamlı mı?
Sjoerd C. de Vries

9
@Sjoerd Anladığım kadarıyla, Unprotectgerçekten olmak zorunda, sadece dışarıda kaldı. Noktası Block(dinamik kapsam) ve $inMsgtam olarak sonsuz özyinelemeyi önlemek içindir. Çünkü $inMsgdışarıda tanımlanmamıştır (bu önemli bir gerekliliktir), ilk önce, TrueQdeğerlendirir Falseve işlevin bedenine gireriz. Ancak, işlev çağrısı gövdeye sahip olduğumuzda, durum değerlendirilir False(değişken Block tarafından yeniden tanımlandığından). Böylece, kullanıcı tanımlı kural eşleşmez ve bunun yerine yerleşik kural kullanılır.
Leonid Shifrin

1
@Leonid Teşekkürler, şimdi anladım. Çok zeki!
Sjoerd C. de Vries

1
Bu tekniğin, 1999 Geliştirici Konferansı'nda Wolfram Research'ten Robby Villegas tarafından tartışıldığını gördüm. Burada yayınlanan "Değerlendirilmemiş İfadelerle Çalışma" not defterine bakın . Bu not defterinde Robby Villegas bu hileyi "Yerleşik işlevlere yapılan çağrıları yakalamak için bloğum hilesi" alt bölümünde tartışmaktadır.
Alexey Popkov

1
@ Mr.Wizard Bunu yapmanın tek yolu bu değil. Uzun bir süre DownValuesboyunca, çalışma zamanında yeniden tanımladığınız bir sürüm kullandım , bu yazı gruplarına bakabilirsiniz. Google.com/group/comp.soft-sys.math.mathematica/… , örneğin ( SetDelayedyeniden tanımlama) . Ancak yöntemim daha az zarif, daha az sağlam, daha hataya yatkın ve özyinelemeden kopmayı daha az önemsiz kılıyor. Yani, çoğu durumda, @Alexey tarafından açıklanan yöntem eller kazanır.
Leonid Shifrin

25

Bu tam bir kaynak değil, bu yüzden burada cevaplar bölümüne atıyorum, ancak hız sorunlarını (ne yazık ki, Mathematica programlama hakkında ne büyük bir kısmı) çözerken çok yararlı buldum.

timeAvg[func_] := Module[
{x = 0, y = 0, timeLimit = 0.1, p, q, iterTimes = Power[10, Range[0, 10]]},
Catch[
 If[(x = First[Timing[(y++; Do[func, {#}]);]]) > timeLimit,
    Throw[{x, y}]
    ] & /@ iterTimes
 ] /. {p_, q_} :> p/iterTimes[[q]]
];
Attributes[timeAvg] = {HoldAll};

Kullanım basitçe timeAvg@funcYouWantToTest .

DÜZENLEME: Bay Büyücü ortadan kaldıran basit bir sürümünü sağlamıştır Throwve Catchve ayrıştırma biraz daha kolaydır:

SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ 
                     Timing @ Do[func, {5^i}]
                     ,{i, 0, 15}]

EDIT: İşte acl bir sürümü ( buradan alınır ):

timeIt::usage = "timeIt[expr] gives the time taken to execute expr, \
  repeating as many times as necessary to achieve a total time of 1s";

SetAttributes[timeIt, HoldAll]
timeIt[expr_] := Module[{t = Timing[expr;][[1]], tries = 1},
  While[t < 1., tries *= 2; t = Timing[Do[expr, {tries}];][[1]];]; 
  t/tries]

Tekrar yaptım ve kendi çantama girme zamanını hedefleyin. tnx!
Dr. belisarius

1
Bu kodla ilgili bir sorun (bu, mükemmeliyetçinin bakış açısı olabilir) atmadığımız bir şeyi yakalayabilmemiz ve bunu yanlış bir zamanlama sonucu olarak yorumlayabilmemizdir. Hem Catchve Throwbenzersiz istisna etiketleriyle kullanılmış olmalıdır.
Leonid Shifrin

2
Timo, yorumumu ekleyecek kadar sevdiğine sevindim. Bana da kredi verdiğiniz için teşekkürler. Kodumu yeniden biçimlendirme şeklinizi merak ediyorum. Kendimi okumayı kolaylaştırmak dışında kendi kodumda belirli bir yönerge izlemiyorum; yeniden biçimlendirmenizin arkasında bir düşünce okulu var mı, yoksa sadece tercih mi? Mathematica, girdiyi yeniden düzenleme biçimi nedeniyle kesin kod biçimlendirmesini teşvik etmez, ancak burada kod göndermek beni düşünmeye başlamama neden oluyor. BTW, ne demek "düşünmek Throwve Catchyerine" " Reapve Sow".
Mr.Wizard

1
@Simon, Mr.Wizard, bu yöntemi, birçok kez çağrılacak ufacık işlevlerin farklı sürümlerini zamanlamak için kullanıyorum. Mutlaka bir döngü yapısında değil, kesinlikle MMA'nın optimize ettiği yapılar içinde. Bu bağlamda bir döngünün yürütülmesi zamanlaması mantıklıdır ve performans gerçek yaşam uygulamasına yakın olacaktır. Büyük karmaşık fonksiyonların (belki de tüm başlatma hücrelerinin bile) zamanlanması için Simon'un yöntemi daha iyi bir sonuç verecektir. Sonuçta, ben göreli değerlerle daha fazla ilgileniyorum ve her iki yöntem de orada çalışması gerekir.
Timo

3
Şimdi RepeatedTimingbunu yapacak.
masterxilo

20

Internal`InheritedBlock

Geçenlerde gibi kullanışlı fonksiyon varlığını öğrendik Internal`InheritedBlockdan, Daniel Lichtblau bu mesajın resmi haber grubundaki.

Anladığım kadarıyla, Internal`InheritedBlockgiden işlevin bir kopyasının Blockkapsam içine aktarılmasına izin verir :

In[1]:= Internal`InheritedBlock[{Message},
Print[Attributes[Message]];
Unprotect[Message];
Message[x___]:=Print[{{x},Stack[]}];
Sin[1,1]
]
Sin[1,1]
During evaluation of In[1]:= {HoldFirst,Protected}
During evaluation of In[1]:= {{Sin::argx,Sin,2},{Internal`InheritedBlock,CompoundExpression,Sin,Print,List}}
Out[1]= Sin[1,1]
During evaluation of In[1]:= Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>
Out[2]= Sin[1,1]

Bu fonksiyonun, yerleşik fonksiyonları geçici olarak değiştirmesi gereken herkes için çok yararlı olabileceğini düşünüyorum!

Blok ile Karşılaştırma

Bazı işlevleri tanımlayalım:

a := Print[b]

Şimdi bu işlevin bir kopyasını Blockkapsama geçirmek istiyoruz . Saf dava istediğimizi vermiyor:

In[2]:= Block[{a = a}, OwnValues[a]]

During evaluation of In[9]:= b

Out[2]= {HoldPattern[a] :> Null}

Şimdi, ilk argümanında gecikmeli tanımı kullanmaya çalışıyorum Block(bu da belgelenmemiş bir özelliktir):

In[3]:= Block[{a := a}, OwnValues[a]]
Block[{a := a}, a]

Out[3]= {HoldPattern[a] :> a}

During evaluation of In[3]:= b

Bu durumda görüyoruz aeserlerin ama biz orijinal bir kopyasını yok aBlock kapsamın .

Şimdi deneyelim Internal`InheritedBlock:

In[5]:= Internal`InheritedBlock[{a}, OwnValues[a]]

Out[5]= {HoldPattern[a] :> Print[b]}

Kapsamın aiçindeki orijinal tanımın bir kopyasını aldık Blockve global tanımlamayı etkilemeden istediğimiz şekilde değiştirebiliriz a!


+1 Çok kullanışlı! Çantada bir araç daha ve sizin için Düzenle ayrıcalığına 10 puan daha yakın.
Mr.Wizard

Bana göre bu, erken veya geç ya da hiç ve tam değerlendirmenin bir varyantı olarak ortaya çıkıyor.
user2432923

19

Mathematica keskin bir araçtır, ancak şifrelenmemiş davranışları ve şifreli tanı mesajlarının çığları ile sizi kesebilir . Bununla başa çıkmanın bir yolu, bu deyimi izleyen fonksiyonları tanımlamaktır:

ClearAll@zot
SetAttributes[zot, ...]
zot[a_] := ...
zot[b_ /; ...] := ...
zot[___] := (Message[zot::invalidArguments]; Abort[])

Bu sık sık atlamak için cazip olduğum bir sürü kazan plakası. Özellikle prototip yaparken, Mathematica'da çok şey oluyor. Bu yüzden,define çok daha az Demirbaş ile beni disipline kalmasını sağlar.

Temel kullanımı defineşöyle:

define[
  fact[0] = 1
; fact[n_ /; n > 0] := n * fact[n-1]
]

fact[5]

120

İlk başta çok fazla görünmüyor, ancak bazı gizli faydalar var. Sağlayan ilk hizmet, defineotomatik olarak geçerli olmasıdırClearAll tanımlanan sembole . Bu, artık tanımların bulunmamasını sağlar - bir fonksiyonun ilk gelişimi sırasında yaygın bir olay.

İkinci hizmet, tanımlanan fonksiyonun otomatik olarak "kapatılması" dır. Bununla demek istediğim, fonksiyon bir mesaj verir ve tanımlardan biri ile eşleşmeyen bir argüman listesi ile çağrılırsa iptal eder:

fact[-1]

define::badargs: There is no definition for 'fact' applicable to fact[-1].
$Aborted

Bu, define çok yaygın bir hata sınıfını yakalayan .

Başka bir kolaylık, tanımlanan işlev üzerindeki öznitelikleri belirtmenin kısa bir yoludur. İşlevi yapalım Listable:

define[
  fact[0] = 1
; fact[n_ /; n > 0] := n * fact[n-1]
, Listable
]

fact[{3, 5, 8}]

{6, 120, 40320}

Tüm normal niteliklere defineek olarak, adlı ek bir niteliği kabul eder Open. Bu define, işleve tümünü yakala hata tanımının işleve eklenmesini önler :

define[
  successor[x_ /; x > 0] := x + 1
, Open
]

successor /@ {1, "hi"}

{2, successor["hi"]}

Bir işlev için birden çok özellik tanımlanabilir:

define[
  flatHold[x___] := Hold[x]
, {Flat, HoldAll}
]

flatHold[flatHold[1+1, flatHold[2+3]], 4+5]

Hold[1 + 1, 2 + 3, 4 + 5]

Daha fazla uzatmadan, işte tanımı define:

ClearAll@define
SetAttributes[define, HoldAll]
define[body_, attribute_Symbol] := define[body, {attribute}]
define[body:(_Set|_SetDelayed), attributes_List:{}] := define[CompoundExpression[body], attributes]
define[body:CompoundExpression[((Set|SetDelayed)[name_Symbol[___], _])..], attributes_List:{}] :=
  ( ClearAll@name
  ; SetAttributes[name, DeleteCases[attributes, Open]]
  ; If[!MemberQ[attributes, Open]
    , def:name[___] := (Message[define::badargs, name, Defer@def]; Abort[])
    ]
  ; body
  ;
  )
def:define[___] := (Message[define::malformed, Defer@def]; Abort[])

define::badargs = "There is no definition for '``' applicable to ``.";
define::malformed = "Malformed definition: ``";

Sergilenen uygulama ne yukarı değerleri ne de köriyi ya da basit fonksiyon tanımından daha genel kalıpları desteklemez. Bununla birlikte, yararlı olmaya devam etmektedir.


2
+1 - bu gerçekten yararlı şeyler. Benzer araçlar kullanıyorum. Makrolar (içgözlem ve diğer meta-programlama teknikleri gibi) çok güçlü olabilir, ancak genellikle Mathematica topluluğu içinde yeterince takdir edilmiyor gibi görünmektedir, ya da en azından şimdiye kadar izlenimim olmuştur.
Leonid Shifrin

Ben de benzer bir şey tanımladım. Birden fazla tanım yapmak için CompoundExpression desteği için +1, Durdur [] (daha fazla iletiden daha iyi görünüyor) ve Açık (örneğin kurucular için güzel).
masterxilo

16

Boş bir not defteri açılmadan başlayın

Mathematica'nın boş bir not defteri açıkken başlaması beni rahatsız etti. Bu not defterini bir komut dosyasıyla kapatabilirim, ancak yine de kısa bir süre açık yanıp söner. Benim hack Invisible.nbiçeren bir dosya oluşturmaktır :

Notebook[{},Visible->False]

Ve bunu da ekle Kernel\init.m:

If[Length[Notebooks["Invisible*"]] > 0, 
  NotebookClose[Notebooks["Invisible*"][[1]]]
]

SetOptions[$FrontEnd,
  Options[$FrontEnd, NotebooksMenu] /. 
    HoldPattern["Invisible.nb" -> {__}] :> Sequence[]
]

Şimdi Mathematica'yı açarak başlıyorum Invisible.nb

Daha iyi bir yol olabilir, ama bu bana iyi hizmet etti.


Özelleştirilmiş FoldveFoldList

Fold[f, x] eşittir Fold[f, First@x, Rest@x]

Bu arada, bunun Mathematica'nın gelecekteki bir versiyonuna girebileceğine inanıyorum.

Sürpriz! Halen belgelenmemiş olmasına rağmen bu uygulanmıştır. 2011 yılında Oliver Ruebenkoenig tarafından uygulandığını öğrendim, görünüşe göre bunu gönderdikten kısa bir süre sonra. Teşekkür ederim Oliver Ruebenkoenig!

Unprotect[Fold, FoldList]

Fold[f_, h_[a_, b__]] := Fold[f, Unevaluated @ a, h @ b]
FoldList[f_, h_[a_, b__]] := FoldList[f, Unevaluated @ a, h @ b]

(* Faysal's recommendation to modify SyntaxInformation *)
SyntaxInformation[Fold]     = {"ArgumentsPattern" -> {_, _, _.}};
SyntaxInformation[FoldList] = {"ArgumentsPattern" -> {_, _., {__}}};

Protect[Fold, FoldList]

Buna izin vermek için güncellendi:

SetAttributes[f, HoldAll]
Fold[f, Hold[1 + 1, 2/2, 3^3]]
f[f[1 + 1, 2/2], 3^3]

"Dinamik Bölüm"

Mathematica.SE gönderisine bakın # 7512 bu işlevin yeni versiyonu için.

Sık sık bir uzunluk dizisine göre bir liste bölmek istiyorum.

sözde kod örneği:

partition[{1,2,3,4,5,6}, {2,3,1}]

Çıktı: {{1,2}, {3,4,5}, {6}}

Ben bununla geldim:

dynP[l_, p_] := 
 MapThread[l[[# ;; #2]] &, {{0} ~Join~ Most@# + 1, #} &@Accumulate@p]

Daha sonra argüman testi de dahil olmak üzere bu ile tamamladım:

dynamicPartition[l_List, p : {_Integer?NonNegative ..}] :=
  dynP[l, p] /; Length@l >= Tr@p

dynamicPartition[l_List, p : {_Integer?NonNegative ..}, All] :=
  dynP[l, p] ~Append~ Drop[l, Tr@p] /; Length@l >= Tr@p

dynamicPartition[l_List, p : {_Integer?NonNegative ..}, n__ | {n__}] :=
  dynP[l, p] ~Join~ Partition[l ~Drop~ Tr@p, n] /; Length@l >= Tr@p

Üçüncü argüman ayrık belirtimin ötesindeki öğelere ne olduğunu kontrol eder.


Szabolcs'un Mathematica hileleri

En sık kullandığım, Tablo Verilerini Yapıştır Paleti

CreatePalette@
 Column@{Button["TSV", 
    Module[{data, strip}, 
     data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
     strip[s_String] := 
      StringReplace[s, RegularExpression["^\\s*(.*?)\\s*$"] -> "$1"];
     strip[e_] := e;
     If[Head[data] === String, 
      NotebookWrite[InputNotebook[], 
       ToBoxes@Map[strip, ImportString[data, "TSV"], {2}]]]]], 
   Button["CSV", 
    Module[{data, strip}, 
     data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
     strip[s_String] := 
      StringReplace[s, RegularExpression["^\\s*(.*?)\\s*$"] -> "$1"];
     strip[e_] := e;
     If[Head[data] === String, 
      NotebookWrite[InputNotebook[], 
       ToBoxes@Map[strip, ImportString[data, "CSV"], {2}]]]]], 
   Button["Table", 
    Module[{data}, data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
     If[Head[data] === String, 
      NotebookWrite[InputNotebook[], 
       ToBoxes@ImportString[data, "Table"]]]]]}

Harici verileri içeriden değiştirin Compile

Son zamanlarda Daniel Lichtblau daha önce hiç görmediğim bu yöntemi gösterdi. Benim düşünceme göre,Compile

ll = {2., 3., 4.};
c = Compile[{{x}, {y}}, ll[[1]] = x; y];

c[4.5, 5.6]

ll

(* Out[1] = 5.6  *)

(* Out[2] = {4.5, 3., 4.}  *)

3
+1 İyi bir koleksiyon! İçerideki dış değişiklikler ile ilgili olarak Compile- buradaki tüm yazım: stackoverflow.com/questions/5246330/… , bu olasılığı önemsiz bir ortamda sergilemekti (Söz konusu sorunun zaten daha kısa ve daha hızlı bir çözümü vardı) . IMO, buradaki en büyük kazanç, referansla öykünmeyi taklit etme ve büyük Derlenmiş işlevleri daha yönetilebilir ve yeniden kullanılabilir parçalara bölme yeteneğidir.
Leonid Shifrin

1
Ayrıca Fold ve FoldList sözdizimi bilgilerini yeni tanımınızda ayarlayabilirsiniz: SyntaxInformation [Fold] = {"ArgumentsPattern" -> {_ ,. , _}}; SözdizimiInformation [FoldList] = {"ArgumentsPattern" -> {_, _., {_ }}};
faysou

14

Genel PDF / EMF ihracat sorunları ve çözümleri

1) Tamamen beklenmedik ve belgesizdir, ancak Mathematica , Defterleri ekranda görüntülemek için kullanılandan farklı bir stil tanımları kümesi kullanarak PDF ve EPS formatlarında grafikleri dışa aktarır ve kaydeder. Varsayılan olarak Defterler (varsayılan değeri olan "Çalışma" tarzı bir ortamda ekranda görüntülenir ScreenStyleEvironmentküresel $FrontEndancak yazdırılır seçeneğe) "Printout"(varsayılan değer olan tarzı bir ortamda PrintingStyleEnvironmentküresel $FrontEndseçeneği). Grafikleri GIF ve PNG gibi raster formatlarında veya EMF formatı stil ortamında dışa aktarıldığında bu durumda oluşturma için kullanılır. Ancak PDF veya EPS formatlarında bir şey dışa aktardığınızda / kaydettiğinizde durum böyle değildir! Bu durumda stil ortamı varsayılan olarak kullanılır aktardığınızda Mathematica , Defter uygulamasında göründüğü gibi görünen grafikler üretir. Öyle görünüyor ki"Working""Printout""Çalışma" tarzı ortamdan çok farklı. Her şeyden önce, stil çevre setleri % 80 . İkinci olarak, farklı stillerin yazı tipi boyutları için kendi değerlerini kullanır ve bu, orijinal ekran gösterimi ile karşılaştırıldığında, oluşturulan PDF dosyasında tutarsız yazı tipi boyutu değişikliklerine neden olur. İkincisi , çok sinir bozucu FontSize dalgalanmaları olarak adlandırılabilir . Ama mutlu bu önlenebilir ayarlayarak küresel "Çalışma" seçeneği :"Printout"MagnificationPrintingStyleEnvironment$FrontEnd

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"]

2) EMF formatına dışa aktarmayla ilgili yaygın sorun, programların çoğunun (sadece Mathematica değil ) varsayılan boyutta güzel görünen, ancak yakınlaştırdığınızda çirkin hale gelen bir dosya oluşturmasıdır. Bunun nedeni, meta dosyaların ekran çözünürlüğüne uygun olarak örneklenmiş olmasıdır . Oluşturulan EMF dosyasının kalitesi Magnify, orijinal grafik nesnesinin girilmesiyle artırılabilir , böylece orijinal grafiklerin örneklemesinin kesinliği çok daha kesin hale gelir. İki dosyayı karşılaştırın:

graphics1 = 
  First@ImportString[
    ExportString[Style["a", FontFamily -> "Times"], "PDF"], "PDF"];
graphics2 = Magnify[graphics1, 10];
Export["C:\\test1.emf", graphics1]
Export["C:\\test2.emf", graphics2]

Bu dosyaları Microsoft Word'e ekleyip yakınlaştırırsanız, ilk "a" nın üzerinde testere dişi olduğunu, ikincisi ise ( Mathematica 6 ile test edildi ) görürsünüz .

Başka bir yol da Chris DegnenImageResolution tarafından önerildi (bu seçenek en azından Mathematica 8'den başlayarak etkilidir ):

Export["C:\\test1.emf", graphics1]
Export["C:\\test2.emf", graphics1, ImageResolution -> 300]

3) Gelen Mathematica biz meta dosyası grafik dönüştürmek için üç yol vardır: aracılığıyla Exportiçin "EMF"şiddetle tavsiye yolu (: aracılığıyla, mümkün olan en yüksek kalite ile meta dosyası) üretir Save selection As...(menü öğesi kesin rakam çok az üretir , önerilmez) ve üzeri Edit ► Copy As ► Metafilemenü öğesi ( şiddetle tavsiye bu rotaya karşı ).


13

Yoğun talep üzerine, ilk 10 SO yanıtlayıcısını oluşturmak için kod ( ek açıklamalar hariç ) SO API'sini kullanarak çizer .

resim açıklamasını buraya girin

getRepChanges[userID_Integer] :=
 Module[{totalChanges},
  totalChanges = 
   "total" /. 
    Import["http://api.stackoverflow.com/1.1/users/" <> 
      ToString[userID] <> "/reputation?fromdate=0&pagesize=10&page=1",
      "JSON"];
  Join @@ Table[
    "rep_changes" /. 
     Import["http://api.stackoverflow.com/1.1/users/" <> 
       ToString[userID] <> 
       "/reputation?fromdate=0&pagesize=10&page=" <> ToString[page], 
      "JSON"],
    {page, 1, Ceiling[totalChanges/10]}
    ]
  ]

topAnswerers = ({"display_name", 
      "user_id"} /. #) & /@ ("user" /. ("top_users" /. 
      Import["http://api.stackoverflow.com/1.1/tags/mathematica/top-\
answerers/all-time", "JSON"]))

repChangesTopUsers =
  Monitor[Table[
    repChange = 
     ReleaseHold[(Hold[{DateList[
              "on_date" + AbsoluteTime["January 1, 1970"]], 
             "positive_rep" - "negative_rep"}] /. #) & /@ 
        getRepChanges[userID]] // Sort;
    accRepChange = {repChange[[All, 1]], 
       Accumulate[repChange[[All, 2]]]}\[Transpose],
    {userID, topAnswerers[[All, 2]]}
    ], userID];

pl = DateListLogPlot[
  Tooltip @@@ 
   Take[({repChangesTopUsers, topAnswerers[[All, 1]]}\[Transpose]), 
    10], Joined -> True, Mesh -> None, ImageSize -> 1000, 
  PlotRange -> {All, {10, All}}, 
  BaseStyle -> {FontFamily -> "Arial-Bold", FontSize -> 16}, 
  DateTicksFormat -> {"MonthNameShort", " ", "Year"}, 
  GridLines -> {True, None}, 
  FrameLabel -> (Style[#, FontSize -> 18] & /@ {"Date", "Reputation", 
      "Top-10 answerers", ""})]

1
Brett neredeyse tam olarak bu kodu soran bir soru yayınladı . Belki de soruya uyması için bir iki ayar ile en uygunudur. Aslında bu soruya karşılık, ben değerinde olacaktır.
rcollyer

@rcollyer haklı. Bu "Topluluk Wiki"
Dr. belisarius

@belisarius Brett'in sorusunun cevabında kopyaladım ...
Sjoerd C. de Vries

@Sjoerd Buradaki Çiziminiz otomatik olarak güncellenmiyor.
Dr. belisarius

@belisarius Aslında sana bu görevi üstleneceğini umuyordum ... ;-)
Sjoerd C. de Vries

13

İfadeleri önbelleğe alma

Bu işlevleri herhangi bir ifadeyi önbelleğe almak için çok yararlı buluyorum. Bu iki işlev için ilginç olan şey, tutulan ifadenin kendisinin, yalnızca işlev f [x_]: = f [x] = ... Bu nedenle, bir kodun herhangi bir bölümünü önbelleğe alabilirsiniz, bu işlev bir işlev birkaç kez çağrılacaksa ancak kodun yalnızca bazı bölümlerinin yeniden hesaplanmaması gerektiğinde yararlıdır.

Bir ifadeyi bağımsız değişkenlerinden bağımsız olarak önbelleğe almak için.

SetAttributes[Cache, HoldFirst];
c:Cache[expr_] := c = expr;

Ex: Cache[Pause[5]; 6]
Cache[Pause[5]; 6]

İfadeyi ikinci kez beklemeden 6 döndürür.

Önbelleğe alınan ifadenin bağımsız değişkenine bağlı olabilecek bir diğer ad ifadesi kullanarak bir ifadeyi önbelleğe almak için.

SetAttributes[CacheIndex, HoldRest];
c:CacheIndex[index_,expr_] := c = expr;

Ex: CacheIndex[{"f",2},x=2;y=4;x+y]

İfadenin hesaplanması biraz zaman alırsa, örneğin önbelleğe alınmış sonucu almak için {"f", 2} değerini değerlendirmek çok daha hızlı olur.

Yerelleştirilmiş bir önbelleğe sahip olmak için bu işlevlerin bir varyasyonu için (yani, önbellek Blok yapısının dışında otomatik olarak serbest bırakılır) bu gönderiye bakın Interpolation kaçının tekrarlanan çağrılar

Önbelleğe alınan değerleri silme

Bir işlevin tanım sayısını bilmediğinizde önbelleğe alınan değerleri silmek için. Tanımların argümanlarında bir yerlerde Boş olduğunu düşünüyorum.

DeleteCachedValues[f_] := 
       DownValues[f] = Select[DownValues[f], !FreeQ[Hold@#,Pattern]&];

Bir işlevin tanım sayısını bildiğinizde önbelleğe alınan değerleri silmek için (biraz daha hızlı gider).

DeleteCachedValues[f_,nrules_] := 
       DownValues[f] = Extract[DownValues[f], List /@ Range[-nrules, -1]];

Bu, bir işlevin tanımlarının DownValues ​​listelerinin sonunda olduğu, önbelleğe alınan değerlerin daha önce olduğu gerçeğini kullanır.

Veri ve nesne benzeri işlevleri saklamak için sembolleri kullanma

Ayrıca burada nesneler gibi sembolleri kullanmak için ilginç işlevler vardır.

Verileri sembollerde saklayabileceğiniz ve DownValues ​​kullanarak hızla erişebileceğiniz bilinmektedir.

mysymbol["property"]=2;

Bu sitedeki bir yayında gönderilen gönderenlere bağlı olarak aşağıdaki işlevleri kullanarak bir sembolün anahtar listesine (veya özelliklerine) erişebilirsiniz:

SetAttributes[RemoveHead, {HoldAll}];
RemoveHead[h_[args___]] := {args};
NKeys[symbol_] := RemoveHead @@@ DownValues[symbol(*,Sort->False*)][[All,1]];
Keys[symbol_] := NKeys[symbol] /. {x_} :> x;

Bir sembolün DownValues ​​içinde bulunan tüm infos görüntülemek için bu işlevi çok kullanın:

PrintSymbol[symbol_] :=
  Module[{symbolKeys},
    symbolKeys = Keys[symbol];
    TableForm@Transpose[{symbolKeys, symbol /@ symbolKeys}]
  ];

Son olarak, nesne yönelimli programlamada bir nesne gibi davranan bir sembol oluşturmanın basit bir yolu (sadece OOP'un en temel davranışını üretir, ancak sözdizimini zarif buluyorum):

Options[NewObject]={y->2};
NewObject[OptionsPattern[]]:=
  Module[{newObject},
    newObject["y"]=OptionValue[y];

    function[newObject,x_] ^:= newObject["y"]+x;
    newObject /: newObject.function2[x_] := 2 newObject["y"]+x;

    newObject
  ];

Özellikler, DownValues ​​olarak ve döndürülen Module tarafından oluşturulan sembolde gecikmiş Upvalues ​​olarak kaydedilir. Mathematica'daki Tree veri yapısındaki işlevler için olağan OO sözdizimi olan function2 sözdizimini buldum .

Her sembolün mevcut değer türlerinin listesi için bkz. Http://reference.wolfram.com/mathematica/tutorial/PatternsAndTransformationRules.html ve http://www.verbeia.com/mathematica/tips/HTMLLinks/Tricks_Misc_4.html .

Örneğin bunu deneyin

x = NewObject[y -> 3];
function[x, 4]
x.function2[5]

Http://library.wolfram.com/infocenter/MathSource/671/ adresinde bulunan InheritRules adlı bir paket kullanarak nesne mirasını taklit etmek istiyorsanız daha da ileri gidebilirsiniz.

İşlev tanımını newObject içinde değil bir tür sembolünde de saklayabilirsiniz, bu nedenle NewObject newObject yerine [newObject] türünü döndürdüyse, bunun gibi işlev ve işlev2'yi NewObject dışında (içeride değil) tanımlayabilir ve daha önce olduğu gibi kullanabilirsiniz .

function[type[object_], x_] ^:= object["y"] + x;
type /: type[object_].function2[x_] := 2 object["y"]+x;

Fonksiyon sembolünün ve fonksiyon2'nin tip sembolünde tanımlandığını görmek için UpValues ​​[type] kullanın.

Bu son sözdizimi hakkında daha fazla fikir burada tanıtıldı https://mathematica.stackexchange.com/a/999/66 .

SelectEquivalents'ın geliştirilmiş sürümü

@rcollyer: SelectEquivalents'ı yüzeye getirdiğiniz için çok teşekkürler, inanılmaz bir işlev. İşte yukarıda listelenen ve daha fazla olasılık ve seçenek kullanan gelişmiş bir SelectEquivalents sürümü, bu kullanımı kolaylaştırır.

Options[SelectEquivalents] = 
   {
      TagElement->Identity,
      TransformElement->Identity,
      TransformResults->(#2&) (*#1=tag,#2 list of elements corresponding to tag*),
      MapLevel->1,
      TagPattern->_,
      FinalFunction->Identity
   };

SelectEquivalents[x_List,OptionsPattern[]] := 
   With[
      {
         tagElement=OptionValue@TagElement,
         transformElement=OptionValue@TransformElement,
         transformResults=OptionValue@TransformResults,
         mapLevel=OptionValue@MapLevel,
         tagPattern=OptionValue@TagPattern,
         finalFunction=OptionValue@FinalFunction
      }
      ,
      finalFunction[
         Reap[
            Map[
               Sow[
                  transformElement@#
                  ,
                  {tagElement@#}
               ]&
               , 
               x
               , 
               {mapLevel}
            ] 
            , 
            tagPattern
            , 
            transformResults
         ][[2]]
      ]
   ];

Bu sürümün nasıl kullanılabileceğine ilişkin örnekler:

Mathematica Gather / Collect'i doğru kullanma

Mathematica'da PivotTable işlevini nasıl yapardınız?

Mathematica hızlı 2D binlama algoritması

Internal`Bag

Daniel Lichtblau burada büyüyen listeler için ilginç bir iç veri yapısı tanımlamaktadır.

Mathematica'da Dörtlü Uygulama

Hata ayıklama işlevleri

Bu iki gönderi, hata ayıklama için yararlı işlevlere işaret eder:

Mathematica kullanarak küçük veya büyük kodlar yazarken nasıl hata ayıklanır? tezgahı? mma hata ayıklayıcı? veya başka bir şey? (Göster)

/programming/5459735/the-clearest-way-to-represent-mathematicas-evaluation-sequence/5527117#5527117 (TraceView)

Burada, bir programın farklı bölümlerinden ifadeleri ayıklamak ve bunları bir sembolde saklamak için Reap and Sow'a dayanan başka bir işlev var.

SetAttributes[ReapTags,HoldFirst];
ReapTags[expr_]:=
   Module[{elements},
      Reap[expr,_,(elements[#1]=#2/.{x_}:>x)&];
      elements
   ];

İşte bir örnek

ftest[]:=((*some code*)Sow[1,"x"];(*some code*)Sow[2,"x"];(*some code*)Sow[3,"y"]);
s=ReapTags[ftest[]];
Keys[s]
s["x"]
PrintSymbol[s] (*Keys and PrintSymbol are defined above*)

Diğer kaynaklar

İşte öğrenme amacı için ilginç bağlantıların bir listesi:

Mathematica öğrenme kaynaklarının bir koleksiyonu

Burada güncellenmiştir: https://mathematica.stackexchange.com/a/259/66


İlgili: " Bellekli bir işlev oluşturmanın en iyi yolu ". WReach, sadece değerlerini hatırlamakla kalmayıp aynı zamanda bir dosyaya yazan ve yeniden başlatma sırasında geriye doğru okuyan basit bir fonksiyonun muhteşem bir örneğini verdi.
Alexey Popkov

1
İlgili: " Mathematica: Bir sembol için önbellek nasıl temizlenir, yani Desensiz DownValues ​​ayarını kaldır ". Bu soru, standart not kullanarak önbelleğin nasıl temizleneceğini gösterir f[x_] := f[x] = some code.
Simon

7
1 güzel simge kolaylık yok ki ortadan kaldırır bir önbelleğe alma fonksiyonu, örneğin içinde tanımının sol tarafını tekrarlamak gerek: c:Cache[expr_] := c = expr.
WReach

Güzel bir çeşidi SelectEquivalents. Yine de, en çok kullanılanı olduğu için TagOnElementvarsayılan ikinci param olarak kalırdım Identity. FinalOpİçinde ele alınabileceği gibi ben de dahil edeceğimi sanmıyorum OpOnTaggedElems. Uzunlukları yazmayı garip hale getirdiğinden, seçenek adlarını da kısaltırım. Deneyin TagFunction, TransformElement, TransformResults, ve TagPatternbunun yerine. Her ikisi de TagPatternve MapLevelişlevsellik için harika eklemeler ve genel olarak iyi bir yeniden yazma.
rcollyer

Yorumunuz için teşekkürler rcollyer. Bunu dikkate aldım ve kodun okunabilirliğini de geliştirdim. FinalFunction'ı saklıyorum çünkü Reap sonucu üzerinde çalışıyor, örneğin nihai sonucunuzu saklıyorsanız etiketlerine göre sıralamak istiyorsanız.
Faysou

12

Benim yarar fonksiyonları (ben bu soruda bahsedilen MASH yerleşik var):

pr = WriteString["stdout", ##]&;            (* More                           *)
prn = pr[##, "\n"]&;                        (*  convenient                    *)
perr = WriteString["stderr", ##]&;          (*   print                        *)
perrn = perr[##, "\n"]&;                    (*    statements.                 *)
re = RegularExpression;                     (* I wish mathematica             *)
eval = ToExpression[cat[##]]&;              (*  weren't so damn               *)
EOF = EndOfFile;                            (*   verbose!                     *)
read[] := InputString[""];                  (* Grab a line from stdin.        *)
doList[f_, test_] :=                        (* Accumulate list of what f[]    *)
  Most@NestWhileList[f[]&, f[], test];      (*  returns while test is true.   *)
readList[] := doList[read, #=!=EOF&];       (* Slurp list'o'lines from stdin. *)
cat = StringJoin@@(ToString/@{##})&;        (* Like sprintf/strout in C/C++.  *)
system = Run@cat@##&;                       (* System call.                   *)
backtick = Import[cat["!", ##], "Text"]&;   (* System call; returns stdout.   *)
slurp = Import[#, "Text"]&;                 (* Fetch contents of file as str. *)
                                            (* ABOVE: mma-scripting related.  *)
keys[f_, i_:1] :=                           (* BELOW: general utilities.      *)
  DownValues[f, Sort->False][[All,1,1,i]];  (* Keys of a hash/dictionary.     *)
SetAttributes[each, HoldAll];               (* each[pattern, list, body]      *)
each[pat_, lst_, bod_] := ReleaseHold[      (*  converts pattern to body for  *)
  Hold[Cases[Evaluate@lst, pat:>bod];]];    (*   each element of list.        *)
some[f_, l_List] := True ===                (* Whether f applied to some      *)
  Scan[If[f[#], Return[True]]&, l];         (*  element of list is True.      *)
every[f_, l_List] := Null ===               (* Similarly, And @@ f/@l         *)
  Scan[If[!f[#], Return[False]]&, l];       (*  (but with lazy evaluation).   *)


11

Kullandığım bir hile, en yerleşik işlevlerin kötü argümanlarla çalışma şeklini taklit etmenize izin verir (bir mesaj göndererek ve ardından tüm formu değerlendirmeden değerlendirerek) Condition, bir tanımda kullanıldığında çalışma şeklinin tuhaflığından yararlanır . Eğer foosadece tek bir argüman birlikte çalışmalıdır:

foo[x_] := x + 1;
expr : foo[___] /; (Message[foo::argx, foo, Length@Unevaluated[expr], 1]; 
                    False) := Null; (* never reached *)

Daha karmaşık ihtiyaçlarınız varsa, bağımsız değişken işlevi olarak bağımsız değişken doğrulamasını ve ileti oluşturmayı ortadan kaldırmak kolaydır. Yan etkileri kullanarak daha ayrıntılı şeyler yapabilirsiniz.ConditionSadece mesaj oluşturmanın ötesinde , ancak bence bunların çoğu "kalitesiz hack" kategorisine girer ve mümkünse kaçınılmalıdır.

Ayrıca, "metaprogramming" kategorisinde bir Mathematica package ( .m) dosyanız varsa, dosyadaki tüm ifadeleri içine almak için "HeldExpressions"öğeyi kullanabilirsiniz HoldComplete. Bu, metin tabanlı aramaları kullanmaktan daha kolay takip etmenizi sağlar. Ne yazık ki, aynı şeyi bir dizüstü bilgisayarla yapmanın kolay bir yolu yoktur, ancak aşağıdaki gibi bir şey kullanarak tüm giriş ifadelerini alabilirsiniz:

inputExpressionsFromNotebookFile[nb_String] :=
 Cases[Get[nb],
  Cell[BoxData[boxes_], "Input", ___] :>
   MakeExpression[StripBoxes[boxes], StandardForm],
  Infinity]

Son olarak, Modulereferans türlerinin eşdeğerini oluşturmak için sözcüksel kapanışları taklit eden gerçeğini kullanabilirsiniz . İşte basit bir yığın ( Conditionbonus olarak hata işleme için bir hile varyasyonu kullanır ):

ClearAll[MakeStack, StackInstance, EmptyQ, Pop, Push, Peek]
 With[{emptyStack = Unique["empty"]},
  Attributes[StackInstance] = HoldFirst;
  MakeStack[] :=
   Module[{backing = emptyStack},
    StackInstance[backing]];

  StackInstance::empty = "stack is empty";

  EmptyQ[StackInstance[backing_]] := (backing === emptyStack);

  HoldPattern[
    Pop[instance : StackInstance[backing_]]] /;
    ! EmptyQ[instance] || (Message[StackInstance::empty]; False) :=
   (backing = Last@backing; instance);

  HoldPattern[Push[instance : StackInstance[backing_], new_]] :=
   (backing = {new, backing}; instance);

  HoldPattern[Peek[instance : StackInstance[backing_]]] /;
    ! EmptyQ[instance] || (Message[StackInstance::empty]; False) :=
   First@backing]

Artık bir listenin elemanlarını gereksiz yere kıvrık bir şekilde ters sırada yazdırabilirsiniz!

With[{stack = MakeStack[], list},
 Do[Push[stack, elt], {elt, list}];

 While[!EmptyQ[stack],
  Print[Peek@stack];
  Pop@stack]]

1
HeldExpressionsPaketlerdeki öğe için +1 , bundan habersizdi. Genellikle dize olarak aktarmayı ve ardından kullanıyordum ToExpressionile HoldCompleteson arg. Kullanarak İlişkin Conditionmesajlar için - bu aracılığıyla kalıcılığını ilgili en az 1994 yılından bu yana ambalaj yazılı bir standart bir teknik olup Modulevars - Bir süre önce Mathgroup üzerinde bu konuda uzun bir yazı oldu: groups.google.com/group/comp.soft- sys.math.mathematica /… (bu konudaki üçüncü yazım ), bu aynı satırlar boyunca ve önemsiz olmayan birkaç kullanım örneğine bağlantılar içeriyor.
Leonid Shifrin

@Leonid Shifrin: Meseleyi Conditionbir iş arkadaşından aldım , ama bunun standart bir teknik olduğunu fark etmedim. ModuleReferans türleri olarak sembollerin kullanımı ile ilgili bağlantı ilginçtir!
Pillsy

+1, bunu hiç düşünmemiştim. Bu dil hakkında ne kadar çok şey öğrenirsem o kadar güçlü görünür.
rcollyer

@Pillsy bu şekilde bir yığın yapmanın amacı nedir?
Sihirbaz

@ Mr.Wizard: Tekniği göstermek için aklıma gelen en basit veri yapılarından birini seçtim.
Pillsy

11

Bağlam eklenmeden sistem sembol tanımlarını yazdırma

Aşağıdaki contextFreeDefinition[]işlev, en yaygın bağlam eklenmeden bir sembolün tanımını yazdırmaya çalışacaktır. Tanım daha sonra Workbench'e kopyalanabilir ve okunabilirlik için biçimlendirilebilir (seçin, sağ tıklayın, Kaynak -> Biçim)

Clear[commonestContexts, contextFreeDefinition]

commonestContexts[sym_Symbol, n_: 1] := Quiet[
  Commonest[
   Cases[Level[DownValues[sym], {-1}, HoldComplete], 
    s_Symbol /; FreeQ[$ContextPath, Context[s]] :> Context[s]], n],
  Commonest::dstlms]

contextFreeDefinition::contexts = "Not showing the following contexts: `1`";

contextFreeDefinition[sym_Symbol, contexts_List] := 
 (If[contexts =!= {}, Message[contextFreeDefinition::contexts, contexts]];
  Internal`InheritedBlock[{sym}, ClearAttributes[sym, ReadProtected];
   Block[{$ContextPath = Join[$ContextPath, contexts]}, 
    Print@InputForm[FullDefinition[sym]]]])

contextFreeDefinition[sym_Symbol, context_String] := 
 contextFreeDefinition[sym, {context}]

contextFreeDefinition[sym_Symbol] := 
 contextFreeDefinition[sym, commonestContexts[sym]]

withRules []

Uyarı: Bu işlev, değişkenleri aynı şekilde lokalize etmez Withve Moduleyapar, yani iç içe yerelleştirme yapıları beklendiği gibi çalışmaz. withRules[{a -> 1, b -> 2}, With[{a=3}, b_ :> b]] olacak yerini ave biç içe yer Withve Rulesüre,With bu yapmaz.

Bu, ve Withyerine kurallar kullanan bir varyanttır :=:=

ClearAll[withRules]
SetAttributes[withRules, HoldAll]
withRules[rules_, expr_] :=
  Internal`InheritedBlock[
    {Rule, RuleDelayed},
    SetAttributes[{Rule, RuleDelayed}, HoldFirst];
    Unevaluated[expr] /. rules
  ]

Deneme sırasında yazılan kodu temizlerken ve değişkenleri yerelleştirirken bunu yararlı buldum. Bazen sonunda parametre listeleri ile sonuçlanır {par1 -> 1.1, par2 -> 2.2}. İlewithRules parametre değerleri daha önce küresel değişkenleri kullanarak yazılı koduna enjekte etmek kolaydır.

Kullanımı aynı With:

withRules[
  {a -> 1, b -> 2},
  a+b
]

Kenar yumuşatma 3D grafikler

Bu, grafik donanımınız doğal olarak desteklemese bile 3B grafiklerin kenarlarını yumuşatmak için çok basit bir tekniktir.

antialias[g_, n_: 3] := 
  ImageResize[Rasterize[g, "Image", ImageResolution -> n 72], Scaled[1/n]]

İşte bir örnek:

Mathematica grafikleri Mathematica grafikleri

Büyük bir değerin nveya büyük bir görüntü boyutunun grafik sürücüsü hatalarını ortaya çıkarma veya artefakt oluşturma eğiliminde olduğunu unutmayın.


Dizüstü bilgisayar dif işlevselliği

Dizüstü bilgisayar dif işlevselliği <<AuthorTools`pakette ve (en azından sürüm 8'de) belgesiz NotebookTools`bağlamda kullanılabilir. Bu, şu anda açık olan iki dizüstü bilgisayarı ayırmak için küçük bir GUI'dir:

PaletteNotebook@DynamicModule[
  {nb1, nb2}, 
  Dynamic@Column[
    {PopupMenu[Dynamic[nb1], 
      Thread[Notebooks[] -> NotebookTools`NotebookName /@ Notebooks[]]], 
     PopupMenu[Dynamic[nb2], 
      Thread[Notebooks[] -> NotebookTools`NotebookName /@ Notebooks[]]], 
     Button["Show differences", 
      CreateDocument@NotebookTools`NotebookDiff[nb1, nb2]]}]
  ]

Mathematica grafikleri


Her şey güzel olurdu, ancak bu, örnek çağrınızdan önce söyleme atayarak ve sonra arayarak görebileceğiniz gibi, değişkenleri gerçekten yerelleştirmez . Bunun yerine aşağıdaki kullanarak kaydedebilirsiniz: . Semantik wrt farklılıklar sonra: şimdi kuralların 1. rhsides edilir değil 2. değerlendirdi olarak iç kapsam yapıları ile adlandırma çakışmalarını çözmez yok. Sonuncusu oldukça ciddi - duruma bağlı olarak iyi veya kötü bir şey. a = 3; b = 4;withRulesSetAttributes[withRules, HoldAll];withRules[rules_, expr_] := Unevaluated[expr] /. Unevaluated[rules]WithwithRulesWith
Leonid Shifrin

@Leonid Tamamen haklısın, görünüşe göre ben göndermeden önce kodu düzgün bir şekilde kontrol etmeyi öğrenemiyorum ... Bunu kullandığımda neredeyse hiç değişkenlere değer atamam, ama bu oldukça ciddi bir problem, haklısın. Düzeltilmiş sürüm hakkında ne düşünüyorsunuz? (İç içe Withgeçmişleri işlememeyi umursamıyorum . Bu her zaman yerleşik yerelleştirme yapılarıyla da çalışmaz, örneğin With[{a=1}, Block[{a=2}, a]]. Blockİç içe geçmiş Withve iç içe geçmiş gibi iç içe geçmenin orada yerelleşmemesinin iyi bir nedeni olduğunu düşünüyor musunuz Module?)
Szabolcs

@ Basitçe kullanmadım Unevaluated[rules]çünkü RHS'yi x -> 1+1değerlendirmek istedim .
Szabolcs

@Leonid Haklısınız, iç içe yerelleştirme sorunu oldukça ciddi olabilir. Ben iç içe düşünüyorum Withler nokta ve önlemek için kolay, ama desenler değildir: With[{a = 1}, a_ -> a]iç lokalize aiken withRulesyapmaz. Mathematica'nın dahili yerelleştirme mekanizmasına erişmenin ve yerelleştiren yeni yapıların (benzer Rule) oluşturulmasının herhangi bir yolu olup olmadığını biliyor musunuz ? Bu cevabı daha sonra faydalı olduğundan daha tehlikeli olacağından muhtemelen sileceğim, ancak önce biraz daha oynamak istiyorum.
Szabolcs

Bence kullanımınız InheritedBlockoldukça havalı ve sorunu çok zarif bir şekilde çözüyor. Kapsam belirleme çatışmalarına gelince, sözcüksel kapsam belirleme için normalde bağlamalar, "sözcük bağlanma zamanında" gerçekleşir, yani çalışma zamanından önce, dinamik kapsam belirleme çalışma zamanında bağlanır ve bunu açıklayabilir. Bunu Moduleyapıcı kullanıma izin veren benzer bir durumla karşılaştırabilirsiniz (bkz. Örneğin stackoverflow.com/questions/7394113/… ). Sorun şu ki Blockbazı sembollere ihtiyacı var ...
Leonid Shifrin

9

Özyinelemeli saf işlevler ( #0), dilin daha karanlık köşelerinden biri gibi görünmektedir. İşte kullanımlarının önemsiz olmayan birkaç örneği, bunun gerçekten yararlı olduğu yerler (onsuz yapılamazlar). Aşağıda, köşe çiftleri olarak belirtilen kenarların bir listesi verildiğinde, grafikteki bağlı bileşenleri bulmak için oldukça özlü ve oldukça hızlı bir işlev vardır:

ClearAll[setNew, componentsBFLS];
setNew[x_, x_] := Null;
setNew[lhs_, rhs_]:=lhs:=Function[Null, (#1 := #0[##]); #2, HoldFirst][lhs, rhs];

componentsBFLS[lst_List] := Module[{f}, setNew @@@ Map[f, lst, {2}];
   GatherBy[Tally[Flatten@lst][[All, 1]], f]];

Burada olan şey, önce köşe numaralarının her birine kukla bir sembol çizmemiz ve ardından bir çift köşe verildiğinde {f[5],f[10]}, sonra f[5]değerlendirmek için bir yol oluşturmamızdır f[10]. Özyinelemeli saf işlev, yol kompresörü olarak kullanılır ( f[1]=f[3],f[3]=f[4],f[4]=f[2], ...memoizasyonu , uzun zincirler yerine , bileşenin yeni bir "kökü" her keşfedildiğinde memolanmış değerler düzeltilecek şekilde ayarlamak için . Bu, önemli bir hızlanma sağlar. Ödevi kullandığımız için, HoldAll olması gerekiyor, bu da bu yapıyı daha da belirsiz ve çekici kılıyor). Bu işlev, Fred Simons, Szabolcs Horvat, DrMajorBob ve sizinki içeren çevrimiçi ve çevrimdışı Mathgroup tartışmasının bir sonucudur. Misal:

In[13]:= largeTest=RandomInteger[{1,80000},{40000,2}];

In[14]:= componentsBFLS[largeTest]//Short//Timing
Out[14]= {0.828,{{33686,62711,64315,11760,35384,45604,10212,52552,63986,  
     <<8>>,40962,7294,63002,38018,46533,26503,43515,73143,5932},<<10522>>}}

Kesinlikle yerleşik bir çok daha yavaş, ama kod boyutu için, oldukça hızlı hala IMO.

Başka bir örnek: burada, Selectbağlantılı listelere ve özyinelemeli saf işlevlere dayalı olarak yinelemeli bir gerçekleştirme :

selLLNaive[x_List, test_] :=
  Flatten[If[TrueQ[test[#1]],
     {#1, If[#2 === {}, {}, #0 @@ #2]},
     If[#2 === {}, {}, #0 @@ #2]] & @@ Fold[{#2, #1} &, {}, Reverse[x]]];

Örneğin,

In[5]:= Block[
         {$RecursionLimit= Infinity},
         selLLNaive[Range[3000],EvenQ]]//Short//Timing

Out[5]= {0.047,{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
 <<1470>>,2972,2974,2976,2978,2980,2982,2984,2986,2988,2990,
  2992,2994,2996,2998,3000}}

Ancak düzgün kuyruk özyinelemeli değildir ve daha büyük listeler için yığını patlatır (çekirdeği çöker). İşte kuyruk özyinelemeli sürüm:

selLLTailRec[x_List, test_] :=
Flatten[
 If[Last[#1] === {},
  If[TrueQ[test[First[#1]]],
   {#2, First[#1]}, #2],
  (* else *)
  #0[Last[#1],
   If[TrueQ[test[First[#1]]], {#2, First[#1]}, #2]
   ]] &[Fold[{#2, #1} &, {}, Reverse[x]], {}]];

Örneğin,

In[6]:= Block[{$IterationLimit= Infinity},
       selLLTailRec[Range[500000],EvenQ]]//Short//Timing
Out[6]= {2.39,{2,4,6,8,10,12,14,16,18,20,22,
       <<249978>>,499980,499982,499984,499986,499988,499990,499992,
        499994,499996,499998,500000}} 

Bağlı bileşenler için işlev hala benim favorim :-)
Szabolcs

@Szabolcs Evet, oldukça havalı. Siz ve Fred çoğunu yaptınız, Bobby ve ben sadece birkaç ayrıntılandırma ekledik, IIRC.
Leonid Shifrin

8

Bu, Stan Wagon'un kitabından bir tarif ... yerleşik arsa, hassasiyet eksikliği nedeniyle düzensiz davrandığında kullanın

Options[PrecisePlot] = {PrecisionGoal -> 6};
PrecisePlot[f_, {x_, a_, b_}, opts___] := Module[{g, pg},
   pg = PrecisionGoal /. {opts} /. Options[PrecisePlot];
   SetAttributes[g, NumericFunction];
   g[z_?InexactNumberQ] := Evaluate[f /. x -> z];
   Plot[N[g[SetPrecision[y, \[Infinity]]], pg], {y, a, b},
    Evaluate[Sequence @@ FilterRules[{opts}, Options[Plot]]]]];

Mathematica'nın aşağılık değerlerinden "sözlük benzeri" davranışa ihtiyaç duyduğumda Kristjan Kannike'ın aşağıdaki numaralarını sık sık kullanıyorum

index[downvalue_, 
   dict_] := (downvalue[[1]] /. HoldPattern[dict[x_]] -> x) // 
   ReleaseHold;
value[downvalue_] := downvalue[[-1]];
indices[dict_] := 
  Map[#[[1]] /. {HoldPattern[dict[x_]] -> x} &, DownValues[dict]] // 
   ReleaseHold;
values[dict_] := Map[#[[-1]] &, DownValues[dict]];
items[dict_] := Map[{index[#, dict], value[#]} &, DownValues[dict]];
indexQ[dict_, index_] := 
  If[MatchQ[dict[index], HoldPattern[dict[index]]], False, True];

(* Usage example: *)
(* Count number of times each subexpression occurs in an expression *)
expr = Cos[x + Cos[Cos[x] + Sin[x]]] + Cos[Cos[x] + Sin[x]]
Map[(counts[#] = If[indexQ[counts, #], counts[#] + 1, 1]; #) &, expr, Infinity];
items[counts]

Değerlendirme sonuçları kafa karıştırıcı olduğunda, bazen değerlendirme adımlarının bir metin dosyasına dökülmesine yardımcı olur

SetAttributes[recordSteps, HoldAll];
recordSteps[expr_] :=
 Block[{$Output = List@OpenWrite["~/temp/msgStream.m"]}, 
  TracePrint[Unevaluated[expr], _?(FreeQ[#, Off] &), 
   TraceInternal -> True];
  Close /@ $Output;
  Thread[Union@
    Cases[ReadList["~/temp/msgStream.m", HoldComplete[Expression]], 
     symb_Symbol /; 
       AtomQ@Unevaluated@symb && 
        Context@Unevaluated@symb === "System`" :> 
      HoldComplete@symb, {0, Infinity}, Heads -> True], HoldComplete]
  ]

(* Usage example: *)
(* puts steps of evaluation of 1+2+Sin[5]) into ~/temp/msgStream.m *)
recordSteps[1+2+Sin[5]]

Bir kullanım örneği harika olurdu. Zamanınız olduğunda bir tane göndermeye çalışın.
Dr. belisarius

Kristjan hakkında ne düşünüyorsunuz? Helsinki'de onunla aynı grupta çalışıyordum. İyi adam, küçük dünya.
Timo

Hayır, kodunu web'de buldu. Aslında, koddaki küçük bir hatayı düzeltmesi için ona e-posta göndermeye çalıştı, ancak web sayfasındaki e-posta artık çalışmıyor
Yaroslav Bulatov

8

Belgelenmemiş komut satırı seçeneklerini-batchinput-batchoutput kullanarak MathKernel'i toplu modda çalıştırmak mümkündür ve :

math -batchinput -batchoutput < input.m > outputfile.txt

( input.myeni satır karakteri ile biten toplu girdi dosyası outputfile.txt, çıktının yeniden yönlendirileceği dosyadır).

In Mathematica . V> = 6 MathKernel belgesiz komut satırı seçeneği vardır:

-noicon

bu, MathKernel'in Görev Çubuğunda görünür simge olup olmayacağını kontrol eder (en azından Windows altında).

Ön Uç (en azından v.5'ten itibaren) belgelenmemiş komut satırı seçeneğine sahiptir

-b

açılış ekranını devre dışı bırakır ve Mathematica FrontEnd'i daha hızlı çalıştırmaya izin verir

ve seçenek

-directlaunch

Bu , sistem kayıt defterinde .nb dosyalarıyla ilişkili sürümü başlatmak yerine en son Mathematica sürümünü başlatan mekanizmayı devre dışı bırakır .

Muhtemelen bu yapmanın bir başka yolu ise :

Yükleme dizininde Mathematica.exe ikili dosyasını başlatmak yerine, SystemFiles \ FrontEnd \ Binaries \ Windows'da Mathematica.exe ikili dosyasını başlatın. Birincisi, dizüstü bilgisayarları açmak için talepleri kullanıcı arayüzünün çalışan kopyalarına yönlendirmek için en zor olan basit bir başlatıcı programıdır. İkincisi, kullanıcı arayüzü ikilisinin kendisidir.

Yüklü VersionedPreferences->True farklı Mathematica sürümleri arasında tercihlerin paylaşımını devre dışı bırakan global FrontEnd seçeneğini ayarlayarak son komut satırı seçeneğini birleştirmek kullanışlıdır :

SetOptions[$FrontEnd, VersionedPreferences -> True]

(Yukarıda belirtilen en son Mathematica sürümünde değerlendirilmelidir .)

In Mathematica 8 bu ayarlar altında "oluşturma ve sürüm Belirli bir ön uç tercihlerini korumak", Sistem bölmesinde, Tercihler iletişim kutusunda kontrol edilir .

Belgesiz anahtarı -h(Windows kodu) kullanarak FrontEnd'in komut satırı seçeneklerinin eksik listesini almak mümkündür :

SetDirectory[$InstallationDirectory <> 
   "\\SystemFiles\\FrontEnd\\Binaries\\Windows\\"];
Import["!Mathematica -h", "Text"]

verir:

Usage:  Mathematica [options] [files]
Valid options:
    -h (--help):  prints help message
    -cleanStart (--cleanStart):  removes existing preferences upon startup
    -clean (--clean):  removes existing preferences upon startup
    -nogui (--nogui):  starts in a mode which is initially hidden
    -server (--server):  starts in a mode which disables user interaction
    -activate (--activate):  makes application frontmost upon startup
    -topDirectory (--topDirectory):  specifies the directory to search for resources and initialization files
    -preferencesDirectory (--preferencesDirectory):  specifies the directory to search for user AddOns and preference files
    -password (--password):  specifies the password contents
    -pwfile (--pwfile):  specifies the path for the password file
    -pwpath (--pwpath):  specifies the directory to search for the password file
    -b (--b):  launches without the splash screen
    -min (--min):  launches as minimized

Diğer seçenekler:

-directLaunch:  force this FE to start
-32:  force the 32-bit FE to start
-matchingkernel:  sets the frontend to use the kernel of matching bitness
-Embedding:  specifies that this instance is being used to host content out of process

MathKernel ve FrontEnd için potansiyel olarak yararlı başka komut satırı seçenekleri var mı? Eğer biliyorsanız lütfen paylaşın.

İlgili soru .


"eşleşen bitness?" Bu ne anlama geliyor?
Sihirbaz

@ Mr.Wizard Muhtemelen bu seçenek sadece seçenekle birlikte 64 bit sistemlerin altında bir anlama sahiptir -32ve FrontEnd tarafından kullanılan MathKernel'in bitinin işletim sisteminin bitiyle eşleşeceği anlamına gelir (64 bit). Diğer durumlarda bu seçenek hiçbir şeyi değiştirmeyecek gibi görünüyor.
Alexey Popkov

7

En sevdiğim bilgisayar korsanları, bir dizi standart kaynatıcı komutunu kısa bir komutla değiştirmenize izin veren küçük kod üreten makrolardır. Alternatif olarak, not defterlerini açmak / oluşturmak için komutlar oluşturabilirsiniz.

İşte benim günlük Mathematica iş akışımda bir süredir kullandığım şey. Kendimi aşağıdakileri yaparken çok buldum:

  1. Bir dizüstü bilgisayarın özel bir içeriğe sahip olmasını sağlayın, ihtiyacım olan paketleri yükleyin, otomatik kaydetmeyi sağlayın.
  2. Bu not defteri ile bir süre çalıştıktan sonra, "ana" not defterinde kullandığım tanımlara erişirken, ayrı bir not defterinde kendi özel bağlamıyla sıfırdan hesaplamalar yapmak istiyorum. Özel içeriği ayarladığım için, bu, $ ContextPath'i manuel olarak ayarlamayı gerektirir

Tüm bunları elle tekrar tekrar yapmak bir acıdır, o zaman otomatikleştirelim! İlk olarak, bazı yardımcı program kodları:

(* Credit goes to Sasha for SelfDestruct[] *)
SetAttributes[SelfDestruct, HoldAllComplete];
SelfDestruct[e_] := (If[$FrontEnd =!= $Failed,
   SelectionMove[EvaluationNotebook[], All, EvaluationCell]; 
   NotebookDelete[]]; e)

writeAndEval[nb_,boxExpr_]:=(
    NotebookWrite[nb,  CellGroupData[{Cell[BoxData[boxExpr],"Input"]}]];
    SelectionMove[nb, Previous, Cell]; 
    SelectionMove[nb, Next, Cell];
    SelectionEvaluate[nb];
)

ExposeContexts::badargs = 
  "Exposed contexts should be given as a list of strings.";
ExposeContexts[list___] := 
 Module[{ctList}, ctList = Flatten@List@list; 
  If[! MemberQ[ctList, Except[_String]],AppendTo[$ContextPath, #] & /@ ctList, 
   Message[ExposeContexts::badargs]];
  $ContextPath = DeleteDuplicates[$ContextPath];
  $ContextPath]

    Autosave[x:(True|False)] := SetOptions[EvaluationNotebook[],NotebookAutoSave->x];

Şimdi, aşağıdaki hücreleri not defterine yerleştirecek bir makro oluşturalım:

SetOptions[EvaluationNotebook[], CellContext -> Notebook]
Needs["LVAutils`"]
Autosave[True]

Ve işte makro:

MyPrivatize[exposedCtxts : ({__String} | Null) : Null]:=
  SelfDestruct@Module[{contBox,lvaBox,expCtxtBox,assembledStatements,strList},
    contBox = MakeBoxes[SetOptions[EvaluationNotebook[], CellContext -> Notebook]];
    lvaBox = MakeBoxes[Needs["LVAutils`"]];

    assembledStatements = {lvaBox,MakeBoxes[Autosave[True]],"(*********)"};
    assembledStatements = Riffle[assembledStatements,"\[IndentingNewLine]"]//RowBox;
    writeAndEval[InputNotebook[],contBox];
    writeAndEval[InputNotebook[],assembledStatements];
    If[exposedCtxts =!= Null,
       strList = Riffle[("\"" <> # <> "\"") & /@ exposedCtxts, ","];
       expCtxtBox = RowBox[{"ExposeContexts", "[", RowBox[{"{", RowBox[strList], "}"}], "]"}];
       writeAndEval[InputNotebook[],expCtxtBox];
      ]
 ]

Şimdi yazdığımda MyPrivatize[]özel bağlam oluşturur ve standart paketimi yükler. Şimdi kendi özel bağlamıyla yeni bir not defteri açacak bir komut oluşturalım (böylece tanımları bozma riski olmadan vahşi terk ile hackleyebilirsiniz), ancak mevcut bağlamlarınıza erişebilirsiniz.

SpawnScratch[] := SelfDestruct@Module[{nb,boxExpr,strList},
    strList = Riffle[("\"" <> # <> "\"") & /@ $ContextPath, ","];
    boxExpr = RowBox[{"MyPrivatize", "[",
        RowBox[{"{", RowBox[strList], "}"}], "]"}];
    nb = CreateDocument[];
    writeAndEval[nb,boxExpr];
]

Bunun en güzel yanı SelfDestruct, komut çalıştığında geçerli not defterinde hiçbir iz bırakmamasıdır - bu iyidir, çünkü aksi takdirde sadece dağınıklık yaratacaktır.

Ek stil noktaları için, bu makrolar için anahtar kelime tetikleyicileri oluşturabilirsiniz InputAutoReplacements, ancak bunu okuyucu için bir egzersiz olarak bırakacağım.


7

Put PageWidth ile ekle -> Sonsuzluk

In Mathematica'nın kullanarak PutAppendkomuta ara hesaplamaların sonuçları ile çalışan bir günlük dosyası korumak için en basit yoldur. Ancak, PageWith->78ifadeleri bir dosyaya dışa aktarırken varsayılan olarak kullanır ve bu nedenle her ara çıktının günlükte yalnızca bir satır alacağının garantisi yoktur.

PutAppendherhangi bir seçeneğe sahip değildir, ancak değerlendirmelerini izlemek OpenAppend, PageWithseçeneğe sahip olan işleve dayandığını ve SetOptionskomutla varsayılan değerini değiştirmeye izin verdiğini gösterir :

In[2]:= Trace[x>>>"log.txt",TraceInternal->True]
Out[2]= {x>>>log.txt,{OpenAppend[log.txt,CharacterEncoding->PrintableASCII],OutputStream[log.txt,15]},Null}

Böylece PutAppend, ayarlayarak her seferinde yalnızca bir satır ekleyebiliriz:

SetOptions[OpenAppend, PageWidth -> Infinity]

GÜNCELLEME

Sürüm 10'da tanıtılan bir hata var (sürüm 11.3'te düzeltildi): ve ve SetOptionsdavranışlarını artık etkilemiyor .OpenWriteOpenAppend

Çözüm, kendi sürümünüzü PutAppendaçık PageWidth -> Infinityseçenekle uygulamaktır:

Clear[myPutAppend]
myPutAppend[expr_, pathtofile_String] :=
 (Write[#, expr]; Close[#];) &[OpenAppend[pathtofile, PageWidth -> Infinity]]

Bunu WriteString, bu cevapta gösterildiği gibi de uygulayabileceğimizi unutmayın , ancak bu durumda, ifadeyi önceden karşılık gelen InputFormyoluyla dönüştürmek gerekecektir ToString[expr, InputForm].


6

Sadece bu eklenmek üzere benim paketlerden birini gözden geçirdikten ve bunun çalışma harikalar tanımlanmış bazı mesajlar tespit edildi: Debug::<some name>. Varsayılan olarak, kapalıdır, bu nedenle fazla yük üretmeyin. Ancak, onlarla kodumu çöp ve tam olarak biraz kod nasıl davrandığını anlamak gerekirse onları açın.


Yardım> Sürüm 2.0'dan beri (1991'de piyasaya sürüldü) Debug'un yerini Trace aldı.
Dr. belisarius

1
@belisarius, noktayı kaçırdın. Ne işlevi ne Debugde Traceişlevidir; Bu, istediğimde açmak / kapatmak için kodumu çöp bırakabileceğim bir dizi mesaj oluşturdu. Kelimenin önüne gelirler Debug, aynı şekilde usageişlevin adıyla bir msj önlenir. Bir grup coutifadeyi c ++ koduna yerleştirmeyle aynı işlevi sağlar .
rcollyer

1
Ah üzgünüm. Kafam karıştı çünkü anaokulundan asla "Başkentler Ülkeler İçin" öğrenmediğim için mezun
olmadım

6

Yerleşik kapsam oluşturma yapıları hakkında beni rahatsız eden şeylerden biri, tüm yerel değişken tanımlarını aynı anda değerlendirmeleridir, bu nedenle örneğin yazamazsınız.

With[{a = 5, b = 2 * a},
    ...
]

Bir süre önce bunu yapmanıza izin veren WithNest adlı bir makro buldum. Kullanışlı buluyorum, çünkü değişken bağlamaları yerel bir şey yapmadan yerel tutmanıza izin veriyor

Module[{a = 5,b},
    b = 2 * a;
    ...
]

Sonunda, bunu yapmanın en iyi yolu, ciltler listesinin geri alınmasını kolaylaştırmak için özel bir sembol kullanmaktı ve bu sembolü gizli tutmak için tanımı kendi paketine koydum. Belki birisinin bu soruna daha basit bir çözümü vardır?

Denemek istiyorsanız, aşağıdakileri adlı bir dosyaya koyun Scoping.m:

BeginPackage["Scoping`"];

WithNest::usage=
"WithNest[{var1=val1,var2=val2,...},body] works just like With, except that
values are evaluated in order and later values have access to earlier ones.
For example, val2 can use var1 in its definition.";

Begin["`Private`"];

(* Set up a custom symbol that works just like Hold. *)
SetAttributes[WithNestHold,HoldAll];

(* The user-facing call.  Give a list of bindings and a body that's not
our custom symbol, and we start a recursive call by using the custom
symbol. *)
WithNest[bindings_List,body:Except[_WithNestHold]]:=
WithNest[bindings,WithNestHold[body]];

(* Base case of recursive definition *)
WithNest[{},WithNestHold[body_]]:=body;

WithNest[{bindings___,a_},WithNestHold[body_]]:=
WithNest[
{bindings},
WithNestHold[With[List@a,body]]];

SyntaxInformation[WithNest]={"ArgumentsPattern"->{{__},_}};
SetAttributes[WithNest,{HoldAll,Protected}];

End[];

EndPackage[];

Janus bunun bir versiyonunu yayınladı ve sorunuzu MathGroup'ta topladı: stackoverflow.com/questions/4190845/custom-notation-question/…
Mr.Wizard

Bunu işaret ettiğiniz için teşekkürler! Bu şeylere baktığımdan beri bir süre geçti ve diğer tüm yaklaşımları görmek ilginç.
DGrady

5

Bu yazı Alberto Di Lullo tarafından yazılmıştır (Stack Overflow'da görünmeyen).

CopyToClipboard, Mathematica 7 için (Mathematica 8'de yerleşiktir)

CopyToClipboard[expr_] := 
  Module[{nb}, 
   nb = CreateDocument[Null, Visible -> False, WindowSelected -> True];
   NotebookWrite[nb, Cell[OutputFormData@expr], All];
   FrontEndExecute[FrontEndToken[nb, "Copy"]];
   NotebookClose@nb];

Orijinal yayın: http://forums.wolfram.com/mathgroup/archive/2010/Jun/msg00148.html

Bu rutini büyük gerçek sayıları panoya sıradan ondalık formda kopyalamak için yararlı buldum. ÖrneğinCopyToClipboard["123456789.12345"]

Cell[OutputFormData@expr] tırnak işaretleri düzgün bir şekilde kaldırır.


5

Bu kod, seçimi bir görüntü olarak Stack Exchange'e yükleyen bir palet oluşturur. Windows'ta, seçimin daha sadık bir şekilde görüntülenmesini sağlayan ekstra bir düğme sağlanır.

Kodu bir defter hücresine kopyalayın ve değerlendirin. Ardından paleti çıktıdan çıkarın vePalettes -> Install Palette...

Bununla ilgili herhangi bir sorun yaşarsanız, buraya bir yorum gönderin. Dizüstü bilgisayar sürümünü buradan indirin .


Begin["SOUploader`"];

Global`palette = PaletteNotebook@DynamicModule[{},

   Column[{
     Button["Upload to SE",
      With[{img = rasterizeSelection1[]},
       If[img === $Failed, Beep[], uploadWithPreview[img]]],
      Appearance -> "Palette"],

     If[$OperatingSystem === "Windows",

      Button["Upload to SE (pp)",
       With[{img = rasterizeSelection2[]},
        If[img === $Failed, Beep[], uploadWithPreview[img]]],
       Appearance -> "Palette"],

      Unevaluated@Sequence[]
      ]
     }],

   (* Init start *)
   Initialization :>
    (

     stackImage::httperr = "Server returned respose code: `1`";
     stackImage::err = "Server returner error: `1`";

     stackImage[g_] :=
      Module[
       {getVal, url, client, method, data, partSource, part, entity,
        code, response, error, result},

       getVal[res_, key_String] :=
        With[{k = "var " <> key <> " = "},
         StringTrim[

          First@StringCases[
            First@Select[res, StringMatchQ[#, k ~~ ___] &],
            k ~~ v___ ~~ ";" :> v],
          "'"]
         ];

       data = ExportString[g, "PNG"];

       JLink`JavaBlock[
        url = "http://stackoverflow.com/upload/image";
        client =
         JLink`JavaNew["org.apache.commons.httpclient.HttpClient"];
        method =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.PostMethod", url];
        partSource =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.multipart.\
ByteArrayPartSource", "mmagraphics.png",
          JLink`MakeJavaObject[data]@toCharArray[]];
        part =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.multipart.FilePart",
          "name", partSource];
        part@setContentType["image/png"];
        entity =
         JLink`JavaNew[
          "org.apache.commons.httpclient.methods.multipart.\
MultipartRequestEntity", {part}, method@getParams[]];
        method@setRequestEntity[entity];
        code = client@executeMethod[method];
        response = method@getResponseBodyAsString[];
        ];

       If[code =!= 200, Message[stackImage::httperr, code];
        Return[$Failed]];
       response = StringTrim /@ StringSplit[response, "\n"];

       error = getVal[response, "error"];
       result = getVal[response, "result"];
       If[StringMatchQ[result, "http*"],
        result,
        Message[stackImage::err, error]; $Failed]
       ];

     stackMarkdown[g_] :=
      "![Mathematica graphics](" <> stackImage[g] <> ")";

     stackCopyMarkdown[g_] := Module[{nb, markdown},
       markdown = Check[stackMarkdown[g], $Failed];
       If[markdown =!= $Failed,
        nb = NotebookCreate[Visible -> False];
        NotebookWrite[nb, Cell[markdown, "Text"]];
        SelectionMove[nb, All, Notebook];
        FrontEndTokenExecute[nb, "Copy"];
        NotebookClose[nb];
        ]
       ];

     (* Returns available vertical screen space,
     taking into account screen elements like the taskbar and menu *)


     screenHeight[] := -Subtract @@
        Part[ScreenRectangle /. Options[$FrontEnd, ScreenRectangle],
         2];

     uploadWithPreview[img_Image] :=
      CreateDialog[
       Column[{
         Style["Upload image to the Stack Exchange network?", Bold],
         Pane[

          Image[img, Magnification -> 1], {Automatic,
           Min[screenHeight[] - 140, 1 + ImageDimensions[img][[2]]]},
          Scrollbars -> Automatic, AppearanceElements -> {},
          ImageMargins -> 0
          ],
         Item[
          ChoiceButtons[{"Upload and copy MarkDown"}, \
{stackCopyMarkdown[img]; DialogReturn[]}], Alignment -> Right]
         }],
       WindowTitle -> "Upload image to Stack Exchange?"
       ];

     (* Multiplatform, fixed-width version.
        The default max width is 650 to fit Stack Exchange *)
     rasterizeSelection1[maxWidth_: 650] :=
      Module[{target, selection, image},
       selection = NotebookRead[SelectedNotebook[]];
       If[MemberQ[Hold[{}, $Failed, NotebookRead[$Failed]], selection],

        $Failed, (* There was nothing selected *)

        target =
         CreateDocument[{}, WindowSelected -> False, Visible -> False,
           WindowSize -> maxWidth];
        NotebookWrite[target, selection];
        image = Rasterize[target, "Image"];
        NotebookClose[target];
        image
        ]
       ];

     (* Windows-only pixel perfect version *)
     rasterizeSelection2[] :=
      If[
       MemberQ[Hold[{}, $Failed, NotebookRead[$Failed]],
        NotebookRead[SelectedNotebook[]]],

       $Failed, (* There was nothing selected *)

       Module[{tag},
        FrontEndExecute[
         FrontEndToken[FrontEnd`SelectedNotebook[], "CopySpecial",
          "MGF"]];
        Catch[
         NotebookGet@ClipboardNotebook[] /.
          r_RasterBox :>
           Block[{},
            Throw[Image[First[r], "Byte", ColorSpace -> "RGB"], tag] /;
              True];
         $Failed,
         tag
         ]
        ]
       ];
     )
   (* Init end *)
   ]

End[];

4

Eminim birçok insan bazı şeyleri yürüttükleri durumla karşılaşmıştır, bunun sadece programı sıkıştırarak değil, aynı zamanda son 10 dakika boyunca da tasarruf !

DÜZENLE

Bir süre bu acı sonra, bir gün öğrendim bir oto-kaydetme oluşturabilir içinden Mathematica kodu. Sanırım böyle bir otomatik kaydetmeyi kullanmak geçmişte bana çok yardımcı oldu ve her zaman olasılığın kendisinin pek çok insanın yapabileceğinin farkında olmadığı bir şey olduğunu hissettim .

Kullandığım orijinal kod en altta. Yorumlar sayesinde problemli olduğunu ve alternatif bir şekilde yapmanın çok daha iyi olduğunu öğrendim ScheduledTask(sadece Mathematica 8'de çalışacak ).

Bunun için kod bulunabilir Bu yanıt dan Sjoerd C. de Vries (Emin 's Tamam burada kopyalamak için, sadece bir bağlantı olarak bırakıyorum eğer değilim beri.)


Aşağıdaki çözüm kullanıyor Dynamic. Dizüstü bilgisayarı her 60 saniyede bir kaydedecek, ancak görünüşe göre sadece hücresi görünürse . Sadece tamamlama nedenleriyle burada bırakıyorum. (ve Mathematica 6 ve 7 kullanıcıları için )

/DÜZENLE

Bunu çözmek için bir dizüstü bilgisayarın başında bu kodu kullanın:

Dynamic[Refresh[NotebookSave[]; DateString[], UpdateInterval -> 60]]

Bu, çalışmanızı her 60 saniyede bir kaydedecektir.
Tercih ederimNotebookAutoSave[] , giriş işlenmeden önce kaydettiği ve bazı dosyaların girişten daha fazla metin olduğu .

Aslında burada buldum: http://en.wikipedia.org/wiki/Talk:Mathematica#Eleştiriler

Bu satırı çalıştırdıktan sonra, dosyanızı kapatıp yeniden açsanız bile (dinamik güncelleme etkin olduğu sürece) kaydetmenin gerçekleşeceğini unutmayın.

Ayrıca, Mathematica'da geri alma olmadığından, tüm içeriğinizi silmemeye dikkat edin, çünkü kaydetme geri döndürülemez hale getirecektir (önlem olarak, bu kodu bitmiş her not defterinden kaldırırım)


ayrıca farklı bir adla kaydedebilirsiniz (örneğin, geçerli saat ve tarihi dosya adının sonuna ekleyerek) ve belki de belirli bir dizine ("Yedekler", örneğin) ekleyebilirsiniz. bu ilkel bir versiyonlama biçimi gibi olurdu.
acl

Böyle bir şey yapabilirsiniz NotebookSave[SelectedNotebook[], "work-" <> IntegerString[i] <> ".nb"]; i++, ancak bence şu anki not defteri adına yapılan her türlü atıf tekrarlanır.
tsvikas

2
DynamicNesneleri yalnızca görünür olduklarında yenileneceğini düşündüm , bu yüzden örneğin Dynamicnesneyi görünür alanın dışına kaydırırsanız bu yöntemin işe yarayacağından emin olmazdım . Sonra tekrar denemedim. Her durumda, sadece bir öneri olarak teklif ettim.
acl

1
Bunu kullanarak test edebilirsiniz Dynamic[Refresh[i++, UpdateInterval -> 1, TrackedSymbols -> {}]]. Artan sayıyı görünürden kaydırın, bir dakika bekleyin, geri kaydırın ve sayının 60'a kadar artırılmadığını görün. Hakkında UpdateInterval: bu genellikle mümkünse kullanılır, ancak kodunuzda değişen değişkenler varsa bu değişiklik, aralık biter. Yukarıdaki satırı olmadan deneyinTrackedSymbols
Sjoerd C. de Vries

1
@ j0ker5 Yukarıdaki kodumu deneyin ve UpdateInterval'in her zaman güncellemeleri belirtilen aralıklarla aralıklandırmaya zorlamadığını görebilirsiniz. Bu kod, Dinamik'in yalnızca içerdiği hücre ön uçta görünürse çalıştığını da gösterir . Görünür olmadığı anı gerçekten durdurur. İnsanlar dosyalarını kaydetmek için bu koda gerçekten güvenmemeliler çünkü öyle değil. Tehlikeli
Sjoerd C. de Vries


3

Bu klavye kısayolunu dosyama eklemek için paketler geliştirirken gerçekten kullanışlı buluyorum SystemFiles/FrontEnd/TextResources/Windows/KeyEventTranslations.tr.

(* Evaluate Initialization Cells: Real useful for reloading library changes. *)

Item[KeyEvent["i", Modifiers -> {Control, Command}],
    FrontEndExecute[
        FrontEndToken[
            SelectedNotebook[],
            "EvaluateInitialization"]]],

Sonra her Packagename.mbiri PackagenameTest.nbtest için bir not defteri yapıyorum ve test not defterinin ilk 2 hücresi başlatma hücreleri olarak ayarlandı. İlk hücreye koydum

Needs["PackageManipulations`"]

Leonid tarafından yazılmış çok faydalı PackageManipulations kütüphanesini yüklemek için . İkinci hücre

PackageRemove["Packagename`Private`"]
PackageRemove["Packagename`"]
PackageReload["Packagename`"]

hepsi gerçek paket yeniden yükleme yapmak. RemoveBağlamları olabildiğince temiz tutmayı sevdiğim için ilk iki satırın tüm sembollerde olduğunu unutmayın.

Daha sonra bir paket yazma ve test etme iş akışı böyle bir şey haline gelir.

  1. Değişiklikleri olarak kaydet Packagename.m.
  2. Git PackagenameTest.nbve yap CTRL + ALT + i.

Bu, başlatma hücrelerinin paketi yeniden yüklemesine neden olur ve bu da test etmeyi basitleştirir.


1

Bir sayfaya yayılan format[expr_]biçimlendirilmemiş mathematicaifadeleri girinti / biçimlendirmek için aşağıdaki işlev kullanılabilir

indent[str_String, ob_String, cb_String, delim_String] := 
  Module[{ind, indent, f, tab}, ind = 0; tab = "    ";
   indent[i_, tab_, nl_] := nl <> Nest[tab <> ToString[#] &, "", i];
   f[c_] := (indent[ind, "", " "] <> c <> indent[++ind, tab, "\n"]) /;StringMatchQ[ob, ___ ~~ c ~~ ___];
   f[c_] := (indent[--ind, "", " "] <> c <> indent[ind, tab, "\n"]) /;StringMatchQ[cb, ___ ~~ c ~~ ___];
   f[c_] := (c <> indent[ind, tab, "\n"]) /;StringMatchQ[delim, ___ ~~ c ~~ ___];
   f[c_] := c;
   f /@ Characters@str // StringJoin];
format[expr_] := indent[expr // InputForm // ToString, "[({", "])}", ";"];

(*    
format[Hold@Module[{ind, indent, f, tab}, ind = 0; tab = "    ";
 indent[i_, tab_, nl_] := nl <> Nest[tab <> ToString[#] &, "", i];
 f[c_] := (indent[ind, "", " "] <> c <> indent[++ind, tab, "\n"]) /;StringMatchQ[ob, ___ ~~ c ~~ ___];
 f[c_] := (indent[--ind, "", " "] <> c <> indent[ind, tab, "\n"]) /;StringMatchQ[cb, ___ ~~ c ~~ ___];
 f[c_] := (c <> indent[ind, tab, "\n"]) /;StringMatchQ[delim, ___ ~~ c ~~ ___];
 f[c_] := c;
 f /@ Characters@str // StringJoin]]
*)

ref: /codegolf/3088/indent-a-string-using-given-parentheses


Bunu pratikte ne için kullanıyorsunuz? Çıktı, kodunuza veya verilere (listeler ) uygulandığında okunamayacak kadar "komik"format@RandomInteger[10,{3,3}] :: pastebin.com/nUT54Emq Zaten temel bilgilere sahip olduğunuzdan ve bununla ilgileniyorsanız, kodu geliştirebilir misiniz? kullanışlı okunabilir bir biçimlendirme üretiyor musunuz? Daha sonra bir sonraki adım, güzel girintili Mathematica koduna sahip bir giriş hücresi oluşturacak bir yapıştırma düğmesi yapmak olacaktır (tercihen yorumları koruyarak !!) Ayrıca bkz . İlgili sorum .
Szabolcs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.