def balance(self): # Get list of unique elements elements = set() [ elements.add(element) for reactant in self.left for element in reactant.count().keys() ] elements = tuple(elements) # Build the matrix rows = [] for element in elements: row = [] for reactant in self.left: row.append(reactant.count(element)) for reactant in self.right: row.append(-reactant.count(element)) rows.append(row) # Balance equation with linear algebra # http://www.ctroms.com/blog/math/2011/05/01/balancing-chemical-equations-with-linear-algebra/ mat = Matrix(rows) solution, pivots = mat.rref() values = [solution.row(r)[-1] for r in range(solution.rows)] factor = lcm([value.as_numer_denom()[1] for value in values]) coeffs = [ -solution.row(i)[i] * solution.row(i)[-1] * factor for i in pivots ] + [factor] for reactant, coeff in zip(self.left + self.right, coeffs): reactant.coefficient = coeff return self
def lambda_n(n, k): factors = factor(k) result = 1 x = symbols('x') term = 1 for i in range(1, n + 1): term = lcm(term, x ** i - 1) for p, e in factors: result = lcm(result, int(p ** (e + math.floor(math.log(n) / math.log(p))) * term.evalf(subs={'x': p}))) return result
def balance(self): # Get list of unique elements elements = set() [elements.add(element) for reactant in self.left for element in reactant.count().keys()] elements = tuple(elements) # Build the matrix rows = [] for element in elements: row = [] for reactant in self.left: row.append(reactant.count(element)) for reactant in self.right: row.append(-reactant.count(element)) rows.append(row) # Balance equation with linear algebra # http://www.ctroms.com/blog/math/2011/05/01/balancing-chemical-equations-with-linear-algebra/ mat = Matrix(rows) solution, pivots = mat.rref() values = [solution.row(r)[-1] for r in range(solution.rows)] factor = lcm([value.as_numer_denom()[1] for value in values]) coeffs = [-solution.row(i)[i] * solution.row(i)[-1] * factor for i in pivots] + [factor] for reactant, coeff in zip(self.left + self.right, coeffs): reactant.coefficient = coeff return self
def __solve_matrix__(self, reactants, products, elems): # Create a coefficient matrix to solve coeff_matrix = [] for e in elems.to_seq(): row = [compnd.num_atoms(e) for compnd in reactants] row += [-compnd.num_atoms(e) for compnd in products] coeff_matrix.append(row) # Check if reaction is null if (reactants == [] and products == []): return [], [] else: # Solve for lhs and rhs coefficients # Uses algorithm proposed here: # https://stackoverflow.com/questions/42637872/solve-system-of-linear-integer-equations-in-python matrix = Matrix(coeff_matrix) null_vectors = matrix.nullspace() if null_vectors == []: raise ValueError( "Invalid ReactionT. Reaction cannot be balanced.") null_vectors = null_vectors[0] multiple = lcm([val.q for val in null_vectors]) x = multiple * null_vectors solution = np.array([int(val) for val in x]).tolist() lhs_coeffs = solution[:len(reactants)] rhs_coeffs = solution[len(reactants):] return lhs_coeffs, rhs_coeffs
def balance(eq): M = form_mx(eq) lhs = re.split("=", eq)[0] rhs = re.split("=", eq)[1] left_compounds = re.split('\s*\+\s*', lhs) right_compounds = re.split('\s*\+\s*', rhs) elements = [] for left_ele in left_compounds: help_list = re.findall(r'([A-Z][a-z]{0,1})(\d*)', left_ele) for ele in help_list: if ele[0] not in elements: elements.append(ele[0]) n = len(left_compounds) + len(right_compounds) x = [parse_expr('x%d' % i) for i in range(n)] x = sp.symbols('x0:%d' % n) sols = sp.solve_linear_system(M, *x) new_dict = {} for i in x: new_dict[i] = 1 for key in sols: if sols[key].args == (): new_dict[key] = 1 else: new_dict[key] = (sols[key]).args[0] # remove fractions final_list = [] for i in range(n): final_list.append(sp.fraction(new_dict[x[i]])[1]) f = sp.lcm(final_list) for key in new_dict: new_dict[key] = new_dict[key] * f # form the final output string result_str = "" for i in range(len(left_compounds)): if new_dict[x[i]] == 1: result_str += left_compounds[i] else: result_str += str(new_dict[x[i]]) + left_compounds[i] if i != (len(left_compounds) - 1): result_str += '+' result_str += '=' for i in range(len(right_compounds)): temp = len(left_compounds) if new_dict[x[i + temp]] == 1: result_str += right_compounds[i] else: result_str += str(new_dict[x[i + temp]]) + right_compounds[i] if i != (len(right_compounds) - 1): result_str += '+' return result_str
def test_lcm_expr(): assert_equal("\\lcm(1+1, 8)", lcm(1 + 1, 8)) assert_equal("920*\\lcm(9, 12*4/2)", 920 * lcm(9, 12 * Rational('4/2'))) assert_equal("\\lcm(32-128, 10)*22", lcm(32 - 128, 10) * 22) assert_equal("\\sqrt{\\lcm(1.25E24, 1E12)}", sqrt(lcm(Rational('1.25E24'), Rational('1E12')))) assert_equal("\\lcm(92.0, 000+2)", lcm(Rational('92.0'), 000 + 2)) assert_equal("\\operatorname{lcm}(1+1, 8)", lcm(1 + 1, 8)) assert_equal("920*\\operatorname{lcm}(9, 12*4/2)", 920 * lcm(9, 12 * Rational('4/2'))) assert_equal("\\operatorname{lcm}(32-128, 10)*22", lcm(32 - 128, 10) * 22) assert_equal("\\sqrt{\\operatorname{lcm}(1.25E24, 1E12)}", sqrt(lcm(Rational('1.25E24'), Rational('1E12')))) assert_equal("\\operatorname{lcm}(92.0, 000+2)", lcm(Rational('92.0'), 000 + 2))
def rat2int(N): """Convert a rational matrix to an integer matrix. Parameters: N: numpy rational array Returns: mN: numpy rational array mN is m*N where m is the least common multiple of all denominators Example: >>> n1 = sp.Matrix([2,1]); n2 = sp.Matrix([4,6]); N = sp.Matrix([n1/2,n2/3]) >>> print(N) Matrix([[1], [1/2], [4/3], [2]]) >>> print(stoich.rat2int(N)) Matrix([[6], [3], [8], [12]]) """ n, m = N.shape lcm_den = 1 for i in range(n): for j in range(m): num, den = sp.fraction(N[i, j]) lcm_den = sp.lcm(lcm_den, den) #print(num,den,lcm_den) return lcm_den * N
def calc_gen(): """ Calculate generator polynomial based on a given primitive polynomial. """ # Initialize primitive polynomial in GF(q). prim_poly = Poly(alpha**m + alpha**4 + 1, alpha).set_domain(GF(q)) print('Primitive poly: %s' % prim_poly) gen_poly = None for i in range(1, t * 2): # No need to calculate for even i. if i % 2 is not 0: print('Current i: %d' % i) # On first loop, calculate only minimal polynomial. if gen_poly is None: gen_poly = min_poly(i, prim_poly) # Otherwise calculate lowest common multiplier using current value # of generator polynomial and minimal polynomial with current i. else: gen_poly = lcm(gen_poly, min_poly(i, prim_poly)) # Truncate to GF(q). gen_poly = gen_poly.trunc(q) print('Generator poly: %s' % gen_poly) return prim_poly, gen_poly
def __init__(self, bits_modulo=2048, e=2**16 + 1): ''' genera una clau RSA (de 2048 bits i amb exponent públic 2**16+1 per defecte) ''' self.publicExponent = e correct_primes = False while not correct_primes: self.primeP = sympy.randprime(2**(bits_modulo // 2 - 1), 2**(bits_modulo // 2) - 1) self.primeQ = sympy.randprime(2**(bits_modulo // 2 - 1), 2**(bits_modulo // 2) - 1) phi_p = self.primeP - 1 if sympy.gcd(phi_p, self.publicExponent) != 1: continue phi_q = self.primeQ - 1 if sympy.gcd(phi_q, self.publicExponent) != 1: continue correct_primes = True phi_n = (self.primeP - 1) * (self.primeQ - 1) # lcm = phi_p * phi_q / math.gcd(phi_p,phi_q) lcm = sympy.lcm(phi_p, phi_q) self.privateExponent = sympy.invert(self.publicExponent, lcm) self.modulus = self.primeP * self.primeQ self.privateExponentModulusPhiP = self.privateExponent % phi_p self.privateExponentModulusPhiQ = self.privateExponent % phi_q self.inverseQModulusP = sympy.invert(self.primeQ, self.primeP)
def process(self, node: Union[c_ast.FileAST, c_ast.FuncDef]) \ -> Tuple[c_ast.FuncDef, TypeSystem, Iterable[str], Iterable[str], str]: if not isinstance(node, (c_ast.FileAST, c_ast.FuncDef)): raise TypeError('node must be of type Union(FileAST, FuncDef)') processed = self.visit(node) # scale up the random noise scales due to limitations of symbolic executor KLEE only supporting integers all_scales = [ f'1 / ({generate(func_call.args.exprs[0])})' for func_call in self._random_scales ] lcm = sp.lcm( tuple( map(lambda scale: sp.fraction(scale)[1], all_scales + [self._goal]))) # TODO: use less hackery method to tackle the Pow operation in sympy # see also https://stackoverflow.com/questions/14264431/expanding-algebraic-powers-in-python-sympy if str(lcm) != '1': logger.warning( f'Scaling down the noise scales by {lcm} due to limitations of symbolic executor KLEE ' f'only supporting integers, therefore the cost calculations will not contain divisions.' ) for scale in self._random_scales: scale.args.exprs[0] = parse( expr_simplify( f'({generate(scale.args.exprs[0])}) / ({lcm})')) logger.warning( f'Scaling up the final goal by {lcm} as well due to the cost scale-ups.' ) self._goal = expr_simplify(f'({self._goal}) * ({lcm})') return processed, self._type_system, self._preconditions, self._hole_preconditions, self._goal
def _polynomial_coeffs_with_roots(roots, scale_entropy): """Returns a polynomial with the given roots. The polynomial is generated by expanding product_{root in roots} (x - root), and then (1) scaling by the coefficients so they are all integers with lcm 1, and then (2) further scaling the coefficients by a random integer or rational with `scale_entropy` digits. Args: roots: List of values. scale_entropy: Float; entropy of the random coefficient scaling. Returns: List of coefficients `coeffs`, such that `coeffs[i]` is the coefficient of variable ** i. """ variable = sympy.Symbol('x') # doesn't matter, only use coefficients polynomial = sympy.Poly(sympy.prod([variable - root for root in roots])) coeffs_reversed = polynomial.all_coeffs() assert len(coeffs_reversed) == len(roots) + 1 coeffs = list(reversed(coeffs_reversed)) # Multiply terms to change rationals to integers, and then maybe reintroduce. lcm = sympy.lcm([sympy.denom(coeff) for coeff in coeffs]) if scale_entropy > 0: while True: scale = number.integer_or_rational(scale_entropy, signed=True) if scale != 0: break else: scale = 1 return [coeff * scale * lcm for coeff in coeffs]
def scale_vector(vector, S, lb, ub, max_error=1e-6, normalize=False): """scale a vector Attempts to scale the vector to the smallest possible integers, while maintaining S * vector = 0 and lb <= vector <= ub If normalize is True, integer scaling is still performed, but the result is then normalized (||vector|| = 1). If the integer scaling works, this still results in less floating point error. """ def check(x): if abs(S * matrix(x).T).max() > max_error: return False if (x > ub).any() or (x < lb).any(): return False return True def prepare_return(x): return x / sum(x * x) if normalize else x # scale the vector so the smallest entry is 1 abolute_vector = abs(vector) scale = min(abolute_vector[abolute_vector > 1e-5]) min_scaled_vector = vector * (1.0 / scale) min_scaled_vector[abs(min_scaled_vector) < 1e-9] = 0 # round down # if scaling makes the solution invalid, return the old one if not check(min_scaled_vector): return prepare_return(vector) # attempt scale the vector to make all entries integers factor = lcm([get_factor(i) for i in min_scaled_vector]) int_scaled_vector = min_scaled_vector * float(factor) if max(abs(int_scaled_vector.round() - int_scaled_vector)) < max_error: int_scaled_vector = int_scaled_vector.round() if check(int_scaled_vector): return prepare_return(int_scaled_vector) # if this point is reached the integer scaling failed return prepare_return(min_scaled_vector)
def get_coefficients(rref: MutableDenseMatrix, chem_eq: str, explain: bool = False) -> list: all_compounds = list(re.split(r"\+|=\>", chem_eq)) coefficients = [1] * len(all_compounds) denoms = [num.denominator() for num in rref.col(-1)] the_lcm = sp.lcm(denoms) if explain: print( "Next, we extract the denominators of the last column from the rref:" ) pause() print(denoms) pause() print( f"Then we find the least common multiple of the denominators, which is: {the_lcm}" ) pause() print( "After that, we multiply each value in that last column by the LCM (and keep the absolute value), and the first coefficient is the first value, the second is the second value, etc." ) pause() print("The coefficient of the last compound is just the LCM") pause() for i, _ in enumerate(coefficients[:-1]): numer, denom = rref[i, -1].p, rref[i, -1].q if numer == 0: return [0] * len(all_compounds) coefficients[i] = abs(numer * (the_lcm / denom)) coefficients[-1] = the_lcm return coefficients
def convert_rationals_to_ints(coef_list): ints = filter(lambda c: isinstance(c, int), coef_list) rationals = filter(lambda c: isinstance(c, sympy.Rational), coef_list) if len(ints) + len(rationals) > len(coef_list): raise Exception("int's and rationals are not mutually exclusive") lcm = reduce(lambda x, y: sympy.lcm(x, y.q), rationals, 1) no_rationals = map(lambda x: x * lcm, coef_list) int_coefs = [int(x) if isinstance(x, sympy.Integer) else x for x in no_rationals] if len(rationals) + len(ints) != len(coef_list): # print "not equal" print "coef_list: %s" %coef_list print "rationals: %s" %rationals print "lcm: %s" %lcm print "int_coefs: %s" %int_coefs print "types: %s" %map(type, int_coefs) raise Exception("not rational") pass return int_coefs
def find_simple_recurrence_vector(l): """ This function is used internally by other functions from the sympy.concrete.guess module. While most users may want to rather use the function find_simple_recurrence when looking for recurrence relations among rational numbers, the current function may still be useful when some post-processing has to be done. The function returns a vector of length n when a recurrence relation of order n is detected in the sequence of rational numbers v. If the returned vector has a length 1, then the returned value is always the list [0], which means that no relation has been found. While the functions is intended to be used with rational numbers, it should work for other kinds of real numbers except for some cases involving quadratic numbers; for that reason it should be used with some caution when the argument is not a list of rational numbers. Examples ======== >>> from sympy.concrete.guess import find_simple_recurrence_vector >>> from sympy import fibonacci >>> find_simple_recurrence_vector([fibonacci(k) for k in range(12)]) [1, -1, -1] See also ======== See the function sympy.concrete.guess.find_simple_recurrence which is more user-friendly. """ q1 = [0] q2 = [Integer(1)] b, z = 0, len(l) >> 1 while len(q2) <= z: while l[b]==0: b += 1 if b == len(l): c = 1 for x in q2: c = lcm(c, denom(x)) if q2[0]*c < 0: c = -c for k in range(len(q2)): q2[k] = int(q2[k]*c) return q2 a = Integer(1)/l[b] m = [a] for k in range(b+1, len(l)): m.append(-sum(l[j+1]*m[b-j-1] for j in range(b, k))*a) l, m = m, [0] * max(len(q2), b+len(q1)) for k in range(len(q2)): m[k] = a*q2[k] for k in range(b, b+len(q1)): m[k] += q1[k-b] while m[-1]==0: m.pop() # because trailing zeros can occur q1, q2, b = q2, m, 1 return [0]
def get_normalized_circuit(self, g): B_g = self.B.dot(g) B_0 = np.zeros((1, self.n), dtype=int) for i in range(self.m_B): if abs(B_g[i]) <= EPS: B_0 = np.concatenate((B_0, self.B[i,:].reshape((1 ,self.n)))) if self.A is not None: B_0 = np.concatenate((self.A, B_0), axis=0) D = sympy.Matrix(B_0) ker_D = D.nullspace() #if len(ker_D) != 1: # raise ValueError('The direction {} is not a circuit of P'.format(g.T)) circuit = np.array(ker_D[0]).reshape(self.n) #normalize circuit= circuit*sympy.lcm([circuit[i].q for i in range(self.n) if circuit[i] != 0]) #make sure circuit has correct sign for i in range(self.n): if abs(g[i]) >= EPS: if circuit[i]*g[i] < 0: circuit = -1*circuit break return circuit
def lcm_arr(Dmat): input1 = Dmat.flatten() Sz = input1.shape lcm1 = 1 for ct1 in range(Sz[0]): lcm1 = spy.lcm(lcm1, input1[ct1]) return int(lcm1)
def KerIntBasis(B): BKer = 1.0 * np.array(Matrix(B).nullspace()) Bk = [] for basis in BKer: l = lcm( map(lambda x: Fraction(x).limit_denominator().denominator, map(str, basis))) basis = map(int, l * basis) Bk.append(basis) Bk = np.array(Bk).T #Basis are column elements return Bk
def apply(self, ns, evaluation): 'LCM[ns___Integer]' ns = ns.get_sequence() result = 1 for n in ns: value = n.get_int_value() if value is None: return result = sympy.lcm(result, value) return Integer(result)
def apply(self, ns, evaluation): "LCM[ns___Integer]" ns = ns.get_sequence() result = 1 for n in ns: value = n.get_int_value() if value is None: return result = sympy.lcm(result, value) return Integer(result)
def coefficients_integerize(self): """Transform coefficients to integers if it could be done.""" # Get the list that contains all items. all_items = self.__left_items + self.__right_items # Initialize the LCM of denominators as 1. denom_lcm = _math_cst.ONE # Process left items. for item in all_items: # Get the coefficient. coeff = item.get_coefficient().simplify() # Get the denominator. nd = coeff.as_numer_denom() nd_denom = nd[1].simplify() # Calculate. if nd_denom.is_Integer: denom_lcm = _sympy.lcm(denom_lcm, nd_denom) # Let all coefficients multiply with the LCM value. for item in all_items: item.set_coefficient(item.get_coefficient() * denom_lcm) # Initialize the GCD of numerators. numer_gcd = None use_numer_gcd = True for item in all_items: # Get the coefficient. coeff = item.get_coefficient().simplify() # Get the numerator. nd = coeff.as_numer_denom() nd_numer = nd[0].simplify() # Calculate. if nd_numer.is_Integer and not nd_numer.is_zero: if numer_gcd is None: numer_gcd = nd_numer else: numer_gcd = _sympy.gcd(nd_numer, numer_gcd) else: use_numer_gcd = False break # Let all coefficients divide by the GCD value if the GCD value is available. if use_numer_gcd and numer_gcd is not None: for item in all_items: item.set_coefficient( (item.get_coefficient() / numer_gcd).simplify())
def __init__(self, p=0, q=0, g=0): self.__p = p self.__q = q self.__n = self.__p * self.__q self.__lambda = sympy.lcm(self.__p - 1, self.__q - 1) self.__g = g self.__u = 0 if self.__g != 0: self.__u = sympy.mod_inverse( self.__L(g**self.__lambda % self.__n**2), self.__n) print("p,q,n,lambda,g,u = ", self.__p, self.__q, self.__n, self.__lambda, self.__g, self.__u) print("Paillier:: initialized")
def getMatrixDenomLCM(self, M): ''' Get lcm of matrix denominator. In sympy, operation of fractionals seems much slower than integers. Thus we multiply a fraction matrix with the LCM of all denominators, then divide the result with the LCM. ''' dm = 1 for e in M: if isinstance(e, Rational): nom, denom = e.as_numer_denom() dm = sympy.lcm(denom, dm) return (M * dm, dm)
def balance(self): """ Taking arguments from java file and separting LHS and RHS """ lst = [' {0} '.format(elem) for elem in sys.argv[1:]] eqn = ''.join(str(e) for e in lst) eqn_final = eqn.split('==') lhs_strings = eqn_final[0].split() lhs_strings.reverse() lhs_compounds = [self.parse_compound(compound) for compound in lhs_strings] rhs_strings = eqn_final[1].split() rhs_strings.reverse() rhs_compounds = [self.parse_compound(compound) for compound in rhs_strings] # Get list of elements els = sorted(set().union(*lhs_compounds, *rhs_compounds)) els_index = dict(zip(els, range(len(els)))) # Building matrix to solve w = len(lhs_compounds) + len(rhs_compounds) h = len(els) A = [[0] * w for _ in range(h)] # load with element coefficients for col, compound in enumerate(lhs_compounds): for el, num in compound.items(): row = els_index[el] A[row][col] = num for col, compound in enumerate(rhs_compounds, len(lhs_compounds)): for el, num in compound.items(): row = els_index[el] A[row][col] = -num # invert coefficients for RHS # Solve using Sympy for absolute-precision math A = sympy.Matrix(A) if not A.nullspace(): print("Invalid Equation!!!") return # finding first basis vector == primary solution coeffs = A.nullspace()[0] # finding least common denominator, multiply through to convert to integer solution coeffs *= sympy.lcm([term.q for term in coeffs]) # Displaying result lhs = " + ".join(["{} {}".format(coeffs[i], s) for i, s in enumerate(lhs_strings)]) rhs = " + ".join(["{} {}".format(coeffs[i], s) for i, s in enumerate(rhs_strings, len(lhs_strings))]) print("{} --> {}".format(lhs, rhs))
def lcm(value, sample_args, context=None): """Question for least common multiple of p and q.""" del value # unused if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() p, q = _pair_with_large_hidden_factor(entropy) answer = sympy.lcm(p, q) if random.choice([False, True]): p, q = context.sample(sample_args, [p, q]) # Ask the question directly. adjective = random.choice( ['paling sedikit', 'paling rendah', 'paling kecil']) template = random.choice([ 'Hitung kelipatan persekutuan {adjective} dari {p} dan {q}.', 'Berapa {adjective} kelipatan persekutuan dari {p} dan {q}?', ]) return example.Problem(question=example.question( context, template, adjective=adjective, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer) else: # Phrase the question as finding the common denominator of two fractions. p = number.integer(2, signed=True, coprime_to=p) / p q = number.integer(2, signed=True, coprime_to=q) / q p, q = context.sample(sample_args, [p, q]) template = random.choice([ 'Berapa penyebut dari {p} dan {q}?', 'Temukan penyebut yang sama dari {p} dan {q}.', 'Hitung penyebut dari {p} dan {q}.', ]) return example.Problem(question=example.question( context, template, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer)
def balanceCoeficients(self): if self.isBalanced(): pass else: els = list() # Get a list of element symbols for compound in self.leftSide: for element in compound.elements: els.append(element.symbol) els_index = dict(zip(els, range(len(els)))) # {'C': 0, 'H': 1, 'O': 2} # Build matrix to solve w = len(self.leftSide) + len(self.rightSide) # 4 h = len(els) # 3 A = [[0] * w for _ in range(h)] # [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] # load the matrix with element coefficients for col, compound in enumerate(self.leftSide): for el in compound.elements: row = els_index[el.symbol] A[row][col] = int(el.amount) for col, compound in enumerate(self.rightSide, len(self.leftSide)): for el in compound.elements: row = els_index[el.symbol] A[row][col] = -int(el.amount) # invert coefficients for RHS # Solve using Sympy for absolute-precision math A = sympy.Matrix(A) # find first basis vector == primary solution coeffs = A.nullspace()[0] # find least common denominator, multiply through to convert to integer solution coeffs *= sympy.lcm([term.q for term in coeffs]) tmp = 0 for i, comp in enumerate(self.leftSide): comp.amount = coeffs[i] tmp = i for i, comp in enumerate(self.rightSide): comp.amount = coeffs[i+tmp+1]
def nullspace_blocked(matrix, **kwargs): """ Calculate the nullspace of a given matrix. This is functionally equivalent to sympy's ``nullspace`` method, but it first subdivides the matrix into block-diagonal parts if possible. Keyword arguments are forwarded to the sympy nullspace method. """ n_rows, n_cols = matrix.shape row_nodes = [(_NodeType.ROW, i) for i in range(n_rows)] column_nodes = [(_NodeType.COLUMN, i) for i in range(n_cols)] graph = nx.Graph() graph.add_nodes_from(row_nodes) graph.add_nodes_from(column_nodes) for row_idx in range(n_rows): for column_idx, val in enumerate(matrix.row(row_idx)): if val.is_nonzero: graph.add_edge((_NodeType.ROW, row_idx), (_NodeType.COLUMN, column_idx)) nullspace = [] components = list(nx.connected_components(graph)) for component in components: row_indices = sorted(idx for kind, idx in component if kind is _NodeType.ROW) column_indices = sorted(idx for kind, idx in component if kind is _NodeType.COLUMN) if len(column_indices) == 0: continue mat_part = matrix[row_indices, column_indices] # Get rid of fractions -- least common multiple of the denominators # This greatly improves the performance of sympy's nullspace -- for # whatever reason. mat_part *= sp.lcm([sp.fraction(val)[1] for val in mat_part]) nullspace_part = np.array(mat_part.nullspace(**kwargs)) if len(nullspace_part) == 0: continue nullspace_part_extended = np.zeros((len(nullspace_part), n_cols), dtype=object) nullspace_part_extended[:, column_indices] = nullspace_part nullspace.extend([sp.Matrix(vec) for vec in nullspace_part_extended]) return nullspace
def lcm(value, sample_args, context=None): """Question for least common multiple of p and q.""" del value # unused if context is None: context = composition.Context() entropy, sample_args = sample_args.peel() p, q = _pair_with_large_hidden_factor(entropy) answer = sympy.lcm(p, q) if random.choice([False, True]): p, q = context.sample(sample_args, [p, q]) # Ask the question directly. adjective = random.choice(['наименьший']) template = random.choice([ 'Найдите {adjective} общий множитель {p} и {q}.', 'Какой {adjective} общий множитель у {p} и {q}?', ]) return example.Problem(question=example.question( context, template, adjective=adjective, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer) else: # Phrase the question as finding the common denominator of two fractions. p = number.integer(2, signed=True, coprime_to=p) / p q = number.integer(2, signed=True, coprime_to=q) / q p, q = context.sample(sample_args, [p, q]) template = random.choice([ 'Найдите общий знаменатель {p} и {q}.', 'Чему равен общий знаменатель {p} и {q}?', # 'Calculate the common denominator of {p} and {q}.', ]) return example.Problem(question=example.question( context, template, p=p.expression_else_handle, q=q.expression_else_handle), answer=answer)
class Random(sympy.Basic): def __init__(self, a=None, b=None): if a is None: self.a = 0 self.b = 1 self.isint = False elif b is None: self.a = 0 self.b = a self.isint = True else: sgn = sympy.sign(b - a) self.a = sgn * a + (1 - sgn) * b self.b = sgn * b + (1 - sgn) * a + 1 self.isint = True def evalf(self, prec): randfloat = sympy.Float(random.random(), dps=prec) / 2.7**(prec / 7 - random.random()) temp = (sympy.Float(random.random(), dps=prec) / (randfloat + time.time() % 1)) % 1 temp *= self.b - self.a temp += self.a if self.isint: temp = sympy.Integer(temp) return temp gcd = lambda self, other, *gens, **args: sympy.gcd(self.evalf(BF_PREC), other, *gens, **args) lcm = lambda self, other, *gens, **args: sympy.lcm(self.evalf(BF_PREC), other, *gens, **args) is_Rational = lambda self: True expand = lambda self, **void: self.evalf(BF_PREC) nsimplify = lambda self, **void: self.evalf(BF_PREC) as_coeff_Add = lambda self, *void: (0, self.evalf(BF_PREC)) as_coeff_Mul = lambda self, *void: (0, self.evalf(BF_PREC)) _eval_power = lambda *void: None _eval_evalf = evalf __abs__ = lambda self: abs(self.evalf(BF_PREC)) __neg__ = lambda self: -self.evalf(BF_PREC) __repr__ = lambda self, *void: str(self.evalf(BF_PREC)) __str__ = __repr__
def test_defect_calculation(): """Tests defect calculation on the cosimulation made of ramps""" slope1, slope2 = 2., 3. step1, step2 = Fraction(5), Fraction(7) cosim = ramp_cosimulation(slope1, slope2, step1, step2) t_end = Fraction(20) defect = cs.evaluate(cosim, t_end) alpha = Fraction(int(lcm(step1.numerator, step2.numerator)), int(gcd(step1.denominator, step2.denominator))) num1, num2 = tuple(map(int, [alpha / step for step in (step1, step2)])) big = max(num1, num2) + 1 small = min(num1, num2) - 1 assert defect.connection['Ramp1', 'u'] > small * slope2 * step2 assert defect.connection['Ramp1', 'u'] < big * slope2 * step2 assert defect.connection['Ramp2', 'u'] > small * slope1 * step1 assert defect.connection['Ramp2', 'u'] < big * slope1 * step1 assert defect.output['Ramp1', 'y'] == pytest.approx(slope1 * step1) assert defect.output['Ramp2', 'y'] == pytest.approx(slope2 * step2)
def common_denominator(f): def mul(a, b): if isinstance(a, (list, tuple)): return [mul(x, b) for x in a] else: return a * b if isinstance(f, (list, tuple)): ns, ds, rs = zip(*map(common_denominator, f)) if None not in ds and len(set(rs)) == 1: cd = sp.lcm(map(S, ds)) return [mul(n, cd // d) for n, d in zip(ns, ds)], cd, rs[0] if rational(f): return rational(f) + (1,) if isinstance(f, sp.Basic): a, b = f.as_coeff_mul() if a.is_Rational and len(b) == 1 and b[0].is_Pow and \ b[0].base.is_Rational and b[0].exp == S(1)/2: return a.p, a.q, b[0].base return None, None, None
def common_denominator(f): def mul(a, b): if isinstance(a, (list, tuple)): return [mul(x, b) for x in a] else: return a * b if isinstance(f, (list, tuple)): ns, ds, rs = zip(*map(common_denominator, f)) if None not in ds and len(set(rs)) == 1: cd = sp.lcm(map(S, ds)) return [mul(n, cd // d) for n, d in zip(ns, ds)], cd, rs[0] if rational(f): return rational(f) + (1, ) if isinstance(f, sp.Basic): a, b = f.as_coeff_mul() if a.is_Rational and len(b) == 1 and b[0].is_Pow and \ b[0].base.is_Rational and b[0].exp == S(1)/2: return a.p, a.q, b[0].base return None, None, None
def gen(self): irr_poly = Poly(alpha ** self.m + alpha + 1, alpha).set_domain(GF(self.q)) if gf_irreducible_p([int(c) for c in irr_poly.all_coeffs()], self.q, ZZ): quotient_size = len(power_dict(self.n, irr_poly, self.q)) else: quotient_size = 0 log.info("irr(q_size: {}): {}".format(quotient_size, irr_poly)) while quotient_size < self.n: irr_poly = Poly([int(c.numerator) for c in gf_irreducible(self.m, self.q, ZZ)], alpha) quotient_size = len(power_dict(self.n, irr_poly, self.q)) log.info("irr(q_size: {}): {}".format(quotient_size, irr_poly)) g_poly = None for i in range(self.b, self.b + self.d - 1): if g_poly is None: g_poly = minimal_poly(i, self.n, self.q, irr_poly) else: g_poly = lcm(g_poly, minimal_poly(i, self.n, self.q, irr_poly)) g_poly = g_poly.trunc(self.q) log.info("g(x)={}".format(g_poly)) return irr_poly, g_poly
def balance(productsSym, molMass, substances): global console console.print( "Skal reaktionsskemaet automatisk afstemmes? ([green]j[/green]/[red]n[/red]): ", end="") autoBalance = input() if autoBalance.lower() == "j": global elementMatrix for i in range(len(reactants)): compoundDecipher(reactants[i], i, 1) for i in range(len(products)): compoundDecipher(products[i], i + len(reactants), -1) elementMatrix = Matrix(elementMatrix) elementMatrix = elementMatrix.transpose() solution = elementMatrix.nullspace()[0] multiple = lcm([val.q for val in solution]) solution = multiple * solution coEffi = solution.tolist() return [coEffi[i][0] for i in range(len(reactants))] + [ coEffi[i + len(reactants)][0] for i in range(len(products)) ] elif autoBalance.lower() == "n": console.clear() x = Table(show_header=True, header_style="cyan") x.add_column("Af: Daniel Nettelfield") for i in productsSym: x.add_column(i) x.add_row(*(["Molare Masse [g/mol]"] + [str(round(i, decimals)) for i in molMass])) x.add_row(*(["Index Værdi"] + [str(i + 1) for i in range(len(substances))])) console.print(x) return [ int(input(f"Indsæt koefficient {i}: ")) for i in range(1, len(substances) + 1) ] else: consider(autoBalance) console.print("Ugyldigt input") return balance(productsSym, molMass, substances)
def findASolution(AMatrix): A = AMatrix U = [[ 0, A[1][0], A[2][0], -A[0][1], 0, 0, -A[0][2], 0, 0], [ A[0][1], A[1][1] - A[0][0], A[2][1], 0, -A[0][1], 0, 0, -A[0][2], 0], [ A[0][2], A[1][2], A[2][2] - A[0][0], 0, 0, -A[0][1], 0, 0, -A[0][2]], [-A[1][0], 0, 0, A[0][0] - A[1][1], A[1][0], A[2][0], -A[1][2], 0, 0], [ 0, -A[1][0], 0, A[0][1], 0, A[2][1], 0, -A[1][2], 0], [ 0, 0, -A[1][0], A[0][2], A[1][2], A[2][2] - A[1][1], 0, 0, -A[1][2]], [-A[2][0], 0, 0, -A[2][1], 0, 0, A[0][0] - A[2][2], A[1][0], A[2][0]], [ 0, -A[2][0], 0, 0, -A[2][1], 0, A[0][1], A[1][1] - A[2][2], A[2][1]], [ 0, 0, -A[2][0], 0, 0, -A[2][1], A[0][2], A[1][2], 0]] U = Matrix(U) NewSols = [] for sol in U.nullspace(): m = lcm([val.q for val in sol]) x = m * sol NewSols.append(x) return NewSols
def lcm_vec(Dmat): """ The function computes the least common multiple (LCM). Parameters ---------- Dmat: int The input number. Returns ------- lcm1: int The least common multiple of the input number. """ input1 = Dmat.flatten() Sz = input1.shape lcm1 = 1 for ct1 in range(Sz[0]): lcm1 = spy.lcm(lcm1, input1[ct1]) return int(lcm1)
def _find_realization(self, G, s): """ Represenatation [A, B, C, D] of the state space model Returns the representation in state space of a given transfer function Parameters ========== G: Matrix Matrix valued transfer function G(s) in laplace space s: symbol variable s, where G is dependent from See Also ======== Utils : some quick tools for matrix polynomials References ========== Joao P. Hespanha, Linear Systems Theory. 2009. """ A, B, C, D = 4 * [None] try: m, k = G.shape except AttributeError: raise TypeError("G must be a matrix") # test if G is proper if not utl.is_proper(G, s, strict=False): raise ValueError("G must be proper!") # define D as the limit of G for s to infinity D = G.limit(s, oo) # define G_sp as the (stricly proper) difference of G and D G_sp = simplify(G - D) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # get the coefficients of the monic least common denominator of all entries of G_sp # compute a least common denominator using utl and lcm lcd = lcm(utl.fraction_list(G_sp, only_denoms=True)) # make it monic lcd = simplify(lcd / LC(lcd, s)) # and get a coefficient list of its monic. The [1:] cuts the LC away (thats a one) lcd_coeff = Poly(lcd, s).all_coeffs()[1:] # get the degree of the lcd lcd_deg = degree(lcd, s) # get the Matrix Valued Coeffs of G_sp in G_sp = 1/lcd * (N_1 * s**(n-1) + N_2 * s**(n-2) .. +N_n) G_sp_coeff = utl.matrix_coeff(simplify(G_sp * lcd), s) G_sp_coeff = [zeros(m, k)] * (lcd_deg - len(G_sp_coeff)) + G_sp_coeff # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # now store A, B, C, D in terms of the coefficients of lcd and G_sp # define A A = (-1) * lcd_coeff[0] * eye(k) for alpha in lcd_coeff[1:]: A = A.row_join((-1) * alpha * eye(k)) for i in xrange(lcd_deg - 1): if i == 0: tmp = eye(k) else: tmp = zeros(k) for j in range(lcd_deg)[1:]: if j == i: tmp = tmp.row_join(eye(k)) else: tmp = tmp.row_join(zeros(k)) if tmp is not None: A = A.col_join(tmp) # define B B = eye(k) for i in xrange(lcd_deg - 1): B = B.col_join(zeros(k)) # define C C = G_sp_coeff[0] for i in range(lcd_deg)[1:]: C = C.row_join(G_sp_coeff[i]) # return the state space representation return [simplify(A), simplify(B), simplify(C), simplify(D)]
def approximants(l, X=Symbol('x'), simplify=False): """ Return a generator for consecutive Pade approximants for a series. It can also be used for computing the rational generating function of a series when possible, since the last approximant returned by the generator will be the generating function (if any). The input list can contain more complex expressions than integer or rational numbers; symbols may also be involved in the computation. An example below show how to compute the generating function of the whole Pascal triangle. The generator can be asked to apply the sympy.simplify function on each generated term, which will make the computation slower; however it may be useful when symbols are involved in the expressions. Examples ======== >>> from sympy.series import approximants >>> from sympy import lucas, fibonacci, symbols, binomial >>> g = [lucas(k) for k in range(16)] >>> [e for e in approximants(g)] [2, -4/(x - 2), (5*x - 2)/(3*x - 1), (x - 2)/(x**2 + x - 1)] >>> h = [fibonacci(k) for k in range(16)] >>> [e for e in approximants(h)] [x, -x/(x - 1), (x**2 - x)/(2*x - 1), -x/(x**2 + x - 1)] >>> x, t = symbols("x,t") >>> p=[sum(binomial(k,i)*x**i for i in range(k+1)) for k in range(16)] >>> y = approximants(p, t) >>> for k in range(3): print(next(y)) 1 (x + 1)/((-x - 1)*(t*(x + 1) + (x + 1)/(-x - 1))) nan >>> y = approximants(p, t, simplify=True) >>> for k in range(3): print(next(y)) 1 -1/(t*(x + 1) - 1) nan See also ======== See function sympy.concrete.guess.guess_generating_function_rational and function mpmath.pade """ p1, q1 = [Integer(1)], [Integer(0)] p2, q2 = [Integer(0)], [Integer(1)] while len(l): b = 0 while l[b]==0: b += 1 if b == len(l): return m = [Integer(1)/l[b]] for k in range(b+1, len(l)): s = 0 for j in range(b, k): s -= l[j+1] * m[b-j-1] m.append(s/l[b]) l = m a, l[0] = l[0], 0 p = [0] * max(len(p2), b+len(p1)) q = [0] * max(len(q2), b+len(q1)) for k in range(len(p2)): p[k] = a*p2[k] for k in range(b, b+len(p1)): p[k] += p1[k-b] for k in range(len(q2)): q[k] = a*q2[k] for k in range(b, b+len(q1)): q[k] += q1[k-b] while p[-1]==0: p.pop() while q[-1]==0: q.pop() p1, p2 = p2, p q1, q2 = q2, q # yield result from sympy import denom, lcm, simplify as simp c = 1 for x in p: c = lcm(c, denom(x)) for x in q: c = lcm(c, denom(x)) out = ( sum(c*e*X**k for k, e in enumerate(p)) / sum(c*e*X**k for k, e in enumerate(q)) ) if simplify: yield(simp(out)) else: yield out return
''' Project Euler Problem #5: 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? ''' import sympy a = list(range(1,21)) print(sympy.lcm(a))