447
$\begingroup$

As you may already know, Mathematica is a wonderful piece of software.
However, it has a few characteristics that tend to confuse new (and sometimes not-so-new) users. That can be clearly seen from the the fact that the same questions keep being posted at this site over and over again.

Please help me to identify and explain those pitfalls, so that fewer new users make the mistake of walking into these unexpected traps.

Suggestions for posting answers:

  • One topic per answer
  • Focus on non-advanced uses (it's intended to be useful for beginners/newbies/novices and as a question closing reference)
  • Include a self explanatory title in h2 style
  • Explain the symptoms of problems, the mechanism behind the scenes and all possible causes and solutions you can think of. Be sure to include a beginner's level explanation (and a more advanced one too, if you're in the mood)
  • Include a link to your answer by editing the Index below (for quick reference)

Stability and usability

Syntax and semantics

Assignment and definition

General guidelines

Graphics and images

Tricky functions

$\endgroup$

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

  • 6
    $\begingroup$ Few suggestions: 1. old definitions in memory and "overloaded" functions like f[x_]:=a; f[x_Integer]=b; 2. Forgotten underscore in patterns f[x]=a 3. Set vs SetDelayed; 4. m = {{1, 2}, {3, 4}} // MatrixForm and then Eigenvalues[q]; 5. Plotting complex function produces empty plot without any warnings. $\endgroup$ – Nick Stranniy Jan 24 '13 at 22:23
  • 2
    $\begingroup$ I want to throw $HistoryLength in there, a memory management in general category including MaxMemoryUsed and MemoryConstrained etc $\endgroup$ – ssch Jan 25 '13 at 0:03
  • 5
    $\begingroup$ Suggestion: If appropriate to the problem, force Mathematica to use approximate numerical algorithms to avoid the computational overhead of their symbolic counterparts. There are several ways to do this (e.g., NIntegrate vs. Integrate, using real approximate numbers instead of integers in equations, etc). $\endgroup$ – Cassini Jan 25 '13 at 3:51
  • 4
    $\begingroup$ Suggestion: mathematica.stackexchange.com/q/18483/193 (Using the result of functions that return replacement rules) $\endgroup$ – Dr. belisarius Jan 26 '13 at 7:46
  • 5
    $\begingroup$ Maybe there should be a (short) answer about security. Most people don't realize mathematica has a large set of functions that are capable of taking over your computer entirely, or as a more specific example, activating your webcam (CurrentImage). $\endgroup$ – Jacob Akkerboom Aug 8 '13 at 11:19

37 Answers 37

6
$\begingroup$

Plot functions do not print output (Where are my plots?)

Quite often new users write something like this and are surprised that no plots are produced:

For[
  n = 1,
  n <= 3,
  n++,
  Plot[Sin[x*n], {x, 0, 2 Pi}]
]

Since version 6 of Mathematica the plot functions (Plot, Plot3D, ListPlot, ContourPlot, ParametricPlot, etc.) do not print their output but instead evaluate to a Graphics or Graphics3D expression, just as 2 + 2 evaluates to 4.

To see the output of Plot in this loop one needs to write it to the Notebook as a side-effect which is exactly what Print does. This can be done explicitly (Print[ Plot[. . .] ]) or by setting $DisplayFunction to something with a side-effect as it was in versions 5.2 and earlier.

A better approach is to collect and display the direct output of Plot as it may be manipulated like any other expression. The most direct substitute for the For loop is Table:

Table[
  Plot[Sin[x*n], {x, 0, 2 Pi}],
  {n, 1, 3}
]

enter image description here

This returns (evaluates to) a List containing three Graphics expressions. These expressions are displayed by the Front End as graphical objects that may be interactively manipulated. This output may be assigned to a Symbol or Indexed Object. It may be displayed in particular arrangements using e.g. Row, Column, Multicolumn, GraphicsRow, etc., or animated with ListAnimate

The Graphics expressions may be modified with the full range of expression manipulation tools, sometimes referred to as post-processing as one starts with the existing plot output.

$\endgroup$
6
$\begingroup$

In symbolic algebra and especially calculus, x[1] is quite different from x1. Easy one-liner avoids problems and gets nice subscript formatting.

x[i_Integer]:=x[i]=With[{u = Unique[x]}, Format[u] = Subscript[x,i]; u]

There are many advantages of using x[1], x[2], ... as symbolic variables, such as creating a list of them with Array[x,5] to pass into Solve[], or creating a list of expressions with Table[x[i]+x[i+1],{i,5}].

There are also some good reasons to avoid this practice. Some operations choke on them. Writing x[1] sometimes declares that x is a function of one variable only and x[1] may be assumed constant.

They also are not formatted as subscripts. Using Subscript[x,1] as a variable also invites trouble. The above one-liner solves both problems.

Array[x,4] prints $\left\{\text{x}_1,\text{x}_2,\text{x}_3,\text{x}_4\right\}$, actually (say) {x$2136, x$2152, x$2163, x$2164}.

Table[x[i]+x[i+1],{i,3}] prints $\{\text{x}_1 + \text{x}_2, \text{x}_2 + \text{x}_3, \text{x}_3 + \text{x}_4\}$.

Further reading:

$\endgroup$
  • $\begingroup$ ??x does not show the internal form. DownValues[x]//InputForm does, but does not list the Format definitions. How can I make Information["x"] print the internal values? How can I discover what Format definitions exist? $\endgroup$ – Edward Huff Feb 7 '17 at 19:36
  • $\begingroup$ I made a new answer because this one is very different from what 3 people downvoted. I hope it will be judged on its merits. $\endgroup$ – Edward Huff Feb 7 '17 at 19:38
  • $\begingroup$ FullDefinition[x] should show what you want. $\endgroup$ – Mr.Wizard Feb 8 '17 at 3:13
  • $\begingroup$ It seems FormatValues[] contains the definitions. It's hard to print it, though, because the Format gets applied even to things inside HoldComplete[]. FormatType inside the MakeBoxes rule triggers an error message. With[{XX=x[100]}, With[{fvxx=FormatValues[XX]}, FormatValues[XX]={}; Print[fvxx/.{Format->"Format",Subscript->"Subscript"}];FormatValues[XX]=fvxx ]]; prints {HoldPattern[Format[x$145]] :> Subscript[x, 100], HoldPattern[MakeBoxes[x$145, FormatType_]] :> Format[Subscript[x, 100], FormatType]} $\endgroup$ – Edward Huff Feb 8 '17 at 6:54
  • $\begingroup$ Oh, sorry, I finally understand what you're talking about. Consider FullDefinition[x] // InputForm $\endgroup$ – Mr.Wizard Feb 8 '17 at 7:45
6
$\begingroup$

How to work always in WYSIWYG mode?

How to get in PDF format exactly what I see in my Notebook?

It is counterintuitive and undocumented, but Mathematica by default prints to PostScript printers and also exports in PDF and EPS formats using a set of style definitions which differs from the one used for displaying Notebooks on screen. Hence you often unexpectedly get your graphics in PDF/EPS damaged: font sizes and magnification of different elements may differ significantly from what you carefully tuned during your interactive work with Notebook. The reason is that FrontEnd uses for on-screen display a set of styles determined by ScreenStyleEvironment option, but for printing (exporting to PostScript) the styles are determined by PrintingStyleEnvironment option:

Options[$DefaultFrontEnd, {ScreenStyleEnvironment, PrintingStyleEnvironment}]
{PrintingStyleEnvironment -> "Printout", ScreenStyleEnvironment -> "Working"}

(Note that for the all other formats Export uses ScreenStyleEnvironment, exporting to PostScript is the only exception.) So for turning on the WYSIWYG mode you should set the value of the global $FrontEnd option PrintingStyleEnvironment identical to the value of the ScreenStyleEnvironment option:

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

Note also that Export ignores the value of this option set on the Notebook[] level and always uses the global ($FrontEnd) setting!


Further details

Apart from ScreenStyleEnvironment the on-screen display is also influenced by such options as StyleDefinitions, Magnification, GraphicsBoxOptions and StyleHints (starting from version 10). From them Magnification and GraphicsBoxOptions affect only on-screen display and do not affect Export, while StyleHints affects both on-screen display and Export.

For vector formats Export ignores StyleDefinitions set on the Notebook level and uses global DefaultStyleDefinitions setting instead. More information can be found in

For raster formats Export uses local StyleDefinitions. Some additional information can be found in


