dnl ********************************************************************** dnl Perform x = alpha * inverse(T) * x dnl ********************************************************************** dnl #include #include "blas_extended.h" #include "blas_extended_private.h" include(cblas.m4)dnl include(trsv-common.m4)dnl dnl dnl dnl ---------------------------------------------------------------------- dnl Usage: TRSV_COMMENT(ax_typeltr, T_typeltr, _x) dnl ... generate the leading comment for the TRSV routine dnl ---------------------------------------------------------------------- dnl define(`TRSV_COMMENT',` /* * Purpose * ======= * * This routine solve : * * x <- alpha * inverse(T) * x * * Arguments * ========= * * order (input) enum blas_order_type * column major, row major * * uplo (input) enum blas_uplo_type * upper, lower * * trans (input) enum blas_trans_type * no trans, trans, conj trans * * diag (input) enum blas_diag_type * unit, non unit * * n (input) int * the dimension of T * * alpha (input) $1_scalar * * T (input) $2_array * Triangular matrix * * x (input) const $1_array * Array of length n. * * incx (input) int * The stride used to access components x[i]. * PREC_COMMENT($3)dnl */')dnl dnl dnl dnl dnl -------------------------------------------------------------------- dnl Usage: TRSV_INIT(ax_typeltr, T_typeltr, _x) dnl declare trsv local variables, and check inputs dnl -------------------------------------------------------------------- dnl define(`TRSV_INIT', ` int i, j; /* used to idx matrix */ int ix, jx; /* used to idx vector x */ int start_x; /* used as the starting idx to vector x */ PTR_CAST(T, $2_type, `const') /* internal matrix T */ PTR_CAST(x, $1_type, `') /* internal x */ SCALAR_CAST(alpha, $1_type) /* internal alpha */ DECLARE(T_element, $2_type) /* temporary variable for an element of matrix A */ int incT=1; /* internal ldt */ if ((order != blas_rowmajor && order != blas_colmajor) || (uplo != blas_upper && uplo != blas_lower) || (trans != blas_trans && trans != blas_no_trans && trans != blas_conj_trans) || (diag != blas_non_unit_diag && diag != blas_unit_diag) || (ldt < n) || (incx == 0)){ BLAS_error(routine_name, 0, 0, NULL); } if (n <= 0) return; INC_ADJUST(incT, $2_type) INC_ADJUST(incx, $1_type) /* configuring the vector starting idx */ if (incx <= 0) { start_x = -(n-1)*incx; } else { start_x = 0; } /* if alpha is zero, then return x as a zero vector */ if (TEST_0(alpha_i, $1_type)) { ix = start_x; for(i=0; i=0; j--) { /* compute Xj = alpha*Xj - SUM Tij(or Tji) * Xi i=j+1 to n-1 */ GET_ARRAY_ELEMENT(temp3, $2, x_i, $3, jx) MUL(temp1, $2, temp3, $2, alpha_i, $3) ix=start_x+(n-1)*incx; for (i=n-1; i>=j+1; i--) { GET_MATRIX_ELEMENT(T_element, T_i, $4*incT, $5, ldt*incT, $1) CONJ(T_element, $1, $6) GET_ARRAY_ELEMENT(temp3, $2, x_i, $3, ix) MUL(temp2, $2, temp3, $2, T_element, $1) SUB(temp1, $2, temp1, $2, temp2, $2) ix -= incx; } /* for j=0 */')dnl dnl dnl dnl dnl --------------------------------------------------------------------- dnl Usage: TRSV2_BACKWARD_SUBST(T_typeltr, internal_prec, x_typeltr, col, row, conj) dnl perform backward substitution to compute dnl x = alpha * inverse(T) * x dnl dnl col and row are used to index a matrix element. dnl The possible pairs of (col, row) values are (i, j) or (j, i) dnl dnl TRSV2_BACKWARD_SUBST is used by a matrix of type: dnl 1. blas_rowmajor, blas_no_trans, blas_upper (i, j) dnl 2. blas_colmajor, blas_trans/blas_conj_trans, blas_lower(i, j) dnl 3. blas_rowmajor, blas_trans/blas_conj_trans, blas_lower(j, i) dnl 4. blas_colmajor, blas_no_trans, blas_upper (j, i) dnl --------------------------------------------------------------------- define(`TRSV2_BACKWARD_SUBST', ` jx = (n-1)*inc_intx; for(j=n-1; j>=0; j--) { /* compute Xj = alpha*Xj - SUM Aij(or Aji) * Xi i=j+1 to n-1 */ GET_ARRAY_ELEMENT(temp3, $2, intx, $2, jx) /* multiply by alpha */ MUL(temp1, $2, temp3, $2, alpha_i, $3) ix=(n-1)*inc_intx; for (i=n-1; i>=j+1; i--) { GET_MATRIX_ELEMENT(T_element, T_i, $4*incT, $5, ldt*incT, $1) CONJ(T_element, $1, $6) GET_ARRAY_ELEMENT(temp3, $2, intx, $2, ix) MUL(temp2, $2, temp3, $2, T_element, $1) SUB(temp1, $2, temp1, $2, temp2, $2) ix -= inc_intx; } /* for j=0 */')dnl dnl dnl dnl --------------------------------------------------------------------- dnl Usage: TRSV1_FORWARD_SUBST(T_typeltr, internal_prec, x_typeltr, col, row) dnl perform forward substitution to compute dnl x = alpha * inverse(T) * x dnl dnl col and row are used to index a matrix element. dnl The possible pairs of (col, row) values are (i, j) or (j, i) dnl dnl TRSV1_FORWARD_SUBST is used by a matrix of type: dnl 1. blas_rowmajor, blas_no_trans, blas_lower (i, j) dnl 2. blas_colmajor, blas_trans/blas_conj_trans, blas_upper(i, j) dnl 3. blas_rowmajor, blas_trans/blas_conj_trans, blas_upper(j, i) dnl 4. blas_colmajor, blas_no_trans, blas_lower (j, i) dnl --------------------------------------------------------------------- define(`TRSV1_FORWARD_SUBST', ` jx = start_x; for(j=0; j= $1_type. Therefore, dnl if ($1_type == $3) then do not need to allocate memory, dnl so use TRSV1 instead of TRSV2 dnl case blas_prec_single: ifelse(`$3', `$4', `', ` ifelse(`$1', `$3', `TRSV1($1, $2, $3)', `TRSV2($1, $2, $3)') break; ')dnl dnl dnl likewise if ($1 == $4) dnl case blas_prec_double: case blas_prec_indigenous: ifelse(`$1', `$4', `TRSV1($1, $2, $4)', `TRSV2($1, $2, $4)') break; case blas_prec_extra: dnl dnl since $5 > $1, use TRSV2 dnl { FPU_FIX_DECL; FPU_FIX_START; { TRSV2($1, $2, $5) } FPU_FIX_STOP; } break; }')dnl dnl dnl dnl dnl -------------------------------------------------------------------- dnl Usage: TRSV_X_BODY(ax_prec, T_prec) ... dispatches dnl TRSV with appropriate type and precision info of dnl the specified internal prec. dnl -------------------------------------------------------------------- dnl define(`TRSV_X_BODY', `SWITCH_prec($1, $2, TMP_TYPE_X($1, S), TMP_TYPE_X($1, D), TMP_TYPE_X($1, E))')dnl dnl dnl define(`TRSV_BODY', `TRSV1($1, $2, $3)')dnl dnl dnl define(`TRSV', ` TRSV_HEAD($1, $2, $3) TRSV_COMMENT($1, $2, $3) { char *routine_name = "TRSV_NAME($1, $2)"; TRSV_INIT($1, $2, $3) ifelse($3, _x, `TRSV_X_BODY($1_type, $2_type)', `TRSV_BODY($1_type, $2_type, $1_type)') } ')dnl dnl dnl