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))
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
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)
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
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)
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)
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
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))
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]
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
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
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
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
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
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
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
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
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 ) ]
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
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 ) ]