-
Notifications
You must be signed in to change notification settings - Fork 46
CKS algorithm #294
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
base: main
Are you sure you want to change the base?
CKS algorithm #294
Conversation
…in from_matrix function of QubitOperator
…ecify their own block encoding, passing the block encoding unitary U, state G, and number of unitaries n. Minor changes to the docstrings.
…he block encoding. b can now be passed as an array, or a function returning the operand. block_encoding keyword removed. kappa keyword introduced.
…s a block encoding touple, b as a state preparing function
|
|
||
| return operand, in_case, out_case | ||
|
|
||
| def inner_CKS_wrapper(qlsp, eps, kappa=None, max_beta=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@positr0nium is there another way to pass numpy arrays without having to use this wrapper workaround?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can pass numpy arrays by using the static feature of RUS and converting the array to a tuple before:
from qrisp import *
import numpy as np
@RUS(static_argnums = 0)
def inner_rus(array):
qv = QuantumVariable(2)
h(qv[array[0]])
return measure(qv) == 0, qv
@jaspify
def main():
array = np.ones(2)
array_tuple = tuple(array)
res_qv = inner_rus(array_tuple)
return measure(res_qv)
print(main())
This snippet needs the latest commit to be bug-free 😇
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but for 2D arrays it's more complicated. Then tuple(arr)will be a tuple of arrays.
Since A can also be a block encoding and b a function, I would keep this as it is. Otherwise, it would require further case distinctions.
|
The documentation has been provided for all of the functions, with an emphasis on the main CKS function and the main circuit constructing inner_CKS function. Tests have also been added. The PR is mature enough for a review @positr0nium @renezander90 Please let me know in case anything else needs to be (re)added to the to-do list above, and/or modified prior to merging into main. |
…d if it is not specified
…lled inside unary_prep and not shown in the documentation
…ith the CKS paper: we now add the Chebyshev polynomials up to 2j_0+1 (before it was 2j_0-1). Also the jrange was adapted.
… for constructing the circuit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work :)
| where $U$ is the block encoding unitary acting on $\mathcal H_a\otimes H_s$ (for some auxiliary Hilbert space $\mathcal H_a$), | ||
| and $G$ prepares the block encoding state $\ket{G}_a=G\ket{0}_a$ in the auxiliary variable such that $(\bra{G}_a\otimes\mathbb I_s)U(\ket{G_a}\otimes\mathbb I_s)=H$. | ||
| Here $\mathbb I_s$ denotes the identity acting on $\mathcal H_s$. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this defintion is of course mathematically sound, to me it was very helpful to understand that a block encoding is a non-unitary matrix
Maybe it could be helpful to elaborate this here.
EDIT: This is only true, if |G> = |0>. But maybe it could still help understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in b91ed66. I think it is true, if |G> = G|0>, i.e., the state preparation acts on |0>.
|
|
||
| @classmethod | ||
| def from_matrix(self, matrix): | ||
| def from_matrix(self, matrix, reversed=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename this parameter to reverse_endianness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 6f9ce42.
| H = \sum_{i=0}^{T-1}\alpha_iP_i | ||
| where $\alpha_i$ are real coefficients, $P_i$ are Pauli operators, and $T$ is the number of terms. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pauli operator -> Pauli string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in b91ed66.
| return unitaries, np.array(coefficients, dtype=float) | ||
|
|
||
| def pauli_block_encoding(self): | ||
| r""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good if there is some paper reference here to compare the conventions etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in b91ed66.
| Examples | ||
| -------- | ||
| We apply a Hermitian matrix to a quantum state via a Pauli block encoding. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would probably be helpful to explain a bit more why applying RUS here gives the observed behavior
| Returns | ||
| ------- | ||
| U : function | ||
| A function ``U(operand, case)`` applying the block encoding unitary $U$ to ``operand`` and ``case`` QuantumVariables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many other functions in Qrisp that have one permeable and one "operated on" type of argument follow the convention that the permeably argument comes first in the signature (for instancee cx or every adder). Could help to continue this :).
Otherwise I really like the way that you abstracted the concept of a Pauli-Block encoding into code. The interface is well designed :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point. I will change this here. However, note that we also do not follow this convention for the qswitch, and changing this in the future will be a breaking change.
|
|
||
|
|
||
| def cheb_coefficients(j0, b): | ||
| """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to have some reference here
|
|
||
|
|
||
| def CKS_parameters(A, eps, kappa=None, max_beta=None): | ||
| """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reference would also be nice here
| corresponds to, e.g., an Ising or a Heisenberg Hamiltonian, the number of Pauli terms may not scale favorably in general. | ||
| For certain sparse matrices, their structure can be exploited to construct more efficient block-encodings. | ||
| In this example, we construct a block-encoding representation for a tridiagonal 3-sparse matrix defined by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be helpful to have an example matrix - seeing the code is also good but an example might help even more.
This PR implements the Childs–Kothari–Somma (CKS) linear systems algorithm using the Chebyshev approach.
To-do:
Improve documentationproofread docstringsadd examples to CKS function (one for A unitary, one for A as a block encoding tuple)fix the compiled html (CKS.rst)extend the description in CKS.rstadd example to inner_CKS showing how to run CKS with post-selection