web-dev-qa-db-ja.com

Mathematicaツールバッグには何が入っていますか?

Mathematicaが素晴らしいことは誰もが知っていますが、多くの場合、重要な機能が欠けています。 Mathematicaではどのような外部パッケージ/ツール/リソースを使用していますか?

このメインポストを編集して(そして他の人にもそうするように)、科学研究における一般的な適用性に焦点を当て、できるだけ多くの人が役に立つリソースを含めるようにします。少しでもコードスニペット(下記のタイミングルーチンで行ったように)に貢献してください。

また、Mathematica 7以降のドキュメントに記載されていない便利な機能や、自分で見つけたもの、またはいくつかの紙/サイトから掘り下げたものも大歓迎です。

簡単な説明を含めるか、何かが素晴らしい理由やそれが提供するユーティリティについてコメントしてください。アフィリエイトリンクを使用してAmazonの書籍にリンクする場合は、リンクの後に名前を入力するなどして、そのことを明記してください。


パッケージ:

  1. LevelScheme は、見栄えの良いプロットを生成するMathematicaの機能を大幅に拡張するパッケージです。フレーム/軸の目盛りのはるかに改善された制御のために、それ以外の場合は使用しません。最新バージョンはSciDrawと呼ばれ、今年中にリリースされます。
  2. デビッドパークの Presentation Package (US $ 50-アップデートの無料)
  3. Jeremy Michelsonの grassmannOps パッケージは、Grassmann変数と非自明な交換関係を持つ演算子で代数と計算を行うためのリソースを提供します。
  4. ジョン・ブラウンの GrassmannAlgebra グラスマン代数とクリフォード代数を扱うためのパッケージと本。
  5. RISC(Research Institute for Symbolic Computation) には、ダウンロード可能なMathematica(およびその他の言語)のさまざまなパッケージがあります。特に、自動定理証明には Theorema があり、 Algorithmic Combinatoricsグループのソフトウェアページ には、シンボリックな総和、差分方程式などの多数のパッケージがあります。

ツール:

  1. MASH はDaniel Reevesの優れたものです Perl Mathematica v7のスクリプトサポートを本質的に提供するスクリプト。 (現在Mathematica 8で-scriptオプション。
  2. alternate Mathematica Shell with GNU readline input(python、* nixのみを使用))
  3. ColourMathsパッケージを使用すると、式の一部を視覚的に選択して操作できます。 http://www.dbaileyconsultancy.co.uk/colour_maths/colour_maths.html

リソース:

  1. Wolfram独自のリポジトリ MathSource は、さまざまなアプリケーション用の狭いノートブックの場合に非常に便利です。次のような他のセクションもチェックしてください

  2. Mathematica Wikibook

書籍:

  1. Mathematicaプログラミング:Leonid Shifrinによる高度な紹介webpdf ) MathematicaのForループ以上のことをしたい場合は必読です。 Leonid 自身がここで質問に答えてくれることを嬉しく思います。
  2. Mathematicaを使用した量子法James F. Feagin( Amazon
  3. The Mathematica Bookby Stephen Wolfram( Amazon )( web
  4. ショームの概要Amazon
  5. Mathematica in Actionby Stan Wagon( Amazon )-600ページの適切な例とMathematicaバージョン7まで。視覚化技術は特に優れています。著者の Demonstrations Page
  6. Mathematica Programming Fundamentalsby Richard Gaylord( pdf )-Mathematicaプログラミングについて知っておくべきことのほとんどを簡潔に紹介します。
  7. O'Reilly 2010 832ページで発行されたSal ManganoによるMathematica Cookbook。 -有名なO'Reilly Cookbookスタイルで書かれています:問題-解決策。中間体用。
  8. Mathematicaによる微分方程式、第3版。 Elsevier 2004 Amsterdam by Martha L. Abell、James P. Braselton-893 pages初心者のために、DEとMathematicaを同時に解くことを学んでください。

文書化されていない(またはほとんど文書化されていない)機能:

  1. Mathematicaキーボードショートカットをカスタマイズする方法。見る - this question
  2. Mathematica独自の関数で使用されるパターンと関数を検査する方法。見る - this answer
  3. MathematicaでGraphPlotsのサイズを一定にする方法は?見る - this question
  4. Mathematicaでドキュメントとプレゼンテーションを作成する方法。見る - this question
149
Timo

以前に this について言及しましたが、最も便利だと思うツールは、Reapの動作を模倣/拡張するSowGatherByのアプリケーションです。

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

これにより、リストを任意の基準でグループ化し、プロセスで変換することができます。動作方法は、基準関数(f)がリスト内の各項目にタグを付け、次に各項目が2番目に提供される関数(g)によって変換され、特定の出力が3番目の関数(h)。関数hは、タグと、そのタグを持つ収集されたアイテムのリストという2つの引数を受け入れます。アイテムは元の順序を保持するため、h = #1&を設定すると、Unionの-​​ examples のように、ソートされていないReapを取得します。ただし、2次処理には使用できます。

その有用性の例として、空間依存ハミルトニアンをファイルに出力する Wannier9 を使用しました。この場合、各行は次のようにマトリックス内の異なる要素です。

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

そのリストを一連のマトリックスに変換するために、同じ座標を含むすべてのサブリストを集め、要素情報をルールに変換しました(つまり{i、j}-> Re [Hij] + I Im [Hij])。次に、収集されたルールを、すべて1つのライナーでSparseArrayに変換しました。

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

正直なところ、これは私のスイスアーミーナイフであり、複雑なことを非常に簡単にします。私の他のツールのほとんどは、ある程度ドメイン固有であるため、おそらく投稿しません。ただし、それらのすべてではないとしても、ほとんどはSelectEquivalentsを参照します。

Edit:完全に模倣するわけではありません GatherBy 単純に複数レベルの式をグループ化することはできませんGatherByとして。ただし、Mapは、必要なほとんどの場合に正常に機能します。

Example:@Yaroslav Bulatovは自己完結型の例を要求しています。これは私の研究からのもので、大幅に簡素化されています。だから、平面に点のセットがあるとしましょう

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}}

