Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hamiltonians #28

Open
stavros11 opened this issue Jun 13, 2024 · 2 comments
Open

Hamiltonians #28

stavros11 opened this issue Jun 13, 2024 · 2 comments

Comments

@stavros11
Copy link
Member

Hamiltonians do not need to be included or accounted for in qibo-core, as they generally do not participate in circuit execution.

We have only found one case were a Hamiltonian is involved during circuit execution: when the Energy callback is used. In that case, it is sufficient to represent the Hamiltonian as a matrix (array) for the case of dense Hamiltonians, or a list of circuits for SymbolicHamiltonians.

The matrix representation of a Hamiltonian is not always unitary. This can be accommodated by having a general Matrix gate in qibo-core which is mapped to an arbitrary (potentially non-unitary) matrix. The current Unitary gate in qibo can also use this Matrix gate with the additional check of being unitary. (this check does not happen currently, meaning that Unitary gates may in fact be non-unitary)

@alecandido
Copy link
Member

Similarly to the channels' case, #27, we can represent Hamiltonians as lists of (coefficient, circuit) pair (while it would be (coefficient, gate) for channels).

However, both because they are not entering execution, and additional complications (see below) I'd not mix the definition with the current list of gates, also used to implement the queue, and instead do something like:

struct Circuit {
    gates: Vec<Gate>,
    ...,
    hamiltonians: Vec<Hamiltonian>,
    observable: Option<usize>,
}

struct Hamiltonian {
    coefficients: Vec<f64>,
    components: Vec<Circuit>
}

where the observable field may be useful to specify an observable for the final contraction, to cater for tensor networks simulators as well.

Apart from being optimal or not, notice that the types above are mutually recursive, though they're size is known at compile time, since the recursion is kepts behind references (Vec<...>s are essentially pointers). I'm going to test whether its possible, otherwise we might need to inline Hamiltonian as Vec<(f64, Circuit)> (possibly with a compile-time-resolved alias) since simply recursive types are actually possible.
https://doc.rust-lang.org/reference/types.html#recursive-types

@alecandido
Copy link
Member

alecandido commented Jun 13, 2024

Ok, I checked: mutual recursion on types is actually possible (provided the guaranteed compile-time size)

#[derive(Debug)]
struct A {
    pub b: Vec<B>,
}

#[derive(Debug)]
struct B {
    pub a: Vec<A>,
}

fn main() {
    let a = A {
        b: vec![B { a: vec![] }],
    };
    println!("{a:#?}");
}
    Finished dev [unoptimized + debuginfo] target(s) in 0.58s
     Running `/Users/alessandro/Projects/quantum/qibo-core/target/debug/ciao`
A {
    b: [
        B {
            a: [],
        },
    ],
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants