General Applied Math#

Overview#

Working with math is perhaps the most common task in any kind of geoscience workflow in Python. This notebook will cover:

  • Python math vs. numpy

  • Mathematical Constants

  • Trigonmetric and Hyperbolic Functions

  • Algebraic Functions

  • Degrees and Radians

  • Rounding

  • Exponents and Logarithms

  • Sorting

math vs. numpy#

math is a built-in part of the standard Python library. This is a useful module for common and simple computations when working with single input values. To work with arrays or large datasets, numpy is a good alternative to the math module. numpy is a powerful external Python package for working with arrays and mathematical functions. numpy is package developed to work with scientific computing and math functions and is tailored to run much faster with large datasets and arrays.

Important Note

The math library cannot be used with complex numbers. Instead, equivalent functions can be found within the standard Python cmath library

Mathematical Constants#

Fixed mathematical constants are built into the standard Python libraries as well as external packages like numpy

pi#

pi represents the ratio of a cicle’s circumferences to its diameter

import math
import numpy as np

print(f"(numpy)            pi = {np.pi}")
print(f"(standard library) pi = {math.pi}")
(numpy)            pi = 3.141592653589793
(standard library) pi = 3.141592653589793

e#

e is the base of the natural logarithm

import math
import numpy as np

print(f"(numpy)            e = {np.e}")
print(f"(standard library) e = {math.e}")
(numpy)            e = 2.718281828459045
(standard library) e = 2.718281828459045

Trigonmetric and Hyperbolic Functions#

sin, cos, and tan#

The functions sin, cos, and tan are part of the standard Python math library when working with single value inputs. When working with lists and arrays, these functions can be evaluated with the external package numpy. By default, the input and output values are in radians.

import math
import numpy as np

input = 3.14
print("Single Value input")
print(f"\tsin (math)  = {math.sin(input)}")
print(f"\tsin (numpy) = {np.sin(input)}")
print(f"\tcos (math)  = {math.cos(input)}")
print(f"\tcos (numpy) = {np.cos(input)}")
print(f"\ttan (math)  = {math.tan(input)}")
print(f"\ttan (numpy) = {np.tan(input)}")

inputs = [1.2, 2.3, 3.14]
print("\nMultiple Value Input (array/list)")
print(f"\tsin (numpy) = {np.sin(inputs)}")
print(f"\tcos (numpy) = {np.cos(inputs)}")
print(f"\ttan (numpy) = {np.tan(inputs)}")
Single Value input
	sin (math)  = 0.0015926529164868282
	sin (numpy) = 0.0015926529164868282
	cos (math)  = -0.9999987317275395
	cos (numpy) = -0.9999987317275395
	tan (math)  = -0.001592654936407223
	tan (numpy) = -0.001592654936407223

Multiple Value Input (array/list)
	sin (numpy) = [0.93203909 0.74570521 0.00159265]
	cos (numpy) = [ 0.36235775 -0.66627602 -0.99999873]
	tan (numpy) = [ 2.57215162e+00 -1.11921364e+00 -1.59265494e-03]

cosecant, secant, and cotangent#

The functions csc, sec, and cot are not part of the standard Python math library or numpy. Instead, these values can be found as the reciprocal of the values sin, cos, and tan

csc = 1 / sin

sec = 1 / cos

cot = 1 / tan
import math
import numpy as np

input = 3.14
print("Single Value input")
print(f"\tcsc (math)  = {1 / math.sin(input)}")
print(f"\tcsc (numpy) = {1 / np.sin(input)}")
print(f"\tsec (math)  = {1 / math.cos(input)}")
print(f"\tsec (numpy) = {1 / np.cos(input)}")
print(f"\tcot (math)  = {1 / math.tan(input)}")
print(f"\tcot (numpy) = {1 / np.tan(input)}")

inputs = [1.2, 2.3, 3.14]
print("\Multiple Value Input (array/list)")
print(f"\tcsc (numpy) = {1 / np.sin(inputs)}")
print(f"\tsec (numpy) = {1 / np.cos(inputs)}")
print(f"\tcot (numpy) = {1 / np.tan(inputs)}")
Single Value input
	csc (math)  = 627.8831939138764
	csc (numpy) = 627.8831939138764
	sec (math)  = -1.000001268274069
	sec (numpy) = -1.000001268274069
	cot (math)  = -627.8823975869133
	cot (numpy) = -627.8823975869133
\Multiple Value Input (array/list)
	csc (numpy) = [  1.07291638   1.34101249 627.88319391]
	sec (numpy) = [ 2.7597036  -1.50087947 -1.00000127]
	cot (numpy) = [ 3.88779569e-01 -8.93484463e-01 -6.27882398e+02]
<>:14: SyntaxWarning: invalid escape sequence '\M'
<>:14: SyntaxWarning: invalid escape sequence '\M'
/tmp/ipykernel_2037/1093943048.py:14: SyntaxWarning: invalid escape sequence '\M'
  print("\Multiple Value Input (array/list)")

asin, acos, atan, and atan2#

The inverse trigonometric functions asin, acos, atan, and atan2 are part of the standard Python math library when working with single value inputs. When working with lists and arrays, these functions can be evaluated with the external package numpy. By default, the input and output values are in radians.

import math
import numpy as np

input = 0.5
print("Single Value input")
print(f"\tasin (math)  = {math.asin(input)}")
print(f"\tasin (numpy) = {np.arcsin(input)}")
print(f"\tacos (math)  = {math.acos(input)}")
print(f"\tacos (numpy) = {np.arccos(input)}")
print(f"\tatan (math)  = {math.atan(input)}")
print(f"\tatan (numpy) = {np.arctan(input)}")

inputs = [0.5, 0.75, 0.14]
print("\nMultiple Value Input (array/list)")
print(f"\tasin (numpy) = {np.arcsin(inputs)}")
print(f"\tacos (numpy) = {np.arccos(inputs)}")
print(f"\tatan (numpy) = {np.arctan(inputs)}")
Single Value input
	asin (math)  = 0.5235987755982989
	asin (numpy) = 0.5235987755982989
	acos (math)  = 1.0471975511965979
	acos (numpy) = 1.0471975511965979
	atan (math)  = 0.4636476090008061
	atan (numpy) = 0.4636476090008061

Multiple Value Input (array/list)
	asin (numpy) = [0.52359878 0.84806208 0.14046141]
	acos (numpy) = [1.04719755 0.72273425 1.43033491]
	atan (numpy) = [0.46364761 0.64350111 0.13909594]

sinh, cosh, and tanh#

The hyperbolic trigonometric functions are analogous functions that make use of the hyperbola instead of the circle. The trigonometric functions sinh, cosh, and tanh are part of the standard Python math library when working with single value inputs. When working with lists and arrays, these functions can be evaluated with the external package numpy. By default, the input and output values are in radians.

import math
import numpy as np

input = 3.14
print("Single Value input")
print(f"\tsinh (math)  = {math.sinh(input)}")
print(f"\tsinh (numpy) = {np.sinh(input)}")
print(f"\tcosh (math)  = {math.cosh(input)}")
print(f"\tcosh (numpy) = {np.cosh(input)}")
print(f"\ttanh (math)  = {math.tanh(input)}")
print(f"\ttanh (numpy) = {np.tanh(input)}")

inputs = [1.2, 2.3, 3.14]
print("\nMultiple Value Input (array/list)")
print(f"\tsinh (numpy) = {np.sinh(inputs)}")
print(f"\tcosh (numpy) = {np.cosh(inputs)}")
print(f"\ttanh (numpy) = {np.tanh(inputs)}")
Single Value input
	sinh (math)  = 11.53029203041011
	sinh (numpy) = 11.53029203041011
	cosh (math)  = 11.573574828312076
	cosh (numpy) = 11.573574828312076
	tanh (math)  = 0.9962602049458319
	tanh (numpy) = 0.9962602049458319

Multiple Value Input (array/list)
	sinh (numpy) = [ 1.50946136  4.93696181 11.53029203]
	cosh (numpy) = [ 1.81065557  5.03722065 11.57357483]
	tanh (numpy) = [0.83365461 0.9800964  0.9962602 ]

asinh, acosh, and atanh#

The inverse hyperbolic trigonmetric functions asinh, acosh, and atanh are part of the standard Python math library when working with single value inputs. When working with lists and arrays, these functions can be evaluated with the external package numpy. By default, the input and output values are in radians.

import math
import numpy as np

input = 3.14
print("Single Value input")
print(f"\tasinh (math)  = {math.asinh(input)}")
print(f"\tasinh (numpy) = {np.arcsinh(input)}")
print(f"\tacosh (math)  = {math.acosh(input)}")
print(f"\tacosh (numpy) = {np.arccosh(input)}")
input = 0.5
print(f"\tatanh (math)  = {math.atanh(input)}")
print(f"\tatanh (numpy) = {np.arctanh(input)}")

inputs = [1.5, 1.75, 3.14]
print("\nMultiple Value Input (array/list)")
print(f"\tasinh (numpy) = {np.arcsinh(inputs)}")
print(f"\tacosh (numpy) = {np.arccosh(inputs)}")
inputs = [0.5, 0.75, 0.14]
print(f"\tatanh (numpy) = {np.arctanh(inputs)}")
Single Value input
	asinh (math)  = 1.8618125572133835
	asinh (numpy) = 1.8618125572133835
	acosh (math)  = 1.810991348900196
	acosh (numpy) = 1.810991348900196
	atanh (math)  = 0.5493061443340548
	atanh (numpy) = 0.5493061443340548

Multiple Value Input (array/list)
	asinh (numpy) = [1.19476322 1.32589777 1.86181256]
	acosh (numpy) = [0.96242365 1.15881036 1.81099135]
	atanh (numpy) = [0.54930614 0.97295507 0.14092558]

Algebraic Functions#

sum and prod#

To find the sum or product of a list of values, Python include sum and prod as part of the standard Python library and are also available as well as part of the numpy library

import math
import numpy as np

input = [1.2, 2.3, 3.4, 4.5]
print("sum of input")
print(f"\tsum (standard library) = {sum(input)}")
print(f"\tsum (numpy)            = {np.sum(input)}")

print("\nproduct of input")
print(f"\tprod (math)  = {math.prod(input)}")
print(f"\tprod (numpy) = {np.prod(input)}")
sum of input
	sum (standard library) = 11.4
	sum (numpy)            = 11.4

product of input
	prod (math)  = 42.227999999999994
	prod (numpy) = 42.227999999999994

cumsum and cumprod#

The numpy package can be used to find the cumulative sum or product of a list of values.

import numpy as np

input = [[1, 2, 3], [4, 5, 6]]
print("cumulative sum")
print(f"\tcumsum (numpy) = {np.cumsum(input)}")

print("\ncumulative product")
print(f"\tcumprod (numpy) = {np.cumprod(input)}")
cumulative sum
	cumsum (numpy) = [ 1  3  6 10 15 21]

cumulative product
	cumprod (numpy) = [  1   2   6  24 120 720]

abs#

The standard Python math module includes the function to find the absolute value of a single value. When working with lists and arrays, the values can be evaluated with the external package numpy.

import numpy as np

input = -3.14
print("Single Value input")
print(f"\t(numpy)            {input} = {np.abs(input)}")
print(f"\t(standard library) {input} = {abs(input)}")

inputs = [-1.5, -1.75, -3.14]
print("\nMultiple Value Input (array/list)")
print(f"\t(numpy) {inputs} = {np.abs(inputs)}")
Single Value input
	(numpy)            -3.14 = 3.14
	(standard library) -3.14 = 3.14

Multiple Value Input (array/list)
	(numpy) [-1.5, -1.75, -3.14] = [1.5  1.75 3.14]

avg#

When working with multiple values, the external numpy package can be used to evaluated the average value across the list of values.

import numpy as np

input_value = [1, 2, 3]
print("Single List")
print(f"\t{input_value} = {np.average(input_value)}")

print("List of Lists - Flattened to a Single List")
input_values = [[1, 2, 3], [4, 5, 6]]
print(f"\t{input_values} = {np.mean(input_values)}")

print("List of Lists")
input_values = [[1, 2, 3], [4, 5, 6]]
print(f"\t{input_values} = {np.mean(input_values, axis=1)}")
Single List
	[1, 2, 3] = 2.0
List of Lists - Flattened to a Single List
	[[1, 2, 3], [4, 5, 6]] = 3.5
List of Lists
	[[1, 2, 3], [4, 5, 6]] = [2. 5.]

mod#

The modulo operator (%) can be used to return the remainder from dividing values.

x1 mod x2 = x1 % x2
import numpy as np

x1 = 17
x2 = 3
print("Single Value input")
print(f"\t(standard library) {x1} % {x2}   = {x1 % x2}")
print(f"\t(numpy)            {x1} mod {x2} = {np.mod(x1, x2)}")

x1_values = [17, 4]
x2_values = [3, 2]
print("\nMultiple Value Input (array/list)")
print(f"\t(numpy) {x1_values} mod {x2_values} = {np.mod(x1_values, x2_values)}")
Single Value input
	(standard library) 17 % 3   = 2
	(numpy)            17 mod 3 = 2

Multiple Value Input (array/list)
	(numpy) [17, 4] mod [3, 2] = [2 0]

Degrees and Radians#

The input and output values of trigonometric functions like sin and cos expect radians. Python allows for various functions to convert between radian and degree values, both has part of the standard Python math library and the external numpy package when working with arrays.

import math
import numpy as np

input = 32  # degrees
print("Convert from Degrees to Radians")
print(f"\t(math)  {input} degrees = {math.radians(input)} radians")
print(f"\t(numpy) {input} degrees = {np.deg2rad(input)} radians")
print(f"\t(numpy) {input} degrees = {np.radians(input)} raidans")

input = 0.5585  # radians
print("\nConvert from Radians to Degrees")
print(f"\t(math)  {input} radians = {math.degrees(input)} degrees")
print(f"\t(numpy) {input} radians = {np.rad2deg(input)} degrees")
print(f"\t(numpy) {input} radians = {np.degrees(input)} degrees")
Convert from Degrees to Radians
	(math)  32 degrees = 0.5585053606381855 radians
	(numpy) 32 degrees = 0.5585053606381855 radians
	(numpy) 32 degrees = 0.5585053606381855 raidans

Convert from Radians to Degrees
	(math)  0.5585 radians = 31.999692858056477 degrees
	(numpy) 0.5585 radians = 31.999692858056477 degrees
	(numpy) 0.5585 radians = 31.999692858056477 degrees

Rounding#

Python includes functions to round off a decimal point value to a desired accuracy, either by rounding up, rounding down, or by manually truncating the decimal value.

round, around, floor, ceil#

import math
import numpy as np

input = 3.1415926535

print("Rounding Up")
print(f"\t(math) {input} to next nearest integer  = {math.ceil(input)}")
print(f"\t(numpy) {input} to 3 decimal points     = {np.around(input, 3)}")

print("\nRounding Down")
print(f"\t(math) {input} to nearest integer = {math.floor(input)}")

print("\nRound to Closest Integer")
print(f"\t(standard library) {input} to closest integer = {round(input)}")
print(f"\t(standard library) {input} to closest integer = {int(input)}")
Rounding Up
	(math) 3.1415926535 to next nearest integer  = 4
	(numpy) 3.1415926535 to 3 decimal points     = 3.142

Rounding Down
	(math) 3.1415926535 to nearest integer = 3

Round to Closest Integer
	(standard library) 3.1415926535 to closest integer = 3
	(standard library) 3.1415926535 to closest integer = 3

truncate#

Truncate will cut off the decimal points after a certain value, without rounding up or down

input = 3.1415926535

# Truncate decimal points after 3 points
decimal_values = str(input).split(".")
truncate_decimal = decimal_values[1][:3]
truncate_output = float(decimal_values[0] + "." + truncate_decimal)
print(truncate_output)
3.141

Exponents and Logarithms#

exp#

Raise e (e approximately = 2.71828) to a given power x

exp(x) = e^x

The exponential is both part of the standard Python math library for single values and can be calculated for multiple values in a list with numpy

import math
import numpy as np

power = 3.2
print("Single Value input")
print(f"\t(math)  e^{power} = {math.exp(power)}")
print(f"\t(numpy) e^{power} = {np.exp(power)}")

power_list = [1.2, 2.2, 3.2]
print("\nMultiple Value Input (array/list)")
print(f"\t(numpy) e^{power_list} = {np.exp(power_list)}")
Single Value input
	(math)  e^3.2 = 24.532530197109352
	(numpy) e^3.2 = 24.532530197109352

Multiple Value Input (array/list)
	(numpy) e^[1.2, 2.2, 3.2] = [ 3.32011692  9.0250135  24.5325302 ]

log, log10, and log2#

Python includes many different functions to calculate the logarithm with various bases of a given value, with the standard Python math library for single values and the arrays/lists with numpy

import math
import numpy as np

print("Single Value input (Base 10)")
input = 3.2
base = 10
print(f"\tlog base 10 of {input} (math.log10) = {math.log10(input)}")
print(f"\tlog base {base} of {input} (math.log)   = {math.log(input, base)}")
print(f"\tlog base 10 of {input} (np.log10)   = {np.log10(input)}")

print("\nSingle Value input (Base 2)")
input = 3.2
base = 2
print(f"\tlog base 2 of {input} (math.log2) = {math.log2(input)}")
print(f"\tlog base {base} of {input} (math.log)  = {math.log(input, base)}")
print(f"\tlog base 2 of {input} (np.log2)   = {np.log2(input)}")

print("\nSingle Value input (Base e)")
input = 3.2
base = math.e
print(f"\tlog base e of {input} (math.log) = {math.log(input)}")
print(f"\tlog base e of {input} (math.log) = {math.log(input, base)}")
print(f"\tlog base e of {input} (np.log)   = {np.log(input)}")

input_list = [1.2, 2.2, 3.2]
print("\nMultiple Value Input (array/list)")
print("\tBase 10")
print(f"\t\tlog10 (np.log10) = {np.log10(input_list)}")
print("\tBase 2")
print(f"\t\tlog2 (np.log2)   = {np.log2(input_list)}")
print("\tBase e")
print(f"\t\tlog (np.log)     = {np.log(input_list)}")
Single Value input (Base 10)
	log base 10 of 3.2 (math.log10) = 0.505149978319906
	log base 10 of 3.2 (math.log)   = 0.5051499783199059
	log base 10 of 3.2 (np.log10)   = 0.505149978319906

Single Value input (Base 2)
	log base 2 of 3.2 (math.log2) = 1.6780719051126378
	log base 2 of 3.2 (math.log)  = 1.6780719051126378
	log base 2 of 3.2 (np.log2)   = 1.6780719051126378

Single Value input (Base e)
	log base e of 3.2 (math.log) = 1.1631508098056809
	log base e of 3.2 (math.log) = 1.1631508098056809
	log base e of 3.2 (np.log)   = 1.1631508098056809

Multiple Value Input (array/list)
	Base 10
		log10 (np.log10) = [0.07918125 0.34242268 0.50514998]
	Base 2
		log2 (np.log2)   = [0.26303441 1.13750352 1.67807191]
	Base e
		log (np.log)     = [0.18232156 0.78845736 1.16315081]

Sorting#

Python includes functions to organize and sort lists of numbers or strings

Functions to sort lists and arrays are part of the standard Python library as well as numpy

Sorting in Python and Numpy#

Python has two similar sorting functions: list.sort() and sorted()

list.sort() reorganizes a numerical or string list in-place, but returns None, while sorted() creates a new copy of the list with the sorted elements.

lst = [2, 1, 3]
lst.sort()
print(lst)
>> [1, 2, 3]
print(lst.sort())
>> None

lst = [2, 1, 3]
new_sorted_list = sorted(lst)
print(lst)
>> [2, 1, 3]
print(new_sorted_list)
>> [1, 2, 3]

The numpy.sort() function works like the sorted function, which creates and returns a sorted array of the original list

import numpy as np
lst = [2, 1, 3]
new_sorted_list = np.sort(lst)
print(lst)
>> [2, 1, 3]
print(new_sorted_list)
>> [1 2 3]
import numpy as np

input_values = ["mango", "egg", "taco", "tea", "milkshake", "cheese"]
print("List of Strings")
print(f"\t(standard library) = {sorted(input_values)}")
print(f"\t(numpy)            = {np.sort(input_values)}")

print("\nList of Numbers")
input_values = [3.14, -1.2, 0.2, 10, 100, 49]
print(f"\t(standard library) = {sorted(input_values)}")
print(f"\t(numpy)            = {np.sort(input_values)}")
List of Strings
	(standard library) = ['cheese', 'egg', 'mango', 'milkshake', 'taco', 'tea']
	(numpy)            = ['cheese' 'egg' 'mango' 'milkshake' 'taco' 'tea']

List of Numbers
	(standard library) = [-1.2, 0.2, 3.14, 10, 49, 100]
	(numpy)            = [ -1.2    0.2    3.14  10.    49.   100.  ]

Curated Resources#

To learn more about working with math in Python, we suggest: