Reference Frames#

class sigmaepsilon.math.linalg.meta.FrameLike(*args, **kwargs)[source]#

Base class for reference frames.

property T: FrameLike#

Returns the transpose.

class sigmaepsilon.math.linalg.ReferenceFrame(axes: ndarray = None, *args, name: str = None, dim: int = None)[source]#

A class for arbitrary reference frames, that facilitates transformation of tensor-like quantities. Instances of this class support NumPy’s functions, universal functions and other standard features of NumPy (see the notes below).

An important feature of the class is that it maintains the property of objectivity of the tensorial quantities that use instances of this class in their representation. Upon transformation of a frame, the components of the associated tensorial quantities transform correspondingly.

Parameters:
  • axes (numpy.ndarray, Optional) – 2d numpy array of floats specifying cartesian reference frames. Default is None.

  • dim (int, Optional) – Dimension of the mesh. Default is 3.

  • name (str, Optional) – The name of the frame. Default is None.

Notes

1) The object is able to handle any reference frame, not just cartesian ones. The only restriction is that the base vectors should be linearly independent. 2) All NumPy universal functions return ReferenceFrame instances. If for a NumPy universal function a ReferenceFrame instance is provided by the parameter ‘out’ (eg. numpy.sqrt(A, out=A)), the instance is modified inplace and all associated tensorial quantities change aggordingly. This also true for operators like +=, -=, @=, etc. that naturally cause inplace modification of the called instance.

Examples

Define a frame and rotate it around axis ‘Z’ with an amount of 180 degrees:

>>> from sigmaepsilon.math.linalg import ReferenceFrame
>>> import numpy as np
>>> A = ReferenceFrame(dim=3)
>>> B = A.orient_new('Space', [0, 0, np.pi], 'XYZ')

If we define a tensorial quantity with components in a frame, the components of the quantity change if the frame changes:

>>> from sigmaepsilon.math.linalg import Vector
>>> v = Vector([1., 0, 0], frame=A)
>>> A *= 2.0
>>> v
Array([0.5, 0. , 0. ])

A ReferenceFrame instance can be an argument to a NumPy universal function, but the result is always a simple array object. The following call results in a simple array, leaving the frame (and hence the associated tensors, if there are any) unchanged

>>> A = ReferenceFrame(dim=3)
>>> np.sqrt(A)
Array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

but this one changes the frame (and hence the associated tensors if there are any):

>>> A = ReferenceFrame(dim=3)
>>> np.sqrt(A, out=A)
Array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

Of course, if you want your result to be a ReferenceFrame instance, you can always do this:

>>> A = ReferenceFrame(np.sqrt(ReferenceFrame(dim=3)))

The basis vectors that make up a frame are accessible through the property ‘axes’:

>>> A = ReferenceFrame(dim=3)
>>> A.axes
Array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

If the basis vectors change, so do the tensors associated with the frame:

>>> import numpy as np
>>> v = Vector([1.0, 0, 0], frame=A)
>>> A.axes = np.eye(3) * 2.0
>>> v
Array([0.5, 0. , 0. ])

The same happens if we change the frame of a tensorial quantity:

>>> A = ReferenceFrame(dim=3)
>>> v = Vector([1., 0, 0], frame=A)
>>> v.frame = A * 2.0
>>> v
Array([0.5, 0. , 0. ])

To get the matrix that transforms quantities from frame A to frame B, use the dcm method:

>>> source = ReferenceFrame(dim=3)
>>> target = source.orient_new('Space', [0, 0, 90*np.pi/180],  'XYZ')
>>> DCM = source.dcm(target=target)

or equivalenty

>>> DCM = target.dcm(source=source)
Gram() ndarray[source]#

Returns the Gram-matrix of the frame.

property axes: ndarray#

Returns a matrix, where each row (or column) is the component array of a basis vector with respect to the ambient frame.

Return type:

numpy.ndarray

copy(deep: bool = False, name: str = None) ReferenceFrame[source]#

Returns a shallow or deep copy of this object, depending of the argument deepcopy (default is False).

dcm(*, target: ReferenceFrame = None, source: ReferenceFrame = None) ndarray[source]#

Returns the direction cosine matrix (DCM) of a transformation from a source (S) to a target (T) frame. The current frame can be the source or the target, depending on the arguments.

If called without arguments, it returns the DCM matrix from the ambient frame to the current frame (S=None, T=self).

If source is not None, then T=self.

If target is not None, then S=self.

Parameters:
  • source ('ReferenceFrame', Optional) – Source frame. Default is None.

  • target ('ReferenceFrame', Optional) – Target frame. Default is None.

Returns:

DCM matrix from S to T.

Return type:

numpy.ndarray

Example

>>> from sigmaepsilon.math.linalg import ReferenceFrame
>>> import numpy as np
>>> source = ReferenceFrame(dim=3)
>>> target = source.orient_new('Space', [0, 0, 90*np.pi/180],  'XYZ')
>>> DCM = source.dcm(target=target)
>>> arr_source = np.array([3 ** 0.5 / 2, 0.5, 0])
>>> arr_target = DCM @ arr_source
deepcopy(name: str = None) ReferenceFrame[source]#

Returns a deep copy of the frame.

dual() ReferenceFrame[source]#

Returns the dual (or reciprocal) frame.

classmethod eye(*args, dim=3, **kwargs) ReferenceFrame[source]#

Returns a standard orthonormal frame.

Return type:

ReferenceFrame

property is_cartesian: bool#

Returns True if the frame is a cartesian (orthonormal) one.

property is_independent: bool#

Returns True if the base vectors that make up the frame are linearly independent.

property is_rectangular: bool#

Returns True if the frame is a rectangular one.

metric_tensor() TensorLike[source]#

Returns the metric tensor of the frame.

property name: str#

Returns the name of the frame.

orient(*args, **kwargs) ReferenceFrame[source]#

Orients the current frame inplace. All arguments are forwarded to rotation_matrix(), see there for the details.

Return type:

ReferenceFrame

Example

Define a standard Cartesian frame and rotate it around axis ‘Z’ with 180 degrees:

>>> from sigmaepsilon.math.linalg import ReferenceFrame
>>> import numpy as np
>>> A = ReferenceFrame(dim=3)
>>> A.orient('Space', [0, 0, np.pi], 'XYZ')
Array([[-1.0000000e+00,  1.2246468e-16,  0.0000000e+00],
       [-1.2246468e-16, -1.0000000e+00,  0.0000000e+00],
       [ 0.0000000e+00,  0.0000000e+00,  1.0000000e+00]])
orient_new(*args, name='', **kwargs) ReferenceFrame[source]#

Returns a new frame, oriented relative to the called object. All extra positional and keyword arguments are forwarded to rotation_matrix(), see there for the details.

Parameters:

name (str) – Name for the new reference frame.

Returns:

A new ReferenceFrame object.

Return type:

ReferenceFrame

Example

Define a standard Cartesian frame and rotate it around axis ‘Z’ with 180 degrees:

>>> A = ReferenceFrame(dim=3)
>>> B = A.orient_new('Space', [0, 0, np.pi], 'XYZ')
rotate(*args, inplace: bool = True, **kwargs) ReferenceFrame[source]#

Alias for orient and orient_new, all extra arguments are forwarded.

Added in version 0.0.4.

Parameters:

inplace (bool, Optional) – If True, transformation is carried out on the instance the function call is made upon, otherwise a new frame is returned. Default is True.

Returns:

An exisitng (if inplace is True) or a new ReferenceFrame object.

Return type:

ReferenceFrame

Example

Define a standard Cartesian frame and rotate it around axis ‘Z’ with 180 degrees:

>>> from sigmaepsilon.math.linalg import ReferenceFrame
>>> import numpy as np
>>> A = ReferenceFrame(dim=3)
>>> A.rotate('Space', [0, 0, np.pi], 'XYZ')
Array([[-1.0000000e+00,  1.2246468e-16,  0.0000000e+00],
       [-1.2246468e-16, -1.0000000e+00,  0.0000000e+00],
       [ 0.0000000e+00,  0.0000000e+00,  1.0000000e+00]])
rotate_new(*args, **kwargs) ReferenceFrame[source]#

Alias for orient_new, all extra arguments are forwarded.

Added in version 0.0.4.

Returns:

A new ReferenceFrame object.

Return type:

ReferenceFrame

See also

orient_new()

show(target: ReferenceFrame = None) ndarray[source]#

Returns the components of the current frame in a target frame. If the target is None, the componants are returned in the ambient frame.

Return type:

numpy.ndarray

transpose(inplace: bool = False) ReferenceFrame[source]#

Either transposes the array of the frame, or returns a copy of it with the components transposed.

Parameters:

inplace (bool, Optional) – If True, the operation is performed on the instance the call is made upon. Default is False.

Note

The rule of transposition differs from the one implemented in NumPy, as only tensorial axes are being transposed.

volume() float[source]#

Returns the signed volume of the general parallelepiped described by the base vectors that make up the frame.

class sigmaepsilon.math.linalg.RectangularFrame(*args, assume_rectangular: bool = False, **kwargs)[source]#

A class for rectangular reference frames. The behaviour of a RectanguarFrame instance is similar to that of a ReferenceFrame, with minor differences. One is that the rectangular property is utilized wherever possible, resulting in slightly better performance for some operations. The downside is that operations causing inplace modifications are only permitted if it can be guaranteed, that the result is a valid ReferenceFrame object. This is generally not true for function calls like numpy.sqrt(A, out=A) and an exception is raised. However, operators like +=, -= are fine.

Note

A frame being rectangular only implies that the base vectors that make up the frame are mutually perpendicular, but it has no say on the length of the base vectors. That is, a rectangular frame is not necessarily orthonormal.

Examples

For operators *= and /= the type of the instance is unchanged

>>> from sigmaepsilon.math.linalg import RectangularFrame
>>> A = RectangularFrame(dim=3)
>>> A *= 2
>>> type(A)
<class 'sigmaepsilon.math.linalg.frame.RectangularFrame'>

but for other operations the type of the object is cast to a more general frame

>>> A += 2
>>> type(A)
<class 'sigmaepsilon.math.linalg.frame.ReferenceFrame'>
property is_independent: bool#

Returns True if the base vectors that make up the frame are linearly independent.

property is_rectangular: bool#

Returns True if the frame is a rectangular one.

class sigmaepsilon.math.linalg.CartesianFrame(*args, normalize: bool = False, assume_cartesian: bool = False, **kwargs)[source]#

A class for cartesian (orthonormal) reference frames. Just like the RectangularFrame class, this is similar to the more general ReferenceFrame, but with increased performance and even more limitations.

Examples

For operators *= and /= the type of the instance is cast to RectangularFrame

>>> from sigmaepsilon.math.linalg import CartesianFrame
>>> import numpy as np
>>> A = CartesianFrame(dim=3)
>>> A *= 2
>>> type(A)
<class 'sigmaepsilon.math.linalg.frame.RectangularFrame'>

For other operations, the type of the object is cast to a general one

>>> A += 2
>>> type(A)
<class 'sigmaepsilon.math.linalg.frame.ReferenceFrame'>

The only operation that results in a CartesianFrame object is a rotation:

>>> A = CartesianFrame(dim=3)
>>> A.orient('Space', [0, 0, np.pi], 'XYZ')
Array([[-1.0000000e+00,  1.2246468e-16,  0.0000000e+00],
       [-1.2246468e-16, -1.0000000e+00,  0.0000000e+00],
       [ 0.0000000e+00,  0.0000000e+00,  1.0000000e+00]])
>>> type(A)
<class 'sigmaepsilon.math.linalg.frame.CartesianFrame'>
Gram() ndarray[source]#

Returns the Gram-matrix of the frame.

dual() ReferenceFrame[source]#

Returns the dual (or reciprocal) frame.

property is_cartesian: bool#

Returns True if the frame is a cartesian (orthonormal) one.

property is_rectangular: bool#

Returns True if the frame is a rectangular one.

volume() float[source]#

Returns the signed volume of the general parallelepiped described by the base vectors that make up the frame.