cholesky.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2020 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Eduard Valeyev
19  *
20  * cholesky.h
21  * Created: 16 October, 2020
22  *
23  */
24 #ifndef TILEDARRAY_MATH_LINALG_NON_DISTRIBUTED_CHOL_H__INCLUDED
25 #define TILEDARRAY_MATH_LINALG_NON_DISTRIBUTED_CHOL_H__INCLUDED
26 
27 #include <TiledArray/config.h>
28 
32 
34 
35 template <typename Tile, typename Policy>
38  using numeric_type = typename Array::numeric_type;
39  static_assert(std::is_same_v<numeric_type, typename Array::element_type>,
40  "TA::lapack::{cholesky*} are only usable with a DistArray of "
41  "scalar types");
42 
43  World& world = A.world();
44  auto A_eig = detail::make_matrix(A);
45  if (world.rank() == 0) {
47  }
48  world.gop.broadcast_serializable(A_eig, 0);
49  return A_eig;
50 }
51 
70 template <typename Array,
71  typename = std::enable_if_t<TiledArray::detail::is_array_v<Array>>>
72 auto cholesky(const Array& A, TiledRange l_trange = TiledRange()) {
73  auto L_eig = rank_local_cholesky(A);
75  if (l_trange.rank() == 0) l_trange = A.trange();
76  return eigen_to_array<Array>(A.world(), l_trange, L_eig);
77 }
78 
96 template <typename ContiguousTensor,
97  typename = std::enable_if_t<
98  TiledArray::detail::is_contiguous_tensor_v<ContiguousTensor>>>
99 auto cholesky(const ContiguousTensor& A) {
100  auto A_eig = detail::make_matrix(A);
103  return detail::make_array<ContiguousTensor>(A_eig, A.range());
104 }
105 
127 template <bool Both, typename Array,
128  typename = std::enable_if_t<TiledArray::detail::is_array_v<Array>>>
129 auto cholesky_linv(const Array& A, TiledRange l_trange = TiledRange()) {
130  World& world = A.world();
131  auto L_eig = rank_local_cholesky(A);
132  if constexpr (Both) detail::zero_out_upper_triangle(L_eig);
133 
134  // if need to return L use its copy to compute inverse
135  decltype(L_eig) L_inv_eig;
136 
137  if (world.rank() == 0) {
138  if (Both) L_inv_eig = L_eig;
139  auto& L_inv_eig_ref = Both ? L_inv_eig : L_eig;
140  linalg::rank_local::cholesky_linv(L_inv_eig_ref);
141  detail::zero_out_upper_triangle(L_inv_eig_ref);
142  }
143  world.gop.broadcast_serializable(Both ? L_inv_eig : L_eig, 0);
144 
145  if (l_trange.rank() == 0) l_trange = A.trange();
146  if constexpr (Both)
147  return std::make_tuple(eigen_to_array<Array>(world, l_trange, L_eig),
148  eigen_to_array<Array>(world, l_trange, L_inv_eig));
149  else
150  return eigen_to_array<Array>(world, l_trange, L_eig);
151  abort(); // unreachable
152 }
153 
154 template <typename Array,
155  typename = std::enable_if_t<TiledArray::detail::is_array_v<Array>>>
156 auto cholesky_solve(const Array& A, const Array& B,
157  TiledRange x_trange = TiledRange()) {
158  using numeric_type = typename Array::numeric_type;
159  static_assert(std::is_same_v<numeric_type, typename Array::element_type>,
160  "TA::lapack::{cholesky*} are only usable with a DistArray of "
161  "scalar types");
162 
163  auto A_eig = detail::make_matrix(A);
164  auto X_eig = detail::make_matrix(B);
165  World& world = A.world();
166  if (world.rank() == 0) {
168  }
169  world.gop.broadcast_serializable(X_eig, 0);
170  if (x_trange.rank() == 0) x_trange = B.trange();
171  return eigen_to_array<Array>(world, x_trange, X_eig);
172 }
173 
174 template <typename Array,
175  typename = std::enable_if_t<TiledArray::detail::is_array_v<Array>>>
176 auto cholesky_lsolve(Op transpose, const Array& A, const Array& B,
177  TiledRange l_trange = TiledRange(),
178  TiledRange x_trange = TiledRange()) {
179  World& world = A.world();
180  auto L_eig = rank_local_cholesky(A);
182 
183  using numeric_type = typename Array::numeric_type;
184  static_assert(std::is_same_v<numeric_type, typename Array::element_type>,
185  "TA::lapack::{cholesky*} are only usable with a DistArray of "
186  "scalar types");
187 
188  auto X_eig = detail::make_matrix(B);
189  if (world.rank() == 0) {
191  }
192  world.gop.broadcast_serializable(X_eig, 0);
193  if (l_trange.rank() == 0) l_trange = A.trange();
194  if (x_trange.rank() == 0) x_trange = B.trange();
195  return std::make_tuple(eigen_to_array<Array>(world, l_trange, L_eig),
196  eigen_to_array<Array>(world, x_trange, X_eig));
197 }
198 
199 } // namespace TiledArray::math::linalg::non_distributed
200 
201 #endif // TILEDARRAY_MATH_LINALG_NON_DISTRIBUTED_CHOL_H__INCLUDED
void cholesky_solve(Matrix< T > &A, Matrix< T > &X)
Definition: rank-local.cpp:91
void cholesky_linv(Matrix< T > &A)
Definition: rank-local.cpp:81
detail::numeric_type< Tile >::type numeric_type
Definition: dist_array.h:69
auto cholesky_lsolve(Op transpose, const Array &A, const Array &B, TiledRange l_trange=TiledRange(), TiledRange x_trange=TiledRange())
Definition: cholesky.h:176
auto cholesky(const Array &A, TiledRange l_trange=TiledRange())
Compute the Cholesky factorization of a HPD rank-2 tensor.
Definition: cholesky.h:72
Range data of a tiled array.
Definition: tiled_range.h:32
DistArray< Tile, Policy > Array
const trange_type & trange() const
Tiled range accessor.
Definition: dist_array.h:917
void transpose(InputOp &&input_op, OutputOp &&output_op, const std::size_t m, const std::size_t n, const std::size_t result_stride, Result *result, const std::size_t arg_stride, const Args *const ... args)
Matrix transpose and initialization.
Definition: transpose.h:178
auto rank_local_cholesky(const DistArray< Tile, Policy > &A)
Definition: cholesky.h:36
void zero_out_upper_triangle(Eigen::MatrixBase< Derived > &A)
Definition: util.h:107
Forward declarations.
Definition: dist_array.h:57
World & world() const
World accessor.
Definition: dist_array.h:1007
auto cholesky_solve(const Array &A, const Array &B, TiledRange x_trange=TiledRange())
Definition: cholesky.h:156
auto cholesky_linv(const Array &A, TiledRange l_trange=TiledRange())
Compute the inverse of the Cholesky factor of an HPD rank-2 tensor. Optionally return the Cholesky fa...
Definition: cholesky.h:129
void cholesky_lsolve(Op transpose, Matrix< T > &A, Matrix< T > &X)
Definition: rank-local.cpp:103
auto make_matrix(const DistArray< Tile, Policy > &A)
Definition: util.h:46