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


152

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

私はこのメインの投稿を編集して(他の人にもそうするように勧めます)、科学研究における一般的な適用性に焦点を当てたリソースを含め、できるだけ多くの人々が役立つと思うようにします。小さなコードスニペット(タイミングルーチンについては以下で説明しました)も含め、何でも自由に投稿してください。

また、Mathematica 7以降の文書化されていない便利な機能はあなた自身が発見したものであるか、またはいくつかの論文/サイトから掘り起こされたものであれば大歓迎です。

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


パッケージ:

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

ツール:

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

リソース:

  1. Wolfram自身のリポジトリMathSourceは、さまざまなアプリケーション向けの狭いノートブックである場合に非常に役立ちます。また、他のセクションもチェックしてください。

  2. MathematicaのWikibook

書籍:

  1. Mathematicaプログラミング:MathematicaForループ以外のものを実行したい場合は、Leonid Shifrin(webpdf)による高度な紹介が必読です。ここで質問にお答えできることをうれしく思います。Leonid
  2. James F. FeaginによるMathematicaによる量子法amazon
  3. スティーブン・ウォルフラム(アマゾン)によるMathematicaブックweb
  4. ショームの概要アマゾン
  5. Mathematica in Action by Stan Wagon(amazon)-600ページのきちんとした例とMathematicaバージョン7まで続きます。視覚化手法は特に優れており、著者の作品でそれらのいくつかを見ることができますDemonstrations Page
  6. Mathematicaプログラミングの基礎:Richard Gaylord(pdf)-Mathematicaプログラミングについて知っておくべきことのほとんどを簡潔に紹介しています。
  7. Sal 'ManganoによるMathematicaクックブックはO'Reilly 2010 832ページから出版されています。-よく知られたO'Reillyクックブックスタイルで書かれています:問題-解決策。中間体用。
  8. Mathematicaによる微分方程式、第3版。Elsevier 2004アムステルダム、Martha L. Abell、James P. Braselton-893ページ初心者のために、DEとMathematicaを同時に解くことを学びます。

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

  1. Mathematicaキーボードショートカットをカスタマイズする方法。を参照してくださいthis question
  2. Mathematica自身の関数によって使用されるパターンと関数を検査する方法。見るthis answer
  3. MathematicaでGraphPlotsの一貫したサイズを達成するには?を参照してくださいthis question
  4. Mathematicaでドキュメントとプレゼンテーションを作成する方法。を参照してくださいthis question

2
Mathematica 8はシェルスクリプトの統合がより良くなりました。wolfram.com/mathematica/new-in-8/mathematica-shell-scripts
Joshua Martell

2
+ 1、LevelSchemeの場合。少し遅いこともあります。しかし、それは目盛りを作成するためのまともな方法を備えており、グラフィックスGrid、またはそのようなもののためのジャーナルにふさわしいレイアウトを作成する方がはるかに簡単です。
rcollyer

2
この質問stackoverflow.com/questions/5152551/…のコメントでアレクセイが提案したように、ここでMathematicaのタグ名の変更を提案しました:meta.stackexchange.com/questions/81152/…。同意する場合は、確認して賛成投票してください。この質問は、ここのMmaコミュニティで多くのお気に入りがあるため、ここに投稿します。
belisarius博士、2011年

1
すべて、この質問は、通常の理由のすべてのために、実際にはコミュニティWikiである必要があります。正解はなく、何よりもリストの詳細です。この質問で評判が良くなったすべての人に謝罪します。
rcollyer 2011

2
この質問に対するこれらの回答は建設的であり、再開する必要があります。
MR

回答:


29

私が言及した、これを前に、私が最も便利なツールは、のアプリケーションであるReapSowどの模倣/の振る舞いを拡張しますGatherBy

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のように、のためにReap。ただし、二次加工に使用できます。

そのユーティリティの例として、空間依存のハミルトニアンをファイルに出力するWannier90を使用してきました。ここで、各行はマトリックス内の異なる要素です。

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

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

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

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

編集GatherBy表現の複数のレベルをできるだけ単純にグループ化できないという点で完全に模倣しているわけではありませんGatherBy。ただし、Map私が必要とするもののほとんどは問題なく動作します。

:@Yaroslav Bulatovは自己完結型の例を求めています。ここに私の研究からの1つが大幅に簡略化されました。それで、平面に一連の点があるとしましょう

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同じ結果が生成されます。)この場合、ポイントはすでに使用する形になっていますが、各グループからの代表的なポイントのみが必要であり、カウントを希望します同等のポイントの。各ポイントを変換する必要がないので、Identity2番目の位置で機能します。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]

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


オリジナルのFortran77コードは1996年の感謝祭の日に再構成されたため、長年turkey.fとして知られていました ...:D非常に素晴らしいグラフィックスBTW。ファリコフの怪物を私に思い出させた...
ベリサリウス博士

@belisarius、私は歴史を読んでいませんでした、それは面白いです。私はWannier90を使い始めたばかりですが、これは私が目にした中で最も体系的でよく書かれたFortranコードの一部です。Fortran... を使用することをほとんど検討させてくれます
rcollyer '19年

実行中のSelectEquivalentsの自己完結型の例を追加できますか
Yaroslav Bulatov

@Yaroslav Bulatov、リクエストごとに例を追加。これで効果があるかどうかをお知らせください。そうでない場合は、何ができるかを確認します。
rcollyer

最も興味深いコードスニペットの貢献について、この「質問」のチェックマークが表示されます。
Timo

57

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

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

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

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

  1. 新しいノートブックを開きます。
  2. メニュー項目[ スタイルシートのフォーマット/編集... ]を選択します
  3. ダイアログでは、横に:スタイル名を入力タイプをShell
  4. 新しいスタイルの横にあるセルブラケットを選択します。
  5. メニュー項目「セル/式を表示」を選択します
  6. 下記のステップ6のテキストでセル式を上書きします。
  7. もう一度、メニュー項目「セル/式を表示」を選択します
  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"]

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

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

EvaluatableセルのShift + Enter機能を有効にします。評価ではCellEvaluationFunction、セルのコンテンツとコンテンツタイプを引数として渡します(shellEvaluate後者の引数は無視されます)。 CellFrameLabelsこのセルが異常であることをユーザーが識別できるようにするための素晴らしい機能です。

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

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

この定義されたスタイルを中央に配置されたスタイルシートに保存するのが最善です。さらに、などの評価関数shellEvaluateは、DeclarePackageを使用してスタブとして定義するのが最適init.mです。これらのアクティビティの詳細は、この応答の範囲を超えています。

この機能により、関心のある構文の入力式を含むノートブックを作成できます。評価関数は、純粋な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[]評価され、入力セルが削除され、シェルコマンドとして、その内容を評価し、新たな入力セルに置き換えられます。


3
@WReach +100!これをもっと早く知って欲しい!これは、少なくとも私にとっては非常に便利なものです。共有してくれてありがとう!
Leonid Shifrin

これはかなりピリッと見えます! CellEvaluationFunction低レベルの構文ハッキングにも使用できると思います。
Mr.Wizard

@Leonid少なくともフロントエンドについてはCellEvaluationFunction、あなたが探していたフックはありますか?
Mr.Wizard

2
さらにCell、セルの評価に関連するもう1つのオプションがあります- Evaluator -> "EvaluatorName"。の意味はEvaluation :: Kernel Configuration Options ...ダイアログで設定"EvaluatorName"できます。それでもプログラムで構成できるかどうかはまだわかりません...この手法では、1つのNotebook 内の異なるsで異なるMathKernelを使用できます。これらのMathKernelは、インストールされているさまざまなバージョンのMathematicaからのものです。Cell
アレクセイポプコフ2011

1
@Szabolcsこの手法の私自身の使用はすべて、上に示したstdin _ / _ stdoutアプローチ、またはSQLクエリやHTTP操作などの自己完結型のリモート要求のいずれかを含みます。Python REPL Webアプリ(このような)を設定し、を使用してそれとやり取りするImportか、外部のPythonプロセスを起動してそのストリームを介して通信する(たとえば、Java ProcessBuilderを使用する)ことができます。Mathematicaにはもっと良い方法があると確信しています-良いSOの質問のように聞こえます:)
WReach

36

Todd Gayley(Wolfram Research)は、組み込み関数を任意のコードで「ラップ」できる素敵なハックを送ってくれました。この便利な楽器を共有する必要があると感じています。以下は、私のトッドの答えquestionです。

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

Unprotect[Message];

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

Protect[Message];

