class_docstr: This class enables to initialize electron's position using gauss distribution around a nucleus and update using Markov Chain Monte-Carlo(MCMC) moves.
  
  Using the probability obtained from the square of magnitude of wavefunction of a molecule/atom, MCMC steps can be performed to get the electron's positions and further update the wavefunction.
  This method is primarily used in methods like Variational Monte Carlo to sample electrons around the nucleons.
  Sampling can be done in 2 ways:
  -Simultaneous: All the electrons' positions are updated all at once.
  
  -Single-electron: MCMC steps are performed only a particular electron, given their index value.
  
  Further these moves can be done in 2 methods:
  -Symmetric: In this configuration, the standard deviation for all the steps are uniform.
  
  -Asymmetric: In this configuration, the standard deviation are not uniform and typically the standard deviation is obtained a function like harmonic distances, etc.
  
  Irrespective of these methods, the initialization is done uniformly around the respective nucleus and the number of electrons specified.
  
  Example
  -------
  >>> from deepchem.utils.electron_sampler import ElectronSampler
  >>> test_f = lambda x: 2*np.log(np.random.uniform(low=0,high=1.0,size=np.shape(x)[0]))
  >>> distribution=ElectronSampler(central_value=np.array([[1,1,3],[3,2,3]]),f=test_f,seed=0,batch_no=2,steps=1000,)
  >>> distribution.gauss_initialize_position(np.array([[1],[2]]))
  
  >> print(distribution.x)
  [[[[1.03528105 1.00800314 3.01957476]]
  
    [[3.01900177 1.99697286 2.99793562]]
  
    [[3.00821197 2.00288087 3.02908547]]]
  
  
  [[[1.04481786 1.03735116 2.98045444]]
  
    [[3.01522075 2.0024335  3.00887726]]
  
    [[3.00667349 2.02988158 2.99589683]]]]
  >>> distribution.move()
  0.5115
  
  >> print(distribution.x)
  [[[[-0.32441754  1.23330263  2.67927645]]
  
    [[ 3.42250997  2.23617126  3.55806632]]
  
    [[ 3.37491385  1.54374006  3.13575241]]]
  
  
  [[[ 0.49067726  1.03987841  3.70277884]]
  
    [[ 3.5631939   1.68703947  2.5685874 ]]
  
    [[ 2.84560249  1.73998364  3.41274181]]]]
docstr: Parameters
  ----------
  central_value: np.ndarray
      Contains each nucleus' coordinates in a 2D array. The shape of the array should be(number_of_nucleus,3).Ex: [[1,2,3],[3,4,5],..]
  f:Callable[[np.ndarray],np.ndarray]
      A function that should give the twice the log probability of wavefunction of the molecular system when called. Should taken in a 4D array of electron's positions(x) as argument and return a numpy array containing the log probabilities of each batch.
  batch_no: int, optional (default 10)
      Number of batches of the electron's positions to be initialized.
  x: np.ndarray, optional (default np.ndarray([]))
      Contains the electron's coordinates in a 4D array. The shape of the array should be(batch_no,no_of_electrons,1,3). Can be a 1D empty array, when electron's positions are yet to be initialized.
  steps: int, optional (default 10)
      The number of MCMC steps to be performed when the moves are called.
  steps_per_update: int (default 10)
      The number of steps after which the parameters of the MCMC gets updated.
  seed: int, optional (default None)
      Random seed to use.
  symmetric: bool, optional(default True)
      If true, symmetric moves will be used, else asymmetric moves will be followed.
  simultaneous: bool, optional(default True)
      If true, MCMC steps will be performed on all the electrons, else only a single electron gets updated.
  
  Attributes
  ----------
  sampled_electrons: np.ndarray
      Keeps track of the sampled electrons at every step, must be empty at start.
docstr_tok: ["Parameters","--","--","--","--","--","central_value",":","np.ndarray","Contains","each","nucleus","'","coordinates","in","a","2D","array",".","The","shape","of","the","array","should","be","(","number_of_nucleus,3",")",".Ex",":","[","[","1,2,3","]",",","[","3,4,5","]",",","..","]","f",":","Callable","[","[","np.ndarray","]",",","np.ndarray","]","A","function","that","should","give","the","twice","the","log","probability","of","wavefunction","of","the","molecular","system","when","called",".","Should","taken","in","a","4D","array","of","electron","'s","positions","(","x",")","as","argument","and","return","a","numpy","array","containing","the","log","probabilities","of","each","batch",".","batch_no",":","int",",","optional","(","default","10",")","Number","of","batches","of","the","electron","'s","positions","to","be","initialized",".","x",":","np.ndarray",",","optional","(","default","np.ndarray","(","[","]",")",")","Contains","the","electron","'s","coordinates","in","a","4D","array",".","The","shape","of","the","array","should","be","(","batch_no",",","no_of_electrons,1,3",")",".","Can","be","a","1D","empty","array",",","when","electron","'s","positions","are","yet","to","be","initialized",".","steps",":","int",",","optional","(","default","10",")","The","number","of","MCMC","steps","to","be","performed","when","the","moves","are","called",".","steps_per_update",":","int","(","default","10",")","The","number","of","steps","after","which","the","parameters","of","the","MCMC","gets","updated",".","seed",":","int",",","optional","(","default","None",")","Random","seed","to","use",".","symmetric",":","bool",",","optional","(","default","True",")","If","true",",","symmetric","moves","will","be","used",",","else","asymmetric","moves","will","be","followed",".","simultaneous",":","bool",",","optional","(","default","True",")","If","true",",","MCMC","steps","will","be","performed","on","all","the","electrons",",","else","only","a","single","electron","gets","updated",".","Attributes","--","--","--","--","--","sampled_electrons",":","np.ndarray","Keeps","track","of","the","sampled","electrons","at","every","step",",","must","be","empty","at","start","."]
code: def __init__(
      self,
      central_value: np.ndarray,
      f: Callable[[np.ndarray], np.ndarray],
      batch_no: int = 10,
      x: np.ndarray = np.array([]),
      steps: int = 200,
      steps_per_update: int = 10,
      seed: Optional[int] = None,
      symmetric: bool = True,
      simultaneous: bool = True,
  ):
      """
      Parameters
      ----------
      central_value: np.ndarray
          Contains each nucleus' coordinates in a 2D array. The shape of the array should be(number_of_nucleus,3).Ex: [[1,2,3],[3,4,5],..]
      f:Callable[[np.ndarray],np.ndarray]
          A function that should give the twice the log probability of wavefunction of the molecular system when called. Should taken in a 4D array of electron's positions(x) as argument and return a numpy array containing the log probabilities of each batch.
      batch_no: int, optional (default 10)
          Number of batches of the electron's positions to be initialized.
      x: np.ndarray, optional (default np.ndarray([]))
          Contains the electron's coordinates in a 4D array. The shape of the array should be(batch_no,no_of_electrons,1,3). Can be a 1D empty array, when electron's positions are yet to be initialized.
      steps: int, optional (default 10)
          The number of MCMC steps to be performed when the moves are called.
      steps_per_update: int (default 10)
          The number of steps after which the parameters of the MCMC gets updated.
      seed: int, optional (default None)
          Random seed to use.
      symmetric: bool, optional(default True)
          If true, symmetric moves will be used, else asymmetric moves will be followed.
      simultaneous: bool, optional(default True)
          If true, MCMC steps will be performed on all the electrons, else only a single electron gets updated.
  
      Attributes
      ----------
      sampled_electrons: np.ndarray
          Keeps track of the sampled electrons at every step, must be empty at start.
      """
      self.x = x
      self.f = f
      self.num_accept = 0
      self.symmetric = symmetric
      self.simultaneous = simultaneous
      self.steps = steps
      self.steps_per_update = steps_per_update
      self.central_value = central_value
      self.batch_no = batch_no
      self.sampled_electrons: np.ndarray = np.array([])
      if seed is not None:
          seed = int(seed)
          np.random.seed(seed)
  
file_path: deepchem/deepchem/utils/electron_sampler.py
imports: import numpy
  from typing import Optional, Callable
label_desc: Use image node_id 1 to create a new ElectronSampler object  with example: obj = ElectronSampler(central_value, f, batch_no, x, steps, steps_per_update, seed, symmetric, simultaneous)