dla_syamv.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /* dla_syamv.f -- translated by f2c (version 20061008).
  2. You must link the resulting object file with libf2c:
  3. on Microsoft Windows system, link with libf2c.lib;
  4. on Linux or Unix systems, link with .../path/to/libf2c.a -lm
  5. or, if you install libf2c.a in a standard place, with -lf2c -lm
  6. -- in that order, at the end of the command line, as in
  7. cc *.o -lf2c -lm
  8. Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
  9. http://www.netlib.org/f2c/libf2c.zip
  10. */
  11. #include "f2c.h"
  12. #include "blaswrap.h"
  13. /* Subroutine */ int dla_syamv__(integer *uplo, integer *n, doublereal *alpha,
  14. doublereal *a, integer *lda, doublereal *x, integer *incx,
  15. doublereal *beta, doublereal *y, integer *incy)
  16. {
  17. /* System generated locals */
  18. integer a_dim1, a_offset, i__1, i__2;
  19. doublereal d__1;
  20. /* Builtin functions */
  21. double d_sign(doublereal *, doublereal *);
  22. /* Local variables */
  23. integer i__, j;
  24. logical symb_zero__;
  25. integer iy, jx, kx, ky, info;
  26. doublereal temp, safe1;
  27. extern doublereal dlamch_(char *);
  28. extern /* Subroutine */ int xerbla_(char *, integer *);
  29. extern integer ilauplo_(char *);
  30. /* -- LAPACK routine (version 3.2) -- */
  31. /* -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */
  32. /* -- Jason Riedy of Univ. of California Berkeley. -- */
  33. /* -- November 2008 -- */
  34. /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
  35. /* -- Univ. of California Berkeley and NAG Ltd. -- */
  36. /* .. */
  37. /* .. Scalar Arguments .. */
  38. /* .. */
  39. /* .. Array Arguments .. */
  40. /* .. */
  41. /* Purpose */
  42. /* ======= */
  43. /* DLA_SYAMV performs the matrix-vector operation */
  44. /* y := alpha*abs(A)*abs(x) + beta*abs(y), */
  45. /* where alpha and beta are scalars, x and y are vectors and A is an */
  46. /* n by n symmetric matrix. */
  47. /* This function is primarily used in calculating error bounds. */
  48. /* To protect against underflow during evaluation, components in */
  49. /* the resulting vector are perturbed away from zero by (N+1) */
  50. /* times the underflow threshold. To prevent unnecessarily large */
  51. /* errors for block-structure embedded in general matrices, */
  52. /* "symbolically" zero components are not perturbed. A zero */
  53. /* entry is considered "symbolic" if all multiplications involved */
  54. /* in computing that entry have at least one zero multiplicand. */
  55. /* Parameters */
  56. /* ========== */
  57. /* UPLO - INTEGER */
  58. /* On entry, UPLO specifies whether the upper or lower */
  59. /* triangular part of the array A is to be referenced as */
  60. /* follows: */
  61. /* UPLO = BLAS_UPPER Only the upper triangular part of A */
  62. /* is to be referenced. */
  63. /* UPLO = BLAS_LOWER Only the lower triangular part of A */
  64. /* is to be referenced. */
  65. /* Unchanged on exit. */
  66. /* N - INTEGER. */
  67. /* On entry, N specifies the number of columns of the matrix A. */
  68. /* N must be at least zero. */
  69. /* Unchanged on exit. */
  70. /* ALPHA - DOUBLE PRECISION . */
  71. /* On entry, ALPHA specifies the scalar alpha. */
  72. /* Unchanged on exit. */
  73. /* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). */
  74. /* Before entry, the leading m by n part of the array A must */
  75. /* contain the matrix of coefficients. */
  76. /* Unchanged on exit. */
  77. /* LDA - INTEGER. */
  78. /* On entry, LDA specifies the first dimension of A as declared */
  79. /* in the calling (sub) program. LDA must be at least */
  80. /* max( 1, n ). */
  81. /* Unchanged on exit. */
  82. /* X - DOUBLE PRECISION array of DIMENSION at least */
  83. /* ( 1 + ( n - 1 )*abs( INCX ) ) */
  84. /* Before entry, the incremented array X must contain the */
  85. /* vector x. */
  86. /* Unchanged on exit. */
  87. /* INCX - INTEGER. */
  88. /* On entry, INCX specifies the increment for the elements of */
  89. /* X. INCX must not be zero. */
  90. /* Unchanged on exit. */
  91. /* BETA - DOUBLE PRECISION . */
  92. /* On entry, BETA specifies the scalar beta. When BETA is */
  93. /* supplied as zero then Y need not be set on input. */
  94. /* Unchanged on exit. */
  95. /* Y - DOUBLE PRECISION array of DIMENSION at least */
  96. /* ( 1 + ( n - 1 )*abs( INCY ) ) */
  97. /* Before entry with BETA non-zero, the incremented array Y */
  98. /* must contain the vector y. On exit, Y is overwritten by the */
  99. /* updated vector y. */
  100. /* INCY - INTEGER. */
  101. /* On entry, INCY specifies the increment for the elements of */
  102. /* Y. INCY must not be zero. */
  103. /* Unchanged on exit. */
  104. /* Level 2 Blas routine. */
  105. /* -- Written on 22-October-1986. */
  106. /* Jack Dongarra, Argonne National Lab. */
  107. /* Jeremy Du Croz, Nag Central Office. */
  108. /* Sven Hammarling, Nag Central Office. */
  109. /* Richard Hanson, Sandia National Labs. */
  110. /* -- Modified for the absolute-value product, April 2006 */
  111. /* Jason Riedy, UC Berkeley */
  112. /* .. */
  113. /* .. Parameters .. */
  114. /* .. */
  115. /* .. Local Scalars .. */
  116. /* .. */
  117. /* .. External Subroutines .. */
  118. /* .. */
  119. /* .. External Functions .. */
  120. /* .. */
  121. /* .. Intrinsic Functions .. */
  122. /* .. */
  123. /* .. Executable Statements .. */
  124. /* Test the input parameters. */
  125. /* Parameter adjustments */
  126. a_dim1 = *lda;
  127. a_offset = 1 + a_dim1;
  128. a -= a_offset;
  129. --x;
  130. --y;
  131. /* Function Body */
  132. info = 0;
  133. if (*uplo != ilauplo_("U") && *uplo != ilauplo_("L")
  134. ) {
  135. info = 1;
  136. } else if (*n < 0) {
  137. info = 2;
  138. } else if (*lda < max(1,*n)) {
  139. info = 5;
  140. } else if (*incx == 0) {
  141. info = 7;
  142. } else if (*incy == 0) {
  143. info = 10;
  144. }
  145. if (info != 0) {
  146. xerbla_("DSYMV ", &info);
  147. return 0;
  148. }
  149. /* Quick return if possible. */
  150. if (*n == 0 || *alpha == 0. && *beta == 1.) {
  151. return 0;
  152. }
  153. /* Set up the start points in X and Y. */
  154. if (*incx > 0) {
  155. kx = 1;
  156. } else {
  157. kx = 1 - (*n - 1) * *incx;
  158. }
  159. if (*incy > 0) {
  160. ky = 1;
  161. } else {
  162. ky = 1 - (*n - 1) * *incy;
  163. }
  164. /* Set SAFE1 essentially to be the underflow threshold times the */
  165. /* number of additions in each row. */
  166. safe1 = dlamch_("Safe minimum");
  167. safe1 = (*n + 1) * safe1;
  168. /* Form y := alpha*abs(A)*abs(x) + beta*abs(y). */
  169. /* The O(N^2) SYMB_ZERO tests could be replaced by O(N) queries to */
  170. /* the inexact flag. Still doesn't help change the iteration order */
  171. /* to per-column. */
  172. iy = ky;
  173. if (*incx == 1) {
  174. i__1 = *n;
  175. for (i__ = 1; i__ <= i__1; ++i__) {
  176. if (*beta == 0.) {
  177. symb_zero__ = TRUE_;
  178. y[iy] = 0.;
  179. } else if (y[iy] == 0.) {
  180. symb_zero__ = TRUE_;
  181. } else {
  182. symb_zero__ = FALSE_;
  183. y[iy] = *beta * (d__1 = y[iy], abs(d__1));
  184. }
  185. if (*alpha != 0.) {
  186. i__2 = *n;
  187. for (j = 1; j <= i__2; ++j) {
  188. if (*uplo == ilauplo_("U")) {
  189. if (i__ <= j) {
  190. temp = (d__1 = a[i__ + j * a_dim1], abs(d__1));
  191. } else {
  192. temp = (d__1 = a[j + i__ * a_dim1], abs(d__1));
  193. }
  194. } else {
  195. if (i__ >= j) {
  196. temp = (d__1 = a[i__ + j * a_dim1], abs(d__1));
  197. } else {
  198. temp = (d__1 = a[j + i__ * a_dim1], abs(d__1));
  199. }
  200. }
  201. symb_zero__ = symb_zero__ && (x[j] == 0. || temp == 0.);
  202. y[iy] += *alpha * (d__1 = x[j], abs(d__1)) * temp;
  203. }
  204. }
  205. if (! symb_zero__) {
  206. y[iy] += d_sign(&safe1, &y[iy]);
  207. }
  208. iy += *incy;
  209. }
  210. } else {
  211. i__1 = *n;
  212. for (i__ = 1; i__ <= i__1; ++i__) {
  213. if (*beta == 0.) {
  214. symb_zero__ = TRUE_;
  215. y[iy] = 0.;
  216. } else if (y[iy] == 0.) {
  217. symb_zero__ = TRUE_;
  218. } else {
  219. symb_zero__ = FALSE_;
  220. y[iy] = *beta * (d__1 = y[iy], abs(d__1));
  221. }
  222. jx = kx;
  223. if (*alpha != 0.) {
  224. i__2 = *n;
  225. for (j = 1; j <= i__2; ++j) {
  226. if (*uplo == ilauplo_("U")) {
  227. if (i__ <= j) {
  228. temp = (d__1 = a[i__ + j * a_dim1], abs(d__1));
  229. } else {
  230. temp = (d__1 = a[j + i__ * a_dim1], abs(d__1));
  231. }
  232. } else {
  233. if (i__ >= j) {
  234. temp = (d__1 = a[i__ + j * a_dim1], abs(d__1));
  235. } else {
  236. temp = (d__1 = a[j + i__ * a_dim1], abs(d__1));
  237. }
  238. }
  239. symb_zero__ = symb_zero__ && (x[j] == 0. || temp == 0.);
  240. y[iy] += *alpha * (d__1 = x[jx], abs(d__1)) * temp;
  241. jx += *incx;
  242. }
  243. }
  244. if (! symb_zero__) {
  245. y[iy] += d_sign(&safe1, &y[iy]);
  246. }
  247. iy += *incy;
  248. }
  249. }
  250. return 0;
  251. /* End of DLA_SYAMV */
  252. } /* dla_syamv__ */