Getting Started with Mathematica

©1998-2018 by Gerald Teschl  <Gerald.Teschl@univie.ac.at>, <https://www.mat.univie.ac.at/~gerald/>

Basic calculations and variables

Mathematica is a powerful tool for doing mathematics. It can handle both symbolic and numeric expressions. In the simplest case you can use it just like a calculator: you type in questions, and Mathematica prints back answers.

27+5^3

You can also use variables or put several commands, separated by semicolons, on one line:

x=5;27 +(x^3)

A semicolon also has the effect of suppressing the corresponding output.

If you wonder how I could input the power as a superscript, go to the File menu and select Palettes->Basic Math Assistant.

You might have noticed that Mathematica assigns numbers to every command you input and to the corresponding  output. In particular, all results are stored and you can use them in any following calculations as long as you do not quit Mathematica (more precisely the kernel).

Out[2]3

In addition, the shortcut % can be used to refer to the previous result

%/3

Note that a space between two expressions is interpreted as multiplication. Be warned that if you omit this space, you will get unexpected results!

xy + x y

Moreover, Mathematica is case sensitive.

X+x

Mathematica also knows a vast number of mathematical constants, in particular Pi and E, which can also be entered as π and e using the Basic Math Assistant.

Functions

Mathematica has a large amount of functions already built in. The arguments of a function are put in between square brackets and separated by commas. Some basic functions are given in the table below:

({{Sqrt[x], square root (Sqrt[x])}, {Exp[x], exponential function (e^x)}, {Log[x], natural logarithm ln(x)}, {Log[a,x], logaritmus (Subscript[log, a])(x)}, {Sin[x],Cos[x],Tan[x], trigonometric functions (with argument in radians)}, {ArcSin[x],ArcCos[x],ArcTan[x], inverse trigonometric functions}, {n!, factorial }, {Abs[x], absolue value|x|}, {Round[x], closest integer}, {Random[], pseudorandom number between 0 and 1}})

Note that all built in functions and variables start with capital letters. To avoid potential conflicts it is a good idea to start your own functions and variables with lower case letters.

For example, we can compute

Sin[1]

Well, this might not be the answer you have expected! Mathematica just returns your input unevaluated. The reason is that we have specified an exact argument (one), and Mathematica tries to find an exact solution in this case. Since there is no simpler exact expression for our input, Mathematica leaves it as it is. You can tell Mathematica that the input is not an exact number by adding a decimal point:

Sin[1.]

In this case Mathematica will try to find an approximative value and give back the result you probably wanted in the first place. Alternatively you can also use the N command to get a numeric answer. In addition, this allows to give the number of digits you want as an optional argument:

N[Sin[1],32]

You can even define your own functions as follows:

f[x_]:=(x^2)+Sin[x]

In this expression the underscore represents a pattern. A single underscore will match a single expression (argument) and x is the name of the pattern (it can be used to refer to the matched expression on the right hand side). The colon tells Mathematica not to evaluate the right hand side. It will only be evaluated when you invoke the function. This is why you get no output. Now you can use your function:

f[a]+3

The underscore is essential! If you omit it, the definition will only be used if the argument exactly matches the one in the definition. It can be used to override the general definition for specific values.

Warning: You can also omit the colon when defining functions

g[x_]=(x^2)+Sin[x]

The output shows that Mathematica has evaluated the expression before making the assignment. In particular, we get

g[a]+3

Can you explain this result? You can look at the definition of a function by using a question mark:

?f

?g

Do you know now what is going on? To avoid such problems you should usually stick to the colon version and undo assignments which are no longer needed:

Clear[x,f,g]

Finally, you can also define functions of more than one argument in a similar fashion.

f[x_,y_]:= ((Sin[ x y])/((x^2)+(y^2)))

Plotting Functions

One of the most important features of Mathematica is its capability of visualizing different types of data. The basic commands for plotting functions of one argument are

({{Plot[f,{x,xmin,xmax}], plot f as a function of x from xmin to xmax}, {Plot[{(Subscript[f, 1]),(Subscript[f, 2]),...},{x,xmin,xmax}], plot several functions together}})

For example let us plot the sine function.

Plot[Sin[x],{x,0,2π}]

Mathematica will automatically try to find appropriate scales. However, if the function has singularities it is often better to specify the plot range as an option.

Plot[Log[x],{x,0,10},PlotRange->{-4,4}]

All options are implemented as rules and are hence of the form OptionName -> OptionValue. There are numerous other options available to control the appearance of a plot. See the online documentation for more information.

The command

Export["Log.eps",%,"EPS"]

will save the previous graphics as an eps file which can then be included in other applications. Other formats are available as well. The directory where the file will end up can be found out using Direcory[] and changed with SetDirectory["path"].

With the command Manipulate[expr, {a, amin, amax}]you can visualize an expression depending on one (or more) parameters. The parameter can be changed using a slider and the changes will take effect immediately.

Manipulate[Plot[Sin[a x+b],{x,0,6}],{a,1,4},{b,0,10}]

A three-dimensional plot can be made with the following command.

({{Plot3D[f,{x,xmin,xmax},{ymin,ymax}], make a three dimensional plot of f}})

Here is a plot of a Bessel function, which can be used to model the vibration of a drum. Never mind if you have never heard of Bessel functions before; just notice the fact that Mathematica has more functions built in than you will probably ever need.

Plot3D[BesselJ[0,(x^2)+(y^2)],{x,-3,3},{y,-3,3},PlotPoints->25,ViewPoint->{1, -2, 2.5}]

The option PlotPoints specifies the number of points computed to generate the plot. See what happens if you change the value! The option ViewPoint specifies your point of view. Drag the grapics with your mouse to change it.

Complex  Numbers

Mathematica of course also knows how to handle complex numbers

Sqrt[-4]

You enter a complex number just by using a capital I:

((4+3 I)/(2-I))

The most important operations with complex numbers are collected in the following table.

({{x+I y, the complex number x+i y}, {Re[z], real part}, {Im[z], imaginary part}, {Conjugate[z], trigonometric functions (with argument in radians)}, {Abs[z], absolue value|z|}, {Arg[z], the argument ϕ in z=|z|(e^(iϕ))}})

However, note that Mathematica will not automatically evaluate real or imaginary parts for you

Re[Sin[x]Exp[x+I y]]

You can get the answer using the built in function ComplexExpand:

ComplexExpand[%]

Note that all variables are assumed real! If you don't want this, you can use

ComplexExpand[Exp[x],x]

You can also use a list of variables as second argument if there are several complex variables in the expression. Lists are enclosed in curly brackets.

ComplexExpand[y Exp[x],{x,y}]

Limits, Differentiation and Integration

Mathematica can compute limits

({{Limit[expr,x->(Subscript[x, 0])], limit of expr as x goes to (Subscript[x, 0])}})

Limit[(((1-(1/n)))^n),n->∞]

It can also be used to compute arbitrary integrals.

({{Integrate[f,x], the indefinite integral∫f dx}, {Integrate[f,x,y], the multiple integral ∫ ∫ f dx dy}, {Integrate[f,{x,xmin,xmax}], the definite integral (∫_xmin^xmax)f dx}, {Integrate[f,{x,xmin,xmax},{y,ymin,ymax}], the multiple integral (∫_xmin^xmax)dx(∫_ymin^ymax)dy f}})

For example

∫(1/((x^4)-1))\[DifferentialD]x

Similarly, we can differentiate arbitrary functions.

({{D[f,x], partial derivative (∂/(∂x)) f}, {D[f,(Subscript[x, 1]),(Subscript[x, 2,...])], multiple derivative (∂/(∂(Subscript[x, 1])))(∂/(∂(Subscript[x, 2]))) ... f}, {D[f,{x,n}], repeated derivative (((∂^n)f)/(∂(x^n)))}, {Dt[f], total differential df}, {Dt[f,x], total derivative(d/(dx)) f}})

For example, we can differentiate the result from above in order to get our integrand back.

(∂_x) %

At first sight it looks like Mathematica made a mistake somewhere along the way. However, performing some simplifications, it is not hard to see that this expression is indeed equivalent to our original integrand. But we can also ask Mathematica to simplify the expression.

Simplify[%]

If an integral cannot be evaluated symbolically, you can use the command NIntegrate to find a numeric approximation.

NIntegrate[ ((BesselJ[0,x])/(1+(x^2))),{x,0,1}]

Finally, let me remark that Mathematica can also handle series or products using

({{Sum[f,x], the indefinite integral(∑_(n=nmin)^nmax)f[n]}, {Prod[f,x,y], the multiple integral (∏_(n=nmin)^nmax)f[n]}})

For example

(∑_(n=1)^∞)(1/(n^2))

