YAKL
YAKL_intrinsics_matinv.h
Go to the documentation of this file.
1 
2 #pragma once
3 // Included by YAKL_intrinsics.h
4 
6 namespace yakl {
7  namespace intrinsics {
8 
9  template <unsigned int n, class real>
11  SArray<real,2,n,n> scratch;
13 
14  // Initialize inverse as identity
15  for (int icol = 0; icol < n; icol++) {
16  for (int irow = 0; irow < n; irow++) {
17  scratch(icol,irow) = a(icol,irow);
18  if (icol == irow) {
19  inv(irow,icol) = 1;
20  } else {
21  inv(irow,icol) = 0;
22  }
23  }
24  }
25 
26  // Gaussian elimination to zero out lower
27  for (int idiag = 0; idiag < n; idiag++) {
28  // Divide out the diagonal component from the first row
29  real factor = static_cast<real>(1)/scratch(idiag,idiag);
30  for (int icol = idiag; icol < n; icol++) {
31  scratch(idiag,icol) *= factor;
32  }
33  for (int icol = 0; icol < n; icol++) {
34  inv(idiag,icol) *= factor;
35  }
36  for (int irow = idiag+1; irow < n; irow++) {
37  real factor = scratch(irow,idiag);
38  for (int icol = idiag; icol < n; icol++) {
39  scratch(irow,icol) -= factor * scratch(idiag,icol);
40  }
41  for (int icol = 0; icol < n; icol++) {
42  inv (irow,icol) -= factor * inv (idiag,icol);
43  }
44  }
45  }
46 
47  // Gaussian elimination to zero out upper
48  for (int idiag = n-1; idiag >= 1; idiag--) {
49  for (int irow = 0; irow < idiag; irow++) {
50  real factor = scratch(irow,idiag);
51  for (int icol = irow+1; icol < n; icol++) {
52  scratch(irow,icol) -= factor * scratch(idiag,icol);
53  }
54  for (int icol = 0; icol < n; icol++) {
55  inv (irow,icol) -= factor * inv (idiag,icol);
56  }
57  }
58  }
59 
60  return inv;
61  }
62 
63 
64  template <int n, class real>
66  FSArray<real,2,SB<n>,SB<n>> scratch;
68 
69  // Initialize inverse as identity
70  for (int icol = 0; icol < n; icol++) {
71  for (int irow = 0; irow < n; irow++) {
72  scratch(icol+1,irow+1) = a(icol+1,irow+1);
73  if (icol == irow) {
74  inv(irow+1,icol+1) = 1;
75  } else {
76  inv(irow+1,icol+1) = 0;
77  }
78  }
79  }
80 
81  // Gaussian elimination to zero out lower
82  for (int idiag = 0; idiag < n; idiag++) {
83  // Divide out the diagonal component from the first row
84  real factor = static_cast<real>(1)/scratch(idiag+1,idiag+1);
85  for (int icol = idiag; icol < n; icol++) {
86  scratch(idiag+1,icol+1) *= factor;
87  }
88  for (int icol = 0; icol < n; icol++) {
89  inv(idiag+1,icol+1) *= factor;
90  }
91  for (int irow = idiag+1; irow < n; irow++) {
92  real factor = scratch(irow+1,idiag+1);
93  for (int icol = idiag; icol < n; icol++) {
94  scratch(irow+1,icol+1) -= factor * scratch(idiag+1,icol+1);
95  }
96  for (int icol = 0; icol < n; icol++) {
97  inv (irow+1,icol+1) -= factor * inv (idiag+1,icol+1);
98  }
99  }
100  }
101 
102  // Gaussian elimination to zero out upper
103  for (int idiag = n-1; idiag >= 1; idiag--) {
104  for (int irow = 0; irow < idiag; irow++) {
105  real factor = scratch(irow+1,idiag+1);
106  for (int icol = irow+1; icol < n; icol++) {
107  scratch(irow+1,icol+1) -= factor * scratch(idiag+1,icol+1);
108  }
109  for (int icol = 0; icol < n; icol++) {
110  inv (irow+1,icol+1) -= factor * inv (idiag+1,icol+1);
111  }
112  }
113  }
114 
115  return inv;
116  }
117 
118  }
119 }
121 
__YAKL_NAMESPACE_WRAPPER_END__
#define __YAKL_NAMESPACE_WRAPPER_END__
Definition: YAKL.h:20
yakl::SB
This specifies a set of bounds for a dimension when declaring a yakl::FSArray.
Definition: YAKL_FSArray.h:18
__YAKL_NAMESPACE_WRAPPER_BEGIN__
#define __YAKL_NAMESPACE_WRAPPER_BEGIN__
Definition: YAKL.h:19
YAKL_INLINE
#define YAKL_INLINE
Used to decorate functions called from kernels (parallel_for and parallel_outer) or from CPU function...
Definition: YAKL_defines.h:140
yakl::CSArray
C-style array on the stack similar in nature to, e.g., float arr[ny][nx];
Definition: YAKL_CSArray.h:30
yakl
yakl::intrinsics::matinv_ge
YAKL_INLINE SArray< real, 2, n, n > matinv_ge(SArray< real, 2, n, n > const &a)
Definition: YAKL_intrinsics_matinv.h:10
yakl::FSArray
Fortran-style array on the stack similar in nature to, e.g., float arr[ny][nx];
Definition: YAKL_FSArray.h:53