2011-12-20 -- Visit the newly launched Mathematica.SE!
Updates to this page coming soon! Meanwhile see the old collection of tips below. Please note that some of these were written for Mathematica version 5, and may not be necessary in the latest version, or may require modifications to work.
On this webpage I collected a few simple tricks and usage patterns, which make working with WRI's Mathematica easier and more efficient. These notes are mostly for myself, but I hope that they will be helpful for others too!
This is a little Mathematica package for Windows that redefines $DisplayFunction to show graphics with GSview. I found it useful because vector graphics exported by Mathematica don't always look the same as they were shown in the notebook interface. The package also contains a function to export nice antialiased bitmap graphics, but this requires convert.exe from ImageMagick.
Note that you must set the path to gsview.exe and convert.exe manually. Search for $GSview and $GSconvert in GSGraphics.m and set the correct values before you start using the package. I recommend that you also set Options -> EPS Clip in GSview. The package was tested with Mathematica 5.2 only.
Using [[ and ]] for indexing is not very readable when you have lots of nested expressions and typing ESC [[ ESC is not too convenient (four keystrokes, two of which is pressing ESC in the far left corner of the keyboard). Fortunately, it is possible to assign keyboard shortcuts to symbols, in the following way:
Find the file Mathematica\(version)\SystemFiles\FrontEnd\TextResources\Windows\KeyEventTranslations.tr and back it up before making any modifications. Find the line EventTranslations[{ and add the following two lines right after it:
Item[KeyEvent["[", Modifiers -> {Control}], FrontEndExecute[{FrontEnd`NotebookWrite[FrontEnd`InputNotebook[], "\[LeftDoubleBracket]", After]}]], Item[KeyEvent["]", Modifiers -> {Control}], FrontEndExecute[{FrontEnd`NotebookWrite[FrontEnd`InputNotebook[], "\[RightDoubleBracket]", After]}]],Now restart the front end and you should be able to type these characters using CTRL-[ and CTRL-]! This has been tested with Mathematica 5.2 and 6.0 on Windows.
Note: If you keep the backup of KeyEventTranslations.tr in the same directory, make sure that its extension is NOT .tr, otherwise this trick will not work.
There are a few very useful features of the Front End that might not be immediately apparent for new users (unless they read the docs carefully). I list some of them below. Nothing new here for seasoned Mathematica users.
If $PrePrint is defined, it is applied to every expression before they are printed. When working with large datasets, sometimes one finds that mistyping a function name causes Mathematica to return the function unevaluated, and therefore print the evaluated form of all its arguments. If the input to the function contained a lot of data, the front end may hang for a long time before everything is printed. Avoid this by limiting the output length to e.g. 100 lines with $PrePrint := Short[#, 100] &.
Note: With Mathematica 6, it is no longer necessary to do this as it will automatically truncate long outputs.
When I work with matrices a lot, I prefer to see them formatted as two-dimensional expressions instead of lists-of-lists. This can be achieved by using MatrixForm[], but it is tedious to type this funtcion every time I want to see a pretty result. One way to automate this is to use the $PrePrint function, which is applied to all output before printing, but does not change the return value of expressions:
$PrePrint = Replace[#, mat_?MatrixQ :> MatrixForm[mat]] &
To get back the default behaviour, simply clear the value of $PrePrint:
$PrePrint =.
It's possible to get a somewhat more general replacement, which will work at deeper levels too (for example a list of matrices) by using
$PrePrint = # /. {expr_ /; Head[expr] =!= List :> expr, m_?MatrixQ :> MatrixForm[m]} &
In[1]:= Table[Random[Integer, {-10, 10}], {10}] Out[1]= {-1, -8, 1, 9, -5, -1, -8, -10, -2, 1} In[2]:= % /. _?Negative -> Sequence[] Out[2]= {1, 9, 1}
Now you may wonder: why didn't Sequence[] get spliced into Rule, causing it to collapse into Rule[_?Negative]? This is because Rule has the SequenceHold attribute.
The same technique can be used for inserting elements:
In[3]:= % /. n_Integer -> Sequence[n, n] Out[3]= {1, 1, 9, 9, 1, 1}
This is a very well known programming pattern in Mathematica. Memoization is an optimisation technique: it means making a function "remember" its last return value.
For example, let us look at the recursively defined Fibonacci function:
In[1]:= fibonacci[0] = 0; fibonacci[1] = 1; fibonacci[n_] := fibonacci[n-1] + fibonacci[n-2] In[4]:= fibonacci[30] // Timing Out[4]= {5.391, 832040}It is easy to see that the execution time of this function depends exponentially on the argument, so above a threshold it gets very-very slow. Now let us change the function definition a slightly: in Mathematica a function may redefine itself!
In[5]:= fibonacci[n_] := fibonacci[n] = fibonacci[n-1] + fibonacci[n-2] In[6]:= fibonacci[30] // Timing Out[6]= {2.50234*10^-16, 832040}This new Fibonacci function is a lot faster since it needs to compute its return value only once for each input argument. On the downside, it never "forgets", so this technique is not be very practical with functions that act on real numbers (as the memory may fill up quickly).
The following function is an attempt to remedy this problem. It caches only up to 200 values. It is intended to be used with functions that take a single numerical quantity as their argument.
In[1]:= SetAttributes[memo, HoldAll] SetAttributes[memoStore, HoldFirst] SetAttributes[memoVals, HoldFirst] In[4]:= memoVals[_]={}; In[5]:= memoStore[f_, x_] := With[{vals = memoVals[f]}, If[Length[vals] > 200, f /: memoStore[f, First[vals]] =. ; memoVals[f] ^= Append[Rest[memoVals[f]], x], memoVals[f] ^= Append[memoVals[f], x] ]; f /: memoStore[f, x] = f[x] ] In[6]:= memo[f_Symbol][x_?NumericQ] := memoStore[f, x]Note that memo[] associates the cached results with the function on which it is acting (the argument f). Therefore, when this function is Cleared, the cached results are removed too. If memoization has been used on a function, care must be taken to always Clear[] it before its definition is changed (otherwise the old cached return values will shadow the new ones). Example usage:
In[7]:= Clear[fun] fun[a_?NumericQ] := First@Module[{f, x}, f /. NDSolve[{f''[x] == -a f[x], f[0]==1, f'[0]==0}, f, {x,0,10}]] In[9]:= Plot3D[fun[a][x], {a, 1, 2}, {x, 0, 10}] // Timing Out[9]= {10.015, <removed plot>} In[10]:= Plot3D[memo[fun][a][x], {a, 1, 2}, {x, 0, 10}] // Timing Out[10]= {0.453, <removed plot>}
In Mathematica 6, the following functions accept the Evaluated option:
{ContourPlot, ContourPlot3D, DensityPlot, FindRoot, ParametricPlot, ParametricPlot3D, Plot, Plot3D, RegionPlot, RegionPlot3D}
This option sets whether the first argument of these functions should be evaluated before numeric values are substituted into it:
In[1]:= FindRoot[NIntegrate[Exp[a x], {x, 0, 1}] == 2, {a, 1}] (* The default for FindRoot is Evaluated -> True *) During evaluation of In[1]:= NIntegrate::inumr: The integrand E^(a x) has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}. During evaluation of In[1]:= NIntegrate::inumr: The integrand E^(a x) x has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}. During evaluation of In[1]:= NIntegrate::inumr: The integrand E^(a x) x has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}. During evaluation of In[1]:= General::stop: Further output of NIntegrate::inumr will be suppressed during this calculation. Out[1]= {a -> 1.25643} In[2]:= FindRoot[NIntegrate[Exp[a x], {x, 0, 1}] == 2, {a, 1}, Evaluated -> False] Out[2]= {a -> 1.25643}Possible values are True, False, and Automatic.
In Mathematica it is possible to declare certain properties for symbols by making direct assignments to otherwise protected functions. For example, the following works, in spite of NumericQ being protected (see this message on MathGroup.):
In[1]:= Attributes[NumericQ] Out[1]= {Protected} In[2]:= NumericQ[var] = True In[3]:= NumericQ[var] Out[3]= True
But the Protected attribute of NumericQ is not in vain:
In[4]:= NumericQ[x_] := x^2 During evaluation of In[4]:= NumericQ::set: Cannot set NumericQ[x_] to x^2; the lhs argument must be a symbol and the rhs must be True or False. In[5]:= NumericQ=4 During evaluation of In[5]:= Set::wrsym: Symbol NumericQ is Protected. Out[5]= 4
While the behaviour of the built-in NumericQ may seem "magical" at first, it is possible to implement similar functions directly in the Mathematica language, using up-values. Here is an example:
In[1]:= HoldPattern[somePropertyQ[x_Symbol] = y: (True|False)] ^:= somePropertyQ[x] ^= y Protect[somePropertyQ]; In[3]:= somePropertyQ[var] = True Out[3]= True In[4]:= somePropertyQ[var] = 123 During evaluation of In[4]:= Set::write: Tag somePropertyQ in somePropertyQ[var] is Protected. Out[4]= 123
Notice that the definitions are associated with var itself, and not somePropertyQ. When var is Cleared, the information associated with it is lost. Alternatively, the property values could be associated with a third symbol. This would result in a behaviour more similar to that of NumericQ: the information would persist until var is Removed. Here is a more detailed example (complete with error checking) that implements this:
(* This property is False by default *) somePropertyQ[x_] := TrueQ[helper[x]] (* If the arguments are of the correct type, associate the value with the helper symbol, *) HoldPattern[(Set|SetDelayed)[somePropertyQ[x_Symbol], y: (True | False)]] ^:= helper[x] = y (* otherwise issue an error and return Null *) HoldPattern[(Set|SetDelayed)[somePropertyQ[_], _]] ^:= Message[somePropertyQ::set] somePropertyQ::set = "lhs argument must be a Symbol and the rhs must be True or False"; Protect[somePropertyQ];
While ReleaseHold[] works for removing the outermost Hold[] from an expression, sometimes one would wish to remove all occurrences of Hold[] at the same time. The following function will do this:
releaseAllHold[expr_] := Replace[expr, (Hold|HoldForm|HoldPattern|HoldComplete)[e___] :> e, {0, Infinity}, Heads -> True]Note that in certain situations this function may behave differently than ReleaseHold[], even if it is acting on an expression that does not contain nested Holds:
In[2]:= releaseAllHold[Hold[][a]] Out[2]= Sequence[][a] In[3]:= ReleaseHold[Hold[][a]] Out[3]= Sequence[a]
zoom[graph_Graphics] := With[ {gr = First[graph], opt = DeleteCases[Options[graph], PlotRange -> _], plr = PlotRange /. Options[graph, PlotRange], rectangle = {Dashing[Small], Line[{#1, {First[#2], Last[#1]}, #2, {First[#1], Last[#2]}, #1}]} & }, DynamicModule[{dragging = False, first, second, range = plr}, Panel@EventHandler[ Dynamic@Graphics[ If[dragging, {gr, rectangle[first, second]}, gr], PlotRange -> range, Sequence @@ opt ], {{"MouseDown", 1} :> (first = MousePosition["Graphics"]), {"MouseDragged", 1} :> (dragging = True; second = MousePosition["Graphics"]), {"MouseUp", 1} :> If[dragging, dragging = False; range = Transpose@{first, second}, range = plr] } ] ]]
Example usage:
Plot[Sin[1/x], {x, 0, 1}] // zoomDrag the mouse around an area to zoom, click once to reset the zoom level. A disadvantage of this approach is that it prevents resizing and Locators from working. (Please let me know about any other problems you experience while using it.)
An alternative (and more precise) zooming function can be found here.
Create a palette with a progress bar,
CreatePalette[Dynamic@ProgressIndicator[progress]] progress = 0;And periodically set the progress indicator variable in the computation:
imax = 10; Table[progress = i/imax; Pause[1]; i^2, {i, 1, imax}]
The Union[] function is for computing the (mathematical) union of two sets represented by lists, but it is often used on a single list also to remove duplicate elements. Union[] sorts the elements of the lists, but sometimes it is necessary to remove duplicates while keeping the remaining elements in order. This is the "unsorted union" problem.
The solutions presented here are found in different versions of the documentation, but I thought that it would be nice to have them at the same place because they demonstrate interesting techniques.
Using Tally[] is the fastest solution in Mathematica 6:
unsortedUnion = Tally[#][[All, 1]] &
Another possibility is to exploit that Mathematica functions can behave as associative arrays:
unsortedUnion[x_] := Module[{f}, f[y_] := (f[y] = Sequence[]; y); f /@ x]
Finally, it is possible to use "tags" with Sow[] and Reap[]:
unsortedUnion = Reap[Sow[1, #], _, #1 &][[2]] &
Compiling expressions using Compile[] can greatly speed up Mathematica programs. However, not all functions can be complied. If an uncompilable function slips into a compiled expression, all the performance gain may be lost. Unfortunately the documentation does not mention which functions can be compiled and which cannot, and finding it out by trial and error can be cumbersome ...
Luckily there is a page in the Wolfram tech support FAQs that lists all compilable functions. This list is quite outdated (for Mathematica 3.0), but it is still a useful guideline when working with current versions.
I use the following palette to paste tabular data from various sources (mostly websites) directly as lists. It is not always reliable, but it works pretty well most of the time. It understands three formats: simple, whitespace separated tables (Table), tab separated values (TSV), and comma separated values (CSV). Use the TSV format when pasting data copied from HTML tables.
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"]] ] ] ]}
Here is one way to lock together the rotation of two 3D graphics in Mathematica 6:
gr = Graphics3D[Cuboid[], SphericalRegion -> True, Boxed -> False] (* Initialize vp and vv with the default values: *) vp = ViewPoint /. Options[Graphics3D] vv = ViewVertical /. Options[Graphics3D] Row[ {Show[gr, ViewPoint -> Dynamic[vp], ViewVertical -> Dynamic[vv]], Show[gr, ViewPoint -> Dynamic[vp], ViewVertical -> Dynamic[vv]]} ]
The global variables vp and vv are used to store (and dynamically set) the ViewPoint and ViewVertical options for the two graphics.
Perhaps the title of this section seems a bit paradoxal, because, by definition, a recursive function is a function that calls itself, but anonymous functions have no name to be called with. In fact, anonymous functions are most useful when they only need to be referred to a single time.
Mathematica has a perhaps not very widely known feature that allows anonymous functions to refer to themselves as their "zeroth argument". This is in agreement with the fact that the head of any expression is treated as the zeroth argument by Mathematica:
In[1]:= fun[a, b, c][[0]] Out[1]= fun In[2]:= fun[a, b, c][[1]] Out[2]= a
So, for example, a recursive anonymous factorial function can be defined like this:
In[3]:= fact = If[# > 0, #0[# - 1] #, 1] &; In[4]:= fact[9] Out[4]= 362880
I'm collecting some undocumented (or not very well documented) functions/symbols here which may turn out to be useful. Note: Under construction
TensorQ, ListQ, OptionQ, OwnValues, SubValues, NValues, DefaultValues, PolynomialForm, SpaceForm, GroebnerBasis`*, LinearAlgebra`*, ToColor, ArgumentCountQ, CheckAll, EllipticReducedHalfPeriods, EndAdd, FileInformation, FullAxes, HeadCompose, SequenceLimit, StringByteCount, StripBoxes, TraceLevel, Integrate with multi-element iterator, Evaluated option.
The Developer` and Experimental` contexts also contain some useful functions with no usage messages. A notable example are Experimental`Infimum and Experimental`Supremum (they have no usage message, but are mentioned in the docs: search for them).