"""Provide diagnostics for autoCAS.
This module implements the Diagnostics class, which stores entropies and
threshold values for the determination of the active space.
"""
# -*- coding: utf-8 -*-
__copyright__ = """ This code is licensed under the 3-clause BSD license.
Copyright ETH Zurich, Department of Chemistry and Applied Biosciences, Reiher Group.
See LICENSE.txt for details. """
from typing import Any, Dict, Optional
import numpy as np
[docs]class Diagnostics:
"""A Class to store the entropies and threshold values to evaluate
diagnostics from it.
Currently there is only a check for single reference and zs1 implemented, hence the
only values are thresholds which are stored.
Attributes
----------
s1_entropy : np.ndarray
the single orbital entropy matrix
s2_entropy : np.ndarray
the two orbtial entropy tensor
mutual_information : np.ndarray
the mutual information tensor
single_reference_threshold : float, default = 0,14
if the largest element in s1 is smaller, the system is considered single reference
weak_correlation threshold : float, default = 0.02
if no active space is found, orbitals with a lower single orbital entropy are remove.
Notes
-----
For further information see
[1] C. J. Stein and M. Reiher J. Comput. Chem. 40, 2216-2226 (2019).
[2] C. J. Stein and M. Reiher J. Chem. Theory Comput. 12, 1760-1771 (2016).
[3] C. J. Stein, V. von Burg and M. Reiher J. Chem. Theory Comput. 12, 3764-3773 (2016).
[4] C. J. Stein and M. Reiher Chimia 71, 170-176 (2017).
"""
__slots__ = (
"s1_entropy",
"s2_entropy",
"mutual_information",
"single_reference_threshold",
"weak_correlation_threshold",
)
[docs] def __init__(self, settings_dict: Optional[Dict[str, Any]] = None):
"""Contruct a Diagnostics object.
If a settings_dict is provided is provided with attributes in this class, these
attributes will be overwritten.
Parameters
----------
settings_dict : Dict[str, Any], optional
a dict, usually provided by the input_handler, which stores attributes and corresponding values
See Also
--------
settings_dict : InputHandler
"""
self.s1_entropy: np.ndarray
"""single orbital entropy"""
self.s2_entropy: np.ndarray
"""two orbital entropy"""
self.mutual_information: np.ndarray
"""mutual information"""
self.single_reference_threshold: float = 0.14
"""if max(s1) is lower then this threshold the system will be defined as single reference"""
self.weak_correlation_threshold: float = 0.02
"""if an orbital has a lower s1 than max(s1) * weak_correlation_threshold, it is excluded"""
if settings_dict is not None:
for key in settings_dict:
if hasattr(self, key):
setattr(self, key, settings_dict[key])
[docs] def zs1(self, s1_entropy: np.ndarray) -> float:
"""Evaluate the Zs(1) diagnostics for a set of s1 values.
Zs(1) indicates a MC character if Zs(1) > 0.2.
If 0.1 < Zs(1) < 0.2 than a SR method can be considered, since it is usually cheaper to
use it.
Parameters
----------
s1_entropy : np.ndarray
set of s1 values to evaluate zs1 from.
Returns
-------
zs1 : float
The Zs(1) diagnostics with respect to the set of s1 values.
"""
n_orbitals = len(s1_entropy)
zs1 = 1 / (n_orbitals * np.log(4)) * sum(s1_entropy)
return zs1
[docs] def is_single_reference(self) -> bool:
"""Check if the system is weak correlated.
Maning the maximum s1 value is lower than 10% of the theoretical maximum, e.g. 0.14.
Returns
-------
bool
True if the system is single reference, else False meaning multi reference
"""
if max(self.s1_entropy) < self.single_reference_threshold:
return True
return False