SpiceDouble vdotg_c ( ConstSpiceDouble * v1, ConstSpiceDouble * v2, SpiceInt ndim ) /* -Brief_I/O VARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- v1 I First vector in the dot product. v2 I Second vector in the dot product. ndim I Dimension of v1 and v2. The function returns the value of the dot product of v1 and v2. -Detailed_Input v1 This may be any double precision vector of arbitrary dimension. v2 This may be any double precision vector of arbitrary dimension. -Detailed_Output The function returns the value of the dot product of v1 and v2. -Parameters None. -Particulars vdotg_c calculates the dot product of v1 and v2 by a simple application of the definition. No error checking is performed to prevent or recover from numeric overflow. -Examples Suppose that given two n-dimensional vectors, we want to change one of the vectors until the two vectors are perpendicular. The following code fragment demonstrates the use of vdot_c to do so. dot = vdotg_c ( v1, v2, ndim ); while ( dot != 0. ) { /. change one of the vectors ./ .... dot = vdotg_c ( v1, v2, ndim ); } -Restrictions The user is responsible for determining that the vectors v1 and v2 are not so large as to cause numeric overflow. In most cases this won't present a problem. -Exceptions 1) If ndim is not physically realistic, greater than zero, a BADDIMENSION error is signaled. The value 0. is returned. -Files None. -Author_and_Institution W.M. Owen (JPL) E.D. Wright (JPL) -Literature_References None. -Version -CSPICE Version 1.1.0, 22-OCT-1998 (NJB) Made input vectors const. Converted check-in style to discovery. -CSPICE Version 1.0.0, 31-MAR-1998 (EDW) -Index_Entries dot product of n-dimensional vectors -& */ { /* Begin vdotg_c */ /* Local variables */ SpiceInt i; SpiceDouble dot; /* Use discovery check-in. */ /* Initialize dot to zero. */ dot = 0.; /* Check ndim is cool. Dimension is positive definite. */ if ( ndim <= 0 ) { chkin_c ( "vdotg_c" ); SpiceError ( "Vector dimension less than or equal to zero", "BADDIMENSION" ); chkout_c ( "vdotg_c" ); return ( 0. ); } /* Do the calculation. Not very involved. */ for ( i = 0; i < ndim; i++ ) { dot += v1[i] * v2[i]; } /* Return the value. */ return dot; } /* End vdotg_c */
void vequg_c ( ConstSpiceDouble * vin, SpiceInt ndim, SpiceDouble * vout ) /* -Brief_I/O VARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- vin I ndim-dimensional double precision vector. ndim I Dimension of vin (and also vout). vout O ndim-dimensional double precision vector set equal to vin. -Detailed_Input vin is a double precision vector of arbitrary dimension. ndim is the number of components of vin. -Detailed_Output vout is a double precision vector set equal to vin. -Parameters None. -Particulars The code simply sets each component of vout equal to the corresponding component of vin. -Examples Let state be a state vector. Set abstat equal to state. vequg_c ( state, 6, abstate ); Note that this routine may be used in place of MOVED, which sets each output array element equal to the corresponding input array element. -Restrictions None. -Exceptions 1) If ndim is not physically realistic, greater than zero, a BADDIMENSION error is flagged. -Files None. -Author_and_Institution W.M. Owen (JPL) E.D. Wright (JPL) -Literature_References None. -Version -CSPICE Version 1.0.0, 23-AUG-1999 (EDW) (NJB) -Index_Entries assign an n-dimensional vector to another -& */ { /* Begin vequg_c */ /* Use discovery check-in. */ /* Check ndim is cool. Dimension is positive definite. */ if ( ndim <= 0 ) { chkin_c ( "vequg_c" ); SpiceError ( "Vector dimension less than or equal to zero", "BADDIMENSION" ); chkout_c ( "vequg_c" ); return; } /* Do the equality thing. */ MOVED ( vin, ndim, vout ); } /* End vequg_c */
SpiceDouble vnormg_c ( ConstSpiceDouble * v1, SpiceInt ndim ) /* -Brief_I/O VARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- v1 I Vector whose magnitude is to be found. ndim I Dimension of v1. -Detailed_Input v1 This may be any double precision vector or arbitrary size. -Detailed_Output vnormg_c is the magnitude of v1 calculated in a numerically stable way. -Parameters None. -Exceptions 1) If ndim is not physically realistic, greater than zero, a BADDIMENSION error is signaled. The value 0. is returned. -Files None. -Particulars vnormg_c finds the component of v1 whose magnitude is the largest. If the absolute magnitude of that component indicates that a numeric overflow would occur when it is squared, or if it indicates that an underflow would occur when squared (falsely giving a magnitude of zero) then the following expression is used: vnormg_c = v1max * MAGNITUDE OF [ (1/v1max)*v1 ] therwise a simpler expression is used: vnormg_c = MAGNITUDE OF [ v1 ] Beyond the logic described above, no further checking of the validity of the input is performed. -Examples The following table show the correlation between various input vectors v1 and vnormg_c: ndim v1 ndim vnormg_c ----------------------------------------------------------------- 1 (-7.0D20) 1 7.D20 3 (1., 2., 2.) 3 3. 4 (3., 3., 3., 3.) 4 6. 5 (5., 12., 0., 0., 0.) 5 13. 3 (-5.D-17, 0.0, 12.D-17) 3 13.D-17 -Restrictions None. -Author_and_Institution W.M. Owen (JPL) -Literature_References None. -Version -CSPICE Version 1.1.0, 22-OCT-1998 (NJB) Made input vector const. -CSPICE Version 1.0.0, 1-APR-1998 (EDW) -Index_Entries norm of n-dimensional vector -& */ { /* Begin vnormg_c */ /* Local variables */ SpiceInt i; SpiceDouble norm; SpiceDouble scale; /* Use discovery check-in. */ /* Initialize norm and scale to zero. */ norm = 0.; scale = 0.; /* Check ndim is cool. Dimension is positive definite. */ if ( ndim <= 0 ) { chkin_c ( "vnormg_c" ); SpiceError ( "Vector dimension less than or equal to zero", "BADDIMENSION" ); chkout_c ( "vnormg_c" ); return ( 0. ); } /* Determine an appropriate scale factor to prevent numerical overflow. Overflow would be bad! */ for ( i = 0; i < ndim; i++ ) { scale = MaxAbs( scale, v1[i] ); } /* If the vector is zero, return zero. */ if ( scale == 0. ) { return 0.; } /* Do the calculation. Not very involved. */ for ( i = 0; i < ndim; i++ ) { norm += pow( v1[i] / scale, 2 ); } /* Return the value. */ return ( scale * sqrt( norm ) ); } /* End vnormg_c */
void unormg_c ( ConstSpiceDouble * v1, SpiceInt ndim, SpiceDouble * vout, SpiceDouble * vmag ) /* -Brief_I/O VARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- v1 I Vector to be normalized. ndim I Dimension of v1 (and also vout). vout O Unit vector v1 / |v1|. If v1 = 0, vout will also be zero. vout can overwrite v1. vmag O Magnitude of v1, that is, |v1|. -Detailed_Input v1 This variable may contain any vector of arbitrary dimension, including the zero vector. ndim This is the dimension of v1 and vout. -Detailed_Output vout This variable contains the unit vector in the direction of v1. If v1 is the zero vector, then vout will also be the zero vector. vmag This is the magnitude of v1. -Parameters None. -Particulars unormg_c references a function called vnormg_c (which itself is numerically stable) to calculate the norm of the input vector v1. If the norm is equal to zero, then each component of the output vector vout is set to zero. Otherwise, vout is calculated by dividing v1 by the norm. No error detection or correction is implemented. -Examples The following table shows how selected v1 implies vout and mag. v1 ndim vout mag ----------------------------------------------------------------- (5, 12) 2 (5/13, 12/13) 13 (1D-7, 2D-7, 2D-7) 3 (1/3, 2/3, 2/3) 3D-7 -Restrictions No error checking is implemented in this subroutine to guard against numeric overflow. -Exceptions 1) If ndim is not physically realistic, greater than zero, a BADDIMENSION error is flagged. -Files None. -Author_and_Institution W.M. Owen (JPL) W.L. Taber (JPL) E.D. Wright (JPL) -Literature_References None. -Version -CSPICE Version 1.1.0, 22-OCT-1998 (NJB) Made input vector const. Converted check-in style to discovery. -CSPICE Version 1.0.0, 31-MAR-1998 (EDW) -Index_Entries n-dimensional unit vector and norm -& */ { /* Begin unormg_c */ /* Local variables */ SpiceInt i; /* Use discovery check-in. */ /* Check ndim is cool. Dimension is positive definite. */ if ( ndim <= 0 ) { chkin_c ( "unormg_c" ); SpiceError ( "Vector dimension less than or equal to zero", "BADDIMENSION" ); chkout_c ( "unormg_c" ); return; } /* Get the magnitude of the vector. */ *vmag = vnormg_c ( v1, ndim ); /* If vmag is nonzero, then normalize. Note that this process is numerically stable: overflow could only happen if vmag were small, but this could only happen if each component of v1 were also small. In fact, the magnitude of any vector is never less than the magnitude of any component. */ if ( *vmag > 0. ) { for ( i = 0; i < ndim; i++ ) { vout[i] = v1[i]/ (*vmag); } } else { for ( i = 0; i < ndim ; i++ ); { vout[i] = 0.; } } } /* End unormg_c */