# TRIQS application maxent
# Copyright (C) 2018 Gernot J. Kraberger
# Copyright (C) 2018 Simons Foundation
# Authors: Gernot J. Kraberger and Manuel Zingl
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import numpy as np
from .analyzer import Analyzer, AnalyzerResult
[docs]
class EntropyAnalyzer(Analyzer):
r""" Analyzer searching a flat feature in the entropy
This analyzer chooses the spectrum :math:`A_\alpha(\omega)` where
the derivative of the entropy with respect to :math:`\log\alpha`
is minimal.
.. plot::
import matplotlib.pyplot as plt
import numpy as np
S = [-0.8456575058822821, -0.8658403520963711, -0.8844467584579873, -0.9015179804032627, -0.917151672328798, -0.9314863556664439, -0.944683164425082, -0.956907556102252, -0.9683133476777639, -0.9790307680896819, -0.9891593596567183, -0.9987657170111451, -1.0078854019950367, -1.0165280011549969, -1.024684177382945, -1.0323336228063789, -1.0394529560517198, -1.0460227711524488, -1.0520332288852523, -1.057487795325951, -1.062404977107112, -1.0668181517074484, -1.070773798901126, -1.0743285656102701, -1.0775456259846594, -1.08049074893449, -1.0832283965498788, -1.0858180930339953, -1.0883112550281395, -1.0907486650570901, -1.0931587807617578, -1.095557070693374, -1.0979465250594018, -1.1003193968995932, -1.1026600976500056, -1.1049490343932176, -1.1071670792456967, -1.1093003459253266, -1.111345024505977, -1.1133121363430305, -1.1152320138828, -1.1171577437178764, -1.1191656036718212, -1.1213502283233436, -1.1238160022650803, -1.1266718510795215, -1.1300348922182275, -1.1340406305366701, -1.1388547911555023, -1.1446847433171343, -1.1517907169027382, -1.1604971815494127, -1.1712045022410134, -1.1844004970446838, -1.2006707511139032, -1.220706440371579, -1.2453068384914605, -1.2753730596069384, -1.311887106342708, -1.355868667039715]
S = np.array(S)
alpha = np.logspace(0, np.log10(2.e5) , len(S))[::-1]
plt.subplot(2,1,1)
plt.semilogx(alpha, S)
plt.xlabel(r'$\alpha$')
plt.ylabel(r'$S$')
plt.subplot(2,1,2)
deriv = np.full(len(alpha), np.nan)
deriv[1:-1] = ((S[2:] - S[:-2]) / (
np.log(alpha[2:]) - np.log(alpha[:-2])))
plt.semilogx(alpha, deriv)
plt.xlabel(r'$\alpha$')
plt.ylabel(r'$dS/d\log\alpha$')
Parameters
==========
name : str
the name of the method, defaults to `EntropyAnalyzer`.
Attributes
==========
A_out : array (vector)
the output, i.e. the one true spectrum
alpha_index : int
the index of the output in the ``A_values`` array
dS_dalpha : array
the derivative of the entropy with respect to :math:`\\log\\alpha`
info : str
some information about what the analyzer did
"""
def __init__(self, name=None):
super(EntropyAnalyzer, self).__init__(name=name)
[docs]
def analyze(self, maxent_result, matrix_element=None):
r""" Perform the analysis
Parameters
----------
maxent_result : :py:class:`.MaxEntResult`
the result where the :math:`\alpha`-dependent data is taken
from
matrix_element : tuple
the matrix element (if applicable) that should be analyzed
Returns
-------
result : :py:class:`AnalyzerResult`
the result of the analysis, including the :math:`A_{out}`
"""
def elem(what):
return maxent_result._get_element(what, matrix_element)
res = AnalyzerResult()
res['dS_dalpha'] = np.full(len(maxent_result.alpha), np.nan)
res['dS_dalpha'][1:-1] = ((elem(maxent_result.S)[2:] - elem(maxent_result.S)[:-2]) / (
np.log(maxent_result.alpha[2:]) - np.log(maxent_result.alpha[:-2])))
res['alpha_index'] = np.nanargmin(res['dS_dalpha']**2)
if np.isnan(res['alpha_index']):
raise ValueError('dS_dalpha is all NaN')
res['A_out'] = elem(maxent_result.A)[res['alpha_index']]
res['name'] = self.name
res['info'] = 'Ideal alpha (entropy): {} (= index {} zero-based)'.format(
maxent_result.alpha[res['alpha_index']], res['alpha_index'])
return res