6. Mathematical Functions#

Saleh Rezaeiravesh, saleh.rezaeiravesh@manchester.ac.uk
Department of Mechanical and Aerospace Engineering, The University of Manchester, Manchester, UK


Overview: In addition to basic arithmetic operations, Python offers a wide range of built-in mathematical functions. In this notebook, we provide an overview of these functions, demonstrating their use with both scalar and array inputs.

6.1. Libraries#

Depending on the type of input to the functions, we can use different libraries in Python:

Input type

Library

List of functions

Non-complex number

math

math functions

Complex number

cmath

cmath functions

numpy array, complex/non-complex number

numpy

numpy functions

In the links provided, you can see different functions including trigonometric, logarithmic, hyperbolic, etc.

To use a function, we need to import the corresponding library at the beginning of a Python script. The imported libraries can also be given shorter names for convenience.

import math as mt
import cmath as cmt
import numpy as np

There are certain functions which are Python native and do not require any library to import. For instance consider the abs function:

  • For a integer/float number x, abs(x) returns the abolosute value of x.

  • For complex number x, abs(x) returns the magnitude of x.

  • For a numpy array x, abs(x) returns either of the above for each element in the array.

See the following example:

a1 = -3.65         #float
a2 = -3.65 + 2.0j  #complex
a3 = np.array([-1.2,2.2,5.9,8.7])  #array of float numbers
a4 = np.array([-1.2,2.2+1.j,5.9-3.6j,8.7+2.5j])  #array of complex numbers

print(a1, abs(a1))
print(a2, abs(a2))
print(a3, abs(a3))
print(a4, abs(a4))
-3.65 3.65
(-3.65+2j) 4.162030754331352
[-1.2  2.2  5.9  8.7] [1.2 2.2 5.9 8.7]
[-1.2+0.j   2.2+1.j   5.9-3.6j  8.7+2.5j] [1.2        2.41660919 6.91158448 9.05207159]

For other mathematical functions, it is important to use the correct library depending on the data type. See the following examples:

Example: For a float or integer input, we can call functions from all the above three libraries. Note that the format of the output can be different depending on the input type and operations.

a = 3.6   #float input

print(mt.sin(a))   #math function
print(cmt.sin(a))  #cmath function
print(np.sin(a))   #numpy function
-0.44252044329485246
(-0.44252044329485246-0j)
-0.44252044329485246

Example: For a complex number input, we can only use functions from cmath and numpy:

a = 3.6 +2.5j   #complex number input

print(cmt.sin(a))    #cmath function
print(np.sin(a))     #numpy function
(-2.7136634589531345-5.425571788915j)
(-2.7136634589531345-5.425571788915j)

Therefore, in this case you will get an error by running print(mt.sin(a)).

Example: For a numpy array, you can only use functions from numpy:

A = np.random.rand(5)   #numpy array inpuy

print(A)          #input
print(np.sin(A))  #output of a numpy function
[0.2048031  0.45308545 0.13425318 0.776385   0.80383683]
[0.20337438 0.43774174 0.13385025 0.70070488 0.72002395]

6.2. Constants#

The above libraries have values for some of the common consttants, see the following table:

Constant

Python value

Description

\(\pi\)

math.pi, numpy.pi

3.141592653589793

\(e\)

math.e, numpy.e

Euler’s constant, base of natural logarithms, Napier’s constant

\(\infty\)

math.inf, numpy.inf

A floating point representation of positive infinity

NaN (Not a Number)

math.inf, numpy.inf

A floating point representation of Not a Number

Similar constants from math and numpy have the same values.

print('math.pi:',mt.pi)
print('numpy.pi:',np.pi)
math.pi: 3.141592653589793
numpy.pi: 3.141592653589793
print('math.e:',mt.e)
print('numpy.e:',np.e)
math.e: 2.718281828459045
numpy.e: 2.718281828459045
print('math.inf:',mt.inf)
print('numpy.inf:',np.inf)
math.inf: inf
numpy.inf: inf

6.3. numpy functions#

The following example showcases the application of numpy functions to input numpy arrays.

Example: Write a python script that evaluates \(f(x)=e^{-x^2} tan(x)\) at an array of \(x\) taken from \([-5,5]\).

First, we create 200 evenly-spaced points from -5. to 5. using numpy.linspace (Refer to numpy arrays for details).

x = np.linspace(-5.,5.,200)

Now, we can easily evaluate the function at all values of the \(x\) array:

f = np.exp(-x**2.)*np.tan(x)

We can use the same line to evaluate \(f(x)\) at a two-dimensional array. For instance, let’s create a 5x6 matrix with its elements being randomly drawn from [0,1] (Refer to numpy arrays for details):

x = np.random.rand(5,6)

Using linear interpolation, we can map these points from [0,1] to [-5,5]:

x = -5.0 + x*10.0
x.shape
(5, 6)
f = np.exp(-x**2.)*np.tan(x)
print(f)
[[-9.99294789e-09 -7.43041604e-05 -2.50247481e-07 -3.98131596e-08
  -1.37481203e-07 -1.71658958e-02]
 [ 7.09573775e-02 -9.22332256e-04  3.20157395e-01 -5.84504594e-01
  -6.54176934e-08  2.72260492e-06]
 [ 1.91060223e-01 -5.53745334e-01  3.10223265e-03  1.38496347e-08
  -4.29783384e-01 -7.20938398e-01]
 [-5.61182786e-01 -5.65514761e-01  6.73325969e-09  1.07876733e-03
  -2.25608554e-02  2.50046701e-08]
 [-8.95266503e-01  5.31354435e-05  1.08467021e-07 -5.78154737e-01
  -1.37132075e-03 -3.67673940e-01]]

As expected, the output f has the same shape as the input x, that is a two-dimensional array of size 5 x 6:

print(f.shape)
(5, 6)