Beispiel #1
0
 def getCFTiming(self, t, y):
     y = self.normalizeY(y)
     dt = t[1] - t[0]
     self.delayInterval = int(self.delay / dt)
     ntrun = int(np.floor(2000 / dt))
     ymax = np.amax(y)
     halfy = np.where(y > ymax * self.gain * 0.9)[0]
     t0 = halfy[0]
     t1 = halfy[-1] + self.delayInterval
     f = self.simulateCFT(t, y, dt)
     yy = f(t[ntrun:-ntrun])
     yys = yy[t0 - ntrun:t1 - ntrun]
     if len(yys) == 0: print(len(yy), [t0 - ntrun, t1 - ntrun])
     x0 = self.crossFinder(yys)
     if x0 < 0: return -1
     inte = [t[t0 + x0 - 1], t[t0 + x0 + 1]]
     if self.method == 'tomas':
         try:
             cft = optimize.toms748(f, inte[0], inte[1])
         except:
             print(inte)
             raise ValueError('failed to get CFT')
         #cft = optimize.newton(lambda x : f(x), x0=(inte[0]+inte[1])/2)
     elif self.method == 'linear':
         x1 = inte[0]
         x2 = inte[1]
         k = (f(x2) - f(x1)) / (x2 - x1)
         cft = x1 - f(x1) / k
     return cft
Beispiel #2
0
def gamma_uncensored(gamma_obs, gammas):
    """ An uncensored gamma estimator. """
    # Handle no observations
    if np.sum(gammas) == 0.0:
        gammas = np.ones_like(gammas)

    gammaCor = np.average(gamma_obs, weights=gammas)
    s = np.log(gammaCor) - np.average(np.log(gamma_obs), weights=gammas)

    def f(k):
        return np.log(k) - sc.polygamma(0, k) - s

    flow = f(1.0)
    fhigh = f(100.0)
    if flow * fhigh > 0.0:
        if np.absolute(flow) < np.absolute(fhigh):
            a_hat0 = 1.0
        elif np.absolute(flow) > np.absolute(fhigh):
            a_hat0 = 100.0
        else:
            a_hat0 = 10.0
    else:
        a_hat0 = toms748(f, 1.0, 100.0)

    return [a_hat0, gammaCor / a_hat0]
Beispiel #3
0
    def optim_b(cls,
                D,
                k,
                alpha,
                b_optim_min=0,
                b_optim_max=None,
                xtol=10**-12,
                **kwds):
        """Find optimal value of the characteristic length scale `b`.

        Parameters
        ----------
        D : (N, N) array_like
            Distance matrix.
        b : float
            Characteristic length scale (positive value).
        alpha :
            Homophily value.
        b_optim_min : float
            Lower bound of the interval used in optimizing `b`.
        b_optim_max : float, optional
            Uppe bound of the interval used in optimizing `b`.
            If ``None`` then defaults to ``D.max()``.
        **kwds :
            Keyword parameters passed to :py:func:`scipy.optimize.brentq`.
        """
        def b_optim(b):
            P = cls.prob_measure(D, b, alpha)
            Ek = P.sum(axis=1).mean()
            return k - Ek

        if b_optim_max is None:
            b_optim_max = D.max()
        b = toms748(b_optim, a=b_optim_min, b=b_optim_max, xtol=xtol, **kwds)
        return b
