Ejemplo n.º 1
0
def operator_trace(A, s):
    d = A.rows
    eigenvalues = sorted(mpmath.mp.eig(A, left=False, right=False),
                         key=abs,
                         reverse=True)
    denominator = mpmath.nprod(
        lambda j: (1 - (eigenvalues[int(j) - 1] / eigenvalues[0])), [2, d])

    return (mpmath.chop((eigenvalues[0]**s) / denominator),
            mpmath.chop((mpmath.log(eigenvalues[0]) * (eigenvalues[0]**s)) /
                        denominator))
Ejemplo n.º 2
0
def select():
    global lastop, a, listindex, argindex, theFile
    if lastop == 0:
        print(
            'Parse Error: SELECT. came before corresponding EXP. or LOG. at instruction '
            + str(pointer))
        print(greporig(pointer))
        left = val
        middle = a[listindex]
        right = val
        if listindex > 0:
            left = a[listindex - 1]
        if listindex < len(a) - 1:
            right = a[listindex + 1]
        print('Nearby Tape Values: ' + mpmath.nstr(left) + ',' +
              mpmath.nstr(middle) + ',' + mpmath.nstr(right))
        sys.exit()
    elif lastop == 1:
        if a[argindex] != 0 or mpmath.im(
                a[listindex]) != 0 or a[listindex] >= 0:
            try:
                a[argindex] = mpmath.power(a[argindex], a[listindex])
            except OverflowError:
                print(
                    'Number too large to represent. Try increasing precision or moving default tape value closer to 1.'
                )
                print(greporig(pointer))
            a[argindex] = mpmath.chop(a[argindex], tol)
        else:
            a[argindex] = mpmath.mpc('inf')
    else:
        if a[listindex] == 1:
            print('Tried to take a log base one at instruction ' +
                  str(pointer))
            print(greporig(pointer))
            left = val
            middle = a[listindex]
            right = val
            if listindex > 0:
                left = a[listindex - 1]
            if listindex < len(a) - 1:
                right = a[listindex + 1]
            print('Nearby Tape Values: ' + mpmath.nstr(left) + ',' +
                  mpmath.nstr(middle) + ',' + mpmath.nstr(right))
            sys.exit()
        a[argindex] = mpmath.log(a[argindex], a[listindex])
        #patch up nans when arg is infinite, since we usually want zero for the real part then
        if mpmath.isinf(mpmath.im(a[argindex])) and mpmath.isnan(
                mpmath.re(a[argindex])):
            a[argindex] = mpmath.mpc(0, mpmath.im(a[argindex]))
        a[argindex] = mpmath.chop(a[argindex], tol)
    oparg = 0
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
 def __call__(self, Xi, Xj, ni, nj, hyper_deriv=None, symmetric=False):
     """Evaluate the covariance between points `Xi` and `Xj` with derivative order `ni`, `nj`.
     
     Parameters
     ----------
     Xi : :py:class:`Matrix` or other Array-like, (`M`, `D`)
         `M` inputs with dimension `D`.
     Xj : :py:class:`Matrix` or other Array-like, (`M`, `D`)
         `M` inputs with dimension `D`.
     ni : :py:class:`Matrix` or other Array-like, (`M`, `D`)
         `M` derivative orders for set `i`.
     nj : :py:class:`Matrix` or other Array-like, (`M`, `D`)
         `M` derivative orders for set `j`.
     hyper_deriv : Non-negative int or None, optional
         The index of the hyperparameter to compute the first derivative
         with respect to. If None, no derivatives are taken. Hyperparameter
         derivatives are not supported at this point. Default is None.
     symmetric : bool, optional
         Whether or not the input `Xi`, `Xj` are from a symmetric matrix.
         Default is False.
     
     Returns
     -------
     Kij : :py:class:`Array`, (`M`,)
         Covariances for each of the `M` `Xi`, `Xj` pairs.
     
     Raises
     ------
     NotImplementedError
         If the `hyper_deriv` keyword is not None.
     """
     if hyper_deriv is not None:
         raise NotImplementedError("Hyperparameter derivatives have not been implemented!")
     n_cat = scipy.asarray(scipy.concatenate((ni, nj), axis=1), dtype=int)
     X_cat = scipy.asarray(scipy.concatenate((Xi, Xj), axis=1), dtype=float)
     n_cat_unique = unique_rows(n_cat)
     k = scipy.zeros(Xi.shape[0], dtype=float)
     # Loop over unique derivative patterns:
     if self.num_proc > 1:
         pool = multiprocessing.Pool(processes=self.num_proc)
     for n_cat_state in n_cat_unique:
         idxs = scipy.where(scipy.asarray((n_cat == n_cat_state).all(axis=1)).squeeze())[0]
         if (n_cat_state == 0).all():
             k[idxs] = self.cov_func(Xi[idxs, :], Xj[idxs, :], *self.params)
         else:
             if self.num_proc > 1 and len(idxs) > 1:
                 k[idxs] = scipy.asarray(
                     pool.map(_ArbitraryKernelEval(self, n_cat_state), X_cat[idxs, :]),
                     dtype=float
                 )
             else:
                 for idx in idxs:
                     k[idx] = mpmath.chop(mpmath.diff(self._mask_cov_func,
                                                      X_cat[idx, :],
                                                      n=n_cat_state,
                                                      singular=True))
     
     if self.num_proc > 0:
         pool.close()
     return k
Ejemplo n.º 5
0
def test_msvd():
    output("""\
    msvd_:{[b;x]
        $[3<>count usv:.qml.msvd x;::;
          not (.qml.mdim[u:usv 0]~2#d 0) and (.qml.mdim[v:usv 2]~2#d 1) and
            .qml.mdim[s:usv 1]~d:.qml.mdim x;::;
          not mortho[u] and mortho[v] and
            all[0<=f:.qml.mdiag s] and mzero s _'til d 0;::;
          not mzero x-.qml.mm[u] .qml.mm[s] flip v;::;
          b;1b;(p*/:m#/:u;m#m#/:s;
              (p:(f>.qml.eps*f[0]*max d)*1-2*0>m#u 0)*/:(m:min d)#/:v)]};""")

    for A in subjects:
        U, S, V = map(mp.matrix, mp.svd(mp.matrix(A)))
        m = min(A.rows, A.cols)
        p = mp.diag([mp.sign(s * u) for s, u in zip(mp.chop(S), U[0, :])])
        U *= p
        S = mp.diag(S)
        V = V.T * p
        test("msvd_[0b", A, (U, S, V))

    reps(250)
    for Aq in large_subjects:
        test("msvd_[1b", qstr(Aq), qstr("1b"))
    reps(10000)
Ejemplo n.º 6
0
def eigen_energy(lattice_depth, lattice_ratio):
    """Calculates the ground state energy per particle of an ideal Bose gas
    within a multi-rods structure modeled through a Kronig-Penney potential.

    :param lattice_depth: The magnitude of the external potential.
    :param lattice_ratio: The relation width/separation of the potential
                            barriers.
    :return: The ground state energy per boson of the system.
    """
    v0 = lattice_depth
    r = lattice_ratio

    try:
        # First find a root with machine precision.
        func = partial(energy_relation, v0, r, momentum=0)
        root = brentq(func, 0, min(v0, (1 + r) ** 2 * math.pi ** 2))

        # Use arbitrary precision.
        mp_solver = partial(mp.findroot, verify=False)

    except OverflowError:
        # Use an arbitrary precision, root-bracketing method.
        root = (0, min(v0, (1 + r) ** 2 * mp.pi ** 2))
        mp_solver = partial(mp.findroot, solver='illinois', verify=False)

    func = partial(energy_relation, v0, r, momentum=0, ctx=mp)
    root = mp_solver(func, root)

    return mp.chop(root)
Ejemplo n.º 7
0
    def set_polar_coordinate(self):
        from mpmath import asin, cos, chop

        self.phi = asin(self.z / self.norm)

        sintheta = chop(self.y / (self.norm * cos(self.phi)))
        theta = asin(sintheta)

        self.theta = theta
Ejemplo n.º 8
0
 def __call__(self, X_cat_row):
     """Return the covariance function of object evaluated at the given `X_cat_row`.
     
     Parameters
     ----------
     X_cat_row : Array-like, (2,)
         The `Xi` and `Xj` point to evaluate at.
     """
     return mpmath.chop(mpmath.diff(self.obj._mask_cov_func,
                                    X_cat_row,
                                    n=self.n_cat_state,
                                    singular=True))
Ejemplo n.º 9
0
    def convertUnitList(self, other):
        if not isinstance(other, list):
            raise ValueError('convertUnitList expects a list argument')

        result = []

        nonIntegral = False

        for i in range(1, len(other)):
            conversion = g.unitConversionMatrix[(other[i - 1].getUnitName(),
                                                 other[i].getUnitName())]

            if conversion != floor(conversion):
                nonIntegral = True

        if nonIntegral:
            source = self

            for count, measurement in enumerate(other):
                with extradps(2):
                    conversion = source.convertValue(measurement)

                    if count < len(other) - 1:
                        result.append(
                            RPNMeasurement(floor(conversion),
                                           measurement.units))
                        source = RPNMeasurement(chop(frac(conversion)),
                                                measurement.units)
                    else:
                        result.append(
                            RPNMeasurement(conversion, measurement.units))

            return result
        else:
            source = self.convert(other[-2])

            with extradps(2):
                result.append(source.getModulo(other[-2]).convert(other[-1]))

            source = source.subtract(result[-1])

            for i in range(len(other) - 2, 0, -1):
                source = source.convert(other[i - 1])

                with extradps(2):
                    result.append(
                        source.getModulo(other[i - 1]).convert(other[i]))

                source = source.subtract(result[-1])

            result.append(source)

            return result[::-1]
Ejemplo n.º 10
0
 def get_feature_importance(self, x0):
     # Returns the feature importance for a prediction at x0
     importance_list = [self.eps for _ in range(self.dim_x)]
     for k in range(len(self.terms_list)):
         g_k, v_k, w_k = self.terms_list[k]
         x_k = np.dot(v_k, x0) / (np.sqrt(self.dim_x) * np.linalg.norm(v_k))
         if x_k > 0:
             coef_k = mpmath.chop(mpmath.taylor(g_k.math_expr, x_k, 1))
             for n in range(self.dim_x):
                 importance_list[n] += sympify(
                     w_k * coef_k[1] * v_k[n] / (np.sqrt(self.dim_x) * np.linalg.norm(v_k)))
     return importance_list
Ejemplo n.º 11
0
def collocation(n, w):
    t = sorted(
        np.squeeze(
            np.asarray(
                np.roots(chop(taylor(lambda x: chebyt(n, x), 0,
                                     n))[::-1]))))  # Корни многочлена Чебышева

    A = np.eye(n)
    B = np.ones((n, 1))
    for i in range(n):
        B[i] = f(t[i])
        for j in range(n):
            A[i][j] = sympy.lambdify(x, Lu(w[j]))(t[i])
    C = np.linalg.solve(A, B)
    mu = infnorm(A) * infnorm(np.linalg.inv(A))
    return A, B, C, mu
Ejemplo n.º 12
0
 def get_taylor(self, x0, approx_order):
     # Returns the Taylor expansion around x0 of order approx_order for our model
     expression = 0
     symbol_list = [Symbol("X" + str(k)) for k in range(self.dim_x)]
     for k in range(len(self.terms_list)):
         g_k, v_k, w_k = self.terms_list[k]
         x_k = np.dot(v_k, x0) / (np.sqrt(self.dim_x) * np.linalg.norm(v_k))
         if x_k > 0:
             P_k = 0
             for n in range(self.dim_x):
                 P_k += v_k[n] * symbol_list[n] / (np.sqrt(self.dim_x) * np.linalg.norm(v_k))
             coef_k = mpmath.chop(mpmath.taylor(g_k.math_expr, x_k, approx_order))
             for n in range(len(coef_k)):
                 if n > 0:
                     expression += w_k * coef_k[n] * (P_k - x_k) ** n
                 else:
                     expression += w_k * coef_k[n]
     return expression
Ejemplo n.º 13
0
def convertToNonintegerBase(num, base):
    epsilon = power(10, -(mp.dps - 3))
    minPlace = -(floor(mp.dps / log(base)))

    output = ''
    integer = ''

    remaining = num

    # find starting place
    place = int(floor(log(remaining, base)))

    while remaining > epsilon:
        if place < minPlace:
            break

        if place == -1:
            integer = output
            output = ''

        placeValue = power(base, place)

        value = fdiv(remaining, placeValue)

        value = fmul(value, power(10, mp.dps - 3))
        value = nint(value)
        value = fdiv(value, power(10, mp.dps - 3))

        value = floor(value)
        remaining = chop(fsub(remaining, fmul(placeValue, value)))

        output += str(value)[:-2]

        place -= 1

    if place >= 0:
        integer = output + '0' * (place + 1)
        output = ''

    if integer == '':
        return output, ''

    return integer, output
