Math

Functions of multidimensional arguments:

flatten(array) Flatten an array of arbitrary dimension.
mesh(ranges, nbins) Generate equally spaced mesh of nbins cells in the given range.
md_map(f, array) Multidimensional map.
refine_mesh(arr, refinement) Refine (subdivide) one-dimensional mesh arr.

Functions of scalar and multidimensional arguments:

clip(a, interval) Clip (limit) the value.
isclose(a, b[, rel_tol, abs_tol]) Return True if a and b are approximately equal, and False otherwise.

Elements:

Mean([start, pass_on_empty]) Calculate mean (average) of input values.
Sum([start]) Calculate sum of input values.

3-dimensional vector:

vector3(v) 3-dimensional vector with Cartesian and spherical coordinates.

Functions of multidimensional arguments

flatten(array)[исходный код]

Flatten an array of arbitrary dimension.

array must be list or a tuple (can be nested). Depth-first flattening is used.

Return an iterator over the flattened array.

Examples:

>>> arr = [1, 2, 3]
>>> list(flatten(arr)) == arr
True
>>> arr = [[1, 2, 3, [4]], 5, [[6]], 7]
>>> list(flatten(arr))
[1, 2, 3, 4, 5, 6, 7]
>>> arr = [[1, 2, [3], 4], 5, [[6]], 7]
>>> list(flatten(arr))
[1, 2, 3, 4, 5, 6, 7]
mesh(ranges, nbins)[исходный код]

Generate equally spaced mesh of nbins cells in the given range.

Параметры:
  • ranges – a pair of (min, max) values for 1-dimensional range, or a list of ranges in corresponding dimensions.
  • nbins – number of bins for 1-dimensional range, or a list of number of bins in corresponding dimensions.
>>> from lena.math import mesh
>>> mesh((0, 1), 2)
[0, 0.5, 1]
>>> mesh(((0, 1), (10, 12)), (1, 2))
[[0, 1], [10, 11.0, 12]]

Note that because of rounding errors two meshes should not be naively compared, they will probably appear different. One should use isclose for comparison.

>>> from lena.math import isclose
>>> isclose(mesh((0, 1), 10),
...         [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
True
md_map(f, array)[исходный код]

Multidimensional map.

Return function f mapped to contents of a multidimensional array. f is a function of one argument.

Array must be a list of (possibly nested) lists. Its contents remain unchanged. Returned array has same dimensions as the initial one. If array is not a list, LenaTypeError is raised.

>>> from lena.math import md_map
>>> arr = [-1, 1, 0]
>>> md_map(abs, arr)
[1, 1, 0]
>>> arr = [[0, -1], [2, 3]]
>>> md_map(abs, arr)
[[0, 1], [2, 3]]
refine_mesh(arr, refinement)[исходный код]

Refine (subdivide) one-dimensional mesh arr.

refinement is the number of subdivisions. It must be not less than 1.

Note that to create a new mesh may be faster. Use this function only for convenience.

Functions of scalar and multidimensional arguments

clip(a, interval)[исходный код]

Clip (limit) the value.

Given an interval (a_min, a_max), values of a outside the interval are clipped to the interval edges. For example, if an interval of [0, 1] is specified, values smaller than 0 become 0, and values larger than 1 become 1.

>>> clip(-1, (0, 1))
0
>>> # tuple looks better, but list can be used too
>>> clip(2, [0, 1])
1
>>> clip(0.5, (0, 1))
0.5

If a_min > a_max or if interval has length more than 2, LenaValueError is raised. If interval is not a container, LenaTypeError is raised.

isclose(a, b, rel_tol=1e-09, abs_tol=0.0)[исходный код]

Return True if a and b are approximately equal, and False otherwise.

rel_tol is the relative tolerance. It is multiplied by the greater of the magnitudes of the two arguments; as the values get larger, so does the allowed difference between them while still considering them close.

abs_tol is the absolute tolerance. If the difference is less than either of those tolerances, the values are considered equal.

a and b must be either numbers or lists/tuples of same dimensions (may be nested), or have a method isclose. Otherwise LenaTypeError is raised. For containers, isclose is called elementwise. If every corresponding element is close, the containers are close. Dimensions are not checked to be equal.

First, a and b are checked if any of them has isclose method. If a and b both have isclose method, then they must both return True to be close. Otherwise, if only one of a or b has isclose method, it is called.

Special values of NaN, inf, and -inf are not supported.

>>> isclose(1, 2)
False
>>> isclose([1, 2, 3], (1, 2., 3))
True

This function for scalar numbers appeared in math module in Python 3.5.

Elements

Elements for mathematical calculations.

class Mean(start=0, pass_on_empty=False)[исходный код]

Calculate mean (average) of input values.

start is the initial value of sum.

If pass_on_empty is True, then if nothing was filled, don’t yield anything. By default it raises an error (see compute()).

compute()[исходный код]

Calculate mean and yield.

If the current context is not empty, yield (mean, context). Otherwise yield only mean.

If no values were filled (count is zero), mean can’t be calculated and LenaZeroDivisionError is raised. This can be changed to yielding nothing if pass_on_empty was initialized to True.

fill(value)[исходный код]

Fill self with value.

The value can be a (data, context) pair. The last context value (if missing, it is considered empty) is saved for output.

reset()[исходный код]

Reset sum, count and context.

Sum is reset to start value, count to zero and context to {}.

class Sum(start=0)[исходный код]

Calculate sum of input values.

start is the initial value of sum.

compute()[исходный код]

Calculate the sum and yield.

If the current context is not empty, yield (sum, context). Otherwise yield only sum.

fill(value)[исходный код]

Fill self with value.

The value can be a (data, context) pair. The last context value (considered empty if missing) sets the current context.

reset()[исходный код]

Reset sum and context.

Sum is reset to start value and context to {}.

3-dimensional vector

vector3 is a 3-dimensional vector with float coordinates. It supports spherical coordinates and basic vector operations.

Initialization, vector addition and scalar multiplication create new vectors:

>>> v1 = vector3([0, 1, 2])
>>> v2 = vector3([3, 4, 5])
>>> v1 + v2
vector3([3.0, 5.0, 7.0])
>>> v1 - v2
vector3([-3.0, -3.0, -3.0])
>>> 3 * v1
vector3([0.0, 3.0, 6.0])
>>> v1 * 3
vector3([0.0, 3.0, 6.0])

Vector attributes can be set and read. Vectors can be tested for exact or approximate equality with == and isclose method.

>>> v2.z = 0
>>> v2
vector3([3.0, 4.0, 0.0])
>>> v2.r = 10
>>> v2 == vector3([6, 8, 0])
True
>>> v2.theta = 0
>>> v2.isclose(vector3([0, 0, 10]))
True
>>> from math import pi
>>> v2.phi = 0
>>> v2.theta = pi/2.
>>> v2.isclose(vector3([10, 0, 0]))
True
class vector3(v)[исходный код]

3-dimensional vector with Cartesian and spherical coordinates.

Create vector3 from Cartesian coordinates.

v should be a container of size 3 (will be transformed to a list of floats).

Attributes

vector3 has usual vector attributes: x, y, z and spherical coordinates r, phi, theta.

They are connected through this formula:

\begin{gather*} \begin{aligned} x & = r * \cos(\phi) * \sin(\theta),\\ y & = r * \sin(\phi) * \sin(\theta),\\ z & = r * \cos(\theta),\\ \end{aligned} \end{gather*}

\(\phi \in [0, 2 \pi], \theta \in [0, \pi]\).

\(\phi\) and \(\phi + 2 \pi\) are equal.

Cartesian coordinates can be obtained and set through indices starting from 0 (v.x = v[0]). In this respect, vector3 behaves as a container of length 3.

Only Cartesian coordinates are stored internally (spherical coordinates are recomputed each time).

Attributes can be got and set using subscript or a function set*, get*. For example:

>>> v = vector3([1, 0, 0])
>>> v.x = 0
>>> x = v.getx()
>>> v.setx(x+1)
>>> v
vector3([1.0, 0.0, 0.0])

\(r^2\) and \(\cos\theta\) can be obtained with methods getr2() and getcostheta().

Comparisons

For elementwise comparison of two vectors one can use „==“ and „!=“ operators. Because of rounding errors, this can often show two same vectors as different. In general, it is recommended to use approximate comparison with isclose method.

Comparisons like „>“, „<=“ are all prohibited: if one tries to use these operators, LenaTypeError is raised.

Truth testing

vector3 is non-zero if its magnitude (r) is not 0.

Vector operations

3-dimensional vectors can be added and subtracted, multiplied or divided by a scalar. Multiplication by a scalar can be written from any side of the vector (c*v or v*c). A vector can also be negated (-v).

For other vector operations see methods below.

classmethod fromspherical(r, phi, theta)[исходный код]

Construct vector3 from spherical coordinates.

r is magnitude, phi is azimuth angle from 0 to \(2 * \pi\), theta is polar angle from 0 (z = 1) to \(\pi\) (z = -1).

>>> from math import pi
>>> vector3.fromspherical(1, 0, 0)
vector3([0.0, 0.0, 1.0])
>>> vector3.fromspherical(1, 0, pi).isclose(vector3([0, 0, -1]))
True
>>> vector3([1, 0, 0]).isclose(vector3.fromspherical(1, 0, pi/2))
True
>>> vector3.fromspherical(1, pi, 0).isclose(vector3([0.0, 0.0, 1.0]))
True
>>> vector3.fromspherical(1, pi/2, pi/2).isclose(vector3([0.0, 1.0, 0.0]))
True
angle(B)[исходный код]

The angle between self and B, in radians.

>>> v1 = vector3([0, 3, 4])
>>> v2 = vector3([0, 3, 4])
>>> v1.angle(v2)
0.0
>>> v2 = vector3([0, -4, 3])
>>> from math import degrees
>>> degrees(v1.angle(v2))
90.0
>>> v2 = vector3([0, -30, -40])
>>> degrees(v1.angle(v2))
180.0
cosine(B)[исходный код]

Cosine of the angle between self and B.

>>> v1 = vector3([0, 3, 4])
>>> v2 = vector3([0, 3, 4])
>>> v1.cosine(v2)
1.0
>>> v2 = vector3([0, -4, 3])
>>> v1.cosine(v2)
0.0
>>> v2 = vector3([0, -30, -40])
>>> v1.cosine(v2)
-1.0
cross(B)[исходный код]

The cross product between self and B, \(A\times B\).

>>> v1 = vector3([0, 3, 4])
>>> v2 = vector3([0, 1, 0])
>>> v1.cross(v2)
vector3([-4.0, 0.0, 0.0])
dot(B)[исходный код]

The scalar product between self and B, \(A \cdot B\).

classmethod fromspherical(r, phi, theta)[исходный код]

Construct vector3 from spherical coordinates.

r is magnitude, phi is azimuth angle from 0 to \(2 * \pi\), theta is polar angle from 0 (z = 1) to \(\pi\) (z = -1).

>>> from math import pi
>>> vector3.fromspherical(1, 0, 0)
vector3([0.0, 0.0, 1.0])
>>> vector3.fromspherical(1, 0, pi).isclose(vector3([0, 0, -1]))
True
>>> vector3([1, 0, 0]).isclose(vector3.fromspherical(1, 0, pi/2))
True
>>> vector3.fromspherical(1, pi, 0).isclose(vector3([0.0, 0.0, 1.0]))
True
>>> vector3.fromspherical(1, pi/2, pi/2).isclose(vector3([0.0, 1.0, 0.0]))
True
isclose(B, rel_tol=1e-09, abs_tol=0.0)[исходный код]

Test whether two vectors are approximately equal.

Parameter semantics is the same as for the general isclose.

>>> v1 = vector3([0, 1, 2])
>>> v1.isclose(vector3([1e-11, 1, 2]))
True
norm()[исходный код]

\(A/|A|\), a unit vector in the direction of self.

>>> v1 = vector3([0, 3, 4])
>>> n1 = v1.norm()
>>> v1n = vector3([0, 0.6, 0.8])
>>> (n1 - v1n)._mag() < 1e-6
True
proj(B)[исходный код]

The vector projection of self along B.

A.proj(B) = \((A \cdot norm(B)) norm(B)\).

>>> v1 = vector3([0, 3, 4])
>>> v2 = vector3([0, 2, 0])
>>> v1.proj(v2)
vector3([0.0, 3.0, 0.0])
rotate(theta, B)[исходный код]

Rotate self around B through angle theta.

From the position where B points towards us, the rotation is counterclockwise (the right hand rule).

>>> v1 = vector3([1, 1, 1.0])
>>> v2 = vector3([0, 1, 0.0])
>>> from math import pi
>>> vrot = v1.rotate(pi/2, v2)
>>> vrot.isclose(vector3([1.0, 1.0, -1.0]))
True
scalar_proj(B)[исходный код]

The scalar projection of self along B.

A.scalar_proj(B) = \(A \cdot norm(B)\).

>>> v1 = vector3([0, 3, 4])
>>> v2 = vector3([0, 2, 0])
>>> v1.scalar_proj(v2)
3.0