return complex value only when isherm is false
avoid extra copy by changing array(X.todense()) to X.toarray(). added optional argument for squeezing out unused dimensions in the resulting ndarray
use cython functions in expect() for better performance