Пример #1
0
def process(seed, K):
    """
    K is model order / number of zeros
    """

    # create the dirac locations with many, many points
    rng = np.random.RandomState(seed)
    tk = np.sort(rng.rand(K)*period)

    # true zeros
    uk = np.exp(-1j*2*np.pi*tk/period)
    coef_poly = poly.polyfromroots(uk)   # more accurate than np.poly
    
    # estimate zeros
    uk_hat = np.roots(np.flipud(coef_poly))
    uk_hat_poly = poly.polyroots(coef_poly)
    uk_hat_mpmath = mpmath.polyroots(np.flipud(coef_poly), maxsteps=100, 
        cleanup=True, error=False, extraprec=50)

    # compute error
    min_dev_norm = distance(uk, uk_hat)[0]
    _err_roots = 20*np.log10(np.linalg.norm(uk)/min_dev_norm)

    min_dev_norm = distance(uk, uk_hat_poly)[0]
    _err_poly = 20*np.log10(np.linalg.norm(uk)/min_dev_norm)

    # for mpmath, need to compute error with its precision
    uk = np.sort(uk)
    uk_mpmath = [mpmath.mpc(z) for z in uk]
    uk_hat_mpmath = sorted(uk_hat_mpmath, key=cmp_to_key(compare_mpc))
    dev = [uk_mpmath[k] - uk_hat_mpmath[k] for k in range(len(uk_mpmath))]
    _err_mpmath = 20*mpmath.log(mpmath.norm(uk_mpmath) / mpmath.norm(dev), 
            b=10)

    return _err_roots, _err_poly, _err_mpmath
Пример #2
0
    def visibility_first_derivative(self, posix_time):
        """Calculate the derivative of the visibility function of the satellite and the site at a
        given time.

        Args:
            posix_time (float): The UNIX time to evaluate the derivative visibility function at.

        Returns:
            The value of the visibility function evaluated at the provided time.
        """

        # Since most helper functions don't play well with mpmath floats we have to perform a lossy
        # conversion.
        posix_time = float(posix_time)
        sat_pos_vel = np.array(
            self.sat_irp.interpolate(posix_time)) * mp.mpf(1.0)
        site_pos = np.array(self.site_ecef) * mp.mpf(1.0)

        pos_diff = np.subtract(sat_pos_vel[0], site_pos)
        vel_diff = sat_pos_vel[1]

        site_normal_pos = site_pos / mp.norm(site_pos)
        site_normal_vel = [0, 0, 0]

        first_term = mp.mpf(
            ((1.0 / mp.norm(pos_diff)) * (mp.fdot(vel_diff, site_normal_pos) +
                                          mp.fdot(pos_diff, site_normal_vel))))

        second_term = mp.mpf(((1.0 / mp.power(
            (mp.norm(pos_diff)), 3)) * mp.fdot(pos_diff, vel_diff) *
                              mp.fdot(pos_diff, site_normal_pos)))

        return first_term - second_term
def run_stoch_eig(P, verbose=0):
    """
    stoch_eig returns a stochastic vector x such that x P = x
    for an irreducible stochstic matrix P.
    """
    if verbose > 1:
        print("original matrix (stoch_eig):\n", P)

    x = mp.stoch_eig(P)

    if verbose > 1:
        print("x\n", x)

    eps = mp.exp(0.8 * mp.log(mp.eps))  # From test_eigen.py

    # x is a left eigenvector of P with eigenvalue unity
    err0 = mp.norm(x*P-x, p=1)
    if verbose > 0:
        print("|xP - x| (stoch_eig):", err0)
    assert err0 < eps

    # x is a nonnegative vector
    if verbose > 0:
        print("min(x) (stoch_eig):", min(x))
    assert min(x) >= 0 - eps

    # 1-norm of x is one
    err1 = mp.fabs(mp.norm(x, p=1) - 1)
    if verbose > 0:
        print("||x| - 1| (stoch_eig):", err1)
    assert err1 < eps
Пример #4
0
def _view_cone_calc(lat_geoc, lon_geoc, sat_pos, sat_vel, q_max, m):
    """Semi-private: Performs the viewing cone visibility calculation for the day defined by m.
    Note: This function is based on a paper titled "rapid satellite-to-site visibility determination
    based on self-adaptive interpolation technique"  with some variation to account for interaction
    of viewing cone with the satellite orbit.

    Args:
        lat_geoc (float): site location in degrees at the start of POI
        lon_geoc (float): site location in degrees at the start of POI
        sat_pos (Vector3D): position of satellite (at the same time as sat_vel)
        sat_vel (Vector3D): velocity of satellite (at the same time as sat_pos)
        q_max (float): maximum orbital radius
        m (int): interval offsets (number of days after initial condition)

    Returns:
        Returns 4 numbers representing times at which the orbit is tangent to the viewing cone,

    Raises:
        ValueError: if any of the 4 formulas has a complex answer. This happens when the orbit and
        viewing cone do not intersect or only intersect twice.

    Note: With more analysis it should be possible to find a correct interval even in the case
        where there are only two intersections but this is beyond the current scope of the project.
    """
    lat_geoc = (lat_geoc * mp.pi) / 180
    lon_geoc = (lon_geoc * mp.pi) / 180

    # P vector (also referred  to as orbital angular momentum in the paper) calculations
    p_unit_x, p_unit_y, p_unit_z = cross(sat_pos, sat_vel) / (mp.norm(sat_pos) * mp.norm(sat_vel))

    # Following are equations from Viewing cone section of referenced paper
    r_site_magnitude = earth_radius_at_geocetric_lat(lat_geoc)
    gamma1 = THETA_NAUGHT + mp.asin((r_site_magnitude * mp.sin((mp.pi / 2) + THETA_NAUGHT)) / q_max)
    gamma2 = mp.pi - gamma1

    # Note: atan2 instead of atan to get the correct quadrant.
    arctan_term = mp.atan2(p_unit_x, p_unit_y)
    arcsin_term_gamma, arcsin_term_gamma2 = [(mp.asin((mp.cos(gamma) - p_unit_z * mp.sin(lat_geoc))
                                             / (mp.sqrt((p_unit_x ** 2) + (p_unit_y ** 2)) *
                                              mp.cos(lat_geoc)))) for gamma in [gamma1, gamma2]]

    angle_1 = (arcsin_term_gamma - lon_geoc - arctan_term + 2 * mp.pi * m)
    angle_2 = (mp.pi - arcsin_term_gamma - lon_geoc - arctan_term + 2 * mp.pi * m)
    angle_3 = (arcsin_term_gamma2 - lon_geoc - arctan_term + 2 * mp.pi * m)
    angle_4 = (mp.pi - arcsin_term_gamma2 - lon_geoc - arctan_term + 2 * mp.pi * m)
    angles = [angle_1, angle_2, angle_3, angle_4]

    # Check for complex answers
    if any([not isinstance(angle, mp.mpf) for angle in angles]):
        raise ValueError()

    # Map all angles to 0 to 2*pi
    for idx in range(len(angles)):
        while angles[idx] < 0:
            angles[idx] += 2 * mp.pi
        while angles[idx] > 2 * mp.pi:
            angles[idx] -= 2 * mp.pi

    # Calculate the corresponding time for each angle and return
    return [mp.nint((1 / ANGULAR_VELOCITY_EARTH) * angle) for angle in angles]
Пример #5
0
def rotate_3D_mp(x, y):
    xnorm = mpm.norm(x)
    ynorm = mpm.norm(y)
    cos = mpm.fdot(x,y)/(xnorm*ynorm)
    sin = mpm.sqrt(1.-cos**2)
    K = (y.T*x-x.T*y)/(xnorm*ynorm*sin)
    return mpm.eye(3) + sin*K + (1.-cos)*(K*K)
def run_gth_solve(A, verbose=0):
    """
    gth_solve returns a stochastic vector x such that x A = 0
    for an irreducible transition rate matrix A.
    """
    if verbose > 1:
        print("original matrix (gth_solve):\n", A)

    x = mp.gth_solve(A)

    if verbose > 1:
        print("x\n", x)

    eps = mp.exp(0.8 * mp.log(mp.eps))  # test_eigen.py

    # x is a solution to x A = 0
    err0 = mp.norm(x*A, p=1)
    if verbose > 0:
        print("|xA| (gth_solve):", err0)
    assert err0 < eps

    # x is a nonnegative vector
    if verbose > 0:
        print("min(x) (gth_solve):", min(x))
    assert min(x) >= 0 - eps

    # 1-norm of x is one
    err1 = mp.fabs(mp.norm(x, p=1) - 1)
    if verbose > 0:
        print("||x| - 1| (gth_solve):", err1)
    assert err1 < eps
Пример #7
0
def test_poincare_reflect0():
    z = mpm.matrix([[0., 0., 0.5]])
    x = mpm.matrix([[0.1, -0.2, 0.1]])

    assert mpm.norm(poincare_reflect0(z, z)) < TOL

    y = poincare_reflect0(z, x)
    assert mpm.norm(poincare_reflect0(z, y) - x) < TOL
Пример #8
0
def test_poincare_reflect():
    x = mpm.matrix([[0.3, -0.3, 0.0]])
    a = mpm.matrix([[0.5, 0., 0.0]])
    y = poincare_reflect(a, x)

    R = mpm.norm(a)
    r1 = mpm.norm(x - a)
    r2 = mpm.norm(y - a)
    assert R**2 - r1 * r2 < TOL
Пример #9
0
def rotate_mp(pts, x, y):
    out = mpm.zeros(pts.rows, pts.cols)
    v = x/mpm.norm(x) 
    cos = mpm.fdot(x,y) / (mpm.norm(x), mpm.norm(y))
    sin = mpm.sqrt(1.-cos**2)
    u = y - mpm.fdot(v, y) * v 

    mat = mpm.eye(x.cols) - u.T * u - v.T * v \
        + cos * u.T * u - sin * v.T * u + sin * u.T * v + cos * v.T * v
    return mat
def sphericalknn(data, no_clusters):

    H = len(data)
    W = len(data[0])

    #calculating the mean to remove the dc component
    sum_sample = sum(data)
    norm_sample = np.linalg.norm(sum_sample)
    mean_sample = (sum_sample) / (norm_sample)

    #calculating global mean to get centroids of the clusters
    deviation = 0.01
    mean_global = np.zeros([no_clusters, W])
    for i in range(0, no_clusters):
        random_sample = np.random.rand(1, W) - 0.5
        random_norm = deviation * (np.random.rand())
        random_sample2 = (random_norm *
                          random_sample) / np.linalg.norm(random_sample)
        temp = mean_sample + random_sample2
        mean_global[i, :] = temp / np.linalg.norm(temp)

#calculating mean from spherical kmeans

    sum_sample3 = np.zeros([1, W])
    difference = 1
    epsilon = 0.01
    number = 100
    iteration = 0

    while (difference > epsilon):
        iteration = iteration + 1
        number2 = number
        #computing the nearest neighbour and assigning the points
        #E Step in EM algorithm
        mean_global2 = np.transpose(mean_global)
        value = np.dot(data, mean_global2)
        value_max = value.max(1)
        clusters = np.argmax(value, axis=1)

        #computing value of the function
        number = sum(value_max)
        #print(number)

        #computing centroids for the clusters
        #M step in EM algorithm
        for i in range(0, no_clusters):
            sum_sample3 = sum(data[np.where(clusters == i)])
            if (mpmath.norm(sum_sample3) != 0):
                temp2 = sum_sample3 / mpmath.norm(
                    sum_sample3)  #np.linalg.norm(sum_sample3) #Check this
                mean_global[i, :] = temp2

        difference = abs(number - number2)

    return clusters
Пример #11
0
def refine_model_mdnewton_mpmath(low_dimensional_model,
                                 newton_steps=5,
                                 expected_quality=(0.1, 0.01, 1e-3, 1e-5, 1e-8,
                                                   1e-12, 1e-18, 1e-24),
                                 log10_stop_quality=-130,
                                 still_good=lambda v70: True,
                                 norm=1):
    """Refines a model using mpmath's MDNewton() solver.

  For some solutions, this fails due to the critical point being not a 'generic'
  one.

  Args:
    low_dimensional_model: A LowDimensionalModel.
    still_good: f(v70) -> bool, determines if the solution is still good.
    newton_steps: The number of multidimensional Newton steps to take.
    expected_quality: List of expected quality thresholds for each step.
      (Last entry implicitly repeats.)
    log10_stop_quality: Stop early if this quality-threshold is reached.
    norm: The `norm` parameter for mpmath.calculus.optimization.MDNewton().

  Returns:
    A refined LowDimensionalModel.

  Raises:
    ValueError, if the solution is no longer good.
  """
    if len(low_dimensional_model.params) == 0:
        return low_dimensional_model

    def f_off(*model_vec):
        v70 = numpy.dot(low_dimensional_model.v70_from_params,
                        numpy.array(model_vec, dtype=mpmath.mpf))
        sinfo = scalar_sector_mpmath.mpmath_scalar_manifold_evaluator(v70)
        return tuple(sinfo.grad_potential)

    newton = mpmath.calculus.optimization.MDNewton(
        mpmath.mp,
        f_off,
        tuple(low_dimensional_model.params),
        verbose=1,
        norm=lambda x: mpmath.norm(x, norm))
    newton_iter = iter(newton)
    for num_step in range(1, newton_steps + 1):
        opt, stationarity = next(newton_iter)
        opt_v70 = numpy.dot(low_dimensional_model.v70_from_params, opt)
        if mpmath.log(stationarity, 10) <= log10_stop_quality:
            break
        expected_stationarity = expected_quality[min(
            len(expected_quality) - 1, num_step)]
        if stationarity > expected_stationarity:
            raise ValueError('Stationarity does not improve as expected: '
                             'seen=%.6g, wanted=%.6g, step=%d' %
                             (stationarity, expected_stationarity, num_step))
        if not still_good(opt_v70):
            raise ValueError('Solution is no longer good.')
        print('[MDNewton] Step %d: stat=%s' % (num_step, mpfmt(stationarity)))
    return LowDimensionalModel(
        v70_from_params=low_dimensional_model.v70_from_params,
        params=numpy.array(opt, dtype=mpmath.mpf))
Пример #12
0
def poincare_dist0(x, c=1.0, precision=None):
    ''' Distance from 0 to x in the Poincare model with curvature -1/c'''
    if precision is not None:
        mpm.mp.dps = precision
    x_norm = mpm.norm(x)
    sqrt_c = mpm.sqrt(c)
    return 2 / sqrt_c * mpm.atanh(x_norm / sqrt_c)
Пример #13
0
    def are_nested(self, v1: NormalVector, r1: float, v2: NormalVector,
                   r2: float):
        from numpy.linalg import norm

        distance = norm(v1.get_coordinate() - v2.get_coordinate())

        return max(r1, r2) >= distance + min(r1, r2)