or

(∏_(m=1)^n)m

Matrix Operations

Vectors are represented in Mathematica as lists

u={1,2}; v={3,4};

and can be added in the usual way.

3 u+2 v

({{c u, multiply by a scalar}, {u.v, dot product}, {Cross[u,v], vector cross product}})

Matrices are represented similarly

M={{1,2},{3,4}}

To multiply matrices you have to use a dot!

M .v

The most common matrix operations are listed in the table below.

({{Inverse[M], inverse of a matrix}, {MatrixPower[M,n], (n^th)power of a matrix}, {Det[x], determinant}, {Tr[M], trace}, {Transpose[M], transpose}, {Eigenvalues[M], eigenvalues}, {Eigenvectors[M], eigenvectors }})

To display matrices in the usual way you can use the command MatrixForm.

MatrixForm[M]

To access different matrix elements you can use the Part operator as in the case of any list.

M[[1]]

M[[1]][[2]]

To create a matrix you can use the following functions.

({{Table[f,{i,m},{j,m}], build an n×n  matrix by evaluating f with i ranging from 1 to m and j  from 1 to n}, {Array[a,{m,n}], build an m×n matrix with "i,j(^th) element a[i,j]}, {IdentityMatrix[n], generate an n×n identity matrix}, {DiagonalMatrix[list], logaritmus (Subscript[log, a])(x)}})

For example

Table[i+j,{i,3},{j,3}] //MatrixForm

In addition, Table and Array can be used to create matrices of arbitrary dimensions

Array[a,{3}]

Table[f[i,j,k],{i,2},{j,2},{k,2}]

Solving Equations

Mathematica can solve various kinds of equations. For example set

eqn= (x^2)+ 2 a x + b==0

Note that the Set operator (=) has lower precedence than the Equal operator (==). To solve this equation for x you use the command

sol=Solve[eqn,x]

Note that the result is given as a list of rules. To verify this solution we can substitute the solution back into the equation and simplify the result.

Simplify[eqn /. sol]

In summary we have

({{Solve[lhs==rhs], solve an equation,giving a list of rules for x}, {x /. solution, use the list of rules to get values for x}, {exp /. solution, use the list of rules to get values for an expression}})

If you are only interested in, say, the first solution, you can use the Part operator to extract it.

sol[[1]]

You can also solve systems of equations for several variables using lists.

({{Solve[{(Subscript[lhs, 1])==(Subscript[rhs, 1]),(Subscript[lhs, 2])==(Subscript[rhs, 2]),...},{x,y,...}], solve a set of simultaneous equations for x, y, …}})

For example

eqns={x+y==a,x-y==0};
Solve[eqns,{x,y}]

If you are looking only for a numerical solution  you can also use

FindRoot[Sin[x]==Cos[x],{x,1}]

Here, the number after the variable is an initial value for the algorithm.

Clear[eqn,eqns,sol]

Simplifying expressions

You have already seen the Simplify command which does a sufficient job on most expressions. However, often further simplifications can be made if certain additional properties are known. Such additional assumptions can be given as a second argument to Simplify.

Simplify[Sqrt[(x^2)],x∈Reals]

Using this approach, Mathematica can even verify inequalities:

Simplify[(((a b c))^(1/3))≤(1/3) (a+b+c),0≤a&&0≤b&&0≤c]

Here && corresponds to a logical And. Similarly, || would correspond to a logical Or.

If Simplify should not suffice, you can also try to use FullSimplify which applies a wider range of transformations (but consequently takes more time). In particular, FullSimplify will do much better on expressions involving special functions.

Simplify[Gamma[1-x] Gamma[x]]

FullSimplify[Gamma[1-x] Gamma[x]]

These two commands are useful for polynomials

({{Expand[expr], multiply out products and powers,writing the result as a sum of terms}, {Factor[expr], write expr as a product of minimal factors}})

Expand[(((1+x))^3)]

Factor[%]

Differential equations

In order to solve differential equations you can use the following command:

({{DSolve[eqns,y[x],x], solve a differential equation for y[x] taking x as the independent variable}})

For example

DSolve[y'[x]==y[x],y[x],x]

Since no initial condition is given, the general solution containing an arbitrary constant C[1] is returned.

Another example with initial condition

sol=DSolve[{y'[x]==1+((y[x])^2),y[0]==1},y[x],x]

y[x_]= y[x] /. Flatten[sol]

Now you can use the solution like any other function. The command Flatten will get rid of additional curly brackets.

Clear[y]

Moreover, DSolve can even be used to solve systems of equations.

sol=DSolve[{x'[t]==6 x[t]-2 y[t],y'[t]==-2 x[t]+9 y[t],x[0]==1,y[0]==2},{x[t],y[t]},t]

{x[t_],y[t_]}= {x[t] ,y[t]}/. Flatten[sol]

Clear[x,y,sol];

If an explicit solution cannot be found you can ask Mathematica to find a numeric solution using the NDSolve command. For example to compute the solution of the Lorenz equation numerically you would use

tmax=20;
sol=NDSolve[{x'[t]==-10 (x[t]-y[t]),y'[t]==-x[t] z[t]+28 x[t]-y[t],z'[t]==x[t] y[t]-(8/3) z[t],x[0]==30,y[0]==10,z[0]==40},{x,y,z},{t,0,tmax},MaxSteps->5000];

The solution can the be plotted as follows

ParametricPlot3D[Evaluate[{x[t],y[t],z[t]}/.sol],{t,0,tmax},PlotPoints->2000,Axes->False,PlotRange->All]

Clear[x,y,z,sol,tmax];

Number Theory

Mathematica also knows several functions related to number theory. We will consider some of them by looking at the RSA-Algorithm.

The first ingredient we need are two prime numbers, for example

p=31;q=37;

That these are indeed prime numbers can be tested with

PrimeQ[{p,q}]

Now one considers

n= p q

and performs all calculations modulo this number. The main theorem behind the RSA-Algorithm is the Euler-Fermat-Theorem, which states that (a^(ϕ(n)))=1 mod n, where ϕ(n) is the Euler phi function. In our case it is given by

EulerPhi[n]==(p-1)(q-1)

Now we take a number which can be inverted mod ϕ(n).

e=29;

For this to be possible, e and ϕ(n) must have no common divisors. This can be tested by computing the greatest common devisor:

GCD[e,EulerPhi[n]]

Its inverse is given by

d=PowerMod[e,-1,EulerPhi[n]]

which can be easily verified by

Mod[e d,EulerPhi[n]]

Now we can use this to encrypt the string BORING as follows. We first convert it to the corresponding ASCII numbers:

ToCharacterCode["BORING"]

Now we can encrypt by

PowerMod[%,e,n]

and decrypt by

PowerMod[%,d,n]

FromCharacterCode[%]

Hence to encrypt we only need (e,n), the so called public key, and to decrypt we only need (d,n), the so called private key. The security of the RSA-Algorithm relies on the fact that in order to compute d from (e,n)
one needs the corresponding prime factorization

FactorInteger[n]

which might take a long time to compute if the two prime numbers are chosen sufficiently large.

Clear[p,q,n,e,d]

Programming I

Clearly, Mathematica can also be used for writing entire programs. For example, Mathematica provides (among others) the following basic control

({{If[test,a,b], give a if test is true and b else}, {Which[(Subscript[test, 1]),(Subscript[value, 1]),(Subscript[test, 2]),...], use the list of rules to get values for x}})

and loop structures

({{Do[expr,{i,imin,imax,di}], evaluate expr with i from imin to imax in steps of di}, {For[start,test,incr,body], evaluate start, then repetitively evaluate body and incr until test fails}, {While[test,body], evaluate body repetitively, sol long as test is True}})

The expressions to be evaluated may of course consist of several statements separated by semicolons.

For example, the following program will produce a list of all primes lower than 100

primes={2};
Do[If[PrimeQ[n],primes=Append[primes,n]],{n,3,99,2}];
primes

The Append command appends its second argument to the list given as first argument.

Clear[primes]

Now let us consider a more complicated example and look at the iterates of the quadratic function f(z)=(z^2)+c. An interesting mathematical question is, for a fixed complex number c, to find all start values for which the iterations remain bounded. It can be shown that the iterations are either bounded by |c|+1 or converge to infinity. The set of all these values is called the (filled) Julia set corresponding to c. To find it we can use a for loop:

Julia[c_,z0_]:=
(For[k=0;z=z0,k<100&&Abs[z]<Abs[c]+1, k++,z=(z^2)+c]; k)

Hence for given c and z0 this function will output the number of iterations needed until the iterates grow above |c|+1. Since this might be true for all iterates, we stop after 100 iterations. Moreover, since our function contains more than one statement (the for loop and the single statement k which just outputs the number of iterations) and since it contains some local variables, it is a good idea to pack everything into a block.

({{Block[{x,y,...},body], evaluate body using local values for x, y, ...}, {Block[{x=(Subscript[x, 0]),y=(Subscript[y, 0]),...},body], assign initial values to x, y, ...}})

Hence our refined function reads

Julia[c_,z0_]:=Block[{z=z0,zmax=Abs[c]+1,k},
For[k=0,k<100&&Abs[z]<zmax, k++,z=z^2+c];
k];

Unfortunately, the for loop is not very efficient and takes up a lot of time. The Timing function shows us how much.

Timing[Julia[I,0]]

To improve performance, we can tell Mathematica to compile our function

({{Compile[{(Subscript[x, 1]),(Subscript[x, 2]),...},expr], create a compiled function which evaluates expr for numerical values of the (Subscript[x, i])}})

In addition, it is also possible to tell Mathematica the type of each argument by using {(Subscript[x, 1]),_Type}, where Type can be Integer, Real, or Complex.

Julia=Compile[{{c,_Complex},{z0,_Complex}},
Block[{z=z0,zmax=Abs[c]+1,k},
For[k=0,k<100&&Abs[z]<zmax, k++,z=(z^2)+c];
k]
];

Using the Timing function again shows that compiling a function does indeed speed up the calculation!

Timing[Julia[I,0]]

Now we can finally visualize the Julia set for given c by creating a density plot for say c=-1.

DensityPlot[Julia[-1,x+I y],{x,-1.5`,1.5`},{y,-1,1},Mesh->False,PlotPoints->400]

The (filled) Julia set is the white part in the middle of the picture. Observe that it has a quite irregular boundary. However, it can be shown that it is still a compact connected set. This is no longer true for c=-0.719-0.25i, where the (filled) Julia set is a Cantor set.

DensityPlot[Julia[-0.719`-0.25` I,x+I y],{x,-1.5`,1.5`},{y,-1,1},Mesh->False,PlotPoints->400]

The set of parameter values c for which the (filled) Julia set is connected is called the Mandelbrot set. It can be shown to be equal to the set of all complex numbers c for which the iterations starting at z0=0 are bounded. We can visualize the Mandelbrot set by making a density plot of the following function

Mandel=Compile[{{c,_Complex}},
Block[{z=0.+0. I,k=0},
While[Abs[z]<2&&k<60,z=(z^2)+c; k++];
k]
];

In addition, we'll make the plot a little more colorful!

DensityPlot[Mandel[x+I y],{x,-1.5`,0.5`},{y,-1,1},ColorFunction->Hue,Mesh->False,PlotPoints->400]

The Mandelbrot set is the red area in the middle. Here is a part of the boundary in more detail.

DensityPlot[Mandel[x+I y],{x,0.365`,0.375`},{y,0.095`,0.105`},ColorFunction->Hue,Mesh->False,PlotPoints->400]

Feel free to experiment with the parameters! For further information you can have a look at the text book R.A. Holmgren, A First Course in Discrete Dynamical Systems, 2nd ed., Springer Verlag, 1996.

Clear[primes,Julia,Mandel]

Programming II

In addition to the classical programming structures presented in the previous section, Mathematica offers several other methods for programming. One of the most powerful ones is via pattern matching. Since statements of the type "If the expression is of type xxx it is equal to yyy." arise frequently, this approach is particularly suitable for mathematical problems.

For example, if f is a linear function, then f applied to a sum is equal to f applied to each summand. You could implement this in Mathematica as follows:

f[x_+y_]:= f[x] + f[y]

Here the blank (underscore) tells Mathematica that the variable is to be understood as a place holder. More precisely, it is a pattern which matches a single expression. Hence, if f is invoked with a sum of two expressions, Mathematica will automatically replace it with f applied to both summands.

f[x+Sin[y]]

In fact, this even works in the following situation.

f[a+b+c]

To see why, let us watch Mathematica by using the Trace command which displays all intermediate steps.

Trace[f[a+b+c]]

From the output you can infer that Mathematica knows that a+b+c is equivalent to a+(b+c) and applies our definition as often as possible.

If you do not want Mathematica to apply the transformation every time f  is used, you could use a transformation rule instead.

Clear[f]

f[a+b] /. f[x_+y_]-> f[x] + f[y]

This only applies the rule once:

f[a+b+c] /. f[x_+y_]-> f[x] + f[y]

If a transformation should be applied repeated, use

f[a+b +c] //. f[x_+y_]-> f[x] + f[y]

In setting up patterns there are virtually no limitations

{(2^3),x,(5/x),(y^3)+7 ,(x^(Sin[x]))} /. x_^n_ -> a[x,n]

However, note that the above transformation might not give the expected result in all cases. First of all, Mathematica performs some simplifications before it applies our transformation rule. In particular, it simplifies (2^3) to 8 and hence our pattern does no longer match. In addition, it uses (1/x)=(x^(-1)) but not x=(x^1). To understand why, it is necessary to look at the representation Mathematica uses internally. This can be done using the following command:

FullForm[{x,(1/x)}]

Here we see two things. First of all, everything is represented internally as "Head[arg1, arg2, ...]".  And second, (1/x) is represented as (x^(-1)) and it is now clear why our pattern matches.

Note that by adding a dot after n_ it will also match the (x^1) case, but this might still not always give the result you want:

(5/x)/. x_^n_. -> a[x,n]

As noted earlier, a single blank only matches a single expression (which could be arbitrary complex) but not several arguments of a function.

{f[x],f[x,y],f[x,y,z]} /. f[x_]->(x^2)

If you want to match one or more arguments, you can use double blanks and if you want to match zero or more arguments you use triple blanks. Triple blanks are useful for optional arguments.

{f[x],f[x,y],f[x,y,z]} /. f[x_,y__]-> a[x] b[y]

{f[x],f[x,y],f[x,y,z]} /. f[x_,y___]->a[x]b[y]

Next, many transformations are only valid if certain conditions are met. Mathematica offers two ways to handle such situations. First of all, a single pattern can be tied to a certain type by specifying its head after the blank. Here head is Integer, Rational, Real, Complex for a number (according to its type), Symbol for a variable and the name of the top level function otherwise. You can find out the head by using the Head command.

Head/@ {5,0.5,I/2, x,x+y,{x,y},f[x]}

Here the Map command (/@) applies the given function to each expression in the first level of a given expression.

The FullForm command from above is also useful in this respect.

FullForm[{I/2,x+y}]

For example, let us use the transformation from above and require that n must be an integer.

{(2^3),x,(5/x),(y^3)+7 ,(x^(Sin[x]))} /. x_^n_Integer -> a[x,n]

Secondly, the Condition operator (/;) can be used to make sure a pattern is used only if a condition is met. For example,

f[x_]:= 0 /; x<0

{f[-1],f[x],f[1]}

Here the condition could be any expression which evaluates to true or false. If the expression cannot be evaluated, Mathematica assumes false and the definition is not used. Conditions can be used for patterns, delayed assignments and delayed rules.

({{pattern /; condition, a pattern that matches only when a condition is satisfied}, {lhs :> rhs /; condition, a rule that applies only when a condition is satisfied}, {lhs:=rhs /; condition, a definition that applies only when a condition is satisfied}})

Finally, you can of course specify several patterns for a given function. Mathematica will order them automatically (more specific patterns will come first) and use the first one which matches.

f[-1]:=1;

{f[-1],f[x],f[1]}

You can list all definitions associated with a function as usual

?f

In particular, this will also show the order in which the definitions are applied.

Clear[f]

To end this section let us define a function which will pull out constant terms from a sum.

PullOut[expr_]:=expr /.((∑_(n_=i_)^(j_))a_ x_ :>a(∑_(n=i)^j)x /; FreeQ[a,n])

PullOut[1+(∑_(j=1)^n)c f[j]]

Here the function FreeQ tests if its first argument does not contain the second. Some other useful tests are listed below

({{IntegerQ[expr], integer}, {EvenQ[expr], OddQ[expr], even,odd number}, {PrimeQ[expr], prime number}, {NumberQ[expr], explicit number of any kind}, {NumericQ[expr], numeric quantity}, {PolynomialQ[expr,{(Subscript[x, 1]),(Subscript[x, 2]),...}], polynomial in (Subscript[x, 1]), (Subscript[x, 2]), ...}, {VectorQ[expr], a list representing a vector}, {MatrixQ[expr], a list of lists representing a matrix}, {FreeQ[expr,form], form matches nothing in expr}, {MatchQ[expr,form], expr matches the pattern form}})

Clear[PullOut]