Related (publication quality export, using Mathematica as desktop publishing tool):

$\endgroup$
5
$\begingroup$

PerformanceGoal -> "Speed" can yield irreproducible results.

For example, the procedure doPlot below

  1. computes a SmoothKernelDistribution on a fixed data vector (DATA);
  2. defines a pdf function based on this distribution;
  3. plots the pdf function.
doPlot[] := Module[{
    pdf,
    distribution = SmoothKernelDistribution[DATA,
                                            "StandardGaussian", "Biweight", 
                                            PerformanceGoal -> "Speed"]
   },
   pdf = Function[x, PDF[distribution, x]];
   Plot[pdf[x], {x, 0, 180000}, PlotRange -> {All, {0, 0.00004}},
        Axes -> False, Frame -> True, FrameTicks -> None,
        ImageSize -> 50, AspectRatio -> 1, ImagePadding -> {{0, 1}, {1, 0}}]
]

Since doPlot takes no arguments, one could hope that it would produce the same results every time, but this is not the case. The figure below shows the result of 100 runs of doPlot.

Mathematica graphics

It appears that "reproducibility" is one of the ingredients of "Quality" that one forfeits when one specifies PerformanceGoal -> "Speed". This is not outlandish, of course, but it is not self-evident either.

$\endgroup$
3
$\begingroup$

Understanding $Context, $ContextPath the parsing stage and runtime scoping constructs

A symbol in Mathematica can never be without a context. We can assume that the internal representation of any symbol stores a string of the form "context`symbol".

But for you as a programmer, there are ways to enter a symbol without stating it's full context: x, Sin, `x are all valid inputs.

The values of $Context and $ContextPath at the parsing stage determine which symbol is actually meant by the above inputs.

This settles which symbols are initially used in the expression put together that will be submitted to the evaluator. You can display the actual name of symbols in a snippet of code by printing the "FullForm" of an expression with context as follows:

Hold[

(*your code here*)
x

] /. x_Symbol :> Context@x <> SymbolName@Unevaluated@x
(*=>*)
"System`Hold"["Global`x"]

(see here for more ways of doing this). Note that Mathematica strips the context whenever possible, even in FullForm, to present to you more or less what you (supposedly) entered: Global`y is displayed as just y.

However, at runtime, an x that is parsed as Global`x might well become something else still. Let's try the following:

Hold[

  Module[{x}, x]

  ] /. x_Symbol :> Context@x <> SymbolName@Unevaluated@x

gives

"System`Hold"["System`Module"["System`List"["Global`x"], "Global`x"]]

So the variable is parsed as Global`x. But evaluating Module[{x}, x] we get something like x$11686. Module changed every literal occurrence of Global`x to a variable created probably via Unique@Unevaluated@x before executing the code.

However, this replacement is aware of some scoping constructs of the language which it will not enter. Rule is one of them:

Module[{x}, {x, x_ -> x}]

gives

{x$12264, x_ -> x}

And not say {x$12264, x$12264_ -> x$12264}.

With and Function are also scoping constructs which interact. Here for example, every x is parsed as Global`x:

Hold[

  With[{y = x}, Function[{x}, x + y]]

  ] /. x_Symbol :> Context@x <> SymbolName@Unevaluated@x
(*=>*)
System`Hold[System`With[System`List[System`Set[Global`y,Global`x]],System`Function[System`List[Global`x],System`Plus[Global`x,Global`y]]]]

But in the result of evaluation a new symbol $x will have been created to resolve a (potential) name clash:

Function[{x$}, x$ + x]

BeginPackage, Begin and messages like

*::shdw: Symbol * appears in multiple contexts {*}; definitions in context * may shadow or be shadowed by other definitions. >>

also fall into this complex of considerations.

Related questions and "articles"

Many questions tagged with variable-definitions scoping and contexts deal with this topic. Here's a selection:

Context of localised (dynamic) symbols

DynamicModule Initialization is not executing when expected?

How to scope `Pattern` labels in rules/set?

How to make a function like Set, but with a Block construct for the pattern names

tutorial/VariablesInPureFunctionsAndRules

package import problem in mathematica (Stackoverflow)

$\endgroup$
  • 3
    $\begingroup$ Is this really a "common pitfall awaiting new users?" It's tricky admittedly, but hardly a pitfall until you start writing packages, imo. $\endgroup$ – Michael E2 Jul 3 '16 at 18:37
  • $\begingroup$ Even when you want to use packages (which is basic/should be encouraged) you need to know that you cannot put (Needs["Apackage`"]; PackageFunction[...];) into one expression (or one line in the frontend!): You need to have one roundtrip to the kernel to have Needs update the $ContextPath, c.f. e.g. stackoverflow.com/questions/4664091/… . And I think knowing what exactly an identifier denotes is crucial in any programming language. $\endgroup$ – masterxilo Jul 3 '16 at 23:30
  • 2
    $\begingroup$ @MichaelE2 I think you both are right but due to the lack of a proper place it is good to have it here. Maybe we could think about another guidelike topic: "Fundamentals that are spread too thinly across documentation", it would fit there best, don't you think? $\endgroup$ – Kuba Jul 4 '16 at 5:52
  • 2
    $\begingroup$ I agree with @Michael and @Kuba: currently this post is intended for experienced users who wish to write a package. The (Needs["Apackage`"]; PackageFunction[...];) case should be included as a point into one of the multi-point answers here (I think this answer perfectly fits). Probably we should move this answer to a new thread and include in the OP here a link to that thread with wordings like "This thread is intended primarily to those who learn the basics of the WL. For discussion on subtle/professional topics see that thread". $\endgroup$ – Alexey Popkov Jul 4 '16 at 9:19
  • $\begingroup$ @MichaelE2 and mastexilo, I tied to polish this topic to make it a generic one about parsing, suggestions appreciated. 119187 $\endgroup$ – Kuba Jul 15 '16 at 7:15
2
$\begingroup$

Association has HoldAllComplete attribute

Association is not just another head denoting a special kind of list of rules or a certain kind of object. It has some properties that make querying it more efficient, but also cause it to behave differently from a List. You should be aware of this if you intend to use Associations as a data structure for object oriented programming.

Let me illustrate. Say we want to have a single expression representing a person with the attribute age. We might use a custom head, list or association to store a rule assigning "age" to something. A list and custom head person will support template objects which have some parameters undefined at the time of their definition. But a head with HoldAll such as hperson and Association will not fill in the blanks once you define them.

ClearAll[p1, p2, p3, x, getAgeSquared, hperson];

(*make hperson behave more like Assocation*)
SetAttributes[hperson, HoldAll];

p1 = person["age" -> x]
p2 = List["age" -> x]
p3 = Association["age" -> x]
p4 = hperson["age" -> x]

getAgeSquared@_["age" -> x_Real] := x^2;
(*these stay unevaluated*)
getAgeSquared@p1
getAgeSquared@p2
getAgeSquared@p3
getAgeSquared@p4

x = 3.;

(*note that x is not inserted into structures with HoldAll*)
p1
p2
p3
p4

(*consequently, you cannot do the following successfully with \
Assocation and hperson*)
getAgeSquared@p1
getAgeSquared@p2
getAgeSquared@p3
getAgeSquared@p4

The output is

person[age->x]
{age->x}
<|age->x|>
hperson[age->x]

getAgeSquared[person[age->x]]
getAgeSquared[{age->x}]
getAgeSquared[<|age->x|>]
getAgeSquared[hperson[age->x]]

person[age->3.]
{age->3.}
<|age->x|>
hperson[age->x]

9.
9.
getAgeSquared[<|age->x|>]
getAgeSquared[hperson[age->x]]

Example confusion

Using Associations and Pattern matching in numerical functions possibly broken

$\endgroup$
  • 4
    $\begingroup$ I must note that this answer is written in a clumsy way and even to me it is almost impossible to follow your thought (despite the fact that I know in principle what you want to say). I would recommend to rewrite it from the scratch or delete. $\endgroup$ – Alexey Popkov Jul 4 '16 at 1:47
2
$\begingroup$

Assocation component access [] vs [[]]

With MMA we spend a lot of time manipulating lists where access to components is done by [[index]], this can make us forget that when using Association keys, the syntax is [key].

If keys are integers this can be a source a bug:

a = <|0 -> "A", 1 -> "B", 2 -> "C", 3 -> "D"|>

a[[2]]

Out: = "B"

a[2]

Out: "C"
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.