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

Feature request: more efficient state sampling #324

Open
kwkbtr opened this issue Aug 30, 2022 · 5 comments
Open

Feature request: more efficient state sampling #324

kwkbtr opened this issue Aug 30, 2022 · 5 comments
Assignees
Labels
enhancement New feature or request

Comments

@kwkbtr
Copy link
Contributor

kwkbtr commented Aug 30, 2022

We currently use QuantumState::sampling for state sampling.
The current implementation involves random number generation for sampling_count times:

qulacs/src/cppsim/state.hpp

Lines 668 to 674 in 00040b9

for (UINT count = 0; count < sampling_count; ++count) {
double r = random.uniform();
auto ite =
std::lower_bound(stacked_prob.begin(), stacked_prob.end(), r);
auto index = std::distance(stacked_prob.begin(), ite) - 1;
result.push_back(index);
}

For our use cases, it is often the case that the sampling_count is much larger than the dimension of a state vector (e.g. sampling_count = 10^12 while qubit_count is around 10). In such a case, the random number generation is quite time-consuming.

We only need statistics of sampling for our use cases (i.e. 00...0 occurred m_1 times, 00...1 occurred m_2 times, ...).
For such use cases, it might be more efficient if we sample the statistics by using a multinomial distribution with parameters given by probabilities of a single measurement on the quantum state.

@m-ymzk
Copy link
Contributor

m-ymzk commented Aug 30, 2022

Hi, @kwkbtr san,
Since uniform random numbers are used for sampling,
If the qubit_count is as small as 10, you might get the same result in the following steps.

  1. Get normalized state_vector
  2. Calculates the square of the norm of each element ( Or element * conj(element) )
  3. multiply each probability by 10^12

Or am I misunderstanding something?

@kwkbtr
Copy link
Contributor Author

kwkbtr commented Aug 30, 2022

@m-ymzk san,
That procedure will give expectation values of counts for each measurement result, which are not random.
What we expect from sampling is a single realization of counts for repeated measurements in a probabilistic simulation.
The latter is random, hence a procedure generating it necessarily uses a random number generator, while your procedure does not.

@m-ymzk
Copy link
Contributor

m-ymzk commented Aug 30, 2022

So there is a case that a value including a stochastic variation is required instead of an ideal value.
I understand. Thank you.

@snuffkin
Copy link

How about using scipy multinomial?
I made a sample.

from scipy.stats import multinomial
import numpy as np
import time

# arrange
n = 1e12 # number of sampling
uniform = np.random.rand(2**10)
p = uniform / np.sum(uniform) # probability distribution

# act
start_time = time.time()
multinomial.rvs(n, p)
end_time = time.time()

print(f"{end_time - start_time:.6f} [s]")

When I ran this it completed within 1 millisecond, sampling 10^12 times at 10 qubits.

In practice, we may need to call scipy's C++ interface from qulacs.

@kwkbtr
Copy link
Contributor Author

kwkbtr commented Sep 23, 2022

Yes, we are currently using multinomial in numpy.
I just thought that this feature would be useful for many users and having this in qulacs may be good for better performance.

@KowerKoint KowerKoint self-assigned this Mar 14, 2024
@KowerKoint KowerKoint added the enhancement New feature or request label Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants