Commit decc1bb0 authored by Dmitry I. Lyakh's avatar Dmitry I. Lyakh
Browse files

Implemented spin Hamiltonian parser for the QCWare collab format


Signed-off-by: default avatarDmitry I. Lyakh <quant4me@gmail.com>
parent 3b64f0f6
/** ExaTN: Quantum computing related
REVISION: 2021/08/12
REVISION: 2021/09/25
Copyright (C) 2018-2021 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2021 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -143,7 +143,8 @@ bool appendPauliComponent(exatn::numerics::TensorOperator & tens_operator,
std::shared_ptr<exatn::numerics::TensorOperator> readSpinHamiltonian(const std::string & operator_name,
const std::string & filename,
TensorElementType precision)
TensorElementType precision,
const std::string & format)
{
assert(filename.length() > 0);
assert(precision == TensorElementType::COMPLEX32 || precision == TensorElementType::COMPLEX64);
......@@ -157,7 +158,17 @@ std::shared_ptr<exatn::numerics::TensorOperator> readSpinHamiltonian(const std::
while(std::getline(input_file,line)){
std::string paulis;
std::complex<double> coef;
auto success = parse_pauli_string(line,paulis,coef); assert(success);
auto success = false;
if(format == "OpenFermion"){
success = parse_pauli_string_ofermion(line,paulis,coef);
}else if(format == "QCWare"){
success = parse_pauli_string_qcware(line,paulis,coef);
}
if(!success){
std::cout << "#ERROR(exatn:quantum:readSpinHamiltonian): Unable to parse file "
<< filename << " with format " << format << std::endl;
assert(false);
}
//std::cout << "#DEBUG: " << paulis << std::endl; //debug
assert(paulis.length() >= 2); //'[]' at least
assert(paulis[0] == '[' && paulis[paulis.length()-1] == ']');
......
/** ExaTN: Quantum computing related
REVISION: 2021/08/12
REVISION: 2021/09/25
Copyright (C) 2018-2021 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2021 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -60,10 +60,14 @@ std::vector<std::complex<double>> getGateData(const Gate gate_name,
std::initializer_list<double> angles = {});
/** Creates a tensor network operator for a given spin Hamiltonian
stored in an OpenFermion file (linear combination of Pauli strings). **/
represented as a linear combination of Pauli strings. Supported formats:
+ "OpenFermion": Open Fermion format (default);
+ "QCWare": QCWare collab format (by Rob Parrish);
**/
std::shared_ptr<exatn::numerics::TensorOperator> readSpinHamiltonian(const std::string & operator_name,
const std::string & filename,
TensorElementType precision = TensorElementType::COMPLEX64);
TensorElementType precision = TensorElementType::COMPLEX64,
const std::string & format = "OpenFermion");
} //namespace quantum
} //namespace exatn
......
......@@ -2872,9 +2872,10 @@ TEST(NumServerTester, HubbardHamiltonian) {
const int num_sites = 8, max_bond_dim = std::min(static_cast<int>(std::pow(2,num_sites/2)),16); //2x2 sites x dim(4) = 8 qubits (sites)
//Read 2x2 Hubbard Hamiltonian in spin representation:
//auto hubbard_operator = exatn::quantum::readSpinHamiltonian("MCVQEHam","mcvqe_8q.txt",TENS_ELEM_TYPE);
//auto hubbard_operator = exatn::quantum::readSpinHamiltonian("MCVQEHam","mcvqe_8q.ofn.txt",TENS_ELEM_TYPE,"OpenFermion");
//auto hubbard_operator = exatn::quantum::readSpinHamiltonian("MCVQEHam","mcvqe_8q.qcw.txt",TENS_ELEM_TYPE,"QCWare");
//success = hubbard_operator->deleteComponent(0); assert(success);
auto hubbard_operator = exatn::quantum::readSpinHamiltonian("HubbardHam","hubbard_2x2_8q.txt",TENS_ELEM_TYPE);
auto hubbard_operator = exatn::quantum::readSpinHamiltonian("HubbardHam","hubbard_2x2_8q.ofn.txt",TENS_ELEM_TYPE,"OpenFermion");
hubbard_operator->printIt();
//Create tensor network ansatz:
......
10729.963236109992*I
+0.013958292661992958*X0
+0.017780394781136848*X0*X1
-0.006896704529177866*X0*Z1
-0.03376113630025557*Z0
+0.011474775121306156*Z0*X1
-0.004444563032874407*Z0*Z1
+0.009522097764876093*X1
-0.008640686174448204*X1*X2
-0.00641012019143096*X1*Z2
-0.042308599255825224*Z1
+0.0033005482717231548*Z1*X2
+0.0024514303165071353*Z1*Z2
-0.006583545256676178*X2
-0.007287160094179741*X2*X3
+0.004086379532445629*X2*Z3
-0.04957343856301523*Z2
-0.005120355594249221*Z2*X3
+0.00289351687114843*Z2*Z3
-0.006327031384126287*X3
-0.01840086316143409*X3*X4
-0.012367083572855955*X3*Z4
-0.03839552410604509*Z3
+0.010913763352627169*Z3*X4
+0.007334390217786867*Z3*Z4
+0.009699304994889446*X4
-0.004742884975867185*X4*X5
-0.0011410992924187104*X4*Z5
-0.03672437524536075*Z4
-0.0028540627220499703*Z4*X5
-0.0006758931704842083*Z4*Z5
-0.008546718038275256*X5
+0.0012774322501627943*X5*X6
-0.0006862884757300228*X5*Z6
-0.040029787841621825*Z5
+0.0004181198916071052*Z5*X6
-0.0002418324220780885*Z5*Z6
-0.004220761908087866*X6
-0.007850802949685699*X6*X7
-0.004536735382497114*X6*Z7
-0.041302161404488*Z6
+0.005221816809904007*Z6*X7
+0.003023554049679674*Z6*Z7
+0.0023629329298370094*X7
-0.04139809785433139*Z7
/** ExaTN: Numerics: Symbolic tensor processing
REVISION: 2021/09/22
REVISION: 2021/09/25
Copyright (C) 2018-2021 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2021 Oak Ridge National Laboratory (UT-Battelle) **/
......@@ -347,7 +347,6 @@ bool generate_addition_pattern(const std::vector<numerics::TensorLeg> & pattern,
}
/* Generates the trivial tensor addition pattern. */
bool generate_addition_pattern(unsigned int tensor_rank,
std::string & symb_pattern,
bool conjugated,
......@@ -360,9 +359,10 @@ bool generate_addition_pattern(unsigned int tensor_rank,
return generate_addition_pattern(pattern,symb_pattern,conjugated,dest_name,left_name);
}
bool parse_pauli_string(const std::string & input,
std::string & paulis,
std::complex<double> & coefficient)
bool parse_pauli_string_ofermion(const std::string & input,
std::string & paulis,
std::complex<double> & coefficient)
{
bool success = true;
double coef_real, coef_imag;
......@@ -389,7 +389,7 @@ bool parse_pauli_string(const std::string & input,
}
if(sep_pos != std::string::npos){
const auto real_len = sep_pos - left_par_pos - 1;
//std::cout << "#DEBUG(parse_pauli_string): Coef: " << input.substr(left_par_pos+1,real_len); //debug
//std::cout << "#DEBUG(parse_pauli_string_ofermion): Coef: " << input.substr(left_par_pos+1,real_len); //debug
if(real_len > 0) coef_real = std::stod(input.substr(left_par_pos+1,real_len));
const auto imag_end_pos = input.find("j",sep_pos);
if(imag_end_pos != std::string::npos){
......@@ -397,6 +397,8 @@ bool parse_pauli_string(const std::string & input,
//std::cout << " " << input.substr(sep_pos+1,imag_len) << std::endl; //debug
if(imag_len > 0) coef_imag = std::stod(input.substr(sep_pos+1,imag_len));
coefficient = std::complex<double>{coef_real, coef_imag};
//std::cout << "#DEBUG(parse_pauli_string_ofermion): Parsed: "
// << paulis << " * " << coefficient << std::endl; //debug
}else{
success = false;
}
......@@ -418,4 +420,62 @@ bool parse_pauli_string(const std::string & input,
return success;
}
bool parse_pauli_string_qcware(const std::string & input,
std::string & paulis,
std::complex<double> & coefficient)
{
bool success = true;
const auto input_len = input.length();
double coef_real = 0.0, coef_imag = 0.0;
const auto first_star_pos = input.find("*");
if(first_star_pos != std::string::npos){
int beg = 0;
while(input[beg] == ' ') ++beg;
if(input[beg] == '+') ++beg;
const auto coef_len = first_star_pos - beg;
if(coef_len > 0){
coef_real = std::stod(input.substr(beg,coef_len));
coefficient = std::complex<double>{coef_real,coef_imag};
paulis = "[";
unsigned int npaulis = 0;
beg = first_star_pos + 1;
int len = 0;
while(beg+len < input_len){
if(input[beg+len] == '*'){
assert(len > 0);
if(input[beg] != 'I'){
if(npaulis > 0){
paulis += (" " + input.substr(beg,len));
}else{
paulis += input.substr(beg,len);
}
++npaulis;
}
beg = beg + len + 1;
len = 0;
}else{
++len;
}
}
if(len > 0 && input[beg] != 'I'){
if(npaulis > 0){
paulis += (" " + input.substr(beg,len));
}else{
paulis += input.substr(beg,len);
}
++npaulis;
}
paulis += "]";
std::cout << "#DEBUG(parse_pauli_string_qcware): Parsed: "
<< paulis << " * " << coefficient << std::endl; //debug
}else{
success = false;
}
}else{
success = false;
}
return success;
}
} //namespace exatn
/** ExaTN: Numerics: Symbolic tensor processing
REVISION: 2021/08/20
REVISION: 2021/09/24
Copyright (C) 2018-2021 Dmitry I. Lyakh (Liakh)
Copyright (C) 2018-2021 Oak Ridge National Laboratory (UT-Battelle)
......@@ -224,9 +224,14 @@ bool generate_addition_pattern(unsigned int tensor_rank,
const std::string & left_name = "L");
/** Parses a Pauli string output from OpenFermion. **/
bool parse_pauli_string(const std::string & input, //in: input string
std::string & paulis, //out: output string with Pauli operators
std::complex<double> & coefficient); //out: linear combination coefficient
bool parse_pauli_string_ofermion(const std::string & input, //in: input string
std::string & paulis, //out: output string with Pauli operators
std::complex<double> & coefficient); //out: linear combination coefficient
/** Parses a Pauli string output from QCWare. **/
bool parse_pauli_string_qcware(const std::string & input, //in: input string
std::string & paulis, //out: output string with Pauli operators
std::complex<double> & coefficient); //out: linear combination coefficient
} //namespace exatn
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment