def meanSterr(self, remove=False, max=None): """ Returns array of mean and standard error of measured data. Parameters ---------- remove : bool Remove inf and -inf as well as nan. (default: False) NOTE: A warning will be issued if remove == False and such objects are encountered. max : float or None Remove data which is strictly above max in absolute value. (default: None) NOTE: max != None will trigger remove = True. Returns ------- SCGF : (self.sValues.size, 3) float Numpy array Scaled cumulant generating function. orderParameter : (self.sValues.size, 3) float Numpy array. Order parameter. orderParameterSq : (self.sValues.size, 3) float Numpy array. Squared order parameter. NOTE: (0) Biasing parameter. (1) Mean. (2) Standard error. I : (self.sValues.size, 4) float Numpy array Rate function. NOTE: (0) (Squared) order parameter. (1) Standard error on (squared) order parameter. (2) Rate function. (3) Standard error on rate function. """ SCGF = np.empty((self.sValues.size, 3)) orderParameter = np.empty((self.sValues.size, 3)) orderParameterSq = np.empty((self.sValues.size, 3)) I = np.empty((self.sValues.size, 4)) for i in range(self.sValues.size): SCGF[i] = [ self.sValues[i], *mean_sterr(self.SCGF[i], remove=remove, max=max) ] orderParameter[i] = [ self.sValues[i], *mean_sterr(self.orderParameter[i], remove=remove, max=max) ] orderParameterSq[i] = [ self.sValues[i], *mean_sterr(self.orderParameterSq[i], remove=remove, max=max) ] I[i] = [ *mean_sterr(self.I[i, :, 0], remove=remove, max=max), *mean_sterr(self.I[i, :, 1], remove=remove, max=max) ] return SCGF, orderParameter, orderParameterSq, I
def corWorkOrderAve(self, n_max=100, int_max=None, min=None, max=None, log=False): """ Compute correlations of the fluctuations of the work averaged over an interval of length `tau' and the fluctuations of the order parameter norm at the beginning of the interval. Parameters ---------- n_max : int Maximum number of values at which to evaluate the correlation. (default: 100) int_max : int or None Maximum number of different intervals to consider in order to compute the mean which appears in the correlation expression. (default: None) NOTE: if int_max == None, then a maximum number of disjoint intervals will be considered. min : int or None Minimum value at which to compute the correlation. (default: None) NOTE: this value is passed as `min' to self.n. max : int or None Maximum value at which to compute the correlation. (default: None) NOTE: this value is passed as `max' to self.n. log : bool Logarithmically space values at which the correlations are computed. (default: True) Returns ------- cor : (5, *) numpy array Array of: (0) value at which the correlation is computed, (1) mean of the computed correlation, (2) standard error of the computed correlation, (3) standard deviation of the active work, (4) standard deviation of the order parameter norm. """ cor = [] for n in self._n(n_max=n_max, min=min, max=max, log=log): works = (lambda l: l - np.mean(l))( self.nWork(n, int_max=int_max) ) # fluctuations of the active wok on intervals of size n orders = (lambda l: l - np.mean(l))( np.array( list( map( # fluctuations of the order parameter norm at the beginning of these intervals lambda t: self.getOrderParameter(t, norm=True), self.framesWork * self._time0(n, int_max=int_max))))) workOrder = works * orders cor += [[n, *mean_sterr(workOrder), np.std(works), np.std(orders)]] return np.array(cor)
def corForce(self, n_max=100, int_max=None, min=None, max=None, log=False): """ Returns correlations of the force fluctuations. Parameters ---------- n_max : int Maximum number of lag times. (default: 100) int_max : int or None Maximum number of different initial times. (default: None) NOTE: if int_max == None, then a maximum number of (disjoint) intervals will be considered. min : int or None Minimum lag time. (default: None) NOTE: if min == None, then min = 1. max : int or None Maximum lag time. (default: None) NOTE: if max == None, then max is taken to be the maximum according to the choice of int_max. log : bool Logarithmically spaced lag times. (default: False) NOTE: This does not apply to .datN files. Returns ------- cor : (*, 3) float numpy array Array of: (0) value at which the correlation is computed, (1) mean of the computed correlation, (2) standard error of the computed correlation. F0sq : (**,) float numpy array Variance of forces at initial times. """ time0, dt = self._dt(n_max=n_max, int_max=int_max, min=min, max=max, log=log) cor = [] forcesIni = np.array( list( map( # fluctuations at initial times lambda t: wo_mean(self.getForce(t), axis=-2), time0))) F0sq = (forcesIni**2).sum(axis=-1).mean( axis=-1) # average over particles for tau in dt: forcesFin = np.array( list( map( # fluctuations at initial times + lag time lambda t: wo_mean(self.getForce(t + tau), axis=-2), time0))) qProd = (forcesIni * forcesFin).sum(axis=-1).mean( axis=-1) # average over particles cor += [[tau, *mean_sterr(qProd / F0sq)]] # average over times return np.array(cor), F0sq
def corOrderOrder(self, n_max=100, int_max=100, max=None, norm=False, log=False): """ Compute autocorrelations of the fluctuations of the order parameter. Parameters ---------- n_max : int Maximum number of values at which to evaluate the correlation. (default: 100) int_max : int Maximum number of different intervals to consider in order to compute the mean which appears in the correlation expression. (default: 100) max : int or None Maximum value at which to compute the correlation. (default: None) NOTE: if max == None, then max = self.frames - 1. norm : bool Consider the norm of the order parameter rather than its vector form. (default: False) log : bool Logarithmically space values at which the correlations are computed. (default: True) Returns ------- cor : (3, *) numpy array Array of: (0) value at which the correlation is computed, (1) mean of the computed correlation, (2) standard error of the computed correlation. """ if max == None: max = self.frames - 1 if log: space = logspace else: space = linspace cor = [] for tau in space(1, max, n_max): time0 = list( OrderedDict.fromkeys( np.linspace(self.skip * self.framesWork, self.frames - tau - 1, int_max, endpoint=True, dtype=int))) ordersIni = (lambda l: np.array(l) - np.mean(l, axis=0))(list( map(lambda t: self.getOrderParameter(t, norm=norm), time0))) ordersFin = (lambda l: np.array(l) - np.mean(l, axis=0))(list( map(lambda t: self.getOrderParameter(t + tau, norm=norm), time0))) orderOrder = list( map(lambda x, y: np.dot(x, y), *(ordersIni, ordersFin))) cor += [[tau, *mean_sterr(orderOrder)]] return np.array(cor)
def corWorkOrderIns(self, tau0=1, n_max=100, int_max=None, min=None, max=None, log=False): """ Compute correlations of the fluctuations of the order parameter norm at a given time and the fluctuations of the active work averaged over a time `tau0' at a later time. Parameters ---------- tau0 : int Number of consecutive individual active works on which to average it. (default: 1) n_max : int Maximum number of values at which to evaluate the correlation. (default: 100) int_max : int or None Maximum number of different intervals to consider in order to compute the mean which appears in the correlation expression. (default: None) NOTE: if int_max == None, then a maximum number of disjoint intervals will be considered. min : int or None Minimum value at which to compute the correlation. (default: None) NOTE: if min == None then min = `tau0', otherwise the minimum of `tau0' and `min' is taken. max : int or None Maximum value at which to compute the correlation. (default: None) NOTE: this value is passed as `max' to self.n. log : bool Logarithmically space values at which the correlations are computed. (default: True) Returns ------- cor : (5, *) numpy array Array of: (0) value at which the correlation is computed, (1) mean of the computed correlation, (2) standard error of the computed correlation, (3) standard deviation of the active work, (4) standard deviation of the order parameter norm. """ cor = [] for n in self._n( n_max=n_max, log=log, min=(2 * tau0 if min == None else np.max([tau0 + min, 2 * tau0])), max=(None if max == None else tau0 + max)): ordersIni = (lambda l: l - np.mean(l))( list( map( lambda t: self.getOrderParameter( t, norm=True ), # fluctuations of the active work averaged between t0 and t0 + tau0 self._time0(n, int_max=int_max)))) worksFin = (lambda l: l - np.mean(l))( list( map( lambda t: self.workArray[t + n - tau0:t + n].mean( ), # fluctuations of the active work averaged between t0 and t0 + tau0 self._time0(n, int_max=int_max)))) workOrder = ordersIni * worksFin cor += [[ n - tau0, *mean_sterr(workOrder), np.std(ordersIni), np.std(worksFin) ]] return np.array(cor)
def varWorkFromCorWork(self, tau0=1, n=100, int_max=None, bruteForce=True): """ Compute variance of the active work from its "instantaneous" fluctuations correlations. This function is primarily for consistency testing of the correlations functions. Parameters ---------- tau0 : int Number of consecutive individual active works on which to average it, and for which correlations will be computed. (default: 1) n : int Compute variance for tau = i*tau0 with i in {1, ..., n}. (default: 100) int_max : int or None Maximum number of different intervals to consider in order to compute the mean which appears in the correlation expression. (default: None) NOTE: if int_max == None, then a maximum number of intervals will intervals will be considered (joint if bruteForce else disjoint). bruteForce : bool Use self.corWorkWorkInsBruteForce rather than self.corWorkWorkIns. (default: True) Returns ------- var : (3, *) numpy array Array of: (0) value at which the variance is computed, (1) mean of the computed variance, (2) standard error of the computed variance. """ if bruteForce: corWorkWorkIns = self.corWorkWorkInsBruteForce else: corWorkWorkIns = self.corWorkWorkIns if bruteForce: cor = self.corWorkWorkInsBruteForce(tau0, n_max=n, int_max=int_max, max=n - 1, log=False) else: cor = self.corWorkWorkIns(tau0, n_max=n, int_max=int_max, min=tau0, max=(n - 1) * tau0, log=False) var0 = mean_sterr( (lambda l: (l - l.mean())**2)(self.nWork(tau0, int_max=int_max))) var = [] for n0 in range(1, n + 1): var += [[n0 * tau0, var0[0] / n0, (var0[1] / n0)**2]] for i in range(1, n0): var[-1][1] += 2 * (n0 - i) * cor[i - 1, 1] / (n0**2) var[-1][2] += (2 * (n0 - i) * cor[i - 1, 2] / (n0**2))**2 var[-1][2] = np.sqrt(var[-1][2]) return np.array(var)
def corWorkWorkInsBruteForce(self, workPart1=None, workPart2=None, tau0=1, n_max=100, int_max=None, max=None, log=True): """ Compute (cross) correlations of the fluctuations of the work averaged over `tau0' between different times. This algorithm computes the correlations more quickly by averaging over successive couples of initial and final values of the active work. Results of this function should then be taken with care as some other unwanted low-time correlations could be picked. Parameters ---------- workPart1 : string Part of the active work to consider at the beginning of the interval: * 'all': active work, * 'force': force part of the active work, * 'orientation': orientation part of the active work, * 'noise': noise part of the active work. (default: None) NOTE: if workPart1 == None, then self.workArray is taken. workPart2 : string Part of the active work to consider at the end of the interval. (default: None) NOTE: if workPart2 == None, then self.workArray is taken. tau0 : int Number of consecutive individual active works on which to average it. (default: 1) n_max : int Maximum number of values at which to evaluate the correlation. (default: 100) int_max : int or None Maximum number of different intervals to consider in order to compute the mean which appears in the correlation expression. (default: None) NOTE: if int_max == None, then a maximum number of intervals will intervals will be considered. max : int or None Maximum value at which to compute the correlation in units of tau0. (default: None) NOTE: if max == None, the maximum number of values is computed. log : bool Logarithmically space values at which the correlations are computed. (default: True) Returns ------- cor : (3, *) numpy array Array of: (0) value at which the correlation is computed, (1) mean of the computed correlation, (2) standard error of the computed correlation. """ work1 = (self.workArray if workPart1 == None else self.workDict[workPart1]) work2 = (self.workArray if workPart2 == None else self.workDict[workPart2]) if log: space = logspace else: space = linspace if int_max == None: int_max = (self.numberWork - self.skip) // tau0 Nsample = int( np.min([(self.numberWork - self.skip) // tau0, int_max * tau0]) ) # size of the sample of consecutive normalised rates of active work to consider workArray1 = np.array( list( map( # array of consecutive normalised rate of active work averaged of time tau0 lambda t: work1[self.skip + t * tau0:self.skip + t * tau0 + tau0].mean(), range(Nsample)))) workArray1 -= workArray1.mean( ) # only considering fluctuations to the mean if workPart1 == workPart2: workArray2 = workArray1 else: workArray2 = np.array( list( map( # array of consecutive normalised rate of active work averaged of time tau0 lambda t: work2[self.skip + t * tau0:self.skip + t * tau0 + tau0].mean(), range(Nsample)))) workArray2 -= workArray2.mean( ) # only considering fluctuations to the mean lagTimes = space( # array of lag times considered 1, (Nsample - 1) if max == None else int(np.min([max, Nsample - 1])), n_max) cor = list( map( lambda dt: [ tau0 * dt, *mean_sterr( (workArray1 * np.roll(workArray2, -dt))[:Nsample - dt]) ], lagTimes)) return np.array(cor)
def corWorkWorkIns(self, workPart1=None, workPart2=None, tau0=1, n_max=100, int_max=None, min=None, max=None, log=True): """ Compute (cross) correlations of the fluctuations of the work averaged over `tau0' between different times. Parameters ---------- workPart1 : string Part of the active work to consider at the beginning of the interval: * 'all': active work, * 'force': force part of the active work, * 'orientation': orientation part of the active work, * 'noise': noise part of the active work. (default: None) NOTE: if workPart1 == None, then self.workArray is taken. workPart2 : string Part of the active work to consider at the end of the interval. (default: None) NOTE: if workPart2 == None, then self.workArray is taken. tau0 : int Number of consecutive individual active works on which to average it. (default: 1) n_max : int Maximum number of values at which to evaluate the correlation. (default: 100) int_max : int or None Maximum number of different intervals to consider in order to compute the mean which appears in the correlation expression. (default: None) NOTE: if int_max == None, then a maximum number of disjoint intervals will be considered. min : int or None Minimum value at which to compute the correlation. (default: None) NOTE: if min == None then min = `tau0', otherwise the minimum of `tau0' and `min' is taken. max : int or None Maximum value at which to compute the correlation. (default: None) NOTE: this value is passed as `max' to self.n. log : bool Logarithmically space values at which the correlations are computed. (default: True) Returns ------- cor : (5, *) numpy array Array of: (0) value at which the correlation is computed, (1) mean of the computed correlation, (2) standard error of the computed correlation, (3) standard deviation of the active work computed at the beginning of the interval, (4) standard deviation of the active work computed at the end of the interval. """ work1 = (self.workArray if workPart1 == None else self.workDict[workPart1]) work2 = (self.workArray if workPart2 == None else self.workDict[workPart2]) cor = [] for n in self._n( n_max=n_max, log=log, min=(2 * tau0 if min == None else np.max([tau0 + min, 2 * tau0])), max=(None if max == None else tau0 + max)): worksIni = (lambda l: l - np.mean(l))( list( map( lambda t: work1[t:t + tau0].mean( ), # fluctuations of the active work averaged between t0 and t0 + tau0 self._time0(n, int_max=int_max)))) worksFin = (lambda l: l - np.mean(l))( list( map( lambda t: work2[t + n - tau0:t + n].mean( ), # fluctuations of the active work averaged between t0 and t0 + tau0 self._time0(n, int_max=int_max)))) workWork = worksIni * worksFin cor += [[ n - tau0, *mean_sterr(workWork), np.std(worksIni), np.std(worksFin) ]] return np.array(cor)
def corWorkWorkAve(self, tau0=1, n_max=100, int_max=None, min=None, max=None, log=True): """ Compute correlations of the fluctuations of the work averaged over `tau0' at the beginning of an interval and the fluctuations of the work averaged over the whole interval. Parameters ---------- tau0 : int Number of consecutive individual active works on which to average it. (default: 1) n_max : int Maximum number of values at which to evaluate the correlation. (default: 100) int_max : int or None Maximum number of different intervals to consider in order to compute the mean which appears in the correlation expression. (default: None) NOTE: if int_max == None, then a maximum number of disjoint intervals will be considered. min : int or None Minimum value at which to compute the correlation. (default: None) NOTE: if min == None then this value is passed as `min' to self.n, otherwise the minimum of `tau0' and `min' is taken. max : int or None Maximum value at which to compute the correlation. (default: None) NOTE: this value is passed as `max' to self.n. log : bool Logarithmically space values at which the correlations are computed. (default: True) Returns ------- cor : (5, *) numpy array Array of: (0) value at which the correlation is computed, (1) mean of the computed correlation, (2) standard error of the computed correlation, (3) standard deviation of the active work computed at the beginning of the interval, (4) standard deviation of the active work computed over the interval. """ cor = [] for n in self._n(n_max=n_max, max=max, log=log, min=(None if min == None else np.max([min, tau0]))): worksTot = (lambda l: l - np.mean(l))( self.nWork(n, int_max=int_max) ) # fluctuations of the active wok on intervals of size n worksIni = (lambda l: l - np.mean(l))( list( map( lambda t: self.workArray[t:t + tau0].mean( ), # fluctuations of the active work averaged on tau0 at the beginning of these intervals self._time0(n, int_max=int_max)))) workWork = worksTot * worksIni cor += [[ n, *mean_sterr(workWork), np.std(worksTot), np.std(worksIni) ]] return np.array(cor)
def meanSterr(self, remove=False, max=None): """ Returns array of mean and standard error of measured data. Parameters ---------- remove : bool Remove inf and -inf as well as nan. (default: False) NOTE: A warning will be issued if remove == False and such objects are encountered. max : float or None Remove data which is strictly above max in absolute value. (default: None) NOTE: max != None will trigger remove = True. Returns ------- activeWork : (self.gValues.size, 3) float Numpy array Normalised rate of active work. activeWorkForce : (self.gValues.size, 3) float Numpy array Force part of the normalised rate of active work. activeWorkOri : (self.gValues.size, 3) float Numpy array Orientation part of the normalised rate of active work. orderParameter : (self.gValues.size, 3) float Numpy array Order parameter. torqueIntegral1 : (self.gValues.size, 3) float Numpy array First torque integral. torqueIntegral2 : (self.gValues.size, 3) float Numpy array Second torque integral. NOTE: (0) Torque parameter. (1) Mean. (2) Standard error. Lambda : (self.gValues.size, 4) float Numpy array Bound to the rate function. NOTE: (0) Active work. (1) Standard error on active work. (2) Bound to the rate function. (3) Standard error on the boudn to the function. """ activeWork = np.empty((self.gValues.size, 3)) activeWorkForce = np.empty((self.gValues.size, 3)) activeWorkOri = np.empty((self.gValues.size, 3)) orderParameter = np.empty((self.gValues.size, 3)) torqueIntegral1 = np.empty((self.gValues.size, 3)) torqueIntegral2 = np.empty((self.gValues.size, 3)) Lambda = np.empty((self.gValues.size, 4)) for i in range(self.gValues.size): activeWork[i] = [ self.gValues[i], *mean_sterr(self.activeWork[i], remove=remove, max=max) ] activeWorkForce[i] = [ self.gValues[i], *mean_sterr(self.activeWorkForce[i], remove=remove, max=max) ] activeWorkOri[i] = [ self.gValues[i], *mean_sterr(self.activeWorkOri[i], remove=remove, max=max) ] orderParameter[i] = [ self.gValues[i], *mean_sterr(self.orderParameter[i], remove=remove, max=max) ] torqueIntegral1[i] = [ self.gValues[i], *mean_sterr(self.torqueIntegral1[i], remove=remove, max=max) ] torqueIntegral2[i] = [ self.gValues[i], *mean_sterr(self.torqueIntegral2[i], remove=remove, max=max) ] Lambda[i] = [ *mean_sterr(self.Lambda[i, :, 0], remove=remove, max=max), *mean_sterr(self.Lambda[i, :, 1], remove=remove, max=max) ] return (activeWork, activeWorkForce, activeWorkOri, orderParameter, torqueIntegral1, torqueIntegral2, Lambda)
def pairDistribution(self, Nbins, min=None, max=None, int_max=None, scale_diameter=False): """ Returns pair distribution function as an histogram of distances between pairs of particles. Parameters ---------- Nbins : int Number of histogram bins. min : float or None Minimum included value for histogram bins. (default: None) NOTE: if min == None then 0 is taken. NOTE: values lesser than to min will be ignored. max : float or None Maximum excluded value for histogram bins. (default: None) NOTE: if max == None then self.L/2 is taken. NOTE: values greater than or equal to max will be ignored. int_max : int or None Maximum number of frames to consider. (default: None) NOTE: If int_max == None, then take the maximum number of frames. WARNING: This can be very big. scale_diameter : bool Divide the distance between pairs of particles by the sum of the radii of the particles in the pair. (default: False) Returns ------- gp : float Numpy array Array of (r, gp(r), errgp(r)) with gp(r) the proportion of pairs at distance r and errgp(r) the standard error on this measure. """ if min == None: min = 0 if max == None: max = self.L / 2 hist = np.array( list( map( # lambda t: (lambda dist: pycpp.getHistogramLinear(dist, # Nbins, min, max)/dist.size)( # pycpp.getDistances(self.getPositions(t), self.L, # diameters=( # self.diameters if scale_diameter else None))), lambda t: pycpp.pairDistribution( Nbins, min, max, self.getPositions(t), self.L, diameters=(self.diameters if scale_diameter else None)), self._time0(int_max=int_max)))) bins = np.array( [min + (b + 0.5) * (max - min) / Nbins for b in range(Nbins)]) histErr = np.array([mean_sterr(h) for h in np.transpose(hist)]) histErr *= (self.L**2) / ((max - min) / Nbins) return np.array([[b, *h / (2 * np.pi * b)] for b, h in zip(bins, histErr)])
def meanSterr(self, remove=False, max=None): """ Returns array of mean and standard error of measured data. Parameters ---------- remove : bool Remove inf and -inf as well as nan. (default: False) NOTE: A warning will be issued if remove == False and such objects are encountered. max : float or None Remove data which is strictly above max in absolute value. (default: None) NOTE: max != None will trigger remove = True. Returns ------- SCGF : (self.sValues.size, 3) float Numpy array Scaled cumulant generating function. activeWork : (self.sValues.size, 3) float Numpy array Normalised rate of active work. activeWorkForce : (self.sValues.size, 3) float Numpy array Force part of the normalised rate of active work. activeWorkOri : (self.sValues.size, 3) float Numpy array Orientation part of the normalised rate of active work. orderParameter : (self.sValues.size, 3) float Numpy array Order parameter. NOTE: (0) Biasing parameter. (1) Mean. (2) Standard error. I : (self.sValues.size, 4) float Numpy array Rate function. NOTE: (0) Active work. (1) Standard error on active work. (2) Rate function. (3) Standard error on rate function. """ if max != None: remove = True SCGF = np.empty((self.sValues.size, 3)) activeWork = np.empty((self.sValues.size, 3)) activeWorkForce = np.empty((self.sValues.size, 3)) activeWorkOri = np.empty((self.sValues.size, 3)) orderParameter = np.empty((self.sValues.size, 3)) I = np.empty((self.sValues.size, 4)) for i in range(self.sValues.size): SCGF[i] = [ self.sValues[i], *mean_sterr(self.SCGF[i], remove=remove, max=max) ] activeWork[i] = [ self.sValues[i], *mean_sterr(self.activeWork[i], remove=remove, max=max) ] activeWorkForce[i] = [ self.sValues[i], *mean_sterr(self.activeWorkForce[i], remove=remove, max=max) ] activeWorkOri[i] = [ self.sValues[i], *mean_sterr(self.activeWorkOri[i], remove=remove, max=max) ] orderParameter[i] = [ self.sValues[i], *mean_sterr(self.orderParameter[i], remove=remove, max=max) ] I[i] = [ *mean_sterr(self.I[i, :, 0], remove=remove, max=max), *mean_sterr(self.I[i, :, 1], remove=remove, max=max) ] return (SCGF, activeWork, activeWorkForce, activeWorkOri, orderParameter, I)
def corPropulsionForce(self, n_max=100, int_max=None, min=None, max=None, log=False): """ Returns correlations between (i) the fluctuations of the propulsion at initial times and the fluctuations of the force at later times, and (ii) the fluctuations of the force at initial times and the fluctations of the propulsion at later times. Parameters ---------- n_max : int Maximum number of lag times. (default: 100) int_max : int or None Maximum number of different initial times. (default: None) NOTE: if int_max == None, then a maximum number of (disjoint) intervals will be considered. min : int or None Minimum lag time. (default: None) NOTE: if min == None, then min = 1. max : int or None Maximum lag time. (default: None) NOTE: if max == None, then max is taken to be the maximum according to the choice of int_max. log : bool Logarithmically spaced lag times. (default: False) NOTE: This does not apply to .datN files. Returns ------- corPF : (*, 3) numpy array Array of: (0) value at which the correlation (i) is computed, (1) mean of the computed correlation (i), (2) standard error of the computed correlation (i). corFP : (*, 3) numpy array Array of: (0) value at which the correlation (ii) is computed, (1) mean of the computed correlation (ii), (2) standard error of the computed correlation (ii). pF0sq : (**,) float numpy array Product of the standard deviations of the propulsion and the force at initial times. """ time0, dt = self._dt(n_max=n_max, int_max=int_max, min=min, max=max, log=log) corPF, corFP = [], [] propIni = np.array( list( map( # fluctuations of the propulsion at initial times lambda t: wo_mean(self.getPropulsions(t, norm=False), axis=-2), time0))) forcesIni = np.array( list( map( # fluctuations of the force at initial times lambda t: wo_mean(self.getForce(t), axis=-2), time0))) pF0sq = np.sqrt( (propIni**2).sum(axis=-1).mean(axis=-1) # average over particles * (forcesIni** 2).sum(axis=-1).mean(axis=-1)) # average over particles for tau in dt: propFin = np.array( list( map( # fluctuations of the propulsion at initial times + lag time lambda t: wo_mean( self.getPropulsions(t + tau, norm=False), axis=-2), time0))) forcesFin = np.array( list( map( # fluctuations of the force at initial times + lag time lambda t: wo_mean(self.getForce(t + tau), axis=-2), time0))) qProd = (propIni * forcesFin).sum(axis=-1).mean( axis=-1) # average over particles corPF += [[tau, *mean_sterr(qProd / pF0sq)]] # average over times qProd = (forcesIni * propFin).sum(axis=-1).mean( axis=-1) # average over particles corFP += [[tau, *mean_sterr(qProd / pF0sq)]] # average over times return np.array(corPF), np.array(corFP), pF0sq