そして、対称操作のセットによってポイントの数を減らしたいと思います。 (好奇心のために、各ポイントの 小グループ を生成しています。)この例では、z軸を中心に4倍の回転軸を使用します。

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

SelectEquivalentsを使用して、これらの操作で同じ画像セットを生成するポイントをグループ化できます。

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}}}

同等のポイントを含む3つのサブリストを生成します。 (注:Unionは、各ポイントによって同じ画像が生成されることを保証するため、ここでは絶対に不可欠です。元々、Sortを使用しましたが、ポイントが対称軸上にある場合、その軸を中心に回転すると、それ自体の余分な画像が得られます。したがって、Unionはこれらの余分な画像を削除します。また、GatherByは同じ結果を生成します。を使用しますが、各グループの代表的なポイントのみが必要であり、同等のポイントのカウントが必要です。各ポイントを変換する必要がないため、2番目の位置でIdentity関数を使用します。 3番目の機能については、注意する必要があります。渡される最初の引数は、_{0,0,0}が4つの同一の要素のリストである回転の下のポイントの画像になり、それを使用するとカウントが無効になります。ただし、2番目の引数はそのタグを持つすべての要素のリストであるため、{0,0,0}のみが含まれます。コードでは、

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}}

この最後のステップは、次のように簡単に実行できます。

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

しかし、これと上記の完全ではない例を使用すると、最小限のコードで非常に複雑な変換がどのように可能になるかを簡単に確認できます。

29
rcollyer

Mathematicaノートブックインターフェースの良いところの1つは、Mathematicaだけでなくany言語で式を評価できることです。簡単な例として、含まれている式を評価のためにオペレーティングシステムシェルに渡す新しいShell入力セルタイプを作成することを検討してください。

最初に、テキストコマンドの評価を外部シェルに委任する関数を定義します。

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

2番目の引数は、後で明らかになる理由で必要であり、無視されます。次に、Shellという新しいスタイルを作成します。

  1. 新しいノートブックを開きます。
  2. メニュー項目を選択しますFormatsheet/Edit Stylesheet ...
  3. ダイアログで、の横にスタイル名を入力します:Shellと入力します。
  4. 新しいスタイルの横にあるセルブラケットを選択します。
  5. メニュー項目を選択Cell/Show Expression
  6. 次のStep 6 Textでセル式を上書きします。
  7. もう一度、メニュー項目Cell/Show Expressionを選択します
  8. ダイアログを閉じます。

次のセル式をとして使用しますステップ6テキスト

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"]

この式のほとんどは、組み込みProgramスタイルから直接コピーされました。主な変更点は次の行です。

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

Evaluatableは、セルのShift + Enter機能を有効にします。評価はCellEvaluationFunctionを呼び出し、セルのコンテンツとコンテンツタイプを引数として渡します(shellEvaluateは後者の引数を無視します)。 CellFrameLabelsは、このセルが異常であることをユーザーが識別できるようにするだけの便利な機能です。

これらすべてが整ったら、シェル式を入力して評価できます。

  1. 上記の手順で作成したノートブックで、空のセルを作成し、セルブラケットを選択します。
  2. メニュー項目Format/Style/Shellを選択します。
  3. 有効なオペレーティングシステムのシェルコマンドをセルに入力します(例:Unixでは「ls」、Windowsでは「dir」)。
  4. Shift + Enterキーを押します。

この定義されたスタイルは、中央に配置されたスタイルシートに保存することをお勧めします。さらに、shellEvaluateのような評価関数は、init.mDeclarePackage を使用してスタブとして最適に定義されます。これら両方のアクティビティの詳細は、この対応の範囲を超えています。

この機能を使用すると、目的の構文の入力式を含むノートブックを作成できます。評価関数は、純粋なMathematicaで作成することも、評価の一部またはすべてを外部機関に委任することもできます。 CellEpilogCellPrologCellDynamicExpressionなど、セル評価に関連する他のフックがあることに注意してください。

一般的なパターンには、入力式テキストを一時ファイルに書き込み、ファイルを何らかの言語でコンパイルし、プログラムを実行し、出力セルに最終表示するために出力をキャプチャすることが含まれます。この種の完全なソリューション(エラーメッセージを適切にキャプチャするなど)を実装する際には、対処すべき詳細がたくさんありますが、このようなことができるだけでなく実用的であるという事実を理解する必要があります。

個人的には、ノートブックインターフェイスを私のプログラミングユニバースの中心にしているのはこのような機能です。

更新

次のヘルパー関数は、このようなセルを作成するのに役立ちます。

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]
  )

次のように使用されます。

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

現在、shellCell[]が評価されると、入力セルは削除され、その内容をシェルコマンドとして評価する新しい入力セルに置き換えられます。

57
WReach

Todd Gayley(Wolfram Research)は、組み込み関数を任意のコードで「ラップ」できるようにするNiceハックを送信しました。この便利な道具を共有しなければならないと感じています。以下は、私の question に対するToddの答えです。

少し興味深い(?)歴史:組み込み関数を「ラップ」するためのそのようなスタイルのハックは、1994年頃にRobby VillegasとIによって発明されました。当時。それ以来、多くの人が何度も使用しています。これはちょっとした裏技ですが、組み込み関数の定義に独自のコードを挿入する標準的な方法になったと言ってもいいと思います。それは仕事をうまくやり遂げます。もちろん、$ inMsg変数を任意のプライベートコンテキストに入れることができます。

Unprotect[Message];

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

Protect[Message];
35
Alexey Popkov

これは完全なリソースではないので、ここで回答セクションに投げていますが、速度の問題を理解する際に非常に便利です(残念ながら、Mathematicaプログラミングの目的の大部分です)。

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};

使用法は単にtimeAvg@funcYouWantToTest

編集:Mr. WizardはThrowCatchを廃止し、解析が少し簡単な簡単なバージョンを提供しました:

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

編集:これは acl からのバージョンです( here から取得):

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]
25
Timo

Internal`InheritedBlock

私は最近、公式ニュースグループの このダニエル・リヒトブロウのメッセージ から、Internal`InheritedBlockのような有用な関数の存在を学びました。

私が理解しているように、Internal`InheritedBlockBlockスコープ内でアウトバウンド関数のコピーを渡すことができます:

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]

この関数は、組み込み関数を一時的に変更する必要があるすべての人にとって非常に役立つと思います!

ブロックとの比較

関数を定義してみましょう。

a := Print[b]

次に、この関数のコピーをBlockスコープに渡します。素朴なトライアルでは、私たちが望むものは得られません。

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

During evaluation of In[9]:= b

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

Blockの最初の引数で遅延定義を使用しようとしています(ドキュメント化されていない機能でもあります)。

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

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

During evaluation of In[3]:= b

この場合、aは機能しますが、aスコープ内に元のBlockのコピーはありません。

Internal`InheritedBlockを試してみましょう:

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

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

aスコープ内のBlockの元の定義のコピーがあり、aのグローバル定義に影響を与えずに、必要に応じて変更できます。

20
Alexey Popkov

Mathematicaは鋭いツールですが、やや ntyped behaviouravalanches の不可解な 診断メッセージ であなたをカットできます。これに対処する1つの方法は、このイディオムに従って関数を定義することです。

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

これは定型的なもので、頻繁にスキップしたいと思います。特にプロトタイピングの場合、これはMathematicaで頻繁に発生します。そこで、defineと呼ばれるマクロを使用します。

defineの基本的な使用法は次のとおりです。

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

fact[5]

120

最初はあまり見かけませんが、いくつかの隠れた利点があります。 defineが提供する最初のサービスは、定義されているシンボルにClearAllを自動的に適用することです。これにより、関数の最初の開発中によく発生する、定義の残りがないことが保証されます。

2番目のサービスは、定義されている関数が自動的に「閉じられる」ことです。これにより、定義の1つと一致しない引数リストで呼び出された場合、関数はメッセージを発行して中止することを意味します。

fact[-1]

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

これはdefineの主要な値であり、非常に一般的なクラスのエラーをキャッチします。

もう1つの便利な方法は、定義されている関数の属性を簡潔に指定する方法です。関数Listableを作成しましょう:

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

fact[{3, 5, 8}]

{6, 120, 40320}

すべての通常の属性に加えて、defineOpenと呼ばれる追加の属性を受け入れます。これにより、defineがキャッチエラーの定義を関数に追加できなくなります。

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

successor /@ {1, "hi"}

{2, successor["hi"]}

関数に対して複数の属性を定義できます:

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

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

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

さらに苦労することなく、ここに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: ``";

展示されている実装は、アップバリューもカリー化も、単純な関数定義よりも一般的なパターンもサポートしていません。ただし、それでも有用です。

19
WReach

空白のノートブックを開かずに起動します

空白のノートブックを開いた状態でMathematicaを起動することに悩まされました。スクリプトを使用してこのノートブックを閉じることもできますが、それでもしばらくの間フラッシュが開きます。私のハックは、以下を含むファイルInvisible.nbを作成することです。

Notebook[{},Visible->False]

これをKernel\init.mに追加します:

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

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

Invisible.nbを開いてMathematicaを開始しました

より良い方法があるかもしれませんが、これは私に役立っています。


カスタマイズされたFoldおよびFoldList

Fold[f, x]Fold[f, First@x, Rest@x]と同等になります

ちなみに、これはMathematicaの将来のバージョンに取り入れられる可能性があると思います。

驚いた!現在は文書化されていませんが、これは実装されています。 2011年にOliver Ruebenkoenigによって実装されたことがわかりました。 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]

これを許可するために更新されました:

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

「動的パーティション」

この関数の新しいバージョンについては、 Mathematica.SE post#7512 を参照してください。

多くの場合、長さのシーケンスに従ってリストを分割します。

擬似コードの例:

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

出力:{{1,2}, {3,4,5}, {6}}

私はこれを思いつきました:

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

引数のテストを含め、これで完了しました:

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

3番目の引数は、分割仕様を超えた要素に何が起こるかを制御します。


SzabolcsのMathematicaトリック

最も頻繁に使用するのは、表形式のデータパレットの貼り付けです

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"]]]]]}

Compile内から外部データを変更します

最近ダニエル・リヒトブロウは、私が前に見たことがなかったこの方法を示しました。私の意見では、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.}  *)
16
Mr.Wizard

一般的なPDF/EMFエクスポートの問題と解決策

1)完全に予想外で文書化されていませんが、Mathematicaはスタイル定義のセットを使用してPDFおよびEPS形式でグラフィックをエクスポートおよび保存します画面にノートブックを表示するために使用されるものとは異なります。デフォルトでは、ノートブックは「Working」スタイル環境(ScreenStyleEvironment global $FrontEndオプションのデフォルト値)で画面に表示されますが、"Printout"スタイル環境(デフォルト)で印刷されますPrintingStyleEnvironment global $FrontEndオプションの値)。 GIFやPNGなどのラスター形式またはEMF形式でグラフィックスをエクスポートすると、Mathematicaは内部のように見えるグラフィックスを生成しますノート。この場合、レンダリングには"Working"スタイルの環境が使用されているようです。ただし、PDFまたはEPS形式でエクスポート/保存する場合はそうではありません。この場合、 "Printout"スタイル環境がデフォルトで使用されます これは、「Working」スタイル環境とは非常に異なります。まず、 "Printout"スタイルの環境はMagnificationを80% に設定します。第二に、異なるスタイルのフォントサイズに独自の値を使用するため、元の画面上の表現と比較して、生成されたPDFファイルのフォントサイズが一貫して変更されます。後者は FontSizeゆらぎ と呼ばれ、非常に迷惑です。しかし、喜んでこれを避けることができます PrintingStyleEnvironment global $FrontEndオプションを "Working" に設定することで:

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

2)EMF形式にエクスポートする際の一般的な問題は、ほとんどのプログラム(Mathematicaだけでなく)Niceに見えるファイルを生成することですデフォルトのサイズですが、ズームインすると見苦しくなります。これは、 メタファイルが画面解像度の忠実度でサンプリングされる であるためです。生成されたEMFファイルの品質は、元のグラフィックオブジェクトのMagnifyingによって向上させることができるため、元のグラフィックのサンプリングの正確さがより正確になります。 2つのファイルを比較します。

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

これらのファイルをMicrosoft Wordに挿入してズームインすると、最初の「a」にはノコギリ歯があり、2番目には「Mathematica6)。

ImageResolutionの別の方法が Chris Degnen によって提案されました(このオプションは、少なくともMathematica8から始まります) :

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

3)Mathematicaには、グラフィックをメタファイルに変換する3つの方法があります:Exportから"EMF"経由(強く推奨される方法:可能な限り最高の品質のメタファイル)、Save selection As...メニュー項目( あまり正確ではない数値を生成する 、推奨しません)およびEdit ► Copy As ► Metafileメニュー項目( このルート )。

14
Alexey Popkov

キャッシュ式

これらの関数は、式をキャッシュするのに非常に役立ちます。ここでこれらの2つの関数の興味深い点は、関数がfのように定義されている場合にのみ結果をキャッシュできる数学でよく知られているメモ化と比較して、保持された式自体がハッシュテーブル/シンボルCacheまたはCacheIndexのキーとして使用されることです[x_]:= f [x] = ...したがって、コードの任意の部分をキャッシュできます。これは、関数を複数回呼び出す場合に便利ですが、コードの一部のみを再計算してはいけません。

引数とは関係なく式をキャッシュします。

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

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

2回目は、式が待機せずに6を返します。

キャッシュされた式の引数に依存できるエイリアス式を使用して式をキャッシュする。

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

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

Exprの計算に時間がかかる場合、たとえばキャッシュされた結果を取得するために{"f"、2}を評価する方がはるかに高速です。

ローカライズされたキャッシュを使用するためのこれらの関数のバリエーションについては(つまり、キャッシュメモリはブロック構造の外部で自動的に解放されます)、この投稿を参照してください Interpolationの繰り返し呼び出しを避ける

キャッシュされた値を削除する

関数の定義の数がわからないときにキャッシュされた値を削除するため。定義の引数のどこかに空白があると思います。

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

関数の定義の数がわかっているときにキャッシュされた値を削除するには(少し速くなります)。

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

これは、関数の定義がDownValuesリストの最後にあり、キャッシュされた値が前にあるという事実を使用しています。

シンボルを使用してデータとオブジェクトのような関数を保存する

また、オブジェクトのようなシンボルを使用する興味深い関数もあります。

データをシンボルに保存し、DownValuesを使用してすばやくアクセスできることは既によく知られています

mysymbol["property"]=2;

このサイトの投稿で提出したものに基づいて、これらの関数を使用して、シンボルのキー(またはプロパティ)のリストにアクセスできます。

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

この関数を頻繁に使用して、シンボルのDownValuesに含まれるすべての情報を表示します。

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

最後に、オブジェクト指向プログラミングでオブジェクトのように動作するシンボルを作成する簡単な方法を示します(OOPの最も基本的な動作を再現しますが、構文はエレガントです):

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
  ];

返されるModuleによって作成されたシンボルには、プロパティがDownValuesとして、メソッドが遅延Upvaluesとして保存されます。 Mathematicaのツリーデータ構造 の関数の通常のオブジェクト指向構文であるfunction2の構文を見つけました。

各シンボルが持つ既存のタイプの値のリストについては、 http://reference.wolfram.com/mathematica/tutorial/PatternsAndTransformationRules.html および http://www.verbeia。 com/mathematica/tips/HTMLLinks/Tricks_Misc_4.html

たとえば、これを試してください

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

ここから入手できるInheritRulesというパッケージを使用してオブジェクトの継承をエミュレートする場合は、さらに先に進むことができます http://library.wolfram.com/infocenter/MathSource/671/

関数定義をnewObjectではなく型シンボルに保存することもできます。そのため、NewObjectがnewObjectの代わりにtype [newObject]を返した場合、このように関数とfunction2をNewObjectの外側(内側ではなく)で定義し、以前と同じように使用できます。

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

UpValues [type]を使用して、typeシンボルでfunctionとfunction2が定義されていることを確認します。

この最後の構文についてのさらなるアイデアがここに紹介されています https://mathematica.stackexchange.com/a/999/66

SelectEquivalentsの改善されたバージョン

@rcollyer:SelectEquivalentsを表面にもたらしたことに感謝します。それは驚くべき機能です。上記のSelectEquivalentsの改善されたバージョンは、より多くの可能性とオプションを使用しており、使いやすくなっています。

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]]
      ]
   ];

このバージョンの使用方法の例を次に示します。

Mathematica Gather/Collectを適切に使用

MathematicaでPivotTable関数をどのように実行しますか?

Mathematica高速2Dビニングアルゴリズム

内袋

Daniel Lichtblauは、ここで成長するリストの興味深い内部データ構造を説明します。

Mathematicaで四分木を実装する

デバッグ機能

これらの2つの投稿は、デバッグに役立つ機能を示しています。

Mathematicaを使用して小さなコードまたは大きなコードを書くときのデバッグ方法?ワークベンチ?mmaデバッガー?または他の何か? (ShowIt)

https://stackoverflow.com/questions/5459735/the-clearest-way-to-represent-mathematicas-evaluation-sequence/5527117#5527117 (TraceView)

次に、ReapとSowに基づいた別の関数を示します。これは、プログラムのさまざまな部分から式を抽出し、シンボルに保存します。

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

ここに例があります

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*)

その他の資料

学習用の興味深いリンクのリストは次のとおりです。

Mathematica学習リソースのコレクション

ここで更新: https://mathematica.stackexchange.com/a/259/66

13
Faysal Aberkane

一般的な需要により、 SO API を使用して、トップ10 SO answerersプロット( annotations を除く)を生成するコード。

enter image description here

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", ""})]
13

私のユーティリティ関数(質問で言及されているMASHにこれらが組み込まれています):

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).   *)
12
dreeves

コンテキストを前に付けずにシステムシンボル定義を印刷する

以下のcontextFreeDefinition[]関数は、最も一般的なコンテキストを前に付けずに、シンボルの定義を印刷しようとします。次に、定義をワークベンチにコピーし、読みやすいようにフォーマットします(選択して右クリックし、ソース->フォーマット)。

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 []

警告:この関数は、WithおよびModuleと同じ方法で変数をローカライズしません。つまり、ネストされたローカライズコンストラクトは期待どおりに機能しません。 withRules[{a -> 1, b -> 2}, With[{a=3}, b_ :> b]]willネストされたaおよびbWithおよびRuleを置き換えます、Withはこれを行いません。

これは、=および:=の代わりにルールを使用するWithのバリアントです。

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

これは、実験中に記述されたコードをクリーンアップし、変数をローカライズするときに役立ちました。時折、{par1 -> 1.1, par2 -> 2.2}の形式のパラメーターリストが作成されます。 withRulesパラメータ値を使用すると、以前にグローバル変数を使用して記述されたコードに簡単に挿入できます。

使用法はWithと同じです:

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

アンチエイリアス3Dグラフィックス

これは、グラフィックハードウェアがネイティブにサポートしていない場合でも、3Dグラフィックをアンチエイリアスする非常に簡単な手法です。

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

以下に例を示します。

Mathematica graphicsMathematica graphics

nの値が大きいか、画像サイズが大きいと、グラフィックスドライバーのバグが発生したり、アーティファクトが生じたりする傾向があることに注意してください。


ノートブックの差分機能

ノートブックdiff機能は、<<AuthorTools`パッケージで、および(少なくともバージョン8では)文書化されていないNotebookTools`コンテキストで使用できます。これは、現在開いている2つのノートブックを比較するための小さなGUIです。

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 graphics

11
Szabolcs

私が使ったトリックの1つは、ほとんどの組み込み関数が不正な引数を処理する方法をエミュレートすることを可能にします(メッセージを送信し、評価されていないフォーム全体を返すことで) Condition は、定義で使用すると機能します。 fooが1つの引数のみで機能する場合:

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

より複雑なニーズがある場合、独立した関数として引数の検証とメッセージ生成を簡単に除外できます。 Conditionでメッセージを生成するだけでなく、副作用を使用することでより複雑なことを行うことができますが、私の意見では、それらのほとんどは "sleazy hack"カテゴリに該当し、可能な場合は避ける必要があります。

また、「メタプログラミング」カテゴリで、Mathematicaパッケージ(.m)ファイル、 "HeldExpressions" elementHoldCompleteでラップされたファイル内のすべての式を取得します。これにより、テキストベースの検索を使用するよりも追跡がはるかに簡単になります。残念ながら、ノートブックで同じことを行う簡単な方法はありませんが、次のようなものを使用してすべての入力式を取得できます。

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

最後に、Moduleがレキシカルクロージャーをエミュレートするという事実を使用して、参照タイプと同等のものを作成できます。以下に簡単なスタックを示します(エラー処理のためにConditionトリックのバリエーションをボーナスとして使用します):

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]

これで、リストの要素を不必要に複雑な方法で逆順で印刷できます!

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

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

再帰的な純粋関数(_#0_)は、言語の暗いコーナーの1つと思われます。ここに、それらの使用の自明でないいくつかの例があります。これは本当に便利です(それなしではできないわけではありません)。以下は、頂点のペアとして指定されたエッジのリストが与えられた場合に、グラフ内の接続されたコンポーネントを見つけるための非常に簡潔で適度に高速な関数です。

_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]];
_

ここで何が起こるかは、最初に各頂点番号にダミーシンボルをマッピングし、頂点のペア_{f[5],f[10]}_が与えられると、たとえば_f[5]_が_f[10]_。再帰的な純粋関数は、パスコンプレッサーとして使用されます(_f[1]=f[3],f[3]=f[4],f[4]=f[2], ..._のような長いチェーンの代わりに、コンポーネントの新しい「ルート」が検出されるたびにメモされた値が修正されるようにメモ化を設定します。割り当てを使用するため、HoldAllである必要があり、この構成はさらに不明瞭で魅力的になります)。この関数は、Fred Simons、Szabolcs Horvat、DrMajorBob、そしてあなたの本当に関係するMathgroupのオンラインおよびオフラインの議論の結果です。例:

_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>>}}
_

それは確かにビルトインよりもはるかに遅いですが、コードのサイズのために、かなり速いIMOです。

別の例:ここに、リンクリストと再帰的な純関数に基づくSelectの再帰的な実現があります。

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

例えば、

_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}}
_

しかし、それは適切に末尾再帰ではなく、より大きなリストのためにスタックを破壊します(カーネルをクラッシュさせます)。これが末尾再帰バージョンです。

_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]], {}]];
_

例えば、

_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}} 
_
9
Leonid Shifrin

これはスタンワゴンの本のレシピです...組み込みのPlotが精度不足のために不安定に動作する場合に使用します

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のダウンバリューから「辞書のような」動作が必要な場合、Kristjan Kannikeの次のトリックをよく使用します

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]

評価結果がわかりにくい場合は、評価手順をテキストファイルにダンプすると役立つ場合があります

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]]
8

私のお気に入りのハックは、標準のボイラープレートコマンドの束を1つの短いものに置き換えることができる小さなコード生成マクロです。または、ノートブックを開く/作成するためのコマンドを作成できます。

日々のMathematicaワークフローで私がしばらく使用してきたものを次に示します。私は次のことをたくさん実行していることに気付きました。

  1. ノートブックにプライベートコンテキストを設定し、必要なパッケージをロードして、自動保存します。
  2. このノートブックをしばらく使用した後、「メイン」ノートブックで使用していた定義にアクセスしながら、独自のプライベートコンテキストを使用して、別のノートブックでスクラッチ計算をいくつか行いたいと思います。プライベートコンテキストを設定したため、$ ContextPathを手動で調整する必要があります

このすべてを何度も手作業で行うのは苦痛なので、自動化しましょう!まず、いくつかのユーティリティコード:

(* 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];

次に、ノートブックに次のセルを配置するマクロを作成しましょう。

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

そして、これがマクロです:

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];
      ]
 ]

MyPrivatize[]と入力すると、プライベートコンテキストが作成され、標準パッケージがロードされます。次に、独自のプライベートコンテキストを使用して新しいスクラッチノートブックを開くコマンドを作成します(そのため、定義を台無しにするリスクなしでワイルドハックでハックできるようになります)が、現在のコンテキストにアクセスできます。

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

これの素晴らしい点は、SelfDestructが原因で、コマンドの実行時に現在のノートブックに痕跡が残らないことです。そうしないと、混乱が生じるだけです。

追加のスタイルポイントについては、InputAutoReplacementsを使用してこれらのマクロのキーワードトリガーを作成できますが、これは読者の演習として残しておきます。

7
Leo Alekseyev

PageWidthでPutAppend-> Infinity

MathematicaPutAppendコマンドを使用することは、実行中のログファイルを中間計算の結果とともに維持する最も簡単な方法です。ただし、式をファイルにエクスポートするときはデフォルトでPageWith->78設定を使用するため、すべての中間出力がログで1行のみを取得するという保証はありません。

PutAppendにはオプションはありませんが、その評価をトレースすると、OpenAppendオプションがあり、PageWithによってデフォルト値を変更できるSetOptions関数に基づいていることがわかります。コマンド:

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

したがって、次を設定することにより、一度に1行のみを追加するPutAppendを取得できます。

SetOptions[OpenAppend, PageWidth -> Infinity]

[〜#〜] update [〜#〜]

バージョン10で導入された バグ (バージョン11.3で修正):SetOptionsOpenWriteおよびOpenAppendの動作に影響しなくなりました。

回避策は、明示的なPageWidth -> InfinityオプションでPutAppendの独自のバージョンを実装することです。

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

this answerに示すようにWriteStringを介して実装することもできますが、この場合は、ToString[expr, InputForm]を介して式を対応するInputFormに事前に変換する必要があります。

7
Alexey Popkov

組み込みのスコープ構成体について気になることの1つは、すべてのローカル変数定義を一度に評価することです。したがって、たとえば、

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

しばらく前に、これを可能にするWithNestというマクロを思いつきました。これは、次のようなことをせずに変数バインディングをローカルに保つことができるので便利です

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

最後に、これを行うための最良の方法は、特別なシンボルを使用してバインディングのリストを再帰的に確認することであり、このシンボルを非表示にするために定義を独自のパッケージに入れました。たぶん誰かがこの問題のより簡単な解決策を持っていますか?

試してみたい場合は、次のファイルを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[];
6
DGrady

これに含めるパッケージを探していたところ、動作が不思議だと定義したメッセージが見つかりました:Debug::<some name>。デフォルトではオフになっているため、オーバーヘッドはあまり発生しません。しかし、私はそれらをコードに散らばらせ、コードのビットがどのように動作しているかを正確に把握する必要がある場合はそれらをオンにすることができます。

6
rcollyer

このコードは、選択範囲を画像としてStack Exchangeにアップロードするパレットを作成します。 Windowsでは、選択のより忠実なレンダリングを提供する追加のボタンが提供されます。

コードをノートブックのセルにコピーして評価します。次に、出力からパレットをポップアウトし、Palettes -> Install Palette...を使用してインストールします

問題がある場合は、ここにコメントを投稿してください。ノートブックバージョンをダウンロードします こちら


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[];
5
Szabolcs

これは、Alberto Di Lulloによって書かれました(Stack Overflowではないようです)。

CopyToClipboard、Mathematica 7の場合(Mathematica 8ではビルトイン)

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

元の投稿: http://forums.wolfram.com/mathgroup/archive/2010/Jun/msg00148.html

このルーチンは、大きな実数を通常の10進数形式でクリップボードにコピーするのに役立ちます。例えば。 CopyToClipboard["123456789.12345"]

Cell[OutputFormData@expr]は引用符をきれいに削除します。

4
Chris Degnen

私は多くの人々が何かを実行する状況に遭遇したと確信しています。それはプログラムを動かさないだけでなく、彼らも最後の10分間保存していない!

編集

これにしばらく苦しんだ後、私はある日、誰かがMathematicaコード内から自動保存を作成できることを発見しました。そのような自動保存を使用することは、過去に私を大いに助けたと思います。そして、私はいつも可能性自体は、多くの人ができることを認識していない何かだと感じました。

使用した元のコードは下部にあります。問題があることと、ScheduledTaskMathematica 8でのみ機能する)を使用して別の方法でそれを行う方がはるかに良いことがわかったコメントのおかげで)。

このコードは this answer from Sjoerd C. de Vries(ここにコピーしてもいいかどうかわからないので、リンクとして残しておきます。)


以下の解決策はDynamicを使用しています。ノートブックは60秒ごとに保存されますが、どうやらセルが表示されている場合のみ。完了の理由のためだけにここに置いておきます。 (およびMathematica 6および7のユーザー向け)

/編集

それを解決するために、ノートブックの冒頭でこのコードを使用します。

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

これにより、60秒ごとに作業が保存されます。
NotebookAutoSave[]入力が処理される前に保存されるため、および一部のファイルは入力よりもテキストが多いためです。

私はもともとここで見つけました: http://en.wikipedia.org/wiki/Talk:Mathematica#Criticisms

この行を実行すると、ファイルを閉じて再度開いても保存が行われることに注意してください(動的更新が有効になっている場合)。

また、Mathematicaには元に戻らないため、保存すると元に戻せないため、すべてのコンテンツを削除しないように注意してください(予防措置として、完成したすべてのノートブックからこのコードを削除します)

4
tsvikas

Mathematica Bookはオンラインで http://reference.wolfram.com/legacy/v5_2/ でも入手できますが、 http:// reference。 wolfram.com

3
Bill White

このキーボードショートカットを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"]]],

次にPackagename.mごとにPackagenameTest.nbテスト用のノートブックを作成し、テストノートブックの最初の2つのセルを初期化セルとして設定します。最初のセルに

Needs["PackageManipulations`"]

とても便利な PackageManipulations Leonidによって書かれたライブラリをロードします。 2番目のセルには

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

これらはすべて実際のパッケージのリロードを行います。コンテキストを可能な限りクリーンに保つために、最初の2行はRemoveすべてのシンボルにのみ存在することに注意してください。

次に、パッケージを作成してテストするためのワークフローは次のようになります。

  1. Packagename.mへの変更を保存します。
  2. PackagenameTest.nbに移動して、CTRL + ALT + iを実行します。

これにより、初期化セルがパッケージをリロードするため、テストが非常に簡単になります。

3
nixeagle

次の関数format[expr_]は、ページにまたがる書式なしmathematica式のインデント/フォーマットに使用できます。

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]]
*)

参照: https://codegolf.stackexchange.com/questions/3088/indent-a-string-using-given-parentheses

1
Prashant Bhate