Math¶
Functions of multidimensional arguments:
|
Flatten an array of arbitrary dimension. |
|
Generate equally spaced mesh of nbins cells in the given range. |
|
Multidimensional map. |
|
Refine (subdivide) one-dimensional mesh arr. |
Functions of scalar and multidimensional arguments:
|
Clip (limit) the value. |
|
Return |
Elements:
|
Calculate an accurate floating point sum using decimals. |
|
Calculate the arithmetic mean (average) of input values. |
|
Calculate the sum of input values. |
|
Apply an algorithm to a vector component-wise. |
3-dimensional vector:
|
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, *arrays)[source]¶
Multidimensional map.
Return function f mapped to contents of multidimensional arrays. f is a function of that many arguments as the number of arrays.
An item of arrays must be a list of (possibly nested) lists. Its contents remain unchanged. Returned array has same dimensions as those of the initial ones (they are all assumed equal). If any of arrays 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]] >>> # multiple arrays >>> md_map(lambda x, y: x+y, [0, 1], [2, 3]) [2, 4]
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 DSum(total=0)[source]¶
Calculate an accurate floating point sum using decimals.
total is the initial value of the sum.
See also
Use
Sum
for quick and precise sums of integer numbers.- compute()[source]¶
Yield the calculated sum as float.
If the current context is not empty, yield (sum, context). Otherwise yield only the sum.
- class Mean(sum_seq=None, pass_on_empty=False)[source]¶
Calculate the arithmetic mean (average) of input values.
sum_seq is the algorithm to calculate the sum. If it is not provided, ordinary Python summation is used. Otherwise it is converted to a FillCompute sequence.
If pass_on_empty is
True
, then if nothing was filled, don’t yield anything. By default an error is raised (seecompute()
).- compute()[source]¶
Calculate the mean and yield.
If the current context is not empty, yield (mean, context). Otherwise yield only mean. If the sum_seq yields several values, they are all yielded, but only the first is divided by number of events (considered the mean value).
If no values were filled (count is zero), the mean can’t be calculated and
LenaZeroDivisionError
is raised. This can be changed to yielding nothing if pass_on_empty was initialized toTrue
.
- class Sum(total=0)[source]¶
Calculate the sum of input values.
total is the initial value of the sum.
See also
Use
DSum
for exact floating summation.- compute()[source]¶
Calculate the sum and yield.
If the current context is not empty, yield (sum, context). Otherwise yield only sum.
- class Vectorize(seq, dim=-1, construct=None)[source]¶
Apply an algorithm to a vector component-wise.
seq must be a FillCompute element or sequence.
dim is the dimension of the input data (and of the constructed structure). seq may also be a list of sequences, in that case dim may be omitted.
construct allows one to create an arbitrary object (by default the resulting values are tuples of dimension dim).
- compute()[source]¶
Yield results from compute() for each component grouped together.
If compute for different components yield different number of results, the longest output is yielded (the others are padded with
None
).If the resulting value can’t be converted to the type of the first value (or construct couldn’t be used), a
tuple
is yielded.
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.
- 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 from_spherical(r, phi, theta)[source]¶
Construct a new vector3 from spherical coordinates.
r is its magnitude, phi is the azimuth angle from 0 to \(2 * \pi\) and theta is the polar angle from 0 (z = 1) to \(\pi\) (z = -1).
>>> from math import pi >>> vector3.from_spherical(1, 0, 0) vector3(0.0, 0.0, 1.0) >>> vector3.from_spherical(1, 0, pi).isclose(vector3(0, 0, -1)) True >>> vector3(1, 0, 0).isclose(vector3.from_spherical(1, 0, pi/2)) True >>> vector3.from_spherical(1, pi, 0).isclose(vector3(0.0, 0.0, 1.0)) True >>> vector3.from_spherical(1, pi/2, pi/2).isclose(vector3(0.0, 1.0, 0.0)) True
Changed in version 0.6: Renamed from fromspherical.
- 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