Ejemplo n.º 14
0
    def _compute_dy_dtau(self, tau, b, r2l2):
        r"""Evaluate the derivative of the inner argument of the Matern kernel.
        
        Uses Faa di Bruno's formula to take the derivative of
        
        .. math::
        
            y = \sqrt{2 \nu \sum_i(\tau_i^2 / l_i^2)}
        
        Parameters
        ----------
        tau : :py:class:`Matrix`, (`M`, `D`)
            `M` inputs with dimension `D`.
        b : :py:class:`Array`, (`P`,)
            Block specifying derivatives to be evaluated.
        r2l2 : :py:class:`Array`, (`M`,)
            Precomputed anisotropically scaled distance.
        
        Returns
        -------
        dy_dtau: :py:class:`Array`, (`M`,)
            Specified derivative at specified locations.
        """
        deriv_partitions = generate_set_partitions(b)
        dy_dtau = scipy.zeros_like(r2l2, dtype=float)
        non_zero_idxs = (r2l2 != 0)
        for p in deriv_partitions:
            dy_dtau[non_zero_idxs] += self._compute_dy_dtau_on_partition(
                tau[non_zero_idxs], p, r2l2[non_zero_idxs])

        # Case at tau=0 is handled with mpmath for now.
        # TODO: This is painfully slow! Figure out how to do this analytically!
        derivs = scipy.zeros(tau.shape[1], dtype=int)
        for d in b:
            derivs[d] += 1
        dy_dtau[~non_zero_idxs] = mpmath.chop(
            mpmath.diff(self._compute_y_wrapper,
                        scipy.zeros(tau.shape[1], dtype=float),
                        n=derivs,
                        singular=True,
                        direction=1))
        return dy_dtau
Ejemplo n.º 15
0
def drawbox():
    global a, listindex, centerx, centery, pixdict, z, red, green, blue, canv, verbose
    if verbose:
        print('Outputting: ' + mpmath.nstr(mpmath.chop(a[listindex])))
    if mpmath.isnan(a[listindex]) or mpmath.isinf(a[listindex]):
        return
    try:
        x = int(mpmath.nint(mpmath.re(a[listindex]))) + centerx
        y = int(mpmath.nint(mpmath.im(a[listindex]))) + centery
        if (x, y) in pixdict:
            canv.delete(pixdict[(x, y)])
            del pixdict[(x, y)]
        pixdict[(x, y)] = canv.create_rectangle(x * z - z + 1,
                                                y * z - z + 1,
                                                x * z + 1,
                                                y * z + 1,
                                                fill=rgb(red, green, blue),
                                                width=0)
    except OverflowError:
        #the number is so huge it's not going to be displayed anyway, so just suppress the error and move on
        pass
Ejemplo n.º 16
0
    def run_ESN(self,
                input_dat=None,
                around=0,
                order=None,
                time=200,
                init='zero',
                force_start=None):
        """
        Runs the resevoir computer for a given number of time steps, with or
        without input data.

        Args:
            self (simple_ESN object): the reservoir computer object.
            input_dat (timexK array or None): the input data. T is the temporal
            length of the data, K is the number of inputs.
            around (array or float): provides coefficients to neuron activation
                functions.
            order (str,int): 'power' gives a Taylor expansion with coefficients
                given by around, 'relu' gives a rectified linear activation
                function with input scaling around, an integer gives the Taylor
                expansion of tanh about around, while any non integer,non-string
                value gives the standard tanh activation function.
            time (int): number of steps to run the reservoir.
            init (str): 'last' starts the run at the last iteration of the
                training run. 'zero' starts the run with all neurons set to
                zero, and any other value starts the run with neuron
                displacements randomize.
            force_start (anything): if force_start is not None, starts output
                at last value of the teacher data.
        Yields:
            self.states (timexN array): states of the reservoir during the run.
            self.outputs (timexL array): reservoir outputs for run.
        """
        if input_dat is None:
            input_dat = np.zeros([time, self.K])
        if init == 'last':
            x = self.M[-1, :]
        elif init == 'zero':
            x = np.zeros([self.N])
        else:
            x = np.random.random_sample([self.N])
        if order == 'power':
            coeffs = np.array(around)
            update = aux.taylor_exp
        elif order == 'relu':
            if around == 0:
                coeffs = 1
            else:
                coeffs = around
            update = aux.ReLU
        elif isinstance(order, int) is True:
            mpm.dps = 16
            mpm.pretty = True
            coeffs = np.array(mpm.chop(mpm.taylor(mpm.tanh, around, order)),
                              dtype=np.float64)
            update = aux.taylor_exp
        else:
            coeffs = None
            update = np.tanh
        if force_start is not None:
            y = force_start  #should be last time step of teacher
        else:
            y = np.zeros([self.L])
        a = self.a

        bias = self.bias

        states = np.zeros([time, self.N])
        outputs = np.zeros([time, self.L])

        for t in range(0, time):
            u = input_dat[t, :]
            x = (1 - a) * x + a * update(
                np.dot(self.W, x) + np.dot(self.W_in, u) +
                np.dot(self.W_fb, y) + bias, coeffs)
            y = np.dot(self.W_out, x)

            states[t, :] = x
            outputs[t, :] = y
        self.input = input_dat
        self.states = states
        self.outputs = outputs
        return states
Ejemplo n.º 17
0
    def _compute_dk_dy(self, y, n):
        r"""Evaluate the derivative of the outer form of the Matern kernel.
        
        Uses the general Leibniz rule to compute the n-th derivative of:
        
        .. math::
        
            f(y) = \frac{2^{1-\nu}}{\Gamma(\nu)} y^\nu K_\nu(y)
        
        Notice that this is very poorly-behaved at :math:`x=0`. There, the
        value is approximated using :py:func:`mpmath.diff` with the `singular`
        keyword. This is rather slow, so if you require a fixed value of `nu`
        you may wish to consider implementing the appropriate kernel separately.
        
        Parameters
        ----------
        y : :py:class:`Array`, (`M`,)
            `M` inputs to evaluate at.
        n : non-negative scalar int.
            Order of derivative to compute.
        
        Returns
        -------
        dk_dy : :py:class:`Array`, (`M`,)
            Specified derivative at specified locations.
        """
        warnings.warn(
            "The Matern kernel has not been verified for derivatives. Consider using MaternKernelArb."
        )

        dk_dy = scipy.zeros_like(y, dtype=float)
        non_zero_idxs = (y != 0)
        for k in xrange(0, n + 1):
            dk_dy[non_zero_idxs] += (
                scipy.special.binom(n, k) *
                scipy.special.poch(1 - k + self.nu, k) *
                (y[non_zero_idxs])**(-k + self.nu) *
                scipy.special.kvp(self.nu, y[non_zero_idxs], n=n - k))

        # Handle the cases at y=0.
        # Compute the appropriate value using mpmath's arbitrary precision
        # arithmetic. This is potentially slow, but seems to behave pretty
        # well. In cases where the value should be infinite, very large
        # (but still finite) floats are returned with the appropriate sign.
        if n >= 2 * self.nu:
            warnings.warn("n >= 2*nu can yield inaccurate results.",
                          RuntimeWarning)

        # Use John Wright's expression for n < 2 * nu:
        if n < 2.0 * self.nu:
            if n % 2 == 1:
                dk_dy[~non_zero_idxs] = 0.0
            else:
                m = n / 2.0
                dk_dy[~non_zero_idxs] = ((-1.0)**m * 2.0**(self.nu - 1.0 - n) *
                                         scipy.special.gamma(self.nu - m) *
                                         scipy.misc.factorial(n) /
                                         scipy.misc.factorial(m))
        else:
            # Fall back to mpmath to handle n >= 2 * nu:
            core_expr = lambda x: x**self.nu * mpmath.besselk(self.nu, x)
            deriv = mpmath.chop(
                mpmath.diff(core_expr, 0, n=n, singular=True, direction=1))
            dk_dy[~non_zero_idxs] = deriv

        dk_dy *= 2.0**(1 - self.nu) / (scipy.special.gamma(self.nu))

        return dk_dy
Ejemplo n.º 18
0
def solveCubicPolynomial( a, b, c, d ):
    # pylint: disable=invalid-name
    '''
    This function applies the cubic formula to solve a polynomial
    with coefficients of a, b, c and d.
    '''
    if mp.dps < 50:
        mp.dps = 50

    if a == 0:
        return solveQuadraticPolynomial( b, c, d )

    f = fdiv( fsub( fdiv( fmul( 3, c ), a ), fdiv( power( b, 2 ), power( a, 2 ) ) ), 3 )

    g = fdiv( fadd( fsub( fdiv( fmul( 2, power( b, 3 ) ), power( a, 3 ) ),
                          fdiv( fprod( [ 9, b, c ] ), power( a, 2 ) ) ),
                    fdiv( fmul( 27, d ), a ) ), 27 )
    h = fadd( fdiv( power( g, 2 ), 4 ), fdiv( power( f, 3 ), 27 ) )

    # all three roots are the same
    if h == 0:
        x1 = fneg( root( fdiv( d, a ), 3 ) )
        x2 = x1
        x3 = x2
    # two imaginary and one real root
    elif h > 0:
        r = fadd( fneg( fdiv( g, 2 ) ), sqrt( h ) )

        if r < 0:
            s = fneg( root( fneg( r ), 3 ) )
        else:
            s = root( r, 3 )

        t = fsub( fneg( fdiv( g, 2 ) ), sqrt( h ) )

        if t < 0:
            u = fneg( root( fneg( t ), 3 ) )
        else:
            u = root( t, 3 )

        x1 = fsub( fadd( s, u ), fdiv( b, fmul( 3, a ) ) )

        real = fsub( fdiv( fneg( fadd( s, u ) ), 2 ), fdiv( b, fmul( 3, a ) ) )
        imaginary = fdiv( fmul( fsub( s, u ), sqrt( 3 ) ), 2 )

        x2 = mpc( real, imaginary )
        x3 = mpc( real, fneg( imaginary ) )
    # all real roots
    else:
        j = sqrt( fsub( fdiv( power( g, 2 ), 4 ), h ) )
        k = acos( fneg( fdiv( g, fmul( 2, j ) ) ) )

        if j < 0:
            l = fneg( root( fneg( j ), 3 ) )
        else:
            l = root( j, 3 )

        m = cos( fdiv( k, 3 ) )
        n = fmul( sqrt( 3 ), sin( fdiv( k, 3 ) ) )
        p = fneg( fdiv( b, fmul( 3, a ) ) )

        x1 = fsub( fmul( fmul( 2, l ), cos( fdiv( k, 3 ) ) ), fdiv( b, fmul( 3, a ) ) )
        x2 = fadd( fmul( fneg( l ), fadd( m, n ) ), p )
        x3 = fadd( fmul( fneg( l ), fsub( m, n ) ), p )

    return [ chop( x1 ), chop( x2 ), chop( x3 ) ]
Ejemplo n.º 19
0
    def train_ESN(self,
                  input_dat=None,
                  teacher=None,
                  around=0,
                  order=None,
                  washout=100,
                  noise=None,
                  bias=0,
                  mp=True,
                  B=0):
        """
        Single shot training of a simple_ESN object. Generates W_out.

        Args:
            self (simple_ESN object): the reservoir computer object.
            input_dat (TxK array): the training input data. T is the temporal
                length of the data, K is the number of inputs.
            teacher (TxL array): the training output ("teacher") data. T is the
                temporal length of the data, L is the number of outputs.
            around (array or float): provides coefficients to neuron activation
                functions.
            order (str,int): 'power' gives a Taylor expansion with coefficients
                given by around, 'relu' gives a rectified linear activation
                function with input scaling around, an integer gives the Taylor
                expansion of tanh about around, while any non integer,
                non-string value gives the standard tanh activation function.
            washout (int): number of discarded initial transient steps.
            noise (float): arbitrary noise added to each training update step.
            bias (float): bias added to each update step.
            mp (Boolean True/False): True for Moore-Penrose pseudoinverse,
                False for ridge regression.
            B (float): ridge regression parameter.
        Yields:
            self.W_out (LxN array): trained simple_ESN output weights.
        """
        time = teacher.shape[0]  #(time,L)
        if order == 'power':
            coeffs = np.array(around)
            update = aux.taylor_exp
        elif order == 'relu':
            if around == 0:
                coeffs = 1
            else:
                coeffs = around
            update = aux.ReLU
        elif isinstance(order, int) is True:
            mpm.dps = 16
            mpm.pretty = True
            coeffs = np.array(mpm.chop(mpm.taylor(mpm.tanh, around, order)),
                              dtype=np.float64)
            update = aux.taylor_exp
        else:
            coeffs = None
            update = np.tanh
        M = np.zeros([time - washout, self.N])  #state collecting matrix
        T = np.zeros([time - washout, self.L])  #target outputs
        x = np.zeros([self.N])
        y = np.zeros([self.L])

        a = self.a
        self.bias = bias
        for t in range(0, time):
            u = input_dat[t, :]
            if noise is not None:
                v = rn.uniform(-noise, noise)
            else:
                v = 0
            x = (1 - a) * x + a * update(
                np.dot(self.W, x) + np.dot(self.W_in, u) +
                np.dot(self.W_fb, y) + v + bias, coeffs)
            if t >= washout:
                k = t - washout
                M[k, :] = x  #just use internal states for now
                T[k, :] = teacher[t, :]
            y = teacher[t, :]

        #Set output weights
        self.M = M
        self.T = T
        if mp is True:  #Moore-Penrose pseudoinverse
            W_out = np.dot(np.linalg.pinv(M), T)
            W_out = np.transpose(W_out)
        else:  #Ridge Regression
            sq = np.dot(np.transpose(M), M)
            inv = np.linalg.inv(sq + B * np.identity(sq.shape[0]))
            W_out = np.dot(np.dot(np.transpose(T), M), inv)
        self.W_out = W_out
        return W_out