Пример #14
0
    def __init__(self, theta, phi, r=None, is_polar=True):
        from mpmath import mpf, mp, norm, fabs, chop

        if not r:
            r = Point._scale
        else:
            r *= Point._scale

        Point._can_change_the_scale = False
        mp.dps = Point._precision

        if not is_polar:

            self.x = mpf(theta)
            self.y = mpf(phi)
            self.z = mpf(r)
            self.norm = norm(self.get_coordinate(), 2)

            self.set_polar_coordinate()

        else:

            self.norm = fabs(r)
            self.theta = theta
            self.phi = phi

            self.set_coordinate()

        # Setting float parameters

        self.floatx = float(self.x)
        self.floaty = float(self.y)
        self.floatz = float(self.z)
def test_gth_solve_fp():
    P = mp.fp.matrix([[-0.1, 0.075, 0.025],
                      [0.15, -0.2 , 0.05 ],
                      [0.25, 0.25 , -0.5 ]])
    x_expected = mp.fp.matrix([[0.625, 0.3125, 0.0625]])
    x = mp.fp.gth_solve(P)
    eps = mp.exp(0.8 * mp.log(mp.eps))  # test_eigen.py
    err0 = mp.norm(x-x_expected, p=1)
    assert err0 < eps
def test_stoch_eig_fp():
    P = mp.fp.matrix([[0.9 , 0.075, 0.025],
                      [0.15, 0.8  , 0.05 ],
                      [0.25, 0.25 , 0.5  ]])
    x_expected = mp.fp.matrix([[0.625, 0.3125, 0.0625]])
    x = mp.fp.stoch_eig(P)
    eps = mp.exp(0.8 * mp.log(mp.eps))  # test_eigen.py
    err0 = mp.norm(x-x_expected, p=1)
    assert err0 < eps
def newtonMethod(VF, X_start):
    X = X_start
    Y = getYacobyMatrix(VF, X)
    Y_1 = Y**-1
    while mp.norm(Y_1 * VF(X), 2) > eps:
        Y = getYacobyMatrix(VF, X)
        Y_1 = Y**-1
        X = X - (Y_1 * VF(X))
    return X
Пример #18
0
    def has_intersection(self, v1: NormalVector, r1: float, v2: NormalVector,
                         r2: float):
        #   v1 and v2 are two distinict points on unit upper semisphere.It returns true if two balls B[v1, r1] and
        # B[v2, r2] has intersection on unit sphere and in this case answers will be returned as
        # up_intersect and down_intersect relative to Z - axis. It is O(1)

        from numpy import cross, dot
        from numpy.linalg import norm
        from math import sqrt

        t1 = r_to_dot(r1)
        t2 = r_to_dot(r2)

        u1 = v1.get_coordinate()
        u2 = v2.get_coordinate()
        t = dot(u1, u2)

        dot_equation_solution_on_u1u2 = ((t1 - t * t2) /
                                         (1 - t**2)) * u1 + ((t2 - t * t1) /
                                                             (1 - t**2)) * u2
        norm_on_u1u2 = norm(dot_equation_solution_on_u1u2)
        if norm_on_u1u2 > 1:
            return False, None, None

        perp = cross(u1, u2)
        perp /= norm(perp)

        if perp[2] < 0:
            perp *= -1

        perp_projection = sqrt(1 - norm_on_u1u2**2) * perp

        up = dot_equation_solution_on_u1u2 + perp_projection
        down = dot_equation_solution_on_u1u2 - perp_projection

        up_intersection = NormalVector(up[0], up[1], up[2], is_polar=False)
        down_intersection = NormalVector(down[0],
                                         down[1],
                                         down[2],
                                         is_polar=False)

        return True, up_intersection, down_intersection
Пример #19
0
    def visibility(self, posix_time):
        """Calculate the visibility function of the satellite and the site at a given time.

        Args:
            posix_time (float): The time to evaluate the visibility function at

        Returns:
            The value of the visibility function evaluated at the provided time.

        Note:
            This function assumes the FOV of the sensors on the satellite are 180 degrees
        """

        # Since most helper functions don't play well with mpmath floats we have to perform a lossy
        # conversion.
        posix_time = float(posix_time)
        site_pos = np.array(self.site_ecef) * mp.mpf(1.0)
        site_normal_pos = site_pos / mp.norm(site_pos)
        sat_pos = self.sat_irp.interpolate(posix_time)[0]
        sat_site = np.subtract(sat_pos, site_pos)

        return mp.mpf(mp.fdot(sat_site, site_normal_pos) / mp.norm(sat_site))
Пример #20
0
 def coherent_state(self, alpha, dtype=complex):
     from ..statevector import StateVector as sv
     x = numpy.empty(self.N1, dtype=dtype)
     x[0] = dtype("1")
     for n in range(1, self.N1):
         x[n] = x[n-1]*alpha/(n)**(0.5)
     if issubclass(dtype, complex):
         a = numpy.exp(-numpy.abs(alpha)**2/2.)
     else:
         import mpmath
         a = mpmath.exp(-mpmath.norm(alpha)**2/2)
     x = a*x[self.N0:self.N1]
     return sv(x, basis=self)
Пример #21
0
def cg(vec_x, mat_a, vec_b, rtol, atol, max_times):
    dim = vec_x.rows
    r = vec_b - mat_a * vec_x
    p = r
    init_norm_r = mpmath.norm(r)
    old_norm_r = init_norm_r
    # メインループ
    for times in range(max_times):
        ap = mat_a * p
        alpha = (r.T * p)[0] / (p.T * ap)[0]
        vec_x = vec_x + alpha * p
        r = r - alpha * ap
        new_norm_r = mpmath.norm(r)
        beta = new_norm_r * new_norm_r / (old_norm_r * old_norm_r)
        # 収束判定
        print(times, mpmath.nstr(new_norm_r / init_norm_r))
        if (new_norm_r <= (rtol * init_norm_r + atol)):
            break

        p = r + beta * p
        old_norm_r = new_norm_r

    return times, vec_x
Пример #22
0
def test_mev():
    output("""\
    reim:{$[0>type x;1 0*x;2=count x;x;'`]};
    mc:{((x[0]*y 0)-x[1]*y 1;(x[0]*y 1)+x[1]*y 0)};
    mmc:{((.qml.mm[x 0]y 0)-.qml.mm[x 1]y 1;(.qml.mm[x 0]y 1)+.qml.mm[x 1]y 0)};
    mev_:{[b;x]
        if[2<>count wv:.qml.mev x;'`length];
        if[not all over prec>=abs
            mmc[flip vc;flip(flip')(reim'')flip x]-
            flip(w:reim'[wv 0])mc'vc:(flip')(reim'')(v:wv 1);'`check];
        / Normalize sign; LAPACK already normalized to real
        v*:1-2*0>{x a?max a:abs x}each vc[;0];
        (?'[prec>=abs w[;1];w[;0];w];?'[b;v;0n])};""")

    for A in eigenvalue_subjects:
        if A.rows <= 3:
            V = []
            for w, n, r in A.eigenvects():
                w = sp.simplify(sp.expand_complex(w))
                if len(r) == 1:
                    r = r[0]
                    r = sp.simplify(sp.expand_complex(r))
                    r = r.normalized() / sp.sign(max(r, key=abs))
                    r = sp.simplify(sp.expand_complex(r))
                else:
                    r = None
                V.extend([(w, r)] * n)
            V.sort(key=lambda (x, _): (-abs(x), -sp.im(x)))
        else:
            Am = mp.matrix(A)
            # extra precision for complex pairs to be equal in sort
            with mp.extradps(mp.mp.dps):
                W, R = mp.eig(Am)
            V = []
            for w, r in zip(W, (R.column(i) for i in range(R.cols))):
                w = mp.chop(w)
                with mp.extradps(mp.mp.dps):
                    _, S, _ = mp.svd(Am - w * mp.eye(A.rows))
                if sum(x == 0 for x in mp.chop(S)) == 1:
                    # nullity 1, so normalized eigenvector is unique
                    r /= mp.norm(r) * mp.sign(max(r, key=abs))
                    r = mp.chop(r)
                else:
                    r = None
                V.append((w, r))
            V.sort(key=lambda (x, _): (-abs(x), -x.imag))
        W, R = zip(*V)
        test("mev_[%sb" % "".join("0" if r is None else "1" for r in R),
             A, (W, [r if r is None else list(r) for r in R]),
             complex_pair=True)
