Blender V2.61 - r43446
|
00001 00004 int strsv_(char *, char *, char *, int *, float *, int *, float *, int *); 00005 00006 00007 /* Subroutine */ int strsv_(char *uplo, char *trans, char *diag, int *n, 00008 float *a, int *lda, float *x, int *incx) 00009 { 00010 00011 00012 /* Local variables */ 00013 static int info; 00014 static float temp; 00015 static int i, j; 00016 extern int lsame_(char *, char *); 00017 static int ix, jx, kx; 00018 extern /* Subroutine */ int xerbla_(char *, int *); 00019 static int nounit; 00020 00021 00022 /* Purpose 00023 ======= 00024 00025 STRSV solves one of the systems of equations 00026 00027 A*x = b, or A'*x = b, 00028 00029 where b and x are n element vectors and A is an n by n unit, or 00030 non-unit, upper or lower triangular matrix. 00031 00032 No test for singularity or near-singularity is included in this 00033 routine. Such tests must be performed before calling this routine. 00034 00035 Parameters 00036 ========== 00037 00038 UPLO - CHARACTER*1. 00039 On entry, UPLO specifies whether the matrix is an upper or 00040 lower triangular matrix as follows: 00041 00042 UPLO = 'U' or 'u' A is an upper triangular matrix. 00043 00044 UPLO = 'L' or 'l' A is a lower triangular matrix. 00045 00046 Unchanged on exit. 00047 00048 TRANS - CHARACTER*1. 00049 On entry, TRANS specifies the equations to be solved as 00050 follows: 00051 00052 TRANS = 'N' or 'n' A*x = b. 00053 00054 TRANS = 'T' or 't' A'*x = b. 00055 00056 TRANS = 'C' or 'c' A'*x = b. 00057 00058 Unchanged on exit. 00059 00060 DIAG - CHARACTER*1. 00061 On entry, DIAG specifies whether or not A is unit 00062 triangular as follows: 00063 00064 DIAG = 'U' or 'u' A is assumed to be unit triangular. 00065 00066 DIAG = 'N' or 'n' A is not assumed to be unit 00067 triangular. 00068 00069 Unchanged on exit. 00070 00071 N - INTEGER. 00072 On entry, N specifies the order of the matrix A. 00073 N must be at least zero. 00074 Unchanged on exit. 00075 00076 A - REAL array of DIMENSION ( LDA, n ). 00077 Before entry with UPLO = 'U' or 'u', the leading n by n 00078 upper triangular part of the array A must contain the upper 00079 00080 triangular matrix and the strictly lower triangular part of 00081 00082 A is not referenced. 00083 Before entry with UPLO = 'L' or 'l', the leading n by n 00084 lower triangular part of the array A must contain the lower 00085 00086 triangular matrix and the strictly upper triangular part of 00087 00088 A is not referenced. 00089 Note that when DIAG = 'U' or 'u', the diagonal elements of 00090 00091 A are not referenced either, but are assumed to be unity. 00092 Unchanged on exit. 00093 00094 LDA - INTEGER. 00095 On entry, LDA specifies the first dimension of A as declared 00096 00097 in the calling (sub) program. LDA must be at least 00098 max( 1, n ). 00099 Unchanged on exit. 00100 00101 X - REAL array of dimension at least 00102 ( 1 + ( n - 1 )*abs( INCX ) ). 00103 Before entry, the incremented array X must contain the n 00104 element right-hand side vector b. On exit, X is overwritten 00105 00106 with the solution vector x. 00107 00108 INCX - INTEGER. 00109 On entry, INCX specifies the increment for the elements of 00110 X. INCX must not be zero. 00111 Unchanged on exit. 00112 00113 00114 Level 2 Blas routine. 00115 00116 -- Written on 22-October-1986. 00117 Jack Dongarra, Argonne National Lab. 00118 Jeremy Du Croz, Nag Central Office. 00119 Sven Hammarling, Nag Central Office. 00120 Richard Hanson, Sandia National Labs. 00121 00122 00123 00124 Test the input parameters. 00125 00126 00127 Parameter adjustments 00128 Function Body */ 00129 #define X(I) x[(I)-1] 00130 00131 #define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] 00132 00133 info = 0; 00134 if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { 00135 info = 1; 00136 } else if (! lsame_(trans, "N") && ! lsame_(trans, "T") && 00137 ! lsame_(trans, "C")) { 00138 info = 2; 00139 } else if (! lsame_(diag, "U") && ! lsame_(diag, "N")) { 00140 info = 3; 00141 } else if (*n < 0) { 00142 info = 4; 00143 } else if (*lda < ((1 > *n)? 1: *n)) { 00144 info = 6; 00145 } else if (*incx == 0) { 00146 info = 8; 00147 } 00148 if (info != 0) { 00149 xerbla_("STRSV ", &info); 00150 return 0; 00151 } 00152 00153 /* Quick return if possible. */ 00154 00155 if (*n == 0) { 00156 return 0; 00157 } 00158 00159 nounit = lsame_(diag, "N"); 00160 00161 /* Set up the start point in X if the increment is not unity. This 00162 will be ( N - 1 )*INCX too small for descending loops. */ 00163 00164 if (*incx <= 0) { 00165 kx = 1 - (*n - 1) * *incx; 00166 } else if (*incx != 1) { 00167 kx = 1; 00168 } 00169 00170 /* Start the operations. In this version the elements of A are 00171 accessed sequentially with one pass through A. */ 00172 00173 if (lsame_(trans, "N")) { 00174 00175 /* Form x := inv( A )*x. */ 00176 00177 if (lsame_(uplo, "U")) { 00178 if (*incx == 1) { 00179 for (j = *n; j >= 1; --j) { 00180 if (X(j) != 0.f) { 00181 if (nounit) { 00182 X(j) /= A(j,j); 00183 } 00184 temp = X(j); 00185 for (i = j - 1; i >= 1; --i) { 00186 X(i) -= temp * A(i,j); 00187 /* L10: */ 00188 } 00189 } 00190 /* L20: */ 00191 } 00192 } else { 00193 jx = kx + (*n - 1) * *incx; 00194 for (j = *n; j >= 1; --j) { 00195 if (X(jx) != 0.f) { 00196 if (nounit) { 00197 X(jx) /= A(j,j); 00198 } 00199 temp = X(jx); 00200 ix = jx; 00201 for (i = j - 1; i >= 1; --i) { 00202 ix -= *incx; 00203 X(ix) -= temp * A(i,j); 00204 /* L30: */ 00205 } 00206 } 00207 jx -= *incx; 00208 /* L40: */ 00209 } 00210 } 00211 } else { 00212 if (*incx == 1) { 00213 for (j = 1; j <= *n; ++j) { 00214 if (X(j) != 0.f) { 00215 if (nounit) { 00216 X(j) /= A(j,j); 00217 } 00218 temp = X(j); 00219 for (i = j + 1; i <= *n; ++i) { 00220 X(i) -= temp * A(i,j); 00221 /* L50: */ 00222 } 00223 } 00224 /* L60: */ 00225 } 00226 } else { 00227 jx = kx; 00228 for (j = 1; j <= *n; ++j) { 00229 if (X(jx) != 0.f) { 00230 if (nounit) { 00231 X(jx) /= A(j,j); 00232 } 00233 temp = X(jx); 00234 ix = jx; 00235 for (i = j + 1; i <= *n; ++i) { 00236 ix += *incx; 00237 X(ix) -= temp * A(i,j); 00238 /* L70: */ 00239 } 00240 } 00241 jx += *incx; 00242 /* L80: */ 00243 } 00244 } 00245 } 00246 } else { 00247 00248 /* Form x := inv( A' )*x. */ 00249 00250 if (lsame_(uplo, "U")) { 00251 if (*incx == 1) { 00252 for (j = 1; j <= *n; ++j) { 00253 temp = X(j); 00254 for (i = 1; i <= j-1; ++i) { 00255 temp -= A(i,j) * X(i); 00256 /* L90: */ 00257 } 00258 if (nounit) { 00259 temp /= A(j,j); 00260 } 00261 X(j) = temp; 00262 /* L100: */ 00263 } 00264 } else { 00265 jx = kx; 00266 for (j = 1; j <= *n; ++j) { 00267 temp = X(jx); 00268 ix = kx; 00269 for (i = 1; i <= j-1; ++i) { 00270 temp -= A(i,j) * X(ix); 00271 ix += *incx; 00272 /* L110: */ 00273 } 00274 if (nounit) { 00275 temp /= A(j,j); 00276 } 00277 X(jx) = temp; 00278 jx += *incx; 00279 /* L120: */ 00280 } 00281 } 00282 } else { 00283 if (*incx == 1) { 00284 for (j = *n; j >= 1; --j) { 00285 temp = X(j); 00286 for (i = *n; i >= j+1; --i) { 00287 temp -= A(i,j) * X(i); 00288 /* L130: */ 00289 } 00290 if (nounit) { 00291 temp /= A(j,j); 00292 } 00293 X(j) = temp; 00294 /* L140: */ 00295 } 00296 } else { 00297 kx += (*n - 1) * *incx; 00298 jx = kx; 00299 for (j = *n; j >= 1; --j) { 00300 temp = X(jx); 00301 ix = kx; 00302 for (i = *n; i >= j+1; --i) { 00303 temp -= A(i,j) * X(ix); 00304 ix -= *incx; 00305 /* L150: */ 00306 } 00307 if (nounit) { 00308 temp /= A(j,j); 00309 } 00310 X(jx) = temp; 00311 jx -= *incx; 00312 /* L160: */ 00313 } 00314 } 00315 } 00316 } 00317 00318 return 0; 00319 00320 /* End of STRSV . */ 00321 00322 } /* strsv_ */ 00323