Skip to content

Commit ec3db25

Browse files
committed
Remove SparseHamiltonian, add sign_mask to SparseOperator
1 parent 5bda62b commit ec3db25

14 files changed

Lines changed: 59 additions & 104 deletions

forte/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ api/scf_info_api.cc
102102
api/sparse_ci_solver_api.cc
103103
api/sparse_exp_api.cc
104104
api/sparse_fact_exp_api.cc
105-
api/sparse_hamiltonian_api.cc
106105
api/sparse_operator_api.cc
107106
api/sparse_operator_list_api.cc
108107
api/sparse_operator_sim_trans_api.cc
@@ -276,7 +275,6 @@ sparse_ci/sorted_string_list.cc
276275
sparse_ci/sparse_ci_solver.cc
277276
sparse_ci/sparse_exp.cc
278277
sparse_ci/sparse_fact_exp.cc
279-
sparse_ci/sparse_hamiltonian.cc
280278
sparse_ci/sparse_initial_guess.cc
281279
sparse_ci/sparse_operator.cc
282280
sparse_ci/sparse_operator_sim_trans.cc

forte/api/forte_python_module.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ PYBIND11_MODULE(_forte, m) {
215215
export_SQOperatorString(m);
216216
export_SparseExp(m);
217217
export_SparseFactExp(m);
218-
export_SparseHamiltonian(m);
219218
export_SparseOperator(m);
220219
export_SparseOperatorList(m);
221220
export_SparseOperatorSimTrans(m);

forte/api/forte_python_module.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ void export_CI_RDMS(py::module& m);
6464
void export_SQOperatorString(py::module& m);
6565
void export_SparseExp(py::module& m);
6666
void export_SparseFactExp(py::module& m);
67-
void export_SparseHamiltonian(py::module& m);
6867
void export_SparseOperator(py::module& m);
6968
void export_SparseOperatorList(py::module& m);
7069
void export_SparseOperatorSimTrans(py::module& m);
Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +0,0 @@
1-
/*
2-
* @BEGIN LICENSE
3-
*
4-
* Forte: an open-source plugin to Psi4 (https://github.com/psi4/psi4)
5-
* that implements a variety of quantum chemistry methods for strongly
6-
* correlated electrons.
7-
*
8-
* Copyright (c) 2012-2025 by its authors (see LICENSE, AUTHORS).
9-
*
10-
* The copyrights for code used from other parties are included in
11-
* the corresponding files.
12-
*
13-
* This program is free software: you can redistribute it and/or modify
14-
* it under the terms of the GNU General Public License as published by
15-
* the Free Software Foundation, either version 3 of the License, or
16-
* (at your option) any later version.
17-
*
18-
* This program is distributed in the hope that it will be useful,
19-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21-
* GNU General Public License for more details.
22-
*
23-
* You should have received a copy of the GNU General Public License
24-
* along with this program. If not, see http://www.gnu.org/licenses/.
25-
*
26-
* @END LICENSE
27-
*/
28-
29-
#include <pybind11/pybind11.h>
30-
#include <pybind11/stl.h>
31-
32-
#include "sparse_ci/sparse_hamiltonian.h"
33-
34-
namespace py = pybind11;
35-
using namespace pybind11::literals;
36-
37-
namespace forte {
38-
39-
void export_SparseHamiltonian(py::module& m) {
40-
py::class_<SparseHamiltonian>(m, "SparseHamiltonian",
41-
"A class to represent a sparse Hamiltonian")
42-
.def(py::init<std::shared_ptr<ActiveSpaceIntegrals>>())
43-
.def("compute", &SparseHamiltonian::compute, "state"_a, "screen_thresh"_a = 1.0e-12,
44-
"Compute the state H|state> using an algorithm that caches the elements of H")
45-
.def("apply", &SparseHamiltonian::compute, "state"_a, "screen_thresh"_a = 1.0e-12,
46-
"Compute the state H|state> using an algorithm that caches the elements of H")
47-
.def(
48-
"compute_on_the_fly", &SparseHamiltonian::compute_on_the_fly, "state"_a,
49-
"screen_thresh"_a = 1.0e-12,
50-
"Compute the state H|state> using an on-the-fly algorithm that has no memory footprint")
51-
.def("timings", &SparseHamiltonian::timings)
52-
.def("to_sparse_operator", &SparseHamiltonian::to_sparse_operator,
53-
"Convert the Hamiltonian to a SparseOperator object");
54-
}
55-
} // namespace forte

forte/api/sparse_operator_api.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,12 @@ void export_SparseOperator(py::module& m) {
224224
.def(
225225
"__str__", [](const SparseOperator& op) { return join(op.str(), "\n"); },
226226
"Get a string representation of the operator")
227+
.def(
228+
"apply_to_state",
229+
[](const SparseOperator& op, const SparseState& state, double screen_thresh) {
230+
return apply_operator_lin(op, state, screen_thresh);
231+
},
232+
"state"_a, "screen_thresh"_a = 1.0e-12, "Apply the operator to a state")
227233
.def(
228234
"fact_trans_lin",
229235
[](SparseOperator& O, const SparseOperatorList& T, bool reverse, double screen_thresh) {

forte/api/sparse_operator_list_api.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,14 @@ void export_SparseOperatorList(py::module& m) {
179179
op1 += op2;
180180
return op1;
181181
},
182-
"Add (concatenate) a SparseOperatorList object to this SparseOperatorList object");
183-
182+
"Add (concatenate) a SparseOperatorList object to this SparseOperatorList object")
183+
.def(
184+
"apply_to_state",
185+
[](const SparseOperatorList& op, const SparseState& state, double screen_thresh) {
186+
auto sop = op.to_operator();
187+
return apply_operator_lin(sop, state, screen_thresh);
188+
},
189+
"state"_a, "screen_thresh"_a = 1.0e-12, "Apply the operator to a state");
184190

185191
// Wrapper class that holds a SparseOperator
186192
// and overloads operator* to apply forte::SparseExp.

forte/modules/general_cc.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
SparseOperatorList,
1717
Determinant,
1818
SparseState,
19-
SparseHamiltonian,
2019
SparseFactExp,
2120
SparseExp,
2221
get_projection,
22+
sparse_operator_hamiltonian,
2323
)
2424

2525

@@ -190,8 +190,8 @@ def solve_cc_equations(
190190
Returns the a tuple containign the converged amplitudes, the energy, the projective energy,
191191
the number of iterations, and timings information
192192
"""
193-
diis = DIIS(t, diis_start, diis_nvec)
194-
ham = SparseHamiltonian(as_ints)
193+
diis = DIIS(t, diis_start)
194+
ham = sparse_operator_hamiltonian(as_ints)
195195
if cc_type == "cc" or cc_type == "ucc":
196196
exp = SparseExp(maxk=maxk, screen_thresh=compute_threshold)
197197
if cc_type == "dcc" or cc_type == "ducc":
@@ -255,19 +255,19 @@ def residual_equations(cc_type, t, op, sop, ref, ham, exp, compute_threshold, li
255255
c0 = 0.0
256256
if cc_type == "cc":
257257
wfn = exp.apply_op(sop, ref)
258-
Hwfn = ham.compute_on_the_fly(wfn, compute_threshold)
258+
Hwfn = ham.apply_to_state(wfn, compute_threshold)
259259
R = exp.apply_op(sop, Hwfn, scaling_factor=-1.0)
260260
elif cc_type == "ucc":
261261
wfn = exp.apply_antiherm(sop, ref)
262-
Hwfn = ham.compute_on_the_fly(wfn, compute_threshold)
262+
Hwfn = ham.apply_to_state(wfn, compute_threshold)
263263
R = exp.apply_antiherm(sop, Hwfn, scaling_factor=-1.0)
264264
elif cc_type == "dcc":
265265
wfn = exp.apply_op(sop, ref)
266-
Hwfn = ham.compute_on_the_fly(wfn, compute_threshold)
266+
Hwfn = ham.apply_to_state(wfn, compute_threshold)
267267
R = exp.apply_op(sop, Hwfn, inverse=True)
268268
elif cc_type == "ducc":
269269
wfn = exp.apply_antiherm(sop, ref)
270-
Hwfn = ham.compute_on_the_fly(wfn, compute_threshold)
270+
Hwfn = ham.apply_to_state(wfn, compute_threshold)
271271
R = exp.apply_antiherm(sop, Hwfn, inverse=True)
272272
else:
273273
raise ValueError("Incorrect value for cc_type")
@@ -340,7 +340,7 @@ def update(self, t, t_old):
340340
self.e_diis.append(np.subtract(t, t_old))
341341

342342
diis_dim = len(self.t_diis)
343-
if (diis_dim >= self.diis_start):
343+
if diis_dim >= self.diis_start:
344344
# consturct diis B matrix (following Crawford Group github tutorial)
345345
B = np.ones((diis_dim + 1, diis_dim + 1)) * -1.0
346346
bsol = np.zeros(diis_dim + 1)

forte/sparse_ci/sparse_state_functions.cc

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,10 @@ SparseState apply_operator_impl_naive(bool is_antihermitian, const SparseOperato
7474
Determinant sign_mask; // a temporary determinant to store the sign mask
7575
Determinant idx; // a temporary determinant to store the index of the determinant
7676
for (const auto& [sqop, t] : sop) {
77-
compute_sign_mask(sqop.cre(), sqop.ann(), sign_mask, idx);
7877
for (const auto& [det, c] : state) {
7978
if (det.faster_can_apply_operator(sqop.cre(), sqop.ann())) {
80-
auto value =
81-
faster_apply_operator_to_det(det, new_det, sqop.cre(), sqop.ann(), sign_mask);
79+
auto value = faster_apply_operator_to_det(det, new_det, sqop.cre(), sqop.ann(),
80+
sqop.sign_mask());
8281
new_terms[new_det] += value * t * c;
8382
}
8483
}
@@ -89,11 +88,10 @@ SparseState apply_operator_impl_naive(bool is_antihermitian, const SparseOperato
8988
}
9089

9190
for (const auto& [sqop, t] : sop) {
92-
compute_sign_mask(sqop.ann(), sqop.cre(), sign_mask, idx);
9391
for (const auto& [det, c] : state) {
9492
if (det.faster_can_apply_operator(sqop.ann(), sqop.cre())) {
95-
auto value =
96-
faster_apply_operator_to_det(det, new_det, sqop.ann(), sqop.cre(), sign_mask);
93+
auto value = faster_apply_operator_to_det(det, new_det, sqop.ann(), sqop.cre(),
94+
sqop.sign_mask());
9795
new_terms[new_det] -= value * t * c;
9896
}
9997
}
@@ -109,18 +107,18 @@ template <bool positive>
109107
void apply_operator_kernel(const auto& sop_groups, const auto& state_sorted,
110108
const auto& screen_thresh, auto& new_terms) {
111109
Determinant new_det;
112-
Determinant sign_mask;
110+
// Determinant sign_mask;
113111
Determinant idx;
114112
for (const auto& [sqop_ann, sqop_group] : sop_groups) {
115113
for (const auto& [det, c] : state_sorted) {
116114
if (det.fast_a_and_b_equal_b(sqop_ann)) {
117115
// loop over the creation operators in this group
118-
for (const auto& [sqop_cre, t] : sqop_group) {
116+
for (const auto& [sqop_cre, sqop_sign_mask, t] : sqop_group) {
119117
if (det.fast_a_and_b_minus_c_eq_zero(sqop_cre, sqop_ann)) {
120118
if (std::abs(c * t) > screen_thresh) {
121-
compute_sign_mask(sqop_cre, sqop_ann, sign_mask, idx);
122-
const auto value = faster_apply_operator_to_det(det, new_det, sqop_cre,
123-
sqop_ann, sign_mask);
119+
// compute_sign_mask(sqop_cre, sqop_ann, sign_mask, idx);
120+
const auto value = faster_apply_operator_to_det(
121+
det, new_det, sqop_cre, sqop_ann, sqop_sign_mask);
124122
if constexpr (positive) {
125123
new_terms[new_det] += value * t * c;
126124
} else {
@@ -151,11 +149,12 @@ SparseState apply_operator_impl_grouped(bool is_antihermitian, const SparseOpera
151149
[](const auto& a, const auto& b) { return a.first < b.first; });
152150

153151
// Group the operators by common annihilation strings
154-
std::unordered_map<Determinant, std::vector<std::pair<Determinant, sparse_scalar_t>>,
152+
std::unordered_map<Determinant,
153+
std::vector<std::tuple<Determinant, Determinant, sparse_scalar_t>>,
155154
Determinant::Hash>
156155
sop_groups;
157156
for (const auto& [sqop, t] : sop.elements()) {
158-
sop_groups[sqop.ann()].emplace_back(sqop.cre(), t);
157+
sop_groups[sqop.ann()].emplace_back(sqop.cre(), sqop.sign_mask(), t);
159158
}
160159

161160
// Call the kernel to apply the operator (adding the result)
@@ -169,7 +168,7 @@ SparseState apply_operator_impl_grouped(bool is_antihermitian, const SparseOpera
169168
// Here we swap the annihilation and creation operators for the antihermitian case
170169
sop_groups.clear();
171170
for (const auto& [sqop, t] : sop.elements()) {
172-
sop_groups[sqop.cre()].emplace_back(sqop.ann(), t);
171+
sop_groups[sqop.cre()].emplace_back(sqop.ann(), sqop.sign_mask(), t);
173172
}
174173

175174
// Call the kernel to apply the operator (subtracting the result)
@@ -186,18 +185,15 @@ template <bool positive>
186185
void apply_operator_kernel_string(const auto& sop_groups, const auto& state_groups,
187186
const auto& screen_thresh, auto& new_terms) {
188187
Determinant new_det;
189-
Determinant sign_mask;
190-
Determinant idx;
191188
for (const auto& [sqop_ann_a, sqop_group] : sop_groups) {
192189
for (const auto& [det_a, state_group] : state_groups) {
193190
// can we annihilate the alfa string?
194191
if (det_a.fast_a_and_b_equal_b(sqop_ann_a)) {
195192
// loop over the creation operators in this group
196-
for (const auto& [sqop_ann, sqop_cre, t] : sqop_group) {
193+
for (const auto& [sqop_ann, sqop_cre, sign_mask, t] : sqop_group) {
197194
for (const auto& [det, c] : state_group) {
198195
if (det.faster_can_apply_operator(sqop_cre, sqop_ann)) {
199196
if (std::abs(c * t) > screen_thresh) {
200-
compute_sign_mask(sqop_cre, sqop_ann, sign_mask, idx);
201197
const auto value = faster_apply_operator_to_det(
202198
det, new_det, sqop_cre, sqop_ann, sign_mask);
203199
if constexpr (positive) {
@@ -232,11 +228,13 @@ SparseState apply_operator_impl_grouped_string(bool is_antihermitian, const Spar
232228
}
233229

234230
// Group the operators by common alfa annihilation strings
235-
std::unordered_map<String, std::vector<std::tuple<Determinant, Determinant, sparse_scalar_t>>,
236-
String::Hash>
231+
std::unordered_map<
232+
String, std::vector<std::tuple<Determinant, Determinant, Determinant, sparse_scalar_t>>,
233+
String::Hash>
237234
sop_groups;
238235
for (const auto& [sqop, t] : sop.elements()) {
239-
sop_groups[sqop.ann().get_alfa_bits()].emplace_back(sqop.ann(), sqop.cre(), t);
236+
sop_groups[sqop.ann().get_alfa_bits()].emplace_back(sqop.ann(), sqop.cre(),
237+
sqop.sign_mask(), t);
240238
}
241239

242240
// Call the kernel to apply the operator (adding the result)
@@ -250,7 +248,8 @@ SparseState apply_operator_impl_grouped_string(bool is_antihermitian, const Spar
250248
// Here we swap the annihilation and creation operators for the antihermitian case
251249
sop_groups.clear();
252250
for (const auto& [sqop, t] : sop.elements()) {
253-
sop_groups[sqop.cre().get_alfa_bits()].emplace_back(sqop.cre(), sqop.ann(), t);
251+
sop_groups[sqop.cre().get_alfa_bits()].emplace_back(sqop.cre(), sqop.ann(),
252+
sqop.sign_mask(), t);
254253
}
255254

256255
// Call the kernel to apply the operator (subtracting the result)

0 commit comments

Comments
 (0)