rotmg(3F)
SROTMG, DROTMG - Constructs a modified Givens plane rotation
As shipped in IRIX 6.5.30. Last changed in IRIX 6.5.19.
NAME SROTMG, DROTMG - Constructs a modified Givens plane rotation SYNOPSIS Real CALL SROTMG (d1, d2, b1, b2, rparam) Double precision CALL DROTMG (d1, d2, b1, b2, rparam) DESCRIPTION These routines compute the elements of a modified Givens plane rotation matrix. These routines have the following arguments: d1 First diagonal element. (input and output) SROTMG: Real. DROTMG: Double precision. On input, this value is the first diagonal element of the scaling matrix D. On the first call to the routine, this value is typically 1.0. Subsequent calls typically use the value from the previous call. On output, this value is the first diagonal element of the updated scaling matrix D'. d2 First diagonal element. (input and output) SROTMG: Real. DROTMG: Double precision. On input, this is the first diagonal element of the scaling matrix D. On the first call to the routine, this value is typically 1.0. Subsequent calls typically use the value from the previous call. On output, this value is the first diagonal element of the updated scaling matrix D'. b1 x-coordinate. (input and output) SROTMG: Real. DROTMG: Double precision. On input, this value is the x-coordinate of the vector used to define the angle of rotation, before scaling (multiplying by the matrix D). On output, this value is the x-coordinate of the rotated vector, before scaling (multiplying by the matrix D'). b2 y-coordinate. (input) SROTMG: Real. DROTMG: Double precision. On input, this value is the y-coordinate of the vector used to define the angle of rotation, before scaling (multiplying by the matrix D). It is unchanged on output. rparam Real array of dimension 5. (output) SROTMG: Real array. DROTMG: Double precision array. This array contains rotation matrix information. The routine sets up the computed elements in rparam from inputs d1, d2, b1, and b2. Standard Givens Rotation A standard Givens rotation (see SROTG(3F)) is based on an orthogonal matrix G that rotates points on a Cartesian xy-coordinate plane. To calculate the rotation matrix, you must provide the angle of rotation desired, or, equivalently, a vector (point) that lies along the angle of rotation. For a given planar point (xr, yr), G is formed so that: _ _ _ _ _ _ _ _ | x' | | c s | | x | G | x | | | | | | r | | r | | 0 | = |-s c | | y | = | y | | | | | | r | | r | - - - - - - - - where x' = sqrt (xr2 + yr2) . With this rotation matrix G, you can then convert any number of existing planar points to the new (rotated) xy-coordinate system. For n points, the rotations would be as follows: _ _ _ _ _ _ | x | | c s | | x | | i | | | | i | | 0 |<- |-s c | | y | | i | | | | i | - - - - - - for i = 1, 2, ..., n Modified Givens Rotation The algorithm for these routines is based on the following observation. The rotation matrix G can be factored into a scaling matrix (diagonal matrix) and modified rotation matrix H, for which either the diagonal or the off-diagonal elements are units (that is, +1 or -1). Thus, to perform m modified (scaled) rotations on n planar points, requires only 2nm, rather than 4nm multiplications for the standard rotation. Because you may want to perform several successive rotations, this routine assumes that you have leftover scaling factors from your previous modified Givens rotation; that is, the routine requires you to input not only a planar rotation vector (b1, b2) but also the squares of the diagonal elements of the scaling matrix, d1 and d2. The actual rotation vector is specified as follows: _ _ _ _ _ _ 1/2_ _ | xr | | sqrt(d1) 0 | | b1 | D | b1 | | yr | = | 0 sqrt(d2) | | b2 | = | b2 | - - - - - - - - where d1 and d2 are the input scaling factors. Given these inputs, the routine generates a new modified rotation matrix H with units for either the diagonal or off-diagonal elements, and new elements d1' and d2' for the new scaling factors, and rotated but unscaled vector (b1', 0), with the following results: _ _ 1/2_ _ 1/2 _ _ 1/2_ _ _ _ G | xr | G D | b1 | D' H | b1 | = D' | h11 h12 | | b1 | | yr | = | b2 | = | b2 | | h21 h22 | | b2 | - - - - - - - - - - 1/2_ _ _ _ D' | b1' | | x' | = | 0 | = | 0 | - - - - where: 1/2 D' ( = diag {sqrt(d1'), sqrt(d2')} ) uses the updated scaling factors d1' and d2', which are d1 and d2 on output. H is stored in the output array argument rparam; b1' is stored as b1 on output. D'1/2H equals G D 1/2, not G, as implied earlier. You must account for the old scaling factors when calculating the new scaling factors. After calculating the matrix H by using SROTMG/DROTMG, you can then use it in SROTM/DROTM to convert points to the new coordinate system. NOTES Meaning of the Output Values The output values are returned through arguments d1, d2, b1, and rparam. The scaling factors d1 and d2 are updated with each call to the routine. Although SROTM/DROTM does not need the updated factors, they are needed in two other important contexts: * As input for subsequent calls to this routine. * As scaling factors for rotated but unscaled points (xi, yi), which are output from SROTM./DROTM. In this second usage, the actual (scaled) points would be given by (sqrt(d1)*x(i), sqrt(d2)*y(i)). Doing this operation frequently on all your points is counterproductive. The main advantage of the modified rotation algorithm is to reduce the number of operations. If you fold in the scaling factors after each rotation, you are performing the same number of operations as in the standard Givens rotation. These two uses for the scaling factors are mutually exclusive; that is, if you fold the scaling factors back into all your points, you no longer need those factors for these routines. After folding in the scaling factors, and before the next call to SROTMG/DROTMG, reset d1 and d2 to 1.0. On output, b1 represents the new x-coordinate after rotating (but before scaling) the rotation vector. Although the y-coordinate of this vector is 0.0 (see the the previous discussion), the corresponding value b2 is unchanged on output. The output array argument rparam specifies the format of matrix H, and it holds the nonunit values of H. This is the only output of these routines that SROTM/DROTM requires. Each element of rparam has a specific meaning, as follows: rparam(1) a flag parameter that specifies how the matrix is stored = 0.0 Off-diagonal elements of H are units. = 1.0 Diagonal elements of H are units. = -1.0 Rescaling case (see the following subsection). = -2.0 H is the identity matrix; no rotation needed. rparam(2) = h1,1 if needed rparam(3) = h2,1 if needed rparam(4) = h1,2 if needed rparam(5) = h2,2 if needed Calculating the Output Values The following presents the algorithm for calculating the output values d1, d2, b1, and rparam, based on the input values d1, d2, b1, and b2. This algorithm is presented without explanation or proof. For a more complete discussion of the modified Givens algorithm, see the papers listed in the SEE ALSO section. Case 1: b2 = 0 (trivial case) In this case, no rotation is needed. The flag value, rparam(1), is set to -2.0. When passed to routine SROTM/DROTM, this flag indicates that it should not do any rotations. On output from SROTMG/DROTMG, d1, d2, and b1 are unchanged. Case 2: | sqrt(d1)*b1 | > | sqrt(d2)*b2 | (|xr| > |yr|) In this case, the diagonal elements of H (h1,1 and h2,2) are set to 1.0 . Thus, the rparam values set on output are as follows: rparam(1) <-- 0.0 rparam(3) <-- h21 = -b2/b1 rparam(4) <-- h1,2 = (d2*b2)/(d1*b1) The output values of the scaling factors are as follows: d1 <-- d1' = d1/u d2 <-- d2' = d2/u where u = det(H) = 1 + (d2*b2*b2)/(d1*b1*b1) . The output value of b1 is as follows: b1 <-- b1' = b1*u If rescaling is needed, SROTMG/DROTMG will further modify these output values before the end of the routine. See case 4 later in this subsection. Case 3: | sqrt(d1)*b1 | <= | sqrt(d2)*b2 | (|xr| <= |yr|) In this case, the off-diagonal elements of H are units (to be specific, h2,1 = -1 and h1,2 = 1). Thus, the rparam values set on output are as follows: rparam(1) <-- 1.0 rparam(2) <-- h1,1 = (d1*b1)/(d2*b2) rparam(5) <-- h2,2 = b1/b2 The output values of the scaling factors are as follows: d1 <-- d1' = d2/u d2 <-- d2' = d1/u where u = det(H) = 1 + (d1*b1*b1)/(d2*b2*b2) . The output value of b1 is as follows: b1 <-- b1' = b2*u If rescaling is needed, SROTMG/DROTMG will further modify these output values before the end of the routine. See case 4. Case 4: Rescaling If the scaling factors become either very large or very small, the scaling and rotation operations may lose a lot of accuracy; therefore, each scaling factor from case 2 or case 3 is kept within the range: gamma**(-2) <= | d(i)' | <= gamma**2 , for i = 1, 2 where d(1)' = d1', d(2)' = d2', and gamma = 2.0**12 = 4096.0. At the end of case 2 or case 3 assignments, if either of the scaling factors falls outside this range, this routine must rescale that factor (and the corresponding elements of H) to bring its size back within the specified range. 48 - log2(gamma) = 48 - 12 = 36 bits (~ 10 decimal digits) Rescaling is performed as follows: If either d1 or d2 is 0, no rescaling is done; otherwise, let q(i) = int(log_base_gamma(sqrt(|d(i)'|))) = int(log2(|d(i)'|)/24) , for i = 1 , 2. Then the following is true: q(i) < 0 , if |d(i)'| < gamma**2 q(i) = 0 , if gamma**(-2) <= |d(i)'| <= gamma**2 q(i) > 0 , if |d(i)'| > gamma**2 Furthermore, |q(i)| represents the number of times d(i)' must be multiplied (or divided) by gamma**2 to return it to the proper range of values. In this case, the rparam values set on output are as follows: rparam(1) <-- -1.0 rparam(2) <-- h1,1' = h1,1*gamma**q(1) rparam(3) <-- h2,1' = h2,1*gamma**q(2) rparam(4) <-- h1,2' = h1,2*gamma**q(1) rparam(5) <-- h2,2' = h2,2*gamma**q(2) The output values of the scaling factors are as follows: d1 <-- d1'' = d1'*gamma**(-2*q(1)) d2 <-- d2'' = d2'*gamma**(-2*q(2)) The output value of b1 is as follows: b1 <-- b1'' = b1'*gamma**q(1) SEE ALSO ROT(3F), ROTG(3F), ROTM(3F) Gentleman, W. M., "Least Squares Computations by Givens Transformations Without Square Roots," Journal of the Institute for Mathematical Applications 12 (1973), Lawson, C., Hanson, R., Kincaid, D., and Krogh, F., "Basic Linear Algebra Subprograms for Fortran Usage," ACM Transactions on Mathematical Software, 5 (1979),