Skip to content

Code ergonomics: Create SparseObservable from QkObs #162

Description

@Estebanrg21

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions