Reference Frames#
- class sigmaepsilon.math.linalg.meta.FrameLike(*args, **kwargs)[source]#
Base class for reference frames.
- 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)
See also
- 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:
- 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:
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:
- property is_independent: bool#
Returns True if the base vectors that make up the frame are linearly independent.
- orient(*args, **kwargs) ReferenceFrame[source]#
Orients the current frame inplace. All arguments are forwarded to
rotation_matrix(), see there for the details.- Return type:
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]])
See also
- 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:
See also
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:
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]])
See also
- 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:
See also
- 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:
- 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.
- 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'>
See also
- 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'>
See also
- dual() ReferenceFrame[source]#
Returns the dual (or reciprocal) frame.