LINEAR++ library: AFF to LAPACK
blas++.h
Go to the documentation of this file.
1 // LAPACK++ (V. 1.1)
2 // Copyright (c) 1992 by J. J. Dongarra, E. Greaser, R. Pozo, D. Walker
3 // see file README.lapack++
4 
5 #ifndef _BLAS_PP_H_
6 #define _BLAS_PP_H_
7 
8 // requires
9 //
10 
11 #include "laexcp.h"
12 #include "blas1++.h"
13 #include "blas2++.h"
14 #include "blas3++.h"
15 
16 double abs(double);
17 
18 //-------------------------------------
19 // Vector/Vector operators
20 //-------------------------------------
21 
22 #ifdef _LA_VECTOR_DOUBLE_H_
23 
24 inline LaVectorDouble operator*(const LaVectorDouble &x, double a)
25 {
26  int N = x.size();
27  LaVectorDouble t(N);
28 
29  for (int i=0; i<N; i++)
30  {
31  t(i) = a * x(i);
32  }
33 
34  return t;
35 }
36 
37 inline LaVectorDouble operator*(double a, const LaVectorDouble &x)
38 {
39  return operator*(x,a);
40 }
41 
42 inline double operator*(const LaVectorDouble &dx,
43  const LaVectorDouble &dy)
44 {
45  assert(dx.size()==dy.size());
46  integer incx = dx.inc(), incy = dy.inc(), n = dx.size();
47 
48  return F77NAME(ddot)(&n, &dx(0), &incx, &dy(0), &incy);
49 }
50 
51 inline LaVectorDouble operator+(const LaVectorDouble &dx,
52  const LaVectorDouble &dy)
53 {
54  assert(dx.size()==dy.size());
55  integer incx = dx.inc(), incy = dx.inc(), n = dx.size();
56  double da = 1.0;
57 
58  LaVectorDouble tmp((int) n);
59  tmp = dy;
60 
61  F77NAME(daxpy)(&n, &da, &dx(0), &incx, &tmp(0), &incy);
62  return tmp;
63 }
64 
65 inline LaVectorDouble operator-(const LaVectorDouble &dx,
66  const LaVectorDouble &dy)
67 {
68  assert(dx.size()==dy.size());
69  integer incx = dx.inc(), incy = dy.inc(), n = dx.size();
70  double da = -1.0;
71 
72  LaVectorDouble tmp(n);
73  tmp = dx;
74 
75  F77NAME(daxpy)(&n, &da, &dy(0), &incx, &tmp(0), &incy);
76  return tmp;
77 }
78 
79 //-------------------------------------
80 // Matrix/Vector operators
81 //-------------------------------------
82 
83 #ifdef _LA_GEN_MAT_DOUBLE_H_
84 inline LaVectorDouble operator*(const LaGenMatDouble &A,
85  const LaVectorDouble &dx)
86 {
87  char trans = 'N';
88  double alpha = 1.0, beta = 0.0;
89  integer M = A.size(0), N = A.size(1), lda = A.gdim(0);
90 
91  LaVectorDouble dy(M);
92  integer incx = dx.inc();
93  integer incy = dy.inc();
94 
95  dy = 0.0;
96 
97  F77NAME(dgemv)(&trans, &M, &N, &alpha, &A(0,0), &lda, &dx(0), &incx,
98  &beta, &dy(0), &incy);
99  return dy;
100 
101 }
102 #endif
103 
104 #ifdef _LA_BAND_MAT_DOUBLE_H_
105 inline LaVectorDouble operator*(const LaBandMatDouble &A,
106  const LaVectorDouble &dx)
107 {
108  char trans = 'N';
109  double alpha = 1.0, beta = 0.0;
110  integer M = A.size(0), N = A.size(1), lda = A.gdim(0),
111  kl = A.subdiags(), ku = A.superdiags();
112 
113  LaVectorDouble dy(N);
114  integer incx = dx.inc(), incy = dy.inc();
115 
116  F77NAME(dgbmv)(&trans, &M, &N, &kl, &ku, &alpha, &A(0,0), &lda,
117  &dx(0), &incx, &beta, &dy(0), &incy);
118  return dy;
119 }
120 #endif
121 
122 #ifdef _LA_SYMM_MAT_DOUBLE_H_
123 inline LaVectorDouble operator*(const LaSymmMatDouble &A,
124  const LaVectorDouble &dx)
125 {
126  char uplo = 'L';
127  double alpha = 1.0, beta = 0.0;
128  integer N = A.size(1), lda = A.gdim(0);
129 
130  LaVectorDouble dy(N);
131  integer incx = dx.inc(), incy = dy.inc();
132 
133  F77NAME(dsymv)(&uplo, &N, &alpha, &A(0,0), &lda, &dx(0), &incx,
134  &beta, &dy(0), &incy);
135  return dy;
136 }
137 #endif
138 
139 #ifdef _LA_SYMM_BAND_MAT_DOUBLE_H_
140 inline LaVectorDouble operator*(const LaSymmBandMatDouble &A,
141  const LaVectorDouble &dx)
142 {
143  char uplo = 'L';
144  double alpha = 1.0, beta = 0.0;
145  integer N = A.size(1), lda = A.gdim(0), k = A.subdiags();
146 
147  LaVectorDouble dy(N);
148  integer incx = dx.inc(), incy = dy.inc();
149 
150  F77NAME(dsbmv)(&uplo, &N, &k, &alpha, &A(0,0), &lda, &dx(0), &incx,
151  &beta, &dy(0), &incy);
152  return dy;
153 }
154 
155 #endif
156 
157 
158 #ifdef _LA_SPD_MAT_DOUBLE_H_
159 inline LaVectorDouble operator*(const LaSpdMatDouble &AP,
160  const LaVectorDouble &dx)
161 {
162  char uplo = 'L';
163  double alpha = 1.0, beta = 0.0;
164  integer N = AP.size(1), incx = dx.inc();
165  integer lda = AP.gdim(0);
166 
167  LaVectorDouble dy(N);
168  integer incy = dy.inc();
169 
170  F77NAME(dsymv)(&uplo, &N, &alpha, &AP(0,0), &lda, &dx(0), &incx, &beta,
171  &dy(0), &incy);
172  return dy;
173 }
174 #endif
175 
176 #ifdef _LA_LOWER_TRIANG_MAT_DOUBLE_H_
177 inline LaVectorDouble operator*(const LaLowerTriangMatDouble &A,
178  const LaVectorDouble &dx)
179 {
180  char uplo = 'L', trans = 'N', diag = 'N';
181  integer N = A.size(1), lda = A.gdim(0),
182  incx = dx.inc();
183 
184  LaVectorDouble dy(dx);
185 
186  F77NAME(dtrmv)(&uplo, &trans, &diag, &N, &A(0,0), &lda, &dy(0), &incx);
187 
188  return dy;
189 }
190 #endif
191 
192 #ifdef _LA_UPPER_TRIANG_MAT_DOUBLE_H_
193 inline LaVectorDouble operator*(const LaUpperTriangMatDouble &A,
194  const LaVectorDouble &dx)
195 {
196  char uplo = 'U', trans = 'N', diag = 'N';
197  integer N = A.size(1), lda = A.gdim(0),
198  incx = dx.inc();
199 
200  LaVectorDouble dy(dx);
201 
202  F77NAME(dtrmv)(&uplo, &trans, &diag, &N, &A(0,0), &lda, &dy(0), &incx);
203 
204  return dy;
205 }
206 #endif
207 
208 #ifdef _LA_UNIT_LOWER_TRIANG_MAT_DOUBLE_H_
209 inline LaVectorDouble operator*(const LaUnitLowerTriangMatDouble &A,
210  const LaVectorDouble &dx)
211 {
212  char uplo = 'L', trans = 'N', diag = 'U';
213  integer N = A.size(1), lda = A.gdim(0),
214  incx = dx.inc();
215 
216  LaVectorDouble dy(dx);
217 
218  F77NAME(dtrmv)(&uplo, &trans, &diag, &N, &A(0,0), &lda, &dy(0), &incx);
219 
220  return dy;
221 }
222 
223 #endif
224 
225 #ifdef _LA_UNIT_UPPER_TRIANG_MAT_DOUBLE_H_
226 inline LaVectorDouble operator*(const LaUnitUpperTriangMatDouble &A,
227  const LaVectorDouble &dx)
228 {
229  char uplo = 'U', trans = 'N', diag = 'U';
230  integer N = A.size(1), lda = A.gdim(0),
231  incx = dx.inc();
232 
233  LaVectorDouble dy(dx);
234 
235  F77NAME(dtrmv)(&uplo, &trans, &diag, &N, &A(0,0), &lda, &dy(0), &incx);
236 
237  return dy;
238 }
239 #endif
240 
241 
242 //-------------------------------------
243 // Matrix/Matrix operators
244 //-------------------------------------
245 
246 inline LaGenMatDouble operator*(const LaGenMatDouble &A,
247  const LaGenMatDouble &B)
248 {
249  char t = 'N';
250  integer m = A.size(0), k = A.size(1), n = B.size(1);
251  integer lda = A.gdim(0), ldb = B.gdim(0);
252  double alpha = 1.0, beta = 1.0;
253 
254  LaGenMatDouble C(m,n);
255  integer ldc = A.gdim(0);
256 
257  C = 0.0;
258 
259  F77NAME(dgemm)(&t, &t, &m, &n, &k, &alpha, &A(0,0), &lda, &B(0,0), &ldb,
260  &beta, &C(0,0), &ldc);
261 
262  return C;
263 }
264 
265 #ifdef _LA_UNIT_LOWER_TRIANG_MAT_DOUBLE_H_
266 inline LaGenMatDouble operator*(const LaUnitLowerTriangMatDouble &A,
267  const LaGenMatDouble &B)
268 {
269  char side = 'L', uplo = 'L', transa = 'N', diag = 'U';
270  double alpha = 1.0;
271  integer m = B.size(0), n = B.size(1),
272  lda = A.gdim(0), ldb = B.gdim(0);
273 
274  LaGenMatDouble C(B);
275 
276  F77NAME(dtrmm)(&side, &uplo, &transa, &diag, &m, &n, &alpha,
277  &A(0,0), &lda, &C(0,0), &ldb);
278 
279  return C;
280 }
281 #endif
282 
283 #ifdef _LA_UNIT_UPPER_TRIANG_MAT_DOUBLE_H_
284 inline LaGenMatDouble operator*(const LaUnitUpperTriangMatDouble &A,
285  const LaGenMatDouble &B)
286 {
287  char side = 'L', uplo = 'U', transa = 'N', diag = 'U';
288  double alpha = 1.0;
289  integer m = B.size(0), n = B.size(1),
290  lda = A.gdim(0), ldb = B.gdim(0);
291 
292  LaGenMatDouble C(B);
293 
294  F77NAME(dtrmm)(&side, &uplo, &transa, &diag, &m, &n, &alpha,
295  &A(0,0), &lda, &C(0,0), &ldb);
296 
297  return C;
298 }
299 #endif
300 
301 #ifdef _LA_LOWER_TRIANG_MAT_DOUBLE_H_
302 inline LaGenMatDouble operator*(const LaLowerTriangMatDouble &A,
303  const LaGenMatDouble &B)
304 {
305  char side = 'L', uplo = 'L', transa = 'N', diag = 'N';
306  double alpha = 1.0;
307  integer m = B.size(0), n = B.size(1),
308  lda = A.gdim(0), ldb = B.gdim(0);
309 
310  LaGenMatDouble C(B);
311 
312  F77NAME(dtrmm)(&side, &uplo, &transa, &diag, &m, &n, &alpha,
313  &A(0,0), &lda, &C(0,0), &ldb);
314 
315  return C;
316 }
317 #endif
318 
319 #ifdef _LA_UPPER_TRIANG_MAT_DOUBLE_H_
320 inline LaGenMatDouble operator*(const LaUpperTriangMatDouble &A,
321  const LaGenMatDouble &B)
322 {
323  char side = 'L', uplo = 'U', transa = 'N', diag = 'N';
324  double alpha = 1.0;
325  integer m = B.size(0), n = B.size(1),
326  lda = A.gdim(0), ldb = B.gdim(0);
327 
328  LaGenMatDouble C(B);
329 
330  F77NAME(dtrmm)(&side, &uplo, &transa, &diag, &m, &n, &alpha,
331  &A(0,0), &lda, &C(0,0), &ldb);
332 
333  return C;
334 }
335 #endif
336 
337 #ifdef _LA_SYMM_MAT_DOUBLE_H_
338 inline LaGenMatDouble operator*(const LaSymmMatDouble &A,
339  const LaGenMatDouble &B)
340 {
341  char side = 'L', uplo = 'L';
342  double alpha = 1.0, beta = 1.0;
343  LaGenMatDouble C(B.size(1),A.size(1));
344  integer m = C.size(0), n = C.size(1), lda = A.gdim(0),
345  ldb = B.gdim(0), ldc = C.gdim(0);
346 
347  F77NAME(dsymm)(&side, &uplo, &m, &n, &alpha, &A(0,0), &lda,
348  &B(0,0), &ldb, &beta, &C(0,0), &ldc);
349 
350  return C;
351 }
352 #endif
353 
354 #ifdef _LA_SYMM_TRIDIAG_MAT_DOUBLE_H_
355 inline LaVectorDouble operator*(const LaSymmTridiagMatDouble& A,
356  const LaVectorDouble& X)
357 {
358  integer M = A.size();
359  integer N = X.size();
360  LaVectorDouble R(M);
361 
362  R(0) = ((A.diag(0)(0) * X(0)) + (A.diag(-1)(0) * X(1)));
363 
364  for (integer i = 1; i < M-2; i++)
365  {
366  R(i) = ((A.diag(-1)(i-1) * X(i-1)) +
367  (A.diag(0)(i) * X(i)) +
368  (A.diag(-1)(i) * X(i+1)));
369  }
370 
371  R(M-1) = ((A.diag(0)(M-1) * X(N-1)) + (A.diag(-1)(M-2) * X(N-2)));
372 
373  return R;
374 }
375 #endif
376 
377 #ifdef _LA_TRIDIAG_MAT_DOUBLE_H_
378 inline LaVectorDouble operator*(const LaTridiagMatDouble& A,
379  const LaVectorDouble& X)
380 {
381  integer M = A.size();
382  integer N = X.size();
383  LaVectorDouble R(M);
384 
385  R(0) = ((A.diag(0)(0) * X(0)) + (A.diag(-1)(0) * X(1)));
386 
387  for (integer i = 1; i < M-2; i++)
388  {
389  R(i) = ((A.diag(-1)(i-1) * X(i-1)) +
390  (A.diag(0)(i) * X(i)) +
391  (A.diag(1)(i) * X(i+1)));
392  }
393 
394  R(M-1) = ((A.diag(0)(M-1) * X(N-1)) + (A.diag(1)(M-2) * X(N-2)));
395 
396  return R;
397 }
398 #endif
399 
400 inline LaGenMatDouble operator-(const LaGenMatDouble &A,
401  const LaGenMatDouble &B)
402 {
403 #ifndef HPPA
404  const char fname[] = "operator+(A,B)";
405 #else
406  char *fname = NULL;
407 #endif
408 
409  integer M = A.size(0);
410  integer N = A.size(1);
411 
412  if (M != B.size(0) || N != B.size(1))
413  {
414  throw(LaException(fname, "matrices non-conformant."));
415  }
416 
417  LaGenMatDouble C(M,N);
418 
419  // slow mode
420  // we'll hook the BLAS in later
421 
422  for (integer i=0; i<M; i++)
423  for(integer j=0; j<N; j++)
424  C(i,j) = A(i,j) - B(i,j);
425 
426  return C;
427 }
428 
429 inline LaGenMatDouble operator+(const LaGenMatDouble &A,
430  const LaGenMatDouble &B)
431 {
432 #ifndef HPPA
433  const char fname[] = "operator+(A,B)";
434 #else
435  char *fname = NULL;
436 #endif
437 
438  integer M = A.size(0);
439  integer N = A.size(1);
440 
441  if (M != B.size(0) || N != B.size(1))
442  {
443  throw(LaException(fname, "matrices non-conformant."));
444  }
445 
446  LaGenMatDouble C(M,N);
447 
448  // slow mode
449  // we'll hook the BLAS in later
450 
451  for (integer i=0; i<M; i++)
452  for(integer j=0; j<N; j++)
453  C(i,j) = A(i,j) + B(i,j);
454 
455  return C;
456 }
457 
458 
459 //-------------------------------------
460 // Matrix/Vector Norms
461 //-------------------------------------
462 
463 inline double Norm_Inf(const LaVectorDouble &x)
464 {
465 
466  integer index = Blas_Index_Max(x);
467  return abs(x(index));
468 }
469 
470 inline double Norm_Inf(const LaGenMatDouble &A)
471 {
472  integer M=A.size(0);
473  integer index;
474 
475  // max row-sum
476 
477  LaVectorDouble R(M);
478 
479  for (integer i=0; i<M; i++)
480  R(i) = Blas_Norm1( A( i, LaIndex() ));
481 
482  index = Blas_Index_Max(R);
483  return R(index);
484 }
485 
486 #ifdef _LA_BAND_MAT_DOUBLE_H_
487 inline double Norm_Inf(const LaBandMatDouble &A)
488 {
489  integer kl = A.subdiags(), ku = A.superdiags();
490  integer N=A.size(1);
491  integer M=N;
492 
493  // slow version
494 
495  LaVectorDouble R(M);
496  integer i;
497  integer j;
498  for (integer i=0; i<M; i++)
499  {
500  R(i) = 0.0;
501  for (j=0; j<N; j++)
502  R(i) += abs(A(i,j));
503  }
504 
505  double max = R(0);
506 
507  // report back largest row sum
508  for (i=1; i<M; i++)
509  if (R(i) > max) max=R(i);
510 
511  return max;
512 }
513 #endif
514 
515 #ifdef _LA_SYMM_MAT_DOUBLE_H_
516 inline double Norm_Inf(const LaSymmMatDouble &S)
517 {
518  integer N = S.size(0); // square matrix
519 
520  // slow version
521 
522  LaVectorDouble R(N);
523  integer i;
524  integer j;
525 
526  for (i=0; i<N; i++)
527  {
528  R(i) = 0.0;
529  for (j=0; j<N; j++)
530  R(i) += abs(S(i,j));
531  }
532 
533  double max = R(0);
534 
535  // report back largest row sum
536  for (i=1; i<N; i++)
537  if (R(i) > max) max=R(i);
538 
539  return max;
540 }
541 #endif
542 
543 #ifdef _LA_SPD_MAT_DOUBLE_H_
544 inline double Norm_Inf(const LaSpdMatDouble &S)
545 {
546  integer N = S.size(0); //SPD matrices are square
547 
548  // slow version
549 
550  LaVectorDouble R(N);
551  integer i;
552  integer j;
553 
554  for (i=0; i<N; i++)
555  {
556  R(i) = 0.0;
557  for (j=0; j<N; j++)
558  R(i) += abs(S(i,j));
559  }
560 
561  double max = R(0);
562 
563  // report back largest row sum
564  for (i=1; i<N; i++)
565  if (R(i) > max) max=R(i);
566 
567  return max;
568 }
569 #endif
570 
571 #ifdef _LA_SYMM_TRIDIAG_MAT_DOUBLE_H_
572 inline double Norm_Inf(const LaSymmTridiagMatDouble &S)
573 {
574  integer N = S.size(); // S is square
575  LaVectorDouble R(N);
576 
577  R(0) = abs(S(0,0)) + abs(S(0,1));
578 
579  for (integer i=1; i<N-1; i++)
580  {
581  R(i) = abs(S(i,i-1)) + abs(S(i,i)) + abs(S(i,i+1));
582  }
583 
584  R(N-1) = abs(S(N-1,N-2)) + abs(S(N-1,N-1));
585 
586  return Norm_Inf(R);
587 }
588 #endif
589 
590 #ifdef _LA_TRIDIAG_MAT_DOUBLE_H_
591 inline double Norm_Inf(const LaTridiagMatDouble &T)
592 {
593  integer N = T.size(); // T is square
594  LaVectorDouble R(N);
595 
596  R(0) = abs(T(0,0)) + abs(T(0,1));
597 
598  for (int i=1; i<N-1; i++)
599  {
600  R(i) = abs(T(i,i-1)) + abs(T(i,i)) + abs(T(i,i+1));
601  }
602 
603  R(N-1) = abs(T(N-1,N-2)) + abs(T(N-1,N-1));
604 
605  return Norm_Inf(R);
606 }
607 #endif
608 
609 
610 #endif
611  // LA_VECTOR_DOUBLE_H
612 #endif
613  // _BLAS_PP_H_
double abs(double)
void F77NAME() dgemv(char *trans, integer *M, integer *N, double *alpha, const double *A, integer *lda, const double *dx, integer *incx, double *beta, double *dy, integer *incy)
void F77NAME() dtrmm(char *side, char *uplo, char *transa, char *diag, integer *m, integer *n, double *alpha, const double *A, integer *lda, const double *B, integer *ldb)
void F77NAME() daxpy(const integer *n, const double *da, const double *dx, const integer *incx, double *dy, const integer *incy)
void F77NAME() dgemm(char *transa, char *transb, integer *m, integer *n, integer *k, double *alpha, const double *a, integer *lda, const double *b, integer *ldb, double *beta, double *c, integer *ldc)
long int integer
Definition: f77lapack.h:61
void F77NAME() dtrmv(char *uplo, char *trans, char *diag, const integer *N, const double *A, integer *lda, const double *dx, integer *incx)
void F77NAME() dsbmv(char *uplo, integer *N, integer *k, double *alpha, const double *A, integer *lda, const double *dx, integer *incx, double *beta, double *dy, integer *incy)
void F77NAME() dsymv(char *uplo, integer *N, double *alpha, const double *A, integer *lda, const double *dx, integer *incx, double *beta, double *dy, integer *incy)
void F77NAME() dgbmv(char *trans, integer *M, integer *N, integer *kl, integer *ku, double *alpha, const double *A, integer *lda, const double *dx, integer *incx, double *beta, double *dy, integer *incy)
void F77NAME() dsymm(char *side, char *uplo, integer *m, integer *n, double *alpha, const double *A, integer *lda, const double *B, integer *ldb, double *beta, double *C, integer *ldc)
#define F77NAME(x)
Definition: arch.h:17
double F77NAME() ddot(const integer *n, const double *dx, const integer *incx, const double *dy, const integer *incy)