SIRIUS 7.5.0
Electronic structure library and applications
inverse_sqrt.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2023 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file inverse_sqrt.hpp
21 *
22 * \brief Compute inverse square root of the matrix.
23 */
24
25#ifndef __INVERSE_SQRT_HPP__
26#define __INVERSE_SQRT_HPP__
27
28#include "core/la/dmatrix.hpp"
30#include "core/la/linalg.hpp"
31#include "core/rte/rte.hpp"
32
33namespace sirius {
34
35namespace la {
36
37/// Compute inverse square root of the matrix.
38/** As by-product, return the eigen-vectors and the eigen-values of the matrix. */
39template <typename T>
40inline auto
42{
43 auto solver = (A__.comm().size() == 1) ? la::Eigensolver_factory("lapack") : la::Eigensolver_factory("scalapack");
44
45 std::unique_ptr<la::dmatrix<T>> Z;
46 std::unique_ptr<la::dmatrix<T>> B;
47 if (A__.comm().size() == 1) {
48 Z = std::make_unique<la::dmatrix<T>>(A__.num_rows(), A__.num_cols());
49 B = std::make_unique<la::dmatrix<T>>(A__.num_rows(), A__.num_cols());
50 } else {
51 Z = std::make_unique<la::dmatrix<T>>(A__.num_rows(), A__.num_cols(), A__.blacs_grid(), A__.bs_row(), A__.bs_col());
52 B = std::make_unique<la::dmatrix<T>>(A__.num_rows(), A__.num_cols(), A__.blacs_grid(), A__.bs_row(), A__.bs_col());
53 }
54 std::vector<real_type<T>> eval(N__);
55
56 if (solver->solve(N__, N__, A__, &eval[0], *Z)) {
57 RTE_THROW("error in diagonalization");
58 }
59 for (int i = 0; i < Z->num_cols_local(); i++) {
60 int icol = Z->icol(i);
61 RTE_ASSERT(eval[icol] > 0);
62 auto f = 1.0 / std::sqrt(eval[icol]);
63 for (int j = 0; j < Z->num_rows_local(); j++) {
64 A__(j, i) = (*Z)(j, i) * static_cast<T>(f);
65 }
66 }
67
68 if (A__.comm().size() == 1) {
69 la::wrap(la::lib_t::blas).gemm('N', 'C', N__, N__, N__, &la::constant<T>::one(),
70 &A__(0, 0), A__.ld(), Z->at(sddk::memory_t::host), Z->ld(), &la::constant<T>::zero(),
71 B->at(sddk::memory_t::host), B->ld());
72 } else {
73 la::wrap(la::lib_t::scalapack).gemm('N', 'C', N__, N__, N__, &la::constant<T>::one(),
74 A__, 0, 0, *Z, 0, 0, &la::constant<T>::zero(), *B, 0, 0);
75 }
76
77 return std::make_tuple(std::move(B), std::move(Z), eval);
78}
79
80}
81
82}
83#endif
Distributed matrix.
Definition: dmatrix.hpp:56
int num_rows() const
Return number of rows in the global matrix.
Definition: dmatrix.hpp:145
int bs_row() const
Row blocking factor.
Definition: dmatrix.hpp:301
int bs_col() const
Column blocking factor.
Definition: dmatrix.hpp:307
void gemm(char transa, char transb, ftn_int m, ftn_int n, ftn_int k, T const *alpha, T const *A, ftn_int lda, T const *B, ftn_int ldb, T const *beta, T *C, ftn_int ldc, acc::stream_id sid=acc::stream_id(-1)) const
General matrix-matrix multiplication.
uint32_t ld() const
Return leading dimension size.
Definition: memory.hpp:1233
Contains definition and implementation of distributed matrix class.
Contains definition of eigensolver factory.
Linear algebra interface.
auto inverse_sqrt(la::dmatrix< T > &A__, int N__)
Compute inverse square root of the matrix.
@ scalapack
CPU ScaLAPACK.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
Eror and warning handling during run-time execution.