def calculate_rst(b_minus, b_plus, a_minus, a_plus, a_m, a0=np.ones(1), d=1, p=0, r_e=0): """Calculate the coefficient of the rst""" perturbation = P.polypow(zero(1), p) s2, r0 = solve_diophantine(P.polymul(perturbation, a_minus), P.polymul(delay(d), b_minus), P.polymul(a_m, a0)) b_m_plus, _ = solve_diophantine(P.polymul(delay(d), b_minus), P.polypow(zero(1), r_e + 1), a_m) t0 = P.polymul(a0, b_m_plus) r = P.polymul(r0, a_plus) s = P.polymul(s2, P.polymul(b_plus, perturbation)) t = P.polymul(t0, a_plus) print("R = ", ", ".join(map(str, r))) print("S = ", ", ".join(map(str, s))) print("T = ", ", ".join(map(str, t))) return r, s, t
def d2d(b, a, T): nb = len(b) na = len(a) b_new = _polytustin(b, T) a_new = _polytustin(a, T) if nb > na: a_new = polymul(a_new, polypow([1, (T - 1) / (T + 1)], nb - na)) elif na > nb: b_new = polymul(b_new, polypow([1, (T - 1) / (T + 1)], na - nb)) return b_new / a_new[0], a_new / a_new[0]
def _polytustin(a, T): n = len(a) if sum(a[1:]) == 0: return a a_new = 0 num = [(T - 1) / (T + 1), 1] den = [1, (T - 1) / (T + 1)] for i in range(n): pnum = polypow(num, i) pden = polypow(den, n - 1 - i) a_new = polyadd(a_new, a[i] * polymul(pnum, pden)) return a_new
def smoothing_poly_lnprior(poly, degree, xmin, xmax, gamma=1): """ A smoothing prior that suppresses higher order derivatives of a polynomial, poly = a + b x + c x*x + ..., described by a vector of its coefficients, [a, b, c, ...]. Functional form is: ln p(poly coeffs) = -gamma * integrate( (diff(poly(x), x, degree))^2, x, xmin, xmax) So it takes the `degree`th derivative of the polynomial, squares it, integrates that from xmin to xmax, and scales by -gamma. """ # Take the `degree`th derivative of the polynomial. poly_diff = P.polyder(poly, m=degree) # Square the polynomial. poly_diff_sq = P.polypow(poly_diff, 2) # Take the indefinite integral of the polynomial. poly_int_indef = P.polyint(poly_diff_sq) # Evaluate the integral at xmin and xmax to get the definite integral. poly_int_def = ( P.polyval(xmax, poly_int_indef) - P.polyval(xmin, poly_int_indef) ) # Scale by -gamma to get the log prior lnp = -gamma * poly_int_def return lnp
def smoothing_poly_lnprior(poly, degree, xmin, xmax, gamma=1): """ A smoothing prior that suppresses higher order derivatives of a polynomial, poly = a + b x + c x*x + ..., described by a vector of its coefficients, [a, b, c, ...]. Functional form is: ln p(poly coeffs) = -gamma * integrate( (diff(poly(x), x, degree))^2, x, xmin, xmax) So it takes the `degree`th derivative of the polynomial, squares it, integrates that from xmin to xmax, and scales by -gamma. """ # Take the `degree`th derivative of the polynomial. poly_diff = P.polyder(poly, m=degree) # Square the polynomial. poly_diff_sq = P.polypow(poly_diff, 2) # Take the indefinite integral of the polynomial. poly_int_indef = P.polyint(poly_diff_sq) # Evaluate the integral at xmin and xmax to get the definite integral. poly_int_def = (P.polyval(xmax, poly_int_indef) - P.polyval(xmin, poly_int_indef)) # Scale by -gamma to get the log prior lnp = -gamma * poly_int_def return lnp
def probability(dice_number, sides, target): powers = [0] + [1] * sides poly = polypow(powers, dice_number) try: return round(poly[target] / sides ** dice_number, 4) except IndexError: return 0
def __init__(self, history, order, order_s, diff, diff_s, period, seed=42): self.order = order # AR order p self.order_s = order_s # seasonal AR order P self.diff = diff # non-seasonal difference order d self.diff_s = diff_s # seasonal difference order D self.period = period # seasonal period s # original series [X_{t-1}, X_{t-2}, ..., X_{t-(p+s*P+d+s*D)}] self.X = np.zeros(order + period * order_s + diff + period * diff_s) trunc = list(reversed(history))[:order + period * order_s + diff + period * diff_s] self.X[:len(trunc)] = trunc self.X = deque(self.X, maxlen=order + period * order_s + diff + period * diff_s) # compute (1-B)^d (1-B^s)^D self.diff_polycoef = polypow([1, -1], diff) # (1-B)^D self.diff_s_polycoef = polypow([1] + [0] * (period - 1) + [-1], diff_s) # (1-B^s)^D self.diff_multiply = self._polymul(self.diff_polycoef, self.diff_s_polycoef) # differenced series [Y_{t-1}, Y_{t-2}, ..., Y_{t-(p+s*P)}] self.Y = self._compute_backshift(self.diff_multiply, self.X) assert len(self.Y) == order + period * order_s self.Y = deque(self.Y, maxlen=order + period * order_s) self.c = 1 self.X_max = 2 self.D = 2 * self.c * np.sqrt(order + order_s) self.G = self.D * (self.X_max**2) self.lambda_ = 1.0 / (order + order_s) if order + order_s != 0 else 1.0 self.eta = 0.5 * min(4 * self.G * self.D, self.lambda_) # learning rate self.epsilon = 1.0 / (self.eta * self.D)**2 self.A = np.matrix(np.diag([1] * (order + order_s)) * self.epsilon) # hessian matrix if seed: np.random.seed(seed) self.gamma = np.matrix(np.random.uniform( -self.c, self.c, (order, 1))) # parameters g_1, g_2, ..., g_p if seed: np.random.seed(seed) self.gamma_s = np.matrix( np.random.uniform( -self.c, self.c, (order_s, 1))) # seasonal parameters gs_1, gs_2, ..., gs_P
def test_polypow(self): for i in range(5): for j in range(5): msg = "At i=%d, j=%d" % (i, j) c = np.arange(i + 1) tgt = reduce(poly.polymul, [c] * j, np.array([1])) res = poly.polypow(c, j) assert_equal(trim(res), trim(tgt), err_msg=msg)
def test_polypow(self): for i in range(5): for j in range(5): msg = "At i=%d, j=%d" % (i, j) c = np.arange(i + 1) tgt = reduce(poly.polymul, [c]*j, np.array([1])) res = poly.polypow(c, j) assert_equal(trim(res), trim(tgt), err_msg=msg)
def YofS(YZn, YZd, omega1, omega2): #Convert Y(Z^2) to Y(S)/S by using EQN(2) Z2n = np.array([1, 0, omega2**2]) Z2d = np.array([1, 0, omega1**2]) #Numerator and denominator of Y(Z^2) will have the same even order YSn = np.array([]) YSd = np.array([]) N_Order = len(YZd)//2 for i in range(N_Order + 1): temp = np.polymul(np_pp.polypow(Z2n, N_Order - i), np_pp.polypow(Z2d, i)) YSn = np.polyadd(YSn, YZn[2*i]*temp) YSd = np.polyadd(YSd, YZd[2*i]*temp) #Ysd constant term is always zero and therefore.. YSd = YSd[:-1] return YSn, YSd
def berlekampTest(prime, poly): m = len(poly) - 1 u = [0, 1] for i in range(0, m // 2): u = P.polydiv(P.polypow(u, prime), poly)[1] % prime d = gcd(P.polysub(u, [0, 1]) % prime, poly, prime) #print(P.polysub(u, [0, 1]) % prime, poly, d) if not np.array_equal(np.array([1.]), d): return False return True
def diePmf(dice, sides): # Source: http://www.johndcook.com/blog/2013/04/29/rolling-dice-for-normal-samples-python-version/ # Create an array of polynomial coefficients for # x + x^2 + ... + x^sides p = ones(sides + 1) p[0] = 0 p /= sides # Extract the coefficients of p(x)**dice and divide by sides**dice pmf = polypow(p, dice) #cdf = pmf.cumsum() return pmf
def magic(sides, dices, health, points): # Prob of getting a sum of k is the coefficient of x^k in # ((x + x^2 + ... + x^m)/m)^n # m = sides per dice # n = number of dices p = ones(sides + 1) p[0] = 0 p /= sides p = polypow(p, dices) # Get cumulative sum to get prob cdf = p.cumsum() k = health - points - 1 return 1 - cdf[k] if k <= len(cdf) and k > 0 else 1 if k < 0 else 0
def roll(d_num, sides, target): """ :param d_num: number of dices OR max size of each part of composition :param sides: sides of dice OR number of parts of composition :param target: number to get through rolling a single roll OR power in power series (or integer n for composition) :return: rounded probability """ polynomial = (poly1d([1 for e in range(0, sides + 1)]) - 1) poly_coeffs = polypow(polynomial.coefficients[::-1], d_num) if target + 1 > len(poly_coeffs): return 0 num_of_compositions = poly_coeffs[target] probability = num_of_compositions / (sides**d_num) return round(probability, 4)
def probability(dice_number, sides, target): """ Using numpy polynomial The number of ways to obtain x as a sum of n s-sided dice is given by the coefficients of the polynomial: f(x) = (x + x^2 + ... + x^s)^n """ # power series (note that the power series starts from x^1, therefore # the first coefficient is zero) powers = [0] + [1] * sides # f(x) polynomial, computed used polypow in numpy poly = polypow(powers, dice_number) return poly[target] / sides**dice_number if target < len(poly) else 0
def __init__(self, pol1, pol2): """ Composes two polynomials (i.e., `pol1'(`pol2')) with distinct covariance matrices. Considering we have polynomials f(x) = \\sum_i a_i x^i, g(x) = \\sum_j b_j x^j, with variances \\sigma_f and \\sigma_g when evaluated (see coll_dyn_activem.maths.Polynomial), we compute \\sigma_fg(x) = \\sigma_f(g(x)) + \\sigma_g(x) \\times [ \\sum_i i a_i g(x)^{i-1} ]^2, as the variance of the composed polynomial f(g) evaluated at x. We stress that this considers no correlations between the coefficients of the polynomials. (see https://en.wikipedia.org/wiki/Propagation_of_uncertainty#Non-linear_combinations) Parameters ---------- pol1 : coll_dyn_activem.maths.Polynomial First polynomial. pol2 : coll_dyn_activem.maths.Polynomial Second polynomial. Returns ------- pol : coll_dyn_activem.maths.Polynomial Composed polynomial. """ self._pol1, self._pol2 = pol1, pol2 self.deg = self._pol1.deg * self._pol2.deg # degree of composed polynomial # WARNING: numpy.polynomial.polynomial.polyadd and polypow considers # arrays as polynomials with lowest coefficient first, # contrarily to polyval and polyfit. _pol1, _pol2 = self._pol1.pol[::-1], self._pol2.pol[::-1] self.pol = np.zeros((1, )) # composed polynomial for i in range(pol1.deg + 1): self.pol = polyadd(self.pol, _pol1[i] * polypow(_pol2, i)) self.pol = self.pol[::-1]
def starsbars(totalLimit,boxLimit,boxNum): # Init a list of coeffs polyCoeff = [0]*(boxLimit+1) polyCoeff[boxLimit] = -1 polyCoeff[0] = 1 # Poly Coeff should be 1-x^boxLimit # Expand the polynomial to be (1-x^boxLimit)^boxNum expandedPolyCoeff = poly.polypow(polyCoeff,boxNum) # Get terms that are valid validPolyCoeff = expandedPolyCoeff[:totalLimit] # Get teh powers of the valid terms powers = [i for i,v in enumerate(validPolyCoeff) if (v)] # Get the coeffs of the valid terms coeffs = [v for i,v in enumerate(validPolyCoeff) if (v)] # substituting the generative function finalpowers = [(i * -1)+totalLimit for i in powers] # print(finalpowers) # Better explanation: https://math.stackexchange.com/questions/1922819/stars-and-bars-with-bounds # Here we have limit = 127, cap = 63, entities = 6 # [x^limit](1-x^cap)^entities * sum(k+entities-1/entities-1)x^k # expressing the above you get the following # [x^limit]x^{384}-6x^{320}+15x^{256}-20x^{192}+15x^{128}-6x^{64}+1 * sum(k+entities-1/entities-1)x^k # we can then apply [x^{p-q}]A(x)=[x^p]x^{q}A(x) # [x^{-257}]-6[x^{-193}]+15[x^{-129}]-20[x^{-65}]+15[x^{-1}]-6x^{63}+[x^127] * sum(k+entities-1/entities-1)x^k # because negative exponents dont do anything we can simplify to # -6[x^{63}]+[x^127] * sum(k+entities-1/entities-1)x^k # which simplifies to -6(68 nCr 5)+(132 nCr 5) # 241888308 # For this case we need to # sum all posibilites from 0 to limit finalAnswer = 0 for idx,value in enumerate(finalpowers): finalAnswer+= coeffs[idx]*C(finalpowers[idx]+boxNum-1, boxNum-1,False) if finalAnswer == 0: # This is just to count the posibility of no EVs finalAnswer+=1 # print(finalAnswer) return finalAnswer
def _get_sufficient_sk_power(self, max_power): """Generate an list of secret key polynomial raised to 1...max_power. Args: max_power: heighest power up to which we want to raise secretkey. Returns: A 2-dim list having secretkey powers. """ sk_power = [[] for _ in range(max_power)] sk_power[0] = self._secret_key for i in range(2, max_power + 1): for j in range(len(self._coeff_modulus)): sk_power[i - 1].append( poly.polypow(self._secret_key[j], i).astype(int).tolist()) return sk_power
def initControl(self): self.ts = 0.005 # Right motor # self.k = 45 # self.tau = 0.100 # Left motor self.k = 48 self.tau = 0.095 self.gd = cnt.tf(self.k, [self.tau, 1, 0]).sample(self.ts) c = np.exp(-self.ts / self.tau) b_minus = self.k * np.array( [self.ts - self.tau * (1 - c), self.tau * (1 - c) - c * self.ts]) b_plus = np.ones(1) a_minus = zero(1) a_plus = zero(c) a_m = P.polypow(zero(0.7), 2) self.r, self.s, self.t =\ map(poly2tf, calculate_rst(b_minus, b_plus, a_minus, a_plus, a_m, d=1, p=1)) self.time = np.linspace(0, 0.99, 100)
def dice_polypow_gmpy2(faces, num): """ Numpy polynomial power function (iterated convolve). With gmpy2. """ return P.polypow(array([mpz(1)]*faces, dtype=object), num)
def polypow(cs, pow, maxpower=None): from numpy.polynomial.polynomial import polypow return polypow(cs, pow, maxpower)
] gr = re.split("\+|-", comps[k]) gr = [ re.search("\d*$", g).group() if "x" in g else "0" for g in gr ] gr = [int(g) if g != "" else 1 for g in gr] fCoef = [ cf.pop() if g in gr else 0 for g in range(max(gr) + 1) ] c = npp.Polynomial(coef=fCoef) k += 1 pol = npp.polymul(pol, c).any() elif op.startswith("^"): g = int(op[1:]) pol = npp.polypow(pol, g).any() res = "" g = pol.degree() for i in [int(q) for q in pol.coef[::-1]]: if i != 0: if g > 0: a = "" if g != pol.degree(): a += "+" if i > 0 else "" a += "" if i == 1 else "-" if i == -1 else str(i) b = a + "x" + ("" if g == 1 else "^" + str(g)) res += b else: res += str(i) if i < 0 else "+" + str(i) g -= 1
def polypow(cs, pow, maxpower=None) : from numpy.polynomial.polynomial import polypow return polypow(cs, pow, maxpower)
def rolldice_sum_prob(sum_, dice_amount): return (P.polypow([1, 1, 1, 1, 1, 1], dice_amount) ).item(sum_ - dice_amount) / (6**dice_amount) if ( sum_ <= 6 * dice_amount) else 0.0
def probability(dice_number, sides, target): if target < 1 or target > dice_number * sides: return 0.0000 prob = polynomial.polypow([0] + [1] * sides, dice_number) return round(prob[target] / sides ** dice_number, 4)
def get_beta(self, p, p0): p2 = nppoly.polypow(p, 2) p02 = nppoly.polypow(p0, 2) return (self.integrate(p2, self.intlims[0], self.intlims[1]) / self.integrate(p02, self.intlims[0], self.intlims[1]))
def get_probs(n_dice, n_turns): p = [1 / n_dice] * n_dice return polypow(p, n_turns)
from numpy.polynomial.polynomial import polypow from numpy import ones sides = 6 dice = 2 # Create an array of polynomial coefficients for # x + x^2 + ... + x^sides p = ones(sides + 1) p[0] = 0 # Extract the coefficients of p(x)**dice and divide by sides**dice pmf = sides**(-dice) * polypow(p, dice) cdf = pmf.cumsum() print cdf
def get_alpha(self, p): p2 = nppoly.polypow(p, 2) xp2 = nppoly.polymulx(p2) return (self.integrate(xp2, self.intlims[0], self.intlims[1]) / self.integrate(p2, self.intlims[0], self.intlims[1]))
def eof_p_opt(sch, max_degree=None, debug=False, capacity=None): """ :param sch: Input scheme. :param max_degree: Max degree of result polinomial. :param debug: If True debug information will be printed due to process. :return: First max_degree+1 members of polinomial EOF(p) for input scheme. """ n = sch.inputs() m = sch.elements() if capacity is None: capacity = min([2 ** sch.inputs(), 32]) nonerror = (0,) * m if max_degree is None: max_degree = m sch_process = d.make_process_func(sch, capacity=capacity) if debug: start = time.time() counter = 0 while time.time() - start < 1: output_true = sch_process((0,) * n, (0,) * m) vec2num(output_true) vec2num(output_true) counter += 1 process_time = (time.time() - start) / counter inputs = 2 ** n / capacity errors = sum(choose(m, degree) for degree in range(max_degree + 1)) estimated_time = process_time * inputs * errors print("Estimated time eof_p: ", estimated_time) poly = Polynomial([Fraction(0, 1)]) input_prob = Fraction(1, 2 ** n) p = Polynomial([Fraction(0, 1), Fraction(1, 1)]) sum_poly = Polynomial([Fraction(0, 1)]) for input_values in inputs_combinations(n, capacity=capacity): output_true = sch_process(input_values, nonerror) if debug: print(input_values) for degree in range(max_degree + 1): error_prob = Polynomial(polypow(p.coef, degree, maxpower=100)) * Polynomial( polypow((1 - p).coef, m - degree, maxpower=100) ) # print(error_prob.coef) errors_number = 0 if debug: print(len(list(combinations(range(m), r=degree)))) for error_comb in combinations(range(m), r=degree): error_vec = [0] * m for i in error_comb: error_vec[i] = 2 ** capacity - 1 output_error = sch_process(input_values, error_vec) errors = [i ^ j for i, j in zip(output_true, output_error)] errors_number += ones(reduce(or_, errors)) if debug: print(errors_number) if errors_number: poly += errors_number * input_prob * error_prob result = list(poly.coef) # removing trailing zeros while not result[-1]: result.pop() return result