Beispiel #4
0
    def solve_timestep_point(self, z_min, z_max, z_downstream, z_past, dt, dx,
                             U, K, A, m, n):
        """Solves the transient equations
        E = K A^m S^n
        dz/dt = U - E
        dz/dt = U - K A^m S^n
        (z^j+1-z^j)/dt = U - K A^m ((z_i^j+1-z_i-1^j+1)/dx)^n
        We move all terms to one side:
        0 = U - K A^m ((z_i^j+1-z_i-1^j+1)/dx)^n - (z^j+1-z^j)/dt
        we then assume this is a function
        z_predict = U - K A^m ((z_i^j+1-z_i-1^j+1)/dx)^n - (z^j+1-z^j)/dt
        and use a root finding algorithm to solve.
        We use Newton's method if n = 1 and the toms748 algorithm if n != 1.
        tom's is faster and guaranteed to converge, but does not work if function is not differentiable 4 times.
        we use upslope values of K, U, A for the discretization

        If n = 1 we can actually solve directly.
        0 = U - K A^m ((z_f-z_ds)/dx) - (z_f-z_0)/dt
        0 = U - K A^m z_f/dx + K A^m z_ds/dx - z_f/dt + z_0/dt
        K A^m z_f/dx + z_f/dt = U + K A^m z_ds/dx + z_0/dt
        z_f (K A^m/dx + 1/dt) = U + K A^m z_ds/dx + z_0/dt

        Args:
            uses all data members, no args

        Returns:
            Overwrites the elevation

        Author:
            Simon M Mudd

        Date:
            18/08/2020
        """

        if n == 1:
            #z_future = optimize.newton(solve_timestep_differencer,z_past,args=(z_downstream,z_past,dt,dx,U,K,A,m,n))
            SP_term = (K * A**m) / dx
            z_future = (U + SP_term * z_downstream + z_past / dt) / (SP_term +
                                                                     1 / dt)
        else:
            z_future = optimize.toms748(solve_timestep_differencer,
                                        z_min,
                                        z_max,
                                        args=(z_downstream, z_past, dt, dx, U,
                                              K, A, m, n))

        #print("Z_future is: ")
        #print(z_future)

        return z_future
Beispiel #5
0
def one_sigma_to_percent_error(percent, sigma):
    sigma_orders = [0, 1, 2, 3, 4, 5, 6]
    sigma_percents = [
        0., 68.2689492137, 95.4499736104, 99.7300203937, 99.9936657516,
        99.9999426697, 99.9999998027
    ]
    for i, sigma_order in enumerate(sigma_orders):
        if percent < sigma_percents[i]: break

    def func(error, percent, sigma, sigma_order):
        x = np.linspace(0, error, sigma_order * 100)
        return percent / 100 / 2 - simps(
            np.exp(-x**2 / 2 / sigma**2) / np.sqrt(2 * np.pi) / sigma, x)

    if sigma_order == 1:
        return toms748(func,
                       1e-2 * sigma,
                       sigma_order * sigma,
                       args=(percent, sigma, sigma_order))
    else:
        return toms748(func, (sigma_order - 1) * sigma,
                       sigma_order * sigma,
                       args=(percent, sigma, sigma_order))
Beispiel #6
0
def squint(x, orbit, attitude, sin_az=0.0):
    """Find imaging time and squint (angle between LOS and velocity) for a
    target at position x."""
    def daz(t):
        xs, _ = orbit.interpolate(t)  # don't need velocity
        look = x - xs
        look *= 1.0 / np.linalg.norm(look)
        R = attitude.rotmat(t)
        err = sin_az - look.dot(R[:, 0])
        #print("t, err =", t, err)
        return err

    # Find imaging time.
    #t = fsolve(daz, orbit.midTime, factor=10)[0]
    t = toms748(daz, orbit.startTime, orbit.endTime)
    #print("t0 =", t)
    # Compute squint.
    xs, vs = orbit.interpolate(t)
    vhat = vs / np.linalg.norm(vs)
    look = (x - xs) / np.linalg.norm(x - xs)
    return t, np.arcsin(look.dot(vhat))
Beispiel #7
0
    td_TANK_ra =   C_TANK_R.td(ss_1, ra = ra + ddd)

    dC_dR_TANK = (td_TANK_ra['C']/ td_TANK_ra['C'][Time-50] -1)*100
    return dC_dR_HANK - dC_dR_TANK[0]


sHTM_g = 0.2
ss['CR'] = ss['C'] * (1-sHTM_g) 
ss['sHTM'] = sHTM_g
ss['avg_beta'] = np.vdot(ss['beta'], ss['pi_beta'])
re_calib_beta = False

ss_copy =  ss.copy()  

args = (ss_copy, dTuni, HANK_MPC)
res_HtM = optimize.toms748(MPC_calib, 0,1, args = args)


ss['sHTM'] = res_HtM
ss_copy['sHTM'] = res_HtM
td_TANK =   C_TANK.td(ss_copy, Tuni = dTuni)
dCC_TANK =  (td_TANK['C']/ td_TANK['C'][Time-50] -1)*100

ss_copy_ra =  ss_copy.copy() 
ddd = - 0.0025  * 0.6**(np.arange(Time))


args = (ss_copy_ra, ddd, dC_dR_HANK)
res_ra = optimize.toms748(R_calib, 0.005,3, args = args)

