Mathematicaが素晴らしいことは誰もが知っていますが、多くの場合、重要な機能が欠けています。 Mathematicaではどのような外部パッケージ/ツール/リソースを使用していますか?
このメインポストを編集して(そして他の人にもそうするように)、科学研究における一般的な適用性に焦点を当て、できるだけ多くの人が役に立つリソースを含めるようにします。少しでもコードスニペット(下記のタイミングルーチンで行ったように)に貢献してください。
また、Mathematica 7以降のドキュメントに記載されていない便利な機能や、自分で見つけたもの、またはいくつかの紙/サイトから掘り下げたものも大歓迎です。
簡単な説明を含めるか、何かが素晴らしい理由やそれが提供するユーティリティについてコメントしてください。アフィリエイトリンクを使用してAmazonの書籍にリンクする場合は、リンクの後に名前を入力するなどして、そのことを明記してください。
パッケージ:
LevelScheme
は、見栄えの良いプロットを生成するMathematicaの機能を大幅に拡張するパッケージです。フレーム/軸の目盛りのはるかに改善された制御のために、それ以外の場合は使用しません。最新バージョンはSciDrawと呼ばれ、今年中にリリースされます。Presentation Package
(US $ 50-アップデートの無料)grassmannOps
パッケージは、Grassmann変数と非自明な交換関係を持つ演算子で代数と計算を行うためのリソースを提供します。GrassmannAlgebra
グラスマン代数とクリフォード代数を扱うためのパッケージと本。ツール:
MASH
はDaniel Reevesの優れたものです Perl Mathematica v7のスクリプトサポートを本質的に提供するスクリプト。 (現在Mathematica 8で-script
オプション。alternate Mathematica Shell
with GNU readline input(python、* nixのみを使用))リソース:
Wolfram独自のリポジトリ MathSource
は、さまざまなアプリケーション用の狭いノートブックの場合に非常に便利です。次のような他のセクションもチェックしてください
Current Documentation
、Courseware
講義の場合、Demos
は、デモ用です。書籍:
web
、 pdf
) MathematicaのForループ以上のことをしたい場合は必読です。 Leonid
自身がここで質問に答えてくれることを嬉しく思います。web
)Demonstrations Page
。pdf
)-Mathematicaプログラミングについて知っておくべきことのほとんどを簡潔に紹介します。文書化されていない(またはほとんど文書化されていない)機能:
this question
。this answer
this question
。this question
。以前に this について言及しましたが、最も便利だと思うツールは、Reap
の動作を模倣/拡張するSow
と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
の- 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]
しかし、これと上記の完全ではない例を使用すると、最小限のコードで非常に複雑な変換がどのように可能になるかを簡単に確認できます。
Mathematicaノートブックインターフェースの良いところの1つは、Mathematicaだけでなくany言語で式を評価できることです。簡単な例として、含まれている式を評価のためにオペレーティングシステムシェルに渡す新しいShell入力セルタイプを作成することを検討してください。
最初に、テキストコマンドの評価を外部シェルに委任する関数を定義します。
shellEvaluate[cmd_, _] := Import["!"~~cmd, "Text"]
2番目の引数は、後で明らかになる理由で必要であり、無視されます。次に、Shellという新しいスタイルを作成します。
Shell
と入力します。次のセル式をとして使用しますステップ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
は、このセルが異常であることをユーザーが識別できるようにするだけの便利な機能です。
これらすべてが整ったら、シェル式を入力して評価できます。
この定義されたスタイルは、中央に配置されたスタイルシートに保存することをお勧めします。さらに、shellEvaluate
のような評価関数は、init.m
で DeclarePackage を使用してスタブとして最適に定義されます。これら両方のアクティビティの詳細は、この対応の範囲を超えています。
この機能を使用すると、目的の構文の入力式を含むノートブックを作成できます。評価関数は、純粋なMathematicaで作成することも、評価の一部またはすべてを外部機関に委任することもできます。 CellEpilog
、CellProlog
、CellDynamicExpression
など、セル評価に関連する他のフックがあることに注意してください。
一般的なパターンには、入力式テキストを一時ファイルに書き込み、ファイルを何らかの言語でコンパイルし、プログラムを実行し、出力セルに最終表示するために出力をキャプチャすることが含まれます。この種の完全なソリューション(エラーメッセージを適切にキャプチャするなど)を実装する際には、対処すべき詳細がたくさんありますが、このようなことができるだけでなく実用的であるという事実を理解する必要があります。
個人的には、ノートブックインターフェイスを私のプログラミングユニバースの中心にしているのはこのような機能です。
更新
次のヘルパー関数は、このようなセルを作成するのに役立ちます。
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[]
が評価されると、入力セルは削除され、その内容をシェルコマンドとして評価する新しい入力セルに置き換えられます。
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];
これは完全なリソースではないので、ここで回答セクションに投げていますが、速度の問題を理解する際に非常に便利です(残念ながら、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はThrow
とCatch
を廃止し、解析が少し簡単な簡単なバージョンを提供しました:
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]
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
のグローバル定義に影響を与えずに、必要に応じて変更できます。
Mathematicaは鋭いツールですが、やや ntyped behaviour と avalanches の不可解な 診断メッセージ であなたをカットできます。これに対処する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}
すべての通常の属性に加えて、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: ``";
展示されている実装は、アップバリューもカリー化も、単純な関数定義よりも一般的なパターンもサポートしていません。ただし、それでも有用です。
空白のノートブックを開いた状態で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番目の引数は、分割仕様を超えた要素に何が起こるかを制御します。
最も頻繁に使用するのは、表形式のデータパレットの貼り付けです
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.} *)
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ファイルの品質は、元のグラフィックオブジェクトのMagnify
ingによって向上させることができるため、元のグラフィックのサンプリングの正確さがより正確になります。 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
メニュー項目( このルート )。
これらの関数は、式をキャッシュするのに非常に役立ちます。ここでこれらの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 。
@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関数をどのように実行しますか?
Daniel Lichtblauは、ここで成長するリストの興味深い内部データ構造を説明します。
これらの2つの投稿は、デバッグに役立つ機能を示しています。
Mathematicaを使用して小さなコードまたは大きなコードを書くときのデバッグ方法?ワークベンチ?mmaデバッガー?または他の何か? (ShowIt)
次に、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*)
学習用の興味深いリンクのリストは次のとおりです。
一般的な需要により、 SO API を使用して、トップ10 SO answerersプロット( annotations を除く)を生成するコード。
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", ""})]
私のユーティリティ関数(質問で言及されている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). *)
以下の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]]
警告:この関数は、With
およびModule
と同じ方法で変数をローカライズしません。つまり、ネストされたローカライズコンストラクトは期待どおりに機能しません。 withRules[{a -> 1, b -> 2}, With[{a=3}, b_ :> b]]
willネストされたa
およびb
のWith
および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グラフィックをアンチエイリアスする非常に簡単な手法です。
antialias[g_, n_: 3] :=
ImageResize[Rasterize[g, "Image", ImageResolution -> n 72], Scaled[1/n]]
以下に例を示します。
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]]}]
]
私が使ったトリックの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]]
再帰的な純粋関数(_#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}}
_
これはスタンワゴンの本のレシピです...組み込みの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]]
私のお気に入りのハックは、標準のボイラープレートコマンドの束を1つの短いものに置き換えることができる小さなコード生成マクロです。または、ノートブックを開く/作成するためのコマンドを作成できます。
日々のMathematicaワークフローで私がしばらく使用してきたものを次に示します。私は次のことをたくさん実行していることに気付きました。
このすべてを何度も手作業で行うのは苦痛なので、自動化しましょう!まず、いくつかのユーティリティコード:
(* 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
を使用してこれらのマクロのキーワードトリガーを作成できますが、これは読者の演習として残しておきます。
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}
したがって、次を設定することにより、一度に1行のみを追加するPutAppend
を取得できます。
SetOptions[OpenAppend, PageWidth -> Infinity]
[〜#〜] update [〜#〜]
バージョン10で導入された バグ (バージョン11.3で修正):SetOptions
はOpenWrite
およびOpenAppend
の動作に影響しなくなりました。
回避策は、明示的なPageWidth -> Infinity
オプションでPutAppend
の独自のバージョンを実装することです。
Clear[myPutAppend]
myPutAppend[expr_, pathtofile_String] :=
(Write[#, expr]; Close[#];) &[OpenAppend[pathtofile, PageWidth -> Infinity]]
this answerに示すようにWriteString
を介して実装することもできますが、この場合は、ToString[expr, InputForm]
を介して式を対応するInputForm
に事前に変換する必要があります。
組み込みのスコープ構成体について気になることの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[];
これに含めるパッケージを探していたところ、動作が不思議だと定義したメッセージが見つかりました:Debug::<some name>
。デフォルトではオフになっているため、オーバーヘッドはあまり発生しません。しかし、私はそれらをコードに散らばらせ、コードのビットがどのように動作しているかを正確に把握する必要がある場合はそれらをオンにすることができます。
このコードは、選択範囲を画像として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[];
これは、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]
は引用符をきれいに削除します。
私は多くの人々が何かを実行する状況に遭遇したと確信しています。それはプログラムを動かさないだけでなく、彼らも最後の10分間保存していない!
これにしばらく苦しんだ後、私はある日、誰かがMathematicaコード内から自動保存を作成できることを発見しました。そのような自動保存を使用することは、過去に私を大いに助けたと思います。そして、私はいつも可能性自体は、多くの人ができることを認識していない何かだと感じました。
使用した元のコードは下部にあります。問題があることと、ScheduledTask
(Mathematica 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には元に戻らないため、保存すると元に戻せないため、すべてのコンテンツを削除しないように注意してください(予防措置として、完成したすべてのノートブックからこのコードを削除します)
Mathematica Bookはオンラインで http://reference.wolfram.com/legacy/v5_2/ でも入手できますが、 http:// reference。 wolfram.com
このキーボードショートカットを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
すべてのシンボルにのみ存在することに注意してください。
次に、パッケージを作成してテストするためのワークフローは次のようになります。
Packagename.m
への変更を保存します。PackagenameTest.nb
に移動して、CTRL + ALT + i
を実行します。これにより、初期化セルがパッケージをリロードするため、テストが非常に簡単になります。
次の関数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