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