Ejemplo n.º 20
0
def solveQuarticPolynomialOperator( _a, _b, _c, _d, _e ):
    # pylint: disable=invalid-name
    '''
    This function applies the quartic formula to solve a polynomial
    with coefficients of a, b, c, d, and e.
    '''
    if mp.dps < 50:
        mp.dps = 50

    # maybe it's really an order-3 polynomial
    if _a == 0:
        return solveCubicPolynomial( _b, _c, _d, _e )

    # degenerate case, just return the two real and two imaginary 4th roots of the
    # constant term divided by the 4th root of a
    if _b == 0 and _c == 0 and _d == 0:
        e = fdiv( _e, _a )

        f = root( _a, 4 )

        x1 = fdiv( root( fneg( e ), 4 ), f )
        x2 = fdiv( fneg( root( fneg( e ), 4 ) ), f )
        x3 = fdiv( mpc( 0, root( fneg( e ), 4 ) ), f )
        x4 = fdiv( mpc( 0, fneg( root( fneg( e ), 4 ) ) ), f )

        return [ x1, x2, x3, x4 ]

    # otherwise we have a regular quartic to solve
    b = fdiv( _b, _a )
    c = fdiv( _c, _a )
    d = fdiv( _d, _a )
    e = fdiv( _e, _a )

    # we turn the equation into a cubic that we can solve
    f = fsub( c, fdiv( fmul( 3, power( b, 2 ) ), 8 ) )
    g = fsum( [ d, fdiv( power( b, 3 ), 8 ), fneg( fdiv( fmul( b, c ), 2 ) ) ] )
    h = fsum( [ e, fneg( fdiv( fmul( 3, power( b, 4 ) ), 256 ) ),
                fmul( power( b, 2 ), fdiv( c, 16 ) ), fneg( fdiv( fmul( b, d ), 4 ) ) ] )

    roots = solveCubicPolynomial( 1, fdiv( f, 2 ), fdiv( fsub( power( f, 2 ), fmul( 4, h ) ), 16 ),
                                  fneg( fdiv( power( g, 2 ), 64 ) ) )
    y1 = roots[ 0 ]
    y2 = roots[ 1 ]
    y3 = roots[ 2 ]

    # pick two non-zero roots, if there are two imaginary roots, use them
    if y1 == 0:
        root1 = y2
        root2 = y3
    elif y2 == 0:
        root1 = y1
        root2 = y3
    elif y3 == 0:
        root1 = y1
        root2 = y2
    elif im( y1 ) != 0:
        root1 = y1

        if im( y2 ) != 0:
            root2 = y2
        else:
            root2 = y3
    else:
        root1 = y2
        root2 = y3

    # more variables...
    p = sqrt( root1 )
    q = sqrt( root2 )
    r = fdiv( fneg( g ), fprod( [ 8, p, q ] ) )
    s = fneg( fdiv( b, 4 ) )

    # put together the 4 roots
    x1 = fsum( [ p, q, r, s ] )
    x2 = fsum( [ p, fneg( q ), fneg( r ), s ] )
    x3 = fsum( [ fneg( p ), q, fneg( r ), s ] )
    x4 = fsum( [ fneg( p ), fneg( q ), r, s ] )

    return [ chop( x1 ), chop( x2 ), chop( x3 ), chop( x4 ) ]