Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ORNL Quantum Computing Institute
xacc
Commits
dfc86566
Commit
dfc86566
authored
Apr 10, 2019
by
Mccaskey, Alex
Browse files
adding FermionOperator Observable implementation
Signed-off-by:
Alex McCaskey
<
mccaskeyaj@ornl.gov
>
parent
d02da5ca
Pipeline
#47287
failed with stages
in 4 minutes and 54 seconds
Changes
53
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
quantum/gate/observable/CMakeLists.txt
View file @
dfc86566
set
(
PACKAGE_NAME
"PauliOperator Parser"
)
set
(
LIBRARY_NAME xacc-pauli
)
file
(
GLOB_RECURSE HEADERS *.hpp generated/*.hpp
)
file
(
GLOB SRC *.cpp generated/*.cpp
)
add_library
(
${
LIBRARY_NAME
}
SHARED
${
SRC
}
)
target_include_directories
(
${
LIBRARY_NAME
}
PUBLIC
.
${
CMAKE_SOURCE_DIR
}
/tpls/antlr/runtime/src
${
CMAKE_CURRENT_SOURCE_DIR
}
${
CMAKE_CURRENT_SOURCE_DIR
}
/generated
${
CMAKE_SOURCE_DIR
}
/tpls/taocpp
${
CMAKE_SOURCE_DIR
}
/tpls/eigen
${
CMAKE_BINARY_DIR
}
)
add_dependencies
(
${
LIBRARY_NAME
}
antlr4_shared
)
target_link_libraries
(
${
LIBRARY_NAME
}
PUBLIC xacc PRIVATE CppMicroServices
${
CMAKE_SOURCE_DIR
}
/dist/libantlr4-runtime.so
)
if
(
APPLE
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES INSTALL_RPATH
"@loader_path"
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES LINK_FLAGS
"-undefined dynamic_lookup"
)
else
()
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES INSTALL_RPATH
"$ORIGIN"
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES LINK_FLAGS
"-shared"
)
endif
()
if
(
XACC_BUILD_TESTS
)
add_subdirectory
(
tests
)
endif
()
file
(
GLOB HEADERS *.hpp
)
install
(
FILES
${
HEADERS
}
DESTINATION include/quantum/gate
)
install
(
TARGETS
${
LIBRARY_NAME
}
DESTINATION lib
)
add_subdirectory
(
pauli
)
add_subdirectory
(
fermion
)
add_subdirectory
(
transforms
)
\ No newline at end of file
quantum/gate/observable/fermion/CMakeLists.txt
0 → 100644
View file @
dfc86566
set
(
PACKAGE_NAME
"FermionOperator Parser"
)
set
(
LIBRARY_NAME xacc-fermion
)
file
(
GLOB_RECURSE HEADERS *.hpp generated/*.hpp
)
file
(
GLOB SRC *.cpp generated/*.cpp
)
add_library
(
${
LIBRARY_NAME
}
SHARED
${
SRC
}
)
target_include_directories
(
${
LIBRARY_NAME
}
PUBLIC
.
${
CMAKE_SOURCE_DIR
}
/tpls/antlr/runtime/src
${
CMAKE_CURRENT_SOURCE_DIR
}
${
CMAKE_CURRENT_SOURCE_DIR
}
/generated
${
CMAKE_SOURCE_DIR
}
/tpls/taocpp
#${CMAKE_SOURCE_DIR}/tpls/eigen
${
CMAKE_BINARY_DIR
}
)
add_dependencies
(
${
LIBRARY_NAME
}
antlr4_shared
)
target_link_libraries
(
${
LIBRARY_NAME
}
PUBLIC xacc PRIVATE CppMicroServices
${
CMAKE_SOURCE_DIR
}
/dist/libantlr4-runtime.so
)
if
(
APPLE
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES INSTALL_RPATH
"@loader_path"
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES LINK_FLAGS
"-undefined dynamic_lookup"
)
else
()
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES INSTALL_RPATH
"$ORIGIN"
)
set_target_properties
(
${
LIBRARY_NAME
}
PROPERTIES LINK_FLAGS
"-shared"
)
endif
()
if
(
XACC_BUILD_TESTS
)
add_subdirectory
(
tests
)
endif
()
file
(
GLOB HEADERS *.hpp
)
install
(
FILES
${
HEADERS
}
DESTINATION include/quantum/gate
)
install
(
TARGETS
${
LIBRARY_NAME
}
DESTINATION lib
)
quantum/gate/observable/fermion/FermionListenerImpl.cpp
0 → 100644
View file @
dfc86566
#include
"FermionListenerImpl.hpp"
namespace
xacc
{
namespace
quantum
{
void
FermionListenerImpl
::
enterPlusorminus
(
FermionOperatorParser
::
PlusorminusContext
*
ctx
)
{
isMinus
=
ctx
->
getText
()
==
"-"
;
}
void
FermionListenerImpl
::
enterTerm
(
FermionOperatorParser
::
TermContext
*
ctx
)
{
// std::cout << "ENTER TERM: " << ctx->getText() << ", " << ctx->fermion().size() << "\n";
std
::
complex
<
double
>
coeff
(
1.0
,
0.0
);
if
(
ctx
->
coeff
()
!=
nullptr
)
{
if
(
ctx
->
coeff
()
->
complex
()
!=
nullptr
)
{
auto
complexAsStr
=
ctx
->
coeff
()
->
complex
()
->
getText
();
complexAsStr
=
complexAsStr
.
substr
(
1
,
complexAsStr
.
length
()
-
2
);
auto
split
=
xacc
::
split
(
complexAsStr
,
','
);
coeff
=
std
::
complex
<
double
>
(
std
::
stod
(
split
[
0
]),
std
::
stod
(
split
[
1
]));
}
else
if
(
ctx
->
coeff
()
->
real
()
!=
nullptr
)
{
auto
realAsStr
=
ctx
->
coeff
()
->
real
()
->
getText
();
coeff
=
std
::
complex
<
double
>
(
std
::
stod
(
realAsStr
),
0.0
);
}
}
if
(
isMinus
)
{
coeff
*=
-
1.0
;
isMinus
=
false
;
}
Operators
term
;
for
(
int
i
=
0
;
i
<
ctx
->
fermion
().
size
();
i
++
)
{
auto
str
=
ctx
->
fermion
(
i
)
->
getText
();
bool
creation
=
false
;
if
(
str
.
find
(
"^"
)
!=
std
::
string
::
npos
)
{
creation
=
true
;
}
term
.
push_back
({
std
::
stoi
(
ctx
->
fermion
(
i
)
->
op
()
->
INT
()
->
getText
()),
creation
});
// std::cout << "HI: " << ctx->fermion(i)->getText() << ", " << "\n";
}
// std::cout << "SIZE OF TERMS: " << term.size() << "\n";
_op
+=
FermionOperator
(
term
,
coeff
);
// std::cout << "ENTER TERM: " << ctx->getText() << ", " << ctx->fermion().size() << "\n";
}
}
}
\ No newline at end of file
quantum/gate/observable/fermion/FermionListenerImpl.hpp
0 → 100644
View file @
dfc86566
#include
"FermionOperatorBaseListener.h"
#include
"Utils.hpp"
#include
"FermionOperator.hpp"
using
namespace
fermion
;
namespace
xacc
{
namespace
quantum
{
class
FermionOperatorErrorListener
:
public
antlr4
::
BaseErrorListener
{
public:
void
syntaxError
(
antlr4
::
Recognizer
*
recognizer
,
antlr4
::
Token
*
offendingSymbol
,
size_t
line
,
size_t
charPositionInLine
,
const
std
::
string
&
msg
,
std
::
exception_ptr
e
)
override
{
std
::
ostringstream
output
;
output
<<
"Invalid Pauli Operator source: "
;
output
<<
"line "
<<
line
<<
":"
<<
charPositionInLine
<<
" "
<<
msg
;
xacc
::
XACCLogger
::
instance
()
->
error
(
output
.
str
());
}
};
class
FermionListenerImpl
:
public
FermionOperatorBaseListener
{
protected:
FermionOperator
_op
;
bool
isMinus
=
false
;
public:
void
enterPlusorminus
(
FermionOperatorParser
::
PlusorminusContext
*
ctx
)
override
;
void
enterTerm
(
FermionOperatorParser
::
TermContext
*
ctx
)
override
;
FermionOperator
getOperator
()
{
return
_op
;}
};
}
}
\ No newline at end of file
quantum/gate/observable/fermion/FermionOperator.cpp
0 → 100644
View file @
dfc86566
#include
"FermionOperator.hpp"
#include
"FermionOperatorLexer.h"
#include
"FermionListenerImpl.hpp"
#include
"ObservableTransform.hpp"
#include
"xacc_service.hpp"
namespace
xacc
{
namespace
quantum
{
FermionTerm
&
FermionTerm
::
operator
*=
(
const
FermionTerm
&
v
)
noexcept
{
coeff
()
*=
std
::
get
<
0
>
(
v
);
// std::cout << "FermionTerm: " << id() << ", " << FermionTerm::id(std::get<1>(v)) << "\n";
auto
otherOps
=
std
::
get
<
1
>
(
v
);
for
(
auto
&
kv
:
otherOps
)
{
auto
site
=
kv
.
first
;
auto
c_or_a
=
kv
.
second
;
// std::cout << "HELLO: " << site << ", " << std::boolalpha << c_or_a << "\n";
Operators
o
=
ops
();
if
(
!
o
.
empty
())
{
auto
it
=
std
::
find_if
(
o
.
begin
(),
o
.
end
(),
[
&
](
const
std
::
pair
<
int
,
bool
>
&
element
)
{
return
element
.
first
==
site
;
});
// std::cout << it->first << ", " << std::boolalpha << it->second << "\n";
if
(
it
->
first
==
site
)
{
if
(
it
->
second
&&
c_or_a
)
{
// zero out this FermionTerm
ops
().
clear
();
}
}
else
{
ops
().
push_back
({
site
,
c_or_a
});
}
}
// This means, we have a op on same qubit in both
}
return
*
this
;
}
FermionOperator
::
FermionOperator
()
{}
FermionOperator
::
FermionOperator
(
std
::
complex
<
double
>
c
)
{
terms
.
emplace
(
std
::
make_pair
(
"I"
,
c
));
}
FermionOperator
::
FermionOperator
(
double
c
)
{
terms
.
emplace
(
std
::
make_pair
(
"I"
,
c
));
}
FermionOperator
::
FermionOperator
(
std
::
string
fromStr
)
{
fromString
(
fromStr
);
}
FermionOperator
::
FermionOperator
(
const
FermionOperator
&
i
)
:
terms
(
i
.
terms
)
{}
FermionOperator
::
FermionOperator
(
Operators
operators
)
{
terms
.
emplace
(
std
::
make_pair
(
FermionTerm
::
id
(
operators
),
operators
));
}
FermionOperator
::
FermionOperator
(
Operators
operators
,
std
::
complex
<
double
>
coeff
)
{
terms
.
emplace
(
std
::
piecewise_construct
,
std
::
forward_as_tuple
(
FermionTerm
::
id
(
operators
)),
std
::
forward_as_tuple
(
coeff
,
operators
));
}
FermionOperator
::
FermionOperator
(
Operators
operators
,
double
coeff
)
:
FermionOperator
(
operators
,
std
::
complex
<
double
>
(
coeff
,
0
))
{}
void
FermionOperator
::
clear
()
{
terms
.
clear
();
}
std
::
vector
<
std
::
shared_ptr
<
Function
>>
FermionOperator
::
observe
(
std
::
shared_ptr
<
Function
>
function
)
{
auto
transform
=
xacc
::
getService
<
ObservableTransform
>
(
"jw"
);
return
transform
->
transform
(
shared_from_this
())
->
observe
(
function
);
}
const
std
::
string
FermionOperator
::
toString
()
{
std
::
stringstream
s
;
for
(
auto
&
kv
:
terms
)
{
std
::
complex
<
double
>
c
=
std
::
get
<
0
>
(
kv
.
second
);
s
<<
c
<<
" "
;
Operators
ops
=
std
::
get
<
1
>
(
kv
.
second
);
std
::
vector
<
int
>
creations
,
annhilations
;
for
(
auto
&
t
:
ops
)
{
// std::cout << "tostring " << t.first << ", " << t.second << "\n";
if
(
t
.
second
)
{
creations
.
push_back
(
t
.
first
);
}
else
{
annhilations
.
push_back
(
t
.
first
);
}
}
std
::
sort
(
creations
.
rbegin
(),
creations
.
rend
());
std
::
sort
(
annhilations
.
rbegin
(),
annhilations
.
rend
());
for
(
auto
&
t
:
creations
)
{
s
<<
t
<<
"^"
<<
std
::
string
(
" "
);
}
for
(
auto
&
t
:
annhilations
)
{
s
<<
t
<<
std
::
string
(
" "
);
}
s
<<
"+ "
;
}
// std::cout << "tostring " << s.str() << "\n";
auto
r
=
s
.
str
().
substr
(
0
,
s
.
str
().
size
()
-
2
);
xacc
::
trim
(
r
);
return
r
;
}
void
FermionOperator
::
fromString
(
const
std
::
string
str
)
{
using
namespace
antlr4
;
using
namespace
fermion
;
ANTLRInputStream
input
(
str
);
FermionOperatorLexer
lexer
(
&
input
);
lexer
.
removeErrorListeners
();
lexer
.
addErrorListener
(
new
FermionOperatorErrorListener
());
CommonTokenStream
tokens
(
&
lexer
);
FermionOperatorParser
parser
(
&
tokens
);
parser
.
removeErrorListeners
();
parser
.
addErrorListener
(
new
FermionOperatorErrorListener
());
// Walk the Abstract Syntax Tree
tree
::
ParseTree
*
tree
=
parser
.
fermionSrc
();
FermionListenerImpl
listener
;
tree
::
ParseTreeWalker
::
DEFAULT
.
walk
(
&
listener
,
tree
);
clear
();
operator
+=
(
listener
.
getOperator
());
}
const
int
FermionOperator
::
nBits
()
{
return
0
;
}
FermionOperator
&
FermionOperator
::
operator
+=
(
const
FermionOperator
&
v
)
noexcept
{
for
(
auto
&
kv
:
v
.
terms
)
{
auto
termId
=
kv
.
first
;
auto
otherTerm
=
kv
.
second
;
if
(
terms
.
count
(
termId
))
{
terms
.
at
(
termId
).
coeff
()
+=
otherTerm
.
coeff
();
}
else
{
terms
.
insert
({
termId
,
otherTerm
});
}
if
(
std
::
abs
(
terms
[
termId
].
coeff
())
<
1e-12
)
{
terms
.
erase
(
termId
);
}
}
return
*
this
;
}
FermionOperator
&
FermionOperator
::
operator
-=
(
const
FermionOperator
&
v
)
noexcept
{
return
operator
+=
(
-
1.0
*
v
);
}
FermionOperator
&
FermionOperator
::
operator
*=
(
const
FermionOperator
&
v
)
noexcept
{
std
::
unordered_map
<
std
::
string
,
FermionTerm
>
newTerms
;
for
(
auto
&
kv
:
terms
)
{
for
(
auto
&
vkv
:
v
.
terms
)
{
auto
multTerm
=
kv
.
second
*
vkv
.
second
;
if
(
!
multTerm
.
ops
().
empty
())
{
auto
id
=
multTerm
.
id
();
if
(
!
newTerms
.
insert
({
id
,
multTerm
}).
second
)
{
newTerms
.
at
(
id
).
coeff
()
+=
multTerm
.
coeff
();
}
if
(
std
::
abs
(
newTerms
.
at
(
id
).
coeff
())
<
1e-12
)
{
newTerms
.
erase
(
id
);
}
}
}
}
terms
=
newTerms
;
return
*
this
;
}
bool
FermionOperator
::
operator
==
(
const
FermionOperator
&
v
)
noexcept
{
if
(
terms
.
size
()
!=
v
.
terms
.
size
())
{
return
false
;
}
for
(
auto
&
kv
:
terms
)
{
bool
found
=
false
;
for
(
auto
&
vkv
:
v
.
terms
)
{
if
(
kv
.
second
.
operator
==
(
vkv
.
second
))
{
found
=
true
;
break
;
}
}
if
(
!
found
)
{
return
false
;
}
}
return
true
;
}
FermionOperator
&
FermionOperator
::
operator
*=
(
const
double
v
)
noexcept
{
return
operator
*=
(
std
::
complex
<
double
>
(
v
,
0
));
}
FermionOperator
&
FermionOperator
::
operator
*=
(
const
std
::
complex
<
double
>
v
)
noexcept
{
for
(
auto
&
kv
:
terms
)
{
std
::
get
<
0
>
(
kv
.
second
)
*=
v
;
}
return
*
this
;
}
}
// namespace quantum
}
// namespace xacc
bool
operator
==
(
const
xacc
::
quantum
::
FermionOperator
&
lhs
,
const
xacc
::
quantum
::
FermionOperator
&
rhs
)
{
if
(
lhs
.
getTerms
().
size
()
!=
rhs
.
getTerms
().
size
())
{
return
false
;
}
for
(
auto
&
kv
:
lhs
.
getTerms
())
{
bool
found
=
false
;
for
(
auto
&
vkv
:
rhs
.
getTerms
())
{
if
(
kv
.
second
.
operator
==
(
vkv
.
second
))
{
found
=
true
;
break
;
}
}
if
(
!
found
)
{
return
false
;
}
}
return
true
;
}
\ No newline at end of file
quantum/gate/observable/fermion/FermionOperator.g4
0 → 100644
View file @
dfc86566
grammar FermionOperator;
fermionSrc : term(plusorminus term) *;
plusorminus : '+' | '-';
term : coeff ? (fermion) *;
fermion : op;
op : INT '^' | INT;
coeff : complex | real;
complex : '('(real | INT)','(real | INT)')';
real : REAL;
comment : COMMENT;
COMMENT : '#' ~[\r\n] * EOL;
/* Real number */
REAL : ('-') ? INT ? '.' INT;
/* Non-negative integer */
INT : ('0'..'9') + ;
/* Strings include numbers and slashes */
/* Whitespaces, we skip'em */
WS : [ \t\r\n]->skip;
/* This is the end of the line, boys */
EOL : '\r' ? '\n';
quantum/gate/observable/fermion/FermionOperator.hpp
0 → 100644
View file @
dfc86566
#ifndef XACC_FERMIONOPERATOR_HPP_
#define XACC_FERMIONOPERATOR_HPP_
#include
"Observable.hpp"
#include
"operators.hpp"
#include
<memory>
#include
<unordered_map>
namespace
xacc
{
namespace
quantum
{
class
FermionOperator
;
}
}
// namespace xacc
bool
operator
==
(
const
xacc
::
quantum
::
FermionOperator
&
lhs
,
const
xacc
::
quantum
::
FermionOperator
&
rhs
);
namespace
xacc
{
namespace
quantum
{
using
Operator
=
std
::
pair
<
int
,
bool
>
;
using
Operators
=
std
::
vector
<
Operator
>
;
// using SiteMap = std::map<Operators, std::complex<double>>;
using
FermionTermTuple
=
std
::
tuple
<
std
::
complex
<
double
>
,
Operators
>
;
class
FermionTerm
:
public
FermionTermTuple
,
public
tao
::
operators
::
commutative_multipliable
<
FermionTerm
>
,
public
tao
::
operators
::
equality_comparable
<
FermionTerm
>
{
public:
FermionTerm
()
{
std
::
get
<
0
>
(
*
this
)
=
std
::
complex
<
double
>
(
1.0
,
0.0
);
std
::
get
<
1
>
(
*
this
)
=
{};
}
FermionTerm
(
const
FermionTerm
&
t
)
{
std
::
get
<
0
>
(
*
this
)
=
std
::
get
<
0
>
(
t
);
std
::
get
<
1
>
(
*
this
)
=
std
::
get
<
1
>
(
t
);
}
FermionTerm
(
std
::
complex
<
double
>
c
)
{
std
::
get
<
0
>
(
*
this
)
=
c
;
std
::
get
<
1
>
(
*
this
)
=
{};
}
FermionTerm
(
std
::
complex
<
double
>
c
,
Operators
ops
)
{
std
::
get
<
0
>
(
*
this
)
=
c
;
std
::
get
<
1
>
(
*
this
)
=
ops
;
}
FermionTerm
(
Operators
ops
)
{
std
::
get
<
0
>
(
*
this
)
=
std
::
complex
<
double
>
(
1.0
,
0.0
);
std
::
get
<
1
>
(
*
this
)
=
ops
;
}
static
const
std
::
string
id
(
const
Operators
&
ops
)
{
std
::
vector
<
int
>
creations
,
annhilations
;
for
(
auto
&
t
:
ops
)
{
if
(
t
.
second
)
{
creations
.
push_back
(
t
.
first
);
}
else
{
annhilations
.
push_back
(
t
.
first
);
}
}
std
::
sort
(
creations
.
rbegin
(),
creations
.
rend
());
std
::
sort
(
annhilations
.
rbegin
(),
annhilations
.
rend
());
std
::
stringstream
s
;
for
(
auto
&
t
:
creations
)
{
s
<<
t
<<
"^"
<<
std
::
string
(
" "
);
}
for
(
auto
&
t
:
annhilations
)
{
s
<<
t
<<
std
::
string
(
" "
);
}
if
(
s
.
str
().
empty
())
{
return
"I"
;
}
return
s
.
str
();
}
const
std
::
string
id
()
{
std
::
vector
<
int
>
creations
,
annhilations
;
for
(
auto
&
t
:
ops
())
{
if
(
t
.
second
)
{
creations
.
push_back
(
t
.
first
);
}
else
{
annhilations
.
push_back
(
t
.
first
);
}
}
std
::
sort
(
creations
.
rbegin
(),
creations
.
rend
());
std
::
sort
(
annhilations
.
rbegin
(),
annhilations
.
rend
());
std
::
stringstream
s
;
for
(
auto
&
t
:
creations
)
{
s
<<
t
<<
"^"
<<
std
::
string
(
" "
);
}
for
(
auto
&
t
:
annhilations
)
{
s
<<
t
<<
std
::
string
(
" "
);
}
if
(
s
.
str
().
empty
())
{
return
"I"
;
}
return
s
.
str
();
}
Operators
&
ops
()
{
return
std
::
get
<
1
>
(
*
this
);
}
std
::
complex
<
double
>
&
coeff
()
{
return
std
::
get
<
0
>
(
*
this
);
}
FermionTerm
&
operator
*=
(
const
FermionTerm
&
v
)
noexcept
;
bool
operator
==
(
const
FermionTerm
&
v
)
noexcept
{
return
(
std
::
get
<
1
>
(
*
this
)
==
std
::
get
<
1
>
(
v
));
}
};
class
FermionOperator
:
public
Observable
,
public
std
::
enable_shared_from_this
<
FermionOperator
>
,
public
tao
::
operators
::
commutative_ring
<
FermionOperator
>
,
public
tao
::
operators
::
equality_comparable
<
FermionOperator
>
,
public
tao
::
operators
::
commutative_multipliable
<
FermionOperator
,
double
>
,
public
tao
::
operators
::
commutative_multipliable
<
FermionOperator
,
std
::
complex
<
double
>>
{