sofa_vml.lis 2020 September 9 -------------------------- SOFA Vector/Matrix Library -------------------------- PREFACE The routines described here comprise the SOFA vector/matrix library. Their general appearance and coding style conforms to conventions agreed by the SOFA Board, and their functions, names and algorithms have been ratified by the Board. Procedures for soliciting and agreeing additions to the library are still evolving. PROGRAMMING LANGUAGES The SOFA routines are available in two programming languages at present: Fortran 77 and ANSI C. There is a one-to-one relationship between the two language versions. The naming convention is such that a SOFA routine referred to generically as "EXAMPL" exists as a Fortran subprogram iau_EXAMPL and a C function iauExampl. The calls for the two versions are very similar, with the same arguments in the same order. In a few cases, the C equivalent of a Fortran SUBROUTINE subprogram uses a return value rather than an argument. GENERAL PRINCIPLES The library consists mostly of routines which operate on ordinary Cartesian vectors (x,y,z) and 3x3 rotation matrices. However, there is also support for vectors which represent velocity as well as position and vectors which represent rotation instead of position. The vectors which represent both position and velocity may be considered still to have dimensions (3), but to comprise elements each of which is two numbers, representing the value itself and the time derivative. Thus: * "Position" or "p" vectors (or just plain 3-vectors) have dimension (3) in Fortran and [3] in C. * "Position/velocity" or "pv" vectors have dimensions (3,2) in Fortran and [2][3] in C. * "Rotation" or "r" matrices have dimensions (3,3) in Fortran and [3][3] in C. When used for rotation, they are "orthogonal"; the inverse of such a matrix is equal to the transpose. Most of the routines in this library do not assume that r-matrices are necessarily orthogonal and in fact work on any 3x3 matrix. * "Rotation" or "r" vectors have dimensions (3) in Fortran and [3] in C. Such vectors are a combination of the Euler axis and angle and are convertible to and from r-matrices. The direction is the axis of rotation and the magnitude is the angle of rotation, in radians. Because the amount of rotation can be scaled up and down simply by multiplying the vector by a scalar, r-vectors are useful for representing spins about an axis which is fixed. * The above rules mean that in terms of memory address, the three velocity components of a pv-vector follow the three position components. Application code is permitted to exploit this and all other knowledge of the internal layouts: that x, y and z appear in that order and are in a right-handed Cartesian coordinate system etc. For example, the cp function (copy a p-vector) can be used to copy the velocity component of a pv-vector (indeed, this is how the CPV routine is coded). * The routines provided do not completely fill the range of operations that link all the various vector and matrix options, but are confined to functions that are required by other parts of the SOFA software or which are likely to prove useful. In addition to the vector/matrix routines, the library contains some routines related to spherical angles, including conversions to and from sexagesimal format. Using the library requires knowledge of vector/matrix methods, spherical trigonometry, and methods of attitude representation. These topics are covered in many textbooks, including "Spacecraft Attitude Determination and Control", James R. Wertz (ed.), Astrophysics and Space Science Library, Vol. 73, D. Reidel Publishing Company, 1986. OPERATIONS INVOLVING P-VECTORS AND R-MATRICES Initialize ZP zero p-vector ZR initialize r-matrix to null IR initialize r-matrix to identity Copy CP copy p-vector CR copy r-matrix Build rotations RX rotate r-matrix about x RY rotate r-matrix about y RZ rotate r-matrix about z Spherical/Cartesian conversions S2C spherical to unit vector C2S unit vector to spherical S2P spherical to p-vector P2S p-vector to spherical Operations on vectors PPP p-vector plus p-vector PMP p-vector minus p-vector PPSP p-vector plus scaled p-vector PDP inner (=scalar=dot) product of two p-vectors PXP outer (=vector=cross) product of two p-vectors PM modulus of p-vector PN normalize p-vector returning modulus SXP multiply p-vector by scalar Operations on matrices RXR r-matrix multiply TR transpose r-matrix Matrix-vector products RXP product of r-matrix and p-vector TRXP product of transpose of r-matrix and p-vector Separation and position-angle SEPP angular separation from p-vectors SEPS angular separation from spherical coordinates PAP position-angle from p-vectors PAS position-angle from spherical coordinates Rotation vectors RV2M r-vector to r-matrix RM2V r-matrix to r-vector OPERATIONS INVOLVING PV-VECTORS Initialize ZPV zero pv-vector Copy/extend/extract CPV copy pv-vector P2PV append zero velocity to p-vector PV2P discard velocity component of pv-vector Spherical/Cartesian conversions S2PV spherical to pv-vector PV2S pv-vector to spherical Operations on pv-vectors PVPPV pv-vector plus pv-vector PVMPV pv-vector minus pv-vector PVDPV inner (=scalar=dot) product of two pv-vectors PVXPV outer (=vector=cross) product of two pv-vectors PVM modulus of pv-vector SXPV multiply pv-vector by scalar S2XPV multiply pv-vector by two scalars PVU update pv-vector PVUP update pv-vector discarding velocity Matrix-vector products RXPV product of r-matrix and pv-vector TRXPV product of transpose of r-matrix and pv-vector OPERATIONS ON ANGLES Wrap ANP normalize radians to range 0 to 2pi ANPM normalize radians to range -pi to +pi To sexagesimal A2TF decompose radians into hours, minutes, seconds A2AF decompose radians into degrees, arcminutes, arcseconds D2TF decompose days into hours, minutes, seconds From sexagesimal AF2A degrees, arcminutes, arcseconds to radians TF2A hours, minutes, seconds to radians TF2D hours, minutes, seconds to days CALLS: FORTRAN VERSION CALL iau_A2AF ( NDP, ANGLE, SIGN, IDMSF ) CALL iau_A2TF ( NDP, ANGLE, SIGN, IHMSF ) CALL iau_AF2A ( S, IDEG, IAMIN, ASEC, RAD, J ) D = iau_ANP ( A ) D = iau_ANPM ( A ) CALL iau_C2S ( P, THETA, PHI ) CALL iau_CP ( P, C ) CALL iau_CPV ( PV, C ) CALL iau_CR ( R, C ) CALL iau_D2TF ( NDP, DAYS, SIGN, IHMSF ) CALL iau_IR ( R ) CALL iau_P2PV ( P, PV ) CALL iau_P2S ( P, THETA, PHI, R ) CALL iau_PAP ( A, B, THETA ) CALL iau_PAS ( AL, AP, BL, BP, THETA ) CALL iau_PDP ( A, B, ADB ) CALL iau_PM ( P, R ) CALL iau_PMP ( A, B, AMB ) CALL iau_PN ( P, R, U ) CALL iau_PPP ( A, B, APB ) CALL iau_PPSP ( A, S, B, APSB ) CALL iau_PV2P ( PV, P ) CALL iau_PV2S ( PV, THETA, PHI, R, TD, PD, RD ) CALL iau_PVDPV ( A, B, ADB ) CALL iau_PVM ( PV, R, S ) CALL iau_PVMPV ( A, B, AMB ) CALL iau_PVPPV ( A, B, APB ) CALL iau_PVU ( DT, PV, UPV ) CALL iau_PVUP ( DT, PV, P ) CALL iau_PVXPV ( A, B, AXB ) CALL iau_PXP ( A, B, AXB ) CALL iau_RM2V ( R, P ) CALL iau_RV2M ( P, R ) CALL iau_RX ( PHI, R ) CALL iau_RXP ( R, P, RP ) CALL iau_RXPV ( R, PV, RPV ) CALL iau_RXR ( A, B, ATB ) CALL iau_RY ( THETA, R ) CALL iau_RZ ( PSI, R ) CALL iau_S2C ( THETA, PHI, C ) CALL iau_S2P ( THETA, PHI, R, P ) CALL iau_S2PV ( THETA, PHI, R, TD, PD, RD, PV ) CALL iau_S2XPV ( S1, S2, PV ) CALL iau_SEPP ( A, B, S ) CALL iau_SEPS ( AL, AP, BL, BP, S ) CALL iau_SXP ( S, P, SP ) CALL iau_SXPV ( S, PV, SPV ) CALL iau_TF2A ( S, IHOUR, IMIN, SEC, RAD, J ) CALL iau_TF2D ( S, IHOUR, IMIN, SEC, DAYS, J ) CALL iau_TR ( R, RT ) CALL iau_TRXP ( R, P, TRP ) CALL iau_TRXPV ( R, PV, TRPV ) CALL iau_ZP ( P ) CALL iau_ZPV ( PV ) CALL iau_ZR ( R ) CALLS: C VERSION iauA2af ( ndp, angle, &sign, idmsf ); iauA2tf ( ndp, angle, &sign, ihmsf ); i = iauAf2a ( s, ideg, iamin, asec, &rad ); d = iauAnp ( a ); d = iauAnpm ( a ); iauC2s ( p, &theta, &phi ); iauCp ( p, c ); iauCpv ( pv, c ); iauCr ( r, c ); iauD2tf ( ndp, days, &sign, ihmsf ); iauIr ( r ); iauP2pv ( p, pv ); iauP2s ( p, &theta, &phi, &r ); d = iauPap ( a, b ); d = iauPas ( al, ap, bl, bp ); d = iauPdp ( a, b ); d = iauPm ( p ); iauPmp ( a, b, amb ); iauPn ( p, &r, u ); iauPpp ( a, b, apb ); iauPpsp ( a, s, b, apsb ); iauPv2p ( pv, p ); iauPv2s ( pv, &theta, &phi, &r, &td, &pd, &rd ); iauPvdpv ( a, b, adb ); iauPvm ( pv, &r, &s ); iauPvmpv ( a, b, amb ); iauPvppv ( a, b, apb ); iauPvu ( dt, pv, upv ); iauPvup ( dt, pv, p ); iauPvxpv ( a, b, axb ); iauPxp ( a, b, axb ); iauRm2v ( r, p ); iauRv2m ( p, r ); iauRx ( phi, r ); iauRxp ( r, p, rp ); iauRxpv ( r, pv, rpv ); iauRxr ( a, b, atb ); iauRy ( theta, r ); iauRz ( psi, r ); iauS2c ( theta, phi, c ); iauS2p ( theta, phi, r, p ); iauS2pv ( theta, phi, r, td, pd, rd, pv ); iauS2xpv ( s1, s2, pv ); d = iauSepp ( a, b ); d = iauSeps ( al, ap, bl, bp ); iauSxp ( s, p, sp ); iauSxpv ( s, pv, spv ); i = iauTf2a ( s, ihour, imin, sec, &rad ); i = iauTf2d ( s, ihour, imin, sec, &days ); iauTr ( r, rt ); iauTrxp ( r, p, trp ); iauTrxpv ( r, pv, trpv ); iauZp ( p ); iauZpv ( pv ); iauZr ( r );