您的Mathematica工具箱里有什么?

159
我们都知道Mathematica非常棒,但它经常缺乏关键功能。你使用哪些外部软件包/工具/资源来与Mathematica一起使用? 我会编辑(并邀请其他人也这样做)这个主帖,以包括专注于科学研究的通用性资源,并且尽可能多的人会发现它们有用。随意贡献任何东西,甚至是小的代码片段(正如我在下面为计时例程所做的那样)。 此外,请包含简短的描述或评论,说明某些东西的优点或提供的实用程序。如果您使用带有附属链接的Amazon图书,请在链接后面提到它,例如通过在链接后面放置您的姓名。

程序包:

  1. LevelScheme是一个扩展Mathematica能力的包,可以生成漂亮的图形。我使用它,不仅因为它可以更好地控制框架/轴刻度,而且因为其最新版本称为SciDraw,将在今年发布。
  2. David Park的Presentation Package(50美元-更新免费)
  3. Jeremy Michelson的grassmannOps包提供了使用Grassmann变量和算子进行代数和微积分运算的资源,这些变量和算子具有非平凡的对易关系。
  4. John Brown的GrassmannAlgebra包和书籍用于处理Grassmann和Clifford代数。
  5. RISC(符号计算研究所)有多个可供下载的Mathematica(和其他语言)包。特别是,有Theorema用于自动定理证明,以及在Algorithmic Combinatorics group's software page上的多个包,用于符号求和、差分方程等。

工具:

  1. MASH 是 Daniel Reeves 出色的 Perl 脚本,基本上为 Mathematica v7 提供了脚本支持。 (现在已经作为 Mathematica 8 的内置功能,使用 -script 选项.)
  2. 一款带有 GNU readline 输入的备用 Mathematica shell (仅限于使用 python 的 *nix 系统)
  3. ColourMaths 包允许您直观地选择表达式的部分并对其进行操作。 http://www.dbaileyconsultancy.co.uk/colour_maths/colour_maths.html

资源:

  1. 沃尔夫拉姆自己的存储库 MathSource 有很多有用但比较狭窄的笔记本,适用于各种应用。还要查看其他部分,例如:

  2. Mathematica Wikibook

书籍:

  1. 如果你想在Mathematica中做更多的事情而不仅仅是使用For循环,那么Leonid Shifrin的《Mathematica programming: an advanced introduction》(webpdf)是必读的。我们很荣幸有Leonid本人在这里回答问题。
  2. James F. Feagin的《Quantum Methods with Mathematica》(amazon
  3. Stephen Wolfram的《The Mathematica Book》(amazon)(web
  4. Schaum's Outline(amazon
  5. Stan Wagon的《Mathematica in Action》(amazon}})- 600页整洁的示例,适用于Mathematica版本7及以上。可视化技术尤其出色,您可以在作者的Demonstrations Page上看到一些示例。
  6. Richard Gaylord的《Mathematica Programming Fundamentals》(pdf)- 对Mathematica编程的大部分必要知识进行了简明扼要的介绍。
  7. Sal Mangano所著的《Mathematica Cookbook》由O'Reilly于2010年出版,共832页。 - 采用著名的O'Reilly Cookbook风格:问题-解决方案。适用于中级用户。
  8. Martha L. Abell和James P. Braselton所著的《Differential Equations with Mathematica, 3rd Ed. Elsevier 2004 Amsterdam》- 893页。适用于初学者,可以同时学习解决微分方程和Mathematica。

未经记录(或很少记录)的功能:

  1. 如何自定义Mathematica键盘快捷键。请参见this question
  2. 如何检查Mathematica自身函数使用的模式和函数。请参见this answer
  3. 如何在Mathematica中实现GraphPlots的一致大小?请参见this question
  4. 如何使用Mathematica制作文档和演示文稿。请参见this question

2
Mathematica 8已经发布,具有更好的shell脚本集成功能。http://www.wolfram.com/mathematica/new-in-8/mathematica-shell-scripts/ - Joshua Martell
2
+1,支持LevelScheme。虽然有时速度有点慢,但它有一个合理的方法来创建刻度线,而且比“Grid”或类似的工具更容易创建适合期刊的图形布局。 - rcollyer
2
正如Alexey在这个问题的评论中提出的建议https://dev59.com/I1TTa4cB1Zd3GeqPvcev,我在这里提出了Mathematica的标签重命名:http://meta.stackexchange.com/questions/81152/retag-mathematica-to-wr-mathematica-or-something-similar。请看一下,如果您同意,请点赞。我在这里发布是因为这个问题在Mma社区中有很多收藏。 - Dr. belisarius
1
这个问题应该是社区维基的,因为它没有正确答案,更像是一个列表。我向所有从这个问题中获得声望的人道歉。 - rcollyer
2
这些回答对于这个问题是有建设性的,应该重新开放。 - M.R.
显示剩余9条评论
26个回答

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

我发现这个例程对于将大的实数以普通十进制形式复制到剪贴板非常有用。例如:CopyToClipboard["123456789.12345"]

Cell[OutputFormData@expr]可以整洁地去掉引号。


5
这段代码制作了一个调色板,将所选内容上传到Stack Exchange作为图像。在Windows上,提供了一个额外的按钮,可以更真实地呈现所选内容。
将代码复制到笔记本单元格中并进行评估。然后从输出中弹出调色板,并使用“Palettes-> Install Palette…”进行安装。
如果您遇到任何问题,请在此处发表评论。在此处下载笔记本版本here
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
我相信很多人都遇到过这种情况:他们运行一些东西,意识到不仅卡住了程序,而且还有最近十分钟没有保存!

编辑

在遭受了一段时间的痛苦后,我有一天发现可以在Mathematica代码内部创建自动保存。我认为使用这样的自动保存在过去帮助了我很多,并且我一直觉得这个可能性并不是很多人知道他们可以做到的。

我使用的原始代码位于底部。感谢评论,我发现它存在问题,并且用ScheduledTask来做要好得多(只适用于Mathematica 8)。

此代码的解决方案可以在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中没有撤消功能,请小心不要删除所有内容,因为保存将使其无法恢复(为了预防起见,我会在每个完成的笔记本中删除此代码)。

你可以像这样做:NotebookSave[SelectedNotebook[], "work-" <> IntegerString[i] <> ".nb"]; i++,但我认为任何对当前笔记本名称的引用都会变成递归。 - tsvikas
我很好奇 - 在这种情况下,定时任务相比于“动态”有哪些优势? - tsvikas
2
我认为Dynamic对象只有在可见时才会刷新,所以如果您将Dynamic对象滚动到不可见区域,我就不确定这种方法是否有效。但再次强调,我仅仅是提出了一个建议。 - acl
1
您可以使用Dynamic[Refresh[i++, UpdateInterval -> 1, TrackedSymbols -> {}]]进行测试。将递增的数字滚动出视线,等待一分钟,然后滚回来,您会发现数字没有增加60。关于UpdateInterval:通常情况下尽可能使用它,但是如果您的代码包括变量更改,则此更改会在间隔结束之前触发新的刷新。尝试在不使用TrackedSymbols的情况下执行上述行。 - Sjoerd C. de Vries
1
@j0ker5 试试我上面的代码,你会发现UpdateInterval并不总是强制更新以指定的间隔间隔。这段代码还表明,Dynamic仅在包含它的单元格在前端可见时才起作用。一旦超出视线,它就真的停止了。人们真的不应该信任这段代码来保存他们的文件,因为它是危险的 - Sjoerd C. de Vries
显示剩余14条评论

3

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笔记本用于测试,测试笔记本的前两个单元格被设置为初始化单元格。在第一个单元格中,我放置了以下内容:

Needs["PackageManipulations`"]

加载非常有用的 PackageManipulations 库,该库由Leonid编写。第二个单元格包含

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

需要实际的包重新加载所有东西。请注意,前两行仅用于删除所有符号,因为我希望尽可能保持上下文的清洁。

然后,编写和测试软件包的工作流程变成了这样。

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

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


你在实践中用这个做什么?输出结果有点太“滑稽”,无论是应用于你的代码还是数据(列表,format@RandomInteger[10,{3,3}]):http://pastebin.com/nUT54Emq。既然你已经掌握了基础知识并且对此感兴趣,你能否改进代码以产生有用的可读格式?然后下一步是制作一个粘贴按钮,它将创建一个带有漂亮缩进的Mathematica代码输入单元格(最好保留注释!!)。另请参见[我的相关问题](https://dev59.com/DlzUa4cB1Zd3GeqP8Pjb)。 - Szabolcs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接