td_ra       = C_TANK.td(ss_copy, ra = ss['ra'] + ddd)
Beispiel #8
0
def calculate_apparent_D_with_noise(meas_erosion,meas_curv,half_length = 6, spacing = 1, S_c = 1.0, rho_ratio=2, topographic_uncert = 0.5, n_iterations = 5, use_brents = False):
    """This functions aim is to see whqat the actualk curvature would be if the profile were displaced

    Args:
        meas_erosion (float): the measured erosion rate (in m/yr)
        meas_curv (float): the curvature measured from the DEM
        half_length (float): The distance covered by the profile away rom the hillcrest
        spacing (float): The spacing of x  in metres       
        S_c (float): Critical slope (dimensionless)
        rho_ratio (float): ratio between rock and soil density
        topographic_uncert (float): the mean uncertainty in m of the topographic data
        n_iterations (int): the number of iterations you use to do the random uncertainty. 
        use_brents (bool): if true, use brent's method instead of toms

    Returns:
        The ridgetop curvature in 1/m

    Author:
        Simon M Mudd
        
    Date:
        15/05/2020   
        updated 04/05/2021 to include Brents method for unstable samples 
    """  
    
    # first guess the diffusivity from the measured data
    D_apparent = -rho_ratio*meas_erosion/meas_curv
    print("The apparent D is:"+str(D_apparent)+" or "+str(D_apparent*1000)+" in m^2/kyr")
    
    # now we get the baseline sampling
    x_loc_baseline = set_profile_locations_half_length(half_length = half_length,spacing = spacing)
    
    # now solve the D needed to get the apparent D
    print("Right, going into the optimization loop")
    #print("By the way, the starting C is")
    #first_curv = curvature_difference_function(D_apparent, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv)
    #print("meas: "+str(meas_curv)+" and difference from the test curvature: "+str(first_curv))
    #big = curvature_difference_function(D_apparent*2, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv)
    #small = curvature_difference_function(D_apparent*0.5, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv)
    #print("big:" +str(big)+" and small: "+str(small))
    
    # plot the curvature function
    #D_vals = [D_apparent*0.5,D_apparent,D_apparent*2]
    #C_offset_vals = []
    #for D in D_vals:
    #    C_offset_vals.append( curvature_difference_function(D, x_loc_baseline, S_c, meas_erosion, rho_ratio,meas_curv) )
    #print("C offsets are: ")
    #print(C_offset_vals)
 
    if(use_brents):
        print("I am going to use Brent's method to optimise")
    else:
        print("I am using the toms748 algorithm to optimise")        
    
    # Run the optimisation
    root_1_list = []
    for i in range(0,n_iterations):
        if use_brents:
            try:
                root_1 = optimize.brentq(curvature_difference_function_with_noise,0.000000000001,100,args=(x_loc_baseline,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert))
            except ValueError:
                print("This iteration did not converge.")
                n_iterations=n_iterations+1

        else:
            try:
                root_1 = optimize.toms748(curvature_difference_function_with_noise,0.000000000001,100,args=(x_loc_baseline,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert))

            except ValueError:
                print("This iteration did not converge.")
                n_iterations=n_iterations+1
        root_1_list.append(root_1)
       
    # now test
    #z = ss_nonlinear_elevation(x_loc_baseline,S_c = S_c,C_0 = meas_erosion , D=root ,rho_ratio = rho_ratio)
    #app_curv = fit_hilltop_curvature(x_loc_baseline,z)  
    #print("Measured curvature is: "+str(meas_curv)+ " and the apparent curvature measured from a gridded sample is: "+str(app_curv))
       
    # now to get a range, we want the minimum and maximum values
    # This is the maximum displacement of the data from the divide
    x_displace_max = displace_profile_locations_constant(x_loc_baseline,spacing/2)
    
    root_2_list = []
    root_3_list = []
    for i in range(0,n_iterations):
        if use_brents:
            try:
                root_2 = optimize.brentq(curvature_difference_function_with_noise,0.000000000001,100,args=(x_displace_max,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert))
            except ValueError:
                print("This iteration did not converge.")
        else:
            try:
                root_2 = optimize.toms748(curvature_difference_function_with_noise,0.000000000001,100,args=(x_displace_max,S_c,meas_erosion,rho_ratio,meas_curv,topographic_uncert))
            except ValueError:
                print("This iteration did not converge.")

        root_1_list.append(root_2)

    
    max_D = max(root_1_list)
    min_D = min(root_1_list)
    med_D = st.median(root_1_list)
    D16 = np.percentile(root_1_list,16)
    D84 = np.percentile(root_1_list,84)
    
    print("Range of D:")
    print([min_D,med_D,max_D])
    
    return [min_D,D16,med_D,D84,max_D]
Beispiel #9
0
    def steady_state_concentraions(self, nxc):
        '''
        Calculats the steady state concentration of carriers,
        provided the number of excess minoirty carriers by peturbing the number of excess majority carriers.

        This assumes a constant intrinsic carrier density.

        Parameters
        ----------
        nxc : float
            the number of excess carrier densities

        Returns
        -------
        ne: float
            the free electron concentration
        nh: float
            the free hole concentration
        nd: array like
            the number of defects in each state

        '''
        def charges(mj):
            '''
            calculations the change in majority carrier density

            this function doesn't really need to be here
            '''

            if self.Nacc > self.Ndon:
                nh = np.array(mj, dtype=np.float64)
                ne = np.array(self.ne0 + nxc[i], dtype=np.float64)

            elif self.Ndon > self.Nacc:
                ne = np.array(mj, dtype=np.float64)
                nh = np.array(self.nh0 + nxc[i], dtype=np.float64)

            return ne, nh

        def charges_HD(Ef):

            # if the fermi energy leve is
            #    negative the holes are the majority carrier
            if Ef < 0:
                qEfh = Ef
                nh = ni * np.exp(-1 * qEfh / self.Vt)
                ne = self.ne0 + nxc[i]
                qEfe = self.Vt * np.log(ne / ni)

            # if its bigger than zero the electrons are
            if Ef > 0:
                qEfe = Ef
                ne = ni * np.exp(qEfe / self.Vt)
                nh = self.nh0 + nxc[i]
                qEfh = -1 * self.Vt * np.log(nh / ni)
            return qEfe, qEfh, ne, nh

        def possion_hd(Ef):
            '''
            determine the charge neutrality for high defect
            densities

            '''
            qEfe, qEfh, ne, nh = charges_HD(Ef)

            # this is just a wrapper to set nte, which the following
            # possion function uses
            defect_charge = np.array(0, dtype=np.float64)

            # find the charge of the defects
            for _dft in self.defectlist:
                defect_charge += _dft.net_charge([qEfe, qEfh], temp)

            # add up all the charges
            return self.Ndon - ne - self.Nacc + nh + defect_charge

        def possion(mj):
            '''
            determine the charge neutrality

            '''
            # get the number of carriers
            ne, nh = charges(mj)

            # turns them into an quasi fermi energy level
            qEfe = self.Vt * np.log(ne / ni)
            qEfh = -1 * self.Vt * np.log(nh / ni)
            # this is just a wrapper to set nte, which the following
            # possion function uses
            defect_charge = np.array(0, dtype=np.float64)

            # find the charge of the defects
            for _dft in self.defectlist:
                defect_charge += _dft.net_charge([qEfe, qEfh], temp)

            # add up all the charges
            return self.Ndon - ne - self.Nacc + nh + defect_charge

        self.equlibrium_concentrations()

        if not isinstance(nxc, np.ndarray):
            nxc = np.array([nxc])

        ne = np.zeros(nxc.shape[0])
        nh = np.zeros(nxc.shape[0])
        nd = []
        nd = np.array([])
        ni = self.ni
        Vt = self.Vt
        temp = self.temp

        mj = max(self.ne0, self.nh0)
        Nd = 0
        for dft in self.defectlist:
            Nd += dft.Nd
        # need to do each carrier density individually
        # for low defect densities its all easy
        if Nd < 0.1 * mj:

            for i, nxc_i in enumerate(nxc):
                # initial guess of the number of excess majority carrier
                # then solve for charge conservation
                mj = newton(possion,
                            np.array(mj + nxc[i], dtype=np.float64),
                            maxiter=100,
                            tol=1.48e-38)
                # get the values
                ne_i, nh_i = charges(mj)

                # save the values into the array
                ne[i] = ne_i
                nh[i] = nh_i

                # save the defect concentrations
                for _dft in self.defectlist:
                    # nd.append(_dft.charge_state_concentration(
                    # [Vt * np.log(ne_i / ni), -Vt * np.log(nh_i / ni)], temp))
                    nd = np.concatenate(
                        (nd,
                         _dft.charge_state_concentration(
                             [Vt * np.log(ne_i / ni), -Vt * np.log(nh_i / ni)],
                             temp)))

        else:
            for i, nxc_i in enumerate(nxc):

                Ef = toms748(possion_hd, -1, 1)

                qEfe, qEfh, ne_i, nh_i = charges_HD(Ef)
                # save the values into the array
                ne[i] = ne_i
                nh[i] = nh_i

                # save the defect concentrations
                for _dft in self.defectlist:

                    nd = np.concatenate(
                        (nd, _dft.charge_state_concentration([qEfe, qEfh],
                                                             temp)))

        return ne, nh, nd
Beispiel #10
0
    def equlibrium_concentrations(self):
        '''
        Calculate the equlibrium carrier concentration

        Returns
        -------
        ne0 : float
            the free electron concentration in the dark
        nh0 : float
            the free hole concentration in the dark
        '''
        def charges(Ef):
            ne0, nh0 = ni * np.exp(np.array([Ef, -Ef]) / self.Vt)
            return ne0, nh0

        def d_charges(Ef):
            ne0, nh0 = np.array([ni, -ni]) * \
                np.exp(np.array([Ef, -Ef]) / self.Vt) / self.Vt
            return ne0, nh0

        def possion(Ef):
            ne0, nh0 = charges(Ef)

            # this is just a wrapper to set nte, which the following
            # possion function uses
            defect_charge = 0
            for _dft in self.defectlist:
                defect_charge += _dft.net_charge(Ef, self.temp)

            charge = self.Ndon - ne0 - self.Nacc + nh0 + defect_charge
            # print('\nsum and individuals for Ef=',
            # Ef, '{0:.2e}'.format(charge))
            # print(self.Ndon - ne0 - self.Nacc + nh0 + defect_charge)
            # print(self.Vt * np.log(abs(self.Ndon - ne0 -
            #                            self.Nacc + nh0 + defect_charge - 1)))
            # print(self.Ndon, '{0:.2e}'.format(ne0),
            #       self.Nacc, '{0:.2e}'.format(nh0), defect_charge)
            # plt.figure('norm')
            # plt.plot(Ef, (charge), 'r.')
            # plt.figure('log')
            # plt.plot(Ef, np.log(abs((charge)) + 1), 'r.')

            return charge

        def d_possion(Ef):
            dne0, dnh0 = d_charges(Ef)
            ne0, nh0 = charges(Ef)

            # this is just a wrapper to set nte, which the following
            # possion function uses
            defect_charge = 0
            d_defect_charge = 0
            for _dft in self.defectlist:
                defect_charge = _dft.net_charge(Ef + 0, self.temp)
                d_defect_charge += _dft.net_charge(
                    Ef + 0.0001, self.temp) - _dft.net_charge(
                        Ef + 0, self.temp)

            # f = self.Ndon - ne0 - self.Nacc + nh0 + defect_charge + 1
            # fd = -dne0 + dnh0 + d_defect_charge
            # return fd / f

            return (-dne0 + dnh0 + d_defect_charge)

        # This line is to speed up calculations
        # recalculation of ni each time is quite slow.
        ni = self.ni
        # initial guess of majority carrier
        # mjc = newton(possion, abs(self.Nacc - self.Ndon), maxiter=100)

        # mjc = newton(possion, x0=Ef, maxiter=200, fprime=d_possion)
        Ef = toms748(possion, -1, 1)
        # new lets work out the details
        self.ne0, self.nh0 = charges(Ef)

        return self.ne0, self.nh0
Beispiel #11
0
    rl_ = rl(x[0], x[2])**3
    return numpy.array([
        x[1], -(1 - MU) * x[0] / r3_ - MU * (x[0] - 1) / rl_, x[3],
        -(1 - MU) * x[2] / r3_ - MU * x[2] / rl_
    ])


def x_star_equation(x):
    def x_star_equation_integral(z):
        return 1 / (numpy.e**(1.7 * (z**2)) + x)

    (integral, _) = quad(x_star_equation_integral, 0, 1)
    return integral - 0.3707355 * x


x_star = toms748(x_star_equation, 0, 3)
a = 1.2 * x_star
b = 0
c = 0
d = 1

initial = numpy.array([a, b, c, d])

lower_bound = 0
upper_bound = T
step = 0.1

_, space_plot = pyplot.subplots()
_, velocities_plot = pyplot.subplots()

Beispiel #12
0
def _rootf(**kwargs):
    return optimize.toms748(k=1, **kwargs)