13 #ifndef XACC_ALGORITHM_DDCL_STRATEGIES_JS_LOSS_HPP_ 14 #define XACC_ALGORITHM_DDCL_STRATEGIES_JS_LOSS_HPP_ 20 #include "InstructionIterator.hpp" 27 double entropy(
const std::vector<double> p,
const std::vector<double> q) {
29 for (
int i = 0; i < p.size(); i++) {
30 if (std::fabs(p[i]) > 1e-12) {
31 sum += p[i] * std::log(p[i] / q[i]);
38 std::pair<double, std::vector<double>>
39 compute(Counts &counts,
const std::vector<double> &target,
const HeterogeneousMap& = {})
override {
41 for (
auto &x : counts) {
46 std::vector<double> q(target.size());
47 for (
auto &x : counts) {
48 int idx = std::stoi(x.first,
nullptr, 2);
49 q[idx] = (double)x.second / shots;
53 std::vector<double> m(target.size());
54 for (
int i = 0; i < m.size(); i++) {
55 m[i] = .5 * (target[i] + q[i]);
58 auto js = 0.5 * (entropy(target, m) + entropy(q, m));
59 return std::make_pair(js, q);
62 bool isValidGradientStrategy(
const std::string &gradientStrategy)
override {
66 const std::string
name()
const override {
return "js"; }
72 std::vector<double> currentParameterSet;
76 getCircuitExecutions(Circuit circuit,
const std::vector<double> &x)
override {
77 currentParameterSet = x;
78 std::set<std::size_t> uniqueBits = circuit->uniqueBits();
79 std::vector<Circuit> grad_circuits;
80 auto provider = xacc::getIRProvider(
"quantum");
81 for (
int i = 0; i < x.size(); i++) {
82 auto xplus = x[i] + xacc::constants::pi / 2.;
83 auto xminus = x[i] - xacc::constants::pi / 2.;
84 std::vector<double> tmpx_plus = x, tmpx_minus = x;
86 tmpx_minus[i] = xminus;
87 auto xplus_circuit = circuit->operator()(tmpx_plus);
88 auto xminus_circuit = circuit->operator()(tmpx_minus);
90 xplus_circuit->setName(circuit->name()+
"param_"+std::to_string(i)+
"_shift_plus");
91 xminus_circuit->setName(circuit->name()+
"param_"+std::to_string(i)+
"_shift_minus");
93 for (
auto &ii : uniqueBits) {
94 auto m = provider->createInstruction(
"Measure",
95 std::vector<std::size_t>{ii});
96 xplus_circuit->addInstruction(m);
98 for (
auto &ii : uniqueBits) {
99 auto m = provider->createInstruction(
"Measure",
100 std::vector<std::size_t>{ii});
101 xminus_circuit->addInstruction(m);
103 grad_circuits.push_back(xplus_circuit);
104 grad_circuits.push_back(xminus_circuit);
107 return grad_circuits;
110 void compute(std::vector<double> &grad, std::vector<std::shared_ptr<AcceleratorBuffer>> results,
111 const std::vector<double> &q_dist,
112 const std::vector<double> &target_dist)
override {
113 assert(2 * grad.size() == results.size());
117 for (
auto &x : results[0]->getMeasurementCounts()) {
123 std::vector<std::vector<double>> qplus_theta, qminus_theta;
124 for (
int i = 0; i < results.size(); i += 2) {
125 std::vector<double> qp(q_dist.size()), qm(q_dist.size());
126 for (
auto &x : results[i]->getMeasurementCounts()) {
127 int idx = std::stoi(x.first,
nullptr, 2);
128 qp[idx] = (double)x.second / shots;
130 for (
auto &x : results[i + 1]->getMeasurementCounts()) {
131 int idx = std::stoi(x.first,
nullptr, 2);
132 qm[idx] = (double)x.second / shots;
135 std::vector<double> shiftedp = currentParameterSet;
136 std::vector<double> shiftedm = currentParameterSet;
137 auto xplus = currentParameterSet[counter] + xacc::constants::pi / 2.;
138 auto xminus = currentParameterSet[counter] - xacc::constants::pi / 2.;
140 shiftedp[counter] = xplus;
141 shiftedm[counter] = xminus;
143 results[i]->addExtraInfo(
"gradient-index", counter);
144 results[i+1]->addExtraInfo(
"gradient-index", counter);
146 results[i]->addExtraInfo(
"shift-direction",
"plus");
147 results[i+1]->addExtraInfo(
"shift-direction",
"minus");
149 results[i]->addExtraInfo(
"qdist", qp);
150 results[i+1]->addExtraInfo(
"qdist", qm);
152 results[i]->addExtraInfo(
"gradient-parameters", shiftedp);
153 results[i+1]->addExtraInfo(
"gradient-parameters", shiftedm);
155 qplus_theta.push_back(qp);
156 qminus_theta.push_back(qm);
161 for (
int i = 0; i < grad.size(); i++) {
163 for (
int x = 0; x < q_dist.size(); x++) {
164 if (std::fabs(q_dist[x]) > 1e-12) {
165 sum += std::log(q_dist[x] / (0.5 * (target_dist[x] + q_dist[x]))) *
166 0.5 * (qplus_theta[i][x] - qminus_theta[i][x]);
176 const std::string
name()
const override {
return "js-parameter-shift"; }
const std::string description() const override
Definition: js.hpp:177
Definition: Accelerator.hpp:25
const std::string name() const override
Definition: js.hpp:66
const std::string name() const override
Definition: js.hpp:176
Definition: heterogeneous.hpp:45
const std::string description() const override
Definition: js.hpp:67