您的Mathematica工具包里有什么?

Tim*_*imo 149 resources wolfram-mathematica

我们都知道Mathematica很棒,但它也经常缺乏关键功能.您在Mathematica中使用哪种外部包/工具/资源?

我将编辑(并邀请任何其他人也这样做)这个主要帖子包括专注于科学研究的一般适用性的资源,并且尽可能多的人会觉得有用.随意贡献任何东西,甚至是小代码片段(正如我在下面做的时间例程).

此外,在Mathematica 7及其他您发现自己,或从一些纸张/网站挖出的无证和有用的功能是非常受欢迎的.

请提供简短描述或评论为什么有什么好东西或它提供的实用程序.如果您使用会员链接链接到亚马逊上的书籍,请提及它,例如,在链接后面加上您的姓名.


包:

  1. LevelScheme是一个大大扩展Mathematica生产美观图的能力的软件包.我使用它,如果没有其他任何东西,那么对框架/轴刻度的大大改进控制.它的最新版本称为SciDraw,它将在今年的某个时候发布.
  2. David Park's Presentation Package(50美元 - 免费更新)
  3. Jeremy Michelson的grassmannOps软件包提供了使用Grassmann变量和具有非平凡换向关系的算子进行代数和微积分的资源.
  4. 约翰·布朗(John Brown)GrassmannAlgebra与格拉斯曼(Grassmann)和克利福德代数(Clifford algebras)合作的包和书.
  5. RISC(符号计算研究所)提供各种Mathematica(和其他语言)包可供下载.特别是,有自动定理证明的Theorema,以及Algorithmic Combinatorics小组软件页面中用于符号求和,差分方程等的多个包.

工具:

  1. MASH是Daniel Reeves出色的Perl脚本,主要为Mathematica v7提供脚本支持.(现在-script可以选择使用Mathematica 8制作.)
  2. 一个alternate Mathematica shell与GNU的readline输入(使用python,*nix中只)
  3. ColourMaths包允许您直观地选择表达式的各个部分并对其进行操作.http://www.dbaileyconsultancy.co.uk/colour_maths/colour_maths.html

资源:

  1. MathSource对于各种应用程序,Wolfram自己的存储库有很多有用的缩小笔记本.另请参阅其他部分,例如

  2. 数学维基教科书.

图书:

  1. Mathematica编程: Leonid Shifrin(web,pdf)的高级介绍是必读的,如果你想在Mathematica中做更多的For循环.我们很高兴在Leonid这里回答问题.
  2. 使用Mathematica量子方法作者:James F. Feagin(亚马逊)
  3. 斯蒂芬沃尔夫勒姆的Mathematica书(亚马逊)(web)
  4. Schaum的大纲(亚马逊)
  5. Stan Wagon(亚马逊)中的Mathematica in Action - 600页简洁的例子和Mathematica版本7.可视化技术特别好,你可以看到作者的一些Demonstrations Page.
  6. Mathematica编程基础由Richard Gaylord撰写(pdf) - 对您需要了解的关于Mathematica编程的大部分内容的简要介绍.
  7. Sal Mangano的Mathematica Cookbook由O'Reilly 2010年出版832页. - 用着名的O'Reilly Cookbook风格写成:问题 - 解决方案.对于中间体.
  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.

WRe*_*ach 57

Mathematica笔记本界面的一个好处是它可以用任何语言评估表达式,而不仅仅是Mathematica.举个简单的例子,考虑创建一个新的Shell输入单元格类型,它将包含的表达式传递给操作系统shell进行评估.

首先,定义一个将文本命令的评估委托给外部shell的函数:

shellEvaluate[cmd_, _] := Import["!"~~cmd, "Text"]
Run Code Online (Sandbox Code Playgroud)

第二个论点是必要的,并且由于后来会变得明显的原因而被忽略.接下来,我们要创建一个名为Shell的新样式:

  1. 打开一个新笔记本.
  2. 选择菜单项格式/编辑样式表...
  3. 在对话框中,旁边输入样式名称:类型Shell.
  4. 选择新样式旁边的单元格括号.
  5. 选择菜单项单元格/显示表达式
  6. 使用下面给出的Step 6 Text覆盖单元格表达式.
  7. 再次选择菜单项Cell/Show Expression
  8. 关闭对话框.

使用以下单元格表达式作为步骤6文本:

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

大多数此表达式都是直接从内置的程序样式复制而来.关键的变化是这些方面:

 Evaluatable->True,
 CellEvaluationFunction->shellEvaluate,
 CellFrameLabels->{{None, "Shell"}, {None, None}},
Run Code Online (Sandbox Code Playgroud)

Evaluatable为单元格启用SHIFT + ENTER功能.评估将调用CellEvaluationFunction传递单元格内容和内容类型作为参数(shellEvaluate忽略后一个参数). CellFrameLabels让用户发现这个细胞是不寻常的,这只是一个非常好的事情.

完成所有这些后,我们现在可以输入并评估shell表达式:

  1. 在上述步骤中创建的笔记本中,创建一个空单元格并选择单元格括号.
  2. 选择菜单项格式/样式/外壳.
  3. 在单元格中键入有效的操作系统shell命令(例如,Unix上的'ls'或Windows上的'dir').
  4. 按SHIFT + ENTER.

最好将此定义的样式保存在位于中心的样式表中.此外,评估函数shellEvaluate最好使用DeclarePackage in 定义为存根init.m.这两项活动的详细信息都超出了本回复的范围.

使用此功能,可以创建包含任何感兴趣语法的输入表达式的笔记本.评估功能可以用纯Mathematica编写,或者将评估的任何或所有部分委托给外部机构.要知道,有一些涉及细胞的评价,像其他的钩子CellEpilog,CellPrologCellDynamicExpression.

常见模式包括将输入表达式文本写入临时文件,以某种语言编译文件,运行程序并捕获输出以在输出单元格中最终显示.在实现这种完整解决方案时(例如正确捕获错误消息),有很多细节需要解决,但是必须认识到这样的事实不仅可以做到这样,而且是实用的.

就个人而言,它是这样的功能,使笔记本界面成为我的编程世界的中心.

更新

以下辅助函数对于创建此类单元格非常有用:

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]
  )
Run Code Online (Sandbox Code Playgroud)

因此使用它:

shellCell[] := evaluatableCell["shell", Import["!"~~#, "Text"] &]
Run Code Online (Sandbox Code Playgroud)

现在,如果shellCell[]进行求值,则输入单元格将被删除并替换为新的输入单元格,该单元格将其内容评估为shell命令.

  • @WReach +100!我希望我早点知道!至少对我来说这是非常有用的东西.感谢分享! (3认同)
  • 另外:还有另一个与细胞评估有关的"细胞"选项 - "评估者 - >"评估者名称"`."EvaluatorName"的含义可以通过*Evaluation :: Kernel Configuration Options ...*对话框进行配置.我仍然不知道是否有可能以编程方式配置它...这种技术允许在一个Notebook中的不同`Cell`s中使用不同的MathKernel.这些MathKernel可以来自*Mathematica*的不同版本. (2认同)

Ale*_*kov 35

Todd Gayley(Wolfram Research)给我发了一个很好的黑客,它允许用任意代码"包装"内置函数.我觉得我必须分享这个有用的工具.以下是托德对我的回答question.

一些有趣的(?)历史:用于"包装"内置函数的黑客风格是由Robby Villegas和我在1994年左右发明的,具有讽刺意义的是函数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];
Run Code Online (Sandbox Code Playgroud)

  • @Sjoerd根据我的理解,'Unprotect`确实必须是,只是被遗漏了."Block"(动态范围)和"$ inMsg"的要点正是为了防止无限递归.因为`$ inMsg`在外面是未定义的(这是一个重要的要求),首先,`TrueQ`评估为'False`,然后我们进入函数体.但是当我们在body体内调用函数时,条件的计算结果为"False"(因为变量已被Block重新定义).因此,不匹配用户定义的规则,而是使用内置规则. (9认同)
  • @Leonid 谢谢,我现在明白了。非常聪明! (2认同)

rco*_*yer 29

我已经提到过这个之前,但工具我觉得最有用的是应用程序ReapSow其模拟/扩展的行为GatherBy:

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

这允许我按任何标准对列表进行分组,并在此过程中对其进行转换.它的工作方式是条件function(f)标记列表中的每个项目,然后每个项目由第二个提供的函数(g)转换,特定的输出由第三个函数(h)控制.该函数h接受两个参数:标记和具有该标记的收集项的列表.这些项目保留了原始顺序,所以如果你设置了h = #1&那么你会得到一个未排序的Union,就像在示例中一样Reap.但是,它可以用于二次加工.

作为其实用程序的一个例子,我一直在使用Wannier90,它将空间相关的哈密顿量输出到一个文件中,其中每一行是矩阵中的不同元素,如下所示

rx ry rz i j Re[Hij] Im[Hij]
Run Code Online (Sandbox Code Playgroud)

为了将该列表转换为一组矩阵,我收集了包含相同坐标的所有子列表,将元素信息转换为规则(即{i,j} - > Re [Hij] + I Im [Hij]),以及然后把收集的规则变成一个SparseArray带有一个班轮的全部:

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

老实说,这是我的瑞士军刀,它使复杂的事情变得非常简单.我的大多数其他工具都是针对特定领域的,所以我可能不会发布它们.但是,大多数(如果不是全部)参考SelectEquivalents.

编辑:它并不完全模仿GatherBy,因为它不能简单地将表达式的多个级别分组GatherBy.但是,Map对于我需要的大部分工作都可以正常工作.

例如:@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}}
Run Code Online (Sandbox Code Playgroud)

我们希望通过一组对称操作来减少点数.(好奇的是,我们正在生成每个点的小组.)对于这个例子,让我们使用围绕z轴的四倍旋转轴

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

使用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}}}
Run Code Online (Sandbox Code Playgroud)

它产生3个包含等效点的子列表.(注意,Union这里绝对至关重要,因为它确保每个点产生相同的图像.最初,我使用过Sort,但如果一个点位于对称轴上,则在围绕该轴的旋转下它是不变的,从而给出了一个额外的图像那么,Union消除这些额外的图像.而且,GatherBy会产生相同的结果.)在这种情况下,这些点已经是我将使用的形式,但我只需要每个分组的代表点,我想要一个计数等效点数.既然,我不需要改变每一点,我就用了Identity功能在第二位置.对于第三个功能,我们需要小心.传递给它的第一个参数将是旋转点下的点的图像,该点{0,0,0}是四个相同元素的列表,并且使用它将丢弃计数.但是,第二个参数只是包含该标记的所有元素的列表,因此它只包含{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}}
Run Code Online (Sandbox Code Playgroud)

注意,这最后一步可以很容易地完成

In[5] := {#[[1]], Length[#]}& /@ Out[3]
Run Code Online (Sandbox Code Playgroud)

但是,通过这个和上面不太完整的示例很容易看到如何使用最少的代码进行非常复杂的转换.


Tim*_*imo 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};
Run Code Online (Sandbox Code Playgroud)

然后简单地使用timeAvg@funcYouWantToTest.

编辑:向导先生提供了一个更简单的版本,可以解决Throw并且Catch更容易解析:

SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ 
                     Timing @ Do[func, {5^i}]
                     ,{i, 0, 15}]
Run Code Online (Sandbox Code Playgroud)

编辑:这是一个来自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]
Run Code Online (Sandbox Code Playgroud)

  • 现在有`RepeatedTiming`来做这件事. (3认同)
  • 蒂莫,我很高兴你能够将我的表现纳入其中.谢谢你也给我信任.我很好奇你重新格式化我的代码的方式.我不会在自己的代码中遵循任何特定的指导原则,除了让自己易于阅读之外; 你的重新格式化背后有一种思想流派,还是仅仅是偏好?Mathematica不鼓励精确的代码格式化,因为它回流输入的方式,但在这里发布代码导​​致我开始考虑它.顺便说一句,我认为你的意思是"扔"和"捕获"而不是"收获"和"播种". (2认同)

Ale*_*kov 20

Internal`InheritedBlock

我最近Internal`InheritedBlock从官方新闻组的Daniel Lichtblau的消息中了解到这种有用功能的存在.

据我了解,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]
Run Code Online (Sandbox Code Playgroud)

我认为这个功能对于需要暂时修改内置函数的每个人都非常有用!

与Block比较

让我们定义一些功能:

a := Print[b]
Run Code Online (Sandbox Code Playgroud)

现在我们希望将此函数的副本传递到Block范围中.天真的试验没有给出我们想要的东西:

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

During evaluation of In[9]:= b

Out[2]= {HoldPattern[a] :> Null}
Run Code Online (Sandbox Code Playgroud)

现在尝试在第一个参数中使用延迟定义Block(它也是一个未记录的功能):

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

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

During evaluation of In[3]:= b
Run Code Online (Sandbox Code Playgroud)

我们看到,在这种情况下a工作,但我们还没有得到原件及复印件a的内部Block范围.

现在让我们试试Internal`InheritedBlock:

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

Out[5]= {HoldPattern[a] :> Print[b]}
Run Code Online (Sandbox Code Playgroud)

我们已经获得了范围a内部原始定义的副本,Block我们可以按照我们想要的方式对其进行修改,而不会影响全局定义a!


WRe*_*ach 19

Mathematica是一个很好的工具,但它可以通过它有点无类型的行为雪崩的神秘诊断信息来削减你.解决这个问题的一种方法是定义遵循这个习语的函数:

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

这是很多样板,我经常试图跳过.特别是在原型设计时,Mathematica中发生了很多.所以,我使用一个叫做的宏define,让我保持纪律,更少的样板.

基本用法define是这样的:

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

fact[5]

120
Run Code Online (Sandbox Code Playgroud)

起初看起来并不多,但有一些隐藏的好处.提供的第一个服务define是它自动应用于ClearAll正在定义的符号.这确保了没有剩余的定义 - 在函数的初始开发期间经常发生.

第二项服务是定义的功能自动"关闭".我的意思是,如果使用与其中一个定义不匹配的参数列表调用该函数,该函数将发出消息并中止:

fact[-1]

define::badargs: There is no definition for 'fact' applicable to fact[-1].
$Aborted
Run Code Online (Sandbox Code Playgroud)

这是主要的值define,它捕获了一个非常常见的错误类.

另一个便利是在所定义的函数上指定属性的简明方法.让我们来做功能Listable:

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

fact[{3, 5, 8}]

{6, 120, 40320}
Run Code Online (Sandbox Code Playgroud)

除了所有常规属性外,还define接受一个名为的附加属性Open.这可以防止define将catch-all错误定义添加到函数中:

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

successor /@ {1, "hi"}

{2, successor["hi"]}
Run Code Online (Sandbox Code Playgroud)

可以为函数定义多个属性:

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

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

Hold[1 + 1, 2 + 3, 4 + 5]
Run Code Online (Sandbox Code Playgroud)

不用多说,这里有以下定义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: ``";
Run Code Online (Sandbox Code Playgroud)

展示的实现既不支持up-value也不支持currying,也不支持比简单函数定义更通用的模式.然而,它仍然有用.

  • +1 - 这是非常有用的东西.我一直在使用类似的工具.宏(以及内省和其他元编程技术)可能非常强大,但似乎在Mathematica社区中一般不被重视,或者至少这是我迄今为止的印象. (2认同)

Mr.*_*ard 16

开始时没有打开空白笔记本

让Mathematica开始打开空白笔记本让我感到困扰.我可以用脚本关闭这个笔记本,但它仍然会短暂地打开.我的黑客是创建一个Invisible.nb包含以下内容的文件:

Notebook[{},Visible->False]
Run Code Online (Sandbox Code Playgroud)

并将此添加到我的Kernel\init.m:

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

SetOptions[$FrontEnd,
  Options[$FrontEnd, NotebooksMenu] /. 
    HoldPattern["Invisible.nb" -> {__}] :> Sequence[]
]
Run Code Online (Sandbox Code Playgroud)

我现在开始打开Mathematica Invisible.nb

可能有更好的方法,但这对我很有帮助.


定制FoldFoldList

Fold[f, x] 相当于 Fold[f, First@x, Rest@x]

顺便说一句,我相信这可能会进入Mathematica的未来版本.

惊喜!这已经实施,但目前没有记录. 我被告知它是由Oliver Ruebenkoenig在2011年实施的,显然不久我发布了这个.谢谢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]
Run Code Online (Sandbox Code Playgroud)

更新以允许此操作:

SetAttributes[f, HoldAll]
Fold[f, Hold[1 + 1, 2/2, 3^3]]
Run Code Online (Sandbox Code Playgroud)
f[f[1 + 1, 2/2], 3^3]
Run Code Online (Sandbox Code Playgroud)

"动态分区"

有关此函数的新版本,请参阅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]
Run Code Online (Sandbox Code Playgroud)

然后我用这个完成了,包括参数测试:

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
Run Code Online (Sandbox Code Playgroud)

第三个参数控制除了拆分规范之外的元素会发生什么.


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"]]]]]}
Run Code Online (Sandbox Code Playgroud)

从内部修改外部数据 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.}  *)
Run Code Online (Sandbox Code Playgroud)

  • +1好收藏!关于"编译"内部的外部修改 - 我的全部帖子在这里:http://stackoverflow.com/questions/5246330/delete-repeating-list-elements-preserving-order-of-appearance/5251034#5251034,是为了展示这种可能性在一个非平凡的环境中(已经有一个更短更快的解决问题的问题).IMO,这里最大的胜利是能够模拟传递引用并将大型编译函数分解为更多可管理和可重用的块. (3认同)

Ale*_*kov 14

一般PDF/EMF出口问题和解决方案

1)它完全出乎意料且没有文档记录,但Mathematica使用一组样式定义导出并保存PDF和EPS格式的图形,这些样式定义与用于在屏幕上显示笔记本的样式定义不同.默认情况下,笔记本在"工作"样式环境中显示在屏幕上(这是ScreenStyleEvironment全局$FrontEnd选项的默认值),但是在"Printout"样式环境中打印(这是PrintingStyleEnvironment全局$FrontEnd选项的默认值).当以光栅格式(如GIF和PNG)或EMF格式导出图形时,Mathematica会生成与Notebook内部完全相同的图形."Working"在这种情况下,似乎样式环境用于渲染.但是,当您导出/保存PDF或EPS格式的任何内容时,情况并非如此!在这种情况下"Printout",默认使用样式环境,它与"工作"样式环境有很大不同.首先,"Printout"风格的环境设置Magnification到80% .其次,它使用自己的值来表示不同样式的字体大小,这导致与原始屏幕表示相比,生成的PDF文件中的字体大小更改不一致.后者可以称为FontSize波动,非常烦人.但幸运的是,通过将PrintingStyleEnvironment全局$FrontEnd选项设置为"Working"可以避免这种情况:

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"]
Run Code Online (Sandbox Code Playgroud)

2)导出到EMF格式的常见问题是大多数程序(不仅仅是Mathematica)生成的文件在默认大小时看起来很漂亮,但在放大时变得很丑.这是因为元文件以屏幕分辨率保真度进行采样.可以通过Magnify原始图形对象来增强生成的EMF文件的质量,使得原始图形的采样精确度变得更加精确.比较两个文件:

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

如果您将这些文件插入Microsoft Word并放大它们,您将看到第一个"a"在其上有锯齿而第二个没有(用Mathematica 6 测试).

另一种方法ImageResolutionChris Degnen建议的(这个选项至少从Mathematica 8 开始有效):

Export["C:\\test1.emf", graphics1]
Export["C:\\test2.emf", graphics1, ImageResolution -> 300]
Run Code Online (Sandbox Code Playgroud)

3)在Mathematica中,我们有三种方法将图形转换为元文件:via Export"EMF"(强烈推荐的方式:生成质量最高的元文件),通过Save selection As...菜单项(产生更精确的图形,不推荐)和Edit ? Copy As ? Metafile菜单项(我强烈推荐)反对这条路线).


Sjo*_*ies 13

根据大众需求,使用SO API生成前10个SO answerers图(除了注释)的代码.

在此输入图像描述

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", ""})]
Run Code Online (Sandbox Code Playgroud)


小智 13

缓存表达式

我发现这些函数对缓存任何表达式非常有帮助.这两个函数的有趣之处在于,保持表达式本身用作哈希表/符号Cache或CacheIndex的键,与mathematica中众所周知的memoization相比,如果函数定义为f,则只能缓存结果[x_]:= f [x] = ...所以你可以缓存代码的任何部分,如果要多次调用一个函数但是不能重新计算代码的某些部分,这很有用.

独立于其参数缓存表达式.

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

Ex: Cache[Pause[5]; 6]
Cache[Pause[5]; 6]
Run Code Online (Sandbox Code Playgroud)

表达式第二次返回6而不等待.

使用别名表达式缓存表达式,该表达式可以依赖于缓存表达式的参数.

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

Ex: CacheIndex[{"f",2},x=2;y=4;x+y]
Run Code Online (Sandbox Code Playgroud)

如果expr需要一些时间来计算,那么评估{"f",2}例如检索缓存结果要快得多.

对于这些函数的变体,以便具有本地化缓存(即,缓存存储器在Block构造之外自动释放),请参阅此帖子避免重复调用插值

删除缓存的值

在不知道函数定义数时删除缓存值.我认为定义在他们的论点中有一个空白.

DeleteCachedValues[f_] := 
       DownValues[f] = Select[DownValues[f], !FreeQ[Hold@#,Pattern]&];
Run Code Online (Sandbox Code Playgroud)

在知道函数定义的数量时(稍快一些)删除缓存的值.

DeleteCachedValues[f_,nrules_] := 
       DownValues[f] = Extract[DownValues[f], List /@ Range[-nrules, -1]];
Run Code Online (Sandbox Code Playgroud)

这使用了这样一个事实,即函数的定义位于其DownValues列表的末尾,缓存值在之前.

使用符号存储数据和类似对象的函数

这里还有一些有趣的函数来使用像对象这样的符号

众所周知,您可以将数据存储在符号中,并使用DownValues快速访问它们

mysymbol["property"]=2;
Run Code Online (Sandbox Code Playgroud)

您可以根据本网站帖子中提交的漏洞使用这些函数访问符号的键(或属性)列表:

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

我使用这个函数来显示符号DownValues中包含的所有信息:

PrintSymbol[symbol_] :=
  Module[{symbolKeys},
    symbolKeys = Keys[symbol];
    TableForm@Transpose[{symbolKeys, symbol /@ symbolKeys}]
  ];
Run Code Online (Sandbox Code Playgroud)

最后,这是一种创建符号的简单方法,该符号在面向对象编程中表现得像一个对象(它只是重现了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
  ];
Run Code Online (Sandbox Code Playgroud)

属性作为DownValues和方法存储为由返回的Module创建的符号中的延迟Upvalues.我找到了function2的语法,它是MathematicaTree数据结构中函数的常用OO语法.

有关每个符号所包含的现有值类型的列表,请参阅http://reference.wolfram.com/mathematica/tutorial/PatternsAndTransformationRules.htmlhttp://www.verbeia.com/mathematica/tips/HTMLLinks/Tricks_Misc_4.html.

例如试试这个

x = NewObject[y -> 3];
function[x, 4]
x.function2[5]
Run Code Online (Sandbox Code Playgroud)

如果你想使用一个名为InheritRules的包模拟对象继承,你可以更进一步 http://library.wolfram.com/infocenter/MathSource/671/

您也可以将函数定义存储在newObject中但不存储在类型符号中,因此如果NewObject返回类型[newObject]而不是newObject,您可以在NewObject之外定义函数和函数2(而不是在内部),并且具有与之前相同的用法.

function[type[object_], x_] ^:= object["y"] + x;
type /: type[object_].function2[x_] := 2 object["y"]+x;
Run Code Online (Sandbox Code Playgroud)

使用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]]
      ]
   ];
Run Code Online (Sandbox Code Playgroud)

以下是如何使用此版本的示例:

使用Mathematica正确收集/收集

您将如何在Mathematica中执行数据透视表功能?

Mathematica快速2D分级算法

Internal`Bag

Daniel Lichtblau在这里描述了一个有趣的内部数据结构,用于增长列表.

在Mathematica中实现四叉树

调试功能

这两个帖子指向用于调试的有用函数:

使用Mathematica编写小代码或大代码时如何调试?工作台?mma调试器?或者是其他东西?(展示下)

/sf/ask/382181481/#5527117(TraceView)

这是另一个基于Reap和Sow的函数,用于从程序的不同部分提取表达式并将它们存储在符号中.

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

这是一个例子

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*)
Run Code Online (Sandbox Code Playgroud)

其他资源

以下是学习目的的有趣链接列表:

Mathematica学习资源的集合

在此处更新:https://mathematica.stackexchange.com/a/259/66

  • +1有一个很好的符号方便,无需在缓存函数中重复定义的左侧,例如:`c:Cache [expr_]:= c = expr`. (7认同)

dre*_*ves 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).   *)
Run Code Online (Sandbox Code Playgroud)


Pil*_*lsy 11

我使用过的一个技巧,它允许你模拟大多数内置函数使用错误参数(通过发送消息然后返回整个表单未评估的方式)的方式Condition,利用在定义中使用的方式的怪癖.如果foo只应该使用一个参数:

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

如果您有更复杂的需求,很容易将参数验证和消息生成分解为一个独立的函数.Condition除了生成消息之外,您可以通过使用副作用来做更精细的事情,但在我看来,大多数都属于"低级黑客"类别,如果可能应该避免.

此外,在"元编程"类别中,如果您有一个Mathematica package(.m)文件,则可以使用该"HeldExpressions"元素来获取包含在文件中的所有表达式HoldComplete.这使得跟踪事物比使用基于文本的搜索更容易.不幸的是,没有简单的方法可以用笔记本做同样的事情,但你可以使用如下内容获得所有输入表达式:

inputExpressionsFromNotebookFile[nb_String] :=
 Cases[Get[nb],
  Cell[BoxData[boxes_], "Input", ___] :>
   MakeExpression[StripBoxes[boxes], StandardForm],
  Infinity]
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用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]
Run Code Online (Sandbox Code Playgroud)

现在,您可以以不必要的复杂方式以相反的顺序打印列表的元素!

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

 While[!EmptyQ[stack],
  Print[Peek@stack];
  Pop@stack]]
Run Code Online (Sandbox Code Playgroud)


Sza*_*lcs 11

打印没有上下文的系统符号定义

contextFreeDefinition[]下面的函数将尝试打印符号的定义,而不会添加最常见的上下文.然后可以将该定义复制到Workbench并进行格式化以便于阅读(选择它,右键单击,源 - >格式)

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]]
Run Code Online (Sandbox Code Playgroud)

withRules []

警告: 此功能不本地化变量以同样的方式WithModule做的,这意味着,随着预期的嵌套本地化结构将无法正常工作. withRules[{a -> 1, b -> 2}, With[{a=3}, b_ :> b]] 取代ab嵌套WithRule,而With并没有这样做.

这是With使用规则而不是=和的变体:=:

ClearAll[withRules]
SetAttributes[withRules, HoldAll]
withRules[rules_, expr_] :=
  Internal`InheritedBlock[
    {Rule, RuleDelayed},
    SetAttributes[{Rule, RuleDelayed}, HoldFirst];
    Unevaluated[expr] /. rules
  ]
Run Code Online (Sandbox Code Playgroud)

我发现这在清理实验期间编写的代码和本地化变量时非常有用.偶尔我会以参数列表的形式结束{par1 -> 1.1, par2 -> 2.2}.使用withRules参数值很容易注入先前使用全局变量编写的代码中.

用法就像With:

withRules[
  {a -> 1, b -> 2},
  a+b
]
Run Code Online (Sandbox Code Playgroud)

抗锯齿3D图形

即使您的图形硬件本身不支持3D图形,这也是一种非常简单的抗锯齿技术.

antialias[g_, n_: 3] := 
  ImageResize[Rasterize[g, "Image", ImageResolution -> n 72], Scaled[1/n]]
Run Code Online (Sandbox Code Playgroud)

这是一个例子:

Mathematica图形 Mathematica图形

请注意,较大的值n或较大的图像大小往往会暴露图形驱动程序错误或引入伪像.


Notebook diff功能

<<AuthorTools`软件包差异功能在软件包中可用,并且(在至少版本8中)在未记录的NotebookTools`上下文中可用.这是一个用于区分当前打开的两个笔记本的小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]]}]
  ]
Run Code Online (Sandbox Code Playgroud)

Mathematica图形


Leo*_*rin 9

递归纯函数(#0)似乎是该语言的黑暗角落之一.以下是一些使用它们的非平凡的例子,其中这非常有用(并非如果没有它就无法完成).以下是一个非常简洁且相当快速的函数,可以在图中找到连接的组件,给定一个指定为顶点对的边列表:

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]];
Run Code Online (Sandbox Code Playgroud)

这里发生的是我们首先在每个顶点数上映射一个虚拟符号,然后设置一种方式,给定一对顶点{f[5],f[10]},然后f[5]评估为f[10].递归纯函数用作路径压缩器(以这样的方式设置f[1]=f[3],f[3]=f[4],f[4]=f[2], ...memoization ,而不是像长链一样,每当发现组件的新"根"时,记忆值就会得到纠正.这样可以显着提高速度.因为我们使用赋值,我们需要它是HoldAll,这使得这个构造更加模糊和更有吸引力).这个函数是由线上和离线Mathgroup讨论的结果,涉及Fred Simons,Szabolcs Horvat,DrMajorBob和你的真实.例:

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>>}}
Run Code Online (Sandbox Code Playgroud)

它肯定比内置慢得多,但对于代码的大小,仍然很快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]]];
Run Code Online (Sandbox Code Playgroud)

例如,

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}}
Run Code Online (Sandbox Code Playgroud)

然而,它不是正确的尾递归,并且会使堆栈(崩溃内核)更大的列表.这是尾递归版本:

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]], {}]];
Run Code Online (Sandbox Code Playgroud)

例如,

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}} 
Run Code Online (Sandbox Code Playgroud)


Yar*_*tov 8

这是Stan Wagon的书的配方......当内置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]]]]];
Run Code Online (Sandbox Code Playgroud)

当我需要来自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]
Run Code Online (Sandbox Code Playgroud)

当评估结果令人困惑时,有时将评估步骤转储到文本文件中会有所帮助

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]]
Run Code Online (Sandbox Code Playgroud)


Ale*_*kov 8

可以使用未记录的命令行选项-batchinput-batchoutput以批处理方式运行MathKernel,并且:

math -batchinput -batchoutput < input.m > outputfile.txt
Run Code Online (Sandbox Code Playgroud)

(input.m以换行符结尾的批输入文件在哪里,outputfile.txt是输出将被重定向到的文件).

Mathematica v.> = 6中,MathKernel具有未记录的命令行选项:

-noicon
Run Code Online (Sandbox Code Playgroud)

它控制MathKernel是否在任务栏上有可见图标(至少在Windows下).

FrontEnd(至少从第5版开始)具有未记录的命令行选项

-b
Run Code Online (Sandbox Code Playgroud)

这会禁用启动画面,并允许更快地运行Mathematica FrontEnd

和选项

-directlaunch
Run Code Online (Sandbox Code Playgroud)

会禁用启动最新安装的Mathematica版本的机制,而不是启动与系统注册表中的.nb文件关联的版本.

另一种方法可能:

不要在安装目录中启动Mathematica.exe二进制文件,而是在SystemFiles\FrontEnd\Binaries\Windows中启动Mathematica.exe二进制文件.前者是一个简单的启动程序,它最努力地将打开笔记本的请求重定向到运行用户界面的副本.后者是用户界面二进制本身.

将最后一个命令行选项与设置全局FrontEnd选项结合使用非常方便,该选项VersionedPreferences->True 禁用了所安装的不同Mathematica版本之间的首选项共享:

SetOptions[$FrontEnd, VersionedPreferences -> True]
Run Code Online (Sandbox Code Playgroud)

(以上内容应在安装的最新Mathematica版本中进行评估.)

Mathematica 8中,这在"首选项"对话框的"系统"窗格中的"创建和维护特定于版本的前端首选项"设置下进行控制.

通过使用未记录的密钥-h(Windows代码),可以获得FrontEnd的命令行选项的不完整列表:

SetDirectory[$InstallationDirectory <> 
   "\\SystemFiles\\FrontEnd\\Binaries\\Windows\\"];
Import["!Mathematica -h", "Text"]
Run Code Online (Sandbox Code Playgroud)

得到:

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
Run Code Online (Sandbox Code Playgroud)

其他选择包括:

-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
Run Code Online (Sandbox Code Playgroud)

MathKernel和FrontEnd还有其他可能有用的命令行选项吗?如果你知道,请分享.

相关问题.


Leo*_*yev 7

我最喜欢的hacks是小代码生成宏,允许您用一个短的替换一堆标准样板命令.或者,您可以创建用于打开/创建笔记本的命令.

以下是我在日常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];
Run Code Online (Sandbox Code Playgroud)

现在,让我们创建一个宏,它将把以下单元格放在笔记本中:

SetOptions[EvaluationNotebook[], CellContext -> Notebook]
Needs["LVAutils`"]
Autosave[True]
Run Code Online (Sandbox Code Playgroud)

这是宏:

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];
      ]
 ]
Run Code Online (Sandbox Code Playgroud)

现在当我输入时MyPrivatize[]创建私有上下文并加载我的标准包.现在让我们创建一个命令,它将打开一个具有自己的私有上下文的新的临时笔记本(这样你就可以放弃那里而不用冒犯定义的风险),但可以访问你当前的上下文.

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

关于这个很酷的事情是,由于SelfDestruct,当命令运行时,它在当前笔记本中没有留下任何痕迹 - 这很好,因为否则它只会造成混乱.

对于额外的样式点,您可以使用这些宏创建关键字触发器InputAutoReplacements,但我会将其作为练习器留给读者.


Ale*_*kov 7

PutAppend的PageWidth - > Infinity

Mathematica中,使用该PutAppend命令是使用中间计算结果维护正在运行的日志文件的最直接方法.但是PageWith->78在将表达式导出到文件时默认使用它,因此无法保证每个中间输出在日志中只占用一行.

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}
Run Code Online (Sandbox Code Playgroud)

因此,我们可以PutAppend通过设置一次只添加一行:

SetOptions[OpenAppend, PageWidth -> Infinity]
Run Code Online (Sandbox Code Playgroud)

UPDATE

有一个错误在版本10(固定在11.3版本)介绍:SetOptions不再影响的行为OpenWriteOpenAppend.

解决方法是PutAppend使用显式PageWidth -> Infinity选项实现您自己的版本:

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

请注意,我们也可以通过答案中WriteString所示实现它,但在这种情况下,有必要将表达式初步转换为相应的via .InputFormToString[expr, InputForm]


rco*_*yer 6

我只是通过我的一个软件包来查看它,并找到了一些我定义的消息: Debug::<some name>.默认情况下,它们会被关闭,因此不会产生太多开销.但是,我可以用它们丢弃我的代码,如果我需要弄清楚一些代码的行为,我可以打开它们.


DGr*_*ady 6

困扰我的内置作用域构造的一个原因是它们一次评估所有局部变量定义,所以你不能写例如

With[{a = 5, b = 2 * a},
    ...
]
Run Code Online (Sandbox Code Playgroud)

不久之前,我想出了一个名为WithNest的宏,它允许你这样做.我发现它很方便,因为它可以让你保持变量绑定本地而不必做类似的事情

Module[{a = 5,b},
    b = 2 * a;
    ...
]
Run Code Online (Sandbox Code Playgroud)

最后,我能找到的最好方法是使用一个特殊的符号来简化递归绑定列表,并将定义放入自己的包中以隐藏此符号.也许有人对这个问题有一个更简单的解决方案?

如果您想尝试一下,请将以下内容放入名为的文件中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[];
Run Code Online (Sandbox Code Playgroud)


Chr*_*nen 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];
Run Code Online (Sandbox Code Playgroud)

原帖:http : //forums.wolfram.com/mathgroup/archive/2010/Jun/msg00148.html

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

Cell[OutputFormData@expr] 整齐地删除引号。


Sza*_*lcs 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[];
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

28234 次

最近记录:

7 年,3 月 前