Skip to content

Code ergonomics: Create SparseObservable from QkObs #162

Description

@banezia

What should we add?

Hello, I wanted to propose an alternative from method for creating SparseObservable objects.

The idea would be to receive a C QkObs pointer where it's extracted its data in order to construct a new SparseObservable object. This would be beneficial if it's wanted to construct observables where the terms have more than one bit_term.

I believe the implementation could be something like the following:

static SparseObservable from_obs(QkObs *obs)
{
    QkComplex64 *c_coeffs = qk_obs_coeffs(obs);
    size_t *c_boundaries = qk_obs_boundaries(obs);
    
    size_t terms_len = qk_obs_num_terms(obs);

    std::vector<size_t> boundaries(terms_len + 1);
    std::vector<std::complex<double>> coeffs(terms_len);
    
    std::vector<QkBitTerm> bit_terms;
    reg_t indices;

    QkObsTerm term;
    for (size_t i = 0; i < terms_len + 1; i++)
    {
        boundaries[i] = c_boundaries[i];
        if (i < terms_len)
        {
            if (qk_obs_term(obs, i, &term) != QkExitCode_Success) {
                throw std::runtime_error("Error while obtaining term from observable.");
            }
            coeffs[i] = std::complex<double>(term.coeff.re, term.coeff.im);
            for (size_t j = 0; j < term.len; j++)
            {
                bit_terms.push_back(term.bit_terms[j]);
                indices.push_back(term.indices[j]);
            }
        }
    }

    return SparseObservable(qk_obs_num_qubits(obs), coeffs, bit_terms, indices, boundaries);
}

And the usage could be something like the following:

size_t num_qubits = 3;
QkObs *obs = qk_obs_zero(num_qubits);

QkBitTerm zz[2] = {QkBitTerm_Z, QkBitTerm_Z};
uint32_t zz_q[2] = {0, 1};
QkObsTerm zz_term = {{1, 0.}, 2, zz, zz_q, num_qubits};
qk_obs_add_term(obs, &zz_term);

QkBitTerm x[1] = {QkBitTerm_X};
uint32_t x_q[1] = {2};
QkObsTerm x_term = {{1, 0.}, 1, x, x_q, num_qubits};
qk_obs_add_term(obs, &x_term);

auto cpp_obs = SparseObservable::from_obs(obs);

qk_obs_free(obs);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions