TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
fundamental_operator_set.cpp
Go to the documentation of this file.
1// Copyright (c) 2015-2018 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2015-2018 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2018-2022 Simons Foundation
4// Copyright (c) 2015 Igor Krivenko
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You may obtain a copy of the License at
17// https://www.gnu.org/licenses/gpl-3.0.txt
18//
19// Authors: Michel Ferrero, Igor Krivenko, Olivier Parcollet, Nils Wentzell
20
25
28
29#include <fmt/format.h>
30#include <fmt/ranges.h>
31#include <h5/h5.hpp>
32#include <itertools/itertools.hpp>
33
34#include <string>
35#include <string_view>
36#include <variant>
37#include <vector>
38
39namespace triqs::hilbert_space {
40
41 namespace {
42
43 // A little visitor for reduction to string.
44 struct variant_visitor {
45 std::string operator()(long i) const { return "i" + std::to_string(i); }
46 std::string operator()(std::string const &s) const { return "s" + s; }
47 std::string operator()(double d) const { return "d" + std::to_string(d); }
48 std::string operator()(std::array<long, 3> const &a) const {
49 return "idx" + std::to_string(a[0]) + "," + std::to_string(a[1]) + "," + std::to_string(a[2]);
50 }
51 };
52
53 // Decode the string.
54 std::variant<long, std::string, double, std::array<long, 3>> string_to_variant(std::string const &s) {
55 if (s.substr(0, 3) == "idx") {
56 // Parse array: "idx0,1,2" -> {0, 1, 2}
57 std::array<long, 3> arr{};
58 auto rest = s.substr(3);
59 size_t pos1 = rest.find(',');
60 size_t pos2 = rest.find(',', pos1 + 1);
61 arr[0] = std::stol(rest.substr(0, pos1));
62 arr[1] = std::stol(rest.substr(pos1 + 1, pos2 - pos1 - 1));
63 arr[2] = std::stol(rest.substr(pos2 + 1));
64 return arr;
65 }
66 switch (s[0]) {
67 case 'i': return std::stol(s.c_str() + 1); // the variant is a long. Skip the first char and recover the long
68 case 's': return std::string(s.c_str() + 1); // the variant is a string. Just skip the first char
69 case 'd': return std::stod(s.c_str() + 1); // the variant is a double. Skip the first char and recover the double
70 default: TRIQS_RUNTIME_ERROR << "Unknown variant type prefix in h5 read: " << s[0];
71 }
72 }
73
74 // Turn a fundamental_operator_set into a vector of vector of strings.
75 auto to_vec_vec_string(fundamental_operator_set const &fops) {
76 std::vector<std::vector<std::string>> vvs(fops.size());
77 for (auto const &[n, alpha] : itertools::enumerate(fops.data())) {
78 for (auto const &beta : alpha) vvs[n].push_back(visit(variant_visitor{}, beta));
79 }
80 return vvs;
81 }
82
83 // Turn a vector of strings into an operator index.
84 fundamental_operator_set::indices_t to_indices(std::vector<std::string> const &v) {
86 for (auto &beta : v)
87 if (!beta.empty()) alpha.push_back(string_to_variant(beta));
88 return alpha;
89 }
90
91 } // anonymous namespace
92
93 std::string format_indices(indices_t const &alpha, std::string_view sep, std::string_view prefix, std::string_view suffix) {
94 // early return for empty indices
95 if (alpha.empty()) return fmt::format("{}{}", prefix, suffix);
96
97 // converts a single variant element to its string representation (strings get single quotes)
98 auto idx_to_str = [](auto const &x) {
99 return std::visit(
100 [](auto const &v) -> std::string {
101 if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::string>)
102 return fmt::format("'{}'", v);
103 else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::array<long, 3>>)
104 return fmt::format("({})", fmt::join(v, ","));
105 else
106 return fmt::format("{}", v);
107 },
108 x);
109 };
110
111 // build the final string
112 std::string str = fmt::format("{}{}", prefix, idx_to_str(alpha.front()));
113 for (int i = 1; i < alpha.size(); ++i) str += fmt::format("{}{}", sep, idx_to_str(alpha[i]));
114 str += fmt::format("{}", suffix);
115 return str;
116 }
117
118 fundamental_operator_set::fundamental_operator_set(std::vector<std::vector<std::string>> const &vvs) {
119 for (auto const &vs : vvs) idxs_.push_back(to_indices(vs));
120 }
121
122 void h5_write_attribute(h5::object obj, std::string const &name, fundamental_operator_set const &fops) {
123 h5::write_attribute(obj, name, to_vec_vec_string(fops));
124 }
125
126 void h5_read_attribute(h5::object obj, std::string const &name, fundamental_operator_set &fops) {
127 std::vector<std::vector<std::string>> vvs;
128 h5::read_attribute(obj, name, vvs);
129 fops = fundamental_operator_set(vvs);
130 }
131
132} // namespace triqs::hilbert_space
const_view_type operator()() const
Make a const view of *this.
Class representing a fundamental operator set.
friend void h5_write_attribute(h5::object obj, std::string const &name, fundamental_operator_set const &fops)
Write a triqs::hilbert_space::fundamental_operator_set to HDF5 as an attribute.
friend void h5_read_attribute(h5::object obj, std::string const &name, fundamental_operator_set &fops)
Read a triqs::hilbert_space::fundamental_operator_set from an HDF5 attribute.
triqs::hilbert_space::indices_t indices_t
Index type to represent a single .
fundamental_operator_set()=default
Default constructor leaves the set of indices empty, i.e. .
TRIQS exception hierarchy and related macros.
std::vector< std::variant< long, std::string, double, std::array< long, 3 > > > indices_t
Index type for single particle state indices .
std::string format_indices(indices_t const &alpha, std::string_view sep, std::string_view prefix, std::string_view suffix)
String representation of a single particle state index .
many_body_operator_generic< T > n(IndexTypes... indices)
Create a number operator .
#define TRIQS_RUNTIME_ERROR
Throw a triqs::runtime_error with the current source location.
string to_string(string const &str)
Identity overload for std::string.
Provides a fundamental operator set class.