@Alexeyこれを理解するのが難しい。これがどのように機能するか説明できますか?Unprotect [Message]はどこかにあるべきではないのですか?そして、この例には無限再帰が含まれていませんか?そして、!TrueQ [$ inMsg]これは、$ inMsgがブロックスコープ内で定義され、ブロック外で定義されていない場合に意味がありますか?
Sjoerd C. de Vries、2011

9
@Sjoerd私が理解していることから、Unprotect確かにそうである必要があるだけですが、除外されました。Block(動的スコープ)のポイントは$inMsg、無限再帰を防ぐことです。$inMsgは外部で定義されていないため(これは重要な要件です)、最初はにTrueQ評価されFalse、関数の本体に入ります。しかし、本体の内部に関数呼び出しがあると、条件はFalse(変数がBlockによって再定義されているため)と評価されます。したがって、ユーザー定義のルールは一致せず、代わりに組み込みのルールが使用されます。
Leonid Shifrin

1
@レオニードありがとう、私は今それを手に入れました。非常に賢い!
Sjoerd C. de Vries、2011

1
私はこの技術が1999年の開発者会議でWolfram ResearchのRobby Villegasによって議論されたことを発見しました。ここに掲載されている「未評価の式の操作」ノートブックを参照してください。このノートブックで、Robby Villegasは、「組み込み関数への呼び出しをトラップするためのマイブロックトリック」サブセクションでこのトリックについて説明しています。
Alexey Popkov 2011年

1
@ Mr.Wizardこれはこれを行う唯一の方法ではありません。長い間、DownValues実行時にを再定義するバージョンを使用しました。例(再定義)については、この投稿groups.google.com/group/comp.soft-sys.math.mathematica/…をご覧くださいSetDelayed。しかし、私の方法は、エレガントさが少なく、堅牢性が低く、エラーが発生しやすく、再帰からの脱却を実装するのが非常に簡単です。そのため、ほとんどの状況で、@ Alexeyによって記述された方法が優先されます。
Leonid Shifrin、2011

25

これは完全なリソースではないので、ここで回答セクションにまとめましたが、速度の問題を理解するときに非常に役立ちます(残念ながら、これは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です。

EDIT:ミスターウィザードがして離れない簡単なバージョンを提供してきたThrowCatchし、解析に少し簡単です。

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

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

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]

もう一度やり直して…自分のバッグに入れる時間。tnx!
belisarius博士、2010年

1
このコードの1つの問題(まあ、これは完璧主義者の視点かもしれません)は、スローしなかったものをキャッチし、これを誤ったタイミング結果として解釈できることです。CatchThrowは両方とも、一意の例外タグとともに使用されるべきでした。
Leonid Shifrin、2011

2
ティモ、それを含めるのに十分な私の演出を気に入ってくれてうれしいです。私も信用してくれてありがとう。あなたが私のコードを再フォーマットした方法に興味があります。私は自分のコードを特定のガイドラインに従っていませんが、自分自身を読みやすくしています。あなたの再フォーマットの背後にある思考の学校はありますか、それとも単なる好みですか?Mathematicaは入力をリフローする方法のために正確なコードフォーマットを推奨しませんが、ここにコードを投稿することで私はそれについて考え始めます。ところで、私はあなたが意味すると思う「ThrowCatch」ではなく「ReapSow。」
Mr.Wizard

1
@サイモン、ウィザード氏、私はこのメソッドを使用して、何度も呼び出される小さなバージョンの異なるバージョンの時間を計っています。必ずしもループ構造である必要はありませんが、MMAが最適化する構造内にあることは確かです。このコンテキストでは、ループの実行のタイミングに意味があり、パフォーマンスは実際のアプリケーションに近くなります。大きな複雑な関数(おそらく初期化セル全体)のタイミングをとる場合、Simonの方法がより良い結果をもたらします。全体として、私は相対的な値にもっと興味があり、どちらの方法もそこで機能するはずです。
ティモ

3
これRepeatedTimingを行うには今があります。
masterxilo

20

Internal`InheritedBlock

最近、公式ニュースグループのダニエル・リクトブラウのこのメッセージInternal`InheritedBlockから、などの便利な機能の存在を学びました。

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

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ます。


+1とても便利!バッグの中のもう1つのツールと、編集権限に10ポイント近づきます。
Mr.Wizard

私には、これは初期評価、後期評価、または評価なしの完全な評価のバリエーションとして表示されます。
user2432923

19

Mathematicaは鋭いツールですが、それはやや型付けされていない振る舞いと不可解な診断メッセージの雪崩であなたをカットすることができます。これに対処する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番目のサービスは、定義されている関数が自動的に「クローズ」されることです。これは、定義のいずれかと一致しない引数リストで呼び出された場合、関数がメッセージを発行して中止することを意味します。

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}

すべての通常の属性にdefine加えて、と呼ばれる追加の属性を受け入れますOpen。これにより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: ``";

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


2
+1-これは本当に便利なものです。同様のツールを使用しています。マクロ(およびイントロスペクションやその他のメタプログラミング手法)は非常に強力ですが、Mathematicaコミュニティ内では一般に評価されていないようです。少なくともこれまでのところ私の印象ではありません。
Leonid Shifrin、2011年

同様のことを定義しました。複数の定義を行うためのCompoundExpressionサポートの+ 1、Abort [](さらに多くのメッセージよりも優れているようです)およびOpen(コンストラクターなどに最適)。
masterxilo

16

空白のノートブックを開かずに開始する

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

Notebook[{},Visible->False]

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

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

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

Mathematicaを起動して Invisible.nb

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


カスタマイズさ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の投稿#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トリック

私が最も頻繁に使用するのは、Paste Tabular Data Paletteです。

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

最近Daniel Lichtblauが、これまで見たことのない方法を示しました。私の意見では、それは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良いコレクション!内部からの外部変更について Compile-私の投稿全体:stackoverflow.com/questions/5246330/…は、この可能性を自明ではない設定で紹介することでした(そこに投稿された問題の問題には、より短くて速い解決策がすでにありました) 。IMO、ここでの最大の勝利は、参照渡しをエミュレートし、大きなコンパイル済み関数をより管理しやすく再利用可能なチャンクに分割する機能です。
Leonid Shifrin

1
また、あなたの新しい定義にフォールドとFoldListの構文情報を調整することができます。SyntaxInformation = {「ArgumentsPattern」[折り]を- > {_、 。、_}}; SyntaxInformation [FoldList] = {"ArgumentsPattern"-> {_、_。、{_ }}};
faysou

14

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

1)それは完全に予想外で文書化されていませんが、Mathematicaはノートブックを画面に表示するために使用されるものとは異なるスタイル定義のセットを使用してPDFおよびEPSフォーマットでグラフィックをエクスポートおよび保存します。デフォルトノートブックによって(デフォルト値である「ワーキング」スタイル環境で画面上に表示されているScreenStyleEvironmentグローバル$FrontEndオプション)が、中に印刷されている"Printout"(デフォルト値であるスタイル環境PrintingStyleEnvironmentグローバル$FrontEndオプション)。GIFやPNGなどのラスター形式またはEMF形式でグラフィックをエクスポートすると、MathematicaはNotebook内とまったく同じように見えるグラフィックを生成します。のようです"Working"この場合、レンダリングにはスタイル環境が使用されます。ただし、PDFまたはEPS形式で何かをエクスポート/保存する場合はそうではありません。この場合、"Printout"スタイル環境はデフォルト使用され、「Working」スタイル環境とは大きく異なります。まず"Printout"スタイル環境はMagnification80%に設定されています。次に、異なるスタイルのフォントサイズに独自の値を使用するため、生成されたPDFファイルのフォントサイズの変更が、元の画面上の表現と比較して不整合になります。後者は、FontSizeの変動と呼ばれ、非常に煩わしいものです。しかし幸いにも、これPrintingStyleEnvironmentグローバル$FrontEndオプションを "Working"に設定することで回避できます。

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

2)EMF形式にエクスポートする際の一般的な問題は、ほとんどのプログラム(Mathematicaだけでなく)がデフォルトサイズで見栄えがよいが、ズームインすると見苦しいファイルを生成することです。これは、メタファイルが画面解像度の忠実度でサンプリングされるためです。生成されたEMFファイルの品質は、Magnify元のグラフィックオブジェクトを使用して向上させることができるため、元のグラフィックのサンプリングの正確さがはるかに正確になります。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番目には鋸歯がないことがわかります(Mathematica 6でテスト済み)。

別の方法ImageResolutionChris Degnenによって提案されました(このオプションは少なくともMathematica 8 以降で有効です):

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

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


13

多くの要望により、SO APIを使用してトップ10のSO回答者プロット(注釈を除く)を生成するコード。

ここに画像の説明を入力してください

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
ブレットは、ほぼこの正確なコードを要求する質問を投稿しました。多分それはそこに最も適切であり、質問に合うように1つか2つ微調整します。この質問とは対照的に、私は実際に担当者の価値があります。
rcollyer

@rcollyerは正しいです。これは「コミュニティWiki」です
belisarius博士11

@belisarius私はそれをブレットの質問への回答にコピーしました...
Sjoerd C. de Vries

@Sjoerdここでのプロットは自動更新されません。
belisarius博士、2011年

@belisarius実は私はあなたがあなたにその仕事を任せてくれることを望んでいました... ;-)
Sjoerd C. de Vries

13

式のキャッシュ

これらの関数は、式をキャッシュするのに非常に役立ちます。これらの2つの関数のここでの興味深い点は、保持された式自体がハッシュテーブル/シンボルのキャッシュまたはキャッシュインデックスのキーとして使用されることです。 [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}を評価する方がはるかに高速です。

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

キャッシュされた値の削除

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

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

プロパティはDownValuesとして保存され、メソッドは返されるModuleによって作成されたシンボルの遅延されたUpvaluesとして保存されます。Mathematicaのツリーデータ構造の関数の通常のOO構文である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]を返した場合、NewObjectの外部(内部ではなく)にfunctionとfunction2を定義して、以前と同じように使用できます。 。

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

UpValues [type]を使用して、関数と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でピボットテーブル関数をどのように実行しますか?

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

