Skip to content

Commit 2d3dee8

Browse files
Remove Particle-Conserving Assumption (#90)
* QITE doesn't need a Hamiltonian * Eliminate particle-conserving assumption from SQOperator * Modify to be more QForte applicable * FAE revisions
1 parent ce2df0b commit 2d3dee8

9 files changed

+250
-258
lines changed

pull_request_template.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ A brief description of the goals accomplished by this PR
66
- [ ] Changes to compilation (if any)
77

88
## Checklist
9-
- [ ] Added/updated tests of new features and included a reference `output.ref` file
10-
- [ ] Removed comments in code and input files
9+
- [ ] Added/updated tests of new features
10+
- [ ] Removed comments in input files
1111
- [ ] Documented source code
12-
- [ ] Checked for redundant headers
12+
- [ ] Checked for redundant headers/imports
1313
- [ ] Checked for consistency in the formatting of the output file
14-
- [ ] Documented new features in the manual
1514
- [ ] Ready to go!

src/qforte/adapters/molecule_adapters.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -318,16 +318,16 @@ def create_psi_mol(**kwargs):
318318
# Build second quantized Hamiltonian
319319
nmo = np.shape(mo_oeis)[0]
320320
Hsq = qforte.SQOperator()
321-
Hsq.add(p4_Enuc_ref, [])
321+
Hsq.add(p4_Enuc_ref, [], [])
322322
for i in range(nmo):
323323
ia = i*2
324324
ib = i*2 + 1
325325
for j in range(nmo):
326326
ja = j*2
327327
jb = j*2 + 1
328328

329-
Hsq.add(mo_oeis[i,j], [ia, ja])
330-
Hsq.add(mo_oeis[i,j], [ib, jb])
329+
Hsq.add(mo_oeis[i,j], [ia], [ja])
330+
Hsq.add(mo_oeis[i,j], [ib], [jb])
331331

332332
for k in range(nmo):
333333
ka = k*2
@@ -337,14 +337,14 @@ def create_psi_mol(**kwargs):
337337
lb = l*2 + 1
338338

339339
if(ia!=jb and kb != la):
340-
Hsq.add( mo_teis[i,l,k,j]/2, [ia, jb, kb, la] ) # abba
340+
Hsq.add( mo_teis[i,l,k,j]/2, [ia, jb], [kb, la] ) # abba
341341
if(ib!=ja and ka!=lb):
342-
Hsq.add( mo_teis[i,l,k,j]/2, [ib, ja, ka, lb] ) # baab
342+
Hsq.add( mo_teis[i,l,k,j]/2, [ib, ja], [ka, lb] ) # baab
343343

344344
if(ia!=ja and ka!=la):
345-
Hsq.add( mo_teis[i,l,k,j]/2, [ia, ja, ka, la] ) # aaaa
345+
Hsq.add( mo_teis[i,l,k,j]/2, [ia, ja], [ka, la] ) # aaaa
346346
if(ib!=jb and kb!=lb):
347-
Hsq.add( mo_teis[i,l,k,j]/2, [ib, jb, kb, lb] ) # bbbb
347+
Hsq.add( mo_teis[i,l,k,j]/2, [ib, jb], [kb, lb] ) # bbbb
348348

349349
# Set attributes
350350
qforte_mol.set_nuclear_repulsion_energy(p4_Enuc_ref)
@@ -376,13 +376,13 @@ def create_external_mol(**kwargs):
376376

377377
# build sq hamiltonian
378378
qforte_sq_hamiltonian = qforte.SQOperator()
379-
qforte_sq_hamiltonian.add(external_data['scalar_energy']['data'], [])
379+
qforte_sq_hamiltonian.add(external_data['scalar_energy']['data'], [], [])
380380

381381
for p, q, h_pq in external_data['oei']['data']:
382-
qforte_sq_hamiltonian.add(h_pq, [p,q])
382+
qforte_sq_hamiltonian.add(h_pq, [p], [q])
383383

384384
for p, q, r, s, h_pqrs in external_data['tei']['data']:
385-
qforte_sq_hamiltonian.add(h_pqrs/4.0, [p,q,s,r]) # only works in C1 symmetry
385+
qforte_sq_hamiltonian.add(h_pqrs/4.0, [p,q], [s,r]) # only works in C1 symmetry
386386

387387
hf_reference = [0 for i in range(external_data['nso']['data'])]
388388
for n in range(external_data['na']['data'] + external_data['nb']['data']):

src/qforte/ite/qite.py

-3
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ class QITE(Algorithm):
3535
_sig : QuantumOpPool
3636
The basis of operators allowed in a unitary evolution step.
3737
_sparseSb : bool
38-
_sq_ham : SqOperator
39-
The second-quantized, fermionic Hamiltonian
4038
_total_phase : complex
4139
_Uqite: QuantumCircuit
4240
_x_thresh : float
@@ -54,7 +52,6 @@ def run(self,
5452
self._beta = beta
5553
self._db = db
5654
self._nbeta = int(beta/db)+1
57-
self._sq_ham = self._sys.get_sq_hamiltonian()
5855
self._expansion_type = expansion_type
5956
self._sparseSb = sparseSb
6057
self._total_phase = 1.0 + 0.0j

src/qforte/sq_op_pool.cc

+48-68
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ void SQOpPool::fill_pool(std::string pool_type){
101101

102102
if( aa != ia ){
103103
SQOperator temp1a;
104-
temp1a.add_term(+1.0, {aa, ia});
105-
temp1a.add_term(-1.0, {ia, aa});
104+
temp1a.add_term(+1.0, {aa}, {ia});
105+
temp1a.add_term(-1.0, {ia}, {aa});
106106
temp1a.simplify();
107107
if(temp1a.terms().size() > 0){
108108
add_term(1.0, temp1a);
@@ -111,8 +111,8 @@ void SQOpPool::fill_pool(std::string pool_type){
111111

112112
if( ab != ib ){
113113
SQOperator temp1b;
114-
temp1b.add_term(+1.0, {ab, ib});
115-
temp1b.add_term(-1.0, {ib, ab});
114+
temp1b.add_term(+1.0, {ab}, {ib});
115+
temp1b.add_term(-1.0, {ib}, {ab});
116116
temp1b.simplify();
117117
if(temp1b.terms().size() > 0){
118118
add_term(1.0, temp1b);
@@ -139,8 +139,8 @@ void SQOpPool::fill_pool(std::string pool_type){
139139

140140
if((aa != ba) && (ia != ja)){
141141
SQOperator temp2aaaa;
142-
temp2aaaa.add_term(+1.0, {aa,ba,ia,ja});
143-
temp2aaaa.add_term(-1.0, {ja,ia,ba,aa});
142+
temp2aaaa.add_term(+1.0, {aa,ba}, {ia,ja});
143+
temp2aaaa.add_term(-1.0, {ja,ia}, {ba,aa});
144144
temp2aaaa.simplify();
145145
if(temp2aaaa.terms().size() > 0){
146146
std::vector<size_t> vtemp {std::get<1>(temp2aaaa.terms()[0])[0], std::get<1>(temp2aaaa.terms()[0])[1], std::get<1>(temp2aaaa.terms()[0])[2], std::get<1>(temp2aaaa.terms()[0])[3]};
@@ -157,8 +157,8 @@ void SQOpPool::fill_pool(std::string pool_type){
157157

158158
if((ab != bb ) && (ib != jb)){
159159
SQOperator temp2bbbb;
160-
temp2bbbb.add_term(+1.0, {ab,bb,ib,jb});
161-
temp2bbbb.add_term(-1.0, {jb,ib,bb,ab});
160+
temp2bbbb.add_term(+1.0, {ab,bb}, {ib,jb});
161+
temp2bbbb.add_term(-1.0, {jb,ib}, {bb,ab});
162162
temp2bbbb.simplify();
163163
if(temp2bbbb.terms().size() > 0){
164164
std::vector<size_t> vtemp {std::get<1>(temp2bbbb.terms()[0])[0], std::get<1>(temp2bbbb.terms()[0])[1], std::get<1>(temp2bbbb.terms()[0])[2], std::get<1>(temp2bbbb.terms()[0])[3]};
@@ -175,8 +175,8 @@ void SQOpPool::fill_pool(std::string pool_type){
175175

176176
if((aa != bb) && (ia != jb)){
177177
SQOperator temp2abab;
178-
temp2abab.add_term(+1.0, {aa,bb,ia,jb});
179-
temp2abab.add_term(-1.0, {jb,ia,bb,aa});
178+
temp2abab.add_term(+1.0, {aa,bb}, {ia,jb});
179+
temp2abab.add_term(-1.0, {jb,ia}, {bb,aa});
180180
temp2abab.simplify();
181181
if(temp2abab.terms().size() > 0){
182182
std::vector<size_t> vtemp {std::get<1>(temp2abab.terms()[0])[0], std::get<1>(temp2abab.terms()[0])[1], std::get<1>(temp2abab.terms()[0])[2], std::get<1>(temp2abab.terms()[0])[3]};
@@ -193,8 +193,8 @@ void SQOpPool::fill_pool(std::string pool_type){
193193

194194
if((ab != ba) && (ib != ja)){
195195
SQOperator temp2baba;
196-
temp2baba.add_term(+1.0, {ab,ba,ib,ja});
197-
temp2baba.add_term(-1.0, {ja,ib,ba,ab});
196+
temp2baba.add_term(+1.0, {ab,ba}, {ib,ja});
197+
temp2baba.add_term(-1.0, {ja,ib}, {ba,ab});
198198
temp2baba.simplify();
199199
if(temp2baba.terms().size() > 0){
200200
std::vector<size_t> vtemp {std::get<1>(temp2baba.terms()[0])[0], std::get<1>(temp2baba.terms()[0])[1], std::get<1>(temp2baba.terms()[0])[2], std::get<1>(temp2baba.terms()[0])[3]};
@@ -211,8 +211,8 @@ void SQOpPool::fill_pool(std::string pool_type){
211211

212212
if((aa != bb) && (ib != ja)){
213213
SQOperator temp2abba;
214-
temp2abba.add_term(+1.0, {aa,bb,ib,ja});
215-
temp2abba.add_term(-1.0, {ja,ib,bb,aa});
214+
temp2abba.add_term(+1.0, {aa,bb}, {ib,ja});
215+
temp2abba.add_term(-1.0, {ja,ib}, {bb,aa});
216216
temp2abba.simplify();
217217
if(temp2abba.terms().size() > 0){
218218
std::vector<size_t> vtemp {std::get<1>(temp2abba.terms()[0])[0], std::get<1>(temp2abba.terms()[0])[1], std::get<1>(temp2abba.terms()[0])[2], std::get<1>(temp2abba.terms()[0])[3]};
@@ -230,8 +230,8 @@ void SQOpPool::fill_pool(std::string pool_type){
230230

231231
if((ab != ba) && (ia != jb)){
232232
SQOperator temp2baab;
233-
temp2baab.add_term(+1.0, {ab,ba,ia,jb});
234-
temp2baab.add_term(-1.0, {jb,ia,ba,ab});
233+
temp2baab.add_term(+1.0, {ab,ba}, {ia,jb});
234+
temp2baab.add_term(-1.0, {jb,ia}, {ba,ab});
235235
temp2baab.simplify();
236236
if(temp2baab.terms().size() > 0){
237237
std::vector<size_t> vtemp {std::get<1>(temp2baab.terms()[0])[0], std::get<1>(temp2baab.terms()[0])[1], std::get<1>(temp2baab.terms()[0])[2], std::get<1>(temp2baab.terms()[0])[3]};
@@ -334,13 +334,12 @@ void SQOpPool::fill_pool(std::string pool_type){
334334
}
335335

336336
if(total_parity==1){
337-
particles.insert(particles.end(), holes.begin(), holes.end());
338-
std::vector<size_t> particles_adj (particles.rbegin(), particles.rend());
339-
340337
// need i, j, a, b
341338
SQOperator t_temp;
342-
t_temp.add_term(+1.0, particles);
343-
t_temp.add_term(-1.0, particles_adj);
339+
t_temp.add_term(+1.0, particles, holes);
340+
std::vector<size_t> rparticles(particles.rbegin(), particles.rend());
341+
std::vector<size_t> rholes(holes.rbegin(), holes.rend());
342+
t_temp.add_term(-1.0, rholes, rparticles);
344343
t_temp.simplify();
345344
add_term(1.0, t_temp);
346345
}
@@ -357,17 +356,17 @@ void SQOpPool::fill_pool(std::string pool_type){
357356
size_t ab = 2*nocc_ + 2*a+1;
358357

359358
SQOperator temp1;
360-
temp1.add_term(+1.0/std::sqrt(2), {aa, ia});
361-
temp1.add_term(+1.0/std::sqrt(2), {ab, ib});
359+
temp1.add_term(+1.0/std::sqrt(2), {aa}, {ia});
360+
temp1.add_term(+1.0/std::sqrt(2), {ab}, {ib});
362361

363-
temp1.add_term(-1.0/std::sqrt(2), {ia, aa});
364-
temp1.add_term(-1.0/std::sqrt(2), {ib, ab});
362+
temp1.add_term(-1.0/std::sqrt(2), {ia}, {aa});
363+
temp1.add_term(-1.0/std::sqrt(2), {ib}, {ab});
365364

366365
temp1.simplify();
367366

368367
std::complex<double> temp1_norm(0.0, 0.0);
369368
for (const auto& term : temp1.terms()){
370-
temp1_norm += std::norm(term.first);
369+
temp1_norm += std::norm(std::get<0>(term));
371370
}
372371
temp1.mult_coeffs(1.0/std::sqrt(temp1_norm));
373372
add_term(1.0, temp1);
@@ -392,70 +391,70 @@ void SQOpPool::fill_pool(std::string pool_type){
392391

393392
SQOperator temp2a;
394393
if((aa != ba) && (ia != ja)){
395-
temp2a.add_term(2.0/std::sqrt(12), {aa,ba,ia,ja});
394+
temp2a.add_term(2.0/std::sqrt(12), {aa,ba}, {ia,ja});
396395
}
397396
if((ab != bb ) && (ib != jb)){
398-
temp2a.add_term(2.0/std::sqrt(12), {ab,bb,ib,jb});
397+
temp2a.add_term(2.0/std::sqrt(12), {ab,bb}, {ib,jb});
399398
}
400399
if((aa != bb) && (ia != jb)){
401-
temp2a.add_term(1.0/std::sqrt(12), {aa,bb,ia,jb});
400+
temp2a.add_term(1.0/std::sqrt(12), {aa,bb}, {ia,jb});
402401
}
403402
if((ab != ba) && (ib != ja)){
404-
temp2a.add_term(1.0/std::sqrt(12), {ab,ba,ib,ja});
403+
temp2a.add_term(1.0/std::sqrt(12), {ab,ba}, {ib,ja});
405404
}
406405
if((aa != bb) && (ib != ja)){
407-
temp2a.add_term(1.0/std::sqrt(12), {aa,bb,ib,ja});
406+
temp2a.add_term(1.0/std::sqrt(12), {aa,bb}, {ib,ja});
408407
}
409408
if((ab != ba) && (ia != jb)){
410-
temp2a.add_term(1.0/std::sqrt(12), {ab,ba,ia,jb});
409+
temp2a.add_term(1.0/std::sqrt(12), {ab,ba}, {ia,jb});
411410
}
412411

413412
// hermitian conjugate
414413
if((ja != ia) && (ba != aa)){
415-
temp2a.add_term(-2.0/std::sqrt(12), {ja,ia,ba,aa});
414+
temp2a.add_term(-2.0/std::sqrt(12), {ja,ia}, {ba,aa});
416415
}
417416
if((jb != ib ) && (bb != ab)){
418-
temp2a.add_term(-2.0/std::sqrt(12), {jb,ib,bb,ab});
417+
temp2a.add_term(-2.0/std::sqrt(12), {jb,ib}, {bb,ab});
419418
}
420419
if((jb != ia) && (bb != aa)){
421-
temp2a.add_term(-1.0/std::sqrt(12), {jb,ia,bb,aa});
420+
temp2a.add_term(-1.0/std::sqrt(12), {jb,ia}, {bb,aa});
422421
}
423422
if((ja != ib) && (ba != ab)){
424-
temp2a.add_term(-1.0/std::sqrt(12), {ja,ib,ba,ab});
423+
temp2a.add_term(-1.0/std::sqrt(12), {ja,ib}, {ba,ab});
425424
}
426425
if((ja != ib) && (bb != aa)){
427-
temp2a.add_term(-1.0/std::sqrt(12), {ja,ib,bb,aa});
426+
temp2a.add_term(-1.0/std::sqrt(12), {ja,ib}, {bb,aa});
428427
}
429428
if((jb != ia) && (ba != ab)){
430-
temp2a.add_term(-1.0/std::sqrt(12), {jb,ia,ba,ab});
429+
temp2a.add_term(-1.0/std::sqrt(12), {jb,ia}, {ba,ab});
431430
}
432431

433432
SQOperator temp2b;
434433
if((aa != bb) && (ia != jb)){
435-
temp2b.add_term(0.5, {aa,bb,ia,jb});
434+
temp2b.add_term(0.5, {aa,bb}, {ia,jb});
436435
}
437436
if((ab != ba) && (ib != ja)){
438-
temp2b.add_term(0.5, {ab,ba,ib,ja});
437+
temp2b.add_term(0.5, {ab,ba}, {ib,ja});
439438
}
440439
if((aa != bb) && (ib != ja)){
441-
temp2b.add_term(-0.5, {aa,bb,ib,ja});
440+
temp2b.add_term(-0.5, {aa,bb}, {ib,ja});
442441
}
443442
if((ab != ba) && (ia != jb)){
444-
temp2b.add_term(-0.5, {ab,ba,ia,jb});
443+
temp2b.add_term(-0.5, {ab,ba}, {ia,jb});
445444
}
446445

447446
// hermetian conjugate
448447
if((jb != ia) && (bb != aa)){
449-
temp2b.add_term(-0.5, {jb,ia,bb,aa});
448+
temp2b.add_term(-0.5, {jb,ia}, {bb,aa});
450449
}
451450
if((ja != ib) && (ba != ab)){
452-
temp2b.add_term(-0.5, {ja,ib,ba,ab});
451+
temp2b.add_term(-0.5, {ja,ib}, {ba,ab});
453452
}
454453
if((ja != ib) && (bb != aa)){
455-
temp2b.add_term(0.5, {ja,ib,bb,aa});
454+
temp2b.add_term(0.5, {ja,ib}, {bb,aa});
456455
}
457456
if((jb != ia) && (ba != ab)){
458-
temp2b.add_term(0.5, {jb,ia,ba,ab});
457+
temp2b.add_term(0.5, {jb,ia}, {ba,ab});
459458
}
460459

461460
temp2a.simplify();
@@ -464,10 +463,10 @@ void SQOpPool::fill_pool(std::string pool_type){
464463
std::complex<double> temp2a_norm(0.0, 0.0);
465464
std::complex<double> temp2b_norm(0.0, 0.0);
466465
for (const auto& term : temp2a.terms()){
467-
temp2a_norm += std::norm(term.first);
466+
temp2a_norm += std::norm(std::get<0>(term));
468467
}
469468
for (const auto& term : temp2b.terms()){
470-
temp2b_norm += std::norm(term.first);
469+
temp2b_norm += std::norm(std::get<0>(term));
471470
}
472471
temp2a.mult_coeffs(1.0/std::sqrt(temp2a_norm));
473472
temp2b.mult_coeffs(1.0/std::sqrt(temp2b_norm));
@@ -482,14 +481,6 @@ void SQOpPool::fill_pool(std::string pool_type){
482481
}
483482
}
484483
}
485-
} else if(pool_type == "test"){
486-
SQOperator A;
487-
A.add_term(+2.0, {1,2,4,3});
488-
A.add_term(-2.0, {2,4});
489-
A.add_term(-2.0, {3,4,2,1});
490-
A.add_term(+2.0, {4,2});
491-
add_term(-0.25, A);
492-
add_term(+0.75, A);
493484
} else {
494485
throw std::invalid_argument( "Invalid pool_type specified." );
495486
}
@@ -505,18 +496,7 @@ std::string SQOpPool::str() const{
505496
s.push_back("<-----\n");
506497
s.push_back(to_string(term.first));
507498
s.push_back("[\n");
508-
for (const auto& sub_term : term.second.terms()) {
509-
int nbody = sub_term.second.size() / 2.0;
510-
s.push_back(to_string(sub_term.first));
511-
s.push_back("(");
512-
for (int k=0; k<nbody; k++ ) {
513-
s.push_back(std::to_string(sub_term.second[k]) + "^");
514-
}
515-
for (int k=nbody; k<2*nbody; k++ ) {
516-
s.push_back(std::to_string(sub_term.second[k]));
517-
}
518-
s.push_back(")\n");
519-
}
499+
s.push_back(term.second.str());
520500
s.push_back("]\n\n");
521501
counter++;
522502
}

0 commit comments

Comments
 (0)