def __init__(self, dict_population, n_max=None, global_softness=None): r"""Initialize linear density model to compute local reactivity descriptors. Parameters ---------- dict_population : dict Dictionary of number of electrons (keys) and corresponding atomic populations array (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): {N_A \left(N_0 - 1\right)}, N_0: {N_A \left(N_0\right)}, (N_0 + 1): {N_A \left(N_0 + 1\right)}`. The :math:`N_0` value is considered as the reference number of electrons. n_max : float, optional Maximum number of electrons that system can accept, i.e. :math:`N_{\text{max}}`. See :attr:`BaseGlobalTool.n_max`. global_softness : float, optional Global softness. See :attr:`BaseGlobalTool.softness`. """ # check number of electrons & density values n_ref, pop_m, pop_0, pop_p = check_dict_values(dict_population) # compute atomic ff+, ff- & ff0 self._ff_plus = pop_p - pop_0 self._ff_minus = pop_0 - pop_m self._ff_zero = 0.5 * (pop_p - pop_m) super(LinearCondensedTool, self).__init__(n_ref, n_max, global_softness) self.dict_population = dict_population
def __init__(self, dict_energy): r"""Initialize linear energy model to compute global reactivity descriptors. Parameters ---------- dict_energy : dict Dictionary of number of electrons (keys) and corresponding energy (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0), (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number of electrons. """ # check number of electrons & energy values n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy) # calculate parameters a, b, a' and b' of linear energy model param_b = energy_0 - energy_m param_a = energy_0 - n_ref * param_b param_b_prime = energy_p - energy_0 param_a_prime = energy_0 - n_ref * param_b_prime self._params = [param_a, param_b, param_a_prime, param_b_prime] # calculate N_max if energy_0 < energy_p: n_max = n_ref else: n_max = None super(LinearGlobalTool, self).__init__(n_ref, n_max) self.dict_energy = dict_energy
def __init__(self, dict_energy): r"""Initialize quadratic energy model to compute global reactivity descriptors. Parameters ---------- dict_energy : dict Dictionary of number of electrons (keys) and corresponding energy (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0), (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number of electrons. """ # check number of electrons & energy values n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy) # calculate parameters a, b, c of quadratic energy model energy_m, energy_0, energy_p = [ dict_energy[n] for n in sorted(dict_energy.keys()) ] param_c = 0.5 * (energy_m - 2 * energy_0 + energy_p) param_b = 0.5 * (energy_p - energy_m) - 2 * param_c * n_ref param_a = energy_0 - param_b * n_ref - param_c * (n_ref**2) self._params = [param_a, param_b, param_c] # calculate N_max (number of electrons for which energy is minimum) n_max = -param_b / (2 * param_c) super(QuadraticGlobalTool, self).__init__(n_ref, n_max) self.dict_energy = dict_energy
def __init__(self, dict_density, n_max=None, global_softness=None): r"""Initialize linear density model to compute local reactivity descriptors. Parameters ---------- dict_density : dict Dictionary of number of electrons (keys) and corresponding density array (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): \rho_{N_0 - 1}\left(\mathbf{ r}\right), N_0: \rho_{N_0}\left(\mathbf{r}\right), (N_0 + 1): \rho_{N_0 + 1}\left( \mathbf{r}\right)\}`. The :math:`N_0` value is considered as the reference number of electrons. n_max : float, optional Maximum number of electrons that system can accept, i.e. :math:`N_{\text{max}}`. See :attr:`base.BaseGlobalTool.n_max`. global_softness : float, optional Global softness. See :attr:`base.BaseGlobalTool.softness`. """ # check number of electrons & density values n_ref, dens_m, dens_0, dens_p = check_dict_values(dict_density) # compute ff+, ff- & ff0 self._ff_plus = dens_p - dens_0 self._ff_minus = dens_0 - dens_m self._ff_zero = 0.5 * (dens_p - dens_m) super(LinearLocalTool, self).__init__(n_ref, n_max, global_softness) self.dict_density = dict_density
def __init__(self, dict_energy, omega=0.5): r"""Initialize cubic energy model to compute global reactivity descriptors. Parameters ---------- dict_energy : dict Dictionary of number of electrons (keys) and corresponding energy (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0), (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number of electrons. omega : float Value of omega parameter in the energy model. """ # check number of electrons & energy values n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy) # compute parameters of energy model param_a = energy_0 param_b = -omega * energy_m + 2. * omega * energy_0 - omega * energy_p param_b += energy_p - energy_0 param_c = (energy_m - 2. * energy_0 + energy_p) / 2. param_d = (2. * omega - 1.) * (energy_m - 2. * energy_0 + energy_p) / 2. self._omega = omega self._params = np.array([param_a, param_b, param_c, param_d]) super(CubicGlobalTool, self).__init__(n_ref, None) self.dict_energy = dict_energy
def __init__(self, dict_energy): r"""Initialize exponential energy model to compute global reactivity descriptors. Parameters ---------- dict_energy : dict Dictionary of number of electrons (keys) and corresponding energy (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0), (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number of electrons. """ # check number of electrons & energy values n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy) # check energy values if not energy_m > energy_0 > energy_p: energies = [energy_m, energy_0, energy_p] raise ValueError( "For exponential model, the energy values for consecutive number of " "electrons should be monotonic! E={0}".format(energies)) # calculate parameters A, B, gamma parameters of the exponential model param_a = (energy_m - energy_0) * (energy_0 - energy_p) param_a /= (energy_m - 2 * energy_0 + energy_p) param_b = energy_0 - param_a param_g = (energy_m - 2 * energy_0 + energy_p) / (energy_p - energy_0) param_g = math.log(1. - param_g) self._params = [param_a, param_g, param_b] # calculate N_max n_max = float("inf") super(ExponentialGlobalTool, self).__init__(n_ref, n_max) self.dict_energy = dict_energy
def __init__(self, dict_energy): r"""Initialize rational energy model to compute global reactivity descriptors. Parameters ---------- dict_energy : dict Dictionary of number of electrons (keys) and corresponding energy (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0), (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number of electrons. """ # check number of electrons & energy values n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy) # check energy values if not energy_m > energy_0 >= energy_p: energies = [energy_m, energy_0, energy_p] raise ValueError( "For rational model, the energy values for consecutive number of " "electrons should be monotonic! E={0}".format(energies)) # calculate parameters a0, a1 and b1 of rational energy model param_b1 = -(energy_p - 2 * energy_0 + energy_m) param_b1 /= ((n_ref + 1) * energy_p - 2 * n_ref * energy_0 + (n_ref - 1) * energy_m) param_a1 = (1 + param_b1 * n_ref) * (energy_p - energy_0) + (param_b1 * energy_p) param_a0 = -param_a1 * n_ref + energy_0 * (1 + param_b1 * n_ref) self._params = [param_a0, param_a1, param_b1] # calculate N_max n_max = float('inf') super(RationalGlobalTool, self).__init__(n_ref, n_max) self.dict_energy = dict_energy
def __init__(self, dict_energy): r"""Initialize the square-root energy model to compute global reactivity descriptors. Parameters ---------- dict_energy : dict Dictionary of number of electrons (keys) and corresponding energy (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0), (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number of electrons. """ # check number of electrons & energy values n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy) # Compute The Coefficients param2 = (energy_p - 2. * energy_0 + energy_m) / \ (np.sqrt(n_ref + 1) - 2. * np.sqrt(n_ref) + np.sqrt(n_ref - 1)) param3 = (energy_p - energy_m) / 2. - param2 * (np.sqrt(n_ref + 1) - np.sqrt(n_ref - 1)) / 2 param1 = energy_0 - param2 * np.sqrt(n_ref) - param3 * n_ref self._params = [param1, param2, param3] n_max = self._compute_nmax() super(SquareRootGlobalTool, self).__init__(n_ref, n_max)
def __init__(self, dict_energy, omega, nth_order=5, weight=0., eps=1e-3): r"""Initialize the least-norm energy model to compute global reactivity descriptors. Parameters ---------- dict_energy : dict Dictionary of number of electrons (keys) and corresponding energy (values). This model expects three energy values corresponding to three consecutive number of electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0), (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number of electrons. omega : float, default=0.5 The parameter :math:`\omega` in the energy model. Reasonable choices are between 0 and 1 see reference for more details. nth_order : int, default=5 The nth degree for the taylor polynomial. weight : float, default=0. The weight between 0 and 1 for the weighted least norm energy model. The weight with value zero gives the un-weighted least norm model. eps : float, default=1e-3 The accuracy for computing the hyper-parameters :math: '\alpha_x' and :math: '\beta_x', only needed for the weighted model. """ if weight > 1. or weight < 0.: raise ValueError( "Weights have to be between 0 and 1. It is {0}".format(weight)) if not isinstance(nth_order, int): raise ValueError("The nth order should be integer") # check number of electrons & energy values n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy) self._omega = omega self._weight = weight self._nth_order = nth_order # Default coefficients for the first two terms. self.dict_energy = dict_energy # Need these to initially define the parameters ionization = energy_m - energy_0 affinity = energy_0 - energy_p diff = ionization - affinity self._params = [ energy_0, -(omega * ionization + (1 - omega) * affinity) ] # Compute the coefficients up-to nth order, specified by `nth_order` argument. if weight != 0.: # If weighted model, compute the weighted coefficients. alpha, beta = self._hyperparameters(eps) self._params += [ self._coefficients_weighted(j, alpha, beta) * diff / factorial(j) for j in range(2, self._nth_order + 1) ] else: self._params += [ self._coefficients_unweighted(j) * diff / factorial(j) for j in range(2, self._nth_order + 1) ] self._n_max = self._compute_n_max() super(LeastNormGlobalTool, self).__init__(n_ref, self._n_max)