diff --git a/examples/05_correlators.ipynb b/examples/05_correlators.ipynb new file mode 100644 index 00000000..616968e9 --- /dev/null +++ b/examples/05_correlators.ipynb @@ -0,0 +1,286 @@ +{ + "metadata": { + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6-final" + }, + "orig_nbformat": 2, + "kernelspec": { + "name": "python3", + "display_name": "Python 3", + "language": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2, + "cells": [ + { + "source": [ + "## Correlator Example" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "source": [ + "We are often dealing with lists of observables defined at every time slice. For a more convenient analysis, those can be represented using the \"correlators.Corr\" class.\n", + "This is especially useful, if there is not one Obs per time slice, but a whole smearing matrix. We will load an example of such an object." + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "64 4\n" + ] + } + ], + "source": [ + "import pyerrors as pe\n", + "import autograd.numpy as np\n", + "P5P5=pe.load_object(\"data/Example_Corr_P5P5.p\")\n", + "print(P5P5.T, P5P5.N)" + ] + }, + { + "source": [ + "What we just printed out, are the only parameters a Corr has. T represents the number of time slices and N the rank of the NxN smearing matrix. \n", + "The content is accessible with P5P5.content and gives a list of np.arrays of obs. There is no formal difference between correlators, which contain a single observable per time slice \n", + "and those, which hold a smearing matrix. \n", + "To initialize a Corr, we only need to pass the content or in the case of N=1, we might pass a list of obs.\n", + "Lets run some code!" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
" + }, + "metadata": {} + } + ], + "source": [ + "P5P5.symmetric().projected().show(logscale=True)" + ] + }, + { + "source": [ + "We will go over this line the way it is executed, left to right. \n", + "The correlator has a method called **symmetric()**, which returns a time symmetrized version of itself. \n", + "We did not need to redo the error estimation. While a Corr has a **.gamma_method()** defined, which simply applies the Obs.gamma_method() to every Obs in the correlator, \n", + "this is done automatically, whenever a new corr is initiated. This is a little slow, but convenient. The next method called is **.projected()**. \n", + "This methods *projects* the smearing matrices $G(t)$ with a set of vectors, returning a single value at every $t$. $$v_l^T G(t) v_r$$ Since we did not pass an argument, it defaulted to $v_l=v_r=(1,0,...,0)$, giving us $G(t)[0,0]$ . The method returns another Corr, but this time with N=1. \n", + " The last method **.show()** just allows us to quickly inspect a correlator. \n", + "Let us now look at the GEVP. \n" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[-6.26306805e-04 1.64198098e-01 -5.99926044e-01 7.83024479e-01]\n" + ] + } + ], + "source": [ + "eigenvector=P5P5.symmetric().GEVP(t0=3,ts=6)\n", + "print(eigenvector)" + ] + }, + { + "source": [ + "**.GEVP()** Needs two time indices as arguments. It then solves:\n", + "\n", + "$$G(t_s)v=\\lambda G(t_0)v$$\n", + "\n", + "and returns the vector $v$ for the largest eigenvalue. It uses a *Scipy* method, which itself is based on a *LAPACK* method. \n", + "To really see the difference this makes, we can visualize the effective mass, which we also have a method for." + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
" + }, + "metadata": {} + } + ], + "source": [ + "P5P5.symmetric().projected().m_eff().show([0,32])\n", + "P5P5.symmetric().projected(eigenvector).m_eff().show([0,32])" + ] + }, + { + "source": [ + "The plateau is definetely larger now. We can use it to extract the pseudoscalar mass. All we need is a plateau range. \n", + "Finding those can be time consuming, if we are dealing with many correlators and we need to zoom in to the plot, to see the range properly.\n", + "We can call a GUI method to help us to visualize the range. Play around with the checkboxes at the bottom of the window to make the program adjust plot to your selected range." + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "The pseudoscalar mass is: Obs[0.64457(66)]\n" + ] + } + ], + "source": [ + "m_eff=P5P5.symmetric().projected(eigenvector).m_eff() # Our lines were getting a little long, so we just assign a new Corr. \n", + "plateau_range=pe.correlators.GUI_range_finder(m_eff)\n", + "m_p=m_eff.plateau(plateau_range)\n", + "print(\"The pseudoscalar mass is: \",m_p)" + ] + }, + { + "source": [ + "For fun you can compare your result with https://arxiv.org/abs/1912.09937v1 Table XV (the first value for $am_{H_{is}}$). \n", + "Before we wrap up, we should look at Corrs and math operations. They can be multiplied by and added to other Corrs (of same N,T), or scaled by an Obs or float. \n", + "Usually the operation is just done for every value at the same time and smearing. \n", + "\n" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "64 4\n" + ] + } + ], + "source": [ + "new_correlator=0.5*P5P5+np.sqrt(P5P5)/np.sin(P5P5**2)+np.arcsinh(P5P5)\n", + "print(new_correlator.T, new_correlator.N)" + ] + }, + { + "source": [ + "This is a senseless but valid expression, which does exactly, what one would expect. It returns a Corr of the same shape as P5P5. \n", + " It is really important, that there is never any confusion about the appropriate time slices. Lets look at *m_eff* once again. \n", + " By default it is calculated as $$ m_{eff}(t)=\\ln(\\frac{Corr[t]}{Corr[t+1]})$$ \n", + " Therefore m_eff is only defined up to the second to last time slice. But the method appends a **None** object, so that m_eff.T=64. \n", + " If we add m_eff to P5P5.projected(), the resulting Corr would still have T=64, with the last item being **None**. \n", + "Another reason for a Corr being **None** at one time slice, is a division by zero or other undefined operation. \n", + "Even if a Corr is partially undefined, math operations still work, as long as T and N are identical.\n", + " " + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "64\n" + ] + } + ], + "source": [ + "print((m_eff+P5P5.projected()).T)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ] +} \ No newline at end of file diff --git a/examples/data/Example_Corr_P5P5.p b/examples/data/Example_Corr_P5P5.p new file mode 100644 index 00000000..d4a9d61d Binary files /dev/null and b/examples/data/Example_Corr_P5P5.p differ diff --git a/pyerrors/__init__.py b/pyerrors/__init__.py index 7397bc5e..f0240f2d 100644 --- a/pyerrors/__init__.py +++ b/pyerrors/__init__.py @@ -2,4 +2,5 @@ from .pyerrors import * from . import fits from . import linalg from . import misc -from . import mpm \ No newline at end of file +from . import mpm +from . import correlators diff --git a/pyerrors/correlators.py b/pyerrors/correlators.py new file mode 100644 index 00000000..60dd857a --- /dev/null +++ b/pyerrors/correlators.py @@ -0,0 +1,653 @@ +import autograd.numpy as np +from .pyerrors import * +from .fits import standard_fit +from matplotlib import pyplot as plt +from matplotlib.ticker import NullFormatter # useful for `logit` scale +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg +import PySimpleGUI as sg +import matplotlib + +class Corr: + """The class for a correlator (time dependent sequence of pe.Obs). + + Everything, this class does, can be achieved using lists or arrays of Obs. + But it is simply more convenient to have a dedicated object for correlators. + One often wants to add or multiply correlators of the same length at every timeslice and it is inconvinient + to iterate over all timeslices for every operation. This is especially true, when dealing with smearing matrices. + + The correlator can have two types of content: An Obs at every timeslice OR a GEVP + smearing matrix at every timeslice. Other dependency (eg. spacial) are not supported. + + """ + + def __init__(self, data_input,padding_front=0,padding_back=0): + #All data_input should be a list of things at different timeslices. This needs to be verified + + if not isinstance(data_input,list): + raise TypeError('Corr__init__ expects a list of timeslices.') + # data_input can have multiple shapes. The simplest one is a list of Obs. + #We check, if this is the case + if all([isinstance(item,Obs) for item in data_input]): + self.content=[np.asarray([item]) for item in data_input] + #Wrapping the Obs in an array ensures that the data structure is consistent with smearing matrices. + self.N=1 # number of smearings + + #data_input in the form [np.array(Obs,NxN)] + elif all([isinstance(item,np.ndarray) or item==None for item in data_input]) and any([isinstance(item,np.ndarray)for item in data_input]): + self.content= data_input + + noNull=[a for a in self.content if not (a is None)] #To check if the matrices are correct for all undefined elements + self.N= noNull[0].shape[0] + # The checks are now identical to the case above + if self.N>1 and noNull[0].shape[0]!=noNull[0].shape[1]: + raise Exception("Smearing matrices are not NxN") + if (not all([item.shape==noNull[0].shape for item in noNull])): + raise Exception("Items in data_input are not of identical shape."+str(noNull)) + + else: # In case its a list of something else. + raise Exception ("data_input contains item of wrong type") + + #We now apply some padding to our list. In case that our list represents a correlator of length T but is not defined at every value. + #An undefined timeslice is represented by the None object + self.content=[None]*padding_front+self.content+[None]*padding_back + self.T=len(self.content) #for convenience: will be used a lot + + + self.gamma_method() + + + def gamma_method(self): + for item in self.content: + if not(item is None): + if self.N==1: + item[0].gamma_method() + else: + for i in range(self.N): + for j in range(self.N): + item[i,j].gamma_method() + + + + + #We need to project the Correlator with a Vector to get a single value at each timeslice. + #The method can use one or two vectors. + #If two are specified it returns v1@G@v2 (the order might be very important.) + #By default it will return the lowest source, which usually means unsmeared-unsmeared (0,0), but it does not have to + def projected(self,vector_l=None,vector_r=None): + if self.N==1: + raise Exception("Trying to project a Corr, that already has N=1.") + #This Exception is in no way necessary. One could just return self + #But there is no scenario, where a user would want that to happen and the error message might be more informative. + + self.gamma_method() + + if vector_l is None: + vector_l,vector_r=np.asarray( [1.]+(self.N-1)*[0.]),np.asarray( [1.]+(self.N-1)*[0.]) + elif(vector_r is None): + vector_r=vector_l + + if not vector_l.shape==vector_r.shape==(self.N,): + raise Exception("Vectors are of wrong shape!") + + #We always normalize before projecting! But we only raise a warning, when it is clear, they where not meant to be normalized. + if (not(0.951: + transposed=[None if (G is None) else G.T for G in self.content] + return 0.5*(Corr(transposed)+self) + if self.N==1: + raise Exception("Trying to symmetrize a smearing matrix, that already has N=1.") + + + #We also include a simple GEVP method based on Scipy.linalg + def GEVP(self,t0,ts): + if (self.content[t0] is None) or (self.content[ts] is None): + raise Exception("Corr not defined at t0/ts") + G0, Gt=np.empty([self.N,self.N],dtype="double"),np.empty([self.N,self.N],dtype="double") + for i in range(self.N): + for j in range(self.N): + G0[i,j]=self.content[t0][i,j].value + Gt[i,j]=self.content[ts][i,j].value + + sp_val,sp_vec=scipy.linalg.eig(Gt,G0) + sp_vec=sp_vec[:,np.argmax(sp_val)] #we only want the eigenvector belonging to the biggest eigenvalue. + sp_vec=sp_vec/np.sqrt(sp_vec@sp_vec) + return sp_vec + + def deriv(self,symmetric=False): #Defaults to forward derivative f'(t)=f(t+1)-f(t) + if not symmetric: + newcontent=[] + for t in range(self.T-1): + if (self.content[t] is None) or (self.content[t+1] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t+1]-self.content[t]) + if(all([x is None for x in newcontent])): + raise Exception("Derivative is undefined at all timeslices") + return Corr(newcontent, padding_back=1) + if symmetric: + newcontent=[] + for t in range(1,self.T-1): + if (self.content[t-1] is None) or (self.content[t+1] is None): + newcontent.append(None) + else: + newcontent.append(0.5*(self.content[t+1]-self.content[t-1])) + if(all([x is None for x in newcontent])): + raise Exception("Derivative is undefined at all timeslices") + return Corr(newcontent, padding_back=1,padding_front=1) + + #effective mass at every timeslice + def m_eff(self, periodic=False): + if self.N!=1: + raise Exception("Correlator must be projected before getting m_eff") + if not periodic: + newcontent=[] + for t in range(self.T-1): + if (self.content[t] is None) or (self.content[t+1] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]/self.content[t+1]) + if(all([x is None for x in newcontent])): + raise Exception("m_eff is undefined at all timeslices") + + return np.log(Corr(newcontent,padding_back=1)) + + else: #This is usually not very stable. One could default back to periodic=False. + newcontent=[] + for t in range(1,self.T-1): + if (self.content[t] is None) or (self.content[t+1] is None)or (self.content[t-1] is None): + newcontent.append(None) + else: + newcontent.append((self.content[t+1]+self.content[t-1])/(2*self.content[t])) + if(all([x is None for x in newcontent])): + raise Exception("m_eff is undefined at all timeslices") + return np.arccosh(Corr(newcontent,padding_back=1,padding_front=1)) + + + #We want to apply a pe.standard_fit directly to the Corr using an arbitrary function and range. + def fit(self,function,fitrange=None): + if self.N!=1: + raise Exception("Correlator must be projected before fitting") + + if fitrange is None: + fitrange=[0,self.T] + + xs = [x for x in range(fitrange[0],fitrange[1]) if not self.content[x] is None] + ys = [self.content[x][0] for x in range(fitrange[0],fitrange[1]) if not self.content[x] is None] + result = standard_fit(xs, ys,function,silent=(True)) + [item.gamma_method() for item in result if isinstance(item,Obs)] + return result + + #we want to quickly get a plateau + def plateau(self,plateau_range,method="fit"): + if self.N!=1: + raise Exception("Correlator must be projected before getting a plateau") + if(all([self.content[t] is None for t in range(plateau_range[0],plateau_range[1])])): + raise Exception("plateau is undefined at all timeslices in plateaurange") + if method=="fit": + def const_func(a,t): + return a[0]+a[1]*0 # At some point pe.standard fit had an issue with single parameter fits. Being careful does not hurt + return self.fit(const_func,plateau_range)[0] + elif method in ["avg","average","mean"]: + returnvalue= np.mean([item[0] for item in self.content if not item is None]) + returnvalue.gamma_method() + return returnvalue + + else: + raise Exception("Unsupported plateau method: "+method) + + #quick and dirty plotting function to view Correlator inside Jupyter + #If one would not want to import pyplot, this could easily be replaced by a call to pe.plot_corrs + #This might be a bit more flexible later + def show(self,xrange=None,logscale=False): + if self.N!=1: + raise Exception("Correlator must be projected before plotting") + if xrange is None: + xrange=[0,self.T] + + x,y,y_err=self.plottable() + plt.errorbar(x,y,y_err,fmt="o-") + if logscale: + plt.yscale("log") + else: + # we generate ylim instead of using autoscaling. + y_min=min([ (x[0].value-x[0].dvalue) for x in self.content[xrange[0]:xrange[1]] if(not x is None)]) + y_max=max([ (x[0].value+x[0].dvalue) for x in self.content[xrange[0]:xrange[1]] if(not x is None)]) + plt.ylim([y_min-0.1*(y_max-y_min),y_max+0.1*(y_max-y_min)]) + + plt.xlabel(r"$n_t$ [a]") + plt.xlim(xrange) + plt.title("Quickplot") + plt.grid() + + plt.show() + plt.clf() + return + + def dump(self,filename): + dump_object(self,filename) + return + + + + + def __repr__(self): + return("Corr[T="+str(self.T)+" , N="+str(self.N)+" , content="+str(self.content)+"]") + def __str__(self): + return ("Corr[T="+str(self.T)+" , N="+str(self.N)+" , content="+str(self.content)+"]") + + #We define the basic operations, that can be performed with correlators. + #While */+- get defined here, they only work for Corr*Obs and not Obs*Corr. + #This is because Obs*Corr checks Obs.__mul__ first and does not catch an exception. + #One could try and tell Obs to check if the y in __mul__ is a Corr and + + def __add__(self, y): + if isinstance(y, Corr): + if ((self.N!=y.N) or (self.T!=y.T) ): + raise Exception("Addition of Corrs with different shape") + newcontent=[] + for t in range(self.T): + if (self.content[t] is None) or (y.content[t] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]+y.content[t]) + return Corr(newcontent) + + elif isinstance(y, Obs) or isinstance(y, int) or isinstance(y,float): + newcontent=[] + for t in range(self.T): + if (self.content[t] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]+y) + return Corr(newcontent) + else: + raise TypeError("Corr + wrong type") + + def __mul__(self,y): + if isinstance(y,Corr): + if not((self.N==1 or y.N==1 or self.N==y.N) and self.T==y.T): + raise Exception("Multiplication of Corr object requires N=N or N=1 and T=T") + newcontent=[] + for t in range(self.T): + if (self.content[t] is None) or (y.content[t] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]*y.content[t]) + return Corr(newcontent) + + elif isinstance(y, Obs) or isinstance(y, int) or isinstance(y,float): + newcontent=[] + for t in range(self.T): + if (self.content[t] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]*y) + return Corr(newcontent) + else: + raise TypeError("Corr * wrong type") + + def __truediv__(self,y): + if isinstance(y,Corr): + if not((self.N==1 or y.N==1 or self.N==y.N) and self.T==y.T): + raise Exception("Multiplication of Corr object requires N=N or N=1 and T=T") + newcontent=[] + for t in range(self.T): + if (self.content[t] is None) or (y.content[t] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]/y.content[t]) + #Here we set the entire timeslice to undefined, if one of the smearings has encountered an division by zero. + #While this might throw away perfectly good values in other smearings, we will never have to check, if all values in our matrix are defined + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + + if all([item is None for item in newcontent]): + raise Exception("Division returns completely undefined correlator") + + + + return Corr(newcontent) + + elif isinstance(y, Obs): + if y.value==0: + raise Exception("Division by Zero will return undefined correlator") + newcontent=[] + for t in range(self.T): + if (self.content[t] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]/y) + return Corr(newcontent) + + elif isinstance(y, int) or isinstance(y,float): + if y==0: + raise Exception("Division by Zero will return undefined correlator") + newcontent=[] + for t in range(self.T): + if (self.content[t] is None): + newcontent.append(None) + else: + newcontent.append(self.content[t]/y) + return Corr(newcontent) + else: + raise TypeError("Corr / wrong type") + + def __neg__(self): + newcontent=[None if (item is None) else -1.*item for item in self.content] + return Corr(newcontent) + + def __sub__(self,y): + return self +(-y) + + def __pow__(self, y): + if isinstance(y, Obs) or isinstance(y,int) or isinstance(y,float): + newcontent=[None if (item is None) else item**y for item in self.content] + return Corr(newcontent) + else: + raise TypeError("type of exponent not supported") + + #The numpy functions: + def sqrt(self): + return self**0.5 + + def log(self): + newcontent=[None if (item is None) else np.log(item) for item in self.content] + return Corr(newcontent) + + def exp(self): + newcontent=[None if (item is None) else np.exp(item) for item in self.content] + return Corr(newcontent) + + def sin(self): + newcontent=[None if (item is None) else np.sin(item) for item in self.content] + return Corr(newcontent) + + def cos(self): + newcontent=[None if (item is None) else np.cos(item) for item in self.content] + return Corr(newcontent) + + def tan(self): + newcontent=[None if (item is None) else np.tan(item) for item in self.content] + + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + + return Corr(newcontent) + + def sinh(self): + newcontent=[None if (item is None) else np.sinh(item) for item in self.content] + return Corr(newcontent) + + def cosh(self): + newcontent=[None if (item is None) else np.cosh(item) for item in self.content] + return Corr(newcontent) + + def tanh(self): + newcontent=[None if (item is None) else np.tanh(item) for item in self.content] + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + return Corr(newcontent) + + def arcsin(self): + newcontent=[None if (item is None) else np.arcsin(item) for item in self.content] + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + return Corr(newcontent) + + def arccos(self): + newcontent=[None if (item is None) else np.arccos(item) for item in self.content] + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + return Corr(newcontent) + + def arctan(self): + newcontent=[None if (item is None) else np.arctan(item) for item in self.content] + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + return Corr(newcontent) + + def arcsinh(self): + newcontent=[None if (item is None) else np.arcsinh(item) for item in self.content] + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + return Corr(newcontent) + + def arccosh(self): + newcontent=[None if (item is None) else np.arccosh(item) for item in self.content] + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + return Corr(newcontent) + + def arctanh(self): + newcontent=[None if (item is None) else np.arctanh(item) for item in self.content] + for t in range(self.T): + if newcontent[t] is None: + continue + if np.isnan(np.sum(newcontent[t]).value): + newcontent[t]=None + if all([item is None for item in newcontent]): + raise Exception("Operation returns completely undefined correlator") + return Corr(newcontent) + + + #right hand side operations (require tweak in main module to work) + def __rsub__(self,y): + return -self+y + def __rmul__(self, y): + return self * y + def __radd__(self,y): + return self + y + + + +#One of the most common tasks is to select a range for a plateau or a fit. This is best done visually. +def GUI_range_finder(corr, current_range=None): + T=corr.T + if corr.N!=1: + raise Exception("The Corr needs to be projected to select a range.") + #We need to define few helper functions for the Gui + def get_figure(corr,values): + fig = matplotlib.figure.Figure(figsize=(7, 4), dpi=100) + fig.clf() + x,y,err=corr.plottable() + ax=fig.add_subplot(111,label="main")#.plot(t, 2 * np.sin(2 * np.pi * t)) + end=int(max(values["range_start"],values["range_end"])) + start=int(min(values["range_start"],values["range_end"])) + db=[0.1,0.2,0.8] + ax.errorbar(x,y,err, fmt="-o",color=[0.4,0.6,0.8]) + ax.errorbar(x[start:end],y[start:end],err[start:end], fmt="-o",color=db) + offset=int(0.3*(end-start)) + xrange=[max(min(start-1,int(start-offset)),0),min(max(int(end+offset),end+1),T-1)] + ax.grid() + if values["Plateau"]: + plateau=corr.plateau([start,end]) + ax.hlines(plateau.value,0,T+1,lw=plateau.dvalue,color="red",alpha=0.5) + ax.hlines(plateau.value,0,T+1,lw=1,color="red") + ax.set_title(r"Current Plateau="+str(plateau)[4:-1]) + if(values["Crop X"]): + ax.set_xlim(xrange) + ax.set_xticks([x for x in ax.get_xticks() if (x-int(x)==0) and (0<=x=1.16', 'autograd>=1.2', 'numdifftools', 'matplotlib', 'scipy', 'iminuit'] + install_requires=['numpy>=1.16', 'autograd>=1.2', 'numdifftools', 'matplotlib', 'scipy', 'iminuit','PySimpleGUI'] )