// Given row and column permutations compute the QR decomposition of a // sparse matrix. void sparse_qr_decomp( const int *P1, sparse_mat *A, const int *P2, sparse_mat **Q, sparse_mat **R ) { // Components of the R matrix: int nnz, *is, *js; double *vs; // Allocate structures to store Q and R. sparse_vec **rows = (sparse_vec**)calloc( A->m, sizeof(sparse_vec*) ); rotation *grots = alloc_rotation( A->m ); // Work variables int i, j, *col; double a, b, c, s, r, *val; sparse_vec row, *row_i, *row_j; grots -> n = A -> m; permute_rows(P1, A); permute_cols(A, P2); for( j = 0; j < A->m; ++j ) { row(*A,j,row); row_j = rows[j] = copy_sparse_vec( &row ); if( row_j->nnz > 0 ) { i = *(row_j->is); b = *(row_j->vs); while( i < j ) { row_i = rows[i]; if( row_i->nnz == 0 || *(row_i->is) > i ) a = 0.0; else a = *(row_i->vs); cblas_drotg( &a, &b, &c, &s ); sp_apply_grot( c, s, rows+i, rows+j ); left_comp_rotation( &grots, i, j, c, s ); row_j = rows[j]; if( row_j->nnz == 0 ) break; i = *(row_j->is); b = *(row_j->vs); } } } *Q = sparse_mat_rotation( grots ); *R = sparse_mat_rows( A->n, rows ); free_rotation( grots ); for( j = 0; j < A->m; ++j ) free( rows[j] ); free( rows ); }
//=========================================================================== int cHydraDevice::getRotation(cMatrix3d& a_rotation) { /************************************************************************ STEP 7: Here you may implement code which reads the orientation frame from your haptic device. The orientation frame is expressed by a 3x3 rotation matrix. The 1st column of this matrix corresponds to the x-axis, the 2nd column to the y-axis and the 3rd column to the z-axis. The length of each column vector should be of length 1 and vectors need to be perpendicular to each other. If the operation fails return an error code such as -1 for instance. Note: If your device is located in front of you, the x-axis is pointing towards you (the operator). The y-axis points towards your right hand side and the z-axis points up towards the sky. If your device has a stylus, make sure that you set the reference frame so that the x-axis corresponds to the axis of the stylus. *************************************************************************/ int error = 0; double r00, r01, r02, r10, r11, r12, r20, r21, r22; cMatrix3d frame; frame.identity(); // *** INSERT YOUR CODE HERE, MODIFY CODE BELLOW ACCORDINGLY *** // if the device does not provide any rotation capabilities // we set the rotation matrix equal to the identiy matrix. sixenseAllControllerData acd; sixenseGetAllNewestData( &acd ); // sixense is COLUMN MAJOR! r00 = acd.controllers[a_deviceNumber].rot_mat[0][0]; r01 = acd.controllers[a_deviceNumber].rot_mat[1][0]; r02 = acd.controllers[a_deviceNumber].rot_mat[2][0]; r10 = acd.controllers[a_deviceNumber].rot_mat[0][1]; r11 = acd.controllers[a_deviceNumber].rot_mat[1][1]; r12 = acd.controllers[a_deviceNumber].rot_mat[2][1]; r20 = acd.controllers[a_deviceNumber].rot_mat[0][2]; r21 = acd.controllers[a_deviceNumber].rot_mat[1][2]; r22 = acd.controllers[a_deviceNumber].rot_mat[2][2]; frame.set(r00, r01, r02, r10, r11, r12, r20, r21, r22); cMatrix3d permute_rows(0, 0, 1, 1, 0, 0, 0, 1, 0); cMatrix3d permute_columns(0, 1, 0, 0, 0, 1, 1, 0, 0); a_rotation = permute_rows*frame*permute_columns; // estimate angular velocity estimateAngularVelocity(a_rotation); // exit return (error); }