Skip to content

Commit

Permalink
Insert CSparseObservable alias for documentation purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
mrossinek committed Dec 20, 2024
1 parent 02ed120 commit ba7b3a4
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 84 deletions.
3 changes: 0 additions & 3 deletions crates/c_ext/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ sys_includes = ["complex.h"]
after_includes = """
typedef float complex Complex32;
typedef double complex Complex64;
/// @defgroup sparse_observable_functions SparseObservable Functions
/// This is a group of functions for interacting with opaque SparseObservable instances.
"""

[parse]
Expand Down
124 changes: 66 additions & 58 deletions crates/c_ext/src/sparse_observable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ use qiskit_accelerate::sparse_observable::{BitTerm, SparseObservable, SparseTerm
type IndexVec = Vec<u32>;
type BitTermVec = Vec<BitTerm>;

/// @defgroup SparseObservable SparseObservable
/// This is a group of functions for interacting with an opaque (Rust-space) SparseObservable
/// instance.
///
/// @ingroup SparseObservable
/// @brief The CSparseObservable is an opaque pointer to the Rust-space SparseObservable.
type CSparseObservable = SparseObservable;

/// Create a new index vector of ``uint32_t``\ s.
///
/// @return A pointer to an empty index vector.
Expand Down Expand Up @@ -150,7 +158,7 @@ pub extern "C" fn bit_terms_push(bit_terms: &mut BitTermVec, value: BitTerm) {
bit_terms.push(value)
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Construct the zero observable (without any terms).
///
/// @param num_qubits The number of qubits the observable is defined on.
Expand All @@ -159,16 +167,16 @@ pub extern "C" fn bit_terms_push(bit_terms: &mut BitTermVec, value: BitTerm) {
///
/// Example:
///
/// SparseObservable* zero = obs_zero(100);
/// CSparseObservable* zero = obs_zero(100);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_zero(num_qubits: u32) -> *mut SparseObservable {
let obs = SparseObservable::zero(num_qubits);
pub extern "C" fn obs_zero(num_qubits: u32) -> *mut CSparseObservable {
let obs = CSparseObservable::zero(num_qubits);
Box::into_raw(Box::new(obs))
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Construct the identity observable.
///
/// @param num_qubits The number of qubits the observable is defined on.
Expand All @@ -177,16 +185,16 @@ pub extern "C" fn obs_zero(num_qubits: u32) -> *mut SparseObservable {
///
/// Example:
///
/// SparseObservable* identity = obs_identity(100);
/// CCSparseObservable* identity = obs_identity(100);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_identity(num_qubits: u32) -> *mut SparseObservable {
let obs = SparseObservable::identity(num_qubits);
pub extern "C" fn obs_identity(num_qubits: u32) -> *mut CSparseObservable {
let obs = CSparseObservable::identity(num_qubits);
Box::into_raw(Box::new(obs))
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Deallocate the observable.
///
/// Memory deallocation is user responsibility. Every constructed observable
Expand All @@ -196,18 +204,18 @@ pub extern "C" fn obs_identity(num_qubits: u32) -> *mut SparseObservable {
///
/// Example:
///
/// SparseObservable* obs = obs_zero(100);
/// CSparseObservable* obs = obs_zero(100);
/// obs_deallocate(obs);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_deallocate(obs: &mut SparseObservable) {
pub extern "C" fn obs_deallocate(obs: &mut CSparseObservable) {
unsafe {
let _ = Box::from_raw(obs);
}
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Add a term to the observable by copy.
///
/// A term is defined by it's bit terms, along with their indices, and the complex coefficient.
Expand All @@ -220,7 +228,7 @@ pub extern "C" fn obs_deallocate(obs: &mut SparseObservable) {
/// Example:
///
/// u_int32_t num_qubits = 100;
/// SparseObservable *obs = obs_zero(num_qubits);
/// CSparseObservable *obs = obs_zero(num_qubits);
///
/// complex double coeff = 1;
///
Expand All @@ -242,7 +250,7 @@ pub extern "C" fn obs_deallocate(obs: &mut SparseObservable) {
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_push_copy(
obs: &mut SparseObservable,
obs: &mut CSparseObservable,
bit_terms: &BitTermVec,
indices: &IndexVec,
coeff: Complex64,
Expand All @@ -258,7 +266,7 @@ pub extern "C" fn obs_push_copy(
obs.add_term(term.view()).unwrap();
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Add a term to the observable and deallocate the memory for the indices and bit terms.
///
/// @param obs A pointer to the observable to which the term is added.
Expand All @@ -269,7 +277,7 @@ pub extern "C" fn obs_push_copy(
/// Example:
///
/// u_int32_t num_qubits = 100;
/// SparseObservable *obs = obs_zero(num_qubits);
/// CSparseObservable *obs = obs_zero(num_qubits);
///
/// complex double coeff = 1;
///
Expand All @@ -288,7 +296,7 @@ pub extern "C" fn obs_push_copy(
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_push_consume(
obs: &mut SparseObservable,
obs: &mut CSparseObservable,
bit_terms: &mut BitTermVec,
indices: &mut IndexVec,
coeff: Complex64,
Expand All @@ -309,7 +317,7 @@ pub extern "C" fn obs_push_consume(
obs.add_term(term.view()).unwrap(); // TODO handle error
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Get an observable term.
///
/// @param obs A pointer to the observable.
Expand All @@ -319,39 +327,39 @@ pub extern "C" fn obs_push_consume(
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// SparseTerm* term = obs_term(obs, 0);
/// // out-of-bounds indices will fail
/// // SparseTerm* will_fail = obs_term(obs, 1);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_term(obs: &SparseObservable, index: u64) -> *mut SparseTerm {
pub extern "C" fn obs_term(obs: &CSparseObservable, index: u64) -> *mut SparseTerm {
// We could also add a read-only view on the SparseTermView,
// whose lifetime would implicitly be bound to the observable.
// For now, we'll only provide a copy, as the Python interface does.
let term = obs.term(index as usize).to_term();
Box::into_raw(Box::new(term))
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Multiply the observable by a complex coefficient.
///
/// @param obs A pointer to the observable.
/// @param coeff The coefficient to multiply the observable with.
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// SparseObservable* result = obs_multiply(obs, 2);
/// CSparseObservable* obs = obs_identity(100);
/// CSparseObservable* result = obs_multiply(obs, 2);
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_multiply(obs: &SparseObservable, coeff: Complex64) -> *mut SparseObservable {
pub extern "C" fn obs_multiply(obs: &CSparseObservable, coeff: Complex64) -> *mut CSparseObservable {
let result = obs * coeff;
Box::into_raw(Box::new(result))
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Add two observables.
///
/// @param left A pointer to the left observable.
Expand All @@ -361,21 +369,21 @@ pub extern "C" fn obs_multiply(obs: &SparseObservable, coeff: Complex64) -> *mut
///
/// Example:
///
/// SparseObservable* left = obs_identity(100);
/// SparseObservable* right = obs_zero(100);
/// SparseObservable* result = obs_add(left, right);
/// CSparseObservable* left = obs_identity(100);
/// CSparseObservable* right = obs_zero(100);
/// CSparseObservable* result = obs_add(left, right);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_add(
left: &SparseObservable,
right: &SparseObservable,
) -> *mut SparseObservable {
left: &CSparseObservable,
right: &CSparseObservable,
) -> *mut CSparseObservable {
let result = left + right;
Box::into_raw(Box::new(result))
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Calculate the canonical representation of the observable.
///
/// @param obs A pointer to the observable.
Expand All @@ -385,23 +393,23 @@ pub extern "C" fn obs_add(
///
/// Example:
///
/// SparseObservable* iden = obs_identity(100);
/// SparseObservable* two = obs_add(iden, iden);
/// CSparseObservable* iden = obs_identity(100);
/// CSparseObservable* two = obs_add(iden, iden);
///
/// double tol = 1e-6;
/// SparseObservable* canonical = obs_canonicalize(two);
/// CSparseObservable* canonical = obs_canonicalize(two);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_canonicalize(
obs: &SparseObservable,
obs: &CSparseObservable,
tol: f64, // no optional arguments in C -- welcome to the ancient past
) -> *mut SparseObservable {
) -> *mut CSparseObservable {
let result = obs.canonicalize(tol);
Box::into_raw(Box::new(result))
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Copy the observable.
///
/// @param obs A pointer to the observable.
Expand All @@ -410,17 +418,17 @@ pub extern "C" fn obs_canonicalize(
///
/// Example:
///
/// SparseObservable* original = obs_identity(100);
/// SparseObservable* copied = obs_copy(original);
/// CSparseObservable* original = obs_identity(100);
/// CSparseObservable* copied = obs_copy(original);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_copy(obs: &SparseObservable) -> *mut SparseObservable {
pub extern "C" fn obs_copy(obs: &CSparseObservable) -> *mut CSparseObservable {
let copied = obs.clone();
Box::into_raw(Box::new(copied))
}

/// @ingroup sparse_observable_functions
/// @ingroup SparseObservable
/// Compare two observables for equality.
///
/// Note that this does not compare mathematical equality, but data equality. This means
Expand All @@ -433,13 +441,13 @@ pub extern "C" fn obs_copy(obs: &SparseObservable) -> *mut SparseObservable {
///
/// Example:
///
/// SparseObservable* observable = obs_identity(100);
/// SparseObservable* other = obs_identity(100);
/// CSparseObservable* observable = obs_identity(100);
/// CSparseObservable* other = obs_identity(100);
/// bool are_equal = obs_equal(observable, other);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_equal(observable: &SparseObservable, other: &SparseObservable) -> bool {
pub extern "C" fn obs_equal(observable: &CSparseObservable, other: &CSparseObservable) -> bool {
observable.eq(other)
}
/// Get the number of terms in the observable.
Expand All @@ -450,12 +458,12 @@ pub extern "C" fn obs_equal(observable: &SparseObservable, other: &SparseObserva
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// uint64_t num_terms = obs_num_terms(obs); // num_terms==1
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_num_terms(observable: &SparseObservable) -> u64 {
pub extern "C" fn obs_num_terms(observable: &CSparseObservable) -> u64 {
observable.num_terms() as u64
}

Expand All @@ -467,27 +475,27 @@ pub extern "C" fn obs_num_terms(observable: &SparseObservable) -> u64 {
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// uint32_t num_qubits = obs_num_qubits(obs); // 100
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_num_qubits(observable: &SparseObservable) -> u32 {
pub extern "C" fn obs_num_qubits(observable: &CSparseObservable) -> u32 {
observable.num_qubits()
}

/// Print the observable.
///
/// @param term A pointer to the ``SparseObservable`` to print.
/// @param term A pointer to the ``CSparseObservable`` to print.
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// obs_print(obs);
///
#[no_mangle]
#[cfg(feature = "cbinding")]
pub extern "C" fn obs_print(observable: &SparseObservable) {
pub extern "C" fn obs_print(observable: &CSparseObservable) {
println!("{:?}", observable);
}

Expand All @@ -500,7 +508,7 @@ pub extern "C" fn obs_print(observable: &SparseObservable) {
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// SparseTerm* term = obs_term(obs, 0);
///
/// obs_deallocate(obs); // term is still allocated!
Expand All @@ -520,7 +528,7 @@ pub extern "C" fn obsterm_deallocate(term: &mut SparseTerm) {
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// SparseTerm* term = obs_term(obs, 0);
/// obsterm_print(term);
///
Expand All @@ -538,7 +546,7 @@ pub extern "C" fn obsterm_print(term: &SparseTerm) {
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// SparseTerm* term = obs_term(obs, 0);
/// complex double coeff = obsterm_coeff(term);
///
Expand All @@ -556,7 +564,7 @@ pub extern "C" fn obsterm_coeff(term: &SparseTerm) -> Complex64 {
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// SparseTerm* term = obs_term(obs, 0);
/// uint32_t num_qubits = obsterm_num_qubits(term);
///
Expand All @@ -574,7 +582,7 @@ pub extern "C" fn obsterm_num_qubits(term: &SparseTerm) -> u32 {
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// SparseTerm* term = obs_term(obs, 0);
/// uint32_t nni = obsterm_nni(term);
///
Expand All @@ -601,7 +609,7 @@ pub struct PauliTerm {
///
/// Example:
///
/// SparseObservable* obs = obs_identity(100);
/// CSparseObservable* obs = obs_identity(100);
/// SparseTerm* term = obs_term(obs, 0);
/// uint32_t nni = obsterm_nni(term);
///
Expand Down
Loading

0 comments on commit ba7b3a4

Please sign in to comment.