内部 `バッグ

Daniel Lichtblauはここで、リストを増やすための興味深い内部データ構造について説明します。

Mathematicaで四分木を実装する

デバッグ機能

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

Mathematicaを使用して小さなコードまたは大きなコードを書き込むときにデバッグする方法は?ワークベンチ?mmaデバッガ?または、他の何か?(それを示す)

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

次に、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


関連:「メモリを備えた関数を構築する最良の方法」。WReachは、その値を記憶するだけでなく、それらをファイルに書き込み、再起動時に逆方向に読み取る単純な関数の驚くべき例を示しました。
Alexey Popkov

1
関連:「Mathematica:シンボルのキャッシュをクリアする方法、すなわちパターンフリーのDownValuesの設定を解除する」この質問は、標準のf[x_] := f[x] = some codeメモ化を使用してキャッシュをクリアする方法を示しています。
Simon

7
+1キャッシング関数の定義の左側を繰り返す必要をなくす、便利な表記法がありますc:Cache[expr_] := c = expr。例:
WReach

の素敵なバリアントSelectEquivalents。ただしTagOnElement、2番目のパラメーターはデフォルトで使用するIdentityので、デフォルトのままにしておきます。FinalOp内で処理できるので、も含めていないと思いますOpOnTaggedElems。また、オプション名を短くすると、入力するのが面倒になるためです。試してみてくださいTagFunctionTransformElementTransformResults、とTagPattern代わりに。どちらも、TagPatternそしてMapLevel全体的な偉大な機能への追加、および優れた書き換え、です。
rcollyer

コメントrcollyerをありがとう。私はそれを考慮に入れて、コードの可読性も改善しました。FinalFunctionはReapの結果を操作するため、たとえば、最終的な結果をタグで並べ替えたい場合は、それらを保持します。
faysou

12

私のユーティリティ関数(これらは質問で言及されている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).   *)

"each"関数については、stackoverflow.com
questions / 160216 / foreach

11

私が使用した1つのトリックは、ほとんどの組み込み関数が不正な引数で動作する方法をエミュレートできるようにします(メッセージを送信し、フォーム全体を未評価で返すことにより)Condition、定義で使用した場合の動作の癖を悪用します。foo1つの引数でのみ機能する場合:

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

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

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

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

1
HeldExpressionsパッケージの要素の+1は、それを認識していませんでした。私は通常、文字列としてインポートしToExpressionてからHoldComplete、最後の引数としてwith を使用していました。Conditionメッセージでの使用について-これは、少なくとも1994年以来、パッケージ作成の標準的な手法ですModule。varsによる永続化について-Mathgroupでこれについて長い間投稿しました:groups.google.com/group/comp.soft- sys.math.mathematica /…(そのスレッドの私の3番目の投稿)、これは同じ行に沿っており、いくつかの重要な使用例へのリンクがあります。
Leonid Shifrin

@Leonid Shifrin:私はConditionおそらく同僚から伝承として物を拾いましたが、それが標準的な技術であることを理解していませんでした。Module参照タイプとしてシンボルを使用することに関するリンクは興味深いです!
ピルシー

+1、私はそのことを考えたことはありません。私がこの言語について学ぶほど、それはより強力に思えます。
rcollyer 2011

@Pillsyそのようにスタックを行う目的は何ですか?
Mr.Wizard、2011年

@ Mr.Wizard:このテクニックを説明するために、考えられる最も単純な可変データ構造の1つを選びました。
ピルシー

11

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

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]] ます置き換えるab、ネストされた中WithRuleしながら、Withこれを実行しません。

これは、andの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グラフィックスをネイティブにサポートしていない場合でも、3Dグラフィックスをアンチエイリアスするための非常にシンプルな手法です。

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

次に例を示します。

Mathematicaグラフィック Mathematicaグラフィック

大きな値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グラフィック


すべてが良いでしょうが、サンプルの呼び出しの前にsayを割り当ててからを呼び出すことでわかるように、これは実際には変数をローカライズしません。代わりに次を使用して保存できます。意味WRT違い、その後:今のルールの1 rhsidesがされていない 2を評価したように、内側のスコープ構築物で名前の競合解決しないんです。最後のものはかなり深刻です-場合に応じて良いことでも悪いことでもあります。a = 3; b = 4;withRulesSetAttributes[withRules, HoldAll];withRules[rules_, expr_] := Unevaluated[expr] /. Unevaluated[rules]WithwithRulesWith
Leonid Shifrin

@Leonidあなたは完全に正しいです。投稿する前にコードを適切にチェックすることについて学ぶことはないようです...これを使用するとき、私は実際には変数に値を割り当てませんが、それはかなり深刻な問題ですよね。修正されたバージョンについてどう思いますか?(私は本当にについて、ネストされた処理していない気にしないWith。Sを組み込みローカリゼーション構築物でこの常にない仕事をいずれか、例えばWith[{a=1}, Block[{a=2}, a]]あなたは、ネストされたが、正当な理由があると思います。Blockネストされたように、そこにローカライズしないWithModuleんが?)
Szabolcs

@RHeonid RHSを評価しUnevaluated[rules]たかっx -> 1+1たので、単に使用しませんでした。
Szabolcs 2011

@Leonid正解です。ネストされたローカリゼーションの問題は非常に深刻です。入れ子になったWithは簡単に見つけて避けることができると思いますが、パターンはそうではありません。With[{a = 1}, a_ -> a]内部aをローカライズしますが、withRulesそうではありません。Mathematicaの内部ローカリゼーションメカニズムにアクセスし、ローカライズする(と同様のRule)新しい構成を作成する方法があるかどうか知っていますか?この回答は役に立つより危険なので、後で削除する可能性がありますが、少し先に試してみたいと思います。
Szabolcs、2011

あなたの使用InheritedBlockはかなりクールで、非常にエレガントに問題を解決すると思います。スコープの競合については、通常、字句スコープのバインディングは「字句バインディング時」に発生します。つまり、実行時の前に、動的スコープは実行時にバインドします。Moduleこれは、建設的な使用を可能にする同様のケースと対照的です(たとえば、ここでstackoverflow.com/questions/7394113/…を参照)。問題は、それBlockが...にシンボルを必要とすることです
レオニードシフリン

9

再帰的な純関数(#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}} 

接続されたコンポーネントの機能は今でも私のお気に入りです:-)
Szabolcs

@Szabolcsはい、それはかなりクールです。あなたとフレッドはそのほとんどを行いました、ボビーと私はいくつかの改良、IIRCを追加しました。
Leonid Shifrin、

8

これはスタンワゴンの本のレシピです...組み込みのプロットが精度の不足のために不規則に動作するときに使用します

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のダウンバリューからの「辞書のような」振る舞いが必要なとき、私はクリスチャン・カンニケの次のトリックをよく使用します

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

使用例は素晴らしいでしょう。時間があるときに投稿してください。
belisarius博士、10

あなたはクリスチャンを知っていますか?私はヘルシンキで彼と同じグループで働いていました。ナイスガイ、小さな世界。
Timo

いいえ、ウェブ上でコードを見つけました。実際、コードの小さなバグを修正するために彼に電子メールを送ろうとしたが、彼のウェブページの電子メールは機能しなくなった
Yaroslav Bulatov

8

文書化されていない使用してバッチモードでMathKernelを実行することが可能であるコマンドラインオプションを-batchinput-batchoutput

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

(ここinput.mで、改行文字で終わるバッチ入力ファイルoutputfile.txtは、出力がリダイレクトされるファイルです)。

Mathematicaの。V> = 6 MathKernelは、文書化されていないコマンドラインオプションがあります。

-noicon

MathKernelのタスクバーにアイコンを表示するかどうかを制御します(少なくともWindowsの場合)。

フロントエンド(少なくともv.5以降)にはドキュメント化されていないコマンドラインオプションがあります

-b

これはスプラッシュスクリーンを無効にし、Mathematicaフロントエンドをより速く実行できるようにします

とオプション

-directlaunch

これにより、システムレジストリの.nbファイルに関連付けられたバージョンを起動する代わりに、インストールされている最新のMathematicaバージョンを起動するメカニズム無効になります。

これを行う別の方法は、おそらく次のとおりです

インストールディレクトリでMathematica.exeバイナリを起動する代わりに、SystemFiles \ FrontEnd \ Binaries \ WindowsでMathematica.exeバイナリを起動します。前者は、ノートブックを開く要求をユーザーインターフェイスの実行中のコピーにリダイレクトするのが最も難しい単純なランチャープログラムです。後者はユーザーインターフェイスバイナリ自体です。

最後のコマンドラインオプションをグローバルフロントエンドオプションの設定と組み合わせて、インストールされているVersionedPreferences->True 異なるバージョンのMathematica間の設定の共有を無効にするのは便利です

SetOptions[$FrontEnd, VersionedPreferences -> True]

(上記は、インストールされている最新のMathematicaバージョンで評価する必要があります。)

Mathematica 8 これは設定の下で、「作成したバージョンの特定のフロントエンドの環境設定を維持する」、システムのペインで、[環境設定]ダイアログで制御されています

ドキュメントに記載されていないキー-h(Windowsのコード)を使用して、フロントエンドのコマンドラインオプションの不完全なリストを取得することができます。

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

与える:

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

その他のオプションは次のとおりです。

-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とフロントエンドの潜在的に有用な他のコマンドラインオプションはありますか?ご存知でしたらシェアしてください。

関連する質問


「一致ビットネス?」どういう意味ですか?
Mr.Wizard、2011年

@ Mr.Wizardおそらくこのオプションは、64ビットシステムとオプションの組み合わせでのみ-32意味があり、FrontEndで使用されるMathKernelのビット数がオペレーティングシステム(64ビット)のビット数と一致することを意味します。他のケースでは、このオプションは何も変更しないようです。
アレクセイポプコフ

7

私のお気に入りのハックは、標準のボイラープレートコマンドの束を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[]is is と入力すると、プライベートコンテキストが作成され、標準パッケージが読み込まれます。次に、独自のプライベートコンテキストで新しいスクラッチノートブックを開くコマンドを作成します(定義をめちゃくちゃにするリスクなしにワイルドアドバンテージでハックできるようになります)が、現在のコンテキストにアクセスできます。

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

これのクールな点はSelfDestruct、コマンドが実行されたときに、現在のノートブックにトレースが残されないことです。

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


7

PageWidthを指定したPutAppend-> Infinity

Mathematicaの使用PutAppendコマンドの中間計算の結果と実行中のログファイルを維持するための最も簡単な方法です。ただし、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}

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

SetOptions[OpenAppend, PageWidth -> Infinity]

更新

バージョン10で導入されたバグがあります(バージョン11.3で修正):およびSetOptionsの動作に影響を与えなくなりました。OpenWriteOpenAppend

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

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

この回答にWriteString示すようにvia を実装することもできますが、この場合、式を対応するvia に事前に変換する必要があることに注意してください。InputFormToString[expr, InputForm]


6

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


ヘルプから>バージョン2.0(1991年にリリース)以降、DebugはTraceに置き換えられました。
belisarius博士、2010年

1
@belisarius、あなたは要点を逃した。DebugTrace機能でもありません。それは私が自由にオン/オフを切り替えるためにコードを散らかすことができる私が作成したメッセージのセットです。msgが関数の名前で始まるのとDebug同じように、それらは単語でusage始まります。coutC ++コードに一連のステートメントを配置するのと同じ機能を提供します。
rcollyer

1
おお…ごめんなさい。「首都は国のために」を学ばなかったために幼稚園を卒業したことがなかったので、私は混乱しました:D
belisarius Dr. belisarius

6

組み込みのスコープ構成について私が気になることの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[];

ヤヌスは、このバージョンを掲示し、MathGroupにあなたの質問を参照しています stackoverflow.com/questions/4190845/custom-notation-question/...
Mr.Wizard

指摘してくれてありがとう!私がこの資料を見たのは久しぶりで、これらすべての他のアプローチを見るのは興味深いです。
DGrady 2011

5

これは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] 引用符をきれいに削除します。


5

このコードは、選択範囲を画像として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[];

4

多くの人が何かを実行する状況に遭遇し、プログラムが動かなくなっただけでなく、最後の10分間保存されていないことに気づいたと思います。

編集

この問題にしばらく悩んだ後、ある日、Mathematicaコード内から自動保存作成できることがわかりました。そういうオートセーブを使えばとても助かったと思いますし、その可能性自体は自分ができると気づいていない人が多いと感じていました。

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

このためのコードはで見つけることができるこの回答から、Sjoerd C. de Vries (ここにそれをコピーすることのOKは、私が唯一のリンクとしてそれを残している場合、私はわからないので。)


以下のソリューションはを使用していDynamicます。60秒ごとにノートブックを保存しますが、そのセルが表示されている場合のみです。完了の理由でのみここに残します。(およびMathematica 6および7のユーザー向け)

/編集

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

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

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

私は最初にそれをここで見つけました:http : //en.wikipedia.org/wiki/Talk : Mathematica#Criticisms

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

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


また、ファイル名の最後に現在の時刻と日付を追加するなどして別の名前で保存したり、特定のディレクトリ(「バックアップ」など)に保存したりすることもできます。これは、バージョン管理の原始的な形式のようなものです。
acl

のようなことができますがNotebookSave[SelectedNotebook[], "work-" <> IntegerString[i] <> ".nb"]; i++、現在のノートブック名を参照すると、どんな種類でも再帰的になると思います。
tsvikas

2
Dynamicオブジェクトは表示されたときにのみ更新されると思ったので、たとえばDynamicオブジェクトを表示領域の外にスクロールした場合、このメソッドが機能するかどうかはわかりません。もう一度、私は試していません。いずれにせよ、私はそれを提案として提示しただけです。
2011

1
を使用してこれをテストできDynamic[Refresh[i++, UpdateInterval -> 1, TrackedSymbols -> {}]]ます。増分する数値をスクロールしてスクロールし、1分待ってからスクロールして、数値が60ずつ増加しないことを確認します。概要UpdateInterval:これは通常、可能な場合に使用されますが、コードに変更する変数が含まれている場合、この変更により、新しい更新がトリガーされます。インターバルは終了します。せずに上記の行を試してくださいTrackedSymbols
Sjoerd C. de Vries '30 / 08/30

1
@ j0ker5上記のコードを試してみると、UpdateIntervalが常に更新を強制的に指定された間隔で配置するわけではないことがわかります。このコードは、Dynamicが含まれているセルがフロントエンドに表示されている場合にのみDynamicが機能することも示しています。見えなくなった瞬間に本当に止まります。ファイルを保存するためにこのコードを信頼するべきではありません。そうしないからです。危険
Sjoerd C. de Vries、2011


3

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

Leonidが作成した非常に便利なPackageManipulationsライブラリをロードします。2番目のセルには

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

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

次に、パッケージの作成とテストのワークフローは次のようになります。

  1. 変更をに保存しますPackagename.m
  2. に行ってPackagenameTest.nbくださいCTRL + ALT + i

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


1

次の関数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]]
*)

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


これを実際に何に使用していますか?出力は少しもあり、「面白い」(、リストあなたのコードやデータに適用したときのいずれかの読み出しを可能にするformat@RandomInteger[10,{3,3}]):pastebin.com/nUT54Emq すでに基本を持っていて、この中で興味を持っているので、あなたがにコードを向上させることができます読みやすいフォーマットを作成しますか?次に、次のステップは、うまくインデントされたMathematicaコードで入力セルを作成する貼り付けボタンを作成することです(できればコメントを保持します!!)私の関連する質問も参照してください。
Szabolcs、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.