Пример #23
0
def test_mev():
    output("""\
    reim:{$[0>type x;1 0*x;2=count x;x;'`]};
    mc:{((x[0]*y 0)-x[1]*y 1;(x[0]*y 1)+x[1]*y 0)};
    mmc:{((.qml.mm[x 0]y 0)-.qml.mm[x 1]y 1;(.qml.mm[x 0]y 1)+.qml.mm[x 1]y 0)};
    mev_:{[b;x]
        if[2<>count wv:.qml.mev x;'`length];
        if[not all over prec>=abs
            mmc[flip vc;flip(flip')(reim'')flip x]-
            flip(w:reim'[wv 0])mc'vc:(flip')(reim'')(v:wv 1);'`check];
        / Normalize sign; LAPACK already normalized to real
        v*:1-2*0>{x a?max a:abs x}each vc[;0];
        (?'[prec>=abs w[;1];w[;0];w];?'[b;v;0n])};""")

    for A in eigenvalue_subjects:
        if A.rows <= 3:
            V = []
            for w, n, r in A.eigenvects():
                w = sp.simplify(sp.expand_complex(w))
                if len(r) == 1:
                    r = r[0]
                    r = sp.simplify(sp.expand_complex(r))
                    r = r.normalized() / sp.sign(max(r, key=abs))
                    r = sp.simplify(sp.expand_complex(r))
                else:
                    r = None
                V.extend([(w, r)]*n)
            V.sort(key=lambda (x, _): (-abs(x), -sp.im(x)))
        else:
            Am = mp.matrix(A)
            # extra precision for complex pairs to be equal in sort
            with mp.extradps(mp.mp.dps):
                W, R = mp.eig(Am)
            V = []
            for w, r in zip(W, (R.column(i) for i in range(R.cols))):
                w = mp.chop(w)
                with mp.extradps(mp.mp.dps):
                    _, S, _ = mp.svd(Am - w*mp.eye(A.rows))
                if sum(x == 0 for x in mp.chop(S)) == 1:
                    # nullity 1, so normalized eigenvector is unique
                    r /= mp.norm(r) * mp.sign(max(r, key=abs))
                    r = mp.chop(r)
                else:
                    r = None
                V.append((w, r))
            V.sort(key=lambda (x, _): (-abs(x), -x.imag))
        W, R = zip(*V)
        test("mev_[%sb" % "".join("0" if r is None else "1" for r in R), A,
             (W, [r if r is None else list(r) for r in R]), complex_pair=True)
Пример #24
0
def poincare_dist(x, y, c=1.0, precision=None):
    ''' 
    The hyperbolic distance between points in the Poincare model with curvature -1/c 
        Args:
            x, y: size 1xD mpmath matrix representing point in the D-dimensional ball |x| < 1
            precision (int): bits of precision to use
        Returns:
            mpmath float object. Can be converted back to regular float
    '''
    if precision is not None:
        mpm.mp.dps = precision
    x2 = mpm.fdot(x, x)
    y2 = mpm.fdot(y, y)
    xy = mpm.fdot(x, y)
    sqrt_c = mpm.sqrt(c)
    denom = 1 - 2 * c * xy + c**2 * x2 * y2
    norm = mpm.norm(
        (-(1 - 2 * c * xy + c * y2) * x + (1. - c * x2) * y) / denom)
    return 2 / sqrt_c * mpm.atanh(sqrt_c * norm)
Пример #25
0
def solve_acos_bsin(a, b, c):
    #   It solves the equation  $ a cos(theta) + b sin(theta) = c $ for theta as the unknown.
    #   This has either two or no answer.  It is needed for the get_covered_phi function.
    #   It always returns the larger answer first.
    from numpy.linalg import norm
    from math import acos

    Norm = norm((a, b))
    if abs(c) > Norm:
        return None, None

    dot = c / Norm
    dtheta = acos(dot)

    if b >= 0:
        angle = acos(a / Norm)
    else:
        angle = -acos(a / Norm)

    upans = angle + dtheta
    downans = angle - dtheta

    return upans, downans
Пример #26
0
        dtheta_values.append(
            d_theta(angle_v, paramv['k'], paramv['R'], paramv['alpha'], An))

    beamshape = [
        20 * mpmath.log10(abs(each / dzero_value)) for each in dtheta_values
    ]

    beamshape_df = pd.DataFrame(data={
        'deg': np.degrees(np.float32(angles)),
        'd0dthet': np.float32(beamshape)
    })

    error = beamshape - ka5['relonaxis_db']
    mean_error = np.float(np.mean(np.abs(error)))
    max_error = np.max(np.float32(np.abs(error)))
    matrixsolve_error = mpmath.norm(mpmath.residual(Mmn, An, bm))

    #print(f'Decimal precision: {decimalprec} \n Ntrend: {Ntrend}')
    print(f'Matrix solve error : {matrixsolve_error }')
    print(f'Mean abs error: {mean_error}, max error: {max_error}\n')

    # # %%
    #     an_candidate = mpmath.lu_solve(Mmn,bm)
    #     res_mat = mpmath.residual(Mmn, an_candidate, bm)
    #     res = mpmath.norm(res_mat)
    #     print(f'matrix error is: {np.float64(res)}')

    # %%
    # an_candidate, res = mpmath.qr_solve(Mmn,bm)
    # print(res)
    # #%%
Пример #27
0
    def run(self,**kwargs):
        """Run the microkinetic model. If recalculate is True then
        data which is re-loaded will be used as an initial guess; otherwise it
        will be assumed to be correct."""
        
        for key in kwargs:
            setattr(self,key,kwargs[key])
        
        #set numerical representation
        if self.numerical_representation == 'mpmath':
            import mpmath as mp
            mp.mp.dps = self.decimal_precision + 25 #pad decimal precision
            self._math = mp
            self._log_imports += "\nfrom mpmath import mpf \n\n"
            self._kB = mp.mpf('8.617332478e-5') #eV/K (from NIST)
            self._h = mp.mpf('4.135667516e-15') #eV s (from NIST)
            self._mpfloat = mp.mpf
            self._matrix = mp.matrix
            self._Axb_solver = mp.lu_solve
            self._math.infnorm = lambda x: mp.norm(x,'inf')
        elif self.numerical_representation in ['numpy','python']:
            self._log_imports += "\nfrom numpy import matrix \n\n"
            self._math = np
            self._math.infnorm = lambda x: np.linalg.norm(x,np.inf)
            self._mpfloat = float
            def matrixT(*args,**kwargs):
                array = np.array(args[0])
                while 1 in array.shape:
                    sum_idx = array.shape.index(1)
                    array = array.sum(sum_idx)
                return array.T

            self._matrix = matrixT
            def Axb_solver(A,b):
                try:
                    return np.linalg.solve(A,b.T)
                except np.linalg.linalg.LinAlgError:
                    raise ZeroDivisionError
            self._Axb_solver = Axb_solver
            if self.decimal_precision > 15:
                print(
                'Warning: Max precision with numpy/python is 16 digits')
                self.decimal_precision = 15
        else:
            raise AttributeError(
            'Numerical representation must be mpmath, numpy, or python.')

        #set up interaction model
        if self.adsorbate_interaction_model == 'first_order':
            interaction_model = catmap.thermodynamics.FirstOrderInteractions(self)
            response_func = interaction_model.interaction_response_function
            if not callable(response_func):
                int_function = getattr(interaction_model,
                        response_func+'_response')
                interaction_model.interaction_response_function = int_function
            self.thermodynamics.__dict__['adsorbate_interactions'] = interaction_model

        elif self.adsorbate_interaction_model == 'second_order':
            interaction_model = catmap.thermodynamics.SecondOrderInteractions(self)
            response_func = interaction_model.interaction_response_function
            if not callable(response_func):
                int_function = getattr(interaction_model,
                        response_func+'_response')
                interaction_model.interaction_response_function = int_function
            self.thermodynamics.__dict__['adsorbate_interactions'] = interaction_model

        elif self.adsorbate_interaction_model in ['ideal',None]:
            self.thermodynamics.adsorbate_interactions = None
        else:
            raise AttributeError(
                    'Invalid adsorbate_interaction_model specified.')

        self.compatibility_check()

        #determine whether or not to (re-)solve model
        has_all = True
        for v in self.output_variables:
            if not hasattr(self,v+'_map'):
                has_all = False

        if not hasattr(self,'stdout'):
            #any re-loaded model will have stdout
            has_all = False

        if self._solved == self._token():
            #Do not solve the same model twice
            has_all = True

        elif has_all and not self.recalculate:
            #All data has been loaded and no verification => solved.
            self._solved = self._token()
            self.log('input_success')

        else:
            #Make "volcano plot"
            if hasattr(self,'descriptor_ranges') and hasattr(self,'resolution'):
                self.descriptor_space_analysis()
            #Get rates at single points
            if hasattr(self,'descriptors'):
                self.single_point_analysis(self.descriptors)
            #Get rates at multiple points
            if hasattr(self,'descriptor_values'):
                self.multi_point_analysis()

            #Save long attrs in data_file
            for attr in dir(self):
                if (not attr.startswith('_') and
                        not callable(getattr(self,attr)) and
                        attr not in self._classes):
                    if (len(repr(getattr(self,attr))) > 
                            self._max_log_line_length):
                        #line is too long for logfile -> put into pickle
                        self._pickle_attrs.append(attr)
            pickled_data = {}
            for attr in self._pickle_attrs:
                pickled_data[attr] = getattr(self,attr)
            pickle.dump(pickled_data,open(self.data_file,'w'))

            #Make logfile
            log_txt = self._log_imports
            log_txt += self._header(exclude_outputs=self._pickle_attrs)
            self._stdout = '\n'.join(self._log_lines)
            log_txt += 'stdout = ' + '"'*3+self._stdout+'"'*3
            #this construction means that self.stdout will only be set
            #for models which have been re-loaded.
            self._solved = self._token()
            if hasattr(self,'log_file'):
                logfile = self.log_file
            else:
                name,suffix = self.setup_file.rsplit('.',1)
                if suffix != 'log':
                    suffix = 'log'
                else:
                    suffix = 'out'
                logfile = '.'.join([name,suffix])

            f = open(logfile,'w')
            f.write(log_txt)
            f.close()

            if getattr(self,'create_standalone',None):
                self.make_standalone() 
Пример #28
0
from pylab import *
import mpmath

mpmath.mp.dps = 50     # higher precision for demonstration
#Nv=100000
Nv=100000
a = [mpmath.sin(2.*mpmath.pi*n/Nv) for n in range(Nv)]
b = array(a)
print  b.dot(b) - Nv/2

b32= array(a,dtype=float32)
b64= array(a,dtype=float64)
b128= array(a,dtype=float128)

print  b32.dot(b32) - Nv/2.
print  b64.dot(b64) - Nv/2.
print  b128.dot(b128) - Nv/2.

print
print mpmath.norm(b) - mpmath.sqrt(Nv/2)
print norm(b32)  - sqrt(Nv/2)
print norm(b64)  - sqrt(Nv/2)
print norm(b128)  -sqrt(Nv/2)
Пример #29
0
    ],
    'agm': [
        'primitive',
        [lambda x, y: mp.agm(x) if y is None else mp.agm(x, y[0]), None]
    ],
    #
    'matrix': [
        'primitive',
        [
            lambda x, y: mp.matrix(x) if isa(x, Vector) else mp.matrix(x)
            if y is None else mp.matrix(x, y[0]), None
        ]
    ],
    'matrix-ref': ['primitive', [lambda x, y: x[y[0], y[1], [0]], None]],
    'matrix-set': [
        'primitive',
        [lambda x, y: matrix_set(x, y[0], y[1][0], y[1][1][0]), None]
    ],
    'zeros': ['primitive', [lambda x, y: mp.zeros(x), None]],
    'ones': ['primitive', [lambda x, y: mp.ones(x), None]],
    'eye': ['primitive', [lambda x, y: mp.eye(x), None]],
    'diag': ['primitive', [lambda x, y: mp.diag(x), None]],
    'randmatrix': ['primitive', [lambda x, y: mp.randmatrix(x), None]],
    'matrix-inv': ['primitive', [lambda x, y: x**(-1), None]],
    'norm': [
        'primitive',
        [lambda x, y: mp.norm(x) if y is None else mp.norm(x, y[0]), None]
    ],
    'mnorm': ['primitive', [lambda x, y: mp.mnorm(x, y[0]), None]],
}
Пример #30
0
mat_a = mpmath.zeros(dim, dim)
for i in range(dim):
    for j in range(dim):
        mat_a[i, j] = mpmath.mpf(dim - max(i, j))

mat_a = mat_a.T * mat_a
# print(mat_a)

# x = [1 2 ... dim]
vec_true_x = mpmath.matrix([i for i in range(1, dim + 1)])
# nprint(vec_true_x)

# b = A * x
vec_b = mat_a * vec_true_x

# CG法実行
# vec_x := 0
vec_x = mpmath.zeros(dim, 1)
start_time1 = time.time()
iterative_times, vec_x = cg(vec_x, mat_a, vec_b, 1.0e-20, 0.0, dim * 10)
time1 = time.time() - start_time1

relerr = mpmath.norm(vec_x - vec_true_x) / mpmath.norm(vec_true_x)
print('CG: iteration, time = ', iterative_times, time1, ', relerr(vec_x) = ',
      relerr)

# -------------------------------------
# Copyright (c) 2021 Tomonori Kouya
# All rights reserved.
# -------------------------------------
Пример #31
0
    def make_polar_coordinate(self,
                              n,
                              is_twisted=True,
                              precision=30,
                              log_scale=0):
        # This function distribute points with polar coordinate on sphere.  This algorithm is O (n^2).
        # It also returns a phi above which we know north pole is a local maximum.

        from mpmath import mp, sin, cos, sqrt, pi, floor, mpf, asin
        from numpy import array, cross
        from numpy.linalg import norm
        from os import remove

        mp.dps = precision

        remove(self.points_address)
        if is_twisted:
            name = "twisted_polar_coordinates_" + str(n)
            self.point_set = PointSet(name=name, address=self.output_folder)
        else:
            name = "polar_coordinates_" + str(n)
            self.point_set = PointSet(name=name, address=self.output_folder)

        self.points_address = self.point_set.point_file_address

        if not float(Point._log_scale) == log_scale:
            Point.change_log_scale(log_scale)
            print("Point scale is", Point.get_scale())

        if not Point._precision == precision:
            Point.change_precision(precision)

        phis = [0] * (n - 1)
        m = [0] * (n - 1)

        for j in range(n - 1):
            phis[j] = ((pi * (j + 1)) / n) - (pi / 2)
            m[j] = int(floor(mpf(".5") + sqrt(3) * n * cos(phis[j])))

        for j in range(n - 1):
            for i in range(m[j]):

                if is_twisted:
                    if j + 1 < n / 2:
                        shift = (2 * pi * (j + 1)) / (n * m[j])
                    else:
                        shift = (2 * pi * (1 - mpf(j + 1) / mpf(n))) / m[j]
                else:
                    shift = 0

                theta = ((2 * pi * i) / m[j]) + shift

                new_point = Point(theta=theta, phi=phis[j])
                self.point_set.add_point(new_point)

        north_pole = Point(theta=0, phi=pi / 2)
        south_pole = Point(theta=0, phi=-pi / 2)
        self.point_set.add_point(north_pole)
        self.point_set.add_point(south_pole)

        self.min_discrepancy_distance = 1 / self.point_set.size

        # In below we get the confidence phi around the north pole

        highest_phi = -1
        for i in range(int(n / 2) - 1, n - 2):
            phi1 = phis[i]
            phi2 = phis[i + 1]

            v1 = array([mpf(0), cos(phi1), mpf(0)])
            v2 = array([2 * cos(phi1), mpf(0), sin(phi2) - sin(phi1)])

            normal_vector = cross(v1, v2)
            normal_vector /= norm(normal_vector)

            highest_phi = max(highest_phi, asin(abs(normal_vector[2])))

        return float(highest_phi)
Пример #32
0
db3 scaling coefficients
Wavelet Analysis: The Scalable Structure of Information (2002)
Howard L. Resnikoff, Raymond O.Jr. Wells
Table 10.3 page 263
'''
db3 = [( _1 +    sqrt10 +    mp.sqrt(_5 + _2*sqrt10))/_16,
       ( _5 +    sqrt10 + _3*mp.sqrt(_5 + _2*sqrt10))/_16,
       (_10 - _2*sqrt10 + _2*mp.sqrt(_5 + _2*sqrt10))/_16,
       (_10 - _2*sqrt10 - _2*mp.sqrt(_5 + _2*sqrt10))/_16,
       ( _5 +    sqrt10 - _3*mp.sqrt(_5 + _2*sqrt10))/_16,
       ( _1 +    sqrt10 -    mp.sqrt(_5 + _2*sqrt10))/_16]
db3 = np.array(db3)
D6 = db3

for a in [D2, D4, D6]:
    norm = mpmath.norm(a)
    assert mpmath.almosteq(norm, mp.sqrt(_2))

def wavelet_coefficients(a):
    # TODO: is this just true for Daubechies wavelets?
    N = len(a)
    return np.array([(-1)**k*a[N-1-k] for k in range(N)])

# maps from genus (i.e. vanishing moments) to the scaling coefficients 
daubechies_wavelets = {
    1: D2,
    2: D4,
    3: D6,
}

Пример #33
0
def calc_ellipsoid_axes(coords, uvals, cell, probability=0.5, longest=True):
    """
    This method calculates the principal axes of an ellipsoid as list of two
    fractional coordinate triples.
    Many thanks to R. W. Grosse-Kunstleve and P. D. Adams
    for their great publication on the handling of atomic anisotropic displacement
    parameters:
    R. W. Grosse-Kunstleve, P. D. Adams, J Appl Crystallogr 2002, 35, 477–480.

    F = ... * exp ( -2π²[ h²(a*)²U11 + k²(b*)²U22 + ... + 2hka*b*U12 ] )

    SHELXL atom:
    Name type  x      y      z    occ     U11 U22 U33 U23 U13 U12
    F3    4    0.210835   0.104067   0.437922  21.00000   0.07243   0.03058 =
       0.03216  -0.01057  -0.01708   0.03014
    >>> import mpmath as mpm
    >>> cell = (10.5086, 20.9035, 20.5072, 90, 94.13, 90)
    >>> coords = [0.210835,   0.104067,   0.437922]
    >>> uvals = [0.07243, 0.03058, 0.03216, -0.01057, -0.01708, 0.03014]
    >>> l = calc_ellipsoid_axes(coords, uvals, cell, longest=True)
    >>> print(mpm.nstr(l))
    [[0.24765096, 0.11383281, 0.43064756], [0.17401904, 0.09430119, 0.44519644]]
    >>> calc_ellipsoid_axes(coords, uvals, cell, longest=False)
    [[[0.24765096, 0.11383281, 0.43064756], [0.218406, 0.09626142, 0.43746127], [0.21924358, 0.10514684, 0.44886868]], [[0.17401904, 0.09430119, 0.44519644], [0.203264, 0.11187258, 0.43838273], [0.20242642, 0.10298716, 0.42697532]]]
    >>> cell = (10.5086, 20.9035, 20.5072, 90, 94.13, 90)
    >>> coords = [0.210835,   0.104067,   0.437922]
    >>> uvals = [0.07243, -0.03058, 0.03216, -0.01057, -0.01708, 0.03014]
    >>> calc_ellipsoid_axes(coords, uvals, cell, longest=True)
    <BLANKLINE>
    Ellipsoid is non positive definite!
    <BLANKLINE>
    False

    >>> uvals = [0.07243, 0.03058, 0.03216, -0.01057, -0.01708]
    >>> calc_ellipsoid_axes(coords, uvals, cell, longest=False)
    Traceback (most recent call last):
    ...
    Exception: 6 Uij values have to be supplied!

    >>> cell = (10.5086, 20.9035, 90, 94.13, 90)
    >>> coords = [0.210835,   0.104067,   0.437922]
    >>> uvals = [0.07243, 0.03058, 0.03216, -0.01057, -0.01708, 0.03014]
    >>> calc_ellipsoid_axes(coords, uvals, cell, longest=True)
    Traceback (most recent call last):
    ...
    Exception: cell needs six parameters!

    :param coords: coordinates of the respective atom in fractional coordinates
    :type coords: list
    :param uvals: Uij valiues of the respective ellipsoid on fractional
                  basis like in cif and SHELXL format
    :type uvals: list
    :param cell: unit cell of the structure: a, b, c, alpha, beta, gamma
    :type cell:  list
    :param probability: thermal probability of the ellipsoid
    :type probability: float or int
    :param longest: not always the length is important. make to False to
                    get all three coordiantes of the ellipsoid axes.
    :type longest: boolean

    """
    from misc import A
    probability += 1
    # Uij is symmetric:
    if len(uvals) != 6:
        raise Exception('6 Uij values have to be supplied!')
    if len(cell) != 6:
        raise Exception('cell needs six parameters!')
    # orthogonalization matrix that transforms the fractional coordinates
    # with respect to a crystallographic basis system to coordinates
    # with respect to a Cartesian basis:
    A = A(cell).orthogonal_matrix
    Ucart = ufrac_to_ucart(A, cell, uvals)
    # print(Ucart)
    # E => eigenvalues, Q => eigenvectors:
    E, Q = mpm.eig(Ucart)
    # calculate vectors of ellipsoid axes  
    try:
        sqrt(E[0])
        sqrt(E[1])
        sqrt(E[2])
    except ValueError:
        print('\nEllipsoid is non positive definite!\n')
        return False
    v1 = mpm.matrix([Q[0, 0], Q[1, 0], Q[2, 0]])
    v2 = mpm.matrix([Q[0, 1], Q[1, 1], Q[2, 1]])
    v3 = mpm.matrix([Q[0, 2], Q[1, 2], Q[2, 2]])
    v1i = v1 * (-1)
    v2i = v2 * (-1)
    v3i = v3 * (-1)
    # multiply probability (usually 50%)
    e1 = sqrt(E[0]) * probability
    e2 = sqrt(E[1]) * probability
    e3 = sqrt(E[2]) * probability
    # scale axis vectors to eigenvalues 
    v1, v2, v3, v1i, v2i, v3i = v1 * e1, v2 * e2, v3 * e3, v1i * e1, v2i * e2, v3i * e3
    # find out which vector is the longest:
    length = mpm.norm(v1)
    v = 0
    if mpm.norm(v2) > length:
        length = mpm.norm(v2)
        v = 1
    elif mpm.norm(v3) > length:
        length = mpm.norm(v3)
        v = 2
    # move vectors back to atomic position
    atom = A * mpm.matrix(coords)
    v1, v1i = v1 + atom, v1i + atom
    v2, v2i = v2 + atom, v2i + atom
    v3, v3i = v3 + atom, v3i + atom
    # go back into fractional coordinates:
    a1 = cart_to_frac(v1, cell)
    a2 = cart_to_frac(v2, cell)
    a3 = cart_to_frac(v3, cell)
    a1i = cart_to_frac(v1i, cell)
    a2i = cart_to_frac(v2i, cell)
    a3i = cart_to_frac(v3i, cell)
    allvec = [[a1, a2, a3], [a1i, a2i, a3i]]
    if longest:
        # only the longest vector
        return [allvec[0][v], allvec[1][v]]
    else:
        # all vectors:
        return allvec
 def test_left_eigen_vec(self):
     self.assertTrue(mp.norm(v - v*mp.mp.matrix(P), 'inf') <= TOL)
Пример #35
0
# chebyshev approximation
start_2 = time.time()

sv_vector = mp.matrix(12, 2)
A_abs = mp.matrix(12)
for i in range(12):
    for j in range(12):
        A_abs[i, j] = abs(A[i, j])

for i in range(12):
    sv_vector[i, 0] = A_abs[i, i] - sum(A_abs[i, :])
    sv_vector[i, 1] = A_abs[i, i] - sum(A_abs[:, i])

s_min = min(max(sv_vector[:, 0]), max(sv_vector[:, 1]))
s_max = mp.sqrt(mp.norm(A, p=1) * mp.norm(A, p=10))
# S = mp.svd_r(A, compute_uv=False)
# delta = max(s_max, abs(1 - s_max))
m = 2
dim = 12
delta = s_min ** 2/ (s_max ** 2 + s_min ** 2)
# delta_2 = min(S) ** 2/ (max(S) ** 2 + min(S) ** 2)
# s_min, s_max = min(S), max(S)
interval = [-1, 1]
func = lambda x : mp.log(1 -  ((1 - 2 * delta) * x + 1) / 2)
coeffs = mp.chebyfit(func, interval, N=m)
# B = mp.eye(12) - A
B = 1/(s_max ** 2 + s_min ** 2) * A.T * A

def Han_algorithm(B, m, dim):
    """
Пример #36
0
    def run(self, **kwargs):
        """Run the microkinetic model. If recalculate is True then
        data which is re-loaded will be used as an initial guess; otherwise it
        will be assumed to be correct.

        :param recalculate: If True solve model again using previous results as initial guess
        :type recalculate: bool

        """

        for key in kwargs:
            setattr(self, key, kwargs[key])

        #ensure resolution has the proper dimensions
        if not hasattr(self.resolution, '__iter__'):
            self.resolution = [self.resolution] * len(self.descriptor_names)

        #set numerical representation
        if self.numerical_representation == 'mpmath':
            import mpmath as mp
            mp.mp.dps = self.decimal_precision + 25  #pad decimal precision
            self._math = mp
            self._log_imports += "\nfrom mpmath import mpf \n\n"
            self._kB = mp.mpf('8.617332478e-5')  #eV/K (from NIST)
            self._h = mp.mpf('4.135667516e-15')  #eV s (from NIST)
            self._mpfloat = mp.mpf
            self._matrix = mp.matrix
            self._Axb_solver = mp.lu_solve
            self._math.infnorm = lambda x: mp.norm(x, 'inf')
        elif self.numerical_representation in ['numpy', 'python']:
            self._log_imports += "\nfrom numpy import matrix \n\n"
            self._math = np
            self._math.infnorm = lambda x: np.linalg.norm(x, np.inf)
            self._mpfloat = float

            def matrixT(*args, **kwargs):
                array = np.array(args[0])
                while 1 in array.shape:
                    sum_idx = array.shape.index(1)
                    array = array.sum(sum_idx)
                return array.T

            self._matrix = matrixT

            def Axb_solver(A, b):
                try:
                    return np.linalg.solve(A, b.T)
                except np.linalg.linalg.LinAlgError:
                    raise ZeroDivisionError

            self._Axb_solver = Axb_solver
            if self.decimal_precision > 15:
                print('Warning: Max precision with numpy/python is 16 digits')
                self.decimal_precision = 15
        else:
            raise AttributeError(
                'Numerical representation must be mpmath, numpy, or python.')

        #set up interaction model
        if self.adsorbate_interaction_model == 'first_order':
            interaction_model = catmap.thermodynamics.FirstOrderInteractions(
                self)
            interaction_model.get_interaction_info()
            response_func = interaction_model.interaction_response_function
            if not callable(response_func):
                int_function = getattr(interaction_model,
                                       response_func + '_response')
                interaction_model.interaction_response_function = int_function
            self.thermodynamics.__dict__[
                'adsorbate_interactions'] = interaction_model

        elif self.adsorbate_interaction_model == 'second_order':
            interaction_model = catmap.thermodynamics.SecondOrderInteractions(
                self)
            interaction_model.get_interaction_info()
            response_func = interaction_model.interaction_response_function
            if not callable(response_func):
                int_function = getattr(interaction_model,
                                       response_func + '_response')
                interaction_model.interaction_response_function = int_function
            self.thermodynamics.__dict__[
                'adsorbate_interactions'] = interaction_model

        elif self.adsorbate_interaction_model in ['ideal', None]:
            self.thermodynamics.adsorbate_interactions = None
        else:
            raise AttributeError(
                'Invalid adsorbate_interaction_model specified.')

        self.compatibility_check()

        #determine whether or not to (re-)solve model
        has_all = True
        for v in self.output_variables:
            if not hasattr(self, v + '_map'):
                has_all = False

        if not hasattr(self, 'stdout'):
            #any re-loaded model will have stdout
            has_all = False

        if self._solved == self._token() and not getattr(
                self, 'recalculate', None):
            #Do not solve the same model twice
            has_all = True

        elif has_all and not getattr(self, 'recalculate', None):
            #All data has been loaded and no verification => solved.
            self._solved = self._token()
            self.log('input_success')

        else:
            ran_dsa = False  #When no map exists, run descriptor space analysis first
            if not getattr(self, 'coverage_map', None):
                #Make "volcano plot"
                if getattr(self, 'descriptor_ranges', None) and getattr(
                        self, 'resolution', None):
                    self.descriptor_space_analysis()
                    ran_dsa = True

            #Get rates at single points
            if getattr(self, 'descriptors', None):
                self.single_point_analysis(self.descriptors)
            #Get rates at multiple points
            if getattr(self, 'descriptor_values', None):
                self.multi_point_analysis()

            #If a map exists, run descriptor space analysis last (so that single-point guesses are
            #not discarded)
            if not ran_dsa and getattr(self, 'descriptor_ranges',
                                       None) and getattr(
                                           self, 'resolution', None):
                self.descriptor_space_analysis()

            #Save long attrs in data_file
            for attr in dir(self):
                if (not attr.startswith('_')
                        and not callable(getattr(self, attr))
                        and attr not in self._classes):
                    if (len(repr(getattr(self, attr))) >
                            self._max_log_line_length):
                        #line is too long for logfile -> put into pickle
                        self._pickle_attrs.append(attr)
            pickled_data = {}
            for attr in self._pickle_attrs:
                pickled_data[attr] = getattr(self, attr)
            pickle.dump(pickled_data, open(self.data_file, 'w'))

            #Make logfile
            log_txt = self._log_imports
            log_txt += self._header(exclude_outputs=self._pickle_attrs)
            self._stdout = '\n'.join(self._log_lines)
            log_txt += 'stdout = ' + '"' * 3 + self._stdout + '"' * 3
            #this construction means that self.stdout will only be set
            #for models which have been re-loaded.
            self._solved = self._token()
            if hasattr(self, 'log_file'):
                logfile = self.log_file
            else:
                name, suffix = self.setup_file.rsplit('.', 1)
                if suffix != 'log':
                    suffix = 'log'
                else:
                    suffix = 'out'
                logfile = '.'.join([name, suffix])

            f = open(logfile, 'w')
            f.write(log_txt)
            f.close()

            if getattr(self, 'create_standalone', None):
                self.make_standalone()
Пример #37
0
def sarkar_embedding(tree, root, **kwargs):
    ''' 
    Embed a tree in the Poincare disc using Sarkar's algorithm 
    from "Low Distortion Delaunay Embedding of Trees in Hyperbolic Plane.
        Args:
            tree (networkx.Graph) : The tree represented with int node labels.
                  Weighted trees should have the edge attribute "weight"
            root (int): The node to use as the root of the embedding 
        Keyword Args:
            weighted (bool): True if the tree is weighted (default True)
            tau (float): the scaling factor for distances. 
                        By default it is calculated based on statistics of the tree.
            epsilon (float): parameter >0 controlling distortion bound (default 0.1).
            precision (int): number of bits of precision to use.
                            By default it is calculated based on tau and epsilon.
        Returns:
            size N x 2 mpmath.matrix containing the coordinates of embedded nodes
    '''
    eps = kwargs.get("epsilon",0.1)
    weighted = kwargs.get("weighted", True)
    tau = kwargs.get("tau")
    max_deg = max(tree.degree)[1]

    if tau is None:
        tau = (1+eps)/eps * mpm.log(2*max_deg/ mpm.pi)
    prc = kwargs.get("precision")
    if prc is None:
        prc = _embedding_precision(tree,root,eps)
    mpm.mp.dps = prc
    
    n = tree.order()
    emb = mpm.zeros(n,2)
    place = []

    # place the children of root
    for i, v in enumerate(tree[root]):
        if weighted: 
            r = mpm.tanh( tau*tree[root][v]["weight"])
        else:
            r = mpm.tanh(tau)
        theta = 2*i*mpm.pi / tree.degree[root]
        emb[v,0] = r*mpm.cos(theta)
        emb[v,1] = r*mpm.sin(theta)
        place.append((root,v))
    
    # TODO parallelize this
    while place:
        u, v = place.pop() # u is the parent of v
        p, x = emb[u,:], emb[v,:]
        rp = poincare_reflect0(x, p, precision=prc)
        arg = mpm.acos(rp[0]/mpm.norm(rp))
        if rp[1] < 0:
            arg = 2*mpm.pi - arg
            
        theta = 2*mpm.pi / tree.degree[v]
        i=0
        for w in tree[v]:
            if w == u: continue
            i+=1
            if weighted:
                r = mpm.tanh(tau*tree[v][w]["weight"])
            else:
                r = mpm.tanh(tau)
            w_emb = r * mpm.matrix([mpm.cos(arg+theta*i),mpm.sin(arg+theta*i)]).T
            w_emb = poincare_reflect0(x, w_emb, precision=prc)
            emb[w,:] = w_emb
            place.append((v,w))
    return emb
def characterize_solution(ss, _matrix):
    residues = residues_calc(ss, _matrix)
    sae_residues = norm(residues, 1)
    sse_residues = norm(residues, 2)
    return sae_residues, sse_residues
Пример #39
0
def lyapunov_exponent(mathcalA, varphi, periodic_points, alg='basic', norm=2):

    k = max([len(word) for word in periodic_points])

    if alg == 'basic':
        approx_basic = []

        for n in range(1, k + 1):
            integral = sum([
                mpmath.log(mpmath.norm(cocycle(word, mathcalA), p=norm)) *
                weight(word, varphi) for word in periodic_points
                if len(word) == n
            ])
            normalization = sum([
                weight(word, varphi) for word in periodic_points
                if len(word) == n
            ])
            approx_basic.append(integral / (n * normalization))

        return approx_basic

    elif alg == 'pollicott':
        #Compute the operator trace for each periodic point
        op_trace = {
            word: operator_trace(cocycle(word, mathcalA), 0)[0]
            for word in periodic_points
        }
        op_trace_der = {
            word: operator_trace(cocycle(word, mathcalA), 0)[1]
            for word in periodic_points
        }

        #Compute traces for products of transfer operator put in dictionary indexed by power
        trace = [
            sum([(op_trace[word] * weight(word, varphi))
                 for word in periodic_points if len(word) == n])
            for n in range(1, k + 1)
        ]
        trace_der = [
            sum([(op_trace_der[word] * weight(word, varphi))
                 for word in periodic_points if len(word) == n])
            for n in range(1, k + 1)
        ]

        coefficients = [mpmath.mpf(1)]

        coefficients_der = [mpmath.mpf(0)]

        for n in range(1, k + 1):
            M = mpmath.matrix(n)
            Der_M = mpmath.matrix(n)
            for i in range(0, n):
                for j in range(0, n):
                    if j > i + 1:
                        M[i, j] = 0
                        Der_M[i, j] = 0
                    elif j == i + 1:
                        M[i, j] = n - j
                        Der_M[i, j] = 0
                    else:
                        M[i, j] = trace[i - j]
                        Der_M[i, j] = trace_der[i - j]

            coefficients.append((((-1)**n) / mpmath.fac(n)) * mpmath.det(M))

            if n == 1:
                coefficients_der.append(
                    (((-1)**n) / mpmath.fac(n)) * trace_der[0])
            else:
                #Use Jacobi's formula to compute derivative of coefficients
                coefficients_der.append(
                    (((-1)**n) / mpmath.fac(n)) * trace_of(adj(M) * Der_M))

        approximation = []

        for n in range(1, k + 1):
            approximation.append(
                sum([coefficients_der[m] for m in range(1, n + 1)]) /
                sum([m * coefficients[m] for m in range(1, n + 1)]))

        return approximation

    else:
        return "Choices of algorithm are 'basic' and 'pollicott'"