YAKL
YAKL_tridiagonal.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include "YAKL.h"
5 
6 
8 namespace yakl {
9 
10 
50  template <class real, unsigned int n>
52  SArray<real,1,n> tmp;
53  // Save the original "b0" because it's needed later on to compute ( (v^T*y) / (1 + v^T*q) )
54  real b0 = b(0);
55 
56  // This is the vector "u"
57  tmp(0 ) = -b0;
58  tmp(n-1) = c(n-1);
59 
60  // The new tridiagonal system "B" alters the entries of the main diagonal
61  b(n-1) = b(n-1) + a(0)*c(n-1)/b(0);
62  b(0 ) = b(0 ) + b(0);
63 
64  // Thomas algorithm for B*y=d and B*q=u simultaneously to save cost
65  real div = static_cast<real>(1) / b(0);
66  c (0) *= div;
67  d (0) *= div;
68  tmp(0) *= div;
69  for (int i = 1; i < n-1; i++) {
70  div = static_cast<real>(1) / (b(i) - a(i)*c(i-1));
71  c (i) = c(i) * div;
72  d (i) = (d(i) - a(i)*d (i-1)) * div;
73  tmp(i) = ( - a(i)*tmp(i-1)) * div;
74  }
75  div = static_cast<real>(1) / (b(n-1) - a(n-1)*c(n-2));
76  d (n-1) = (d (n-1) - a(n-1)*d (n-2)) * div;
77  tmp(n-1) = (tmp(n-1) - a(n-1)*tmp(n-2)) * div;
78  for (int i = n-2; i >= 0; i--) {
79  d (i) -= c(i)*d (i+1);
80  tmp(i) -= c(i)*tmp(i+1);
81  }
82 
83  // Compute factor = ( (v^T*y) / (1 + v^T*q) )
84  real factor;
85  if ( (tmp(0) - a(0)*tmp(n-1)/b0 + static_cast<real>(1)) == 0 ) {
86  factor = 0;
87  } else {
88  factor = (d(0) - a(0)*d(n-1)/b0)/(tmp(0) - a(0)*tmp(n-1)/b0 + static_cast<real>(1));
89  }
90 
91  // Subtract factor * q from the previous solution to get the final solution
92  for (int i = 0; i < n; i++) {
93  d(i) -= factor*tmp(i);
94  }
95  }
96 
97 
98 
118  template <class real, unsigned int n>
120  real tmp = static_cast<real>(1) / b(0);
121  c(0) *= tmp;
122  d(0) *= tmp;
123  for (int i = 1; i < n-1; i++) {
124  real tmp = static_cast<real>(1) / (b(i) - a(i)*c(i-1));
125  c(i) *= tmp;
126  d(i) = (d(i) - a(i)*d(i-1)) * tmp;
127  }
128  d(n-1) = (d(n-1) - a(n-1)*d(n-2)) / (b(n-1) - a(n-1)*c(n-2));
129  for (int i = n-2; i >= 0; i--) {
130  d(i) -= c(i)*d(i+1);
131  }
132  }
133 
134 }
136 
137 
YAKL.h
__YAKL_NAMESPACE_WRAPPER_END__
#define __YAKL_NAMESPACE_WRAPPER_END__
Definition: YAKL.h:20
__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::tridiagonal_periodic
YAKL_INLINE void tridiagonal_periodic(SArray< real, 1, n > const &a, SArray< real, 1, n > &b, SArray< real, 1, n > &c, SArray< real, 1, n > &d)
Performs a small periodic tridiagional solve. Click for more details.
Definition: YAKL_tridiagonal.h:51
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::tridiagonal
YAKL_INLINE void tridiagonal(SArray< real, 1, n > const &a, SArray< real, 1, n > const &b, SArray< real, 1, n > &c, SArray< real, 1, n > &d)
Solves a small non-periodic tridiagional system.
Definition: YAKL_tridiagonal.h:119