General Applied Math#

Warning

This is not meant to be a standalone notebook. This notebook is part of the process we have for adding entries to the NCL Index and is not meant to be used as tutorial or example code.

Functions covered#

NCL code#

; abs
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/abs.shtml
f = -5
abs_f = abs(f)  ; abs_f = 5
print(abs_f)

f_array = (/-3, -2, -1, 0, 1, 2, 3/)
abs_f = abs(f_array)
print(abs_f)
; (0)	3
; (1)	2
; (2)	1
; (3)	0
; (4)	1
; (5)	2
; (6)	3

; avg
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/avg.shtml
f = (/ (/1,2,3/), (/4,5,6/)/)
avg_f = avg(f)  ; avg_f = 3.5
print(avg_f)

; ceil
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/ceil.shtml
f = 6.4
ceil_f = ceil(f)  ; ceil_f = 7
print(ceil_f)

; cumsum
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/cumsum.shtml
f = (/1,2,3,4,5/)
cumsum_f = cumsum(f, 0) ; cumsum_f = (/1  3  6  10  15/)
print(cumsum_f)
; (0)	1
; (1)	3
; (2)	6
; (3)	10
; (4)	15

; decimalPlaces
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Contributed/decimalPlaces.shtml
f = 12.345678
decimalPlaces_f = decimalPlaces(f, 2, True)  ; decimalPlaces_f = 12.35

; exp
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/exp.shtml
f = -0.2
exp_f = exp(f)  ; exp_f = 0.8187308
print(exp_f)

; fabs
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/fabs.shtml
iarray = (/-3.5, -2.2, -1.0, 0.0, 1.2, 2.4, 3.9/)
jarray = fabs(iarray)  ; jarray = (/3.5, 2.2, 1, 0, 1.2, 2.4, 3.9/)
print(jarray)

; floor
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/floor.shtml
f = -6.4
floor_f  = floor(f)  ; floor_f  = 6
print(floor_f )

; get_d2r
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Contributed/get_d2r.shtml
d2r = get_d2r("double")  ; d2r = 0.0174532925199433

; get_r2d
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Contributed/get_r2d.shtml
r2d = get_r2d("double")  ; r2d = 57.29577951308232

; get_pi
; Adapted from https://www.ncl.ucar.edu/D
pi = get_pi("double")  ; pi = 3.141592653589793

; log
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/log.shtml
f = 3.6
log_f = log(f)  ; log_f = 1.280934
print(log_f

; log10
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/log10.shtml
f = 3.4
log10_f = log10(f)  ; log10_f = 0.5314789
print(log10_f)

; max
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/max.shtml
f = (/2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7, 9.8/)
max_f = max(f)  ; max_f = 9.8
print(max_f)

; min
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/min.shtml
f = (/2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7, 9.8/)
min_f = min(f)  ; min_f = 2.1
print(min_f)

; mod
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Contributed/mod.shtml
mod_f = mod(17, 3)  ; mod_f = 2
print(mod_f)

; product
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/product.shtml
x = (/ (/1,-99/), (/3,4/), (/-99,6/) /)
x@_FillValue = -99
xproduct = product(x)  ; xproduct = 72
print(xproduct)

; qsort
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/qsort.shtml
x = (/4.3, 0.9, 5.2, 7.7, 2.3, -4.7, -9.1/)
qsort(x)
print(x)  ; x = (/-9.1, -4.7, 0.9, 2.3, 4.3, 5.2, 7.7/)

; round
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/round.shtml
f = 5.7
round_f = round(f, 0)
print(round_f)  ; round_f = 6

; sign_matlab
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Contributed/sign_matlab.shtml
i = (/-3.5, 0.0, 1.2/)
matlab_i = sqrt(matlab_i)
print(matlab_i)  ; matlab_i = (/-1, 0, 1/)

; sqrt
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/sqrt.shtml
f = 12.5
sqrt_f = sqrt(f)
print(sqrt_f)  ; sqrt = 3.535534

; sqsort
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/sqsort.shtml
s = (/"Auf Wiedersehen", "Goodbye", "Hasta Luego", "Ciao"/)
sqsort(s)
print(s)  ; s= (/"Auf Wiedersehen", "Ciao", "Goodbye", "Hasta Luego"/)

; sum
; Adapted from https://www.ncl.ucar.edu/Document/Functions/Built-in/sum.shtml
x = (/ (/1,-99/), (/3,4/), (/-99,6/) /)
x@_FillValue = -99
xsum  = sum(x)  ; xsum  = 14
print(xsum)

Python Functionality#

import math
import numpy as np

results_math = {}
results_np = {}

# abs
f = -5
results_math["abs"] = abs(f)
results_np["abs"] = np.absolute(f)

# avg
f = [[1, 2, 3], [4, 5, 6]]
results_np["avg"] = np.mean(f)

# ceil
f = 6.4
results_math["ceil"] = math.ceil(f)
results_np["ceil"] = np.ceil(f)

# cumsum
f = [1, 2, 3, 4, 5]
results_np["cumsum"] = np.cumsum(f, axis=0)

# decimalPlaces
f = 12.345678
results_math["decimalPlaces"] = round(f, 2)
results_np["decimalPlaces"] = np.round(f, 2)

# exp
f = -0.2
results_math["exp"] = math.exp(f)
results_np["exp"] = np.exp(f)

# fabs
f = [-3.5, -2.2, -1.0, 0.0, 1.2, 2.4, 3.9]
results_np["fabs"] = np.absolute(f)

# floor
f = 6.4
results_math["floor"] = math.floor(f)
results_np["floor"] = np.floor(f)

# get_d2r
results_math["get_d2r"] = math.pi / 180
results_np["get_d2r"] = np.pi / 180

# get_r2d
results_math["get_r2d"] = 180 / math.pi
results_np["get_r2d"] = 180 / np.pi

# get_pi
results_math["get_pi"] = math.pi
results_np["get_pi"] = np.pi

# log
f = 3.6
results_math["log"] = math.log(f)
results_np["log"] = np.log(f)

# log10
f = 3.4
results_math["log10"] = math.log10(f)
results_np["log10"] = np.log10(f)

# max
f = [2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7, 9.8]
results_math["max"] = max(f)
results_np["max"] = np.max(f)

# min
f = [2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7, 9.8]
results_math["min"] = min(f)
results_np["min"] = np.min(f)

# mod
results_math["mod"] = 17 % 3
results_np["mod"] = np.mod([17], [3])[0]

# product
f = [1, 3, 4, 6]
results_math["product"] = math.prod(f)
results_np["product"] = np.prod(f)

# qsort
f = [4.3, 0.9, 5.2, 7.7, 2.3, -4.7, -9.1]
results_math["qsort"] = sorted(f)
h = [4.3, 0.9, 5.2, 7.7, 2.3, -4.7, -9.1]
results_np["qsort"] = np.sort(h)

# round
f = 5.7
results_math["round"] = round(f)
results_np["round"] = np.round(f)

# sign_matlab
f = [-3.5, 0.0, 1.2]
results_np["sign_matlab"] = np.sign(f)

# sqrt
f = 12.5
results_math["sqrt"] = math.sqrt(f)
results_np["sqrt"] = np.sqrt(f)

# sqsort
s = ["Auf Wiedersehen", "Goodbye", "Hasta Luego", "Ciao"]
results_math["sqsort"] = sorted(s)
q = ["Auf Wiedersehen", "Goodbye", "Hasta Luego", "Ciao"]
results_np["sqsort"] = np.sort(q)

# sum
f = [1, 3, 4, 6]
results_math["sum"] = sum(f)
results_np["sum"] = np.sum(f)

Comparison#

ncl_results = {
    "abs": 5,
    "avg": 3.5,
    "ceil": 7,
    "cumsum": np.array([1, 3, 6, 10, 15]),
    "decimalPlaces": 12.35,
    "exp": 0.8187308,
    "fabs": [3.5, 2.2, 1, 0, 1.2, 2.4, 3.9],
    "floor": 6,
    "get_d2r": 0.0174532925199433,
    "get_r2d": 57.29577951308232,
    "get_pi": 3.141592653589793,
    "log": 1.280934,
    "log10": 0.5314789,
    "max": 9.8,
    "min": 2.1,
    "mod": 2,
    "product": 72,
    "qsort": np.array([-9.1, -4.7, 0.9, 2.3, 4.3, 5.2, 7.7]),
    "round": 6,
    "sign_matlab": [-1, 0, 1],
    "sqsort": np.array(["Auf Wiedersehen", "Ciao", "Goodbye", "Hasta Luego"]),
    "sqrt": 3.535534,
    "sum": 14,
}

for key in ncl_results.keys():
    if key == "sqsort":
        # compare string outputs
        assert np.all(ncl_results[key] == results_math[key])
        assert np.all(ncl_results[key] == results_np[key])
        assert np.all(results_math[key] == results_np[key])
    elif key in results_math.keys() and key in results_np.keys():
        print(
            f"{key}: \n\tncl:\t\t{ncl_results[key]}\n\tpython (math):\t{results_math[key]}\n\tpython (numpy):\t{results_np[key]}\n"
        )
        try:
            assert math.isclose(
                results_np[key], results_math[key], rel_tol=1e-15
            )  # within 15 decimal points
            assert math.isclose(
                ncl_results[key], results_math[key], rel_tol=1e-06
            )  # within 6 decimal points
            assert math.isclose(
                ncl_results[key], results_np[key], rel_tol=1e-06
            )  # within 6 decimal points
        except Exception:
            assert np.all(
                np.isclose(ncl_results[key], results_math[key], rtol=1e-06)
            )  # within 6 decimal points
            assert np.all(
                np.isclose(results_np[key], results_math[key], rtol=1e-15)
            )  # within 15 decimal points
            assert np.all(
                np.isclose(ncl_results[key], results_np[key], rtol=1e-06)
            )  # within 6 decimal points
    elif key in results_math.keys() and key not in results_np.keys():
        print(
            f"{key}: \n\tncl:\t\t{ncl_results[key]}\n\tpython (math):\t{results_math[key]}\n"
        )
        try:
            assert math.isclose(
                ncl_results[key], results_math[key], rel_tol=1e-06
            )  # within 6 decimal points
        except Exception:
            assert np.all(
                np.isclose(ncl_results[key], results_np[key], rtol=1e-06)
            )  # within 6 decimal points
    elif key in results_np.keys() and key not in results_math.keys():
        print(
            f"{key}: \n\tncl:\t\t{ncl_results[key]}\n\tpython (numpy):\t{results_np[key]}\n"
        )
        try:
            assert math.isclose(
                ncl_results[key], results_np[key], rel_tol=1e-06
            )  # within 6 decimal points
        except Exception:
            assert np.all(
                np.isclose(ncl_results[key], results_np[key], rtol=1e-06)
            )  # within 6 decimal points
abs: 
	ncl:		5
	python (math):	5
	python (numpy):	5

avg: 
	ncl:		3.5
	python (numpy):	3.5

ceil: 
	ncl:		7
	python (math):	7
	python (numpy):	7.0

cumsum: 
	ncl:		[ 1  3  6 10 15]
	python (numpy):	[ 1  3  6 10 15]

decimalPlaces: 
	ncl:		12.35
	python (math):	12.35
	python (numpy):	12.35

exp: 
	ncl:		0.8187308
	python (math):	0.8187307530779818
	python (numpy):	0.8187307530779818

fabs: 
	ncl:		[3.5, 2.2, 1, 0, 1.2, 2.4, 3.9]
	python (numpy):	[3.5 2.2 1.  0.  1.2 2.4 3.9]

floor: 
	ncl:		6
	python (math):	6
	python (numpy):	6.0

get_d2r: 
	ncl:		0.0174532925199433
	python (math):	0.017453292519943295
	python (numpy):	0.017453292519943295

get_r2d: 
	ncl:		57.29577951308232
	python (math):	57.29577951308232
	python (numpy):	57.29577951308232

get_pi: 
	ncl:		3.141592653589793
	python (math):	3.141592653589793
	python (numpy):	3.141592653589793

log: 
	ncl:		1.280934
	python (math):	1.2809338454620642
	python (numpy):	1.2809338454620642

log10: 
	ncl:		0.5314789
	python (math):	0.5314789170422551
	python (numpy):	0.5314789170422551

max: 
	ncl:		9.8
	python (math):	9.8
	python (numpy):	9.8

min: 
	ncl:		2.1
	python (math):	2.1
	python (numpy):	2.1

mod: 
	ncl:		2
	python (math):	2
	python (numpy):	2

product: 
	ncl:		72
	python (math):	72
	python (numpy):	72

qsort: 
	ncl:		[-9.1 -4.7  0.9  2.3  4.3  5.2  7.7]
	python (math):	[-9.1, -4.7, 0.9, 2.3, 4.3, 5.2, 7.7]
	python (numpy):	[-9.1 -4.7  0.9  2.3  4.3  5.2  7.7]

round: 
	ncl:		6
	python (math):	6
	python (numpy):	6.0

sign_matlab: 
	ncl:		[-1, 0, 1]
	python (numpy):	[-1.  0.  1.]

sqrt: 
	ncl:		3.535534
	python (math):	3.5355339059327378
	python (numpy):	3.5355339059327378

sum: 
	ncl:		14
	python (math):	14
	python (numpy):	14

Differences#

for key in ncl_results.keys():
    if key == "sqsort":
        # ignore string comparison
        continue
    elif key in results_math.keys() and key in results_np.keys():
        print(f"{key}:")
        print(f"\t{results_math[key] - ncl_results[key]}")
        print(f"\t{results_np[key] - ncl_results[key]}")
    elif key in results_math.keys() and key not in results_np.keys():
        print(f"{key}:")
        print(f"\t{results_math[key] - ncl_results[key]}")
    elif key in results_np.keys() and key not in results_math.keys():
        print(f"{key}:")
        print(f"\t{results_np[key] - ncl_results[key]}")

for key in ncl_results.keys() & results_math.keys() & results_np.keys():
    if key == "sqsort":
        # ignore string comparison
        continue
    else:
        print(f"{key}:")
        print(f"\t{results_math[key] - ncl_results[key]}")
        print(f"\t{results_np[key] - ncl_results[key]}")
abs:
	0
	0
avg:
	0.0
ceil:
	0
	0.0
cumsum:
	[0 0 0 0 0]
decimalPlaces:
	0.0
	0.0
exp:
	-4.6922018159811785e-08
	-4.6922018159811785e-08
fabs:
	[0. 0. 0. 0. 0. 0. 0.]
floor:
	0
	0.0
get_d2r:
	-3.469446951953614e-18
	-3.469446951953614e-18
get_r2d:
	0.0
	0.0
get_pi:
	0.0
	0.0
log:
	-1.5453793578146247e-07
	-1.5453793578146247e-07
log10:
	1.704225516263591e-08
	1.704225516263591e-08
max:
	0.0
	0.0
min:
	0.0
	0.0
mod:
	0
	0
product:
	0
	0
qsort:
	[0. 0. 0. 0. 0. 0. 0.]
	[0. 0. 0. 0. 0. 0. 0.]
round:
	0
	0.0
sign_matlab:
	[0. 0. 0.]
sqrt:
	-9.406726242389141e-08
	-9.406726242389141e-08
sum:
	0
	0
get_pi:
	0.0
	0.0
exp:
	-4.6922018159811785e-08
	-4.6922018159811785e-08
product:
	0
	0
sqrt:
	-9.406726242389141e-08
	-9.406726242389141e-08
min:
	0.0
	0.0
get_d2r:
	-3.469446951953614e-18
	-3.469446951953614e-18
abs:
	0
	0
log:
	-1.5453793578146247e-07
	-1.5453793578146247e-07
qsort:
	[0. 0. 0. 0. 0. 0. 0.]
	[0. 0. 0. 0. 0. 0. 0.]
max:
	0.0
	0.0
decimalPlaces:
	0.0
	0.0
get_r2d:
	0.0
	0.0
floor:
	0
	0.0
log10:
	1.704225516263591e-08
	1.704225516263591e-08
round:
	0
	0.0
sum:
	0
	0
mod:
	0
	0
ceil:
	0
	0.0