TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
jackknife.hpp
Go to the documentation of this file.
1// Copyright (c) 2018 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2018 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2018-2021 Simons Foundation
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 may obtain a copy of the License at
16// https://www.gnu.org/licenses/gpl-3.0.txt
17//
18// Authors: Philipp Dumitrescu, Olivier Parcollet, Nils Wentzell
19
24
25#pragma once
26
27#include "./concepts.hpp"
28#include "./mean_error.hpp"
29
30#include <mpi/mpi.hpp>
31#include <nda/nda.hpp>
32
33#include <cstddef>
34#include <optional>
35#include <ranges>
36#include <stdexcept>
37#include <tuple>
38#include <type_traits>
39#include <utility>
40
41namespace triqs::stat {
42
47
48 namespace detail {
49
50 // Implementation of the jackknife resampling.
51 auto jackknife_impl(std::optional<mpi::communicator> comm, auto &&f, StatCompatibleRange auto &&...rgs) { // NOLINT (ranges need not be forwarded)
52 // check that the ranges all have the same size
53 auto rgs_tup = std::tie(rgs...);
54 auto size = std::ranges::size(std::get<0>(rgs_tup));
55 if (((std::ranges::size(rgs) != size) or ...)) throw std::runtime_error("Error in jackknife: Ranges must have the same size.");
56
57 // all_reduce the size of the ranges if a communicator is provided
58 if (comm) mpi::all_reduce_in_place(size, *comm);
59
60 // get the mean and the jackknife samples of each range and store them in a tuple
61 auto [mean_tup, jk_tup] = [&comm, size, &rgs_tup]<std::size_t... Is>(std::index_sequence<Is...>) {
62 auto mtup = std::make_tuple(mean_mpi(comm, std::get<Is>(rgs_tup))...);
63 auto jtup = std::make_tuple(std::ranges::transform_view(
64 std::get<Is>(rgs_tup), [m = std::get<Is>(mtup), size](auto const &x) { return (size * m - x) / (size - 1); })...);
65 return std::make_pair(mtup, jtup);
66 }(std::make_index_sequence<sizeof...(rgs)>{});
67
68 // get a zipped view of the jackknife samples from all the ranges
69 auto zipped = std::apply([](auto &&...jks) { return std::ranges::zip_view(jks...); }, jk_tup);
70
71 // compute the jackknife mean and error (we need regular types to avoid dangling references)
72 auto f_wrapped = [f](auto const &...args) { return nda::make_regular(f(args...)); };
73 auto [jk_f, jk_err] = mean_and_err_mpi<error_tag::jk_err>(
74 comm, std::ranges::transform_view(zipped, [f_wrapped](auto const &tup) { return std::apply(f_wrapped, tup); }));
75
76 // compute the naive estimate of f(...) and the bias corrected estimate
77 auto naive_f = nda::make_regular(std::apply(f, mean_tup));
78 auto corr_f = nda::make_regular(size * naive_f - (size - 1) * jk_f);
79
80 return std::make_tuple(corr_f, jk_err, jk_f, naive_f);
81 }
82
83 } // namespace detail
84
118 template <typename F, StatCompatibleRange R, StatCompatibleRange... Rs>
119 requires(not std::same_as<std::remove_cvref_t<F>, mpi::communicator>)
120 auto jackknife(F &&f, R &&rg, Rs &&...rgs) { // NOLINT (ranges need not be forwarded)
121 return detail::jackknife_impl(std::nullopt, std::forward<F>(f), rg, rgs...);
122 }
123
139 template <typename F, StatCompatibleRange R, StatCompatibleRange... Rs>
140 auto jackknife_mpi(mpi::communicator comm, F &&f, R &&rg, Rs &&...rgs) { // NOLINT (ranges need not be forwarded)
141 return detail::jackknife_impl(comm, std::forward<F>(f), rg, rgs...);
142 }
143
145
146} // namespace triqs::stat
int size() const
Get the total number of blocks.
Concept to check if a range can be used with various Statistical analysis tools.
Definition concepts.hpp:71
auto mean_and_err_mpi(std::optional< mpi::communicator > c, R &&rg)
Calculate the arithmetic mean or the simple sum as well as a corresponding error estimate of some ran...
auto mean_mpi(std::optional< mpi::communicator > c, R &&rg)
Calculate the arithmetic mean or the simple sum of some range of values spread across multiple MPI pr...
auto jackknife(F &&f, R &&rg, Rs &&...rgs)
Perform jackknife resampling.
auto jackknife_mpi(mpi::communicator comm, F &&f, R &&rg, Rs &&...rgs)
Perform jackknife resampling with MPI support.
Provides functions to calculate the arithmetic mean and standard error of a range of values.
Provides various concepts for the Utilities.