F. Fassò.    University of Padova. 
Introduction to the use of Mathematica in Mathematics and Science. SoftSkills course for the PhD program in Mathematics
Lecture 2 (October 13, 2023)

1. A first look at Mathematica:  What can you do?  How?
(part 2)

6. Definition of functions

6.1 Functions in Mathematica

Extremely important: Mathematica is a functional language

Functions can be defined in different ways
The basic one is
    f[x_] := expression
This specifies that “f” is the function that trasforms its argument into “expression”

NB: in the definition of a function
        the argument “x” is a symbol and must be followed by _ (“blank”)
        use    :=     
(or else  = ; the difference will be explained later)

Functions of more variables:
    f[x1_, x2_ , .... , xn_ ] :=  ....

Functions are not only numerical.  (Basic for functional programming)

6.2 Examples

Exercise: write a function that takes as argument a function R->R (given as an expression containing the variable “x”) and plots its graph in the interval 0 < x < 1

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

pl[expr_] := Plot[expr, {x, 0, 1}]

Test:

pl[ Sin[(x^2)] ]

Exercise: write a function
                          pl(expr,a,b)
which does the saem thing but in the interval a < x < b with any a and b

pl[expr_,a_,b_]:=Plot[expr,{x,a,b}]

pl[(E^(x-1)), -3,1]

Can we use the same symbol (“pl”) for the two functions? 
Yes, because they have a different number of arguments.

In fact, Mathematica has two definitions for the function “pl”:
(see below for the command “?”)

?pl

6.3 Function evaluations

In evaluating a function, Mathematica
• substitutes the argument to the variable (here “x”) that appears in the expression at the left hand side of the definition    f[x_]:=....   
• and, possibly, makes some (obvious/simple) computations and simplifications

Example: define the function
     f[u_] := (Sqrt[(u^2)])       ( Sqrt[u^2] )  .
     
Which will be the resulta of   f[2] ?  And of   f[x]   or   f[gianni] ?

f[u_]:= Sqrt[ (u^2) ]

f[2]

f[x]

Why no simplification in the second case?
Can we force it?

FullSimplify@%

No.
Does it make sense?

Yes:
      (Sqrt[(u^2)]) =  u    only if  u  is a positive real.
Withouth that information, Mathematica does not simplify

What does Mathematica do when evaluating a function?

     Trace[command]  gives a list of the expressions used in evaluating “command”

Trace[  f[2 ]]

It keeps substituting symbols with their values (if any) and computing things.

Trace[f[u]]

6.4 Note: Assumptions

How to tell Mathematica that the argument is (e.g.) a positive real?

Refine[ expr ,  condition   ]
evaluates  expr  assuming true the condition
       Assuming[    condition ,  Simplify[ expr ]   ]
semplifica  expr  assumendo vera la condizione (fra le altre cose, Simplify prova a usare Refine)

Refine[f[u],u>0]

Assuming[u>0, Simplify@f[u]]

Exercise: and if x<0?

Refine[f[x],x<0]

Assuming[x<0, Simplify@f[x]]

6.5 Role of “_” in the definition of a function

Careful:
       writing (e.g.) “x” instead of “x_” in the definition of a function, defines the function  only if the argument is exactly x .
So, don’t forget it.

g[x]:=(x^2)-(x^3)

g[x]

g[1]

x=1

g[x]

Note: This can however be used to assign the value of a function for particular values of the arguments

Exercise:  Define the function  f : (Reals)-> (Reals)such that
    f(x) =   ((sin(x))/x)  if  x+ ≠ 0
    f(x) =   1  f  x+ = 0
(without using “If” or similar constructs)

f[x_]:=((Sin[x])/x)

f[0]

f[0]:=1

f[0]

or else   f[0] = 1  (see next subsection)

6.6 Using “:=” or  “=” in function definition?

Two ways of defining a function:
•  =  "Set"
• :=  "Set Delayed"  
The difference is on when the definition is executed

• "Set":  the right hand side hand side (including the variables on which the function depends) is evaluated at the moment in which the definition is executed
• "Set Delayed": the right  hand side will be (re)evaluated each time the function is called 
    (this is why Set Delayed does not produce Output)

The two procedures are not equivalent if 
- the variables on which the function depends have a value assigned at the moment of the definition
- the r.h.s. contains symbols
because with SET the variables and the symbols are (forever) given the value that they have at the moment of the definition,

Example 1

x=5;

g[x_] := x

h[x_] = x

g[1]

h[1]

x=0;

g[1]

h[1]

Correct?

?g

?h

Example 2

Clear[x];
p=3;

g[x_] := x+p

h[x_] = x+p

g[1]

h[1]

p=0;

g[1]

h[1]

Thus, be careful with “=”!

• In general, it is safer to use :=

Use := or = depending on what you need to do.
• E.g., use “=” if you want that a specific value of a symbol is used (e.g., a global parameter set at the beginning of the computations)

Exercise: You want to define a random number. 
Native Mathematica functions:
            RandomReal[ ]  :  random number in interval (0,1)
            RandomReal[ Interval] :  random number in specified interval
Which is difference between
  rr1 = RandomReal[]
  rr2 := RandomReal[]
?

rr1=RandomReal[]

rr1

rr1

rr2:=RandomReal[]

rr2

rr2

Note:  Using “=” or “:=” may affect the execution time of a function 

Exercise: Compare the time  Mathematica  takes to make the graph of:
•   test1[x_]:= Expand[(((1+Sin[x]))^200)] 
•   test2[x_] = Expand[(((1+Sin[x]))^200)]
and explain the result

The time used by Mathematica to process a command is given by
      Timing[  command]
which produces
     {used time,  output of “command”}

test1[x_]:=Expand[(((((1+Sin[x])/2)))^200)]

Clear[x];       (* this precaution is recommended before using SET!  *)
test2[x_]=Expand[(((((1+Sin[x])/2)))^200)];

Plot[test1[x],{x,0,2Pi},PlotRange->{0,1}]//Timing

Plot[test2[x]//Evaluate,{x,0,2Pi},PlotRange->{0,1}]//Timing

Answer:
- During the evaluation of test1 a numerical value is substituted to x and then numerical sums and powers are made (there is nothing to expand)
- test 2 first symbolically expand the power of the bynomial (slow!) and then substitutes into the resulting expression the numerical value to x
Check this with “Trace”

test1[x_]:=Expand[(((1+Sin[x]))^200)]

test1[.2]//Trace

Expand[(((1+Sin[.1]))^200)]//Trace

Expand[(((1+Sin[x]))^200)]

7. Help and documentation

There are two types of help:

•  a short description of each command (?command)

• a complete dcumentation/help system  (with description of all commands, tutorials, and much more) which can be accessed
   ••   from the “Help” menu  
   ••  pressing F1  
   ••  clicking on “i” in the ineractive menu that appears when typing a command or  ?command

Example:  info on the command “Expand”

?Expand

Expand

8. Organization of the notebook: “elegant” formulas, sections, text cells ....

The display of the input can be improved using  2-dimensional notation ((x/y),(x^y) ,etc),  greek symbols  etc.
• either inserting symbols/placeholders from a palette (from the  Palettes menu)
• or using  key shortcuts

Examples of key shortcuts:
    Sqrt[ ]   ->   (Sqrt[□])               (CTRL 2)
       x/y       ->   (x/y)                 (CTRL /)
       x^3       ->   (x^3)                  (CTRL  6)
            α                                       ( ESC a ESC )

(2/3)    (x^87)    α     (Reals)      α ∈ (Reals)

Exercise: using only the keyboard, write
      η ,     (Sqrt[4 β])  ,    (x^(3α))  ,   (5/3)   ,     (((((Sqrt[x+(x^2)])/(2-x))))^67)

Formatting styles (“Forms”)

Mathematica uses different formats for the mathematical notations in the  input and output cells
Main formats: 
  • Input Form: only inline alphanumerical characters.
  • Standard Form: it’s the form used for the display of input and output; can be made 2-dimensional 
  • Traditional Form: suitable for printing a notebook
  • Full Form: internal representation of all objects

Example

((x^2)/(Log[x]))+Sin[(Sqrt[x])]

x^2/Log[y] + Sin[Sqrt[x]]

% // StandardForm

%% //  InputForm

%%% // FullForm

%%%%// TraditionalForm

The first three are equivalent.
Traditional Form is not equivalent to the others (it might not be interpretable in a unique way): avoid it, possibly except for comments etc.

Organization of notebooks: hierarchy of sections, text cells

Text cells

Insertions of  comments: 
• inside an input cell :    (*   comments   *)
• in a text cell

ALT7:
- Creates a text cell at the cursor position
- Changes an existing cell to a text cell

(Alternatively: use menu  Format->Style->Text).

Simplify[(Sqrt[(x^2)]) ]   (* This will not be simplified because x is not a positive real *)

this cell will become a text cell (pressing  ALT 7)

(To change it back to an input cell press ALT 9)

Advantages of text cells:
• cannot be executed
• better formatting/more easily readable

Sections

Notebooks can be hierarchically organized in sections, subsections, ...

ALT 1, ... ..., ALT 6
   create (or convert to) “title”, “subtitle”, “chapter”,...., “subsubsection”  cells
(or use meu Format->Style-> .... )

9. Exact and approximate numerical computations

Mathematica
•  can make both  EXACT and APPROXIMATE computations 
and 
• works with different types of numbers:
  •• exact 
  •• machine-precision 
  •• arbitrary precision

9.1 “Exact” arithmetics

In Mathematica
   • Integers
   • Rationals
   • Complex numbers with integer or rational real and imaginary parts
   • Certain “notable” reals (π, E, ...)
are EXACT numbers
 
Mathematica performs all operations on them EXACTLY

Careful:  “Exact” is great, but might be slow!

(56^230)

(1/3)+(3/4)

((%)^2)

(Sqrt[-4])

((10-5I)/(2+I))

Abs[1+I]

((%)^2)

Sin[π]

ArcCos[0]

(E^(Log[2]))

The evalutation of expressions containing all exact arguments is exact

(this means that most outputs are not evaluated numerically)

Sin[(Pi/14)]

((%)^2)+((Cos[(Pi/14)])^2)

%//Simplify

9.2 “Machine-precision” arithmetics

Real and complex numbers are, by default, machine-precision numbers 
(∼ floating point)

Operations on them are performed numerically (hence, fast and approximate)

2.1+3.0

Operations involving both exact and machine-precision numbers give machine-precision results

2.1+3

To transform an exact number into a machine-precision number: 
     N[ ]

N[2]

N[Pi]

9.3 “Arbitrary precision” arithmetics

Mathematica can handle real numbers with any numer of digits (hence, arbitrarily large or small) and while working with them attempts to keep that precision.

If you need this, consult the documentation.
Just a few examples:

Approximate an exact number/expression into one with a given precision:
         N[ expression,  number of digits]

N[Pi,50]

N[ E, 121]

N[Log[2]+(E^12),34]

9.4 Displaying decimal digits

Example of exact rational number

1+(1/(10^10))

Example of machine-precision real number

1.+(1/(10^10))

??? 
Can we see the first 12 digits?

N[1.+(1/(10^10)),12]

1.0000000001`

???

By default, Mathematica displays machine-precision numbers with at most 5 decimal digits, and does not display the trailing zeroes

How to display more digits?
        NumberForm[ expr , n ]
prints expr with all numbers with n digits (but no trailing zeroes)

NumberForm[1.+(1/(10^10)),10]

NumberForm[1.+(1/(10^10)),11]

Note:
To print also the traling zeroes, use
      NumberForm[expr , {n , c } ]
which prints expr with all numbers with n digits, c of which after the decimal point  (including the trailing zeroes)

NumberForm[1.+(1/(10^10)),{10,10}]

NB: modificabile da Edit -> Preferences -> .....

9.5 Efficiency: avoid exact arithmetic if you don’t need it!

Mathematica uses different internal algorithms for exact and approximate computations.

However, the “types” of the numbers (and other objects) need not be specified.

Mathematica makes assumptions  on them (e.g., if all numbers in an expression are exact, Mathematica assumes that the result must be exact) and use the approprie algorithms.

(1/2)+1

(1/2.0)+1

Algorithms for exact arithmetics are much slower than those for machine-precision arithmetics, and execution times may then be much longer.

If you don’t need exact result, avoids Mathematica working in exact arithemtics. 
This is especially important in complicated/repetitive computations.

The simplest way to do this  is to be sure that not all numers in the expression to be computed are exact, e.g. by insert some machine-precision number. 
(E.g., write 1. instead of  1  or approximate some number/exprssion with  N)

Exercise
Compare times for a repetitive computation with integers and reals

E.g. compute
     ArcTan[Log[Sin[(E^(n^(-3)))]]]
for n=1,....,100000

To make a loop: 
     Do[ expression, {iterator, number of iterations} ]

Do[ x=n, {n,10}]

x

Do[    ArcTan[Log[Sin[Exp[(n^(-3))]]]]  ,           {n,1,100000}]//Timing

Do[    ArcTan[Log[Sin[Exp[ (((N[n]))^(-3))]]]] , {n,1,100000}]//Timing

Do[  ArcTan[Log[Sin[Exp[ (((1.n))^(-3))]]]] , {n,1,100000}]//Timing

NB: In Mathematica,  “Do” does not produce an output.

9.6. “Types” of objects

In Mathematica, everything is an expression
              At the core of Mathematica is the foundational idea that everything—data, programs,
              formulas, graphics, documents—can be represented as symbolic expressions
However, expressions can be of different “types”.

The “type” is called Head
   Head[expr]

E.g., integers and reals are different objects and have different Heads

Head[2]

Head[2.0]

So are symbols, strings, graphics, ...

Head[a]

a=1

Head[a]

Head["ciao"]

Head[  Plot[Sin[x],{x,0,Pi}]  ]

10. Lists

Lists

Lists are omnipresent  in Mathematica.

Reason: lists are the basic data structure used to represent objects, both from Mathematica and the user.

It is necessary to know how to work with lists.

A list is created and represented as a set of expressions
• separated by commas 
• (hierarchically) enclosed in curly brackets

Example: A list of three elements (a symbol, a  number, a string)

u={u1,23,"ciao"}

Working with the elements of a list

Elements of a list
   list[[position]]

u[[1]]

u[[3]]

NB: need a pair of square brackets

(u[1] is the value at x=1 of the function u(x) )

The elements of a list can themselves be lists:

M={c, {a,b}, u}

M[[2]]

M[[2,1]]

In such a case, the list has different levels

Level[M,{1}]

Level[M,{2}]

Exercise: Let
  A = { {a11,a12}, {a21 , {a221,a222}} }
Using Extract  and   Level
• extract the element of A in positoin  {2,2,1}
• crate a list of all elements of A at levels 2 and 3

Suggestion: look at the syntax of the commandsi in the Help

Deleting elements from a list:
      Delete[ list, position(s)]

Delete[M,1]

(Algorithmically) creating lists

Lists can also be created with the command
     Table[ expression,  iterators ]

Table[ n , {n,5}]

Table[ n , {n,-3,5}]

Table[ n , {n,-3,5,(1/2)}]

Dimensions of lists

Dimensions of a list:
-  Length[lista] gives the number of elemnts (at first level)
-  Dimensions[lista]  gives the lenghs
          – of the list
         – and of its sublists (in the levels in which they all the same length)
(in form of list!)

M

Length[M]

Dimensions[ M]

Dimensions[{{a1,a2},{a3,a4}}]

Example of appearance of lists in Mathematica

The elements of a list may be images, sounds, ...

M1=Table[      Plot[(x^n),{x,-1,1}]   ,        {n,0,2}]

Why? What is a "plot"? How is it represented?

pl=Plot[(x^0),{x,-1,1}]

pl//InputForm

Besides the Head ("Graphics") it’s a list of lists (lists are omnipresents!)

Can we work with/modify/put our hands into this list?

Which are its elements (at the first level)?

Length[pl]

pl[[1]]

pl[[1]]//InputForm

pl[[2]]

Let us remove the second element from the list
       Delete[list, position of the element to be deleted]

Delete[pl,2]//InputForm

It is possible to manipulate all objects (graphics, ...) at a very low level.
This is one of the reason of the versatility of Mathematica: it is really possible to have it doing what you want!

Exercise: changing the values in 
    RGBColor[0.368417, 0.506779, 0.709798]
try to make the line, e.g, red