pymgp.crstrans.covtransform#

pymgp.crstrans.covtransform(qin, fmtin, fmtout, rotmatrix=None)[source]#

Transform and reformat compact co-variance matrices/vectors.

Parameters:
qinarray_like shape (…,6) or shape (…,3,3)

Input (compact) co-variance matrix/vector.

fmtinstr

Format of the input compact co-variance matrix/vector, see notes.

fmtoutstr

Format of the output compact co-variance matrix/vector, see notes.

rotmatrixarray_like with shape (…,3,3), default=None

Optional rotation matrix to obtain Qout = R.T @ Qin @ R .

Returns:
qoutndarray with shape (…,6) or shape (…,3,3)

Output (compact) co-variance matrix/vector.

Notes

Supported input and output (compact) “co-variance” matrix/vector formats are:

qmat    matrix [ [ qx qxy qxz ] 
                 [ qxy qy qyz ] 
                 [ qxy qyz qz ] ]

qvec    vector [ qx, qy, qz, qxy, qxz, qyz ]
scor    vector [ sx, sy, sz, rxy, rxz, ryz ]    (geo++, NRCAN)
scof    vector [ sx, sy, sz, cxy, cxz, cyz ]    (gamit/globk)
scov    vector [ sx, sy, sz, sxy, sxz, syz ]

qvecd   vector [ qx, qy, qz, qxy, qyz, qxz ] 
scord   vector [ sx, sy, sz, rxy, ryz, rxz ]    
scofd   vector [ sx, sy, sz, cxy, cyz, cxz ]    
scovd   vector [ sx, sy, sz, sxy, syz, sxz ]    (rtklib)

with si=sqrt(qi), rij=qij/(sqrt(qi)*sqrt(qj)), cij=sign(rij)*sqrt(abs(rij)) and sij=sign(qij)*sqrt(abs(qij)).

The vector formats ending with “d” are store by diagonal, as is illustrated by:

qmat = [[ 1 4 6 ]   ->  qvecd = [ 1 2 3 4 5 6 ]  ->  qvec = [ 1 2 3 4 6 5] 
        [ 4 2 5 ]                                                     |_|
        [ 6 5 3 ]] 

The other vector formats have their last two positions swapped compared to the store by diagonal formats.

The input rotation matrix is transposed compared to what is often found in literature and what is used by the Matlab versions. This is intentional, as the rotation matrix from xyz2neu and neu2xyz is defined by:

xout = xin @ R
qout = R.T @ qin @ R 

These equations can only be used for the most simple use cases with simple shapes and is NOT recommended for coding. Instead, Einstein summation is used in this function:

xout = np.einsum('...j,...ji',xin, R)

tmp = np.einsum('...ij, ...jk -> ...ik', qin, R)
qout = np.einsum('...ji, ...jk -> ...ik', R, tmp)

Examples

Examples reformatting compact co-variance matrices

>>> covtransform([ 0.2061, 0.0708, 0.6352, -0.0109, 0.1514, -0.0188 ], 'scovd', 'qmat')
array([[ 4.2477210e-02, -1.1881000e-04, -3.5344000e-04],
       [-1.1881000e-04,  5.0126400e-03,  2.2921960e-02],
       [-3.5344000e-04,  2.2921960e-02,  4.0347904e-01]])
>>> covtransform([[ 1, 2, 3, 0.4, 0.5, -0.6], [ 2, 1, 3, 0.5, 0.4, -0.6]], 'scord','qvec')
array([[ 1. ,  4. ,  9. ,  0.8, -1.8,  3. ],
       [ 4. ,  1. ,  9. ,  1. , -3.6,  1.2]])

Example transforming compact xyz co-variance matrix into neu compact covariance matrix, using example data from NRCAN PPP processing

>>> xyz = [ 3923153.4730, 327268.0593, 5001437.4151 ]
>>> plh = [ 51+58/60+46.39902/3600, 4+46/60+6.78968/3600,  44.3163]
>>> scorxyz = [ 0.0049, 0.0020, 0.0058, 0.1538,  0.8101,  0.1681 ]
>>> scorneu = [ 0.0023, 0.0020, 0.0072, 0.0357, -0.0769, -0.0086 ]
>>> neu, R = xyz2neu(xyz, plh, unit='deg', origin='ecef', rotmatrix='true')
>>> print(R)
[[-0.78506419 -0.0831309   0.61381062]
 [-0.06548977  0.99653864  0.05120386]
 [ 0.61594262  0.          0.78779102]]
>>> scorneu_test = covtransform(scorxyz,fmtin='scor',fmtout='scor',rotmatrix=R)
>>> print(np.round(scorneu_test,4))
[ 0.0023  0.002   0.0072  0.0337 -0.0572 -0.0058]
>>> print(np.round(scorneu_test - scorneu,4))
[ 0.     -0.      0.     -0.002   0.0197  0.0028]