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 (x, y, z) |
3-dimensional vector with Cartesian, spherical and cylindrical coordinates. |
Functions of multidimensional arguments¶
-
flatten
(array)[source]¶ 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)[source]¶ Generate equally spaced mesh of nbins cells in the given range.
Parameters: - 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)[source]¶ 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]]
Functions of scalar and multidimensional arguments¶
-
clip
(a, interval)[source]¶ 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)[source]¶ Return
True
if a and b are approximately equal, andFalse
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)[source]¶ 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
()[source]¶ 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.
-
-
class
Sum
(start=0)[source]¶ Calculate sum of input values.
start is the initial value of sum.
-
compute
()[source]¶ Calculate the sum and yield.
If the current context is not empty, yield (sum, context). Otherwise yield only sum.
-
3-dimensional vector¶
vector3 is a 3-dimensional vector. It supports spherical and cylindrical 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, 5, 7)
>>> v1 - v2
vector3(-3, -3, -3)
>>> 3 * v1
vector3(0, 3, 6)
>>> v1 * 3
vector3(0, 3, 6)
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, 4, 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
Vector components are floats in general. Other values can be used as well, if that makes sense for the operations used (types are not tested during the initialization). For example, vectors in the examples above have integer coordinates, which will become floats if we multiply them by floats, divide or maybe rotate. For usual vector additions or subtractions, though, their coordinates will remain integer.
-
class
vector3
(x, y, z)[source]¶ 3-dimensional vector with Cartesian, spherical and cylindrical coordinates.
Create a vector from Cartesian coordinates x, y, z.
Attributes
vector3 has usual vector attributes x, y, z, spherical coordinates r, phi, theta and cylindrical ones rho and rho2 (rho^2 = x^2 + y^2).
Spherical and Cartesian coordinates are connected by 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 and other 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)
\(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)[source]¶ 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)[source]¶ 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)[source]¶ 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)[source]¶ 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)
-
classmethod
fromspherical
(r, phi, theta)[source] 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)[source]¶ 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
()[source]¶ \(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).r < 1e-6 True
-
proj
(B)[source]¶ 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)[source]¶ 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) >>> v2 = vector3(0, 1, 0) >>> from math import pi >>> vrot = v1.rotate(pi/2, v2) >>> vrot.isclose(vector3(1, 1, -1)) True
-
classmethod